diff --git a/.editorconfig b/.editorconfig index 039c4069..8c2e20b4 100644 --- a/.editorconfig +++ b/.editorconfig @@ -13,7 +13,7 @@ indent_style = space indent_size = 4 # Xml project files -[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj,msbuildproj}] +[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj,msbuildproj,nuproj}] indent_size = 2 # Xml config files @@ -23,6 +23,7 @@ indent_size = 2 # YAML files [*.{yaml,yml}] indent_size = 2 +indent_style = space # JSON files [*.json] diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 937df914..ebb70b90 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,18 +1,38 @@ name: build on: push +env: + DOTNET_NOLOGO: true + MSBUILDDISABLENODEREUSE: 1 + jobs: build: runs-on: windows-latest steps: - uses: actions/checkout@v2 + - uses: actions/setup-dotnet@v1 + with: + dotnet-version: 5.0.100-rc.1.20452.10 + - uses: actions/setup-dotnet@v1 + with: + dotnet-version: 2.1.x - uses: actions/setup-dotnet@v1 with: dotnet-version: 3.1.x - run: dotnet tool update -g dotnet-vs + - name: set version + run: echo "::set-env name=VERSION_SUFFIX::$(git name-rev --name-only --refs=refs/heads/* HEAD).$($env:GITHUB_RUN_NUMBER)" - run: echo "::set-env name=MSB::$(vs where preview --prop=InstallationPath)" - run: vs install preview --quiet +Microsoft.VisualStudio.Component.ManagedDesktop.Core +Microsoft.NetCore.Component.DevelopmentTools if: env.MSB == '' - run: echo "::add-path::$(vs where preview --prop=InstallationPath)\MSBuild\Current\Bin" - - run: msbuild -r - - run: msbuild -t:test + - name: build + run: msbuild -r -p:versionsuffix=$($env:VERSION_SUFFIX) + - name: test + run: msbuild -t:test + - name: pack + run: msbuild -t:pack -p:nobuild=true -p:versionsuffix=$($env:VERSION_SUFFIX) + - name: sleet + run: | + dotnet tool install -g --version 2.3.33 sleet + sleet push bin --config none -f --verbose -p "SLEET_FEED_CONTAINER=nuget" -p "SLEET_FEED_CONNECTIONSTRING=${{ secrets.SLEET_CONNECTION }}" -p "SLEET_FEED_TYPE=azure" \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..c5873bb6 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,38 @@ +name: release +on: + release: + types: [created] + +env: + DOTNET_NOLOGO: true + MSBUILDDISABLENODEREUSE: 1 + +jobs: + build: + runs-on: windows-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-dotnet@v1 + with: + dotnet-version: 5.0.100-rc.1.20452.10 + - uses: actions/setup-dotnet@v1 + with: + dotnet-version: 2.1.x + - uses: actions/setup-dotnet@v1 + with: + dotnet-version: 3.1.x + - run: dotnet tool update -g dotnet-vs + - name: set version + run: echo "::set-env name=VERSION::${GITHUB_REF#refs/*/v} + - run: echo "::set-env name=MSB::$(vs where preview --prop=InstallationPath)" + - run: vs install preview --quiet +Microsoft.VisualStudio.Component.ManagedDesktop.Core +Microsoft.NetCore.Component.DevelopmentTools + if: env.MSB == '' + - run: echo "::add-path::$(vs where preview --prop=InstallationPath)\MSBuild\Current\Bin" + - name: build + run: msbuild -r -p:version=$($env:VERSION) + - name: test + run: msbuild -t:test + - name: pack + run: msbuild -t:pack -p:nobuild=true -p:version=$($env:VERSION) + - name: push + run: dotnet nuget push ./bin/**/*.nupkg -s https://api.nuget.org/v3/index.json -k ${{secrets.NUGET_API_KEY}} --skip-duplicate \ No newline at end of file diff --git a/NuGetizer.sln b/NuGetizer.sln index 2a775ff1..450f9b60 100644 --- a/NuGetizer.sln +++ b/NuGetizer.sln @@ -11,15 +11,19 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution src\Directory.Build.props = src\Directory.Build.props src\Directory.Build.targets = src\Directory.Build.targets src\NuGet.Config = src\NuGet.Config + README.md = README.md + .github\workflows\release.yml = .github\workflows\release.yml EndProjectSection EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NuGet.Build.Packaging.Tasks", "src\Build\NuGet.Build.Packaging.Tasks\NuGet.Build.Packaging.Tasks.csproj", "{57F59BF6-9272-4B66-98A1-334B3FDA5721}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NuGetizer.Tasks", "src\NuGetizer.Tasks\NuGetizer.Tasks.csproj", "{57F59BF6-9272-4B66-98A1-334B3FDA5721}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NuGet.Build.Packaging.Tests", "src\Build\NuGet.Build.Packaging.Tests\NuGet.Build.Packaging.Tests.csproj", "{50032C88-1B52-4DB1-BFC5-6BADE2CC58CC}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NuGetizer.Tests", "src\NuGetizer.Tests\NuGetizer.Tests.csproj", "{50032C88-1B52-4DB1-BFC5-6BADE2CC58CC}" ProjectSection(ProjectDependencies) = postProject {57F59BF6-9272-4B66-98A1-334B3FDA5721} = {57F59BF6-9272-4B66-98A1-334B3FDA5721} EndProjectSection EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnet-nugetize", "src\dotnet-nugetize\dotnet-nugetize.csproj", "{53B47B9E-212F-420D-9E9A-68EC3B44D39E}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -34,6 +38,10 @@ Global {50032C88-1B52-4DB1-BFC5-6BADE2CC58CC}.Debug|Any CPU.Build.0 = Debug|Any CPU {50032C88-1B52-4DB1-BFC5-6BADE2CC58CC}.Release|Any CPU.ActiveCfg = Release|Any CPU {50032C88-1B52-4DB1-BFC5-6BADE2CC58CC}.Release|Any CPU.Build.0 = Release|Any CPU + {53B47B9E-212F-420D-9E9A-68EC3B44D39E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {53B47B9E-212F-420D-9E9A-68EC3B44D39E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {53B47B9E-212F-420D-9E9A-68EC3B44D39E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {53B47B9E-212F-420D-9E9A-68EC3B44D39E}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/README.md b/README.md index 7bcf3c9a..8e47bdbb 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,140 @@ -![Nugetizer-3000 Logo](https://raw.githubusercontent.com/NuGet/NuGet.Build.Packaging/master/Nugetizer-3000.png) +![icon](img/nugetizer-32.png) nugetizer +=== -# NuGetizer 3000 - -For the original design and intended goals and features, check out the [spec](https://github.com/NuGet/Home/wiki/NuGetizer-3000). +Simple, flexible, intuitive and powerful NuGet packaging. ## Why -I got sick of trying to modify the gazillion properties, weird item, property and target names and more from the built-in SDK Pack targets, and still never quite achieving the simple goals I had in mind. Also, the original clean and clear design from [NuGet.Build.Packaging](https://github.com/NuGet/NuGet.Build.Packaging) never got traction or support from the NuGet team, so the weirdness kept evolving in ever more incomprehensible ways ¯\_(ツ)_/¯. +The .NET SDK has built-in support for packing. The design of its targets, property +and item names it not very consistent, however. When packing non-trivial solutions +with multiple projects, it's quite hard to actually get it to pack exactly the +way you want it to. + +An [alternative clean and clear design](https://github.com/NuGet/Home/wiki/NuGetizer-3000) +was proposed and I got to implement the initial spec, but it never got traction +with the NuGet team. + +## What + +With the learnings from years of building and shipping packages of different +levels of complexity, as well as significant use of the SDK Pack functionality +and its various extension points, NuGetizer takes a fresh look and exposes a +clean set of primitives so that you never have to create `.nuspec` files again. + +All the [built-in properties](https://docs.microsoft.com/en-us/nuget/reference/msbuild-targets#pack-target) +are supported. + +A key difference is that adding arbitrary content to the package is supported +with the first-class `PackageFile` item for absolute control of the package +contents. + +```xml + + + +``` + +Another key design choice is that any package content inference should be trivial +to turn off wholesale in case the heuristics don't do exactly what you need. Just set +`EnablePackInference=false` and you will only get explicit `PackageFile` items +in your package. + +### Package Inference + +Package inference provides some built-in heuristics for common scenarios so you +don't have to customize the packing much. It works by transforming various built-in +items into corresponding `PackageFile` items, much as if you had added them by +hand. + +Inference can be turned off for specific items by just adding `Pack="false"` +item metadata. + +The default transformations are: + +| Source | Inferred | Notes | +| --------------------------------------------------------------- | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ | +| Project build output | `` | Kind defaults to `Lib`. Includes .xml and .pdb if they are generated. (1) | +| `` | `` | `PrivateAssets=all` is present, it's not added as dependency. (2) | +| `` | `` | Regular content that's not part of the build output | +| `` | `` | `` | | +| `` | ` dotnet tool install -g dotnet-nugetize +``` + +After installation, you can just run `nugetize` from the project directory to quickly get a report of the package that would be generated. This is done in the fastest possible way without compromising your customizations to the build process. They way this is achieved is by a combination of a simulated [design-time build](https://github.com/dotnet/project-system/blob/master/docs/design-time-builds.md) that skips the compiler invocation and avoids the output file copying entirely, and built-in support in NuGetizer to emit the entire contents of the package as MSBuild items with full metadata, that the tool can use to render an accurate report that contains exactly the same information that would be used to actually emit the final `.nupkg` without actually emitting it. -So, on to forking and shipping for real the simplified, understandable way of packing your libraries. +Here's a sample output screenshot: +![nugetize screenshot](img/dotnet-nugetize.png) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index d4c2a832..4c1b38aa 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -1,8 +1,19 @@ pool: vmImage: 'windows-2019' + +variables: + - name: DOTNET_NOLOGO + value: 'true' + steps: - checkout: self +- task: UseDotNet@2 + inputs: + packageType: sdk + version: 5.0.100-rc.1.20452.10 + performMultiLevelLookup: true + - task: UseDotNet@2 inputs: packageType: sdk @@ -17,7 +28,12 @@ steps: condition: eq(variables['MSB'], '') - pwsh: echo "##vso[task.prependpath]$(vs where preview --prop=InstallationPath)\MSBuild\Current\Bin" displayName: prepend MSBuild to %PATH% -- script: msbuild -r +- script: msbuild -r -bl:$(System.DefaultWorkingDirectory)/logs/build.binlog displayName: msbuild -r - script: msbuild -t:test - displayName: msbuild -t:test \ No newline at end of file + displayName: msbuild -t:test +- publish: $(System.DefaultWorkingDirectory)/logs + artifact: logs + condition: always() +- script: msbuild -t:Pack -p:PackOnBuild=true + displayName: msbuild -t:pack \ No newline at end of file diff --git a/img/dotnet-nugetize-xplat.png b/img/dotnet-nugetize-xplat.png new file mode 100644 index 00000000..dabb14f8 Binary files /dev/null and b/img/dotnet-nugetize-xplat.png differ diff --git a/img/dotnet-nugetize.png b/img/dotnet-nugetize.png new file mode 100644 index 00000000..763ed951 Binary files /dev/null and b/img/dotnet-nugetize.png differ diff --git a/img/nugetizer-100.png b/img/nugetizer-100.png new file mode 100644 index 00000000..4b05db41 Binary files /dev/null and b/img/nugetizer-100.png differ diff --git a/img/nugetizer-128.png b/img/nugetizer-128.png new file mode 100644 index 00000000..96bf2953 Binary files /dev/null and b/img/nugetizer-128.png differ diff --git a/img/nugetizer-256.png b/img/nugetizer-256.png new file mode 100644 index 00000000..4b2c74c2 Binary files /dev/null and b/img/nugetizer-256.png differ diff --git a/img/nugetizer-32.png b/img/nugetizer-32.png new file mode 100644 index 00000000..2853eea5 Binary files /dev/null and b/img/nugetizer-32.png differ diff --git a/img/nugetizer-512.png b/img/nugetizer-512.png new file mode 100644 index 00000000..463698b8 Binary files /dev/null and b/img/nugetizer-512.png differ diff --git a/img/nugetizer.svg b/img/nugetizer.svg new file mode 100644 index 00000000..9e8ddbac --- /dev/null +++ b/img/nugetizer.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tasks/AssignPackagePath.cs b/src/Build/NuGet.Build.Packaging.Tasks/AssignPackagePath.cs deleted file mode 100644 index 217139df..00000000 --- a/src/Build/NuGet.Build.Packaging.Tasks/AssignPackagePath.cs +++ /dev/null @@ -1,192 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; -using static ThisAssembly.Strings; -using NuGet.Packaging; - -namespace NuGet.Build.Packaging.Tasks -{ - /// - /// Ensures all files have the PackagePath metadata. - /// If the PackagePath was not explicitly specified, - /// determine one from the project relative path and - /// the TargetFramework and Kind metadata, and set it - /// on the projected item. - /// - public class AssignPackagePath : Task - { - public string IsPackaging { get; set; } - - [Required] - public ITaskItem[] Files { get; set; } - - [Required] - public ITaskItem[] Kinds { get; set; } - - [Output] - public ITaskItem[] AssignedFiles { get; set; } - - public override bool Execute() - { - var kindMap = Kinds.ToDictionary( - kind => kind.ItemSpec, - StringComparer.OrdinalIgnoreCase); - - AssignedFiles = Files.Select(file => EnsurePackagePath(file, kindMap)).ToArray(); - - return !Log.HasLoggedErrors; - } - - ITaskItem EnsurePackagePath(ITaskItem file, IDictionary kindMap) - { - var output = new TaskItem(file); - - // Map the Kind to a target top-level directory. - var kind = file.GetMetadata("Kind"); - var packageFolder = ""; - var frameworkSpecific = false; - if (!string.IsNullOrEmpty(kind) && kindMap.TryGetValue(kind, out var kindItem)) - { - packageFolder = kindItem.GetMetadata(MetadataName.PackageFolder); - bool.TryParse(kindItem.GetMetadata(MetadataName.FrameworkSpecific), out frameworkSpecific); - } - else if (!string.IsNullOrEmpty(kind)) - { - // By convention, we just turn the first letter of Kind to lowercase and assume that - // to be a valid folder kind. - packageFolder = char.IsLower(kind[0]) ? kind : - char.ToLower(kind[0]).ToString() + kind.Substring(1); - } - - // Specific PackageFile can always override Kind-inferred FrameworkSpecific value. - if (bool.TryParse(file.GetMetadata(MetadataName.FrameworkSpecific), out var frameworkSpecificOverride)) - frameworkSpecific = frameworkSpecificOverride; - - output.SetMetadata(MetadataName.PackageFolder, packageFolder); - - // NOTE: a declared TargetFramework metadata trumps TargetFrameworkMoniker, - // which is defaulted to that of the project being built. - var targetFramework = output.GetMetadata(MetadataName.TargetFramework); - if (string.IsNullOrEmpty(targetFramework) && frameworkSpecific) - { - var frameworkMoniker = file.GetTargetFrameworkMoniker(); - targetFramework = frameworkMoniker.GetShortFrameworkName() ?? ""; - // At this point we have the correct target framework - output.SetMetadata(MetadataName.TargetFramework, targetFramework); - } - - // If PackagePath already specified, we're done. - if (!string.IsNullOrEmpty(file.GetMetadata("PackagePath"))) - return output; - - // If a packaging project is requesting the package path assignment, - // perform it regardless of whether there is a PackageId on the items, - // since they all need to be assigned at this point. - bool isPackaging = false; - isPackaging = !string.IsNullOrEmpty(IsPackaging) && - bool.TryParse(IsPackaging, out isPackaging) && - isPackaging; - - // If no PackageId specified, we let referencing projects define the package path - // as it will be included in their package. - // NOTE: if we don't do this, the package path of a project would be determined - // by the declaring project's TFM, rather than the referencing one, and this - // would be incorrect (i.e. a referenced PCL project that does not build a - // nuget itself, would end up in the PCL lib folder rather than the referencing - // package's lib folder for its own TFM, i.e. 'lib\net45'). - if (string.IsNullOrEmpty(file.GetMetadata("PackageId")) && !isPackaging) - return output; - - // If we got this far but there wasn't a Kind to process, it's an error. - if (string.IsNullOrEmpty(kind)) - { - Log.LogErrorCode(nameof(ErrorCode.NG0010), ErrorCode.NG0010(file.ItemSpec)); - // We return the file anyway, since the task result will still be false. - return file; - } - - // If the kind is known but it isn't mapped to a folder inside the package, we're done. - // Special-case None kind since that means 'leave it wherever it lands' ;) - if (string.IsNullOrEmpty(packageFolder) && kind != PackageItemKind.None) - return output; - - // Special case for contentFiles, since they can also provide a codeLanguage metadata - if (packageFolder == PackagingConstants.Folders.ContentFiles) - { - if (file.GetMetadata("TargetPath").StartsWith(packageFolder, StringComparison.OrdinalIgnoreCase)) - { - Log.LogErrorCode(nameof(ErrorCode.NG0013), ErrorCode.NG0013(file.GetMetadata("TargetPath"))); - // We return the file anyway, since the task result will still be false. - return file; - } - - // See https://docs.nuget.org/create/nuspec-reference#contentfiles-with-visual-studio-2015-update-1-and-later - var codeLanguage = file.GetMetadata(MetadataName.ContentFile.CodeLanguage); - if (string.IsNullOrEmpty(codeLanguage)) - { - codeLanguage = PackagingConstants.AnyFramework; - output.SetMetadata(MetadataName.ContentFile.CodeLanguage, codeLanguage); - } - - packageFolder = Path.Combine(packageFolder, codeLanguage); - - // And they also cannot have an empty framework, at most, it will be "any" - if (string.IsNullOrEmpty(targetFramework)) - targetFramework = PackagingConstants.AnyFramework; - - // Once TF is defaulted, a content file is actually always framework-specific, - // although the framework may be 'any'. - frameworkSpecific = true; - - // At this point we have the correct target framework for a content file, so persist it. - output.SetMetadata(MetadataName.TargetFramework, targetFramework); - } - - var targetPath = file.GetMetadata("TargetPath"); - // Linked files already have the desired target path specified by the user - if (string.IsNullOrEmpty(targetPath)) - targetPath = file.GetMetadata("Link"); - - // NOTE: TargetPath allows a framework-specific file to still specify its relative - // location without hardcoding the target framework (useful for multi-targetting and - // P2P references). - if (string.IsNullOrEmpty(targetPath)) - { - targetPath = string.IsNullOrEmpty(packageFolder) ? - Path.Combine(file.GetMetadata("RelativeDir"), file.GetMetadata("FileName") + file.GetMetadata("Extension")) : - // Well-known folders only get root-level files by default. Can be overriden with PackagePath or TargetPath - // explicitly, of course - file.GetMetadata("FileName") + file.GetMetadata("Extension"); - } - - if (!string.IsNullOrEmpty(packageFolder) && - targetPath.StartsWith(packageFolder + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase)) - { - // Avoid duplicating already determined package folder in package path later on. - targetPath = targetPath.Substring(packageFolder.Length + 1); - } - - // At this point we have the correct calculated target path, so persist it for inspection if necessary. - output.SetMetadata("TargetPath", targetPath); - - // If we have no known package folder, files go to their RelativeDir location. - // This allows custom packaging paths such as "workbooks", "docs" or whatever, which aren't prohibited by - // the format. - var packagePath = string.IsNullOrEmpty(packageFolder) ? - // File goes to the determined target path (or the root of the package), such as a readme.txt - targetPath : - frameworkSpecific ? - // Otherwise, it goes to a framework-specific folder. - Path.Combine(new[] { packageFolder, targetFramework }.Concat(targetPath.Split(Path.DirectorySeparatorChar)).ToArray()) : - // Except if frameworkSpecific is false, such as for build, tools, runtimes - Path.Combine(new[] { packageFolder }.Concat(targetPath.Split(Path.DirectorySeparatorChar)).ToArray()); - - output.SetMetadata(MetadataName.PackagePath, packagePath); - - return output; - } - } -} diff --git a/src/Build/NuGet.Build.Packaging.Tasks/CreatePackage.cs b/src/Build/NuGet.Build.Packaging.Tasks/CreatePackage.cs deleted file mode 100644 index a501e44b..00000000 --- a/src/Build/NuGet.Build.Packaging.Tasks/CreatePackage.cs +++ /dev/null @@ -1,391 +0,0 @@ -using System; -using System.Linq; -using System.IO; -using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; -using NuGet.Versioning; -using NuGet.Frameworks; -using NuGet.Packaging.Core; -using NuGet.Packaging; -using System.Collections.Generic; -using static ThisAssembly.Strings; -using System.Security.Cryptography; - -namespace NuGet.Build.Packaging.Tasks -{ - public class CreatePackage : Task - { - [Required] - public ITaskItem Manifest { get; set; } - - [Required] - public ITaskItem[] Contents { get; set; } - - [Required] - public string TargetPath { get; set; } - - public string NuspecFile { get; set; } - - [Output] - public ITaskItem OutputPackage { get; set; } - - public override bool Execute() - { - try - { - using (var stream = File.Create(TargetPath)) - { - BuildPackage(stream); - } - - OutputPackage = new TaskItem(TargetPath); - Manifest.CopyMetadataTo(OutputPackage); - - return !Log.HasLoggedErrors; - } - catch (Exception ex) - { - Log.LogErrorFromException(ex); - return false; - } - } - - // Implementation for testing to avoid I/O - public Manifest Execute(Stream output) - { - BuildPackage(output); - - output.Seek(0, SeekOrigin.Begin); - using (var reader = new PackageArchiveReader(output)) - { - return reader.GetManifest(); - } - } - - public Manifest CreateManifest() - { - var metadata = new ManifestMetadata(); - - metadata.Id = Manifest.GetMetadata("Id"); - metadata.Version = NuGetVersion.Parse(Manifest.GetMetadata(MetadataName.Version)); - metadata.DevelopmentDependency = Manifest.GetBoolean("DevelopmentDependency"); - - metadata.Title = Manifest.GetMetadata("Title"); - metadata.Description = Manifest.GetMetadata("Description"); - metadata.Summary = Manifest.GetMetadata("Summary"); - metadata.Language = Manifest.GetMetadata("Language"); - - metadata.Copyright = Manifest.GetMetadata("Copyright"); - metadata.RequireLicenseAcceptance = Manifest.GetBoolean("RequireLicenseAcceptance"); - - if (!string.IsNullOrEmpty(Manifest.GetMetadata("Authors"))) - metadata.Authors = Manifest.GetMetadata("Authors").Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); - if (!string.IsNullOrEmpty(Manifest.GetMetadata("Owners"))) - metadata.Owners = Manifest.GetMetadata("Owners").Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); - - if (!string.IsNullOrEmpty(Manifest.GetMetadata("LicenseUrl"))) - metadata.SetLicenseUrl(Manifest.GetMetadata("LicenseUrl")); - if (!string.IsNullOrEmpty(Manifest.GetMetadata("ProjectUrl"))) - metadata.SetProjectUrl(Manifest.GetMetadata("ProjectUrl")); - if (!string.IsNullOrEmpty(Manifest.GetMetadata("IconUrl"))) - metadata.SetIconUrl(Manifest.GetMetadata("IconUrl")); - - metadata.ReleaseNotes = Manifest.GetMetadata("ReleaseNotes"); - metadata.Tags = Manifest.GetMetadata("Tags"); - metadata.MinClientVersionString = Manifest.GetMetadata("MinClientVersion"); - metadata.PackageTypes = ParsePackageTypes(Manifest.GetMetadata("PackageTypes")); - - var manifest = new Manifest(metadata); - - AddDependencies(manifest); - AddFiles(manifest); - AddFrameworkAssemblies(manifest); - - return manifest; - } - - void AddDependencies(Manifest manifest) - { - var dependencies = from item in Contents - where item.GetMetadata(MetadataName.Kind) == PackageItemKind.Dependency && - !"all".Equals(item.GetMetadata(MetadataName.PrivateAssets), StringComparison.OrdinalIgnoreCase) - select new Dependency - { - Id = item.ItemSpec, - Version = VersionRange.Parse(item.GetMetadata(MetadataName.Version)), - TargetFramework = item.GetNuGetTargetFramework(), - Include = item.GetNullableMetadata(MetadataName.IncludeAssets), - Exclude = item.GetNullableMetadata(MetadataName.ExcludeAssets) - }; - - var definedDependencyGroups = (from dependency in dependencies - group dependency by dependency.TargetFramework into dependenciesByFramework - select new PackageDependencyGroup - ( - dependenciesByFramework.Key, - (from dependency in dependenciesByFramework - where dependency.Id != "_._" - group dependency by dependency.Id into dependenciesById - select new PackageDependency - ( - dependenciesById.Key, - dependenciesById.Select(x => x.Version).Aggregate(AggregateVersions), - dependenciesById.Select(x => x.Include).Aggregate(default(List), AggregateAssetsFlow), - dependenciesById.Select(x => x.Exclude).Aggregate(default(List), AggregateAssetsFlow) - )).ToList() - )).ToDictionary(p => p.TargetFramework.GetFrameworkString()); - - // include frameworks referenced by libraries, but without dependencies.. - foreach (var targetFramework in (from item in Contents - where item.GetMetadata(MetadataName.Kind) == PackageItemKind.Lib && - !"all".Equals(item.GetMetadata(MetadataName.PrivateAssets), StringComparison.OrdinalIgnoreCase) - select item.GetNuGetTargetFramework())) - if (!definedDependencyGroups.ContainsKey(targetFramework.GetFrameworkString())) - definedDependencyGroups.Add(targetFramework.GetFrameworkString(), - new PackageDependencyGroup(targetFramework, Array.Empty())); - - manifest.Metadata.DependencyGroups = definedDependencyGroups.Values; - } - - void AddFiles(Manifest manifest) - { - var contents = new List(); - - var groupedByPackagePath = Contents - .Where(item => !string.IsNullOrEmpty(item.GetMetadata(MetadataName.PackagePath))) - .GroupBy(item => item.GetMetadata(MetadataName.PackagePath)) - // Iterate only once for this grouping. - .ToDictionary(item => item.Key, item => item.ToArray()); - - // Add the ones we already determined as unique by package path. - contents.AddRange(groupedByPackagePath - .Where(group => group.Value.Length == 1) - .Select(group => group.Value.First())); - - var groupedByLastWriteAndLength = groupedByPackagePath - .Where(group => group.Value.Length > 1) - .SelectMany(group => group.Value) - // Tuple provides structural comparison and hashing already, so leverage that. - .GroupBy(item => Tuple.Create( - item.GetMetadata(MetadataName.PackagePath), - item.GetMetadata("Filename"), - item.GetMetadata("Extension"), - File.GetLastWriteTime(item.GetMetadata("FullPath")), - new FileInfo(item.GetMetadata("FullPath")).Length)) - .ToDictionary(item => item.Key, item => item.ToArray()); - - // Add the ones we already determined to be duplicates that can safely be - // unified by package path, file name, last write time and file length. - contents.AddRange(groupedByLastWriteAndLength - .Where(group => group.Value.Length > 1) - .Select(group => group.Value.First())); - - var md5 = new Lazy(() => MD5.Create()); - string hash(ITaskItem item) - { - using (var file = File.OpenRead(item.GetMetadata("FullPath"))) - { - return string.Concat(md5.Value.ComputeHash(file).Select(x => x.ToString("x2"))); - } - } - - // Last remaining attempt at de-duplication is costly, but by now, we should - // have successfully removed all obvious cases. - // This deals with case where the files are modified at different times - // (maybe a generated file?) but their actual contents are the same. - var groupedByContentHash = groupedByLastWriteAndLength - .Where(group => group.Value.Length == 1) - .SelectMany(group => group.Value) - .GroupBy(item => Tuple.Create( - item.GetMetadata(MetadataName.PackagePath), - hash(item))) - .ToDictionary(item => item.Key, item => item.ToArray()); - - // Add the ones we determined to be duplicates that can safely be - // unified by package path and MD5 hash - contents.AddRange(groupedByContentHash - .Where(group => group.Value.Length > 1) - .Select(group => group.Value.First())); - - // At this point, we're 100% certain these are duplicate package path - // files that have distinct sources and would result in one overwriting - // the other or an invalid package. - var duplicates = string.Join(Environment.NewLine, groupedByContentHash - .Where(group => group.Value.Length == 1) - .SelectMany(group => group.Value) - .Select(item => $"'{item.GetMetadata("FullPath")}' > '{item.GetMetadata(MetadataName.PackagePath)}'")); - - if (duplicates.Length > 0) - Log.LogErrorCode(nameof(ErrorCode.NG0012), ErrorCode.NG0012(duplicates)); - - // All files need to be added so they are included in the nupkg - manifest.Files.AddRange(contents - .Select(item => new ManifestFile - { - Source = item.GetMetadata("FullPath"), - Target = item.GetMetadata(MetadataName.PackagePath), - })); - - // Additional metadata for the content files must be added separately - manifest.Metadata.ContentFiles = contents - .Where(item => item.GetMetadata(MetadataName.PackageFolder) == PackagingConstants.Folders.ContentFiles) - .Select(item => new ManifestContentFiles - { - Include = item.GetContentFileInclude(), - BuildAction = item.GetNullableMetadata(MetadataName.ContentFile.BuildAction), - CopyToOutput = item.GetNullableMetadata(MetadataName.ContentFile.CopyToOutput), - Flatten = item.GetNullableMetadata(MetadataName.ContentFile.Flatten), - }).ToArray(); - } - - void AddFrameworkAssemblies(Manifest manifest) - { - var frameworkReferences = (from item in Contents - where item.GetMetadata(MetadataName.Kind) == PackageItemKind.FrameworkReference - select new FrameworkAssemblyReference - ( - item.ItemSpec, - new[] { NuGetFramework.Parse(item.GetTargetFrameworkMoniker().FullName) } - )).Distinct(FrameworkAssemblyReferenceComparer.Default); - - manifest.Metadata.FrameworkReferences = frameworkReferences; - } - - void BuildPackage(Stream output) - { - var builder = new PackageBuilder(); - var manifest = CreateManifest(); - - builder.Populate(manifest.Metadata); - // We don't use PopulateFiles because that performs search expansion, base path - // extraction and the like, which messes with our determined files to include. - // TBD: do we support wilcard-based include/exclude? - builder.Files.AddRange(manifest.Files.Select(file => - new PhysicalPackageFile { SourcePath = file.Source, TargetPath = file.Target })); - - builder.Save(output); - - if (!string.IsNullOrEmpty(NuspecFile)) - { - Directory.CreateDirectory(Path.GetDirectoryName(NuspecFile)); - using (var stream = File.Create(NuspecFile)) - { - manifest.Save(stream, true); - } - } - } - - static VersionRange AggregateVersions(VersionRange aggregate, VersionRange next) - { - var versionSpec = new VersionSpec(); - SetMinVersion(versionSpec, aggregate); - SetMinVersion(versionSpec, next); - SetMaxVersion(versionSpec, aggregate); - SetMaxVersion(versionSpec, next); - - if (versionSpec.MinVersion == null && versionSpec.MaxVersion == null) - return null; - - return versionSpec.ToVersionRange(); - } - - static List AggregateAssetsFlow(List aggregate, string next) - { - if (next == null) - return aggregate; - if (aggregate == null) - aggregate = new List(1); - aggregate.AddRange(next.Split(';')); - return aggregate; - } - - static void SetMinVersion(VersionSpec target, VersionRange source) - { - if (source == null || source.MinVersion == null) - return; - - if (target.MinVersion == null) - { - target.MinVersion = source.MinVersion; - target.IsMinInclusive = source.IsMinInclusive; - } - - if (target.MinVersion < source.MinVersion) - { - target.MinVersion = source.MinVersion; - target.IsMinInclusive = source.IsMinInclusive; - } - - if (target.MinVersion == source.MinVersion) - target.IsMinInclusive = target.IsMinInclusive && source.IsMinInclusive; - } - - static void SetMaxVersion(VersionSpec target, VersionRange source) - { - if (source == null || source.MaxVersion == null) - return; - - if (target.MaxVersion == null) - { - target.MaxVersion = source.MaxVersion; - target.IsMaxInclusive = source.IsMaxInclusive; - } - - if (target.MaxVersion > source.MaxVersion) - { - target.MaxVersion = source.MaxVersion; - target.IsMaxInclusive = source.IsMaxInclusive; - } - - if (target.MaxVersion == source.MaxVersion) - target.IsMaxInclusive = target.IsMaxInclusive && source.IsMaxInclusive; - } - - static ICollection ParsePackageTypes(string packageTypes) - { - var listOfPackageTypes = new List(); - if (!string.IsNullOrEmpty(packageTypes)) - { - foreach (var packageType in packageTypes.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)) - { - string[] packageTypeSplitInPart = packageType.Split(new char[] { ',' }); - string packageTypeName = packageTypeSplitInPart[0].Trim(); - var version = PackageType.EmptyVersion; - if (packageTypeSplitInPart.Length > 1) - { - string versionString = packageTypeSplitInPart[1]; - Version.TryParse(versionString, out version); - } - listOfPackageTypes.Add(new PackageType(packageTypeName, version)); - } - } - return listOfPackageTypes; - } - - class Dependency - { - public string Id { get; set; } - - public NuGetFramework TargetFramework { get; set; } - - public VersionRange Version { get; set; } - - public string Include { get; set; } - - public string Exclude { get; set; } - } - - class VersionSpec - { - public bool IsMinInclusive { get; set; } - public NuGetVersion MinVersion { get; set; } - public bool IsMaxInclusive { get; set; } - public NuGetVersion MaxVersion { get; set; } - - public VersionRange ToVersionRange() - { - return new VersionRange(MinVersion, IsMinInclusive, MaxVersion, IsMaxInclusive); - } - } - } -} diff --git a/src/Build/NuGet.Build.Packaging.Tasks/Extensions.cs b/src/Build/NuGet.Build.Packaging.Tasks/Extensions.cs deleted file mode 100644 index d8b70c31..00000000 --- a/src/Build/NuGet.Build.Packaging.Tasks/Extensions.cs +++ /dev/null @@ -1,127 +0,0 @@ -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Runtime.Versioning; -using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; -using NuGet.Build.Packaging.Tasks; -using NuGet.Frameworks; -using NuGet.Packaging; -using NuGet.Packaging.Core; - -namespace NuGet.Build.Packaging -{ - public static class Extensions - { - static readonly FrameworkName NullFramework = new FrameworkName("Null,Version=v1.0"); - - public static IEnumerable NullAsEmpty(this IEnumerable source) => source ?? Enumerable.Empty(); - - public static bool GetBoolean(this ITaskItem taskItem, string metadataName, bool defaultValue = false) - { - var result = false; - var metadataValue = taskItem.GetMetadata(metadataName); - - return bool.TryParse(metadataValue, out result) && result; - } - - public static string GetNullableMetadata(this ITaskItem taskItem, string metadataName) - { - var value = taskItem.GetMetadata(metadataName); - if (string.IsNullOrEmpty(value)) - return null; - - return value; - } - - public static string GetContentFileInclude(this ITaskItem taskItem) - { - const string contentFilesFolder = @"contentFiles\"; - var include = taskItem.GetMetadata(MetadataName.PackagePath); - if (include.StartsWith(contentFilesFolder)) - return include.Substring(contentFilesFolder.Length); - return include; - } - - public static Manifest GetManifest(this IPackageCoreReader packageReader) - { - using (var stream = packageReader.GetNuspec()) - { - var manifest = Manifest.ReadFrom(stream, true); - manifest.Files.AddRange(packageReader.GetFiles() - // Skip the auto-added stuff - .Where(file => - file != "[Content_Types].xml" && - file != "_rels/.rels" && - !file.EndsWith(".nuspec") && - !file.EndsWith(".psmdcp")) - .Select(file => new ManifestFile - { - // Can't replicate the Source path as it was originally before adding - // to the package, so leave it null to avoid false promises in tests. - //Source = file.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar), - Target = file.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar) - })); - - return manifest; - } - } - - public static NuGetFramework GetNuGetTargetFramework(this ITaskItem taskItem) - { - if (bool.TryParse(taskItem.GetMetadata(MetadataName.FrameworkSpecific), out var frameworkSpecific) && - !frameworkSpecific) - return NuGetFramework.AnyFramework; - - var metadataValue = taskItem.GetMetadata(MetadataName.TargetFramework); - if (string.IsNullOrEmpty(metadataValue)) - metadataValue = taskItem.GetMetadata(MetadataName.TargetFrameworkMoniker); - - if (!string.IsNullOrEmpty(metadataValue)) - return NuGetFramework.Parse(metadataValue); - else - return NuGetFramework.AnyFramework; - } - - public static FrameworkName GetTargetFramework(this ITaskItem taskItem) - { - var metadataValue = taskItem.GetMetadata(MetadataName.TargetFramework); - if (string.IsNullOrEmpty(metadataValue)) - metadataValue = taskItem.GetMetadata(MetadataName.TargetFrameworkMoniker); - - if (!string.IsNullOrEmpty(metadataValue)) - return new FrameworkName(NuGetFramework.Parse(metadataValue).DotNetFrameworkName); - else - return NullFramework; - } - - public static FrameworkName GetTargetFrameworkMoniker(this ITaskItem item) - { - var value = item.GetMetadata(MetadataName.TargetFrameworkMoniker); - // \o/: Turn .NETPortable,Version=v5.0 into .NETPlatform,Version=v5.0, hardcoded for now? - // TODO: should be able to get .NETStandard,Version=v1.x from the item metadata somehow. - - return string.IsNullOrEmpty(value) ? - NullFramework : - new FrameworkName(value); - } - - public static string GetShortFrameworkName(this FrameworkName frameworkName) - { - if (frameworkName == null || frameworkName == NullFramework) - return null; - - // In this case, NuGet returns portable50, is that correct? - //if (frameworkName.Identifier == ".NETPortable" && frameworkName.Version.Major == 5 && frameworkName.Version.Minor == 0) - // return "dotnet"; - - return NuGetFramework.Parse(frameworkName.FullName).GetShortFolderName(); - } - - public static void LogErrorCode(this TaskLoggingHelper log, string code, string message, params object[] messageArgs) => - log.LogError(string.Empty, code, string.Empty, string.Empty, 0, 0, 0, 0, message, messageArgs); - - public static void LogWarningCode(this TaskLoggingHelper log, string code, string file, string message, params object[] messageArgs) => - log.LogWarning(string.Empty, code, string.Empty, file, 0, 0, 0, 0, message, messageArgs); - } -} diff --git a/src/Build/NuGet.Build.Packaging.Tasks/MetadataName.cs b/src/Build/NuGet.Build.Packaging.Tasks/MetadataName.cs deleted file mode 100644 index 0a78c0dc..00000000 --- a/src/Build/NuGet.Build.Packaging.Tasks/MetadataName.cs +++ /dev/null @@ -1,62 +0,0 @@ -namespace NuGet.Build.Packaging.Tasks -{ - public static class MetadataName - { - public const string FileSource = "FullPath"; - - public const string Kind = nameof(Kind); - - public const string Version = nameof(Version); - - /// - /// One of https://github.com/NuGet/NuGet.Client/blob/dev/src/NuGet.Core/NuGet.Packaging/PackagingConstants.cs#L27 - /// - public const string PackageFolder = nameof(PackageFolder); - - /// - /// The package that declares the given package file. - /// - public const string PackageId = nameof(PackageId); - - /// - /// Concatenation of and . - /// For contentFiles, also includes the or any if - /// none was provided. - /// - public const string PackagePath = nameof(PackagePath); - - /// - /// Marks a @(PackageReference) as a development dependency when set to 'All'. - /// - public const string PrivateAssets = nameof(PrivateAssets); - - public const string IncludeAssets = nameof(IncludeAssets); - - public const string ExcludeAssets = nameof(ExcludeAssets); - - /// - /// Whether the project can be packed as a .nupkg. - /// - public const string IsPackable = nameof(IsPackable); - - /// - /// Whether a PackageFile is framework-specific or not. - /// - public const string FrameworkSpecific = nameof(FrameworkSpecific); - - public const string TargetFramework = nameof(TargetFramework); - - public const string TargetFrameworkMoniker = nameof(TargetFrameworkMoniker); - - /// - /// Available optional metadata values of contentFiles. - /// - public static class ContentFile - { - public const string CodeLanguage = nameof(CodeLanguage); - public const string BuildAction = nameof(BuildAction); - public const string CopyToOutput = nameof(CopyToOutput); - public const string Flatten = nameof(Flatten); - } - } -} \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tasks/NuGet.Build.Packaging.Authoring.targets b/src/Build/NuGet.Build.Packaging.Tasks/NuGet.Build.Packaging.Authoring.targets deleted file mode 100644 index 23319003..00000000 --- a/src/Build/NuGet.Build.Packaging.Tasks/NuGet.Build.Packaging.Authoring.targets +++ /dev/null @@ -1,83 +0,0 @@ - - - - - - $(PackageId) - - - - - - - - - true - false - FromPackagingProject=true - - - - - - - - - - - - - - - - - - - - - - - - - @(PackageTargetPath->'%(FullPath)') - - - - - - - - - - - - - - diff --git a/src/Build/NuGet.Build.Packaging.Tasks/NuGet.Build.Packaging.Inference.targets b/src/Build/NuGet.Build.Packaging.Tasks/NuGet.Build.Packaging.Inference.targets deleted file mode 100644 index 24ef3b91..00000000 --- a/src/Build/NuGet.Build.Packaging.Tasks/NuGet.Build.Packaging.Inference.targets +++ /dev/null @@ -1,252 +0,0 @@ - - - - - - Lib - - - true - - false - - true - - true - - - - true - - <_OutputFullPath Condition="$([System.IO.Path]::IsPathRooted($(OutputPath)))">$(OutputPath) - <_OutputFullPath Condition="'$(_OutputFullPath)' == ''">$(MSBuildProjectDirectory)\$(OutputPath) - - - - - $(GetPackageContentsDependsOn); - _PrimaryOutputFrameworkSpecific; - InferPackageContents - - - - - - - - - - false - false - - - - <_ReferenceRelatedPaths> - false - false - - - - - - - - - <_PrimaryOutputKind Include="@(PackageItemKind->'%(FrameworkSpecific)')" Condition="'%(Identity)' == '$(PrimaryOutputKind)'" /> - - - @(_PrimaryOutputKind) - - - - - - - - - - - - - - - <_InferredPackageFile Include="@(BuiltProjectOutputGroupOutput -> '%(FinalOutputPath)');@(BuiltProjectOutputGroupKeyOutput -> '%(FinalOutputPath)')" - Condition="'$(IncludeOutputsInPackage)' == 'true' and '$(IsPackagingProject)' != 'true'"> - - $(PrimaryOutputKind) - $(PrimaryOutputFrameworkSpecific) - - - - <_DocumentationProjectOutputGroupOutput Include="@(DocumentationProjectOutputGroupOutput)" - Condition="'$(IncludeOutputsInPackage)' == 'true'"> - $(MSBuildProjectDirectory)\%(FinalOutputPath) - - <_InferredPackageFile Include="@(_DocumentationProjectOutputGroupOutput -> '%(FinalOutputPath)')" - Condition="'$(IncludeOutputsInPackage)' == 'true' and '$(IsPackagingProject)' != 'true'"> - - $(PrimaryOutputKind) - $(PrimaryOutputFrameworkSpecific) - - - <_InferredPackageFile Include="@(DebugSymbolsProjectOutputGroupOutput -> '%(FinalOutputPath)')" - Condition="'$(IncludeOutputsInPackage)' == 'true' and '$(IncludeSymbolsInPackage)' == 'true' and '$(IsPackagingProject)' != 'true'"> - - $(PrimaryOutputKind) - $(PrimaryOutputFrameworkSpecific) - - - - <_InferredPackageFile Include="@(SatelliteDllsProjectOutputGroupOutput -> '%(FullPath)')" - Condition="'$(IncludeOutputsInPackage)' == 'true' and '$(IsPackagingProject)' != 'true'"> - - $(PrimaryOutputKind) - $(PrimaryOutputFrameworkSpecific) - - - - - - <_InferredPackageFile Include="@(_ContentToInfer->'$(_OutputFullPath)\%(TargetPath)')" - Condition="'%(_ContentToInfer.CopyToOutputDirectory)' != '' and '%(_ContentToInfer.CopyToOutputDirectory)' != 'Never'"> - $(PrimaryOutputKind) - - - <_InferredPackageFile Include="@(_ContentToInfer->'%(FullPath)')" - Condition="'%(_ContentToInfer.CopyToOutputDirectory)' == '' or '%(_ContentToInfer.CopyToOutputDirectory)' == 'Never'"> - Content - - - - - <_InferredPackageFile Include="@(_NoneToInfer->'$(_OutputFullPath)\%(TargetPath)')" - Condition="'%(_NoneToInfer.CopyToOutputDirectory)' != '' and '%(_NoneToInfer.CopyToOutputDirectory)' != 'Never'"> - $(PrimaryOutputKind) - - <_InferredPackageFile Include="@(_NoneToInfer->'%(FullPath)')" - Condition="'%(_NoneToInfer.CopyToOutputDirectory)' == '' or '%(_NoneToInfer.CopyToOutputDirectory)' == 'Never'"> - None - - - - <_InferredPackageFile Include="@(PackageReference)" Condition="'%(PackageReference.Identity)' != 'NuGet.Build.Packaging' and - '%(PackageReference.Identity)' != 'NETStandard.Library' and - '%(PackageReference.PrivateAssets)' != 'all' and - '%(PackageReference.Pack)' != 'false'"> - Dependency - - - - <_InferredPackageFile Include="@(ReferencePath->'%(OriginalItemSpec)')" - Condition="'$(IncludeFrameworkReferencesInPackage)' == 'true' and '%(ReferencePath.ResolvedFrom)' == '{TargetFrameworkDirectory}'"> - FrameworkReference - - - - - - - Implicit - $(PackageId) - $(Platform) - $(TargetFrameworkMoniker) - - - - - - - <_PrimaryOutputRelatedFile Include="@(ReferencePath);@(_ReferenceRelatedPaths)" - Condition="'%(NuGetPackageId)' != 'NETStandard.Library' and - '%(Facade)' != 'true' and - '%(FrameworkFile)' != 'true' and - '%(Pack)' != 'false'"/> - - - - - - <_NuGetPackageId Include="@(_PrimaryOutputRelatedFile -> '%(NuGetPackageId)')" Condition="'%(NuGetPackageId)' != 'NETStandard.Library'" /> - - - <_NuGetPackageId>@(_NuGetPackageId -> Distinct()) - - - <_PrimaryPackageReference Include="@(PackageReference)" Condition="'$(_NuGetPackageId)' != '' and '%(Identity)' == '$(_NuGetPackageId)'" /> - - - <_PrivateAssets>@(_PrimaryPackageReference -> '%(PrivateAssets)') - <_ShouldIncludeAssetsRegex>$(_NuGetPackageId)\\.+\\$(_PrivateAssets)\\.* - - - - <_InferredPackageFile Include="@(_PrimaryOutputRelatedFile)" Condition="'%(_PrimaryOutputRelatedFile.FrameworkFile)' != 'true'"> - $(PrimaryOutputKind) - $(PrimaryOutputFrameworkSpecific) - - - - - - <_InferredPackageFile Include="@(_PrimaryOutputRelatedFile)" Condition="$([System.Text.RegularExpressions.Regex]::IsMatch('%(_PrimaryOutputRelatedFile.FullPath)', '$(_ShouldIncludeAssetsRegex)', 'RegexOptions.IgnoreCase')) == 'true'"> - $(PrimaryOutputKind) - $(PrimaryOutputFrameworkSpecific) - - - - - - - - <_SupportsReferences Condition=" - $(_AllProjectCapabilities.Contains('AssemblyReferences')) or - $(_AllProjectCapabilities.Contains('COMReferences')) or - $(_AllProjectCapabilities.Contains('ProjectReferences')) or - $(_AllProjectCapabilities.Contains('PackageReferences')) or - $(_AllProjectCapabilities.Contains('WinRTReferences')) or - $(_AllProjectCapabilities.Contains('SDKReferences'))">true - - - ResolveReferences; - InferPrimaryOutputDependencies - - - $(InferPackageContentsDependsOn); - GetPackageTargetPath - - - $(InferPackageContentsDependsOn); - AllProjectOutputGroups - - - - - diff --git a/src/Build/NuGet.Build.Packaging.Tasks/NuGet.Build.Packaging.MultiTargeting.targets b/src/Build/NuGet.Build.Packaging.Tasks/NuGet.Build.Packaging.MultiTargeting.targets deleted file mode 100644 index ada493bb..00000000 --- a/src/Build/NuGet.Build.Packaging.Tasks/NuGet.Build.Packaging.MultiTargeting.targets +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - - - - - true - - - - - - - GetTargetPathWithTargetPlatformMoniker - - - - - - - <_PackageContent Include="@(InnerOutput)" /> - - - - - - GetPackageContents - - - - diff --git a/src/Build/NuGet.Build.Packaging.Tasks/NuGet.Build.Packaging.Tasks.csproj b/src/Build/NuGet.Build.Packaging.Tasks/NuGet.Build.Packaging.Tasks.csproj deleted file mode 100644 index 3cf06ff6..00000000 --- a/src/Build/NuGet.Build.Packaging.Tasks/NuGet.Build.Packaging.Tasks.csproj +++ /dev/null @@ -1,35 +0,0 @@ - - - - netstandard2.0 - NuGetizer - NO-SDK-PACK - false - true - true - NuGet.Build.Packaging - - - - - - - - - - - - - - - buildMultiTargeting\NuGetizer%(Extension) - - - - - - - - - - \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tasks/NuGet.Build.Packaging.Tasks.targets b/src/Build/NuGet.Build.Packaging.Tasks/NuGet.Build.Packaging.Tasks.targets deleted file mode 100644 index 0a57f9de..00000000 --- a/src/Build/NuGet.Build.Packaging.Tasks/NuGet.Build.Packaging.Tasks.targets +++ /dev/null @@ -1,128 +0,0 @@ - - - - - - - - - PreserveNewest - true - - - - - $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - - NuGetizer - NuGetizer - Simple and flexible NuGet packaging - true - build - - true - ..\..\bin - - - - - - - - - - - - - - <Namespace Prefix='msb' Uri='http://schemas.microsoft.com/developer/msbuild/2003'/> - - - - - - - PackageItemKind; - $(CoreCompileDependsOn); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - /keyfile:"$(AssemblyOriginatorKeyFile)" - - - - - - - - - - - - - diff --git a/src/Build/NuGet.Build.Packaging.Tasks/NuGet.Build.Packaging.targets b/src/Build/NuGet.Build.Packaging.Tasks/NuGet.Build.Packaging.targets deleted file mode 100644 index c93608fc..00000000 --- a/src/Build/NuGet.Build.Packaging.Tasks/NuGet.Build.Packaging.targets +++ /dev/null @@ -1,405 +0,0 @@ - - - - - - - - - - - - true - - false - - - true - false - - true - - - $(OutputPath) - - - $(MSBuildProjectDirectory)\.packonbuild - - - false - - $(OutputPath)\$(PackageId).nuspec - - - - - - - - - - - - - $(IsPackable) - true - - - - - - - $(GetPackageVersionDependsOn); - _SetDefaultPackageVersion - - - - - - $(Version) - - - - - - - $(GetPackageTargetPathDependsOn); - GetPackageVersion; - _SetDefaultPackageTargetPath; - - - - - - - - $(PackageId) - $(PackageVersion) - true - - $(Authors) - $(Owners) - $(Title) - $(Description) - $(Summary) - $(NeutralLanguage) - $(Copyright) - - $(PackageRequireLicenseAcceptance) - $(PackageLicenseUrl) - $(PackageProjectUrl) - $(PackageIconUrl) - $(PackageTags) - - $(PackageReleaseNotes) - $(RepositoryUrl) - $(RepositoryType) - $(PackageType) - - - - - - $([System.IO.Path]::Combine('$(PackageOutputPath)', '$(PackageId).$(PackageVersion).nupkg')) - - - - - - GetPackageTargetPath;$(PackageOutputGroupDependsOn) - - - - - - - $(GetPackageContentsDependsOn); - GetPackageTargetPath; - _AddPackageManifest - - - $(GetPackageContentsDependsOn); - _GetReferencedPackageContents - - - - - - - - $(PackageId) - $(Platform) - $(TargetFrameworkMoniker) - - - - - - - - - - - - - - Metadata - $(PackageId) - $(Platform) - $(TargetFrameworkMoniker) - - - - - - - - - - - - - - - - <_ReferencedPackageDependency Include="@(_ReferencedPackageContent)" - Condition="'%(_ReferencedPackageContent.PackageId)' != '$(PackageId)' and '%(_ReferencedPackageContent.Kind)' == 'Metadata'"> - - $(PackageId) - $(TargetFrameworkMoniker) - Dependency - - - <_PackageContentFromDependency Include="@(_ReferencedPackageContent)" - Condition="'%(_ReferencedPackageContent.PackageId)' != '' and - '%(_ReferencedPackageContent.PackageId)' != '$(PackageId)'" /> - <_ReferencedPackageContent Remove="@(_PackageContentFromDependency)" /> - - - - - - - - - - <_ReferencedPackageContentWithOriginalValues Condition="'%(_ReferencedPackageContentWithOriginalValues.PackageId)' == ''"> - $(PackageId) - - - - - $(TargetFrameworkMoniker) - - - - - - <_ReferencedPackageContentWithOriginalValues Condition="'%(_ReferencedPackageContentWithOriginalValues.PackageId)' == ''"> - $(PackageId) - - - - %(_ReferencedPackageContentWithOriginalValues.OriginalTargetFrameworkMoniker) - - - - - - - $(BuildingPackage) - - - - - - - - - - - - - <_IsExcludedFromPack>%(_MSBuildProjectReferenceExistent.Pack) - <_IsNuGetized>%(_ReferencedProjectTargetPath.IsNuGetized) - - - - - - <_NonNuGetizedProjectReference Include="@(_MSBuildProjectReferenceExistent)" Condition="'$(_IsNuGetized)' != 'true'" /> - - <_NuGetizedProjectReference Include="@(_MSBuildProjectReferenceExistent)" Condition="'$(_IsNuGetized)' == 'true'" /> - - - - - - - <_ShouldPackOnBuild Condition="('$(PackOnBuild)' == 'true' Or Exists('$(PackOnBuildFile)')) And '$(IsPackable)' == 'true'">true - - $(BuildDependsOn); - Pack; - - - - Build; - - - $(PackDependsOn) - GetPackageTargetPath; - GetPackageContents - - - - - - - - - - - - - - - - - <_AllProjectCapabilities>@(ProjectCapability) - - <_SupportsProjectReferences>$(_AllProjectCapabilities.Contains('ProjectReferences')) - <_GetReferencedPackageContentsDependsOn Condition="'$(_SupportsProjectReferences)' == 'true'"> - $(_GetReferencedPackageContentsDependsOn); - AssignProjectConfiguration; - _SplitProjectReferencesByFileExistence; - _SplitProjectReferencesByIsNuGetized - - - - - - - diff --git a/src/Build/NuGet.Build.Packaging.Tasks/NuGetizer.props b/src/Build/NuGet.Build.Packaging.Tasks/NuGetizer.props deleted file mode 100644 index 30dd346d..00000000 --- a/src/Build/NuGet.Build.Packaging.Tasks/NuGetizer.props +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tasks/NuGetizer.targets b/src/Build/NuGet.Build.Packaging.Tasks/NuGetizer.targets deleted file mode 100644 index e8e297a5..00000000 --- a/src/Build/NuGet.Build.Packaging.Tasks/NuGetizer.targets +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/Directory.Build.props b/src/Build/NuGet.Build.Packaging.Tests/Scenarios/Directory.Build.props deleted file mode 100644 index f1ae1872..00000000 --- a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/Directory.Build.props +++ /dev/null @@ -1,25 +0,0 @@ - - - - false - false - false - obj\$(MSBuildProjectName) - - - - - - - - $(TargetPlatformMoniker) - $(TargetPlatformIdentifier) - $(TargetFrameworkIdentifier) - $(TargetFrameworkVersion.TrimStart('vV')) - $(TargetRefPath) - @(CopyUpToDateMarker) - - - - - \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/Directory.Build.targets b/src/Build/NuGet.Build.Packaging.Tests/Scenarios/Directory.Build.targets deleted file mode 100644 index 4de98b5c..00000000 --- a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/Directory.Build.targets +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/Scenario.props b/src/Build/NuGet.Build.Packaging.Tests/Scenarios/Scenario.props deleted file mode 100644 index d03eff0a..00000000 --- a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/Scenario.props +++ /dev/null @@ -1,51 +0,0 @@ - - - - - - Debug - AnyCPU - bin\$(MSBuildProjectName) - obj\$(MSBuildProjectName)\ - Library - Scenario - - v4.5 - $(MSBuildProjectName) - - - {AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA} - {BBBBBBBB-BBBB-BBBB-BBBB-BBBBBBBBBBBB} - {CCCCCCCC-CCCC-CCCC-CCCC-CCCCCCCCCCCC} - {DDDDDDDD-DDDD-DDDD-DDDD-DDDDDDDDDDDD} - {EEEEEEEE-EEEE-EEEE-EEEE-EEEEEEEEEEEE} - {FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF} - - $(GuidA) - - - true - - - 1 - - - None - - true - - - - - NuGet - Package for '$(MSBuildProjectName)' project. - - - $([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), NuGet.Build.Packaging.props)) - - $(MSBuildThisFileDirectory)..\..\NuGet.Build.Packaging.Tasks\bin\$(Configuration) - - - - \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/fakeframework.targets b/src/Build/NuGet.Build.Packaging.Tests/Scenarios/fakeframework.targets deleted file mode 100644 index 79848e84..00000000 --- a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/fakeframework.targets +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - $(ProgramFiles)\Reference Assemblies\Microsoft\Framework\ - $(TargetFrameworkRootPath).NETFramework\v4.6 - - - - - - - - \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_complex_pack/a.csproj b/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_complex_pack/a.csproj deleted file mode 100644 index d5d5b0b5..00000000 --- a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_complex_pack/a.csproj +++ /dev/null @@ -1,21 +0,0 @@ - - - - - $(GuidA) - v4.7.2 - A - 1.0.0 - - - - $(GuidB) - b - - - $(GuidE) - e - - - - \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_complex_pack/b.csproj b/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_complex_pack/b.csproj deleted file mode 100644 index e215828a..00000000 --- a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_complex_pack/b.csproj +++ /dev/null @@ -1,21 +0,0 @@ - - - - - $(GuidB) - v4.7.2 - B - 2.0.0 - - - - $(GuidC) - c - - - $(GuidD) - d - - - - \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_complex_pack/c.csproj b/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_complex_pack/c.csproj deleted file mode 100644 index e9ef3711..00000000 --- a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_complex_pack/c.csproj +++ /dev/null @@ -1,16 +0,0 @@ - - - - - $(GuidC) - v4.5 - C - 3.0.0 - - - - 1.0.0 - - - - \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_complex_pack/d.csproj b/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_complex_pack/d.csproj deleted file mode 100644 index 89c5573b..00000000 --- a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_complex_pack/d.csproj +++ /dev/null @@ -1,11 +0,0 @@ - - - netstandard1.6 - - - - $(GuidD) - false - - - \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_complex_pack/e.csproj b/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_complex_pack/e.csproj deleted file mode 100644 index 4313cf91..00000000 --- a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_complex_pack/e.csproj +++ /dev/null @@ -1,9 +0,0 @@ - - - - - $(GuidE) - v4.5 - - - \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_non_nugetized_reference/a.csproj b/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_non_nugetized_reference/a.csproj deleted file mode 100644 index d7334cf9..00000000 --- a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_non_nugetized_reference/a.csproj +++ /dev/null @@ -1,21 +0,0 @@ - - - - - v4.6 - a.package - 1.0.0 - - - - $(GuidB) - b - $(IncludeInPackage) - - - $(GuidC) - c - - - - \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_non_nugetized_reference/b/b.csproj b/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_non_nugetized_reference/b/b.csproj deleted file mode 100644 index 8e050ade..00000000 --- a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_non_nugetized_reference/b/b.csproj +++ /dev/null @@ -1,19 +0,0 @@ - - - - - $(GuidB) - v4.6 - $(AssemblyName).xml - - - - - - - $(GuidD) - d - - - - \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_non_nugetized_reference/b/project.json b/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_non_nugetized_reference/b/project.json deleted file mode 100644 index b4b09e00..00000000 --- a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_non_nugetized_reference/b/project.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "dependencies": { - "Newtonsoft.Json": "6.0.4", - "Microsoft.CodeAnalysis": "1.3.2" - }, - "frameworks": { - "net46": {} - }, - "runtimes": { - "win": {} - } -} \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_non_nugetized_reference/c.csproj b/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_non_nugetized_reference/c.csproj deleted file mode 100644 index 19f7ef24..00000000 --- a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_non_nugetized_reference/c.csproj +++ /dev/null @@ -1,9 +0,0 @@ - - - - - $(GuidC) - v4.5 - - - \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_non_nugetized_reference/d.csproj b/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_non_nugetized_reference/d.csproj deleted file mode 100644 index 2b245133..00000000 --- a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_non_nugetized_reference/d.csproj +++ /dev/null @@ -1,13 +0,0 @@ - - - - - $(GuidD) - v4.6 - - - - - - - \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_private_assets_reference/a.csproj b/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_private_assets_reference/a.csproj deleted file mode 100644 index aed265d0..00000000 --- a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_private_assets_reference/a.csproj +++ /dev/null @@ -1,21 +0,0 @@ - - - - - v4.5 - - - - 5.3.0 - all - - - 9.0.1 - lib - - - 2.3.0 - - - - \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_project_reference/a.csproj b/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_project_reference/a.csproj deleted file mode 100644 index e944f000..00000000 --- a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_project_reference/a.csproj +++ /dev/null @@ -1,20 +0,0 @@ - - - - - v4.5 - - - - $(GuidB) - b - $(IncludeInPackage) - - - - - 1.0.0-pre - - - - \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_project_reference/b.csproj b/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_project_reference/b.csproj deleted file mode 100644 index fc019bef..00000000 --- a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_project_reference/b.csproj +++ /dev/null @@ -1,14 +0,0 @@ - - - - - $(GuidB) - v4.5 - - - - 1.0.0 - - - - \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_localized_library/library.csproj b/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_localized_library/library.csproj deleted file mode 100644 index 1299b4dd..00000000 --- a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_localized_library/library.csproj +++ /dev/null @@ -1,14 +0,0 @@ - - - - - library - library - v4.5 - - - - - - - \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_multi_platform_solution/android/forms.android.csproj b/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_multi_platform_solution/android/forms.android.csproj deleted file mode 100644 index 4fcd280b..00000000 --- a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_multi_platform_solution/android/forms.android.csproj +++ /dev/null @@ -1,23 +0,0 @@ - - - - - Forms - MonoAndroid,Version=v9.0 - $(GuidE) - false - - - - - $([System.String]::new('%(Extension)').TrimStart('.')) - None - - - $(GuidF) - common - - - - - \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_multi_platform_solution/common/common.csproj b/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_multi_platform_solution/common/common.csproj deleted file mode 100644 index 271fcc59..00000000 --- a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_multi_platform_solution/common/common.csproj +++ /dev/null @@ -1,15 +0,0 @@ - - - netstandard1.6 - - - - Common - $(GuidF) - bin - obj\ - false - - - - \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_multi_platform_solution/forms.proj b/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_multi_platform_solution/forms.proj deleted file mode 100644 index f6f8584c..00000000 --- a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_multi_platform_solution/forms.proj +++ /dev/null @@ -1,38 +0,0 @@ - - - - - Forms - $(GuidA) - Forms - 1.0.0 - true - - - - $(GuidB) - common - - - $(GuidC) - forms.net - - - $(GuidD) - forms.ios - - - $(GuidE) - forms.android - - - - - <_Docs Include="docs\**\*.*" /> - - docs\%(_Docs.RecursiveDir)%(_Docs.Filename)%(_Docs.Extension) - - - - - \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_multi_platform_solution/ios/forms.ios.csproj b/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_multi_platform_solution/ios/forms.ios.csproj deleted file mode 100644 index 19566b53..00000000 --- a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_multi_platform_solution/ios/forms.ios.csproj +++ /dev/null @@ -1,19 +0,0 @@ - - - - - Forms - Xamarin.iOS,Version=v1.0 - $(GuidD) - false - - - - - $(GuidF) - common - - - - - \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_multi_platform_solution/net/forms.net.csproj b/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_multi_platform_solution/net/forms.net.csproj deleted file mode 100644 index fb332d5e..00000000 --- a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_multi_platform_solution/net/forms.net.csproj +++ /dev/null @@ -1,20 +0,0 @@ - - - - - Forms - v4.7.2 - $(GuidC) - bin - obj\ - false - - - - - $(GuidF) - common - - - - \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_packaging_project/a.nuproj b/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_packaging_project/a.nuproj deleted file mode 100644 index 779d8d79..00000000 --- a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_packaging_project/a.nuproj +++ /dev/null @@ -1,33 +0,0 @@ - - - - - PackageReference - netstandard1.0 - net11;net20;net35;net40;net403;net45;net451;net452;net46;net461;net462;netcore;netcore45;netcore451;netcore50;win8;win81;win10;sl4;sl5;wp;wp7;wp75;wp8;wp81;wpa81;uap;uap10;netstandard1.0;netstandard1.1;netstandard1.2;netstandard1.3;netstandard1.4;netstandard1.5;netstandard1.6;netstandard2.0;netcoreapp1.0;netcoreapp2.0;monoandroid;monotouch;monomac;xamarinios;xamarinmac;xamarinpsthree;xamarinpsfour;xamarinpsvita;xamarinwatchos;xamarintvos;xamarinxboxthreesixty;xamarinxboxone - a.package - 1.0.0 - - - - $(GuidB) - b - - - $(GuidC) - c - - - $(GuidE) - e - - - - - - Bar - - - - - \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_packaging_project/b/b.csproj b/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_packaging_project/b/b.csproj deleted file mode 100644 index 85542301..00000000 --- a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_packaging_project/b/b.csproj +++ /dev/null @@ -1,19 +0,0 @@ - - - - - $(GuidB) - v4.6 - $(AssemblyName).xml - - - - - - - $(GuidD) - d - - - - \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_packaging_project/b/project.json b/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_packaging_project/b/project.json deleted file mode 100644 index b4b09e00..00000000 --- a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_packaging_project/b/project.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "dependencies": { - "Newtonsoft.Json": "6.0.4", - "Microsoft.CodeAnalysis": "1.3.2" - }, - "frameworks": { - "net46": {} - }, - "runtimes": { - "win": {} - } -} \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_packaging_project/c.csproj b/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_packaging_project/c.csproj deleted file mode 100644 index 19f7ef24..00000000 --- a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_packaging_project/c.csproj +++ /dev/null @@ -1,9 +0,0 @@ - - - - - $(GuidC) - v4.5 - - - \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_packaging_project/d.csproj b/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_packaging_project/d.csproj deleted file mode 100644 index 2b245133..00000000 --- a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_packaging_project/d.csproj +++ /dev/null @@ -1,13 +0,0 @@ - - - - - $(GuidD) - v4.6 - - - - - - - \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_packaging_project/e.csproj b/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_packaging_project/e.csproj deleted file mode 100644 index 0f3ef846..00000000 --- a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_packaging_project/e.csproj +++ /dev/null @@ -1,11 +0,0 @@ - - - - - $(GuidE) - v4.5 - E - 2.0.0 - - - \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_packaging_project_with_netstandard/a.nuproj b/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_packaging_project_with_netstandard/a.nuproj deleted file mode 100644 index a8cd7ca1..00000000 --- a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_packaging_project_with_netstandard/a.nuproj +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - Debug - {AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA} - - - - - NuGet - Package for '$(MSBuildProjectName)' project. - bin - - a.package - 1.0.0 - - - - - - - - $(GuidB) - b - - - - - \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_packaging_project_with_netstandard/b/b.csproj b/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_packaging_project_with_netstandard/b/b.csproj deleted file mode 100644 index 141f54a5..00000000 --- a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_packaging_project_with_netstandard/b/b.csproj +++ /dev/null @@ -1,24 +0,0 @@ - - - netstandard1.6 - netstandard1.6;net45 - {BBBBBBBB-BBBB-BBBB-BBBB-BBBBBBBBBBBB} - - - - - $([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), NuGet.Build.Packaging.props)) - - $(MSBuildThisFileDirectory)..\..\..\..\NuGet.Build.Packaging.Tasks\bin\$(Configuration) - - - - - - 10.0.2 - - - - - - \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_an_empty_library_project/empty_library_project.csproj b/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_an_empty_library_project/empty_library_project.csproj deleted file mode 100644 index 27b26abc..00000000 --- a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_an_empty_library_project/empty_library_project.csproj +++ /dev/null @@ -1,9 +0,0 @@ - - - - - library - v4.5 - - - \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_duplicate_package_files/a.csproj b/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_duplicate_package_files/a.csproj deleted file mode 100644 index cf290e38..00000000 --- a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_duplicate_package_files/a.csproj +++ /dev/null @@ -1,38 +0,0 @@ - - - - - v4.5 - A - This is a readme - - - - $(GuidB) - b - - - - - PreserveNewest - - - content\content.txt - - - content\a\1\content.txt - - - content\a\2\content.txt - - - - - - - Readme.txt - - - - - \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_duplicate_package_files/b.csproj b/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_duplicate_package_files/b.csproj deleted file mode 100644 index 52176f3e..00000000 --- a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_duplicate_package_files/b.csproj +++ /dev/null @@ -1,32 +0,0 @@ - - - - - $(GuidB) - v4.5 - This is a readme - - - - PreserveNewest - - - content\content.txt - - - content\b\1\content.txt - - - content\b\2\content.txt - - - - - - - Readme.txt - - - - - \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tests/TargetsTests.cs b/src/Build/NuGet.Build.Packaging.Tests/TargetsTests.cs deleted file mode 100644 index 9ae257ee..00000000 --- a/src/Build/NuGet.Build.Packaging.Tests/TargetsTests.cs +++ /dev/null @@ -1,121 +0,0 @@ -using System.Collections.Generic; -using System.IO; -using System.Reflection; -using Microsoft.Build.Construction; -using Microsoft.Build.Evaluation; -using Microsoft.Build.Execution; -using Xunit; -using Xunit.Abstractions; - -namespace NuGet.Build.Packaging -{ - public class TargetsTests - { - ITestOutputHelper output; - - public TargetsTests(ITestOutputHelper output) => this.output = output; - - [Fact] - public void IncludeFrameworkReferencesInPackage_is_not_true_for_build_primary_output() - { - var project = new Project("NuGet.Build.Packaging.targets", new Dictionary - { - { "PrimaryOutputKind", "build" } - }, null); - - Assert.NotEqual("true", project.GetPropertyValue("IncludeFrameworkReferencesInPackage")); - } - - [Fact] - public void IncludeFrameworkReferencesInPackage_is_not_true_for_tool_primary_output() - { - var project = new Project("NuGet.Build.Packaging.targets", new Dictionary - { - { "PrimaryOutputKind", "tool" } - }, null); - - Assert.NotEqual("true", project.GetPropertyValue("IncludeFrameworkReferencesInPackage")); - } - - [Fact] - public void IncludeFrameworkReferencesInPackage_is_not_true_for_tools_primary_output() - { - var project = new Project("NuGet.Build.Packaging.targets", new Dictionary - { - { "PrimaryOutputKind", "tools" } - }, null); - - Assert.NotEqual("true", project.GetPropertyValue("IncludeFrameworkReferencesInPackage")); - } - - [Fact] - public void IncludeFrameworkReferencesInPackage_is_true_for_primary_output_lib() - { - var project = new Project("NuGet.Build.Packaging.targets", new Dictionary - { - { "PrimaryOutputKind", "lib" } - }, null); - - Assert.Equal("true", project.GetPropertyValue("IncludeFrameworkReferencesInPackage")); - } - - [Fact] - public void IncludeFrameworkReferencesInPackage_is_true_for_default_primary_output_kind() - { - var project = new Project("NuGet.Build.Packaging.targets", new Dictionary - { - }, null); - - Assert.Equal("true", project.GetPropertyValue("IncludeFrameworkReferencesInPackage")); - } - - [Fact] - public void IncludeFrameworkReferencesInPackage_is_not_true_for_compat_istool() - { - var project = new Project("NuGet.Build.Packaging.targets", new Dictionary - { - { "IsTool", "true" } - }, null); - - Assert.NotEqual("true", project.GetPropertyValue("IncludeFrameworkReferencesInPackage")); - } - - [Fact] - public void PackOnBuild_defaults_to_true_for_compat_GeneratePackageOnBuild_true() - { - var project = new Project("NuGet.Build.Packaging.targets", new Dictionary - { - { "GeneratePackageOnBuild", "true" } - }, null); - - Assert.Equal("true", project.GetPropertyValue("PackOnBuild")); - } - - [Fact] - public void package_contents_never_includes_nugetizer_package_reference() - { - var xml = ProjectRootElement.Create(Path.Combine(Directory.GetCurrentDirectory(), MethodBase.GetCurrentMethod().Name)); - xml.AddImport(@"Scenarios\Scenario.props"); - xml.AddImport(@"Scenarios\Scenario.targets"); - xml.AddItemGroup() - .AddItem("PackageReference", "NuGet.Build.Packaging", new[] { new KeyValuePair("Version", "*") }); - - xml.Save(); - - var project = new ProjectInstance(xml); - - var result = Builder.Build(project, "GetPackageContents"); - - Assert.Equal(BuildResultCode.Success, result.OverallResult); - Assert.Equal(TargetResultCode.Success, result["GetPackageContents"].ResultCode); - - var items = result["GetPackageContents"].Items; - - Assert.DoesNotContain(items, item => item.Matches(new - { - Kind = PackageItemKind.Dependency, - Identity = "NuGet.Build.Packaging", - })); - } - } -} diff --git a/src/Build/NuGet.Build.Packaging.Tests/given_an_empty_library_project.cs b/src/Build/NuGet.Build.Packaging.Tests/given_an_empty_library_project.cs deleted file mode 100644 index f94b2d2d..00000000 --- a/src/Build/NuGet.Build.Packaging.Tests/given_an_empty_library_project.cs +++ /dev/null @@ -1,170 +0,0 @@ -using Microsoft.Build.Execution; -using Xunit; -using Xunit.Abstractions; - -namespace NuGet.Build.Packaging -{ - public class given_an_empty_library_project - { - ITestOutputHelper output; - - public given_an_empty_library_project(ITestOutputHelper output) - { - this.output = output; - } - - [Fact] - public void when_getting_package_contents_then_includes_output_assembly() - { - var result = Builder.BuildScenario(nameof(given_an_empty_library_project)); - - result.AssertSuccess(output); - Assert.Contains(result.Items, item => item.Matches(new - { - Extension = ".dll", - Kind = "Lib" - })); - } - - [Fact] - public void when_include_outputs_in_package_is_false_then_does_not_include_main_assembly() - { - var result = Builder.BuildScenario(nameof(given_an_empty_library_project), new - { - IncludeOutputsInPackage = false, - }); - - result.AssertSuccess(output); - Assert.DoesNotContain(result.Items, item => item.Matches(new - { - Extension = ".dll", - Kind = "Lib" - })); - } - - [Fact] - public void when_getting_package_contents_then_includes_symbols() - { - var result = Builder.BuildScenario(nameof(given_an_empty_library_project), new { Configuration = "Debug" }); - - result.AssertSuccess(output); - Assert.Contains(result.Items, item => item.Matches(new - { - Extension = ".pdb", - })); - } - - [Fact] - public void when_include_symbols_in_package_is_true_but_include_outputs_is_false_then_does_not_include_symbols() - { - var result = Builder.BuildScenario(nameof(given_an_empty_library_project), new - { - IncludeOutputsInPackage = false, - IncludeSymbolsInPackage = true, - }); - - result.AssertSuccess(output); - Assert.DoesNotContain(result.Items, item => item.Matches(new - { - Extension = ".pdb", - })); - } - - [Fact] - public void when_include_symbols_in_package_is_false_then_does_not_include_symbols() - { - var result = Builder.BuildScenario(nameof(given_an_empty_library_project), new - { - IncludeSymbolsInPackage = false, - }); - - result.AssertSuccess(output); - Assert.DoesNotContain(result.Items, item => item.Matches(new - { - Extension = ".pdb", - })); - } - - [Fact] - public void when_getting_package_contents_then_includes_xmldoc() - { - var result = Builder.BuildScenario(nameof(given_an_empty_library_project)); - - Assert.Equal(TargetResultCode.Success, result.ResultCode); - Assert.Contains(result.Items, item => item.Matches(new - { - Extension = ".xml", - Kind = PackageItemKind.Lib, - })); - } - - [Fact] - public void when_include_output_in_package_is_false_then_does_not_include_xmldoc() - { - var result = Builder.BuildScenario(nameof(given_an_empty_library_project), new - { - IncludeOutputsInPackage = false, - }); - - result.AssertSuccess(output); - Assert.DoesNotContain(result.Items, item => item.Matches(new - { - Extension = ".xml", - Kind = PackageItemKind.Lib, - })); - } - - [Fact] - public void when_getting_package_contents_then_annotates_items_with_package_id() - { - var result = Builder.BuildScenario(nameof(given_an_empty_library_project), new { PackageId = "Foo" }, output: output); - - result.AssertSuccess(output); - Assert.All(result.Items, item => Assert.Equal("Foo", item.GetMetadata("PackageId"))); - } - - [Fact] - public void when_getting_package_contents_then_includes_framework_reference() - { - var result = Builder.BuildScenario(nameof(given_an_empty_library_project), new { PackageId = "Foo" }, output: output); - - result.AssertSuccess(output); - Assert.Contains(result.Items, item => item.Matches(new - { - Identity = "System.Core", - Kind = PackageItemKind.FrameworkReference, - })); - } - - [Fact] - public void when_include_framework_references_in_package_is_false_then_does_not_include_framework_reference() - { - var result = Builder.BuildScenario(nameof(given_an_empty_library_project), new - { - IncludeFrameworkReferencesInPackage = false, - PackageId = "Foo", - }, output: output); - - result.AssertSuccess(output); - Assert.DoesNotContain(result.Items, item => item.Matches(new - { - Identity = "System.Core", - Kind = PackageItemKind.FrameworkReference, - })); - } - - [Fact] - public void when_packing_with_empty_version_then_build_fails() - { - var result = Builder.BuildScenario(nameof(given_an_empty_library_project), new - { - PackageId = "Library", - PackageVersion = "", - Version = "", - }, target: "Pack"); - - Assert.Equal(TargetResultCode.Failure, result.ResultCode); - Assert.Equal("NG1002", result.Logger.Errors[0].Code); - } - } -} diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 68f6c213..9f9b24be 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -7,20 +7,24 @@ false Apache-2.0 - 42.42.42 - $(Version) + 42.42.42 true true - $(MSBuildThisFileDirectory)..\bin + $([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)..\bin')) + true embedded true Preview + true false $(DefaultItemExcludes);*.binlog;*.zip;*.rsp + + + false @@ -28,7 +32,15 @@ true - - + + + + + + + + + + \ No newline at end of file diff --git a/src/Directory.Build.targets b/src/Directory.Build.targets index 0f431a33..3291b60e 100644 --- a/src/Directory.Build.targets +++ b/src/Directory.Build.targets @@ -1,5 +1,17 @@ + + true + false + + + + + false + + + + $(IntermediateOutputPath)PackageItemKind.g$(DefaultLanguageSourceExtension) @@ -8,22 +20,7 @@ - - - false - true - - - + $(LocalAppData)\NuGet\v3-cache $(IsPackable) @@ -64,7 +61,7 @@ + AfterTargets="Build;Pack"> $(NuGetCache)\$(PackageId.ToLowerInvariant()) @@ -76,7 +73,7 @@ + AfterTargets="Build;Pack"> diff --git a/src/NuGetizer.Tasks/AssignPackagePath.cs b/src/NuGetizer.Tasks/AssignPackagePath.cs new file mode 100644 index 00000000..fca2d79c --- /dev/null +++ b/src/NuGetizer.Tasks/AssignPackagePath.cs @@ -0,0 +1,192 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; +using static ThisAssembly.Strings; +using NuGet.Packaging; + +namespace NuGetizer.Tasks +{ + /// + /// Ensures all files have the PackagePath metadata. + /// If the PackagePath was not explicitly specified, + /// determine one from the project relative path and + /// the TargetFramework and Kind metadata, and set it + /// on the projected item. + /// + public class AssignPackagePath : Task + { + public string IsPackaging { get; set; } + + [Required] + public ITaskItem[] Files { get; set; } + + [Required] + public ITaskItem[] Kinds { get; set; } + + [Output] + public ITaskItem[] AssignedFiles { get; set; } + + public override bool Execute() + { + var kindMap = Kinds.ToDictionary( + kind => kind.ItemSpec, + StringComparer.OrdinalIgnoreCase); + + AssignedFiles = Files.Select(file => EnsurePackagePath(file, kindMap)).ToArray(); + + return !Log.HasLoggedErrors; + } + + ITaskItem EnsurePackagePath(ITaskItem file, IDictionary kindMap) + { + var output = new TaskItem(file); + + // Map the Kind to a target top-level directory. + var kind = file.GetMetadata("Kind"); + var packageFolder = ""; + var frameworkSpecific = false; + if (!string.IsNullOrEmpty(kind) && kindMap.TryGetValue(kind, out var kindItem)) + { + packageFolder = kindItem.GetMetadata(MetadataName.PackageFolder); + bool.TryParse(kindItem.GetMetadata(MetadataName.FrameworkSpecific), out frameworkSpecific); + } + else if (!string.IsNullOrEmpty(kind)) + { + // By convention, we just turn the first letter of Kind to lowercase and assume that + // to be a valid folder kind. + packageFolder = char.IsLower(kind[0]) ? kind : + char.ToLower(kind[0]).ToString() + kind.Substring(1); + } + + // Specific PackageFile can always override Kind-inferred FrameworkSpecific value. + if (bool.TryParse(file.GetMetadata(MetadataName.FrameworkSpecific), out var frameworkSpecificOverride)) + frameworkSpecific = frameworkSpecificOverride; + + output.SetMetadata(MetadataName.PackageFolder, packageFolder); + + // NOTE: a declared TargetFramework metadata trumps TargetFrameworkMoniker, + // which is defaulted to that of the project being built. + var targetFramework = output.GetMetadata(MetadataName.TargetFramework); + if (string.IsNullOrEmpty(targetFramework) && frameworkSpecific) + { + var frameworkMoniker = file.GetTargetFrameworkMoniker(); + targetFramework = frameworkMoniker.GetShortFrameworkName() ?? ""; + // At this point we have the correct target framework + output.SetMetadata(MetadataName.TargetFramework, targetFramework); + } + + // If PackagePath already specified, we're done. + if (!string.IsNullOrEmpty(file.GetMetadata("PackagePath"))) + return output; + + // If a packaging project is requesting the package path assignment, + // perform it regardless of whether there is a PackageId on the items, + // since they all need to be assigned at this point. + bool isPackaging = false; + isPackaging = !string.IsNullOrEmpty(IsPackaging) && + bool.TryParse(IsPackaging, out isPackaging) && + isPackaging; + + // If no PackageId specified, we let referencing projects define the package path + // as it will be included in their package. + // NOTE: if we don't do this, the package path of a project would be determined + // by the declaring project's TFM, rather than the referencing one, and this + // would be incorrect (i.e. a referenced PCL project that does not build a + // nuget itself, would end up in the PCL lib folder rather than the referencing + // package's lib folder for its own TFM, i.e. 'lib\net45'). + if (string.IsNullOrEmpty(file.GetMetadata("PackageId")) && !isPackaging) + return output; + + // If we got this far but there wasn't a Kind to process, it's an error. + if (string.IsNullOrEmpty(kind)) + { + Log.LogErrorCode(nameof(ErrorCode.NG0010), ErrorCode.NG0010(file.ItemSpec)); + // We return the file anyway, since the task result will still be false. + return file; + } + + // If the kind is known but it isn't mapped to a folder inside the package, we're done. + // Special-case None kind since that means 'leave it wherever it lands' ;) + if (string.IsNullOrEmpty(packageFolder) && kind != PackageItemKind.None) + return output; + + // Special case for contentFiles, since they can also provide a codeLanguage metadata + if (packageFolder == PackagingConstants.Folders.ContentFiles) + { + if (file.GetMetadata("TargetPath").StartsWith(packageFolder, StringComparison.OrdinalIgnoreCase)) + { + Log.LogErrorCode(nameof(ErrorCode.NG0013), ErrorCode.NG0013(file.GetMetadata("TargetPath"))); + // We return the file anyway, since the task result will still be false. + return file; + } + + // See https://docs.nuget.org/create/nuspec-reference#contentfiles-with-visual-studio-2015-update-1-and-later + var codeLanguage = file.GetMetadata(MetadataName.ContentFile.CodeLanguage); + if (string.IsNullOrEmpty(codeLanguage)) + { + codeLanguage = PackagingConstants.AnyFramework; + output.SetMetadata(MetadataName.ContentFile.CodeLanguage, codeLanguage); + } + + packageFolder = Path.Combine(packageFolder, codeLanguage); + + // And they also cannot have an empty framework, at most, it will be "any" + if (string.IsNullOrEmpty(targetFramework)) + targetFramework = PackagingConstants.AnyFramework; + + // Once TF is defaulted, a content file is actually always framework-specific, + // although the framework may be 'any'. + frameworkSpecific = true; + + // At this point we have the correct target framework for a content file, so persist it. + output.SetMetadata(MetadataName.TargetFramework, targetFramework); + } + + var targetPath = file.GetMetadata("TargetPath"); + // Linked files already have the desired target path specified by the user + if (string.IsNullOrEmpty(targetPath)) + targetPath = file.GetMetadata("Link"); + + // NOTE: TargetPath allows a framework-specific file to still specify its relative + // location without hardcoding the target framework (useful for multi-targetting and + // P2P references). + if (string.IsNullOrEmpty(targetPath)) + { + targetPath = string.IsNullOrEmpty(packageFolder) ? + Path.Combine(file.GetMetadata("RelativeDir"), file.GetMetadata("FileName") + file.GetMetadata("Extension")) : + // Well-known folders only get root-level files by default. Can be overriden with PackagePath or TargetPath + // explicitly, of course + file.GetMetadata("FileName") + file.GetMetadata("Extension"); + } + + if (!string.IsNullOrEmpty(packageFolder) && + targetPath.StartsWith(packageFolder + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase)) + { + // Avoid duplicating already determined package folder in package path later on. + targetPath = targetPath.Substring(packageFolder.Length + 1); + } + + // At this point we have the correct calculated target path, so persist it for inspection if necessary. + output.SetMetadata("TargetPath", targetPath); + + // If we have no known package folder, files go to their RelativeDir location. + // This allows custom packaging paths such as "workbooks", "docs" or whatever, which aren't prohibited by + // the format. + var packagePath = string.IsNullOrEmpty(packageFolder) ? + // File goes to the determined target path (or the root of the package), such as a readme.txt + targetPath : + frameworkSpecific ? + // Otherwise, it goes to a framework-specific folder. + Path.Combine(new[] { packageFolder, targetFramework }.Concat(targetPath.Split(Path.DirectorySeparatorChar)).ToArray()) : + // Except if frameworkSpecific is false, such as for build, tools, runtimes + Path.Combine(new[] { packageFolder }.Concat(targetPath.Split(Path.DirectorySeparatorChar)).ToArray()); + + output.SetMetadata(MetadataName.PackagePath, packagePath); + + return output; + } + } +} diff --git a/src/NuGetizer.Tasks/CreatePackage.cs b/src/NuGetizer.Tasks/CreatePackage.cs new file mode 100644 index 00000000..b587b697 --- /dev/null +++ b/src/NuGetizer.Tasks/CreatePackage.cs @@ -0,0 +1,465 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Security.Cryptography; +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; +using NuGet.Frameworks; +using NuGet.Packaging; +using NuGet.Packaging.Core; +using NuGet.Packaging.Licenses; +using NuGet.Versioning; +using static ThisAssembly.Strings; + +namespace NuGetizer.Tasks +{ + public class CreatePackage : Task + { + [Required] + public ITaskItem Manifest { get; set; } + + [Required] + public ITaskItem[] Contents { get; set; } = Array.Empty(); + + [Required] + public string TargetPath { get; set; } + + [Required] + public string EmitPackage { get; set; } + + [Required] + public string EmitNuspec { get; set; } + + [Output] + public string NuspecFile { get; set; } + + [Output] + public ITaskItem OutputPackage { get; set; } + + Manifest manifest; + + public override bool Execute() + { + try + { + if (bool.TryParse(EmitPackage, out var emitPkg) && emitPkg) + GeneratePackage(); + + if (bool.TryParse(EmitNuspec, out var emitSpec) && emitSpec && !string.IsNullOrEmpty(NuspecFile)) + GenerateNuspec(); + + OutputPackage = new TaskItem(TargetPath); + Manifest.CopyMetadataTo(OutputPackage); + + return !Log.HasLoggedErrors; + } + catch (Exception ex) + { + Log.LogErrorFromException(ex); + return false; + } + } + + // Implementation for testing to avoid I/O + public Manifest Execute(Stream output) + { + GeneratePackage(output); + + output.Seek(0, SeekOrigin.Begin); + using (var reader = new PackageArchiveReader(output)) + { + return reader.GetManifest(); + } + } + + public Manifest CreateManifest() + { + var metadata = new ManifestMetadata(); + + metadata.Id = Manifest.GetMetadata(nameof(MetadataName.PackageId)); + + if (Manifest.TryGetMetadata(nameof(ManifestMetadata.Version), out var version)) + metadata.Version = NuGetVersion.Parse(Manifest.GetMetadata(MetadataName.Version)); + + if (Manifest.TryGetBoolMetadata(nameof(ManifestMetadata.DevelopmentDependency), out var devDep) && devDep) + metadata.DevelopmentDependency = true; + + if (Manifest.TryGetMetadata("Title", out var title)) + metadata.Title = title; + + if (Manifest.TryGetMetadata("Description", out var description)) + metadata.Description = description; + + if (Manifest.TryGetMetadata("Summary", out var summary)) + metadata.Summary = summary; + + if (Manifest.TryGetMetadata("Language", out var language)) + metadata.Language = language; + + if (Manifest.TryGetMetadata("Copyright", out var copyright)) + metadata.Copyright = copyright; + + if (Manifest.TryGetBoolMetadata("RequireLicenseAcceptance", out var requireLicenseAcceptance) && + requireLicenseAcceptance) + metadata.RequireLicenseAcceptance = requireLicenseAcceptance; + + if (!string.IsNullOrEmpty(Manifest.GetMetadata("Authors"))) + metadata.Authors = Manifest.GetMetadata("Authors").Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); + + if (!string.IsNullOrEmpty(Manifest.GetMetadata("Owners"))) + metadata.Owners = Manifest.GetMetadata("Owners").Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); + + if (!string.IsNullOrEmpty(Manifest.GetMetadata("LicenseUrl"))) + metadata.SetLicenseUrl(Manifest.GetMetadata("LicenseUrl")); + + if (Manifest.TryGetMetadata("LicenseExpression", out var expression)) + { + metadata.LicenseMetadata = new LicenseMetadata( + LicenseType.Expression, + expression, + NuGetLicenseExpression.Parse(expression), + null, LicenseMetadata.CurrentVersion); + } + + if (!string.IsNullOrEmpty(Manifest.GetMetadata("ProjectUrl"))) + metadata.SetProjectUrl(Manifest.GetMetadata("ProjectUrl")); + + if (Manifest.TryGetMetadata("RepositoryType", out var repoType)) + (metadata.Repository ??= new RepositoryMetadata()).Type = repoType; + + if (Manifest.TryGetMetadata("RepositoryUrl", out var repoUrl)) + (metadata.Repository ??= new RepositoryMetadata()).Url = repoUrl; + + if (Manifest.TryGetMetadata("RepositoryBranch", out var repoBranch)) + (metadata.Repository ??= new RepositoryMetadata()).Branch = repoBranch; + + if (Manifest.TryGetMetadata("RepositoryCommit", out var repoCommit)) + (metadata.Repository ??= new RepositoryMetadata()).Commit = repoCommit; + + if (!string.IsNullOrEmpty(Manifest.GetMetadata("ProjectUrl"))) + metadata.SetProjectUrl(Manifest.GetMetadata("ProjectUrl")); + + if (!string.IsNullOrEmpty(Manifest.GetMetadata("ProjectUrl"))) + metadata.SetProjectUrl(Manifest.GetMetadata("ProjectUrl")); + + if (!string.IsNullOrEmpty(Manifest.GetMetadata("IconUrl"))) + metadata.SetIconUrl(Manifest.GetMetadata("IconUrl")); + + if (Manifest.TryGetMetadata("Icon", out var icon)) + metadata.Icon = icon; + + if (Manifest.TryGetMetadata("ReleaseNotes", out var releaseNotes)) + metadata.ReleaseNotes = releaseNotes; + + if (Manifest.TryGetMetadata("Tags", out var tags)) + metadata.Tags = tags; + + if (Manifest.TryGetMetadata("MinClientVersion", out var minClientVersion)) + metadata.MinClientVersionString = minClientVersion; + + metadata.PackageTypes = ParsePackageTypes(Manifest.GetMetadata("PackageTypes")); + + var manifest = new Manifest(metadata); + + AddDependencies(manifest); + AddFiles(manifest); + AddFrameworkAssemblies(manifest); + + return manifest; + } + + void GeneratePackage(Stream output = null) + { + manifest ??= CreateManifest(); + + var builder = new PackageBuilder(); + builder.Populate(manifest.Metadata); + + // We don't use PopulateFiles because that performs search expansion, base path + // extraction and the like, which messes with our determined files to include. + builder.Files.AddRange(manifest.Files.Select(file => + new PhysicalPackageFile { SourcePath = file.Source, TargetPath = file.Target })); + + if (output == null) + { + using var stream = File.Create(TargetPath); + builder.Save(stream); + } + else + { + builder.Save(output); + } + } + + void GenerateNuspec() + { + manifest ??= CreateManifest(); + + Directory.CreateDirectory(Path.GetDirectoryName(NuspecFile)); + + using var stream = File.Create(NuspecFile); + manifest.Save(stream, true); + } + + void AddDependencies(Manifest manifest) + { + var dependencies = from item in Contents + where item.GetMetadata(MetadataName.Kind) == PackageItemKind.Dependency && + !"all".Equals(item.GetMetadata(MetadataName.PrivateAssets), StringComparison.OrdinalIgnoreCase) + select new Dependency + { + Id = item.ItemSpec, + Version = VersionRange.Parse(item.GetMetadata(MetadataName.Version)), + TargetFramework = item.GetNuGetTargetFramework(), + Include = item.GetNullableMetadata(MetadataName.IncludeAssets), + Exclude = item.GetNullableMetadata(MetadataName.ExcludeAssets) + }; + + var definedDependencyGroups = (from dependency in dependencies + group dependency by dependency.TargetFramework into dependenciesByFramework + select new PackageDependencyGroup + ( + dependenciesByFramework.Key, + (from dependency in dependenciesByFramework + where dependency.Id != "_._" + group dependency by dependency.Id into dependenciesById + select new PackageDependency + ( + dependenciesById.Key, + dependenciesById.Select(x => x.Version).Aggregate(AggregateVersions), + dependenciesById.Select(x => x.Include).Aggregate(default(List), AggregateAssetsFlow), + dependenciesById.Select(x => x.Exclude).Aggregate(default(List), AggregateAssetsFlow) + )).ToList() + )).ToDictionary(p => p.TargetFramework.GetFrameworkString()); + + // include frameworks referenced by libraries, but without dependencies.. + foreach (var targetFramework in (from item in Contents + where item.GetMetadata(MetadataName.Kind) == PackageItemKind.Lib && + !"all".Equals(item.GetMetadata(MetadataName.PrivateAssets), StringComparison.OrdinalIgnoreCase) + select item.GetNuGetTargetFramework())) + if (!definedDependencyGroups.ContainsKey(targetFramework.GetFrameworkString())) + definedDependencyGroups.Add(targetFramework.GetFrameworkString(), + new PackageDependencyGroup(targetFramework, Array.Empty())); + + manifest.Metadata.DependencyGroups = definedDependencyGroups.Values; + } + + void AddFiles(Manifest manifest) + { + var contents = new List(); + + var groupedByPackagePath = Contents + .Where(item => !string.IsNullOrEmpty(item.GetMetadata(MetadataName.PackagePath))) + .GroupBy(item => item.GetMetadata(MetadataName.PackagePath)) + // Iterate only once for this grouping. + .ToDictionary(item => item.Key, item => item.ToArray()); + + // Add the ones we already determined as unique by package path. + contents.AddRange(groupedByPackagePath + .Where(group => group.Value.Length == 1) + .Select(group => group.Value.First())); + + var groupedByLastWriteAndLength = groupedByPackagePath + .Where(group => group.Value.Length > 1) + .SelectMany(group => group.Value) + // Tuple provides structural comparison and hashing already, so leverage that. + .GroupBy(item => Tuple.Create( + item.GetMetadata(MetadataName.PackagePath), + item.GetMetadata("Filename"), + item.GetMetadata("Extension"), + File.GetLastWriteTime(item.GetMetadata("FullPath")), + new FileInfo(item.GetMetadata("FullPath")).Length)) + .ToDictionary(item => item.Key, item => item.ToArray()); + + // Add the ones we already determined to be duplicates that can safely be + // unified by package path, file name, last write time and file length. + contents.AddRange(groupedByLastWriteAndLength + .Where(group => group.Value.Length > 1) + .Select(group => group.Value.First())); + + var md5 = new Lazy(() => MD5.Create()); + string hash(ITaskItem item) + { + using (var file = File.OpenRead(item.GetMetadata("FullPath"))) + { + return string.Concat(md5.Value.ComputeHash(file).Select(x => x.ToString("x2"))); + } + } + + // Last remaining attempt at de-duplication is costly, but by now, we should + // have successfully removed all obvious cases. + // This deals with case where the files are modified at different times + // (maybe a generated file?) but their actual contents are the same. + var groupedByContentHash = groupedByLastWriteAndLength + .Where(group => group.Value.Length == 1) + .SelectMany(group => group.Value) + .GroupBy(item => Tuple.Create( + item.GetMetadata(MetadataName.PackagePath), + hash(item))) + .ToDictionary(item => item.Key, item => item.ToArray()); + + // Add the ones we determined to be duplicates that can safely be + // unified by package path and MD5 hash + contents.AddRange(groupedByContentHash + .Where(group => group.Value.Length > 1) + .Select(group => group.Value.First())); + + // At this point, we're 100% certain these are duplicate package path + // files that have distinct sources and would result in one overwriting + // the other or an invalid package. + var duplicates = string.Join(Environment.NewLine, groupedByContentHash + .Where(group => group.Value.Length == 1) + .SelectMany(group => group.Value) + .Select(item => $"'{item.GetMetadata("FullPath")}' > '{item.GetMetadata(MetadataName.PackagePath)}'")); + + if (duplicates.Length > 0) + Log.LogErrorCode(nameof(ErrorCode.NG0012), ErrorCode.NG0012(duplicates)); + + // All files need to be added so they are included in the nupkg + manifest.Files.AddRange(contents + .Select(item => new ManifestFile + { + Source = item.GetMetadata("FullPath"), + Target = item.GetMetadata(MetadataName.PackagePath), + })); + + // Additional metadata for the content files must be added separately + manifest.Metadata.ContentFiles = contents + .Where(item => item.GetMetadata(MetadataName.PackageFolder) == PackagingConstants.Folders.ContentFiles) + .Select(item => new ManifestContentFiles + { + Include = item.GetContentFileInclude(), + BuildAction = item.GetNullableMetadata(MetadataName.ContentFile.BuildAction), + CopyToOutput = item.GetNullableMetadata(MetadataName.ContentFile.CopyToOutput), + Flatten = item.GetNullableMetadata(MetadataName.ContentFile.Flatten), + }).ToArray(); + } + + void AddFrameworkAssemblies(Manifest manifest) + { + var frameworkReferences = (from item in Contents + where item.GetMetadata(MetadataName.Kind) == PackageItemKind.FrameworkReference + select new FrameworkAssemblyReference + ( + item.ItemSpec, + new[] { NuGetFramework.Parse(item.GetTargetFrameworkMoniker().FullName) } + )).Distinct(FrameworkAssemblyReferenceComparer.Default); + + manifest.Metadata.FrameworkReferences = frameworkReferences; + } + + static VersionRange AggregateVersions(VersionRange aggregate, VersionRange next) + { + var versionSpec = new VersionSpec(); + SetMinVersion(versionSpec, aggregate); + SetMinVersion(versionSpec, next); + SetMaxVersion(versionSpec, aggregate); + SetMaxVersion(versionSpec, next); + + if (versionSpec.MinVersion == null && versionSpec.MaxVersion == null) + return null; + + return versionSpec.ToVersionRange(); + } + + static List AggregateAssetsFlow(List aggregate, string next) + { + if (next == null) + return aggregate; + if (aggregate == null) + aggregate = new List(1); + aggregate.AddRange(next.Split(';')); + return aggregate; + } + + static void SetMinVersion(VersionSpec target, VersionRange source) + { + if (source == null || source.MinVersion == null) + return; + + if (target.MinVersion == null) + { + target.MinVersion = source.MinVersion; + target.IsMinInclusive = source.IsMinInclusive; + } + + if (target.MinVersion < source.MinVersion) + { + target.MinVersion = source.MinVersion; + target.IsMinInclusive = source.IsMinInclusive; + } + + if (target.MinVersion == source.MinVersion) + target.IsMinInclusive = target.IsMinInclusive && source.IsMinInclusive; + } + + static void SetMaxVersion(VersionSpec target, VersionRange source) + { + if (source == null || source.MaxVersion == null) + return; + + if (target.MaxVersion == null) + { + target.MaxVersion = source.MaxVersion; + target.IsMaxInclusive = source.IsMaxInclusive; + } + + if (target.MaxVersion > source.MaxVersion) + { + target.MaxVersion = source.MaxVersion; + target.IsMaxInclusive = source.IsMaxInclusive; + } + + if (target.MaxVersion == source.MaxVersion) + target.IsMaxInclusive = target.IsMaxInclusive && source.IsMaxInclusive; + } + + static ICollection ParsePackageTypes(string packageTypes) + { + var listOfPackageTypes = new List(); + if (!string.IsNullOrEmpty(packageTypes)) + { + foreach (var packageType in packageTypes.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)) + { + string[] packageTypeSplitInPart = packageType.Split(new char[] { ',' }); + string packageTypeName = packageTypeSplitInPart[0].Trim(); + var version = PackageType.EmptyVersion; + if (packageTypeSplitInPart.Length > 1) + { + string versionString = packageTypeSplitInPart[1]; + Version.TryParse(versionString, out version); + } + listOfPackageTypes.Add(new PackageType(packageTypeName, version)); + } + } + return listOfPackageTypes; + } + + class Dependency + { + public string Id { get; set; } + + public NuGetFramework TargetFramework { get; set; } + + public VersionRange Version { get; set; } + + public string Include { get; set; } + + public string Exclude { get; set; } + } + + class VersionSpec + { + public bool IsMinInclusive { get; set; } + public NuGetVersion MinVersion { get; set; } + public bool IsMaxInclusive { get; set; } + public NuGetVersion MaxVersion { get; set; } + + public VersionRange ToVersionRange() + { + return new VersionRange(MinVersion, IsMinInclusive, MaxVersion, IsMaxInclusive); + } + } + } +} diff --git a/src/NuGetizer.Tasks/Extensions.cs b/src/NuGetizer.Tasks/Extensions.cs new file mode 100644 index 00000000..2006e5c3 --- /dev/null +++ b/src/NuGetizer.Tasks/Extensions.cs @@ -0,0 +1,146 @@ +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.Versioning; +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; +using NuGetizer.Tasks; +using NuGet.Frameworks; +using NuGet.Packaging; +using NuGet.Packaging.Core; + +namespace NuGetizer +{ + public static class Extensions + { + static readonly FrameworkName NullFramework = new FrameworkName("Null,Version=v1.0"); + + public static IEnumerable NullAsEmpty(this IEnumerable source) => source ?? Enumerable.Empty(); + + public static bool TryGetMetadata(this ITaskItem taskItem, string metadataName, out string value) + { + value = taskItem.GetMetadata(metadataName); + if (string.IsNullOrEmpty(value)) + return false; + + return true; + } + + public static bool TryGetBoolMetadata(this ITaskItem taskItem, string metadataName, out bool value) + { + value = false; + var metadataValue = taskItem.GetMetadata(metadataName); + if (string.IsNullOrEmpty(metadataValue)) + return false; + + return bool.TryParse(metadataValue, out value); + } + + public static bool GetBoolean(this ITaskItem taskItem, string metadataName, bool defaultValue = false) + { + var result = false; + var metadataValue = taskItem.GetMetadata(metadataName); + + return bool.TryParse(metadataValue, out result) && result; + } + + public static string GetNullableMetadata(this ITaskItem taskItem, string metadataName) + { + var value = taskItem.GetMetadata(metadataName); + if (string.IsNullOrEmpty(value)) + return null; + + return value; + } + + public static string GetContentFileInclude(this ITaskItem taskItem) + { + const string contentFilesFolder = @"contentFiles\"; + var include = taskItem.GetMetadata(MetadataName.PackagePath); + if (include.StartsWith(contentFilesFolder)) + return include.Substring(contentFilesFolder.Length); + return include; + } + + public static Manifest GetManifest(this IPackageCoreReader packageReader) + { + using (var stream = packageReader.GetNuspec()) + { + var manifest = Manifest.ReadFrom(stream, true); + manifest.Files.AddRange(packageReader.GetFiles() + // Skip the auto-added stuff + .Where(file => + file != "[Content_Types].xml" && + file != "_rels/.rels" && + !file.EndsWith(".nuspec") && + !file.EndsWith(".psmdcp")) + .Select(file => new ManifestFile + { + // Can't replicate the Source path as it was originally before adding + // to the package, so leave it null to avoid false promises in tests. + //Source = file.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar), + Target = file.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar) + })); + + return manifest; + } + } + + public static NuGetFramework GetNuGetTargetFramework(this ITaskItem taskItem) + { + if (bool.TryParse(taskItem.GetMetadata(MetadataName.FrameworkSpecific), out var frameworkSpecific) && + !frameworkSpecific) + return NuGetFramework.AnyFramework; + + var metadataValue = taskItem.GetMetadata(MetadataName.TargetFramework); + if (string.IsNullOrEmpty(metadataValue)) + metadataValue = taskItem.GetMetadata(MetadataName.TargetFrameworkMoniker); + + if (!string.IsNullOrEmpty(metadataValue)) + return NuGetFramework.Parse(metadataValue); + else + return NuGetFramework.AnyFramework; + } + + public static FrameworkName GetTargetFramework(this ITaskItem taskItem) + { + var metadataValue = taskItem.GetMetadata(MetadataName.TargetFramework); + if (string.IsNullOrEmpty(metadataValue)) + metadataValue = taskItem.GetMetadata(MetadataName.TargetFrameworkMoniker); + + if (!string.IsNullOrEmpty(metadataValue)) + return new FrameworkName(NuGetFramework.Parse(metadataValue).DotNetFrameworkName); + else + return NullFramework; + } + + public static FrameworkName GetTargetFrameworkMoniker(this ITaskItem item) + { + var value = item.GetMetadata(MetadataName.TargetFrameworkMoniker); + // \o/: Turn .NETPortable,Version=v5.0 into .NETPlatform,Version=v5.0, hardcoded for now? + // TODO: should be able to get .NETStandard,Version=v1.x from the item metadata somehow. + + return string.IsNullOrEmpty(value) ? + NullFramework : + new FrameworkName(value); + } + + public static string GetShortFrameworkName(this FrameworkName frameworkName) + { + if (frameworkName == null || frameworkName == NullFramework) + return null; + + // In this case, NuGet returns portable50, is that correct? + //if (frameworkName.Identifier == ".NETPortable" && frameworkName.Version.Major == 5 && frameworkName.Version.Minor == 0) + // return "dotnet"; + + return NuGetFramework.Parse(frameworkName.FullName).GetShortFolderName(); + } + + public static void LogErrorCode(this TaskLoggingHelper log, string code, string message, params object[] messageArgs) => + log.LogError(string.Empty, code, string.Empty, string.Empty, 0, 0, 0, 0, message, messageArgs); + + public static void LogWarningCode(this TaskLoggingHelper log, string code, string file, string message, params object[] messageArgs) => + log.LogWarning(string.Empty, code, string.Empty, file, 0, 0, 0, 0, message, messageArgs); + } +} diff --git a/src/Build/NuGet.Build.Packaging.Tasks/FrameworkAssemblyReferenceComparer.cs b/src/NuGetizer.Tasks/FrameworkAssemblyReferenceComparer.cs similarity index 82% rename from src/Build/NuGet.Build.Packaging.Tasks/FrameworkAssemblyReferenceComparer.cs rename to src/NuGetizer.Tasks/FrameworkAssemblyReferenceComparer.cs index f90a50d9..82ed54a1 100644 --- a/src/Build/NuGet.Build.Packaging.Tasks/FrameworkAssemblyReferenceComparer.cs +++ b/src/NuGetizer.Tasks/FrameworkAssemblyReferenceComparer.cs @@ -3,11 +3,11 @@ using System.Linq; using NuGet.Packaging; -namespace NuGet.Build.Packaging.Tasks +namespace NuGetizer.Tasks { - public class FrameworkAssemblyReferenceComparer : IEqualityComparer + public class FrameworkAssemblyReferenceComparer : IEqualityComparer { - public static FrameworkAssemblyReferenceComparer Default { get; } = new FrameworkAssemblyReferenceComparer(); + public static FrameworkAssemblyReferenceComparer Default { get; } = new FrameworkAssemblyReferenceComparer(); public bool Equals(FrameworkAssemblyReference x, FrameworkAssemblyReference y) { diff --git a/src/NuGetizer.Tasks/MetadataName.cs b/src/NuGetizer.Tasks/MetadataName.cs new file mode 100644 index 00000000..bb2d9c06 --- /dev/null +++ b/src/NuGetizer.Tasks/MetadataName.cs @@ -0,0 +1,62 @@ +namespace NuGetizer.Tasks +{ + public static class MetadataName + { + public const string FileSource = "FullPath"; + + public const string Kind = nameof(Kind); + + public const string Version = nameof(Version); + + /// + /// One of https://github.com/NuGet/NuGet.Client/blob/dev/src/NuGet.Core/NuGet.Packaging/PackagingConstants.cs#L27 + /// + public const string PackageFolder = nameof(PackageFolder); + + /// + /// The package that declares the given package file. + /// + public const string PackageId = nameof(PackageId); + + /// + /// Concatenation of and . + /// For contentFiles, also includes the or any if + /// none was provided. + /// + public const string PackagePath = nameof(PackagePath); + + /// + /// Marks a @(PackageReference) as a development dependency when set to 'All'. + /// + public const string PrivateAssets = nameof(PrivateAssets); + + public const string IncludeAssets = nameof(IncludeAssets); + + public const string ExcludeAssets = nameof(ExcludeAssets); + + /// + /// Whether the project can be packed as a .nupkg. + /// + public const string IsPackable = nameof(IsPackable); + + /// + /// Whether a PackageFile is framework-specific or not. + /// + public const string FrameworkSpecific = nameof(FrameworkSpecific); + + public const string TargetFramework = nameof(TargetFramework); + + public const string TargetFrameworkMoniker = nameof(TargetFrameworkMoniker); + + /// + /// Available optional metadata values of contentFiles. + /// + public static class ContentFile + { + public const string CodeLanguage = nameof(CodeLanguage); + public const string BuildAction = nameof(BuildAction); + public const string CopyToOutput = nameof(CopyToOutput); + public const string Flatten = nameof(Flatten); + } + } +} \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tasks/NuGet.Build.Packaging.Authoring.props b/src/NuGetizer.Tasks/NuGetizer.Authoring.props similarity index 71% rename from src/Build/NuGet.Build.Packaging.Tasks/NuGet.Build.Packaging.Authoring.props rename to src/NuGetizer.Tasks/NuGetizer.Authoring.props index b776f603..7c6df184 100644 --- a/src/Build/NuGet.Build.Packaging.Tasks/NuGet.Build.Packaging.Authoring.props +++ b/src/NuGetizer.Tasks/NuGetizer.Authoring.props @@ -1,6 +1,6 @@ - - PackageReference - netstandard1.0 + + PackageReference + netstandard1.0 net11;net20;net35;net40;net403;net45;net451;net452;net46;net461;net462;net47;net471;net472;net48;netcore;netcore45;netcore451;netcore50;net5.0;win8;win81;win10;sl4;sl5;wp;wp7;wp75;wp8;wp81;wpa81;uap;uap10;netstandard1.0;netstandard1.1;netstandard1.2;netstandard1.3;netstandard1.4;netstandard1.5;netstandard1.6;netstandard2.0;netstandard2.1;netcoreapp1.0;netcoreapp2.0;netcoreapp2.1;netcoreapp2.2;netcoreapp3.0;netcoreapp3.1;monoandroid;monotouch;monomac;xamarinios;xamarinmac;xamarinpsthree;xamarinpsfour;xamarinpsvita;xamarinwatchos;xamarintvos;xamarinxboxthreesixty;xamarinxboxone - .nupkg - - - true + .nupkg - - false + + true - false - + + false - - - - false - - true - + true + diff --git a/src/NuGetizer.Tasks/NuGetizer.Authoring.targets b/src/NuGetizer.Tasks/NuGetizer.Authoring.targets new file mode 100644 index 00000000..58245649 --- /dev/null +++ b/src/NuGetizer.Tasks/NuGetizer.Authoring.targets @@ -0,0 +1,83 @@ + + + + + + $(PackageId) + + + + + + + + + true + false + FromPackagingProject=true + + + + + + + + + + + + + + + + + + + + + + + + + @(PackageTargetPath->'%(FullPath)') + + + + + + + + + + + + + + diff --git a/src/NuGetizer.Tasks/NuGetizer.Compatibility.props b/src/NuGetizer.Tasks/NuGetizer.Compatibility.props new file mode 100644 index 00000000..f7163b03 --- /dev/null +++ b/src/NuGetizer.Tasks/NuGetizer.Compatibility.props @@ -0,0 +1,27 @@ + + + + + true + tool + $(BuildOutputTargetFolder) + $(IncludeSymbols) + $(IncludeContentInPack) + $(IncludeBuildOutput) + $(PackageDescription) + + + diff --git a/src/NuGetizer.Tasks/NuGetizer.Inference.targets b/src/NuGetizer.Tasks/NuGetizer.Inference.targets new file mode 100644 index 00000000..29b9040c --- /dev/null +++ b/src/NuGetizer.Tasks/NuGetizer.Inference.targets @@ -0,0 +1,241 @@ + + + + + + Lib + + + true + + false + + true + + true + + + + true + + <_OutputFullPath Condition="$([System.IO.Path]::IsPathRooted($(OutputPath)))">$(OutputPath) + <_OutputFullPath Condition="'$(_OutputFullPath)' == ''">$(MSBuildProjectDirectory.TrimEnd('\'))\$(OutputPath) + + + + + $(GetPackageContentsDependsOn); + _BuildOutputFrameworkSpecific; + InferPackageContents + + + + + + + + + + false + false + + + + <_ReferenceRelatedPaths> + false + false + + + + + + + + + <_BuildOutputKindFrameworkSpecific Include="@(PackageItemKind->'%(FrameworkSpecific)')" Condition="'%(Identity)' == '$(BuildOutputKind)'" /> + + + @(_BuildOutputKindFrameworkSpecific) + + + + + + + + + + + + + + + + <_SatelliteDllsProjectOutputGroupOutput Include="@(SatelliteDllsProjectOutputGroupOutput)" FinalOutputPath="'%(FullPath)')" /> + + <_InferredProjectOutput Include="@(BuiltProjectOutputGroupOutput -> '%(FinalOutputPath)'); + @(BuiltProjectOutputGroupKeyOutput -> '%(FinalOutputPath)'); + @(DocumentationProjectOutputGroupOutput -> '%(FinalOutputPath)'); + @(_SatelliteDllsProjectOutputGroupOutput -> '%(FinalOutputPath)')" + Condition="'$(PackBuildOutput)' == 'true'"> + $(BuildOutputKind) + $(BuildOutputFrameworkSpecific) + + + <_InferredProjectOutput Include="@(DebugSymbolsProjectOutputGroupOutput -> '%(FinalOutputPath)')" + Condition="'$(PackBuildOutput)' == 'true' and '$(PackSymbols)' != 'false'"> + $(BuildOutputKind) + $(BuildOutputFrameworkSpecific) + + + <_InferredPackageFile Include="@(_InferredProjectOutput -> Distinct())" /> + + + + <_InferredPackageFile Include="@(_ContentToInfer->'$(_OutputFullPath)\%(TargetPath)')" + Condition="'%(_ContentToInfer.CopyToOutputDirectory)' != '' and '%(_ContentToInfer.CopyToOutputDirectory)' != 'Never'"> + $(BuildOutputKind) + + + <_InferredPackageFile Include="@(_ContentToInfer->'%(FullPath)')" + Condition="'%(_ContentToInfer.CopyToOutputDirectory)' == '' or '%(_ContentToInfer.CopyToOutputDirectory)' == 'Never'"> + Content + + + + + <_InferredPackageFile Include="@(_NoneToInfer->'$(_OutputFullPath)\%(TargetPath)')" + Condition="'%(_NoneToInfer.CopyToOutputDirectory)' != '' and '%(_NoneToInfer.CopyToOutputDirectory)' != 'Never'"> + $(BuildOutputKind) + + <_InferredPackageFile Include="@(_NoneToInfer->'%(FullPath)')" + Condition="'%(_NoneToInfer.CopyToOutputDirectory)' == '' or '%(_NoneToInfer.CopyToOutputDirectory)' == 'Never'"> + None + + + <_InferredPackageFile Include="@(PackageReference)" + Condition="'%(PackageReference.Identity)' != 'NuGetizer' and + '%(PackageReference.Identity)' != 'NETStandard.Library' and + '%(PackageReference.PrivateAssets)' != 'all' and + '%(PackageReference.Pack)' != 'false'"> + Dependency + + + + <_InferredPackageFile Include="@(ReferencePath->'%(OriginalItemSpec)')" + Condition="'$(PackFrameworkReferences)' == 'true' and '%(ReferencePath.ResolvedFrom)' == '{TargetFrameworkDirectory}' and '%(ReferencePath.Pack)' != 'false'"> + FrameworkReference + + + + + + + Implicit + $(PackageId) + $(Platform) + $(TargetFrameworkMoniker) + + + + + + + <_PrimaryOutputRelatedFile Include="@(ReferencePath);@(_ReferenceRelatedPaths)" + Condition="'%(NuGetPackageId)' != 'NETStandard.Library' and + '%(Facade)' != 'true' and + '%(FrameworkFile)' != 'true' and + '%(Pack)' != 'false'"/> + + + + + + <_NuGetPackageId Include="@(_PrimaryOutputRelatedFile -> '%(NuGetPackageId)')" Condition="'%(NuGetPackageId)' != 'NETStandard.Library'" /> + + + <_NuGetPackageId>@(_NuGetPackageId -> Distinct()) + + + <_PrimaryPackageReference Include="@(PackageReference)" Condition="'$(_NuGetPackageId)' != '' and '%(Identity)' == '$(_NuGetPackageId)'" /> + + + <_PrivateAssets>@(_PrimaryPackageReference -> '%(PrivateAssets)') + <_ShouldIncludeAssetsRegex>$(_NuGetPackageId)\\.+\\$(_PrivateAssets)\\.* + + + + <_InferredPackageFile Include="@(_PrimaryOutputRelatedFile)" Condition="'%(_PrimaryOutputRelatedFile.FrameworkFile)' != 'true'"> + $(BuildOutputKind) + $(BuildOutputFrameworkSpecific) + + + + + + <_InferredPackageFile Include="@(_PrimaryOutputRelatedFile)" Condition="$([System.Text.RegularExpressions.Regex]::IsMatch('%(_PrimaryOutputRelatedFile.FullPath)', '$(_ShouldIncludeAssetsRegex)', 'RegexOptions.IgnoreCase')) == 'true'"> + $(BuildOutputKind) + $(BuildOutputFrameworkSpecific) + + + + + + + + <_SupportsReferences Condition=" + $(_AllProjectCapabilities.Contains('AssemblyReferences')) or + $(_AllProjectCapabilities.Contains('COMReferences')) or + $(_AllProjectCapabilities.Contains('ProjectReferences')) or + $(_AllProjectCapabilities.Contains('PackageReferences')) or + $(_AllProjectCapabilities.Contains('WinRTReferences')) or + $(_AllProjectCapabilities.Contains('SDKReferences'))">true + + + ResolveReferences; + InferPrimaryOutputDependencies + + + $(InferPackageContentsDependsOn); + GetPackageTargetPath + + + $(InferPackageContentsDependsOn); + AllProjectOutputGroups + + + + + diff --git a/src/Build/NuGet.Build.Packaging.Tasks/NuGet.Build.Packaging.Compatibility.props b/src/NuGetizer.Tasks/NuGetizer.MultiTargeting.props similarity index 56% rename from src/Build/NuGet.Build.Packaging.Tasks/NuGet.Build.Packaging.Compatibility.props rename to src/NuGetizer.Tasks/NuGetizer.MultiTargeting.props index fdc428ca..3d2538b3 100644 --- a/src/Build/NuGet.Build.Packaging.Tasks/NuGet.Build.Packaging.Compatibility.props +++ b/src/NuGetizer.Tasks/NuGetizer.MultiTargeting.props @@ -1,6 +1,6 @@ - - - - true - tool - $(IncludeSymbols) - - + + ..\build\NuGetizer.props + ..\build\NuGetizer.Shared.targets + + + + diff --git a/src/NuGetizer.Tasks/NuGetizer.MultiTargeting.targets b/src/NuGetizer.Tasks/NuGetizer.MultiTargeting.targets new file mode 100644 index 00000000..004ab3ed --- /dev/null +++ b/src/NuGetizer.Tasks/NuGetizer.MultiTargeting.targets @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + <_PackageMetadataContent Include="@(_PackageContent -> WithMetadataValue('Kind', 'Metadata'))" /> + <_PackageContent Remove="@(_PackageMetadataContent)" /> + <_PackageContent Include="@(_PackageMetadataContent -> Distinct())"> + + $(Platform) + + + + + + + + + diff --git a/src/NuGetizer.Tasks/NuGetizer.PackageMetadata.targets b/src/NuGetizer.Tasks/NuGetizer.PackageMetadata.targets new file mode 100644 index 00000000..8bb075d0 --- /dev/null +++ b/src/NuGetizer.Tasks/NuGetizer.PackageMetadata.targets @@ -0,0 +1,43 @@ + + + + + + $(PackageId) + true + + $(Authors) + $(Owners) + $(Title) + $(Description) + $(Summary) + $(NeutralLanguage) + $(Copyright) + $(PackageReleaseNotes) + true + $(PackageLicenseUrl) + $(PackageLicenseExpression) + $(PackageIcon) + $(PackageIconUrl) + $(PackageTags) + $(PackageProjectUrl) + $(PackageType) + + $(RepositoryType) + $(RepositoryUrl) + $(RepositoryBranch) + $(RepositoryCommit) + + + + diff --git a/src/NuGetizer.Tasks/NuGetizer.Shared.targets b/src/NuGetizer.Tasks/NuGetizer.Shared.targets new file mode 100644 index 00000000..427bd3e6 --- /dev/null +++ b/src/NuGetizer.Tasks/NuGetizer.Shared.targets @@ -0,0 +1,252 @@ + + + + + + + + + + true + + + + + + $(BaseOutputPath) + + + true + + + false + $(BaseOutputPath.TrimEnd('\'))\$(PackageId).nuspec + $(BaseOutputPath.TrimEnd('\'))\$(AssemblyName).nuspec + + + + true + false + + true + + + + + + + + + + + $(IsPackable) + true + + + + + + + $(GetPackageVersionDependsOn); + _SetDefaultPackageVersion + + + + + + $(Version) + + + + + + + $(GetPackageMetadataDependsOn); + _InitializeRepositoryProperties; + GetPackageVersion; + + + + + + + + $(PackageId) + true + $(Authors) + $(Owners) + $(Title) + $(Description) + $(Summary) + $(NeutralLanguage) + $(Copyright) + $(PackageReleaseNotes) + true + $(PackageLicenseUrl) + $(PackageLicenseExpression) + $(PackageIcon) + $(PackageIconUrl) + $(PackageTags) + $(PackageProjectUrl) + $(PackageType) + + + + + $(PackageVersion) + + $(RepositoryType) + $(RepositoryUrl) + $(RepositoryBranch) + $(RepositoryCommit) + + + + + + + + $(PrivateRepositoryUrl) + $(SourceRevisionId) + + + + + + + $(GetPackageTargetPathDependsOn); + GetPackageMetadata; + _SetDefaultPackageTargetPath; + + + + + + $([System.IO.Path]::GetFullPath('$(PackageTargetPath)')) + + + + + + + + $([System.IO.Path]::Combine('$(PackageOutputPath)', '$(PackageId).$(PackageVersion).nupkg')) + + + + + + GetPackageTargetPath;$(PackageOutputGroupDependsOn) + + + + + + + <_ShouldPackOnBuild Condition="'$(PackOnBuild)' == 'true' And '$(IsPackable)' == 'true'">true + + $(BuildDependsOn); + Pack; + + + + Build; + + + $(PackDependsOn) + GetPackageTargetPath; + GetPackageContents + + + + + + + + + + + + + + + + diff --git a/src/NuGetizer.Tasks/NuGetizer.Tasks.csproj b/src/NuGetizer.Tasks/NuGetizer.Tasks.csproj new file mode 100644 index 00000000..5ef44a62 --- /dev/null +++ b/src/NuGetizer.Tasks/NuGetizer.Tasks.csproj @@ -0,0 +1,41 @@ + + + + netstandard2.0 + NuGetizer + true + NuGetizer + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/NuGetizer.Tasks/NuGetizer.Tasks.targets b/src/NuGetizer.Tasks/NuGetizer.Tasks.targets new file mode 100644 index 00000000..da70f077 --- /dev/null +++ b/src/NuGetizer.Tasks/NuGetizer.Tasks.targets @@ -0,0 +1,88 @@ + + + + + + + + + PreserveNewest + true + + + + + $(MSBuildAllProjects);$(MSBuildThisFileFullPath) + + NuGetizer + NuGetizer + Simple, flexible and powerful NuGet packaging + icon.png + + true + build + + true + ..\..\bin + + + + + + + + + + + + <Namespace Prefix='msb' Uri='http://schemas.microsoft.com/developer/msbuild/2003'/> + + + + + + + PackageItemKind; + $(CoreCompileDependsOn); + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Build/NuGet.Build.Packaging.Tasks/NuGet.Build.Packaging.Version.props b/src/NuGetizer.Tasks/NuGetizer.Version.props similarity index 85% rename from src/Build/NuGet.Build.Packaging.Tasks/NuGet.Build.Packaging.Version.props rename to src/NuGetizer.Tasks/NuGetizer.Version.props index 8ec7c5ca..f5585ad3 100644 --- a/src/Build/NuGet.Build.Packaging.Tasks/NuGet.Build.Packaging.Version.props +++ b/src/NuGetizer.Tasks/NuGetizer.Version.props @@ -1,6 +1,6 @@ - 1.0.0 + 1.0.0 \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tasks/NuGet.Build.Packaging.props b/src/NuGetizer.Tasks/NuGetizer.props similarity index 85% rename from src/Build/NuGet.Build.Packaging.Tasks/NuGet.Build.Packaging.props rename to src/NuGetizer.Tasks/NuGetizer.props index 0c230589..55cbcfaf 100644 --- a/src/Build/NuGet.Build.Packaging.Tasks/NuGet.Build.Packaging.props +++ b/src/NuGetizer.Tasks/NuGetizer.props @@ -1,6 +1,6 @@ - + + true - - NO-SDK-PACK false true + + + $(MSBuildThisFileDirectory)NuGetizer.PackageMetadata.targets + true + + @@ -122,12 +127,13 @@ Copyright (c) .NET Foundation. All rights reserved. - + true - true + true - - + + + diff --git a/src/NuGetizer.Tasks/NuGetizer.targets b/src/NuGetizer.Tasks/NuGetizer.targets new file mode 100644 index 00000000..d4f2ea7d --- /dev/null +++ b/src/NuGetizer.Tasks/NuGetizer.targets @@ -0,0 +1,223 @@ + + + + + + + + + + + + + + + + + $(GetPackageContentsDependsOn); + GetPackageTargetPath; + _AddPackageManifest + + + $(GetPackageContentsDependsOn); + _GetReferencedPackageContents + + + + + + + + $(PackageId) + $(Platform) + $(TargetFrameworkMoniker) + + + + + + + + + + + + + + Metadata + $(PackageId) + $(Platform) + $(TargetFrameworkMoniker) + + + + + + + + + + + + + + + + <_ReferencedPackageDependency Include="@(_ReferencedPackageContent)" + Condition="'%(_ReferencedPackageContent.PackageId)' != '$(PackageId)' and '%(_ReferencedPackageContent.Kind)' == 'Metadata'"> + + $(PackageId) + $(TargetFrameworkMoniker) + Dependency + + + <_PackageContentFromDependency Include="@(_ReferencedPackageContent)" + Condition="'%(_ReferencedPackageContent.PackageId)' != '' and '%(_ReferencedPackageContent.PackageId)' != '$(PackageId)'" /> + <_ReferencedPackageContent Remove="@(_PackageContentFromDependency)" /> + + + + + + + + + + <_ReferencedPackageContentWithOriginalValues Condition="'%(_ReferencedPackageContentWithOriginalValues.PackageId)' == ''"> + $(PackageId) + + + + + $(TargetFrameworkMoniker) + + + + + + + <_ReferencedPackageContentWithOriginalValues Condition="'%(_ReferencedPackageContentWithOriginalValues.PackageId)' == ''"> + $(PackageId) + + + + %(_ReferencedPackageContentWithOriginalValues.OriginalTargetFrameworkMoniker) + + + + + + + $(BuildingPackage) + + + + + + + + + + + + + <_ShouldPack>%(_MSBuildProjectReferenceExistent.Pack) + <_IsNuGetized>%(_ReferencedProjectTargetPath.IsNuGetized) + + + + + + <_NonNuGetizedProjectReference Include="@(_MSBuildProjectReferenceExistent)" Condition="'$(_IsNuGetized)' != 'true'" /> + + <_NuGetizedProjectReference Include="@(_MSBuildProjectReferenceExistent)" Condition="'$(_IsNuGetized)' == 'true'" /> + + + + + + + <_AllProjectCapabilities>@(ProjectCapability) + + <_SupportsProjectReferences>$(_AllProjectCapabilities.Contains('ProjectReferences')) + <_GetReferencedPackageContentsDependsOn Condition="'$(_SupportsProjectReferences)' == 'true'"> + $(_GetReferencedPackageContentsDependsOn); + AssignProjectConfiguration; + _SplitProjectReferencesByFileExistence; + _SplitProjectReferencesByIsNuGetized + + + + + + + diff --git a/src/Build/NuGet.Build.Packaging.Tasks/Resources.resx b/src/NuGetizer.Tasks/Resources.resx similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tasks/Resources.resx rename to src/NuGetizer.Tasks/Resources.resx diff --git a/src/NuGetizer.Tasks/WriteItemsToFile.cs b/src/NuGetizer.Tasks/WriteItemsToFile.cs new file mode 100644 index 00000000..f85b7bac --- /dev/null +++ b/src/NuGetizer.Tasks/WriteItemsToFile.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Xml.Linq; +using Microsoft.Build.Framework; +using Microsoft.Build.Utilities; + +namespace NuGetizer.Tasks +{ + /// + /// Writes items to an MSBuild document. + /// + public class WriteItemsToFile : Task + { + [Required] + public ITaskItem[] Items { get; set; } = Array.Empty(); + + public string ItemName { get; set; } + + [Required] + public ITaskItem File { get; set; } + + public string IncludeMetadata { get; set; } = "true"; + + public string UseFullPath { get; set; } = "false"; + + public string Overwrite { get; set; } = "true"; + + public override bool Execute() + { + var itemName = ItemName ?? "None"; + var includeMetadata = bool.Parse(IncludeMetadata); + var useFullPath = bool.Parse(UseFullPath); + var overwrite = bool.Parse(Overwrite); + + Func> metadataFromItem; + if (includeMetadata) + metadataFromItem = item => item.CloneCustomMetadata() + .OfType>() + .Select(entry => new XElement(entry.Key, entry.Value)); + else + metadataFromItem = item => Enumerable.Empty(); + + Func itemFromElement = item => new XElement(itemName, + new XAttribute("Include", useFullPath ? item.GetMetadata("FullPath") : item.ItemSpec), metadataFromItem(item)); + var filePath = File.GetMetadata("FullPath"); + + XDocument document; + if (!overwrite && System.IO.File.Exists(filePath)) + document = XDocument.Load(filePath); + else + document = new XDocument(new XElement("Project")); + + document.Root.Add( + new XElement("ItemGroup", + Items.Select(item => itemFromElement(item)))); + + if (overwrite && System.IO.File.Exists(filePath)) + System.IO.File.Delete(filePath); + + if (!Directory.Exists(Path.GetDirectoryName(filePath))) + Directory.CreateDirectory(Path.GetDirectoryName(filePath)); + + document.Save(filePath); + + return true; + } + } +} diff --git a/src/NuGetizer.Tasks/dotnet-nugetize.props b/src/NuGetizer.Tasks/dotnet-nugetize.props new file mode 100644 index 00000000..43bf4a5f --- /dev/null +++ b/src/NuGetizer.Tasks/dotnet-nugetize.props @@ -0,0 +1,19 @@ + + + + + + $(MSBuildThisFileDirectory)dotnet-nugetize.targets + + + \ No newline at end of file diff --git a/src/NuGetizer.Tasks/dotnet-nugetize.targets b/src/NuGetizer.Tasks/dotnet-nugetize.targets new file mode 100644 index 00000000..b75930cc --- /dev/null +++ b/src/NuGetizer.Tasks/dotnet-nugetize.targets @@ -0,0 +1,30 @@ + + + + + + + + <_AbsoluteNuspecFile Condition="$([System.IO.Path]::IsPathRooted($(NuspecFile)))">$(NuspecFile) + <_AbsoluteNuspecFile Condition="'$(_NuspecFile)' == ''">$(MSBuildProjectDirectory.TrimEnd('\'))\$(NuspecFile) + <_AbsoluteNuspecFile>$([System.IO.Path]::GetFullPath('$(_AbsoluteNuspecFile)')) + + + + + + + + + + \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tests/AssignPackagePathTests.cs b/src/NuGetizer.Tests/AssignPackagePathTests.cs similarity index 99% rename from src/Build/NuGet.Build.Packaging.Tests/AssignPackagePathTests.cs rename to src/NuGetizer.Tests/AssignPackagePathTests.cs index 5a552388..3364e8fc 100644 --- a/src/Build/NuGet.Build.Packaging.Tests/AssignPackagePathTests.cs +++ b/src/NuGetizer.Tests/AssignPackagePathTests.cs @@ -6,18 +6,18 @@ using Xunit; using Xunit.Abstractions; using System.Linq; -using NuGet.Build.Packaging.Tasks; +using NuGetizer.Tasks; using Metadata = System.Collections.Generic.Dictionary; using System; -namespace NuGet.Build.Packaging +namespace NuGetizer { public class AssignPackagePathTests { static ITaskItem[] kinds; static ITaskItem[] Kinds - => kinds ??= new Project(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "NuGet.Build.Packaging.props"), null, null, new ProjectCollection()) + => kinds ??= new Project(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "NuGetizer.props"), null, null, new ProjectCollection()) .GetItems("PackageItemKind") .Select(item => new TaskItem(item.EvaluatedInclude, item.Metadata.ToDictionary(meta => meta.Name, meta => meta.UnevaluatedValue))) .ToArray(); diff --git a/src/Build/NuGet.Build.Packaging.Tests/Builder.NuGetizer.cs b/src/NuGetizer.Tests/Builder.NuGetizer.cs similarity index 88% rename from src/Build/NuGet.Build.Packaging.Tests/Builder.NuGetizer.cs rename to src/NuGetizer.Tests/Builder.NuGetizer.cs index 2175c76d..2c4622ba 100644 --- a/src/Build/NuGet.Build.Packaging.Tests/Builder.NuGetizer.cs +++ b/src/NuGetizer.Tests/Builder.NuGetizer.cs @@ -17,7 +17,7 @@ /// static partial class Builder { - public static TargetResult BuildScenario( + public static TargetResult BuildScenario( string scenarioName, object properties = null, string projectName = null, @@ -62,8 +62,23 @@ public static TargetResult BuildScenario( logger = new TestOutputLogger(null); } - var loggers = OpenBuildLogAttribute.IsActive ? - new ILogger[] { logger, new StructuredLogger { Verbosity = verbosity.GetValueOrDefault(), Parameters = scenarioName + ".binlog" } } : + var logFile = scenarioName + ".binlog"; + + if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("SYSTEM_DEFAULTWORKINGDIRECTORY"))) + { + var logDir = Path.Combine(Environment.GetEnvironmentVariable("SYSTEM_DEFAULTWORKINGDIRECTORY"), "logs"); + if (!Directory.Exists(logDir)) + Directory.CreateDirectory(logDir); + + logFile = Path.Combine(logDir, logFile); + } + + var loggers = OpenBuildLogAttribute.IsActive || Environment.GetEnvironmentVariable("SYSTEM_DEBUG") == "true" ? + new ILogger[] { logger, new StructuredLogger + { + Verbosity = LoggerVerbosity.Diagnostic, + Parameters = logFile + } } : new ILogger[] { logger }; var buildProps = properties?.GetType().GetProperties() diff --git a/src/Build/NuGet.Build.Packaging.Tests/Builder.cs b/src/NuGetizer.Tests/Builder.cs similarity index 96% rename from src/Build/NuGet.Build.Packaging.Tests/Builder.cs rename to src/NuGetizer.Tests/Builder.cs index acdbb793..a895924d 100644 --- a/src/Build/NuGet.Build.Packaging.Tests/Builder.cs +++ b/src/NuGetizer.Tests/Builder.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Runtime.CompilerServices; using System.Xml.Linq; using Microsoft.Build.Evaluation; using Microsoft.Build.Execution; @@ -58,6 +59,8 @@ public static BuildResult Build(string projectOrSolution, string targets, Dictio return Build(projectInstance, targets, properties, loggers); } + public static string TestOutputPath([CallerMemberName] string testName = null) => "bin\\" + testName + "\\"; + static void AddSolutionConfiguration(string projectFile, Dictionary properties) { var collection = new ProjectCollection(properties); diff --git a/src/Build/NuGet.Build.Packaging.Tests/CreatePackageTests.cs b/src/NuGetizer.Tests/CreatePackageTests.cs similarity index 97% rename from src/Build/NuGet.Build.Packaging.Tests/CreatePackageTests.cs rename to src/NuGetizer.Tests/CreatePackageTests.cs index 426eaab3..5d47c69e 100644 --- a/src/Build/NuGet.Build.Packaging.Tests/CreatePackageTests.cs +++ b/src/NuGetizer.Tests/CreatePackageTests.cs @@ -10,10 +10,11 @@ using NuGet.Frameworks; using NuGet.Packaging.Core; using Metadata = System.Collections.Generic.Dictionary; -using NuGet.Build.Packaging.Tasks; +using NuGetizer.Tasks; using NuGet.Packaging; +using NuGet.Packaging.Licenses; -namespace NuGet.Build.Packaging +namespace NuGetizer { public class CreatePackageTests { @@ -85,7 +86,7 @@ public void when_creating_package_then_contains_all_metadata() Assert.True(metadata.RequireLicenseAcceptance); - Assert.Equal(task.Manifest.GetMetadata("Id"), metadata.Id); + Assert.Equal(task.Manifest.GetMetadata("PackageId"), metadata.Id); Assert.Equal(task.Manifest.GetMetadata("Version"), metadata.Version.ToString()); Assert.Equal(task.Manifest.GetMetadata("Title"), metadata.Title); Assert.Equal(task.Manifest.GetMetadata("Description"), metadata.Description); @@ -127,7 +128,21 @@ public void when_creating_package_has_development_dependency_metadata_then_manif Assert.True(metadata.DevelopmentDependency); } - [Fact] + [Fact] + public void when_creating_package_has_license_expression_then_manifest_has_license() + { + task.Manifest.SetMetadata("LicenseUrl", ""); + task.Manifest.SetMetadata("LicenseExpression", "MIT"); + + var metadata = ExecuteTask().Metadata; + + Assert.Equal("MIT", metadata.LicenseMetadata.License); + Assert.Equal(LicenseType.Expression, metadata.LicenseMetadata.Type); + Assert.Equal(LicenseExpressionType.License, metadata.LicenseMetadata.LicenseExpression.Type); + Assert.True(metadata.LicenseMetadata.LicenseExpression is NuGetLicense license && license.IsStandardLicense); + } + + [Fact] public void when_creating_package_with_simple_dependency_then_contains_dependency_group() { task.Contents = new[] diff --git a/src/Build/NuGet.Build.Packaging.Tests/ModuleInitializer.cs b/src/NuGetizer.Tests/ModuleInitializer.cs similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/ModuleInitializer.cs rename to src/NuGetizer.Tests/ModuleInitializer.cs diff --git a/src/Build/NuGet.Build.Packaging.Tests/NuGet.Build.Packaging.Tests.csproj b/src/NuGetizer.Tests/NuGetizer.Tests.csproj similarity index 83% rename from src/Build/NuGet.Build.Packaging.Tests/NuGet.Build.Packaging.Tests.csproj rename to src/NuGetizer.Tests/NuGetizer.Tests.csproj index d4e810ae..83a53602 100644 --- a/src/Build/NuGet.Build.Packaging.Tests/NuGet.Build.Packaging.Tests.csproj +++ b/src/NuGetizer.Tests/NuGetizer.Tests.csproj @@ -2,7 +2,6 @@ net472 - NO-SDK-PACK $(DefaultItemExcludes);Scenarios\**\* Preview @@ -10,7 +9,7 @@ - ..\NuGet.Build.Packaging.Tasks\bin\$(Configuration)\NuGet.Build.Packaging.Tasks.dll + ..\NuGetizer.Tasks\bin\$(Configuration)\NuGetizer.Tasks.dll @@ -32,12 +31,12 @@ - - + + - + @@ -61,6 +60,6 @@ - + \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tests/NuGet.Build.Packaging.Tests.targets b/src/NuGetizer.Tests/NuGetizer.Tests.targets similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/NuGet.Build.Packaging.Tests.targets rename to src/NuGetizer.Tests/NuGetizer.Tests.targets diff --git a/src/NuGetizer.Tests/Scenarios/Directory.Build.props b/src/NuGetizer.Tests/Scenarios/Directory.Build.props new file mode 100644 index 00000000..f3a2214b --- /dev/null +++ b/src/NuGetizer.Tests/Scenarios/Directory.Build.props @@ -0,0 +1,22 @@ + + + + false + false + false + false + + + bin\$(MSBuildProjectName)\ + $(BaseOutputPath)\ + obj\$(MSBuildProjectName)\ + $(BaseIntermediateOutputPath)\ + + + $(BaseOutputPath) + + + None + + + \ No newline at end of file diff --git a/src/NuGetizer.Tests/Scenarios/Directory.Build.targets b/src/NuGetizer.Tests/Scenarios/Directory.Build.targets new file mode 100644 index 00000000..67b7bd51 --- /dev/null +++ b/src/NuGetizer.Tests/Scenarios/Directory.Build.targets @@ -0,0 +1,13 @@ + + + + $(OutputPath)\$(AssemblyName).xml + + + + + + + + + \ No newline at end of file diff --git a/src/NuGetizer.Tests/Scenarios/Scenario.props b/src/NuGetizer.Tests/Scenarios/Scenario.props new file mode 100644 index 00000000..5d5e877d --- /dev/null +++ b/src/NuGetizer.Tests/Scenarios/Scenario.props @@ -0,0 +1,31 @@ + + + + Scenario + + + {AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA} + {BBBBBBBB-BBBB-BBBB-BBBB-BBBBBBBBBBBB} + {CCCCCCCC-CCCC-CCCC-CCCC-CCCCCCCCCCCC} + {DDDDDDDD-DDDD-DDDD-DDDD-DDDDDDDDDDDD} + {EEEEEEEE-EEEE-EEEE-EEEE-EEEEEEEEEEEE} + {FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF} + + $(GuidA) + + + + + NuGet + Package for '$(MSBuildProjectName)' project. + + + $([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), NuGetizer.props)) + + $(MSBuildThisFileDirectory)..\..\NuGetizer.Tasks\bin\$(Configuration) + $(NuGetTargetsPath)\NuGetizer.props + $(NuGetTargetsPath)\NuGetizer.Shared.targets + + + + \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/Scenario.targets b/src/NuGetizer.Tests/Scenarios/Scenario.targets similarity index 64% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/Scenario.targets rename to src/NuGetizer.Tests/Scenarios/Scenario.targets index 5ba566d0..b3ec0a04 100644 --- a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/Scenario.targets +++ b/src/NuGetizer.Tests/Scenarios/Scenario.targets @@ -1,26 +1,16 @@  - - $(OutputPath)\$(AssemblyName).xml - - - - - - - - - - + + - @@ -89,6 +79,6 @@ - + \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/_._ b/src/NuGetizer.Tests/Scenarios/_._ similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/_._ rename to src/NuGetizer.Tests/Scenarios/_._ diff --git a/src/NuGetizer.Tests/Scenarios/given_a_complex_pack/a.csproj b/src/NuGetizer.Tests/Scenarios/given_a_complex_pack/a.csproj new file mode 100644 index 00000000..fdee25bb --- /dev/null +++ b/src/NuGetizer.Tests/Scenarios/given_a_complex_pack/a.csproj @@ -0,0 +1,12 @@ + + + + net472 + A + 1.0.0 + + + + + + \ No newline at end of file diff --git a/src/NuGetizer.Tests/Scenarios/given_a_complex_pack/b.csproj b/src/NuGetizer.Tests/Scenarios/given_a_complex_pack/b.csproj new file mode 100644 index 00000000..3bb618ce --- /dev/null +++ b/src/NuGetizer.Tests/Scenarios/given_a_complex_pack/b.csproj @@ -0,0 +1,12 @@ + + + + net472 + B + 2.0.0 + + + + + + \ No newline at end of file diff --git a/src/NuGetizer.Tests/Scenarios/given_a_complex_pack/c.csproj b/src/NuGetizer.Tests/Scenarios/given_a_complex_pack/c.csproj new file mode 100644 index 00000000..46d64482 --- /dev/null +++ b/src/NuGetizer.Tests/Scenarios/given_a_complex_pack/c.csproj @@ -0,0 +1,13 @@ + + + + net45 + C + 3.0.0 + + + + 1.0.0 + + + \ No newline at end of file diff --git a/src/NuGetizer.Tests/Scenarios/given_a_complex_pack/d.csproj b/src/NuGetizer.Tests/Scenarios/given_a_complex_pack/d.csproj new file mode 100644 index 00000000..d0b1c40a --- /dev/null +++ b/src/NuGetizer.Tests/Scenarios/given_a_complex_pack/d.csproj @@ -0,0 +1,6 @@ + + + + netstandard1.6 + + \ No newline at end of file diff --git a/src/NuGetizer.Tests/Scenarios/given_a_complex_pack/e.csproj b/src/NuGetizer.Tests/Scenarios/given_a_complex_pack/e.csproj new file mode 100644 index 00000000..e2564a9e --- /dev/null +++ b/src/NuGetizer.Tests/Scenarios/given_a_complex_pack/e.csproj @@ -0,0 +1,6 @@ + + + + net45 + + \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_complex_pack/pack.sln b/src/NuGetizer.Tests/Scenarios/given_a_complex_pack/pack.sln similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_complex_pack/pack.sln rename to src/NuGetizer.Tests/Scenarios/given_a_complex_pack/pack.sln diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_custom_build_project/Readme.txt b/src/NuGetizer.Tests/Scenarios/given_a_custom_build_project/Readme.txt similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_custom_build_project/Readme.txt rename to src/NuGetizer.Tests/Scenarios/given_a_custom_build_project/Readme.txt diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_custom_build_project/build.proj b/src/NuGetizer.Tests/Scenarios/given_a_custom_build_project/build.proj similarity index 72% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_custom_build_project/build.proj rename to src/NuGetizer.Tests/Scenarios/given_a_custom_build_project/build.proj index 8e54f1a4..3185f135 100644 --- a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_custom_build_project/build.proj +++ b/src/NuGetizer.Tests/Scenarios/given_a_custom_build_project/build.proj @@ -1,11 +1,11 @@ - $([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), NuGet.Build.Packaging.props)) + $([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), NuGetizer.props)) - $(MSBuildThisFileDirectory)..\..\NuGet.Build.Packaging.Tasks\bin\Debug + $(MSBuildThisFileDirectory)..\..\NuGetizer.Tasks\bin\Debug - + build @@ -17,5 +17,5 @@ - + \ No newline at end of file diff --git a/src/NuGetizer.Tests/Scenarios/given_a_framework_library/framework_library_project.csproj b/src/NuGetizer.Tests/Scenarios/given_a_framework_library/framework_library_project.csproj new file mode 100644 index 00000000..fead9cb5 --- /dev/null +++ b/src/NuGetizer.Tests/Scenarios/given_a_framework_library/framework_library_project.csproj @@ -0,0 +1,14 @@ + + + + + net472 + + + + + + + + + \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/Resources/drawable-hdpi/Icon.png b/src/NuGetizer.Tests/Scenarios/given_a_library_with_content/Resources/drawable-hdpi/Icon.png similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/Resources/drawable-hdpi/Icon.png rename to src/NuGetizer.Tests/Scenarios/given_a_library_with_content/Resources/drawable-hdpi/Icon.png diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/Resources/drawable-mdpi/Icon.png b/src/NuGetizer.Tests/Scenarios/given_a_library_with_content/Resources/drawable-mdpi/Icon.png similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/Resources/drawable-mdpi/Icon.png rename to src/NuGetizer.Tests/Scenarios/given_a_library_with_content/Resources/drawable-mdpi/Icon.png diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/Resources/drawable-xhdpi/Icon.png b/src/NuGetizer.Tests/Scenarios/given_a_library_with_content/Resources/drawable-xhdpi/Icon.png similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/Resources/drawable-xhdpi/Icon.png rename to src/NuGetizer.Tests/Scenarios/given_a_library_with_content/Resources/drawable-xhdpi/Icon.png diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/Resources/drawable-xxhdpi/Icon.png b/src/NuGetizer.Tests/Scenarios/given_a_library_with_content/Resources/drawable-xxhdpi/Icon.png similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/Resources/drawable-xxhdpi/Icon.png rename to src/NuGetizer.Tests/Scenarios/given_a_library_with_content/Resources/drawable-xxhdpi/Icon.png diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/Resources/drawable-xxxhdpi/Icon.png b/src/NuGetizer.Tests/Scenarios/given_a_library_with_content/Resources/drawable-xxxhdpi/Icon.png similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/Resources/drawable-xxxhdpi/Icon.png rename to src/NuGetizer.Tests/Scenarios/given_a_library_with_content/Resources/drawable-xxxhdpi/Icon.png diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/content-copy-with-include-false.txt b/src/NuGetizer.Tests/Scenarios/given_a_library_with_content/content-copy-with-include-false.txt similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/content-copy-with-include-false.txt rename to src/NuGetizer.Tests/Scenarios/given_a_library_with_content/content-copy-with-include-false.txt diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/content-copy-with-include-true.txt b/src/NuGetizer.Tests/Scenarios/given_a_library_with_content/content-copy-with-include-true.txt similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/content-copy-with-include-true.txt rename to src/NuGetizer.Tests/Scenarios/given_a_library_with_content/content-copy-with-include-true.txt diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/content-copy-with-kind.txt b/src/NuGetizer.Tests/Scenarios/given_a_library_with_content/content-copy-with-kind.txt similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/content-copy-with-kind.txt rename to src/NuGetizer.Tests/Scenarios/given_a_library_with_content/content-copy-with-kind.txt diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/content-copy.txt b/src/NuGetizer.Tests/Scenarios/given_a_library_with_content/content-copy.txt similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/content-copy.txt rename to src/NuGetizer.Tests/Scenarios/given_a_library_with_content/content-copy.txt diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/content-with-include-false.txt b/src/NuGetizer.Tests/Scenarios/given_a_library_with_content/content-with-include-false.txt similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/content-with-include-false.txt rename to src/NuGetizer.Tests/Scenarios/given_a_library_with_content/content-with-include-false.txt diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/content-with-include-true.txt b/src/NuGetizer.Tests/Scenarios/given_a_library_with_content/content-with-include-true.txt similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/content-with-include-true.txt rename to src/NuGetizer.Tests/Scenarios/given_a_library_with_content/content-with-include-true.txt diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/content-with-kind.txt b/src/NuGetizer.Tests/Scenarios/given_a_library_with_content/content-with-kind.txt similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/content-with-kind.txt rename to src/NuGetizer.Tests/Scenarios/given_a_library_with_content/content-with-kind.txt diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/content.txt b/src/NuGetizer.Tests/Scenarios/given_a_library_with_content/content-with-packagepath.txt similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/content.txt rename to src/NuGetizer.Tests/Scenarios/given_a_library_with_content/content-with-packagepath.txt diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_duplicate_package_files/content/content.txt b/src/NuGetizer.Tests/Scenarios/given_a_library_with_content/content.txt similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_duplicate_package_files/content/content.txt rename to src/NuGetizer.Tests/Scenarios/given_a_library_with_content/content.txt diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/contentFiles/cs/monoandroid/content.cs b/src/NuGetizer.Tests/Scenarios/given_a_library_with_content/contentFiles/cs/monoandroid/content.cs similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/contentFiles/cs/monoandroid/content.cs rename to src/NuGetizer.Tests/Scenarios/given_a_library_with_content/contentFiles/cs/monoandroid/content.cs diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/contentFiles/cs/monoandroid/none.cs b/src/NuGetizer.Tests/Scenarios/given_a_library_with_content/contentFiles/cs/monoandroid/none.cs similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/contentFiles/cs/monoandroid/none.cs rename to src/NuGetizer.Tests/Scenarios/given_a_library_with_content/contentFiles/cs/monoandroid/none.cs diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/library_with_content.csproj b/src/NuGetizer.Tests/Scenarios/given_a_library_with_content/library_with_content.csproj similarity index 82% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/library_with_content.csproj rename to src/NuGetizer.Tests/Scenarios/given_a_library_with_content/library_with_content.csproj index a058df69..70a4efd9 100644 --- a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/library_with_content.csproj +++ b/src/NuGetizer.Tests/Scenarios/given_a_library_with_content/library_with_content.csproj @@ -1,9 +1,10 @@ - - - - + + + library - MonoAndroid,Version=v5.1 + MonoAndroid51 + MyLibrary + true @@ -43,9 +44,10 @@ + + + - - diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/none-copy-with-include-false.txt b/src/NuGetizer.Tests/Scenarios/given_a_library_with_content/none-copy-with-include-false.txt similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/none-copy-with-include-false.txt rename to src/NuGetizer.Tests/Scenarios/given_a_library_with_content/none-copy-with-include-false.txt diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/none-copy-with-include-true.txt b/src/NuGetizer.Tests/Scenarios/given_a_library_with_content/none-copy-with-include-true.txt similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/none-copy-with-include-true.txt rename to src/NuGetizer.Tests/Scenarios/given_a_library_with_content/none-copy-with-include-true.txt diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/none-copy-with-kind.txt b/src/NuGetizer.Tests/Scenarios/given_a_library_with_content/none-copy-with-kind.txt similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/none-copy-with-kind.txt rename to src/NuGetizer.Tests/Scenarios/given_a_library_with_content/none-copy-with-kind.txt diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/none-copy.txt b/src/NuGetizer.Tests/Scenarios/given_a_library_with_content/none-copy.txt similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/none-copy.txt rename to src/NuGetizer.Tests/Scenarios/given_a_library_with_content/none-copy.txt diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/none-with-include-false.txt b/src/NuGetizer.Tests/Scenarios/given_a_library_with_content/none-with-include-false.txt similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/none-with-include-false.txt rename to src/NuGetizer.Tests/Scenarios/given_a_library_with_content/none-with-include-false.txt diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/none-with-include-true.txt b/src/NuGetizer.Tests/Scenarios/given_a_library_with_content/none-with-include-true.txt similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/none-with-include-true.txt rename to src/NuGetizer.Tests/Scenarios/given_a_library_with_content/none-with-include-true.txt diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/none-with-kind.txt b/src/NuGetizer.Tests/Scenarios/given_a_library_with_content/none-with-kind.txt similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/none-with-kind.txt rename to src/NuGetizer.Tests/Scenarios/given_a_library_with_content/none-with-kind.txt diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/none.txt b/src/NuGetizer.Tests/Scenarios/given_a_library_with_content/none-with-packagepath.txt similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/none.txt rename to src/NuGetizer.Tests/Scenarios/given_a_library_with_content/none-with-packagepath.txt diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/quickstart/any-any.txt b/src/NuGetizer.Tests/Scenarios/given_a_library_with_content/none.txt similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/quickstart/any-any.txt rename to src/NuGetizer.Tests/Scenarios/given_a_library_with_content/none.txt diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/quickstart/any-non-tfm.txt b/src/NuGetizer.Tests/Scenarios/given_a_library_with_content/quickstart/any-any.txt similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/quickstart/any-non-tfm.txt rename to src/NuGetizer.Tests/Scenarios/given_a_library_with_content/quickstart/any-any.txt diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/quickstart/cs-any.txt b/src/NuGetizer.Tests/Scenarios/given_a_library_with_content/quickstart/any-non-tfm.txt similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/quickstart/cs-any.txt rename to src/NuGetizer.Tests/Scenarios/given_a_library_with_content/quickstart/any-non-tfm.txt diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/quickstart/fs-tfm.txt b/src/NuGetizer.Tests/Scenarios/given_a_library_with_content/quickstart/cs-any.txt similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/quickstart/fs-tfm.txt rename to src/NuGetizer.Tests/Scenarios/given_a_library_with_content/quickstart/cs-any.txt diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/relative/content-copy-with-kind.txt b/src/NuGetizer.Tests/Scenarios/given_a_library_with_content/quickstart/fs-tfm.txt similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/relative/content-copy-with-kind.txt rename to src/NuGetizer.Tests/Scenarios/given_a_library_with_content/quickstart/fs-tfm.txt diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/relative/content-copy.txt b/src/NuGetizer.Tests/Scenarios/given_a_library_with_content/relative/content-copy-with-kind.txt similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/relative/content-copy.txt rename to src/NuGetizer.Tests/Scenarios/given_a_library_with_content/relative/content-copy-with-kind.txt diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/relative/none-copy-with-kind.txt b/src/NuGetizer.Tests/Scenarios/given_a_library_with_content/relative/content-copy.txt similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/relative/none-copy-with-kind.txt rename to src/NuGetizer.Tests/Scenarios/given_a_library_with_content/relative/content-copy.txt diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/relative/none-copy.txt b/src/NuGetizer.Tests/Scenarios/given_a_library_with_content/relative/none-copy-with-kind.txt similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_content/relative/none-copy.txt rename to src/NuGetizer.Tests/Scenarios/given_a_library_with_content/relative/none-copy-with-kind.txt diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_multi_platform_solution/android/quickstart/sample.cs b/src/NuGetizer.Tests/Scenarios/given_a_library_with_content/relative/none-copy.txt similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_multi_platform_solution/android/quickstart/sample.cs rename to src/NuGetizer.Tests/Scenarios/given_a_library_with_content/relative/none-copy.txt diff --git a/src/NuGetizer.Tests/Scenarios/given_a_library_with_non_nugetized_reference/a.csproj b/src/NuGetizer.Tests/Scenarios/given_a_library_with_non_nugetized_reference/a.csproj new file mode 100644 index 00000000..a7bfc848 --- /dev/null +++ b/src/NuGetizer.Tests/Scenarios/given_a_library_with_non_nugetized_reference/a.csproj @@ -0,0 +1,12 @@ + + + + net46 + a.package + 1.0.0 + + + + + + \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_non_nugetized_reference/b.sln b/src/NuGetizer.Tests/Scenarios/given_a_library_with_non_nugetized_reference/b.sln similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_non_nugetized_reference/b.sln rename to src/NuGetizer.Tests/Scenarios/given_a_library_with_non_nugetized_reference/b.sln diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_non_nugetized_reference/b/Resources.es-AR.resx b/src/NuGetizer.Tests/Scenarios/given_a_library_with_non_nugetized_reference/b/Resources.es-AR.resx similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_non_nugetized_reference/b/Resources.es-AR.resx rename to src/NuGetizer.Tests/Scenarios/given_a_library_with_non_nugetized_reference/b/Resources.es-AR.resx diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_non_nugetized_reference/b/Resources.resx b/src/NuGetizer.Tests/Scenarios/given_a_library_with_non_nugetized_reference/b/Resources.resx similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_library_with_non_nugetized_reference/b/Resources.resx rename to src/NuGetizer.Tests/Scenarios/given_a_library_with_non_nugetized_reference/b/Resources.resx diff --git a/src/NuGetizer.Tests/Scenarios/given_a_library_with_non_nugetized_reference/b/b.csproj b/src/NuGetizer.Tests/Scenarios/given_a_library_with_non_nugetized_reference/b/b.csproj new file mode 100644 index 00000000..c428567f --- /dev/null +++ b/src/NuGetizer.Tests/Scenarios/given_a_library_with_non_nugetized_reference/b/b.csproj @@ -0,0 +1,11 @@ + + + net46 + $(AssemblyName).xml + + + + + + + \ No newline at end of file diff --git a/src/NuGetizer.Tests/Scenarios/given_a_library_with_non_nugetized_reference/c.csproj b/src/NuGetizer.Tests/Scenarios/given_a_library_with_non_nugetized_reference/c.csproj new file mode 100644 index 00000000..eb14ac04 --- /dev/null +++ b/src/NuGetizer.Tests/Scenarios/given_a_library_with_non_nugetized_reference/c.csproj @@ -0,0 +1,6 @@ + + + + net45 + + \ No newline at end of file diff --git a/src/NuGetizer.Tests/Scenarios/given_a_library_with_non_nugetized_reference/d.csproj b/src/NuGetizer.Tests/Scenarios/given_a_library_with_non_nugetized_reference/d.csproj new file mode 100644 index 00000000..ac53ec6a --- /dev/null +++ b/src/NuGetizer.Tests/Scenarios/given_a_library_with_non_nugetized_reference/d.csproj @@ -0,0 +1,10 @@ + + + + net46 + + + + + + \ No newline at end of file diff --git a/src/NuGetizer.Tests/Scenarios/given_a_library_with_private_assets_reference/a.csproj b/src/NuGetizer.Tests/Scenarios/given_a_library_with_private_assets_reference/a.csproj new file mode 100644 index 00000000..8d181c1a --- /dev/null +++ b/src/NuGetizer.Tests/Scenarios/given_a_library_with_private_assets_reference/a.csproj @@ -0,0 +1,11 @@ + + + + net45 + + + + + + + \ No newline at end of file diff --git a/src/NuGetizer.Tests/Scenarios/given_a_library_with_project_reference/a.csproj b/src/NuGetizer.Tests/Scenarios/given_a_library_with_project_reference/a.csproj new file mode 100644 index 00000000..e4e209d0 --- /dev/null +++ b/src/NuGetizer.Tests/Scenarios/given_a_library_with_project_reference/a.csproj @@ -0,0 +1,12 @@ + + + + net45 + + + + + + + + \ No newline at end of file diff --git a/src/NuGetizer.Tests/Scenarios/given_a_library_with_project_reference/b.csproj b/src/NuGetizer.Tests/Scenarios/given_a_library_with_project_reference/b.csproj new file mode 100644 index 00000000..ae462a3b --- /dev/null +++ b/src/NuGetizer.Tests/Scenarios/given_a_library_with_project_reference/b.csproj @@ -0,0 +1,9 @@ + + + + net45 + + + + + \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_localized_library/Resources.es-AR.resx b/src/NuGetizer.Tests/Scenarios/given_a_localized_library/Resources.es-AR.resx similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_localized_library/Resources.es-AR.resx rename to src/NuGetizer.Tests/Scenarios/given_a_localized_library/Resources.es-AR.resx diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_localized_library/Resources.resx b/src/NuGetizer.Tests/Scenarios/given_a_localized_library/Resources.resx similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_localized_library/Resources.resx rename to src/NuGetizer.Tests/Scenarios/given_a_localized_library/Resources.resx diff --git a/src/NuGetizer.Tests/Scenarios/given_a_localized_library/library.csproj b/src/NuGetizer.Tests/Scenarios/given_a_localized_library/library.csproj new file mode 100644 index 00000000..151e4aac --- /dev/null +++ b/src/NuGetizer.Tests/Scenarios/given_a_localized_library/library.csproj @@ -0,0 +1,12 @@ + + + + library + library + net45 + + + + + + \ No newline at end of file diff --git a/src/NuGetizer.Tests/Scenarios/given_a_multi_platform_solution/android/forms.android.csproj b/src/NuGetizer.Tests/Scenarios/given_a_multi_platform_solution/android/forms.android.csproj new file mode 100644 index 00000000..d7ea0a0d --- /dev/null +++ b/src/NuGetizer.Tests/Scenarios/given_a_multi_platform_solution/android/forms.android.csproj @@ -0,0 +1,17 @@ + + + + Forms + MonoAndroid90 + true + false + + + + + $([System.String]::new('%(Extension)').TrimStart('.')) + None + + + + \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_multi_platform_solution/android/quickstart/sample.fs b/src/NuGetizer.Tests/Scenarios/given_a_multi_platform_solution/android/quickstart/sample.cs similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_multi_platform_solution/android/quickstart/sample.fs rename to src/NuGetizer.Tests/Scenarios/given_a_multi_platform_solution/android/quickstart/sample.cs diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_multi_platform_solution/android/quickstart/sample.vb b/src/NuGetizer.Tests/Scenarios/given_a_multi_platform_solution/android/quickstart/sample.fs similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_multi_platform_solution/android/quickstart/sample.vb rename to src/NuGetizer.Tests/Scenarios/given_a_multi_platform_solution/android/quickstart/sample.fs diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_multi_platform_solution/docs/gettingstarted.html b/src/NuGetizer.Tests/Scenarios/given_a_multi_platform_solution/android/quickstart/sample.vb similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_multi_platform_solution/docs/gettingstarted.html rename to src/NuGetizer.Tests/Scenarios/given_a_multi_platform_solution/android/quickstart/sample.vb diff --git a/src/NuGetizer.Tests/Scenarios/given_a_multi_platform_solution/common/common.csproj b/src/NuGetizer.Tests/Scenarios/given_a_multi_platform_solution/common/common.csproj new file mode 100644 index 00000000..e497c120 --- /dev/null +++ b/src/NuGetizer.Tests/Scenarios/given_a_multi_platform_solution/common/common.csproj @@ -0,0 +1,9 @@ + + + + netstandard1.6 + Common + false + + + \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_multi_platform_solution/docs/overview/index.html b/src/NuGetizer.Tests/Scenarios/given_a_multi_platform_solution/docs/gettingstarted.html similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_multi_platform_solution/docs/overview/index.html rename to src/NuGetizer.Tests/Scenarios/given_a_multi_platform_solution/docs/gettingstarted.html diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_duplicate_package_files/content/inferred.txt b/src/NuGetizer.Tests/Scenarios/given_a_multi_platform_solution/docs/overview/index.html similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_duplicate_package_files/content/inferred.txt rename to src/NuGetizer.Tests/Scenarios/given_a_multi_platform_solution/docs/overview/index.html diff --git a/src/NuGetizer.Tests/Scenarios/given_a_multi_platform_solution/forms.proj b/src/NuGetizer.Tests/Scenarios/given_a_multi_platform_solution/forms.proj new file mode 100644 index 00000000..41093add --- /dev/null +++ b/src/NuGetizer.Tests/Scenarios/given_a_multi_platform_solution/forms.proj @@ -0,0 +1,24 @@ + + + + Forms + Forms + 1.0.0 + true + netstandard1.0 + + + + + + + + + + <_Docs Include="docs\**\*.*" /> + + docs\%(_Docs.RecursiveDir)%(_Docs.Filename)%(_Docs.Extension) + + + + \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_multi_platform_solution/forms.sln b/src/NuGetizer.Tests/Scenarios/given_a_multi_platform_solution/forms.sln similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_multi_platform_solution/forms.sln rename to src/NuGetizer.Tests/Scenarios/given_a_multi_platform_solution/forms.sln diff --git a/src/NuGetizer.Tests/Scenarios/given_a_multi_platform_solution/ios/forms.ios.csproj b/src/NuGetizer.Tests/Scenarios/given_a_multi_platform_solution/ios/forms.ios.csproj new file mode 100644 index 00000000..9b80d1f3 --- /dev/null +++ b/src/NuGetizer.Tests/Scenarios/given_a_multi_platform_solution/ios/forms.ios.csproj @@ -0,0 +1,13 @@ + + + + Forms + xamarinios10 + true + false + + + + + + \ No newline at end of file diff --git a/src/NuGetizer.Tests/Scenarios/given_a_multi_platform_solution/net/forms.net.csproj b/src/NuGetizer.Tests/Scenarios/given_a_multi_platform_solution/net/forms.net.csproj new file mode 100644 index 00000000..cc3297f0 --- /dev/null +++ b/src/NuGetizer.Tests/Scenarios/given_a_multi_platform_solution/net/forms.net.csproj @@ -0,0 +1,12 @@ + + + + Forms + net472 + false + + + + + + \ No newline at end of file diff --git a/src/NuGetizer.Tests/Scenarios/given_a_multitargeting_library/library.csproj b/src/NuGetizer.Tests/Scenarios/given_a_multitargeting_library/library.csproj new file mode 100644 index 00000000..edf231e7 --- /dev/null +++ b/src/NuGetizer.Tests/Scenarios/given_a_multitargeting_library/library.csproj @@ -0,0 +1,21 @@ + + + + Library + Library + netstandard2.0;net472 + + + + + Foo + + + + + + MIT + + + + \ No newline at end of file diff --git a/src/NuGetizer.Tests/Scenarios/given_a_packaging_project/a.nuproj b/src/NuGetizer.Tests/Scenarios/given_a_packaging_project/a.nuproj new file mode 100644 index 00000000..13ed5f35 --- /dev/null +++ b/src/NuGetizer.Tests/Scenarios/given_a_packaging_project/a.nuproj @@ -0,0 +1,21 @@ + + + + PackageReference + netstandard1.0 + a.package + 1.0.0 + + + + + + + + + + Bar + + + + \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_packaging_project/b.sln b/src/NuGetizer.Tests/Scenarios/given_a_packaging_project/b.sln similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_packaging_project/b.sln rename to src/NuGetizer.Tests/Scenarios/given_a_packaging_project/b.sln diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_packaging_project/b/Resources.es-AR.resx b/src/NuGetizer.Tests/Scenarios/given_a_packaging_project/b/Resources.es-AR.resx similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_packaging_project/b/Resources.es-AR.resx rename to src/NuGetizer.Tests/Scenarios/given_a_packaging_project/b/Resources.es-AR.resx diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_packaging_project/b/Resources.resx b/src/NuGetizer.Tests/Scenarios/given_a_packaging_project/b/Resources.resx similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_packaging_project/b/Resources.resx rename to src/NuGetizer.Tests/Scenarios/given_a_packaging_project/b/Resources.resx diff --git a/src/NuGetizer.Tests/Scenarios/given_a_packaging_project/b/b.csproj b/src/NuGetizer.Tests/Scenarios/given_a_packaging_project/b/b.csproj new file mode 100644 index 00000000..6533db69 --- /dev/null +++ b/src/NuGetizer.Tests/Scenarios/given_a_packaging_project/b/b.csproj @@ -0,0 +1,12 @@ + + + + net46 + $(AssemblyName).xml + + + + + + + \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_packaging_project/b/b.xml b/src/NuGetizer.Tests/Scenarios/given_a_packaging_project/b/b.xml similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_a_packaging_project/b/b.xml rename to src/NuGetizer.Tests/Scenarios/given_a_packaging_project/b/b.xml diff --git a/src/NuGetizer.Tests/Scenarios/given_a_packaging_project/c.csproj b/src/NuGetizer.Tests/Scenarios/given_a_packaging_project/c.csproj new file mode 100644 index 00000000..eb14ac04 --- /dev/null +++ b/src/NuGetizer.Tests/Scenarios/given_a_packaging_project/c.csproj @@ -0,0 +1,6 @@ + + + + net45 + + \ No newline at end of file diff --git a/src/NuGetizer.Tests/Scenarios/given_a_packaging_project/d.csproj b/src/NuGetizer.Tests/Scenarios/given_a_packaging_project/d.csproj new file mode 100644 index 00000000..14e96bd3 --- /dev/null +++ b/src/NuGetizer.Tests/Scenarios/given_a_packaging_project/d.csproj @@ -0,0 +1,10 @@ + + + + net46 + + + + + + \ No newline at end of file diff --git a/src/NuGetizer.Tests/Scenarios/given_a_packaging_project/e.csproj b/src/NuGetizer.Tests/Scenarios/given_a_packaging_project/e.csproj new file mode 100644 index 00000000..86787e87 --- /dev/null +++ b/src/NuGetizer.Tests/Scenarios/given_a_packaging_project/e.csproj @@ -0,0 +1,8 @@ + + + + net45 + E + 2.0.0 + + \ No newline at end of file diff --git a/src/NuGetizer.Tests/Scenarios/given_a_packaging_project_with_netstandard/a.nuproj b/src/NuGetizer.Tests/Scenarios/given_a_packaging_project_with_netstandard/a.nuproj new file mode 100644 index 00000000..d5741d1f --- /dev/null +++ b/src/NuGetizer.Tests/Scenarios/given_a_packaging_project_with_netstandard/a.nuproj @@ -0,0 +1,18 @@ + + + + + + NuGet + Package for '$(MSBuildProjectName)' project. + bin + + a.package + 1.0.0 + + + + + + + \ No newline at end of file diff --git a/src/NuGetizer.Tests/Scenarios/given_a_packaging_project_with_netstandard/b/b.csproj b/src/NuGetizer.Tests/Scenarios/given_a_packaging_project_with_netstandard/b/b.csproj new file mode 100644 index 00000000..ec83c708 --- /dev/null +++ b/src/NuGetizer.Tests/Scenarios/given_a_packaging_project_with_netstandard/b/b.csproj @@ -0,0 +1,11 @@ + + + + netstandard1.6 + netstandard1.6;net45 + + + + + + \ No newline at end of file diff --git a/src/NuGetizer.Tests/Scenarios/given_an_empty_library/empty_library_project.csproj b/src/NuGetizer.Tests/Scenarios/given_an_empty_library/empty_library_project.csproj new file mode 100644 index 00000000..ba45f69b --- /dev/null +++ b/src/NuGetizer.Tests/Scenarios/given_an_empty_library/empty_library_project.csproj @@ -0,0 +1,29 @@ + + + + + netstandard2.0 + + + + + + + + + + + ItemDescription + + + + + + + PropertyDescription + + + + \ No newline at end of file diff --git a/src/NuGetizer.Tests/Scenarios/given_duplicate_package_files/a.csproj b/src/NuGetizer.Tests/Scenarios/given_duplicate_package_files/a.csproj new file mode 100644 index 00000000..34116a87 --- /dev/null +++ b/src/NuGetizer.Tests/Scenarios/given_duplicate_package_files/a.csproj @@ -0,0 +1,23 @@ + + + + net45 + A + This is a readme + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/NuGetizer.Tests/Scenarios/given_duplicate_package_files/b.csproj b/src/NuGetizer.Tests/Scenarios/given_duplicate_package_files/b.csproj new file mode 100644 index 00000000..63a9d5b4 --- /dev/null +++ b/src/NuGetizer.Tests/Scenarios/given_duplicate_package_files/b.csproj @@ -0,0 +1,21 @@ + + + + net45 + This is a readme + + + + + + + + + + + + Readme.txt + + + + \ No newline at end of file diff --git a/src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_duplicate_package_files/content/web/js/nuget.js b/src/NuGetizer.Tests/Scenarios/given_duplicate_package_files/content/content.txt similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Scenarios/given_duplicate_package_files/content/web/js/nuget.js rename to src/NuGetizer.Tests/Scenarios/given_duplicate_package_files/content/content.txt diff --git a/src/NuGetizer.Tests/Scenarios/given_duplicate_package_files/content/inferred.txt b/src/NuGetizer.Tests/Scenarios/given_duplicate_package_files/content/inferred.txt new file mode 100644 index 00000000..e69de29b diff --git a/src/NuGetizer.Tests/Scenarios/given_duplicate_package_files/content/web/js/nuget.js b/src/NuGetizer.Tests/Scenarios/given_duplicate_package_files/content/web/js/nuget.js new file mode 100644 index 00000000..e69de29b diff --git a/src/NuGetizer.Tests/Scenarios/global.json b/src/NuGetizer.Tests/Scenarios/global.json new file mode 100644 index 00000000..4887f1c7 --- /dev/null +++ b/src/NuGetizer.Tests/Scenarios/global.json @@ -0,0 +1,7 @@ +{ + "sdk": { + "allowPrerelease": true, + "rollForward": "latestFeature", + "version": "5.0.100-rc.1.20452.10" + } +} \ No newline at end of file diff --git a/src/NuGetizer.Tests/TargetsTests.cs b/src/NuGetizer.Tests/TargetsTests.cs new file mode 100644 index 00000000..98380b58 --- /dev/null +++ b/src/NuGetizer.Tests/TargetsTests.cs @@ -0,0 +1,121 @@ +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using Microsoft.Build.Construction; +using Microsoft.Build.Evaluation; +using Microsoft.Build.Execution; +using Xunit; +using Xunit.Abstractions; + +namespace NuGetizer +{ + public class TargetsTests + { + ITestOutputHelper output; + + public TargetsTests(ITestOutputHelper output) => this.output = output; + + [Fact] + public void PackFrameworkReferences_is_not_true_for_build_primary_output() + { + var project = new Project("NuGetizer.targets", new Dictionary + { + { "BuildOutputKind", "build" } + }, null); + + Assert.NotEqual("true", project.GetPropertyValue("PackFrameworkReferences")); + } + + [Fact] + public void PackFrameworkReferences_is_not_true_for_tool_primary_output() + { + var project = new Project("NuGetizer.targets", new Dictionary + { + { "BuildOutputKind", "tool" } + }, null); + + Assert.NotEqual("true", project.GetPropertyValue("PackFrameworkReferences")); + } + + [Fact] + public void PackFrameworkReferences_is_not_true_for_tools_primary_output() + { + var project = new Project("NuGetizer.targets", new Dictionary + { + { "BuildOutputKind", "tools" } + }, null); + + Assert.NotEqual("true", project.GetPropertyValue("PackFrameworkReferences")); + } + + [Fact] + public void PackFrameworkReferences_is_true_for_primary_output_lib() + { + var project = new Project("NuGetizer.targets", new Dictionary + { + { "BuildOutputKind", "lib" } + }, null); + + Assert.Equal("true", project.GetPropertyValue("PackFrameworkReferences")); + } + + [Fact] + public void PackFrameworkReferences_is_true_for_default_primary_output_kind() + { + var project = new Project("NuGetizer.targets", new Dictionary + { + }, null); + + Assert.Equal("true", project.GetPropertyValue("PackFrameworkReferences")); + } + + [Fact] + public void PackFrameworkReferences_is_not_true_for_compat_istool() + { + var project = new Project("NuGetizer.targets", new Dictionary + { + { "IsTool", "true" } + }, null); + + Assert.NotEqual("true", project.GetPropertyValue("PackFrameworkReferences")); + } + + [Fact] + public void PackOnBuild_defaults_to_true_for_compat_GeneratePackageOnBuild_true() + { + var project = new Project("NuGetizer.targets", new Dictionary + { + { "GeneratePackageOnBuild", "true" } + }, null); + + Assert.Equal("true", project.GetPropertyValue("PackOnBuild")); + } + + [Fact] + public void package_contents_never_includes_nugetizer_package_reference() + { + var xml = ProjectRootElement.Create(Path.Combine(Directory.GetCurrentDirectory(), MethodBase.GetCurrentMethod().Name)); + xml.AddImport(@"Scenarios\Scenario.props"); + xml.AddImport(@"Scenarios\Scenario.targets"); + xml.AddItemGroup() + .AddItem("PackageReference", "NuGetizer", new[] { new KeyValuePair("Version", "*") }); + + xml.Save(); + + var project = new ProjectInstance(xml); + + var result = Builder.Build(project, "GetPackageContents"); + + Assert.Equal(BuildResultCode.Success, result.OverallResult); + Assert.Equal(TargetResultCode.Success, result["GetPackageContents"].ResultCode); + + var items = result["GetPackageContents"].Items; + + Assert.DoesNotContain(items, item => item.Matches(new + { + Kind = PackageItemKind.Dependency, + Identity = "NuGetizer", + })); + } + } +} diff --git a/src/Build/NuGet.Build.Packaging.Tests/Utilities/ManifestContentFilesComparer.cs b/src/NuGetizer.Tests/Utilities/ManifestContentFilesComparer.cs similarity index 97% rename from src/Build/NuGet.Build.Packaging.Tests/Utilities/ManifestContentFilesComparer.cs rename to src/NuGetizer.Tests/Utilities/ManifestContentFilesComparer.cs index 10bba742..ddd6c857 100644 --- a/src/Build/NuGet.Build.Packaging.Tests/Utilities/ManifestContentFilesComparer.cs +++ b/src/NuGetizer.Tests/Utilities/ManifestContentFilesComparer.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using NuGet.Packaging; -namespace NuGet.Build.Packaging +namespace NuGetizer { class ManifestContentFilesComparer : IEqualityComparer { diff --git a/src/Build/NuGet.Build.Packaging.Tests/Utilities/ManifestFileComparer.cs b/src/NuGetizer.Tests/Utilities/ManifestFileComparer.cs similarity index 96% rename from src/Build/NuGet.Build.Packaging.Tests/Utilities/ManifestFileComparer.cs rename to src/NuGetizer.Tests/Utilities/ManifestFileComparer.cs index 7d972c78..aef9209f 100644 --- a/src/Build/NuGet.Build.Packaging.Tests/Utilities/ManifestFileComparer.cs +++ b/src/NuGetizer.Tests/Utilities/ManifestFileComparer.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using NuGet.Packaging; -namespace NuGet.Build.Packaging +namespace NuGetizer { class ManifestFileComparer : IEqualityComparer { diff --git a/src/Build/NuGet.Build.Packaging.Tests/Utilities/MockBuildEngine.cs b/src/NuGetizer.Tests/Utilities/MockBuildEngine.cs similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Utilities/MockBuildEngine.cs rename to src/NuGetizer.Tests/Utilities/MockBuildEngine.cs diff --git a/src/Build/NuGet.Build.Packaging.Tests/Utilities/PackageDependencyComparer.cs b/src/NuGetizer.Tests/Utilities/PackageDependencyComparer.cs similarity index 96% rename from src/Build/NuGet.Build.Packaging.Tests/Utilities/PackageDependencyComparer.cs rename to src/NuGetizer.Tests/Utilities/PackageDependencyComparer.cs index 3045db78..b0d816c2 100644 --- a/src/Build/NuGet.Build.Packaging.Tests/Utilities/PackageDependencyComparer.cs +++ b/src/NuGetizer.Tests/Utilities/PackageDependencyComparer.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using NuGet.Packaging.Core; -namespace NuGet.Build.Packaging +namespace NuGetizer { class PackageDependencyComparer : IEqualityComparer { diff --git a/src/Build/NuGet.Build.Packaging.Tests/Utilities/PackageDependencyGroupComparer.cs b/src/NuGetizer.Tests/Utilities/PackageDependencyGroupComparer.cs similarity index 97% rename from src/Build/NuGet.Build.Packaging.Tests/Utilities/PackageDependencyGroupComparer.cs rename to src/NuGetizer.Tests/Utilities/PackageDependencyGroupComparer.cs index 27cc430b..ebfff96d 100644 --- a/src/Build/NuGet.Build.Packaging.Tests/Utilities/PackageDependencyGroupComparer.cs +++ b/src/NuGetizer.Tests/Utilities/PackageDependencyGroupComparer.cs @@ -3,7 +3,7 @@ using NuGet.Packaging; using NuGet.Packaging.Core; -namespace NuGet.Build.Packaging +namespace NuGetizer { class PackageDependencyGroupComparer : IEqualityComparer { diff --git a/src/Build/NuGet.Build.Packaging.Tests/Utilities/TargetFrameworks.cs b/src/NuGetizer.Tests/Utilities/TargetFrameworks.cs similarity index 91% rename from src/Build/NuGet.Build.Packaging.Tests/Utilities/TargetFrameworks.cs rename to src/NuGetizer.Tests/Utilities/TargetFrameworks.cs index 86fcb725..695e4e3e 100644 --- a/src/Build/NuGet.Build.Packaging.Tests/Utilities/TargetFrameworks.cs +++ b/src/NuGetizer.Tests/Utilities/TargetFrameworks.cs @@ -1,4 +1,4 @@ -namespace NuGet.Build.Packaging +namespace NuGetizer { static class TargetFrameworks { diff --git a/src/Build/NuGet.Build.Packaging.Tests/Utilities/TaskItemExtensions.cs b/src/NuGetizer.Tests/Utilities/TaskItemExtensions.cs similarity index 83% rename from src/Build/NuGet.Build.Packaging.Tests/Utilities/TaskItemExtensions.cs rename to src/NuGetizer.Tests/Utilities/TaskItemExtensions.cs index 7a718b93..f09e66b6 100644 --- a/src/Build/NuGet.Build.Packaging.Tests/Utilities/TaskItemExtensions.cs +++ b/src/NuGetizer.Tests/Utilities/TaskItemExtensions.cs @@ -1,7 +1,8 @@ -using Microsoft.Build.Framework; +using System; +using Microsoft.Build.Framework; using NuGet.Packaging; -namespace NuGet.Build.Packaging +namespace NuGetizer { static class TaskItemExtensions { @@ -16,7 +17,7 @@ public static bool Matches(this ITaskItem item, object metadata) var actual = item.GetMetadata(prop.Name); var expected = prop.GetValue(metadata).ToString(); - if (actual != expected) + if (!actual.Equals(expected, StringComparison.OrdinalIgnoreCase)) return false; } diff --git a/src/Build/NuGet.Build.Packaging.Tests/Utilities/TestOutputLogger.cs b/src/NuGetizer.Tests/Utilities/TestOutputLogger.cs similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/Utilities/TestOutputLogger.cs rename to src/NuGetizer.Tests/Utilities/TestOutputLogger.cs diff --git a/src/Build/NuGet.Build.Packaging.Tests/UtilitiesTests.cs b/src/NuGetizer.Tests/UtilitiesTests.cs similarity index 97% rename from src/Build/NuGet.Build.Packaging.Tests/UtilitiesTests.cs rename to src/NuGetizer.Tests/UtilitiesTests.cs index 92fc9b26..c7cf73c9 100644 --- a/src/Build/NuGet.Build.Packaging.Tests/UtilitiesTests.cs +++ b/src/NuGetizer.Tests/UtilitiesTests.cs @@ -3,7 +3,7 @@ using Xunit; using Metadata = System.Collections.Generic.Dictionary; -namespace NuGet.Build.Packaging +namespace NuGetizer { public class UtilitiesTests { diff --git a/src/Build/NuGet.Build.Packaging.Tests/given_a_complex_pack.cs b/src/NuGetizer.Tests/given_a_complex_pack.cs similarity index 79% rename from src/Build/NuGet.Build.Packaging.Tests/given_a_complex_pack.cs rename to src/NuGetizer.Tests/given_a_complex_pack.cs index 03765df2..6ce2fdcc 100644 --- a/src/Build/NuGet.Build.Packaging.Tests/given_a_complex_pack.cs +++ b/src/NuGetizer.Tests/given_a_complex_pack.cs @@ -1,10 +1,11 @@ -using System.Linq; +using System.IO; +using System.Linq; using Microsoft.Build.Execution; using NuGet.Frameworks; using Xunit; using Xunit.Abstractions; -namespace NuGet.Build.Packaging +namespace NuGetizer { public class given_a_complex_pack { @@ -27,7 +28,7 @@ public void when_getting_package_target_path_then_gets_package_metadata() var metadata = result.Items.FirstOrDefault(); Assert.NotNull(metadata); - Assert.Equal("A", metadata.GetMetadata("Id")); + Assert.Equal("A", metadata.GetMetadata("PackageId")); Assert.Equal("1.0.0", metadata.GetMetadata("Version")); Assert.Equal("NuGet", metadata.GetMetadata("Authors")); } @@ -62,7 +63,7 @@ public void when_preparing_a_then_contains_assemblies_and_direct_dependency() })); Assert.Contains(result.Items, item => item.Matches(new { - Id = "B", + Identity = "B", Kind = "Dependency", Version = "2.0.0", })); @@ -98,7 +99,7 @@ public void when_preparing_b_then_contains_assemblies_and_direct_dependency() })); Assert.Contains(result.Items, item => item.Matches(new { - Id = "C", + Identity = "C", Kind = "Dependency", Version = "3.0.0", })); @@ -217,5 +218,49 @@ public void when_packing_d_without_package_id_then_target_is_skipped() Assert.Equal(TargetResultCode.Skipped, result.ResultCode); } - } + + [Fact] + public void when_pack_with_emit_nuspec_but_not_package_then_creates_nuspec_but_not_package() + { + var result = Builder.BuildScenario(nameof(given_a_complex_pack), + new + { + EmitNuspec = "true", + EmitPackage = "false", + BaseOutputPath = Builder.TestOutputPath(), + }, + projectName: "a", + target: "Pack", output: output); + + result.AssertSuccess(output); + Assert.Single(result.Items); + + var pkgFile = result.Items[0].GetMetadata("FullPath"); + + Assert.False(File.Exists(pkgFile)); + Assert.True(File.Exists(Path.Combine(Path.GetDirectoryName(pkgFile), "A.nuspec"))); + } + + [Fact] + public void when_pack_with_emit_package_but_not_nuspec_then_creates_package_but_not_nuspec() + { + var result = Builder.BuildScenario(nameof(given_a_complex_pack), + new + { + EmitNuspec = "false", + EmitPackage = "true", + BaseOutputPath = Builder.TestOutputPath(), + }, + projectName: "a", + target: "Pack", output: output); + + result.AssertSuccess(output); + Assert.Single(result.Items); + + var pkgFile = result.Items[0].GetMetadata("FullPath"); + + Assert.True(File.Exists(pkgFile)); + Assert.False(File.Exists(Path.Combine(Path.GetDirectoryName(pkgFile), "A.nuspec"))); + } + } } diff --git a/src/Build/NuGet.Build.Packaging.Tests/given_a_custom_build_project.cs b/src/NuGetizer.Tests/given_a_custom_build_project.cs similarity index 94% rename from src/Build/NuGet.Build.Packaging.Tests/given_a_custom_build_project.cs rename to src/NuGetizer.Tests/given_a_custom_build_project.cs index 72f407c6..258e315f 100644 --- a/src/Build/NuGet.Build.Packaging.Tests/given_a_custom_build_project.cs +++ b/src/NuGetizer.Tests/given_a_custom_build_project.cs @@ -1,7 +1,7 @@ using Xunit; using Xunit.Abstractions; -namespace NuGet.Build.Packaging +namespace NuGetizer { public class given_a_custom_build_project { diff --git a/src/NuGetizer.Tests/given_a_framework_library.cs b/src/NuGetizer.Tests/given_a_framework_library.cs new file mode 100644 index 00000000..d5d011f9 --- /dev/null +++ b/src/NuGetizer.Tests/given_a_framework_library.cs @@ -0,0 +1,46 @@ +using Xunit; +using Xunit.Abstractions; + +namespace NuGetizer +{ + public class given_a_framework_library + { + ITestOutputHelper output; + + public given_a_framework_library(ITestOutputHelper output) + { + this.output = output; + Builder.BuildScenario(nameof(given_a_framework_library), target: "Restore") + .AssertSuccess(output); + } + + [Fact] + public void when_getting_package_contents_then_includes_framework_references_by_default() + { + var result = Builder.BuildScenario(nameof(given_a_framework_library)); + + result.AssertSuccess(output); + Assert.Contains(result.Items, item => item.Matches(new + { + Identity = "PresentationCore", + Kind = PackageItemKind.FrameworkReference, + })); + } + + [Fact] + public void when_include_outputs_in_package_is_false_then_does_not_include_main_assembly() + { + var result = Builder.BuildScenario(nameof(given_a_framework_library), new + { + IncludeWPF = false, + }); + + result.AssertSuccess(output); + Assert.DoesNotContain(result.Items, item => item.Matches(new + { + Identity = "PresentationCore", + Kind = PackageItemKind.FrameworkReference, + })); + } + } +} diff --git a/src/Build/NuGet.Build.Packaging.Tests/given_a_library_with_content.cs b/src/NuGetizer.Tests/given_a_library_with_content.cs similarity index 87% rename from src/Build/NuGet.Build.Packaging.Tests/given_a_library_with_content.cs rename to src/NuGetizer.Tests/given_a_library_with_content.cs index 755b7143..d750cc20 100644 --- a/src/Build/NuGet.Build.Packaging.Tests/given_a_library_with_content.cs +++ b/src/NuGetizer.Tests/given_a_library_with_content.cs @@ -3,7 +3,7 @@ using Xunit; using Xunit.Abstractions; -namespace NuGet.Build.Packaging +namespace NuGetizer { public class given_a_library_with_content { @@ -12,7 +12,9 @@ public class given_a_library_with_content public given_a_library_with_content(ITestOutputHelper output) { this.output = output; - } + Builder.BuildScenario(nameof(given_a_library_with_content), target: "Restore") + .AssertSuccess(output); + } [Fact] public void when_library_is_not_packable_then_still_contains_content_files() @@ -32,7 +34,7 @@ public void when_global_include_content_is_false_then_does_not_contain_content_f { var result = Builder.BuildScenario(nameof(given_a_library_with_content), new { - IncludeContentInPackage = "false" + PackContent = "false" }); result.AssertSuccess(output); @@ -48,7 +50,7 @@ public void when_global_include_none_is_false_then_does_not_contain_none_copy_fi { var result = Builder.BuildScenario(nameof(given_a_library_with_content), new { - IncludeNoneInPackage = "false" + PackNone = "false" }); result.AssertSuccess(output); @@ -270,7 +272,7 @@ public void content_include_true_is_included_even_if_global_include_contents_is_ var result = Builder.BuildScenario(nameof(given_a_library_with_content), new { PackageId = "ContentPackage", - IncludeContentInPackage = "false" + PackContent = "false" }); result.AssertSuccess(output); @@ -346,11 +348,28 @@ public void content_copy_relative_kind_is_included_as_relative_kind() })); } - #endregion + [Fact] + public void content_with_package_path_is_included_even_with_pack_content_false() + { + var result = Builder.BuildScenario(nameof(given_a_library_with_content), new + { + PackageId = "ContentPackage", + PackContent = "false" + }); - #region None scenarios + result.AssertSuccess(output); - [Fact] + Assert.Contains(result.Items, item => item.Matches(new + { + PackagePath = @"build\content-with-packagepath.txt", + })); + } + + #endregion + + #region None scenarios + + [Fact] public void none_no_copy_is_specified_relative_path() { var result = Builder.BuildScenario(nameof(given_a_library_with_content), new @@ -436,7 +455,7 @@ public void none_copy_is_included_as_lib() var result = Builder.BuildScenario(nameof(given_a_library_with_content), new { PackageId = "ContentPackage", - IncludeNoneInPackage = "true", + PackNone = "true", }); result.AssertSuccess(output); @@ -485,7 +504,7 @@ public void none_include_true_is_included_even_if_global_include_none_is_false() var result = Builder.BuildScenario(nameof(given_a_library_with_content), new { PackageId = "ContentPackage", - IncludeNoneInPackage = "false" + PackNone = "false" }); result.AssertSuccess(output); @@ -536,7 +555,7 @@ public void none_no_kind_is_included__as_none() var result = Builder.BuildScenario(nameof(given_a_library_with_content), new { PackageId = "ContentPackage", - IncludeNoneInPackage = "true" + PackNone = "true" }); result.AssertSuccess(output); @@ -579,6 +598,39 @@ public void none_copy_relative_kind_is_included_as_relative_kind() })); } - #endregion - } + [Fact] + public void none_with_package_path_is_included_by_default() + { + var result = Builder.BuildScenario(nameof(given_a_library_with_content), new + { + PackageId = "ContentPackage", + }); + + result.AssertSuccess(output); + + Assert.Contains(result.Items, item => item.Matches(new + { + PackagePath = @"build\none-with-packagepath.txt", + })); + } + + [Fact] + public void none_with_package_path_is_included_even_with_pack_none_false() + { + var result = Builder.BuildScenario(nameof(given_a_library_with_content), new + { + PackageId = "ContentPackage", + PackNone = "false", + }); + + result.AssertSuccess(output); + + Assert.Contains(result.Items, item => item.Matches(new + { + PackagePath = @"build\none-with-packagepath.txt", + })); + } + + #endregion + } } diff --git a/src/Build/NuGet.Build.Packaging.Tests/given_a_library_with_non_nugetized_reference.cs b/src/NuGetizer.Tests/given_a_library_with_non_nugetized_reference.cs similarity index 68% rename from src/Build/NuGet.Build.Packaging.Tests/given_a_library_with_non_nugetized_reference.cs rename to src/NuGetizer.Tests/given_a_library_with_non_nugetized_reference.cs index e32cfd14..4cdf871c 100644 --- a/src/Build/NuGet.Build.Packaging.Tests/given_a_library_with_non_nugetized_reference.cs +++ b/src/NuGetizer.Tests/given_a_library_with_non_nugetized_reference.cs @@ -2,26 +2,26 @@ using Xunit; using Xunit.Abstractions; -namespace NuGet.Build.Packaging +namespace NuGetizer { public class given_a_library_with_non_nugetized_reference { ITestOutputHelper output; - public given_a_library_with_non_nugetized_reference(ITestOutputHelper output) - { - this.output = output; - } - + public given_a_library_with_non_nugetized_reference(ITestOutputHelper output) => this.output = output; + [Fact] public void when_getting_contents_then_fails() { var properties = new { Configuration = "Release", - IncludeFrameworkReferences = "false", - }; - Builder.BuildScenario(nameof(given_a_library_with_non_nugetized_reference), properties, projectName: "a", target: "Restore"); + PackFrameworkReferences = "false", + }; + + Builder.BuildScenario(nameof(given_a_library_with_non_nugetized_reference), properties, projectName: "a", target: "Restore") + .AssertSuccess(output); + var result = Builder.BuildScenario(nameof(given_a_library_with_non_nugetized_reference), properties, projectName: "a", target: "GetPackageContents"); Assert.Equal(TargetResultCode.Failure, result.ResultCode); @@ -34,10 +34,13 @@ public void when_include_in_package_false_then_does_not_fail() var properties = new { Configuration = "Release", - IncludeFrameworkReferences = "false", - IncludeInPackage = "false" - }; - Builder.BuildScenario(nameof(given_a_library_with_non_nugetized_reference), properties, projectName: "a", target: "Restore"); + PackFrameworkReferences = "false", + IncludeInPackage = "false", + }; + + Builder.BuildScenario(nameof(given_a_library_with_non_nugetized_reference), properties, projectName: "a", target: "Restore") + .AssertSuccess(output); + var result = Builder.BuildScenario(nameof(given_a_library_with_non_nugetized_reference), properties, projectName: "a", target: "GetPackageContents", output: output); result.AssertSuccess(output); diff --git a/src/Build/NuGet.Build.Packaging.Tests/given_a_library_with_private_assets_reference.cs b/src/NuGetizer.Tests/given_a_library_with_private_assets_reference.cs similarity index 86% rename from src/Build/NuGet.Build.Packaging.Tests/given_a_library_with_private_assets_reference.cs rename to src/NuGetizer.Tests/given_a_library_with_private_assets_reference.cs index 86ab0c4e..f598107d 100644 --- a/src/Build/NuGet.Build.Packaging.Tests/given_a_library_with_private_assets_reference.cs +++ b/src/NuGetizer.Tests/given_a_library_with_private_assets_reference.cs @@ -1,21 +1,20 @@ using Xunit; using Xunit.Abstractions; -namespace NuGet.Build.Packaging +namespace NuGetizer { public class given_a_library_with_private_assets_reference { ITestOutputHelper output; - public given_a_library_with_private_assets_reference(ITestOutputHelper output) - { - this.output = output; - } + public given_a_library_with_private_assets_reference(ITestOutputHelper output) => this.output = output; [Fact] public void when_getting_package_contents_then_contains_private_assets_as_primary_output() { - Builder.BuildScenario(nameof(given_a_library_with_private_assets_reference), target: "Restore", output: output); + Builder.BuildScenario(nameof(given_a_library_with_private_assets_reference), target: "Restore", output: output) + .AssertSuccess(output); + var result = Builder.BuildScenario(nameof(given_a_library_with_private_assets_reference), output: output); result.AssertSuccess(output); @@ -37,7 +36,9 @@ public void when_getting_package_contents_then_contains_private_assets_as_primar [Fact] public void when_getting_package_contents_then_contains_private_lib_assets_as_primary_output_and_also_package_reference() { - Builder.BuildScenario(nameof(given_a_library_with_private_assets_reference), target: "Restore", output: output); + Builder.BuildScenario(nameof(given_a_library_with_private_assets_reference), target: "Restore", output: output) + .AssertSuccess(output); + var result = Builder.BuildScenario(nameof(given_a_library_with_private_assets_reference), output: output); result.AssertSuccess(output); @@ -59,7 +60,9 @@ public void when_getting_package_contents_then_contains_private_lib_assets_as_pr [Fact] public void when_getting_package_contents_then_contains_dependency_for_non_private_assets_reference() { - Builder.BuildScenario(nameof(given_a_library_with_private_assets_reference), target: "Restore", output: output); + Builder.BuildScenario(nameof(given_a_library_with_private_assets_reference), target: "Restore", output: output) + .AssertSuccess(output); + var result = Builder.BuildScenario(nameof(given_a_library_with_private_assets_reference), output: output); result.AssertSuccess(output); diff --git a/src/Build/NuGet.Build.Packaging.Tests/given_a_library_with_project_reference.cs b/src/NuGetizer.Tests/given_a_library_with_project_reference.cs similarity index 91% rename from src/Build/NuGet.Build.Packaging.Tests/given_a_library_with_project_reference.cs rename to src/NuGetizer.Tests/given_a_library_with_project_reference.cs index 47451e66..123d50db 100644 --- a/src/Build/NuGet.Build.Packaging.Tests/given_a_library_with_project_reference.cs +++ b/src/NuGetizer.Tests/given_a_library_with_project_reference.cs @@ -2,7 +2,7 @@ using Xunit; using Xunit.Abstractions; -namespace NuGet.Build.Packaging +namespace NuGetizer { public class given_a_library_with_project_reference { @@ -11,7 +11,9 @@ public class given_a_library_with_project_reference public given_a_library_with_project_reference(ITestOutputHelper output) { this.output = output; - } + Builder.BuildScenario(nameof(given_a_library_with_project_reference), output: output, target: "Restore") + .AssertSuccess(output); + } [Fact] public void when_getting_package_contents_then_retrieves_main_assembly_transitively() @@ -60,8 +62,8 @@ public void when_include_outputs_in_package_false_then_can_include_referenced_pr var result = Builder.BuildScenario(nameof(given_a_library_with_project_reference), properties: new { - IncludeOutputsInPackage = "false", - IncludeProjectReferencesInPackage = "true" + PackBuildOutput = "false", + PackProjectReference = "true" }, output: output); diff --git a/src/Build/NuGet.Build.Packaging.Tests/given_a_localized_library.cs b/src/NuGetizer.Tests/given_a_localized_library.cs similarity index 74% rename from src/Build/NuGet.Build.Packaging.Tests/given_a_localized_library.cs rename to src/NuGetizer.Tests/given_a_localized_library.cs index 871b734a..b968f741 100644 --- a/src/Build/NuGet.Build.Packaging.Tests/given_a_localized_library.cs +++ b/src/NuGetizer.Tests/given_a_localized_library.cs @@ -2,7 +2,7 @@ using Xunit; using Xunit.Abstractions; -namespace NuGet.Build.Packaging +namespace NuGetizer { public class given_a_localized_library { @@ -11,9 +11,11 @@ public class given_a_localized_library public given_a_localized_library(ITestOutputHelper output) { this.output = output; - } + Builder.BuildScenario(nameof(given_a_localized_library), output: output, target: "Restore") + .AssertSuccess(output); + } - [Fact] + [Fact] public void when_getting_package_contents_then_contains_localized_resources() { var result = Builder.BuildScenario(nameof(given_a_localized_library)); diff --git a/src/Build/NuGet.Build.Packaging.Tests/given_a_multi_platform_solution.cs b/src/NuGetizer.Tests/given_a_multi_platform_solution.cs similarity index 98% rename from src/Build/NuGet.Build.Packaging.Tests/given_a_multi_platform_solution.cs rename to src/NuGetizer.Tests/given_a_multi_platform_solution.cs index e3e578a1..2881d925 100644 --- a/src/Build/NuGet.Build.Packaging.Tests/given_a_multi_platform_solution.cs +++ b/src/NuGetizer.Tests/given_a_multi_platform_solution.cs @@ -1,7 +1,7 @@ using Xunit; using Xunit.Abstractions; -namespace NuGet.Build.Packaging +namespace NuGetizer { public class given_a_multi_platform_solution { diff --git a/src/NuGetizer.Tests/given_a_multitargeting_library.cs b/src/NuGetizer.Tests/given_a_multitargeting_library.cs new file mode 100644 index 00000000..9a74b0e5 --- /dev/null +++ b/src/NuGetizer.Tests/given_a_multitargeting_library.cs @@ -0,0 +1,90 @@ +using Xunit; +using Xunit.Abstractions; + +namespace NuGetizer +{ + public class given_a_multitargeting_library + { + ITestOutputHelper output; + + public given_a_multitargeting_library(ITestOutputHelper output) + { + this.output = output; + Builder.BuildScenario(nameof(given_a_multitargeting_library), target: "Restore", output: output) + .AssertSuccess(output); + } + + + [Fact] + public void when_gettingcontents_then_includes_content_from_all_frameworks() + { + var result = Builder.BuildScenario(nameof(given_a_multitargeting_library), output: output); + result.AssertSuccess(output); + + Assert.Contains(result.Items, item => item.Matches(new + { + PackagePath = "lib\\netstandard2.0\\library.dll", + })); + + Assert.Contains(result.Items, item => item.Matches(new + { + PackagePath = "lib\\net472\\library.dll", + })); + } + + [Fact] + public void when_gettingcontents_then_includes_single_metadata() + { + var result = Builder.BuildScenario(nameof(given_a_multitargeting_library), output: output); + result.AssertSuccess(output); + + Assert.Single(result.Items, item => item.Matches(new + { + Kind = "Metadata", + TargetFrameworkMoniker = "", + })); + } + + [Fact] + public void when_packing_then_succeeds() + { + Builder.BuildScenario(nameof(given_a_multitargeting_library), target: "Pack", output: output) + .AssertSuccess(output); + } + + [Fact] + public void when_customizing_item_definition_then_adds_package_metadata() + { + var result = Builder.BuildScenario(nameof(given_a_multitargeting_library), new + { + CustomizeItemDefinition = "true" + }); + result.AssertSuccess(output); + + Assert.Single(result.Items, item => item.Matches(new + { + Kind = "Metadata", + NewMetadata = "Foo", + })); + } + + [Fact] + public void when_customizing_item_then_adds_package_metadata() + { + var result = Builder.BuildScenario(nameof(given_a_multitargeting_library), new + { + CustomizeItem = "true", + Description = "Customized" + }); + result.AssertSuccess(output); + + Assert.Single(result.Items, item => item.Matches(new + { + Kind = "Metadata", + Description = "Customized", + LicenseExpression = "MIT", + })); + } + + } +} diff --git a/src/Build/NuGet.Build.Packaging.Tests/given_a_packaging_project.cs b/src/NuGetizer.Tests/given_a_packaging_project.cs similarity index 87% rename from src/Build/NuGet.Build.Packaging.Tests/given_a_packaging_project.cs rename to src/NuGetizer.Tests/given_a_packaging_project.cs index f97497cd..4d8de5ef 100644 --- a/src/Build/NuGet.Build.Packaging.Tests/given_a_packaging_project.cs +++ b/src/NuGetizer.Tests/given_a_packaging_project.cs @@ -1,7 +1,7 @@ using Xunit; using Xunit.Abstractions; -namespace NuGet.Build.Packaging +namespace NuGetizer { public class given_a_packaging_project { @@ -10,12 +10,14 @@ public class given_a_packaging_project public given_a_packaging_project(ITestOutputHelper output) { this.output = output; - } + Builder.BuildScenario(nameof(given_a_packaging_project), target: "Restore") + .AssertSuccess(output); + } [Fact] public void when_getting_contents_then_includes_referenced_project_outputs() { - var result = Builder.BuildScenario(nameof(given_a_packaging_project), target: "GetPackageContents", output: output); + var result = Builder.BuildScenario(nameof(given_a_packaging_project), output: output); result.AssertSuccess(output); @@ -36,7 +38,7 @@ public void when_getting_contents_then_includes_referenced_project_outputs() [Fact] public void when_getting_contents_then_can_augment_package_metadata() { - var result = Builder.BuildScenario(nameof(given_a_packaging_project), target: "GetPackageContents", output: output); + var result = Builder.BuildScenario(nameof(given_a_packaging_project), output: output); result.AssertSuccess(output); @@ -50,7 +52,7 @@ public void when_getting_contents_then_can_augment_package_metadata() [Fact] public void when_getting_contents_then_includes_referenced_project_satellite_assembly() { - var result = Builder.BuildScenario(nameof(given_a_packaging_project), target: "GetPackageContents", output: output); + var result = Builder.BuildScenario(nameof(given_a_packaging_project), output: output); result.AssertSuccess(output); @@ -63,7 +65,7 @@ public void when_getting_contents_then_includes_referenced_project_satellite_ass [Fact] public void when_getting_contents_then_includes_referenced_project_dependencies() { - var result = Builder.BuildScenario(nameof(given_a_packaging_project), target: "GetPackageContents", output: output); + var result = Builder.BuildScenario(nameof(given_a_packaging_project), output: output); result.AssertSuccess(output); @@ -80,7 +82,7 @@ public void when_getting_contents_then_includes_referenced_project_dependencies( [Fact] public void when_getting_contents_then_includes_referenced_project_dependency_satellite_assembly() { - var result = Builder.BuildScenario(nameof(given_a_packaging_project), target: "GetPackageContents", output: output); + var result = Builder.BuildScenario(nameof(given_a_packaging_project), output: output); result.AssertSuccess(output); @@ -93,7 +95,7 @@ public void when_getting_contents_then_includes_referenced_project_dependency_sa [Fact] public void when_getting_contents_then_includes_referenced_packagable_project_as_dependency() { - var result = Builder.BuildScenario(nameof(given_a_packaging_project), target: "GetPackageContents", output: output); + var result = Builder.BuildScenario(nameof(given_a_packaging_project), output: output); result.AssertSuccess(output); @@ -107,7 +109,7 @@ public void when_getting_contents_then_includes_referenced_packagable_project_as [Fact] public void when_getting_contents_then_does_not_include_referenced_project_nuget_assembly_reference() { - var result = Builder.BuildScenario(nameof(given_a_packaging_project), target: "GetPackageContents", output: output); + var result = Builder.BuildScenario(nameof(given_a_packaging_project), output: output); result.AssertSuccess(output); @@ -120,7 +122,7 @@ public void when_getting_contents_then_does_not_include_referenced_project_nuget [Fact] public void when_getting_contents_from_packaging_project_then_referenced_outputs_have_original_tfm_path() { - var result = Builder.BuildScenario(nameof(given_a_packaging_project), target: "GetPackageContents", output: output); + var result = Builder.BuildScenario(nameof(given_a_packaging_project), output: output); result.AssertSuccess(output); diff --git a/src/Build/NuGet.Build.Packaging.Tests/given_a_packaging_project_with_netstandard.cs b/src/NuGetizer.Tests/given_a_packaging_project_with_netstandard.cs similarity index 90% rename from src/Build/NuGet.Build.Packaging.Tests/given_a_packaging_project_with_netstandard.cs rename to src/NuGetizer.Tests/given_a_packaging_project_with_netstandard.cs index 5cb82f1f..7b85a3e1 100644 --- a/src/Build/NuGet.Build.Packaging.Tests/given_a_packaging_project_with_netstandard.cs +++ b/src/NuGetizer.Tests/given_a_packaging_project_with_netstandard.cs @@ -1,7 +1,7 @@ using Xunit; using Xunit.Abstractions; -namespace NuGet.Build.Packaging +namespace NuGetizer { // NOTE: not added to the main project because it's built using MSBuild 14 and it's not working // by adding binding redirects, appdomain isolation, etc. :( @@ -20,7 +20,6 @@ public void can_get_content_from_referenced_single_targeting_netstandard() var result = Builder.BuildScenario(nameof(given_a_packaging_project_with_netstandard), target: "GetPackageContents", properties: new { SimulateCrossTargeting = "false" }, - //verbosity: Microsoft.Build.Framework.LoggerVerbosity.Diagnostic, output: output); result.AssertSuccess(output); @@ -40,7 +39,6 @@ public void can_get_content_from_referenced_cross_targeting_netstandard() var result = Builder.BuildScenario(nameof(given_a_packaging_project_with_netstandard), target: "GetPackageContents", properties: new { SimulateCrossTargeting = "true" }, - //verbosity: Microsoft.Build.Framework.LoggerVerbosity.Diagnostic, output: output); result.AssertSuccess(output); diff --git a/src/NuGetizer.Tests/given_an_empty_library.cs b/src/NuGetizer.Tests/given_an_empty_library.cs new file mode 100644 index 00000000..8bb166e2 --- /dev/null +++ b/src/NuGetizer.Tests/given_an_empty_library.cs @@ -0,0 +1,254 @@ +using Microsoft.Build.Execution; +using Xunit; +using Xunit.Abstractions; + +namespace NuGetizer +{ + public class given_an_empty_library + { + ITestOutputHelper output; + + public given_an_empty_library(ITestOutputHelper output) + { + this.output = output; + Builder.BuildScenario(nameof(given_an_empty_library), target: "Restore") + .AssertSuccess(output); + } + + [Fact] + public void when_getting_package_contents_then_includes_output_assembly() + { + var result = Builder.BuildScenario(nameof(given_an_empty_library)); + + result.AssertSuccess(output); + Assert.Contains(result.Items, item => item.Matches(new + { + Extension = ".dll", + Kind = "Lib" + })); + } + + [Fact] + public void when_include_outputs_in_package_is_false_then_does_not_include_main_assembly() + { + var result = Builder.BuildScenario(nameof(given_an_empty_library), new + { + PackBuildOutput = false, + }); + + result.AssertSuccess(output); + Assert.DoesNotContain(result.Items, item => item.Matches(new + { + Extension = ".dll", + Kind = "Lib" + })); + } + + [Fact] + public void when_getting_package_contents_then_includes_symbols() + { + var result = Builder.BuildScenario(nameof(given_an_empty_library), new { Configuration = "Debug" }); + + result.AssertSuccess(output); + Assert.Contains(result.Items, item => item.Matches(new + { + Extension = ".pdb", + })); + } + + [Fact] + public void when_include_symbols_in_package_is_true_but_include_outputs_is_false_then_does_not_include_symbols() + { + var result = Builder.BuildScenario(nameof(given_an_empty_library), new + { + PackBuildOutput = false, + PackSymbols = true, + }); + + result.AssertSuccess(output); + Assert.DoesNotContain(result.Items, item => item.Matches(new + { + Extension = ".pdb", + })); + } + + [Fact] + public void when_include_symbols_in_package_is_false_then_does_not_include_symbols() + { + var result = Builder.BuildScenario(nameof(given_an_empty_library), new + { + PackSymbols = false, + }); + + result.AssertSuccess(output); + Assert.DoesNotContain(result.Items, item => item.Matches(new + { + Extension = ".pdb", + })); + } + + [Fact] + public void when_getting_package_contents_then_includes_xmldoc() + { + var result = Builder.BuildScenario(nameof(given_an_empty_library)); + + Assert.Equal(TargetResultCode.Success, result.ResultCode); + Assert.Contains(result.Items, item => item.Matches(new + { + Extension = ".xml", + Kind = PackageItemKind.Lib, + })); + } + + [Fact] + public void when_include_output_in_package_is_false_then_does_not_include_xmldoc() + { + var result = Builder.BuildScenario(nameof(given_an_empty_library), new + { + PackBuildOutput = false, + }); + + result.AssertSuccess(output); + Assert.DoesNotContain(result.Items, item => item.Matches(new + { + Extension = ".xml", + Kind = PackageItemKind.Lib, + })); + } + + [Fact] + public void when_getting_package_contents_then_annotates_items_with_package_id() + { + var result = Builder.BuildScenario(nameof(given_an_empty_library), new { PackageId = "Foo" }, output: output); + + result.AssertSuccess(output); + Assert.All(result.Items, item => Assert.Equal("Foo", item.GetMetadata("PackageId"))); + } + + [Fact] + public void when_getting_package_contents_then_includes_framework_reference() + { + Builder.BuildScenario(nameof(given_an_empty_library), new + { + PackageId = "Foo", + TargetFramework = "net472", + },target: "Restore").AssertSuccess(output); + + var result = Builder.BuildScenario(nameof(given_an_empty_library), new + { + PackageId = "Foo", + TargetFramework = "net472", + }, output: output); + + result.AssertSuccess(output); + Assert.Contains(result.Items, item => item.Matches(new + { + Identity = "PresentationFramework", + Kind = PackageItemKind.FrameworkReference, + })); + } + + [Fact] + public void when_include_framework_references_in_package_is_false_then_does_not_include_framework_reference() + { + var result = Builder.BuildScenario(nameof(given_an_empty_library), new + { + PackFrameworkReferences = false, + PackageId = "Foo", + }, output: output); + + result.AssertSuccess(output); + Assert.DoesNotContain(result.Items, item => item.Matches(new + { + Identity = "System.Core", + Kind = PackageItemKind.FrameworkReference, + })); + } + + [Fact] + public void when_getting_metadata_then_adds_repository_info() + { + var result = Builder.BuildScenario(nameof(given_an_empty_library), new + { + PackageId = "Foo", + PublishRepositoryUrl = "true", + }, target: "GetPackageMetadata", output: output); + + result.AssertSuccess(output); + + Assert.Single(result.Items); + var metadata = result.Items[0]; + + Assert.Equal("git", metadata.GetMetadata("RepositoryType")); + Assert.Equal("https://github.com/kzu/NuGetizer", metadata.GetMetadata("RepositoryUrl")); + Assert.NotEmpty(metadata.GetMetadata("RepositoryCommit")); + } + + [Fact] + public void when_getting_metadata_with_no_explicit_publish_repo_url_then_does_not_expose_it() + { + var result = Builder.BuildScenario(nameof(given_an_empty_library), new + { + PackageId = "Foo", + }, target: "GetPackageMetadata", output: output); + + result.AssertSuccess(output); + + Assert.Single(result.Items); + var metadata = result.Items[0]; + + Assert.Empty(metadata.GetMetadata("RepositoryUrl")); + Assert.NotEmpty(metadata.GetMetadata("RepositoryCommit")); + } + + [Fact] + public void when_updating_package_item_metadata_then_updates_metadata() + { + var result = Builder.BuildScenario(nameof(given_an_empty_library), new + { + PackageId = "Foo", + AdvancedCustomization = "true", + }, target: "GetPackageMetadata", output: output); + + result.AssertSuccess(output); + + Assert.Single(result.Items); + var metadata = result.Items[0]; + + Assert.Equal("ItemDescription", metadata.GetMetadata("Description")); + } + + [Fact] + public void when_updating_package_metadata_property_in_target_then_updates_metadata() + { + var result = Builder.BuildScenario(nameof(given_an_empty_library), new + { + PackageId = "Foo", + }, target: "GetPackageMetadata", output: output); + + result.AssertSuccess(output); + + Assert.Single(result.Items); + var metadata = result.Items[0]; + + Assert.Equal("PropertyDescription", metadata.GetMetadata("Description")); + } + + [Fact] + public void when_setting_metadata_property_then_updates_metadata() + { + var result = Builder.BuildScenario(nameof(given_an_empty_library), new + { + PackageId = "Foo", + Title = "MyPackage", + }, target: "GetPackageMetadata", output: output); + + result.AssertSuccess(output); + + Assert.Single(result.Items); + var metadata = result.Items[0]; + + Assert.Equal("MyPackage", metadata.GetMetadata("Title")); + } + } +} diff --git a/src/Build/NuGet.Build.Packaging.Tests/given_duplicate_package_files.cs b/src/NuGetizer.Tests/given_duplicate_package_files.cs similarity index 91% rename from src/Build/NuGet.Build.Packaging.Tests/given_duplicate_package_files.cs rename to src/NuGetizer.Tests/given_duplicate_package_files.cs index c351a905..3b2cf5ff 100644 --- a/src/Build/NuGet.Build.Packaging.Tests/given_duplicate_package_files.cs +++ b/src/NuGetizer.Tests/given_duplicate_package_files.cs @@ -3,7 +3,7 @@ using Xunit; using Xunit.Abstractions; -namespace NuGet.Build.Packaging +namespace NuGetizer { public class given_duplicate_package_files { @@ -12,9 +12,11 @@ public class given_duplicate_package_files public given_duplicate_package_files(ITestOutputHelper output) { this.output = output; - } + Builder.BuildScenario(nameof(given_duplicate_package_files), target: "Restore") + .AssertSuccess(output); + } - [Fact] + [Fact] public void exact_duplicates_are_removed() { var result = Builder.BuildScenario(nameof(given_duplicate_package_files), target: "Pack"); diff --git a/src/Build/NuGet.Build.Packaging.Tests/xunit.runner.json b/src/NuGetizer.Tests/xunit.runner.json similarity index 100% rename from src/Build/NuGet.Build.Packaging.Tests/xunit.runner.json rename to src/NuGetizer.Tests/xunit.runner.json diff --git a/src/Sample/Before.Sample.sln.targets b/src/Sample/Before.Sample.sln.targets index 1752dabc..26f8d603 100644 --- a/src/Sample/Before.Sample.sln.targets +++ b/src/Sample/Before.Sample.sln.targets @@ -6,7 +6,7 @@ - + diff --git a/src/Sample/Sample.targets b/src/Sample/Sample.targets index ed4d891a..1e8b354b 100644 --- a/src/Sample/Sample.targets +++ b/src/Sample/Sample.targets @@ -17,12 +17,12 @@ - + - diff --git a/src/dotnet-nugetize/DotnetMuxer.cs b/src/dotnet-nugetize/DotnetMuxer.cs new file mode 100644 index 00000000..11eee730 --- /dev/null +++ b/src/dotnet-nugetize/DotnetMuxer.cs @@ -0,0 +1,49 @@ +using System; +using System.IO; +using System.Runtime.InteropServices; + +internal static class DotnetMuxer +{ + public static FileInfo Path { get; } + + static DotnetMuxer() + { + var muxerFileName = ExecutableName("dotnet"); + var fxDepsFile = GetDataFromAppDomain("FX_DEPS_FILE"); + + if (string.IsNullOrEmpty(fxDepsFile)) + + { + return; + } + + var muxerDir = new FileInfo(fxDepsFile).Directory?.Parent?.Parent?.Parent; + + if (muxerDir == null) + { + return; + + } + + var muxerCandidate = new FileInfo(System.IO.Path.Combine(muxerDir.FullName, muxerFileName)); + + if (muxerCandidate.Exists) + { + Path = muxerCandidate; + } + else + { + throw new InvalidOperationException("no muxer!"); + } + } + + public static string GetDataFromAppDomain(string propertyName) + { + return AppContext.GetData(propertyName) as string; + } + + public static string ExecutableName(this string withoutExtension) => + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + ? withoutExtension + ".exe" + : withoutExtension; +} \ No newline at end of file diff --git a/src/dotnet-nugetize/Program.cs b/src/dotnet-nugetize/Program.cs new file mode 100644 index 00000000..b3eed1b3 --- /dev/null +++ b/src/dotnet-nugetize/Program.cs @@ -0,0 +1,207 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Xml.Linq; +using ColoredConsole; + +namespace NuGetize +{ + class Program + { + static int Main(string[] args) + { + var binlog = Debugger.IsAttached || args.Any(arg => arg == "--bl" || arg == "-bl"); + var debug = args.Any(args => args == "--debug"); + + if (args.Any(arg => arg == "--version")) + ColorConsole.WriteLine($"{ThisAssembly.Project.ToolCommandName} version {ThisAssembly.Project.Version}".Green()); + + return Execute(binlog, debug); + } + + static int Execute(bool binlog, bool debug) + { + var tooldir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); + var project = ""; + var bl = binlog ? $"-bl:\"{Directory.GetCurrentDirectory()}\\build.binlog;ProjectImports=None\"" : ""; + var file = Path.Combine(Directory.GetCurrentDirectory(), "dotnet-nugetize.items"); + + var projects = Directory.EnumerateFiles(Directory.GetCurrentDirectory(), "*.*proj").ToList(); + var solutions = Directory.EnumerateFiles(Directory.GetCurrentDirectory(), "*.sln").ToList(); + + // TODO: allow specifying which project. + if (solutions.Count == 1) + project = solutions[0]; + else if (projects.Count > 1) + project = projects[0]; + + if (!Execute(DotnetMuxer.Path.FullName, $"restore {project} -nologo {bl.Replace("build.binlog", "restore.binlog")}", debug)) + return -1; + + if (File.Exists(file)) + File.Delete(file); + + // Optimize the "build" so that it doesn't actually do a full compile if possible. + if (!Execute(DotnetMuxer.Path.FullName, $"msbuild {project} -m:1 -p:dotnet-nugetize=\"{file}\" -nologo {bl} -t:\"GetPackageContents;Pack\" -p:EmitNuspec=true -p:EmitPackage=false -p:SkipCompilerExecution=true -p:DesignTimeBuild=true -p:DesignTimeSilentResolution=true -p:ResolveAssemblyReferencesSilent=true", debug)) + return -1; + + var items = XDocument.Load(file); + var foundPackage = false; + + foreach (var metadata in items.Root.Descendants("PackageMetadata") + .Distinct(AnonymousEqualityComparer.Create( + (x, y) => x.Element("PackageId")?.Value == y.Element("PackageId")?.Value, + x => x.Element("PackageId")?.Value.GetHashCode() ?? 0))) + { + var packageId = metadata.Element("PackageId").Value; + foundPackage = true; + ColorConsole.WriteLine($"Package: {Path.GetFileName(metadata.Element("NuPkg").Value)}".Yellow()); + ColorConsole.WriteLine($" {metadata.Element("Nuspec").Value}".Yellow()); + + var width = metadata.Elements() + .Select(x => x.Name.LocalName.Length) + .OrderByDescending(x => x) + .First(); + + foreach (var md in metadata.Elements() + .Where(x => + x.Name != "PackageId" && + x.Name != "Nuspec" && + x.Name != "NuPkg") + .OrderBy(x => x.Name.LocalName)) + { + ColorConsole.WriteLine($" {md.Name.LocalName.PadRight(width)}: ", md.Value.White()); + } + + var dependencies = items.Root.Descendants("PackageContent") + .Where(x => + "Dependency".Equals(x.Element("Kind")?.Value, StringComparison.OrdinalIgnoreCase) && + x.Element("PackageId")?.Value == packageId) + .ToList(); + + if (dependencies.Count > 0) + { + ColorConsole.WriteLine($" Dependencies:".Yellow()); + foreach (var group in dependencies.GroupBy(x => x.Element("TargetFramework").Value)) + { + ColorConsole.WriteLine(" ", group.Key.Green()); + foreach (var dependency in group) + { + ColorConsole.WriteLine(" ", dependency.Attribute("Include").Value.White(), $", {dependency.Element("Version").Value}".Gray()); + } + } + } + + ColorConsole.WriteLine($" Contents:".Yellow()); + + var contents = items.Root.Descendants("PackageContent") + .Where(x => + x.Element("PackagePath") != null && + x.Element("PackageId")?.Value == packageId) + .Select(x => x.Element("PackagePath").Value) + .Distinct() + .OrderBy(x => x); + + RenderContents(contents.ToList(), 0, 0, ""); + Console.WriteLine(); + } + + if (!foundPackage) + { + ColorConsole.WriteLine($"No package content was found.".Red()); + return -1; + } + + Console.WriteLine(); + ColorConsole.WriteLine("Items: ", file.Yellow()); + + return 0; + } + + static int RenderContents(IList files, int index, int level, string path) + { + while (index < files.Count) + + { + var file = files[index]; + var dir = Path.GetDirectoryName(file); + var paths = dir.Split(new[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar }, StringSplitOptions.RemoveEmptyEntries); + + if (!string.Join(Path.DirectorySeparatorChar, paths).StartsWith(path) || + paths.Length < level) + return index; + + if (paths.Length > level) + { + ColorConsole.Write(new string(' ', (level + 1) * 2 + 2)); + if (level == 0) + ColorConsole.Write("/".Gray()); + + ColorConsole.WriteLine(paths[level].Green(), "/".Gray()); + index = RenderContents(files, index, level + 1, string.Join(Path.DirectorySeparatorChar, paths[..(level + 1)])); + } + else + { + Console.Write(new string(' ', (level + 1) * 2 + 2)); + if (level == 0) + ColorConsole.Write("/".Gray()); + + ColorConsole.WriteLine(Path.GetFileName(file).White()); + index++; + } + } + + return index; + } + + static bool Execute(string program, string arguments, bool debug = false) + { + var info = new ProcessStartInfo(program, arguments) + { + RedirectStandardOutput = debug, + RedirectStandardError = debug + }; + + var proc = Process.Start(info); + if (debug) + { + Console.Out.Write(proc.StandardOutput.ReadToEnd()); + Console.Error.Write(proc.StandardError.ReadToEnd()); + } + + if (!proc.WaitForExit(5000)) + { + proc.Kill(); + return false; + } + + return proc.ExitCode == 0; + } + + static class AnonymousEqualityComparer + { + public static IEqualityComparer Create(Func equals, Func getHashCode) + => new AnonymousEqualityComparer(equals, getHashCode); + } + + class AnonymousEqualityComparer : IEqualityComparer + { + Func equals; + Func getHashCode; + + public AnonymousEqualityComparer(Func equals, Func getHashCode) + { + this.equals = equals; + this.getHashCode = getHashCode; + } + + public bool Equals(T x, [AllowNull] T y) => equals(x, y); + + public int GetHashCode([DisallowNull] T obj) => getHashCode(obj); + } + } +} diff --git a/src/dotnet-nugetize/Properties/.gitignore b/src/dotnet-nugetize/Properties/.gitignore new file mode 100644 index 00000000..8392c905 --- /dev/null +++ b/src/dotnet-nugetize/Properties/.gitignore @@ -0,0 +1 @@ +launchSettings.json \ No newline at end of file diff --git a/src/dotnet-nugetize/Range.cs b/src/dotnet-nugetize/Range.cs new file mode 100644 index 00000000..b3bf7f3f --- /dev/null +++ b/src/dotnet-nugetize/Range.cs @@ -0,0 +1,279 @@ +// https://github.com/dotnet/corefx/blob/1597b894a2e9cac668ce6e484506eca778a85197/src/Common/src/CoreLib/System/Index.cs +// https://github.com/dotnet/corefx/blob/1597b894a2e9cac668ce6e484506eca778a85197/src/Common/src/CoreLib/System/Range.cs +#pragma warning disable CS0436 // Type conflicts with imported type +#nullable enable + +using System.Runtime.CompilerServices; + +namespace System +{ + /// Represent a type can be used to index a collection either from the start or the end. + /// + /// Index is used by the C# compiler to support the new index syntax + /// + /// int[] someArray = new int[5] { 1, 2, 3, 4, 5 } ; + /// int lastElement = someArray[^1]; // lastElement = 5 + /// + /// + internal readonly struct Index : IEquatable + { + private readonly int _value; + + /// Construct an Index using a value and indicating if the index is from the start or from the end. + /// The index value. it has to be zero or positive number. + /// Indicating if the index is from the start or from the end. + /// + /// If the Index constructed from the end, index value 1 means pointing at the last element and index value 0 means pointing at beyond last element. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Index(int value, bool fromEnd = false) + { + if (value < 0) + { + throw new ArgumentOutOfRangeException(nameof(value), "value must be non-negative"); + } + + if (fromEnd) + _value = ~value; + else + _value = value; + } + + // The following private constructors mainly created for perf reason to avoid the checks + private Index(int value) + { + _value = value; + } + + /// Create an Index pointing at first element. + public static Index Start => new Index(0); + + /// Create an Index pointing at beyond last element. + public static Index End => new Index(~0); + + /// Create an Index from the start at the position indicated by the value. + /// The index value from the start. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Index FromStart(int value) + { + if (value < 0) + { + throw new ArgumentOutOfRangeException(nameof(value), "value must be non-negative"); + } + + return new Index(value); + } + + /// Create an Index from the end at the position indicated by the value. + /// The index value from the end. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Index FromEnd(int value) + { + if (value < 0) + { + throw new ArgumentOutOfRangeException(nameof(value), "value must be non-negative"); + } + + return new Index(~value); + } + + /// Returns the index value. + public int Value + { + get + { + if (_value < 0) + { + return ~_value; + } + else + { + return _value; + } + } + } + + /// Indicates whether the index is from the start or the end. + public bool IsFromEnd => _value < 0; + + /// Calculate the offset from the start using the giving collection length. + /// The length of the collection that the Index will be used with. length has to be a positive value + /// + /// For performance reason, we don't validate the input length parameter and the returned offset value against negative values. + /// we don't validate either the returned offset is greater than the input length. + /// It is expected Index will be used with collections which always have non negative length/count. If the returned offset is negative and + /// then used to index a collection will get out of range exception which will be same affect as the validation. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public int GetOffset(int length) + { + var offset = _value; + if (IsFromEnd) + { + // offset = length - (~value) + // offset = length + (~(~value) + 1) + // offset = length + value + 1 + + offset += length + 1; + } + return offset; + } + + /// Indicates whether the current Index object is equal to another object of the same type. + /// An object to compare with this object + public override bool Equals(object? value) => value is Index && _value == ((Index)value)._value; + + /// Indicates whether the current Index object is equal to another Index object. + /// An object to compare with this object + public bool Equals(Index other) => _value == other._value; + + /// Returns the hash code for this instance. + public override int GetHashCode() => _value; + + /// Converts integer number to an Index. + public static implicit operator Index(int value) => FromStart(value); + + /// Converts the value of the current Index object to its equivalent string representation. + public override string ToString() + { + if (IsFromEnd) + return "^" + ((uint)Value).ToString(); + + return ((uint)Value).ToString(); + } + } + + /// Represent a range has start and end indexes. + /// + /// Range is used by the C# compiler to support the range syntax. + /// + /// int[] someArray = new int[5] { 1, 2, 3, 4, 5 }; + /// int[] subArray1 = someArray[0..2]; // { 1, 2 } + /// int[] subArray2 = someArray[1..^0]; // { 2, 3, 4, 5 } + /// + /// + internal readonly struct Range : IEquatable + { + /// Represent the inclusive start index of the Range. + public Index Start { get; } + + /// Represent the exclusive end index of the Range. + public Index End { get; } + + /// Construct a Range object using the start and end indexes. + /// Represent the inclusive start index of the range. + /// Represent the exclusive end index of the range. + public Range(Index start, Index end) + { + Start = start; + End = end; + } + + /// Indicates whether the current Range object is equal to another object of the same type. + /// An object to compare with this object + public override bool Equals(object? value) => + value is Range r && + r.Start.Equals(Start) && + r.End.Equals(End); + + /// Indicates whether the current Range object is equal to another Range object. + /// An object to compare with this object + public bool Equals(Range other) => other.Start.Equals(Start) && other.End.Equals(End); + + /// Returns the hash code for this instance. + public override int GetHashCode() + { + return Start.GetHashCode() * 31 + End.GetHashCode(); + } + + /// Converts the value of the current Range object to its equivalent string representation. + public override string ToString() + { + return Start + ".." + End; + } + + /// Create a Range object starting from start index to the end of the collection. + public static Range StartAt(Index start) => new Range(start, Index.End); + + /// Create a Range object starting from first element in the collection to the end Index. + public static Range EndAt(Index end) => new Range(Index.Start, end); + + /// Create a Range object starting from first element to the end. + public static Range All => new Range(Index.Start, Index.End); + + /// Calculate the start offset and length of range object using a collection length. + /// The length of the collection that the range will be used with. length has to be a positive value. + /// + /// For performance reason, we don't validate the input length parameter against negative values. + /// It is expected Range will be used with collections which always have non negative length/count. + /// We validate the range is inside the length scope though. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public (int Offset, int Length) GetOffsetAndLength(int length) + { + int start; + var startIndex = Start; + if (startIndex.IsFromEnd) + start = length - startIndex.Value; + else + start = startIndex.Value; + + int end; + var endIndex = End; + if (endIndex.IsFromEnd) + end = length - endIndex.Value; + else + end = endIndex.Value; + + if ((uint)end > (uint)length || (uint)start > (uint)end) + { + throw new ArgumentOutOfRangeException(nameof(length)); + } + + return (start, end - start); + } + } +} + +namespace System.Runtime.CompilerServices +{ + internal static class RuntimeHelpers + { + /// + /// Slices the specified array using the specified range. + /// + public static T[] GetSubArray(T[] array, Range range) + { + if (array == null) + { + throw new ArgumentNullException(nameof(array)); + } + + (int offset, int length) = range.GetOffsetAndLength(array.Length); + + if (default(T) != null || typeof(T[]) == array.GetType()) + { + // We know the type of the array to be exactly T[]. + + if (length == 0) + { + return Array.Empty(); + } + + var dest = new T[length]; + Array.Copy(array, offset, dest, 0, length); + return dest; + } + else + { + // The array is actually a U[] where U:T. +#pragma warning disable CS8604 // Possible null reference argument. + var dest = (T[])Array.CreateInstance(array.GetType().GetElementType(), length); +#pragma warning restore CS8604 // Possible null reference argument. + Array.Copy(array, offset, dest, 0, length); + return dest; + } + } + } +} +#pragma warning restore CS0436 // Type conflicts with imported type diff --git a/src/dotnet-nugetize/dotnet-nugetize.csproj b/src/dotnet-nugetize/dotnet-nugetize.csproj new file mode 100644 index 00000000..d6bbf659 --- /dev/null +++ b/src/dotnet-nugetize/dotnet-nugetize.csproj @@ -0,0 +1,35 @@ + + + + Exe + netcoreapp2.1;netcoreapp3.1;net5.0 + true + false + + dotnet-nugetize + nugetize + true + + Discover how NuGetizer packs a project + Run the `nugetize` tool on a folder with a packable project (i.e. it has at least a PackageId value) to see what package structure NuGetizer would produce. + + + + + + + + + + + + + + + + + + + + +