static void Main(string[] args)
        {
            int exitCode = 0;
            IRepositoryProxy sourceRep = null;
            IRepositoryProxy destRep   = null;

            do
            {
                DateTime startTime = DateTime.Now;

                ManifestConsole console = new ManifestConsole();

                int    argIndex   = 0;
                string commandArg = "help";

                if (argIndex < args.Count())
                {
                    commandArg = args[argIndex++];
                }

                bool seedCommand     = false;
                bool validateCommand = false;

                switch (commandArg)
                {
                case "help":
                case "diff":
                case "update":
                case "sync":
                case "mirror":
                    break;

                case "seed":
                    seedCommand = true;
                    break;

                case "validateCrypt":
                    validateCommand = true;
                    break;

                default:
                    console.WriteLine("Unrecognized command \"" + commandArg + "\"");
                    Environment.Exit(1);
                    break;
                }

                if (commandArg == "help")
                {
                    console.Write(Properties.Resources.RepositorySyncHelp);
                    Environment.Exit(1);
                    break;
                }

                bool parseTwoRepositoryStrings = args.Length >= 3;

                string sourceRepString = "";
                string destRepString   = "";

                if (validateCommand && args.Length >= 2)
                {
                    // Special case only has source repository
                    sourceRepString = args[argIndex++];
                }
                else if (parseTwoRepositoryStrings == true)
                {
                    // Skip repositories for now and process options
                    sourceRepString = args[argIndex++];
                    destRepString   = args[argIndex++];
                }
                else
                {
                    console.WriteLine("Source or destination repositories were not supplied.");
                    exitCode = 1;
                    break;
                }


                // Process options

                bool time  = false;
                bool retry = false;

                String sourceKeyString = null;
                String destKeyString   = null;

                while (argIndex < args.Length)
                {
                    string nextArg = args[argIndex++];

                    switch (nextArg)
                    {
                    case "-silent":
                        console.Silent = true;
                        break;

                    case "-detail":
                        console.Detail = true;
                        break;

                    case "-noTimeout":
                        RemoteRepositoryProxy.RequestReadWriteTimeout =
                            System.Threading.Timeout.Infinite;

                        RemoteRepositoryProxy.RequestTimeout =
                            System.Threading.Timeout.Infinite;
                        break;

                    case "-time":
                        time = true;
                        break;

                    case "-sourceKey":
                        if (ArgUtilities.HasAnotherArgument(
                                args, argIndex, console) == true)
                        {
                            sourceKeyString = args[argIndex++];
                        }
                        break;

                    case "-destKey":
                        if (ArgUtilities.HasAnotherArgument(
                                args, argIndex, console) == true)
                        {
                            destKeyString = args[argIndex++];
                        }
                        break;

                    case "-cryptSource":
                        console.Write("Enter source key: ");
                        sourceKeyString = console.EnterPassword();
                        break;

                    case "-cryptDest":
                        console.Write("Enter dest key: ");
                        destKeyString = console.EnterPassword();
                        break;

                    case "-retry":
                        retry = true;
                        break;

                    default:
                        console.WriteLine("Unrecognized parameter \" " + nextArg + "\"");
                        Environment.Exit(1);
                        break;
                    }
                }


                // Resolve repositories

                bool sourceReadOnly = true;
                bool destReadOnly   = false;
                if (commandArg == "diff")
                {
                    destReadOnly = true;
                }
                else if (commandArg == "sync")
                {
                    sourceReadOnly = false;
                }

                bool remoteSource =
                    RemoteRepositoryProxy.IsRemoteRepositoryString(
                        sourceRepString);

                bool remoteDest =
                    RemoteRepositoryProxy.IsRemoteRepositoryString(
                        destRepString);

                if (remoteSource == false)
                {
                    try
                    {
                        sourceRep = new LocalRepositoryProxy(
                            new System.IO.DirectoryInfo(sourceRepString),
                            sourceReadOnly);

                        if (sourceKeyString != null)
                        {
                            CryptRepositoryProxy cryptProxy =
                                new CryptRepositoryProxy(
                                    sourceRep,
                                    sourceKeyString,
                                    sourceReadOnly);

                            ReportCrypt(cryptProxy, "Source", console);
                            sourceRep = cryptProxy;
                        }
                    }
                    catch (Exception e)
                    {
                        console.WriteLine("Exception: " + e.Message);
                        exitCode = 1;
                        break;
                    }
                }

                if (remoteDest == false &&
                    seedCommand == false &&
                    destRepString != "")
                {
                    try
                    {
                        destRep = new LocalRepositoryProxy(
                            new System.IO.DirectoryInfo(destRepString),
                            destReadOnly);

                        if (destKeyString != null)
                        {
                            CryptRepositoryProxy cryptProxy =
                                new CryptRepositoryProxy(
                                    destRep,
                                    destKeyString,
                                    destReadOnly);

                            ReportCrypt(cryptProxy, "Dest", console);
                            destRep = cryptProxy;
                        }
                    }
                    catch (Exception e)
                    {
                        console.WriteLine("Exception: " + e.Message);
                        exitCode = 1;
                        break;
                    }
                }

                if (remoteSource == true)
                {
                    try
                    {
                        sourceRep = new RemoteRepositoryProxy(
                            sourceRepString,
                            destRep.Manifest);

                        if (sourceKeyString != null)
                        {
                            CryptRepositoryProxy cryptProxy =
                                new CryptRepositoryProxy(
                                    sourceRep,
                                    sourceKeyString,
                                    sourceReadOnly);

                            ReportCrypt(cryptProxy, "Source", console);
                            sourceRep = cryptProxy;
                        }
                    }
                    catch (Exception e)
                    {
                        console.WriteLine("Exception: " + e.Message);
                        exitCode = 1;
                        break;
                    }
                }

                if (remoteDest == true &&
                    seedCommand == false &&
                    destRepString != "")
                {
                    try
                    {
                        destRep = new RemoteRepositoryProxy(
                            destRepString,
                            sourceRep.Manifest);

                        if (destKeyString != null)
                        {
                            CryptRepositoryProxy cryptProxy =
                                new CryptRepositoryProxy(
                                    destRep,
                                    destKeyString,
                                    destReadOnly);

                            ReportCrypt(cryptProxy, "Dest", console);
                            destRep = cryptProxy;
                        }
                    }
                    catch (Exception e)
                    {
                        console.WriteLine("Exception: " + e.Message);
                        exitCode = 1;
                        break;
                    }
                }

                if (sourceRep == null && destRep == null)
                {
                    console.WriteLine("Could not resolve a source or destination repository.");
                    exitCode = 1;
                    break;
                }
                else if (sourceRep == null)
                {
                    console.WriteLine("Could not resolve a source repository.");
                    exitCode = 1;
                    break;
                }
                else if (destRep == null && seedCommand == false && validateCommand == false)
                {
                    console.WriteLine("Could not resolve a destination repository.");
                    exitCode = 1;
                    break;
                }


                switch (commandArg)
                {
                case "update":
                case "sync":
                case "mirror":
                    if (sourceRep != null &&
                        destRep != null &&
                        sourceRep.Manifest.Guid.Equals(
                            destRep.Manifest.Guid) == false)
                    {
                        console.WriteLine("Source and destination GUIDs are different.");
                        exitCode = 1;
                    }
                    break;
                }

                if (exitCode == 1)
                {
                    break;
                }

                RepositorySync syncTool = null;
                if (seedCommand == false && validateCommand == false)
                {
                    syncTool       = new RepositorySync(sourceRep, destRep);
                    syncTool.Retry = retry;

                    syncTool.WriteLogDelegate =
                        delegate(String message)
                    {
                        console.Write(message);
                    };

                    syncTool.CompareManifests();
                }


                // Process command

                if (time)
                {
                    console.WriteLine("Started: " + startTime.ToString());
                }

                switch (commandArg)
                {
                case "diff":
                    ShowDiff(syncTool, console);
                    break;

                case "update":
                    syncTool.DoUpdate();
                    break;

                case "sync":
                    syncTool.BothWays = true;
                    syncTool.DoUpdate();
                    break;

                case "mirror":
                    syncTool.Mirror = true;
                    syncTool.DoUpdate();
                    break;

                case "seed":
                    if (destKeyString == null)
                    {
                        LocalRepositoryProxy.SeedLocalRepository(
                            sourceRep.Manifest,
                            destRepString,
                            console);
                    }
                    else
                    {
                        CryptRepositoryProxy.SeedLocalRepository(
                            sourceRep.Manifest,
                            destKeyString,
                            destRepString,
                            console);
                    }
                    break;

                case "validateCrypt":
                    CryptRepositoryProxy sourceCryptRep =
                        sourceRep as CryptRepositoryProxy;

                    if (sourceCryptRep == null)
                    {
                        console.WriteLine("The validateCrypt command requires an encrypted repository.");
                        exitCode = 1;
                        break;
                    }

                    long fileCount = sourceCryptRep.Validate(console);
                    console.WriteLine(fileCount + " files checked.");

                    break;
                }

                if (time)
                {
                    DateTime finishedTime = DateTime.Now;
                    console.WriteLine("Finished: " + finishedTime.ToString());
                    console.WriteLine("Duration: " + (finishedTime - startTime).ToString());
                }
            } while (false);


            if (sourceRep != null)
            {
                sourceRep.CleanupBeforeExit();
                sourceRep = null;
            }

            if (destRep != null)
            {
                destRep.CleanupBeforeExit();
                destRep = null;
            }

            Environment.Exit(exitCode);
        }
