コード例 #1
0
        public void BuildAssetsUtils_GenerateContentFilesItem_CopyToOutput_Flatten()
        {
            // Arrange
            var path = "contentFiles/cs/net46/a/b/c.txt";
            var item = new LockFileContentFile(path);

            item.BuildAction  = BuildAction.None;
            item.CodeLanguage = "cs";
            item.CopyToOutput = true;
            item.OutputPath   = "c.txt";

            // Act
            var node     = BuildAssetsUtils.GenerateContentFilesItem(path, item, "a", "1.0.0");
            var metadata = node.Elements().ToDictionary(e => e.Name.LocalName, e => e.Value, StringComparer.OrdinalIgnoreCase);

            // Assert
            Assert.Equal("a", metadata["NuGetPackageId"]);
            Assert.Equal("1.0.0", metadata["NuGetPackageVersion"]);
            Assert.Equal("None", metadata["NuGetItemType"]);
            Assert.Equal("True", metadata["Private"]);
            Assert.Equal("c.txt", metadata["TargetPath"]);
            Assert.Equal("a/b/c.txt", metadata["Link"].Replace('\\', '/'));
            Assert.Equal("PreserveNewest", metadata["CopyToOutputDirectory"]);
            Assert.False(metadata.ContainsKey("DestinationSubDirectory"));
        }
        public AssetsFileTargetLibraryContentFile(LockFileContentFile file)
        {
            Requires.NotNull(file, nameof(file));

            BuildAction  = file.BuildAction.Value;
            CodeLanguage = file.CodeLanguage;
            CopyToOutput = file.CopyToOutput;
            OutputPath   = file.OutputPath;
            Path         = file.Path ?? ""; // Path should always be present so don't require consumers to null check. Not worth throwing if null though.
            PPOutputPath = file.PPOutputPath;
        }
コード例 #3
0
        public static XElement GenerateContentFilesItem(string path, LockFileContentFile item, string packageId, string packageVersion)
        {
            var entry = new XElement(Namespace + item.BuildAction.Value,
                                     new XAttribute("Include", path),
                                     new XAttribute("Condition", $"Exists('{path}')"),
                                     new XElement(Namespace + "NuGetPackageId", packageId),
                                     new XElement(Namespace + "NuGetPackageVersion", packageVersion),
                                     new XElement(Namespace + "NuGetItemType", item.BuildAction),
                                     new XElement(Namespace + "Pack", false));

            var privateFlag = false;

            if (item.CopyToOutput)
            {
                var outputPath = item.OutputPath ?? item.PPOutputPath;

                if (outputPath != null)
                {
                    // Convert / to \
                    outputPath = LockFileUtils.ToDirectorySeparator(outputPath);

                    privateFlag = true;
                    entry.Add(new XElement(Namespace + "CopyToOutputDirectory", "PreserveNewest"));

                    entry.Add(new XElement(Namespace + "TargetPath", outputPath));

                    var destinationSubDirectory = Path.GetDirectoryName(outputPath);

                    if (!string.IsNullOrEmpty(destinationSubDirectory))
                    {
                        entry.Add(new XElement(Namespace + "DestinationSubDirectory", destinationSubDirectory + Path.DirectorySeparatorChar));
                    }
                }
            }

            entry.Add(new XElement(Namespace + "Private", privateFlag.ToString()));

            // Remove contentFile/lang/tfm/ from start of the path
            var linkPath = string.Join(string.Empty + Path.DirectorySeparatorChar,
                                       item.Path.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries)
                                       .Skip(3)
                                       .ToArray());

            if (linkPath != null)
            {
                entry.Add(new XElement(Namespace + "Link", linkPath));
            }

            return(entry);
        }
コード例 #4
0
        public void BuildAssetsUtils_GenerateContentFilesItem_CompileAsset()
        {
            // Arrange
            var path = "contentFiles/cs/net46/test/test.cs";
            var item = new LockFileContentFile(path);

            item.BuildAction  = BuildAction.Compile;
            item.CodeLanguage = "cs";

            // Act
            var node     = BuildAssetsUtils.GenerateContentFilesItem(path, item, "a", "1.0.0");
            var metadata = node.Elements().ToDictionary(e => e.Name.LocalName, e => e.Value, StringComparer.OrdinalIgnoreCase);

            // Assert
            Assert.Equal("a", metadata["NuGetPackageId"]);
            Assert.Equal("1.0.0", metadata["NuGetPackageVersion"]);
            Assert.Equal("Compile", metadata["NuGetItemType"]);
            Assert.Equal("False", metadata["Private"]);
            Assert.Equal("test/test.cs", metadata["Link"].Replace('\\', '/'));
        }
