Skip to content

Commit

Permalink
Add -n (non-recursive) mode.
Browse files Browse the repository at this point in the history
Property pluralize file and folder count.
  • Loading branch information
KirillOsenkov committed Nov 5, 2016
1 parent 84515f6 commit ed66276
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 28 deletions.
4 changes: 4 additions & 0 deletions src/ContentSync/Arguments.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ public class Arguments
public string Source { get; set; }
public string Destination { get; set; }
public string Pattern { get; set; } = "*";
public bool Nonrecursive { get; set; }

public bool CopyLeftOnlyFiles { get; private set; } = true;
public bool UpdateChangedFiles { get; private set; } = true;
Expand Down Expand Up @@ -101,6 +102,9 @@ private void Parse()
case "dc":
DeleteChangedFiles = true;
break;
case "n":
Nonrecursive = true;
break;
case "q":
Quiet = true;
Log.Quiet = true;
Expand Down
24 changes: 17 additions & 7 deletions src/ContentSync/Folders.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,18 @@ public class Folders
/// <summary>
/// Assumes leftRoot is an existing folder. rightRoot may not exist if operating in speculative mode.
/// </summary>
public static FolderDiffResults DiffFolders(string leftRoot, string rightRoot, string pattern, bool compareContents = true)
public static FolderDiffResults DiffFolders(
string leftRoot,
string rightRoot,
string pattern,
bool recursive = true,
bool compareContents = true)
{
HashSet<string> leftRelativePaths = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
HashSet<string> leftOnlyFolders = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
using (Log.MeasureTime("Scanning source directory"))
{
GetRelativePathsOfAllFiles(leftRoot, pattern, leftRelativePaths, leftOnlyFolders);
GetRelativePathsOfAllFiles(leftRoot, pattern, recursive, leftRelativePaths, leftOnlyFolders);
}

HashSet<string> rightRelativePaths = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
Expand All @@ -28,7 +33,7 @@ public static FolderDiffResults DiffFolders(string leftRoot, string rightRoot, s
{
using (Log.MeasureTime("Scanning destination directory"))
{
GetRelativePathsOfAllFiles(rightRoot, pattern, rightRelativePaths, rightOnlyFolders);
GetRelativePathsOfAllFiles(rightRoot, pattern, recursive, rightRelativePaths, rightOnlyFolders);
}
}

Expand Down Expand Up @@ -108,16 +113,18 @@ public static FolderDiffResults DiffFolders(string leftRoot, string rightRoot, s

private static readonly FieldInfo pathField = typeof(FileSystemInfo).GetField("FullPath", BindingFlags.Instance | BindingFlags.NonPublic);

public static void GetRelativePathsOfAllFiles(string rootFolder, string pattern, HashSet<string> files, HashSet<string> folders)
public static void GetRelativePathsOfAllFiles(string rootFolder, string pattern, bool recursive, HashSet<string> files, HashSet<string> folders)
{
if (DirectoryContentsCache.TryReadFromCache(rootFolder, pattern, files, folders))
// don't go through the cache for non-recursive case
if (recursive && DirectoryContentsCache.TryReadFromCache(rootFolder, pattern, files, folders))
{
return;
}

var rootDirectoryInfo = new DirectoryInfo(rootFolder);
var prefixLength = rootFolder.Length;
var fileSystemInfos = rootDirectoryInfo.EnumerateFileSystemInfos(pattern, SearchOption.AllDirectories);
var searchOption = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;
var fileSystemInfos = rootDirectoryInfo.EnumerateFileSystemInfos(pattern, searchOption);
foreach (var fileSystemInfo in fileSystemInfos)
{
string relativePath = (string)pathField.GetValue(fileSystemInfo);
Expand All @@ -132,7 +139,10 @@ public static void GetRelativePathsOfAllFiles(string rootFolder, string pattern,
}
}

DirectoryContentsCache.SaveToCache(rootFolder, pattern, files, folders);
if (recursive)
{
DirectoryContentsCache.SaveToCache(rootFolder, pattern, files, folders);
}
}
}
}
4 changes: 3 additions & 1 deletion src/ContentSync/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ private static int Main(string[] args)
private static void PrintUsage()
{
Console.WriteLine(@"Usage: ContentSync.exe <source> <destination> [<pattern>] [-c] [-u] [-d]
[-dc] [-ds]
[-dc] [-ds] [-n]
[-whatif] [-q]
[-h]
Expand All @@ -101,6 +101,8 @@ destination that are not in source.
-dc Delete changed files from destination (can't be used with -u).
-n Non-recursive (only compare files at top-level).
-whatif Print what would have been done (without changing anything).
-q Quiet mode. Do not output anything to the console.
Expand Down
58 changes: 38 additions & 20 deletions src/ContentSync/Sync.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.IO;
using System.Linq;
using static GuiLabs.Common.Utilities;

namespace GuiLabs.FileUtilities
{
Expand All @@ -19,7 +20,12 @@ public static void Directories(string source, string destination, Arguments argu
source = Paths.TrimSeparator(source);
destination = Paths.TrimSeparator(destination);

var diff = Folders.DiffFolders(source, destination, arguments.Pattern, compareContents: arguments.UpdateChangedFiles);
var diff = Folders.DiffFolders(
source,
destination,
arguments.Pattern,
recursive: !arguments.Nonrecursive,
compareContents: arguments.UpdateChangedFiles);

bool changesMade = false;
int filesFailedToCopy = 0;
Expand Down Expand Up @@ -163,113 +169,125 @@ public static void Directories(string source, string destination, Arguments argu

if (diff.LeftOnlyFiles.Any() && arguments.CopyLeftOnlyFiles)
{
var count = diff.LeftOnlyFiles.Count();
var fileOrFiles = Pluralize("file", count);
if (arguments.WhatIf)
{
Log.WriteLine($"Would have copied {diff.LeftOnlyFiles.Count()} new files", ConsoleColor.Green);
Log.WriteLine($"Would have copied {count} new {fileOrFiles}", ConsoleColor.Green);
}
else
{
Log.WriteLine($"{diff.LeftOnlyFiles.Count()} new files copied", ConsoleColor.Green);
Log.WriteLine($"{count} new {fileOrFiles} copied", ConsoleColor.Green);
}
}

if (foldersCreated > 0 && arguments.CopyEmptyDirectories)
{
var folderOrFolders = Pluralize("folder", foldersCreated);
if (arguments.WhatIf)
{
Log.WriteLine($"Would have created {foldersCreated} folders", ConsoleColor.Green);
Log.WriteLine($"Would have created {foldersCreated} {folderOrFolders}", ConsoleColor.Green);
}
else
{
Log.WriteLine($"{foldersCreated} folders created", ConsoleColor.Green);
Log.WriteLine($"{foldersCreated} {folderOrFolders} created", ConsoleColor.Green);
}
}

if (diff.ChangedFiles.Any() && arguments.UpdateChangedFiles)
{
var count = diff.ChangedFiles.Count();
var fileOrFiles = Pluralize("file", count);
if (arguments.WhatIf)
{
Log.WriteLine($"Would have updated {diff.ChangedFiles.Count()} changed files", ConsoleColor.Yellow);
Log.WriteLine($"Would have updated {count} changed {fileOrFiles}", ConsoleColor.Yellow);
}
else
{
Log.WriteLine($"{diff.ChangedFiles.Count()} changed files updated", ConsoleColor.Yellow);
Log.WriteLine($"{count} changed {fileOrFiles} updated", ConsoleColor.Yellow);
}
}

if (diff.ChangedFiles.Any() && arguments.DeleteChangedFiles)
{
var count = diff.ChangedFiles.Count();
var fileOrFiles = Pluralize("file", count);
if (arguments.WhatIf)
{
Log.WriteLine($"Would have deleted {diff.ChangedFiles.Count()} changed files", ConsoleColor.Yellow);
Log.WriteLine($"Would have deleted {count} changed {fileOrFiles}", ConsoleColor.Yellow);
}
else
{
Log.WriteLine($"{diff.ChangedFiles.Count()} changed files deleted", ConsoleColor.Yellow);
Log.WriteLine($"{count} changed {fileOrFiles} deleted", ConsoleColor.Yellow);
}
}

if (diff.RightOnlyFiles.Any() && arguments.DeleteRightOnlyFiles)
{
var count = diff.RightOnlyFiles.Count();
var fileOrFiles = Pluralize("file", count);
if (arguments.WhatIf)
{
Log.WriteLine($"Would have deleted {diff.RightOnlyFiles.Count()} right-only files", ConsoleColor.Red);
Log.WriteLine($"Would have deleted {count} right-only {fileOrFiles}", ConsoleColor.Red);
}
else
{
Log.WriteLine($"{diff.RightOnlyFiles.Count()} right-only files deleted", ConsoleColor.Red);
Log.WriteLine($"{count} right-only {fileOrFiles} deleted", ConsoleColor.Red);
}
}

if (foldersDeleted > 0 && arguments.DeleteRightOnlyDirectories)
{
var folderOrFolders = Pluralize("folder", foldersDeleted);
if (arguments.WhatIf)
{
Log.WriteLine($"Would have deleted {foldersDeleted} right-only folders", ConsoleColor.Red);
Log.WriteLine($"Would have deleted {foldersDeleted} right-only {folderOrFolders}", ConsoleColor.Red);
}
else
{
Log.WriteLine($"{foldersDeleted} right-only folders deleted", ConsoleColor.Red);
Log.WriteLine($"{foldersDeleted} right-only {folderOrFolders} deleted", ConsoleColor.Red);
}
}

if (diff.IdenticalFiles.Any())
{
var count = diff.IdenticalFiles.Count();
var fileOrFiles = Pluralize("file", count);
if (arguments.DeleteSameFiles)
{
if (arguments.WhatIf)
{
Log.WriteLine($"Would have deleted {diff.IdenticalFiles.Count()} identical files from destination", ConsoleColor.White);
Log.WriteLine($"Would have deleted {count} identical {fileOrFiles} from destination", ConsoleColor.White);
}
else
{
Log.WriteLine($"{diff.IdenticalFiles.Count()} identical files deleted from destination", ConsoleColor.White);
Log.WriteLine($"{count} identical {fileOrFiles} deleted from destination", ConsoleColor.White);
}
}
else
{
Log.WriteLine($"{diff.IdenticalFiles.Count()} identical files", ConsoleColor.White);
Log.WriteLine($"{count} identical {fileOrFiles}", ConsoleColor.White);
}
}

if (filesFailedToCopy > 0)
{
Log.WriteLine($"Failed to copy {filesFailedToCopy} files", ConsoleColor.Red);
Log.WriteLine($"Failed to copy {filesFailedToCopy} {Pluralize("file", filesFailedToCopy)}", ConsoleColor.Red);
}

if (filesFailedToDelete > 0)
{
Log.WriteLine($"Failed to delete {filesFailedToDelete} files.", ConsoleColor.Red);
Log.WriteLine($"Failed to delete {filesFailedToDelete} {Pluralize("file", filesFailedToDelete)}.", ConsoleColor.Red);
}

if (foldersFailedToCreate > 0)
{
Log.WriteLine($"Failed to create {foldersFailedToCreate} folders.", ConsoleColor.Red);
Log.WriteLine($"Failed to create {foldersFailedToCreate} {Pluralize("folder", foldersFailedToCreate)}.", ConsoleColor.Red);
}

if (foldersFailedToDelete > 0)
{
Log.WriteLine($"Failed to delete {foldersFailedToDelete} folders.", ConsoleColor.Red);
Log.WriteLine($"Failed to delete {foldersFailedToDelete} {Pluralize("folder", foldersFailedToDelete)}.", ConsoleColor.Red);
}

if (!changesMade)
Expand Down
12 changes: 12 additions & 0 deletions src/ContentSync/Utilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,17 @@ public static string ByteArrayToHexString(byte[] bytes)

return new string(c);
}

public static string Pluralize(string noun, int count)
{
if (count == 1)
{
return noun;
}
else
{
return noun + "s";
}
}
}
}

0 comments on commit ed66276

Please sign in to comment.