diff --git a/packaging/nuget/package.ps1 b/packaging/nuget/package.ps1 index 3924b4d2b..d93302143 100644 --- a/packaging/nuget/package.ps1 +++ b/packaging/nuget/package.ps1 @@ -37,7 +37,7 @@ foreach ($ProjectName in $Projects) { Write-Host "$toolsDir\dotnet restore failed for: $ProjectFile" Exit 1 } - & $toolsDir\dotnet pack "$ProjectFile" --output "$IntermediatePackagesDir" $versionArg + & $toolsDir\dotnet pack "$ProjectFile" --input "Stage2Dir\bin" --output "$IntermediatePackagesDir" $versionArg if (!$?) { Write-Host "$toolsDir\dotnet pack failed for: $ProjectFile" Exit 1 diff --git a/src/Microsoft.DotNet.Tools.Pack/ArtifactPathsCalculator.cs b/src/Microsoft.DotNet.Tools.Pack/ArtifactPathsCalculator.cs new file mode 100644 index 000000000..92397ed01 --- /dev/null +++ b/src/Microsoft.DotNet.Tools.Pack/ArtifactPathsCalculator.cs @@ -0,0 +1,58 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.IO; +using Microsoft.DotNet.Cli.Utils; +using Microsoft.DotNet.ProjectModel; +using NuGet.Frameworks; + +namespace Microsoft.DotNet.Tools.Pack +{ + public class ArtifactPathsCalculator + { + private readonly Project _project; + + private readonly string _configuration; + + private bool PackageArtifactsPathSet => !string.IsNullOrWhiteSpace(PackageArtifactsPathParameter); + + public string CompiledArtifactsPathParameter { get; } + + public string PackageArtifactsPathParameter { get; } + + public bool CompiledArtifactsPathSet => !string.IsNullOrWhiteSpace(CompiledArtifactsPathParameter); + + public string CompiledArtifactsPath => CompiledArtifactsPathSet ? CompiledArtifactsPathParameter : PackageArtifactsPath; + + public string PackageArtifactsPath + { + get + { + if (PackageArtifactsPathSet) + { + return PackageArtifactsPathParameter; + } + + var outputPath = Path.Combine( + _project.ProjectDirectory, + Constants.BinDirectoryName, + _configuration); + + return outputPath; + } + } + + public ArtifactPathsCalculator(Project project, string compiledArtifactsPath, string packageArtifactsPath, string configuration) + { + _project = project; + CompiledArtifactsPathParameter = compiledArtifactsPath; + PackageArtifactsPathParameter = packageArtifactsPath; + _configuration = configuration; + } + + public string InputPathForContext(ProjectContext context) + { + return CompiledArtifactsPathSet ? CompiledArtifactsPath : Path.Combine(CompiledArtifactsPath, context.TargetFramework.GetTwoDigitShortFolderName()); + } + } +} diff --git a/src/Microsoft.DotNet.Tools.Pack/BuildProjectCommand.cs b/src/Microsoft.DotNet.Tools.Pack/BuildProjectCommand.cs new file mode 100644 index 000000000..9f3718957 --- /dev/null +++ b/src/Microsoft.DotNet.Tools.Pack/BuildProjectCommand.cs @@ -0,0 +1,68 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.Linq; +using System.Text; +using Microsoft.DotNet.Cli.Utils; +using Microsoft.DotNet.ProjectModel; + +namespace Microsoft.DotNet.Tools.Pack +{ + internal class BuildProjectCommand + { + private readonly Project _project; + private readonly ArtifactPathsCalculator _artifactPathsCalculator; + + private readonly string _intermediateOutputPath; + private readonly string _configuration; + + private bool SkipBuild => _artifactPathsCalculator.CompiledArtifactsPathSet; + + public BuildProjectCommand( + Project project, + ArtifactPathsCalculator artifactPathsCalculator, + string intermediateOutputPath, + string configuration) + { + _project = project; + _artifactPathsCalculator = artifactPathsCalculator; + _intermediateOutputPath = intermediateOutputPath; + _configuration = configuration; + } + + public int Execute() + { + if (SkipBuild) + { + return 0; + } + + if (_project.Files.SourceFiles.Any()) + { + var argsBuilder = new StringBuilder(); + argsBuilder.Append($"--configuration {_configuration}"); + + if (!string.IsNullOrEmpty(_artifactPathsCalculator.PackageArtifactsPathParameter)) + { + argsBuilder.Append($" --output \"{_artifactPathsCalculator.PackageArtifactsPathParameter}\""); + } + + if (!string.IsNullOrEmpty(_intermediateOutputPath)) + { + argsBuilder.Append($" --temp-output \"{_intermediateOutputPath}\""); + } + + argsBuilder.Append($" \"{_project.ProjectFilePath}\""); + + var result = Command.Create("dotnet-build", argsBuilder.ToString()) + .ForwardStdOut() + .ForwardStdErr() + .Execute(); + + return result.ExitCode; + } + + return 0; + } + } +} diff --git a/src/Microsoft.DotNet.Tools.Pack/PackageGenerator.cs b/src/Microsoft.DotNet.Tools.Pack/PackageGenerator.cs index be8a483ed..aba042e57 100644 --- a/src/Microsoft.DotNet.Tools.Pack/PackageGenerator.cs +++ b/src/Microsoft.DotNet.Tools.Pack/PackageGenerator.cs @@ -17,25 +17,27 @@ using NuGet.Frameworks; using NuGet.Packaging.Core; using NuGet.Versioning; using Microsoft.DotNet.Cli.Compiler.Common; +using Microsoft.DotNet.Tools.Pack; +using PackageBuilder = NuGet.PackageBuilder; namespace Microsoft.DotNet.Tools.Compiler { public class PackageGenerator { + protected ArtifactPathsCalculator ArtifactPathsCalculator { get; } + protected Project Project { get; } protected string Configuration { get; } - protected string OutputPath { get; } - protected PackageBuilder PackageBuilder { get; private set; } - public PackageGenerator(Project project, string configuration, string outputPath) + public PackageGenerator(Project project, string configuration, ArtifactPathsCalculator artifactPathsCalculator) { + ArtifactPathsCalculator = artifactPathsCalculator; Project = project; Configuration = configuration; - OutputPath = outputPath; - } + } public bool BuildPackage(IEnumerable contexts, List packDiagnostics) { @@ -55,7 +57,9 @@ namespace Microsoft.DotNet.Tools.Compiler Reporter.Verbose.WriteLine(""); } - var packageOutputPath = Path.Combine(GetOutputPath(), GetPackageName() + NuGet.Constants.PackageExtension); + var packageOutputPath = Path.Combine( + ArtifactPathsCalculator.PackageArtifactsPath, + GetPackageName() + NuGet.Constants.PackageExtension); if (GeneratePackage(packageOutputPath, packDiagnostics)) { @@ -69,7 +73,7 @@ namespace Microsoft.DotNet.Tools.Compiler { PopulateDependencies(context); - var outputPath = GetOutputPath(context); + var inputFolder = ArtifactPathsCalculator.InputPathForContext(context); var outputName = GetProjectOutputName(context.TargetFramework); var resourceCultures = context.ProjectFile.Files.ResourceFiles @@ -84,11 +88,11 @@ namespace Microsoft.DotNet.Tools.Compiler } var resourceFilePath = Path.Combine(culture, $"{Project.Name}.resources.dll"); - TryAddOutputFile(context, outputPath, resourceFilePath); + TryAddOutputFile(context, inputFolder, resourceFilePath); } - TryAddOutputFile(context, outputPath, outputName); - TryAddOutputFile(context, outputPath, $"{Project.Name}.xml"); + TryAddOutputFile(context, inputFolder, outputName); + TryAddOutputFile(context, inputFolder, $"{Project.Name}.xml"); } protected virtual bool GeneratePackage(string nupkg, List packDiagnostics) @@ -317,46 +321,7 @@ namespace Microsoft.DotNet.Tools.Compiler } return Project.Name + outputExtension; - } - - protected string GetOutputPath() - { - var outputPath = string.Empty; - - if (string.IsNullOrEmpty(OutputPath)) - { - outputPath = Path.Combine( - GetDefaultRootOutputPath(Project, OutputPath), - Cli.Utils.Constants.BinDirectoryName, - Configuration); - } - else - { - outputPath = OutputPath; - } - - return outputPath; - } - - protected string GetOutputPath(ProjectContext context) - { - var outputPath = string.Empty; - - if (string.IsNullOrEmpty(OutputPath)) - { - outputPath = Path.Combine( - GetDefaultRootOutputPath(context.ProjectFile, OutputPath), - Cli.Utils.Constants.BinDirectoryName, - Configuration, - context.TargetFramework.GetTwoDigitShortFolderName()); - } - else - { - outputPath = OutputPath; - } - - return outputPath; - } + } private static string GetDefaultRootOutputPath(Project project, string outputOptionValue) { diff --git a/src/Microsoft.DotNet.Tools.Pack/PackagesGenerator.cs b/src/Microsoft.DotNet.Tools.Pack/PackagesGenerator.cs new file mode 100644 index 000000000..5858b6ae8 --- /dev/null +++ b/src/Microsoft.DotNet.Tools.Pack/PackagesGenerator.cs @@ -0,0 +1,41 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.Collections.Generic; +using System.Linq; +using Microsoft.DotNet.ProjectModel; +using Microsoft.DotNet.Tools.Compiler; + +namespace Microsoft.DotNet.Tools.Pack +{ + public class PackagesGenerator + { + private readonly IEnumerable _contexts; + private readonly ArtifactPathsCalculator _artifactPathsCalculator; + private readonly string _configuration; + + public PackagesGenerator( + IEnumerable contexts, + ArtifactPathsCalculator artifactPathsCalculator, + string configuration) + { + _contexts = contexts; + _artifactPathsCalculator = artifactPathsCalculator; + _configuration = configuration; + } + + public int Build() + { + var project = _contexts.First().ProjectFile; + + var packDiagnostics = new List(); + + var mainPackageGenerator = new PackageGenerator(project, _configuration, _artifactPathsCalculator); + var symbolsPackageGenerator = + new SymbolPackageGenerator(project, _configuration, _artifactPathsCalculator); + + return mainPackageGenerator.BuildPackage(_contexts, packDiagnostics) && + symbolsPackageGenerator.BuildPackage(_contexts, packDiagnostics) ? 0 : 1; + } + } +} diff --git a/src/Microsoft.DotNet.Tools.Pack/Program.cs b/src/Microsoft.DotNet.Tools.Pack/Program.cs index ba3d6b779..0fa4d1041 100644 --- a/src/Microsoft.DotNet.Tools.Pack/Program.cs +++ b/src/Microsoft.DotNet.Tools.Pack/Program.cs @@ -2,13 +2,12 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; -using System.Collections.Generic; using System.IO; using System.Linq; -using System.Text; using Microsoft.DotNet.ProjectModel; using Microsoft.Dnx.Runtime.Common.CommandLine; using Microsoft.DotNet.Cli.Utils; +using Microsoft.DotNet.Tools.Pack; namespace Microsoft.DotNet.Tools.Compiler { @@ -24,29 +23,30 @@ namespace Microsoft.DotNet.Tools.Compiler app.Description = "Packager for the .NET Platform"; app.HelpOption("-h|--help"); + var input = app.Option("-i|--input ", "Directory from where the assets to be packages are going to be picked up", CommandOptionType.SingleValue); var output = app.Option("-o|--output ", "Directory in which to place outputs", CommandOptionType.SingleValue); var intermediateOutput = app.Option("-t|--temp-output ", "Directory in which to place temporary outputs", CommandOptionType.SingleValue); var configuration = app.Option("-c|--configuration ", "Configuration under which to build", CommandOptionType.SingleValue); var versionSuffix = app.Option("--version-suffix ", "Defines what `*` should be replaced with in version field in project.json", CommandOptionType.SingleValue); - var project = app.Argument("", "The project to compile, defaults to the current directory. Can be a path to a project.json or a project directory"); + var path = app.Argument("", "The project to compile, defaults to the current directory. Can be a path to a project.json or a project directory"); app.OnExecute(() => { // Locate the project and get the name and full path - var path = project.Value; - if (string.IsNullOrEmpty(path)) + var pathValue = path.Value; + if (string.IsNullOrEmpty(pathValue)) { - path = Directory.GetCurrentDirectory(); + pathValue = Directory.GetCurrentDirectory(); } - if(!path.EndsWith(Project.FileName)) + if(!pathValue.EndsWith(Project.FileName)) { - path = Path.Combine(path, Project.FileName); + pathValue = Path.Combine(pathValue, Project.FileName); } - if(!File.Exists(path)) + if(!File.Exists(pathValue)) { - Reporter.Error.WriteLine($"Unable to find a project.json in {path}"); + Reporter.Error.WriteLine($"Unable to find a project.json in {pathValue}"); return 1; } @@ -60,10 +60,21 @@ namespace Microsoft.DotNet.Tools.Compiler settings.VersionSuffix = versionSuffix.Value(); } - var configValue = configuration.Value() ?? Cli.Utils.Constants.DefaultConfiguration; - var outputValue = output.Value(); + var contexts = ProjectContext.CreateContextForEachFramework(pathValue, settings); - return TryBuildPackage(path, configValue, outputValue, intermediateOutput.Value(), settings) ? 0 : 1; + var configValue = configuration.Value() ?? Cli.Utils.Constants.DefaultConfiguration; + var inputValue = input.Value(); + var outputValue = output.Value(); + var intermediateOutputValue = intermediateOutput.Value(); + + var project = contexts.First().ProjectFile; + + var artifactPathsCalculator = new ArtifactPathsCalculator(project, inputValue, outputValue, configValue); + var buildProjectCommand = new BuildProjectCommand(project, artifactPathsCalculator, intermediateOutputValue, configValue); + var packageBuilder = new PackagesGenerator(contexts, artifactPathsCalculator, configValue); + + var buildResult = buildProjectCommand.Execute(); + return buildResult != 0 ? buildResult : packageBuilder.Build(); }); try @@ -79,48 +90,6 @@ namespace Microsoft.DotNet.Tools.Compiler #endif return 1; } - } - - private static bool TryBuildPackage(string path, string configuration, string outputValue, string intermediateOutputValue, ProjectReaderSettings settings = null) - { - var contexts = ProjectContext.CreateContextForEachFramework(path, settings); - var project = contexts.First().ProjectFile; - - if (project.Files.SourceFiles.Any()) - { - var argsBuilder = new StringBuilder(); - argsBuilder.Append($"--configuration {configuration}"); - - if (!string.IsNullOrEmpty(outputValue)) - { - argsBuilder.Append($" --output \"{outputValue}\""); - } - - if (!string.IsNullOrEmpty(intermediateOutputValue)) - { - argsBuilder.Append($" --temp-output \"{intermediateOutputValue}\""); - } - - argsBuilder.Append($" \"{path}\""); - - var result = Command.Create("dotnet-build", argsBuilder.ToString()) - .ForwardStdOut() - .ForwardStdErr() - .Execute(); - - if (result.ExitCode != 0) - { - return false; - } - } - - var packDiagnostics = new List(); - - var mainPackageGenerator = new PackageGenerator(project, configuration, outputValue); - var symbolsPackageGenerator = new SymbolPackageGenerator(project, configuration, outputValue); - - return mainPackageGenerator.BuildPackage(contexts, packDiagnostics) && - symbolsPackageGenerator.BuildPackage(contexts, packDiagnostics); - } + } } } \ No newline at end of file diff --git a/src/Microsoft.DotNet.Tools.Pack/SymbolPackageGenerator.cs b/src/Microsoft.DotNet.Tools.Pack/SymbolPackageGenerator.cs index 8fd7f1e49..4e1d93ca7 100644 --- a/src/Microsoft.DotNet.Tools.Pack/SymbolPackageGenerator.cs +++ b/src/Microsoft.DotNet.Tools.Pack/SymbolPackageGenerator.cs @@ -2,16 +2,17 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using Microsoft.DotNet.ProjectModel; -using Microsoft.DotNet.Tools.Common; using NuGet; using System.Collections.Generic; using System.IO; +using Microsoft.DotNet.Tools.Pack; namespace Microsoft.DotNet.Tools.Compiler { public class SymbolPackageGenerator: PackageGenerator { - public SymbolPackageGenerator(Project project, string configuration, string outputPath) : base(project, configuration, outputPath) + public SymbolPackageGenerator(Project project, string configuration, ArtifactPathsCalculator artifactPathsCalculator) + : base(project, configuration, artifactPathsCalculator) { } @@ -24,18 +25,21 @@ namespace Microsoft.DotNet.Tools.Compiler { base.ProcessContext(context); - var outputPath = GetOutputPath(context); - TryAddOutputFile(context, outputPath, $"{Project.Name}.pdb"); - TryAddOutputFile(context, outputPath, $"{Project.Name}.mdb"); + var inputFolder = ArtifactPathsCalculator.InputPathForContext(context); + TryAddOutputFile(context, inputFolder, $"{Project.Name}.pdb"); + TryAddOutputFile(context, inputFolder, $"{Project.Name}.mdb"); } protected override bool GeneratePackage(string nupkg, List packDiagnostics) { foreach (var path in Project.Files.SourceFiles) { - var srcFile = new PhysicalPackageFile(); - srcFile.SourcePath = path; - srcFile.TargetPath = Path.Combine("src", Common.PathUtility.GetRelativePath(Project.ProjectDirectory, path)); + var srcFile = new PhysicalPackageFile + { + SourcePath = path, + TargetPath = Path.Combine("src", Common.PathUtility.GetRelativePath(Project.ProjectDirectory, path)) + }; + PackageBuilder.Files.Add(srcFile); } return base.GeneratePackage(nupkg, packDiagnostics);