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);
        }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
 public static IEnumerable <IncludeEntry> GetIncludeFiles(IncludeContext context, string targetBasePath, IList <DiagnosticMessage> diagnostics)
 {
     return(GetIncludeFiles(context, targetBasePath, diagnostics, flatten: false));
 }