<commit_before>﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Xml;
using Cake.Core;

namespace Cake.Common.Tools.NuGet.Pack
{
    internal static class NuspecTransformer
    {
        private static readonly Dictionary<string, Func<NuGetPackSettings, string>> _mappings;
        private const string NuSpecXsd = "http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd";

        static NuspecTransformer()
        {
            _mappings = new Dictionary<string, Func<NuGetPackSettings, string>>
            {
                { "id", settings => ToString(settings.Id) },
                { "version", settings => ToString(settings.Version) },
                { "title", settings => ToString(settings.Title) },
                { "authors", settings => ToCommaSeparatedString(settings.Authors) },
                { "owners", settings => ToCommaSeparatedString(settings.Owners) },
                { "description", settings => ToString(settings.Description) },
                { "summary", settings => ToString(settings.Summary) },
                { "licenseUrl", settings => ToString(settings.LicenseUrl) },
                { "projectUrl", settings => ToString(settings.ProjectUrl) },
                { "iconUrl", settings => ToString(settings.IconUrl) },
                { "requireLicenseAcceptance", settings => ToString(settings.RequireLicenseAcceptance) },
                { "copyright", settings => ToString(settings.Copyright) },
                { "releaseNotes", settings => ToMultiLineString(settings.ReleaseNotes) },
                { "tags", settings => ToSpaceSeparatedString(settings.Tags) }
            };
        }

        public static void Transform(XmlDocument document, NuGetPackSettings settings)
        {
            // Create the namespace manager.
            var namespaceManager = new XmlNamespaceManager(document.NameTable);
            namespaceManager.AddNamespace("nu", NuSpecXsd);

            foreach (var elementName in _mappings.Keys)
            {
                var content = _mappings[elementName](settings);
                if (content != null)
                {
                    // Replace the node content.
                    var node = FindOrCreateElement(document, namespaceManager, elementName);
                    node.InnerText = content;
                }
            }

            if (settings.Files != null && settings.Files.Count > 0)
            {
                var filesPath = string.Format(CultureInfo.InvariantCulture, "/package//*[local-name()='files']");
                var filesElement = document.SelectSingleNode(filesPath, namespaceManager);
                if (filesElement == null)
                {
                    // Get the package element.
                    var package = GetPackageElement(document);
                    filesElement = document.CreateAndAppendElement(package, "files");
                }

                // Add the files
                filesElement.RemoveAll();
                foreach (var file in settings.Files)
                {
                    var fileElement = document.CreateAndAppendElement(filesElement, "file");
                    fileElement.AddAttributeIfSpecified(file.Source, "src");
                    fileElement.AddAttributeIfSpecified(file.Exclude, "exclude");
                    fileElement.AddAttributeIfSpecified(file.Target, "target");
                }
            }
        }

        private static XmlNode GetPackageElement(XmlDocument document)
        {
            var package = document.SelectSingleNode("/package");
            if (package == null)
            {
                throw new CakeException("Nuspec file is missing package root.");
            }
            return package;
        }

        private static XmlNode FindOrCreateElement(XmlDocument document, XmlNamespaceManager ns, string name)
        {
            var path = string.Format(CultureInfo.InvariantCulture, "/package//*[local-name()='metadata']//*[local-name()='{0}']", name);
            var node = document.SelectSingleNode(path, ns);
            if (node == null)
            {
                var parent = document.SelectSingleNode("/package//*[local-name()='metadata']", ns);
                if (parent == null)
                {<commit_msg>Adjusted nuspec xpaths, Fixes #198<commit_after>﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Xml;
using Cake.Core;

namespace Cake.Common.Tools.NuGet.Pack
{
    internal static class NuspecTransformer
    {
        private static readonly Dictionary<string, Func<NuGetPackSettings, string>> _mappings;
        private const string NuSpecXsd = "http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd";

        static NuspecTransformer()
        {
            _mappings = new Dictionary<string, Func<NuGetPackSettings, string>>
            {
                { "id", settings => ToString(settings.Id) },
                { "version", settings => ToString(settings.Version) },
                { "title", settings => ToString(settings.Title) },
                { "authors", settings => ToCommaSeparatedString(settings.Authors) },
                { "owners", settings => ToCommaSeparatedString(settings.Owners) },
                { "description", settings => ToString(settings.Description) },
                { "summary", settings => ToString(settings.Summary) },
                { "licenseUrl", settings => ToString(settings.LicenseUrl) },
                { "projectUrl", settings => ToString(settings.ProjectUrl) },
                { "iconUrl", settings => ToString(settings.IconUrl) },
                { "requireLicenseAcceptance", settings => ToString(settings.RequireLicenseAcceptance) },
                { "copyright", settings => ToString(settings.Copyright) },
                { "releaseNotes", settings => ToMultiLineString(settings.ReleaseNotes) },
                { "tags", settings => ToSpaceSeparatedString(settings.Tags) }
            };
        }

        public static void Transform(XmlDocument document, NuGetPackSettings settings)
        {
            // Create the namespace manager.
            var namespaceManager = new XmlNamespaceManager(document.NameTable);
            namespaceManager.AddNamespace("nu", NuSpecXsd);

            foreach (var elementName in _mappings.Keys)
            {
                var content = _mappings[elementName](settings);
                if (content != null)
                {
                    // Replace the node content.
                    var node = FindOrCreateElement(document, namespaceManager, elementName);
                    node.InnerText = content;
                }
            }

            if (settings.Files != null && settings.Files.Count > 0)
            {
                var filesPath = string.Format(CultureInfo.InvariantCulture, "//*[local-name()='package']//*[local-name()='files']");
                var filesElement = document.SelectSingleNode(filesPath, namespaceManager);
                if (filesElement == null)
                {
                    // Get the package element.
                    var package = GetPackageElement(document);
                    filesElement = document.CreateAndAppendElement(package, "files");
                }

                // Add the files
                filesElement.RemoveAll();
                foreach (var file in settings.Files)
                {
                    var fileElement = document.CreateAndAppendElement(filesElement, "file");
                    fileElement.AddAttributeIfSpecified(file.Source, "src");
                    fileElement.AddAttributeIfSpecified(file.Exclude, "exclude");
                    fileElement.AddAttributeIfSpecified(file.Target, "target");
                }
            }
        }

        private static XmlNode GetPackageElement(XmlDocument document)
        {
            var package = document.SelectSingleNode("//*[local-name()='package']");
            if (package == null)
            {
                throw new CakeException("Nuspec file is missing package root.");
            }
            return package;
        }

        private static XmlNode FindOrCreateElement(XmlDocument document, XmlNamespaceManager ns, string name)
        {
            var path = string.Format(CultureInfo.InvariantCulture, "//*[local-name()='package']//*[local-name()='metadata']//*[local-name()='{0}']", name);
            var node = document.SelectSingleNode(path, ns);
            if (node == null)
            {
                var parent = document.SelectSingleNode("//*[local-name()='package']//*[local-name()='metadata']", ns);
                if (parent == null)
                {
{'fraction_non_alphanumeric': 0.11076782240530954, 'fraction_numerical': 0.0021741618034100013, 'mean_word_length': 1.9497131285858926, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 41, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6982717', 'n_tokens_mistral': 2192, 'n_tokens_neox': 2037, 'n_words': 428}