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); }