Beispiel #2
0
        static void Main(string[] args)
        {
            // Initialize some things
            ManifestConsole console = new ManifestConsole();

            RepositoryTool tool = new RepositoryTool();

            tool.WriteLogDelegate =
                delegate(String message)
            {
                console.Write(message);
            };

            DateTime startTime = DateTime.Now;
            int      exitCode  = 0;
            int      argIndex  = 0;


            // Give the user some help if they need it
            string commandArg = "help";

            if (args.Length > 0)
            {
                commandArg = args[argIndex++];
            }


            // Initial screen for valid command
            switch (commandArg)
            {
            case "create":
            case "validate":
            case "status":
            case "update":
            case "edit":
            case "groom":
            case "clear":
            case "info":
            case "help":
                break;

            default:
                console.WriteLine("Unrecognized command \"" + commandArg + "\"");
                exitCode = 1;
                Environment.Exit(exitCode);
                break;
            }


            // Set up options and parameters
            bool ignoreDate          = false;
            bool ignoreNew           = false;
            bool time                = false;
            bool all                 = false;
            bool force               = false;
            bool ignoreDefault       = false;
            bool recursive           = false;
            bool cascade             = false;
            bool manifestInfoChanged = false;
            bool noTouch             = false;
            bool confirmUpdate       = false;
            bool forceJSON           = false;
            bool forceBinary         = false;

            string repositoryName               = null;
            string repositoryDescription        = null;
            string hashMethod                   = null;
            string manifestFilePathNotRecursive = null;

            List <String> ignoreList     = new List <string>();
            List <String> dontIgnoreList = new List <string>();


            // Parse options and parameters
            while (argIndex < args.Length)
            {
                string nextArg = args[argIndex++];

                switch (nextArg)
                {
                case "-all":
                    all = true;
                    break;

                case "-silent":
                    console.Silent        = true;
                    tool.WriteLogDelegate = null;
                    break;

                case "-detail":
                    console.Detail = true;
                    break;

                case "-showProgress":
                    tool.ShowProgress = true;
                    break;

                case "-ignoreDate":
                    ignoreDate = true;
                    break;

                case "-ignoreNew":
                    ignoreNew = true;
                    break;

                case "-reHash":
                    tool.AlwaysCheckHash = true;
                    break;

                case "-newHash":
                    tool.MakeNewHash = true;
                    break;

                case "-time":
                    time = true;
                    break;

                case "-name":
                    if (ArgUtilities.HasAnotherArgument(
                            args, argIndex, console) == true)
                    {
                        repositoryName = args[argIndex++];
                    }
                    break;

                case "-description":
                    if (ArgUtilities.HasAnotherArgument(
                            args, argIndex, console) == true)
                    {
                        repositoryDescription = args[argIndex++];
                    }
                    break;

                case "-hashMethod":
                    if (ArgUtilities.HasAnotherArgument(
                            args, argIndex, console) == true)
                    {
                        hashMethod = args[argIndex++];
                    }
                    break;

                case "-backDate":
                    tool.BackDate = true;
                    break;

                case "-trackMoves":
                    tool.TrackMoves = true;
                    break;

                case "-trackDuplicates":
                    tool.TrackDuplicates = true;
                    break;

                case "-ignore":
                    if (ArgUtilities.HasAnotherArgument(
                            args, argIndex, console) == true)
                    {
                        ignoreList.Add(args[argIndex++]);
                    }
                    break;

                case "-dontIgnore":
                    if (ArgUtilities.HasAnotherArgument(
                            args, argIndex, console) == true)
                    {
                        dontIgnoreList.Add(args[argIndex++]);
                    }
                    break;

                case "-manifestFile":
                    if (ArgUtilities.HasAnotherArgument(
                            args, argIndex, console) == true)
                    {
                        manifestFilePathNotRecursive = args[argIndex++];
                    }
                    break;

                case "-force":
                    force = true;
                    break;

                case "-ignoreDefault":
                    ignoreDefault = true;
                    break;

                case "-recursive":
                    recursive = true;
                    break;

                case "-cascade":
                    cascade = true;
                    break;

                case "-noTouch":
                    noTouch = true;
                    break;

                case "-confirmUpdate":
                    confirmUpdate = true;
                    break;

                case "-forceJSON":
                    forceJSON = true;
                    break;

                case "-forceBinary":
                    forceBinary = true;
                    break;

                default:
                    console.WriteLine("Unrecognized parameter \" " + nextArg + "\"");
                    commandArg = "";
                    exitCode   = 1;
                    break;
                }
            }

            if (time)
            {
                console.WriteLine("Started: " + startTime.ToString());
            }

            // Prepare a list of paths to be processed
            List <String> manifestFilePaths = new List <string>();

            if (recursive)
            {
                FindManifests(
                    new DirectoryInfo(Directory.GetCurrentDirectory()),
                    cascade,
                    manifestFilePaths);
            }
            else
            {
                if (manifestFilePathNotRecursive == null)
                {
                    // Default manifest file name located in current directory.
                    manifestFilePathNotRecursive =
                        PathUtilities.NativeFromNativeAndStandard(
                            System.IO.Directory.GetCurrentDirectory(),
                            Manifest.DefaultManifestStandardFilePath);
                }

                manifestFilePaths.Add(manifestFilePathNotRecursive);
            }


            // Outer loop over manifests
            foreach (String manifestFilePath in manifestFilePaths)
            {
                if (recursive == true)
                {
                    console.WriteLine(Path.GetDirectoryName(manifestFilePath) + ":");
                }

                // Initialize the tool for this manifest
                tool.Clear();
                tool.Manifest = null;

                // Second copy of the manifest which will remain unmodified
                // and possibly rewritten after a validate.
                Manifest manifestForValidateDateUpdate = null;

                FileInfo fileInfo = new FileInfo(manifestFilePath);

                if (recursive == true)
                {
                    tool.RootDirectory = fileInfo.Directory;
                }
                else
                {
                    // In case -manifestFile was specified, we always want this:
                    tool.RootDirectory = new DirectoryInfo(
                        System.IO.Directory.GetCurrentDirectory());
                }

                // Command-specific code to initialize tool object and
                // manifest object, and then execute command using tool.
                switch (commandArg)
                {
                case "create":
                {
                    bool doCreate = true;

                    if (force == false)
                    {
                        if (File.Exists(manifestFilePath))
                        {
                            doCreate = false;
                            console.Write("Replace existing manifest file? ");
                            doCreate = console.CheckConfirm();
                        }
                    }

                    if (doCreate == true)
                    {
                        tool.Manifest         = tool.MakeManifest();
                        tool.Manifest.UseJSON = true;
                    }

                    break;
                }

                case "validate":
                case "status":
                case "update":
                case "edit":
                case "groom":
                {
                    if (commandArg == "validate")
                    {
                        tool.AlwaysCheckHash = true;
                    }
                    else if (commandArg == "update")
                    {
                        tool.Update = true;
                    }

                    bool different = false;

                    try
                    {
                        tool.Manifest = Manifest.ReadManifestFile(manifestFilePath);

                        if (commandArg == "validate" && noTouch == false)
                        {
                            // Read a second copy which will remain unmodified
                            manifestForValidateDateUpdate =
                                Manifest.ReadManifestFile(manifestFilePath);
                        }
                    }
                    catch (Exception ex)
                    {
                        console.ReportException(ex);
                        console.WriteLine("Could not read manifest.");
                        Environment.Exit(1);
                    }

                    if (tool.Manifest == null)
                    {
                        exitCode = 1;
                    }
                    else if (commandArg != "edit")
                    {
                        tool.DoUpdate();

                        if (tool.MissingFiles.Count > 0)
                        {
                            console.WriteLine(tool.MissingFiles.Count.ToString() + " files are missing.");
                            console.DetailFiles(tool.MissingFiles);
                            different = true;
                        }

                        if (tool.ChangedFiles.Count > 0)
                        {
                            console.WriteLine(tool.ChangedFiles.Count.ToString() + " files have changed content.");
                            console.DetailFiles(tool.ChangedFiles);
                            different = true;
                        }

                        if (tool.NewFiles.Count > 0)
                        {
                            console.WriteLine(tool.NewFiles.Count.ToString() + " files are new.");
                            console.DetailFiles(tool.NewFiles);

                            if (ignoreNew == false)
                            {
                                different = true;
                            }
                        }

                        if (tool.LastModifiedDateFiles.Count > 0)
                        {
                            console.WriteLine(tool.LastModifiedDateFiles.Count.ToString() +
                                              " files have last-modified dates which are different.");

                            console.DetailFiles(tool.LastModifiedDateFiles);

                            if (ignoreDate == false)
                            {
                                different = true;
                            }
                        }

                        if (tool.ErrorFiles.Count > 0)
                        {
                            console.WriteLine(tool.ErrorFiles.Count.ToString() + " files have errors.");
                            console.DetailFiles(tool.ErrorFiles);
                            different = true;
                        }

                        if (tool.MovedFiles.Count > 0)
                        {
                            console.WriteLine(tool.MovedFiles.Count.ToString() + " files were moved.");
                            console.DetailFiles(tool.MovedFileOrder, tool.MovedFiles);
                            different = true;
                        }

                        if (tool.DuplicateFiles.Keys.Count > 0)
                        {
                            console.WriteLine(tool.DuplicateFiles.Keys.Count.ToString() + " file hashes were duplicates.");
                            console.DetailFiles(tool.DuplicateFiles);
                        }

                        if (tool.NewlyIgnoredFiles.Count > 0)
                        {
                            console.WriteLine(tool.NewlyIgnoredFiles.Count.ToString() + " files are newly ignored.");
                            console.DetailFiles(tool.NewlyIgnoredFiles);
                        }

                        if (tool.IgnoredFiles.Count > 1)
                        {
                            console.WriteLine(tool.IgnoredFiles.Count.ToString() + " files were ignored.");

                            if (all == true)
                            {
                                console.DetailFiles(tool.IgnoredFiles);
                            }
                        }


                        console.WriteLine(tool.FileCheckedCount.ToString() + " files were checked.");

                        if (commandArg == "validate")
                        {
                            if (different)
                            {
                                console.WriteLine("Problems found.");
                                exitCode = 1;
                            }
                            else
                            {
                                console.WriteLine("No problems.");
                            }
                        }
                    }
                    break;
                }

                case "clear":
                    try
                    {
                        tool.Manifest = Manifest.ReadManifestFile(manifestFilePath);
                    }
                    catch (Exception ex)
                    {
                        console.ReportException(ex);
                        console.WriteLine("Could not read manifest.");
                    }

                    if (tool.Manifest != null)
                    {
                        bool doClear = true;

                        if (force == false)
                        {
                            console.Write("Clear " +
                                          tool.Manifest.CountFiles().ToString() +
                                          " files from the manifest? ");

                            doClear = console.CheckConfirm();
                        }

                        if (doClear == true)
                        {
                            if (tool.Manifest == null)
                            {
                                exitCode = 1;
                            }
                            else
                            {
                                tool.Manifest.RootDirectory.Files.Clear();
                                tool.Manifest.RootDirectory.Subdirectories.Clear();
                            }
                        }
                    }

                    break;

                case "info":
                    try
                    {
                        tool.Manifest = Manifest.ReadManifestFile(manifestFilePath);
                    }
                    catch (Exception ex)
                    {
                        console.ReportException(ex);
                        console.WriteLine("Could not read manifest.");
                    }

                    if (tool.Manifest == null)
                    {
                        exitCode = 1;
                    }
                    else
                    {
                        if (tool.Manifest.Name != null)
                        {
                            console.WriteLine("Name:                          " + tool.Manifest.Name);
                        }

                        console.WriteLine("GUID:                          " + tool.Manifest.Guid.ToString());

                        if (tool.Manifest.DefaultHashMethod != null)
                        {
                            console.WriteLine("Default hash method:           " + tool.Manifest.DefaultHashMethod);
                        }

                        console.WriteLine("Date of creation:              " +
                                          (tool.Manifest.InceptionDateUtc.ToLocalTime()).ToString());

                        console.WriteLine("Date of last update:           " +
                                          (tool.Manifest.LastUpdateDateUtc.ToLocalTime()).ToString());

                        console.WriteLine("Last change of manifest info:  " +
                                          (tool.Manifest.ManifestInfoLastModifiedUtc.ToLocalTime()).ToString());

                        console.WriteLine("Date of last validation:       " +
                                          (tool.Manifest.LastValidateDateUtc.ToLocalTime()).ToString());

                        NumberFormatInfo nfi = new CultureInfo("en-US", false).NumberFormat;
                        nfi.NumberDecimalDigits = 0;


                        console.WriteLine("Total number of files:         " + tool.Manifest.CountFiles().ToString("N", nfi));
                        console.WriteLine("Total number of bytes:         " + tool.Manifest.CountBytes().ToString("N", nfi));
                        if (tool.Manifest.IgnoreList.Count > 0)
                        {
                            console.WriteLine("Ignoring these file patterns:");
                            foreach (String nextIgnore in tool.Manifest.IgnoreList)
                            {
                                console.WriteLine("   " + nextIgnore);
                            }
                        }
                    }

                    if (tool.Manifest.Description != null)
                    {
                        console.WriteLine();
                        console.WriteLine("Description: ");
                        console.WriteLine(tool.Manifest.Description);
                    }

                    break;

                case "help":
                    console.Write(Properties.Resources.RepositoryToolHelp);
                    break;

                case "":
                    break;
                }

                if (tool.Manifest != null)
                {
                    if (forceJSON)
                    {
                        tool.Manifest.UseJSON = true;
                    }

                    if (forceBinary)
                    {
                        tool.Manifest.UseJSON = false;
                    }
                }


                // Command-specific code to write the manifest, and possibly
                // delete some files if grooming.
                switch (commandArg)
                {
                case "create":
                case "update":
                case "edit":
                case "clear":
                    if (tool.Manifest != null)
                    {
                        if (repositoryName != null)
                        {
                            tool.Manifest.Name  = repositoryName;
                            manifestInfoChanged = true;
                        }

                        if (repositoryDescription != null)
                        {
                            tool.Manifest.Description = repositoryDescription;
                            manifestInfoChanged       = true;
                        }

                        if (hashMethod != null)
                        {
                            tool.Manifest.DefaultHashMethod = hashMethod;
                            manifestInfoChanged             = true;
                        }

                        if (ignoreList.Count > 0)
                        {
                            foreach (String nextIgnore in ignoreList)
                            {
                                if (tool.Manifest.IgnoreList.Contains(nextIgnore) == false)
                                {
                                    tool.Manifest.IgnoreList.Add(nextIgnore);
                                }
                            }
                            manifestInfoChanged = true;
                        }

                        if (dontIgnoreList.Count > 0)
                        {
                            foreach (String nextIgnore in dontIgnoreList)
                            {
                                if (tool.Manifest.IgnoreList.Contains(nextIgnore) == true)
                                {
                                    tool.Manifest.IgnoreList.Remove(nextIgnore);
                                }
                            }
                            manifestInfoChanged = true;
                        }

                        if (ignoreDefault == true)
                        {
                            tool.Manifest.IgnoreList.Clear();

                            Manifest defaultPrototype = tool.MakeManifest();
                            foreach (String nextIgnore in defaultPrototype.IgnoreList)
                            {
                                tool.Manifest.IgnoreList.Add(nextIgnore);
                            }
                            manifestInfoChanged = true;
                        }

                        if (manifestInfoChanged)
                        {
                            tool.Manifest.ManifestInfoLastModifiedUtc =
                                DateTime.UtcNow;
                        }

                        if (confirmUpdate)
                        {
                            console.Write("Update manifest? ");

                            bool writeManifest = console.CheckConfirm();
                            if (writeManifest == false)
                            {
                                break;
                            }
                        }

                        try
                        {
                            tool.Manifest.WriteManifestFile(manifestFilePath);
                        }
                        catch (Exception ex)
                        {
                            console.ReportException(ex);
                            console.WriteLine("Could not write manifest.");
                            exitCode = 1;
                        }
                    }
                    break;

                case "validate":
                    if (noTouch == false)
                    {
                        manifestForValidateDateUpdate.LastValidateDateUtc =
                            DateTime.UtcNow;

                        try
                        {
                            manifestForValidateDateUpdate.WriteManifestFile(
                                manifestFilePath);
                        }
                        catch (Exception ex)
                        {
                            console.ReportException(ex);
                            console.WriteLine("Could not write manifest.");
                            exitCode = 1;
                        }
                    }
                    break;

                case "groom":
                    if (tool.NewFilesForGroom.Count > 0)
                    {
                        bool doGroom = true;

                        if (force == false)
                        {
                            console.Write("Delete " +
                                          tool.NewFilesForGroom.Count.ToString() +
                                          " new files? ");

                            doGroom = console.CheckConfirm();
                        }

                        if (doGroom == true)
                        {
                            foreach (FileInfo delFile in tool.NewFilesForGroom)
                            {
                                delFile.Delete();
                            }
                        }
                    }

                    if (all == true && tool.IgnoredFilesForGroom.Count > 0)
                    {
                        bool doGroomAll = true;

                        if (force == false)
                        {
                            console.Write("Delete " +
                                          tool.IgnoredFilesForGroom.Count.ToString() +
                                          " ignored files? ");

                            doGroomAll = console.CheckConfirm();
                        }

                        if (doGroomAll == true)
                        {
                            foreach (FileInfo delFile in
                                     tool.IgnoredFilesForGroom)
                            {
                                delFile.Delete();
                            }
                        }
                    }

                    break;
                }

                if (recursive)
                {
                    console.WriteLine();
                }
            }

            if (time)
            {
                DateTime finishedTime = DateTime.Now;
                console.WriteLine("Finished: " + finishedTime.ToString());
                console.WriteLine("Duration: " + (finishedTime - startTime).ToString());
            }

            Environment.Exit(exitCode);
        }