Ejemplo n.º 1
0
        private IEnumerable <IList <RobocopyMetadata> > GetBuckets()
        {
            IList <RobocopyMetadata>          allSources = new List <RobocopyMetadata>();
            IList <IList <RobocopyMetadata> > allBuckets = new List <IList <RobocopyMetadata> >();

            foreach (ITaskItem item in Sources ?? Enumerable.Empty <ITaskItem>())
            {
                if (RobocopyMetadata.TryParse(item, Log, FileSystem.DirectoryExists, out RobocopyMetadata metadata))
                {
                    allSources.Add(metadata);
                }
            }

            int bucketNum = -1;
            int itemIndex = 0;

            while (allSources.Count > 0)
            {
                RobocopyMetadata first = allSources.First();
                allSources.RemoveAt(0);

                List <RobocopyMetadata> bucket = new List <RobocopyMetadata>
                {
                    first,
                };

                allBuckets.Add(bucket);

                if (ShowDiagnosticTrace)
                {
                    first.Dump(Log, ++bucketNum, 0);
                    itemIndex = 1;
                }

                for (int i = 0; i < allSources.Count; ++i)
                {
                    RobocopyMetadata item = allSources[i];
                    if (string.Equals(item.SourceFolder, first.SourceFolder, StringComparison.OrdinalIgnoreCase) &&
                        item.HasWildcardMatches == first.HasWildcardMatches &&
                        item.IsRecursive == first.IsRecursive)
                    {
                        bucket.Add(item);
                        allSources.RemoveAt(i);
                        --i;

                        if (ShowDiagnosticTrace)
                        {
                            item.Dump(Log, bucketNum, itemIndex++);
                        }
                    }
                }
            }

            return(allBuckets);
        }
Ejemplo n.º 2
0
        private void CopyItems(IList <RobocopyMetadata> items)
        {
            // buckets are grouped by source, IsRecursive, and HasWildcardMatches
            RobocopyMetadata first        = items.First();
            bool             isRecursive  = first.IsRecursive;
            bool             hasWildcards = first.HasWildcardMatches;
            DirectoryInfo    source       = new DirectoryInfo(first.SourceFolder);

            if (hasWildcards || isRecursive)
            {
                string match = GetMatchString(items);
                CopySearch(items, isRecursive, match, source, null);
            }
            else
            {
                // optimized path for direct file copies
                CopyItems(items, source);
            }
        }
Ejemplo n.º 3
0
        public static bool TryParse(ITaskItem item, TaskLoggingHelper log, Func <string, bool> directoryExists, out RobocopyMetadata metadata)
        {
            metadata = null;

            if (string.IsNullOrEmpty(item.GetMetadata("DestinationFolder")))
            {
                log.LogError("A value for \"DestinationFolder\" is required for the item \"{0}\".", item.ItemSpec);
                return(false);
            }

            // A common error - a property doesn't resolve and it references the drive root
            if (item.ItemSpec.StartsWith(@"\") && !item.ItemSpec.StartsWith(@"\\"))
            {
                log.LogError("The specified source location \"{0}\" cannot start with '\'", item.ItemSpec);
                return(false);
            }

            string source;

            try
            {
                source = Path.GetFullPath(item.ItemSpec).TrimEnd(Path.DirectorySeparatorChar);
            }
            catch (Exception e)
            {
                log.LogError("Failed to expand the path \"{0}\".", item.ItemSpec);
                log.LogErrorFromException(e);

                return(false);
            }

            metadata = new RobocopyMetadata
            {
                IsRecursive  = item.GetMetadataBoolean(nameof(IsRecursive)),
                VerifyExists = item.GetMetadataBoolean(nameof(VerifyExists)),
                AlwaysCopy   = item.GetMetadataBoolean(nameof(AlwaysCopy), defaultValue: false),
                OnlyNewer    = item.GetMetadataBoolean(nameof(OnlyNewer), defaultValue: false),
            };

            foreach (string destination in item.GetMetadata("DestinationFolder").Split(DestinationSplitter, StringSplitOptions.RemoveEmptyEntries))
            {
                if (destination.StartsWith(@"\") && !destination.StartsWith(@"\\"))
                {
                    log.LogError("The specified destination \"{0}\" cannot start with '{1}'", destination, Path.DirectorySeparatorChar);
                    return(false);
                }

                try
                {
                    metadata.DestinationFolders.Add(Path.GetFullPath(destination).TrimEnd(Path.DirectorySeparatorChar));
                }
                catch (Exception e)
                {
                    log.LogError("Failed to expand the path \"{0}\".", item.ItemSpec);
                    log.LogErrorFromException(e);

                    return(false);
                }
            }

            if (directoryExists(source))
            {
                metadata.SourceFolder = source;
                metadata.SplitItems("FileMatch", item);
                metadata.SplitItems("FileExclude", item);
                metadata.SplitItems("DirExclude", item);
                metadata.HasWildcardMatches = metadata.FileRegexMatches != null || metadata.FileRegexExcludes != null || metadata.DirRegexExcludes != null;
            }
            else
            {
                metadata.IsRecursive  = false;
                metadata.SourceFolder = Path.GetDirectoryName(source);
                metadata.FileMatches  = new[] { Path.GetFileName(source) };

                if (metadata.SourceFolder == null)
                {
                    return(false);
                }
            }

            return(true);
        }
Ejemplo n.º 4
0
        private void CopyFile(FileInfo sourceFile, FileInfo destFile, bool createDirs, RobocopyMetadata metadata)
        {
            if (createDirs)
            {
                CreateDirectoryWithRetries(destFile.DirectoryName);
            }

            for (int retry = 0; retry <= RetryCount; ++retry)
            {
                try
                {
                    if (metadata.ShouldCopy(FileSystem, sourceFile, destFile))
                    {
                        destFile               = FileSystem.CopyFile(sourceFile, destFile.FullName, true);
                        destFile.Attributes    = FileAttributes.Normal;
                        destFile.LastWriteTime = sourceFile.LastWriteTime;
                        Log.LogMessage(MessageImportance.Low, "Copied {0} to {1}", sourceFile.FullName, destFile.FullName);
                    }
                    else
                    {
                        Log.LogMessage(MessageImportance.Low, "Skipped copying {0} to {1}", sourceFile.FullName, destFile.FullName);
                    }

                    break;
                }
                catch (IOException e)
                {
                    LogCopyFailureAndSleep(retry, "Failed to copy {0} to {1}. {2}", sourceFile.FullName, destFile.FullName, e.Message);
                }
            }
        }