public static IEnumerable <string> GetPatternsCollection(JObject rawProject, string projectDirectory, string projectFilePath, string propertyName, IEnumerable <string> defaultPatterns = null, bool literalPath = false) { defaultPatterns = defaultPatterns ?? Enumerable.Empty <string>(); try { JToken propertyNameToken; if (!rawProject.TryGetValue(propertyName, out propertyNameToken)) { return(IncludeContext.CreateCollection( projectDirectory, propertyName, defaultPatterns, literalPath)); } if (propertyNameToken.Type == JTokenType.String) { return(IncludeContext.CreateCollection( projectDirectory, propertyName, new string[] { propertyNameToken.Value <string>() }, literalPath)); } if (propertyNameToken.Type == JTokenType.Array) { var valuesInArray = propertyNameToken.Values <string>(); return(IncludeContext.CreateCollection( projectDirectory, propertyName, valuesInArray.Select(s => s.ToString()), literalPath)); } } catch (Exception ex) { throw FileFormatException.Create(ex, rawProject.Value <JToken>(propertyName), projectFilePath); } throw FileFormatException.Create("Value must be either string or array.", rawProject.Value <JToken>(propertyName), projectFilePath); }
public static IEnumerable <IncludeEntry> GetIncludeFiles( IncludeContext context, string targetBasePath, IList <DiagnosticMessage> diagnostics, bool flatten) { var sourceBasePath = PathUtility.EnsureTrailingSlash(context.SourceBasePath); targetBasePath = PathUtility.GetPathWithDirectorySeparator(targetBasePath); var includeEntries = new HashSet <IncludeEntry>(); // Check for illegal characters in target path if (string.IsNullOrEmpty(targetBasePath)) { diagnostics?.Add(new DiagnosticMessage( ErrorCodes.NU1003, $"Invalid '{context.Option}' section. The target '{targetBasePath}' is invalid, " + "targets must either be a file name or a directory suffixed with '/'. " + "The root directory of the package can be specified by using a single '/' character.", sourceBasePath, DiagnosticMessageSeverity.Error)); } else if (targetBasePath.Split(Path.DirectorySeparatorChar).Any(s => s.Equals(".") || s.Equals(".."))) { diagnostics?.Add(new DiagnosticMessage( ErrorCodes.NU1004, $"Invalid '{context.Option}' section. " + $"The target '{targetBasePath}' contains path-traversal characters ('.' or '..'). " + "These characters are not permitted in target paths.", sourceBasePath, DiagnosticMessageSeverity.Error)); } else { var files = GetIncludeFilesCore( sourceBasePath, context.IncludePatterns, context.ExcludePatterns, context.IncludeFiles, context.BuiltInsInclude, context.BuiltInsExclude).ToList(); var isFile = targetBasePath[targetBasePath.Length - 1] != Path.DirectorySeparatorChar; if (isFile && files.Count > 1) { // It's a file. But the glob matched multiple things diagnostics?.Add(new DiagnosticMessage( ErrorCodes.NU1005, $"Invalid '{ProjectFilesCollection.PackIncludePropertyName}' section. " + $"The target '{targetBasePath}' refers to a single file, but the corresponding pattern " + "produces multiple files. To mark the target as a directory, suffix it with '/'.", sourceBasePath, DiagnosticMessageSeverity.Error)); } else if (isFile && files.Count > 0) { var filePath = Path.GetFullPath( Path.Combine(sourceBasePath, PathUtility.GetPathWithDirectorySeparator(files[0].Path))); includeEntries.Add(new IncludeEntry(targetBasePath, filePath)); } else if (!isFile) { targetBasePath = targetBasePath.Substring(0, targetBasePath.Length - 1); foreach (var file in files) { var fullPath = Path.GetFullPath( Path.Combine(sourceBasePath, PathUtility.GetPathWithDirectorySeparator(file.Path))); string targetPath; if (flatten) { targetPath = Path.Combine(targetBasePath, PathUtility.GetPathWithDirectorySeparator(file.Stem)); } else { targetPath = Path.Combine( targetBasePath, PathUtility.GetRelativePathIgnoringDirectoryTraversals(sourceBasePath, fullPath)); } includeEntries.Add(new IncludeEntry(targetPath, fullPath)); } } if (context.IncludeFiles != null) { foreach (var literalRelativePath in context.IncludeFiles) { var fullPath = Path.GetFullPath(Path.Combine(sourceBasePath, literalRelativePath)); string targetPath; if (isFile) { targetPath = targetBasePath; } else if (flatten) { targetPath = Path.Combine(targetBasePath, Path.GetFileName(fullPath)); } else { targetPath = Path.Combine(targetBasePath, PathUtility.GetRelativePath(sourceBasePath, fullPath)); } includeEntries.Add(new IncludeEntry(targetPath, fullPath)); } } if (context.ExcludeFiles != null) { var literalExcludedFiles = new HashSet <string>( context.ExcludeFiles.Select(file => Path.GetFullPath(Path.Combine(sourceBasePath, file))), StringComparer.Ordinal); includeEntries.RemoveWhere(entry => literalExcludedFiles.Contains(entry.SourcePath)); } } if (context.Mappings != null) { // Finally add all the mappings foreach (var map in context.Mappings) { var targetPath = Path.Combine(targetBasePath, PathUtility.GetPathWithDirectorySeparator(map.Key)); foreach (var file in GetIncludeFiles(map.Value, targetPath, diagnostics, flatten: true)) { file.IsCustomTarget = true; // Prefer named targets over default ones includeEntries.RemoveWhere(f => string.Equals(f.SourcePath, file.SourcePath) && !f.IsCustomTarget); includeEntries.Add(file); } } } return(includeEntries); }
public static IEnumerable <IncludeEntry> GetIncludeFiles(IncludeContext context, string targetBasePath, IList <DiagnosticMessage> diagnostics) { return(GetIncludeFiles(context, targetBasePath, diagnostics, flatten: false)); }