コード例 #5
0
        /// <summary>
        /// Apply build actions from the nuspec to items from the contentFiles folder.
        /// </summary>
        internal static List <LockFileContentFile> GetContentFileGroup(
            NuspecReader nuspec,
            List <ContentItemGroup> contentFileGroups)
        {
            var results = new List <LockFileContentFile>(contentFileGroups.Count);
            var rootFolderPathLength = ContentFilesFolderName.Length;

            // Read the contentFiles section of the nuspec
            // Read the entries so that the bottom entry has priority
            var nuspecContentFiles = nuspec.GetContentFiles().ToList();

            // Initialize mappings
            var entryMappings    = new Dictionary <string, List <ContentFilesEntry> >(StringComparer.OrdinalIgnoreCase);
            var languageMappings = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase);

            foreach (var group in contentFileGroups)
            {
                var codeLanguage = group.Properties[ManagedCodeConventions.PropertyNames.CodeLanguage] as string;

                foreach (var item in group.Items)
                {
                    if (!entryMappings.ContainsKey(item.Path))
                    {
                        entryMappings.Add(item.Path, new List <ContentFilesEntry>());
                        languageMappings.Add(item.Path, codeLanguage);
                    }
                }
            }

            // Virtual root for file globbing
            var rootDirectory = new VirtualFileInfo(VirtualFileProvider.RootDir, isDirectory: true);

            // Apply all nuspec property mappings to the files returned by content model
            foreach (var filesEntry in nuspecContentFiles)
            {
                // this is validated in the nuspec reader
                Debug.Assert(filesEntry.Include != null, "invalid contentFiles entry");

                // Create a filesystem matcher for globbing patterns
                var matcher = new Matcher(StringComparison.OrdinalIgnoreCase);
                matcher.AddInclude(filesEntry.Include);

                if (filesEntry.Exclude != null)
                {
                    matcher.AddExclude(filesEntry.Exclude);
                }

                // Check each file against the patterns
                foreach (var file in entryMappings.Keys)
                {
                    // Remove contentFiles/ from the string
                    Debug.Assert(file.StartsWith(ContentFilesFolderName, StringComparison.OrdinalIgnoreCase),
                                 "invalid file path: " + file);

                    // All files should begin with the same root folder
                    if (file.Length > rootFolderPathLength)
                    {
                        var relativePath = file.Substring(rootFolderPathLength, file.Length - rootFolderPathLength);

                        // Check if the nuspec group include/exclude patterns apply to the file
                        var virtualDirectory = new VirtualFileProvider(new List <string>()
                        {
                            relativePath
                        });
                        var globbingDirectory = new FileProviderGlobbingDirectory(
                            virtualDirectory,
                            fileInfo: rootDirectory,
                            parent: null);

                        // Currently Matcher only returns the file name not the full path, each file must be
                        // check individually.
                        var matchResults = matcher.Execute(globbingDirectory);

                        if (matchResults.Files.Any())
                        {
                            entryMappings[file].Add(filesEntry);
                        }
                    }
                }
            }

            // Create lock file entries for each item in the contentFiles folder
            foreach (var file in entryMappings.Keys)
            {
                // defaults
                var action       = BuildAction.Parse(PackagingConstants.ContentFilesDefaultBuildAction);
                var copyToOutput = false;
                var flatten      = false;

                // _._ is needed for empty codeLanguage groups
                if (file.EndsWith(PackagingCoreConstants.ForwardSlashEmptyFolder, StringComparison.Ordinal))
                {
                    action = BuildAction.None;
                }
                else
                {
                    // apply each entry
                    // entries may not have all the attributes, if a value is null
                    // ignore it and continue using the previous value.
                    foreach (var filesEntry in entryMappings[file])
                    {
                        if (!string.IsNullOrEmpty(filesEntry.BuildAction))
                        {
                            action = BuildAction.Parse(filesEntry.BuildAction);
                        }

                        if (filesEntry.CopyToOutput.HasValue)
                        {
                            copyToOutput = filesEntry.CopyToOutput.Value;
                        }

                        if (filesEntry.Flatten.HasValue)
                        {
                            flatten = filesEntry.Flatten.Value;
                        }
                    }
                }

                // Add attributes to the lock file item
                var lockFileItem = new LockFileContentFile(file);

                // Add the language from the directory path
                lockFileItem.CodeLanguage = languageMappings[file].ToLowerInvariant();

                if (!action.IsKnown)
                {
                    // Throw an error containing the package identity, invalid action, and file where it occurred.
                    var message = string.Format(CultureInfo.CurrentCulture, Strings.Error_UnknownBuildAction, nuspec.GetIdentity(), action, file);
                    throw new PackagingException(message);
                }

                lockFileItem.BuildAction  = action;
                lockFileItem.CopyToOutput = copyToOutput;

                // Check if this is a .pp transform. If the filename is ".pp" ignore it since it will
                // have no file name after the transform.
                var isPP = lockFileItem.Path.EndsWith(".pp", StringComparison.OrdinalIgnoreCase) &&
                           !string.IsNullOrEmpty(Path.GetFileNameWithoutExtension(lockFileItem.Path));

                if (copyToOutput)
                {
                    string destination = null;

                    if (flatten)
                    {
                        destination = Path.GetFileName(lockFileItem.Path);
                    }
                    else
                    {
                        // Find path relative to the TxM
                        // Ex: contentFiles/cs/net45/config/config.xml -> config/config.xml
                        destination = GetContentFileFolderRelativeToFramework(file);
                    }

                    if (isPP)
                    {
                        // Remove .pp from the output file path
                        destination = destination.Substring(0, destination.Length - 3);
                    }

                    lockFileItem.OutputPath = destination;
                }

                // Add the pp transform file if one exists
                if (isPP)
                {
                    var destination = lockFileItem.Path.Substring(0, lockFileItem.Path.Length - 3);
                    destination = GetContentFileFolderRelativeToFramework(destination);

                    lockFileItem.PPOutputPath = destination;
                }

                results.Add(lockFileItem);
            }

            return(results);
        }