diff --git a/src/Microsoft.DotNet.Tools.Publish/Program.cs b/src/Microsoft.DotNet.Tools.Publish/Program.cs index 341291362..b6dd956d1 100644 --- a/src/Microsoft.DotNet.Tools.Publish/Program.cs +++ b/src/Microsoft.DotNet.Tools.Publish/Program.cs @@ -26,6 +26,7 @@ namespace Microsoft.DotNet.Tools.Publish var output = app.Option("-o|--output ", "Path in which to publish the app", CommandOptionType.SingleValue); var configuration = app.Option("-c|--configuration ", "Configuration under which to build", CommandOptionType.SingleValue); var projectPath = app.Argument("", "The project to publish, defaults to the current directory. Can be a path to a project.json or a project directory"); + var nativeSubdirectories = app.Option("--native-subdirectory", "Temporary mechanism to include subdirectories from native assets of dependency packages in output", CommandOptionType.NoValue); app.OnExecute(() => { @@ -36,6 +37,7 @@ namespace Microsoft.DotNet.Tools.Publish publish.Runtime = runtime.Value() ?? RuntimeIdentifier.Current; publish.OutputPath = output.Value(); publish.Configuration = configuration.Value() ?? Constants.DefaultConfiguration; + publish.NativeSubdirectories = nativeSubdirectories.HasValue(); publish.ProjectPath = projectPath.Value; if (string.IsNullOrEmpty(publish.ProjectPath)) @@ -64,5 +66,5 @@ namespace Microsoft.DotNet.Tools.Publish return 1; } } - } + } } diff --git a/src/Microsoft.DotNet.Tools.Publish/PublishCommand.cs b/src/Microsoft.DotNet.Tools.Publish/PublishCommand.cs index de640f35d..0ff7ff2c3 100644 --- a/src/Microsoft.DotNet.Tools.Publish/PublishCommand.cs +++ b/src/Microsoft.DotNet.Tools.Publish/PublishCommand.cs @@ -19,6 +19,7 @@ namespace Microsoft.DotNet.Tools.Publish public string OutputPath { get; set; } public string Framework { get; set; } public string Runtime { get; set; } + public bool NativeSubdirectories { get; set; } public NuGetFramework NugetFramework { get; set; } public IEnumerable ProjectContexts { get; set; } @@ -57,7 +58,7 @@ namespace Microsoft.DotNet.Tools.Publish NumberOfProjects = 0; foreach (var project in ProjectContexts) { - if (PublishProjectContext(project, OutputPath, Configuration)) + if (PublishProjectContext(project, OutputPath, Configuration, NativeSubdirectories)) { NumberOfPublishedProjects++; } @@ -96,7 +97,7 @@ namespace Microsoft.DotNet.Tools.Publish /// Location of published files /// Debug or Release /// Return 0 if successful else return non-zero - private static bool PublishProjectContext(ProjectContext context, string outputPath, string configuration) + private static bool PublishProjectContext(ProjectContext context, string outputPath, string configuration, bool nativeSubdirectories) { Reporter.Output.WriteLine($"Publishing {context.RootProject.Identity.Name.Yellow()} for {context.TargetFramework.DotNetFrameworkName.Yellow()}/{context.RuntimeIdentifier.Yellow()}"); @@ -147,8 +148,8 @@ namespace Microsoft.DotNet.Tools.Publish Reporter.Verbose.WriteLine($"Publishing {export.Library.Identity.ToString().Green().Bold()} ..."); - PublishFiles(export.RuntimeAssemblies, outputPath); - PublishFiles(export.NativeLibraries, outputPath); + PublishFiles(export.RuntimeAssemblies, outputPath, false); + PublishFiles(export.NativeLibraries, outputPath, nativeSubdirectories); } // Publish a host if this is an application @@ -184,12 +185,48 @@ namespace Microsoft.DotNet.Tools.Publish return 0; } - private static void PublishFiles(IEnumerable files, string outputPath) + private static void PublishFiles(IEnumerable files, string outputPath, bool nativeSubdirectories) { foreach (var file in files) { - File.Copy(file.ResolvedPath, Path.Combine(outputPath, Path.GetFileName(file.ResolvedPath)), overwrite: true); + var destinationDirectory = DetermineFileDestinationDirectory(file, outputPath, nativeSubdirectories); + + if (!Directory.Exists(destinationDirectory)) + { + Directory.CreateDirectory(destinationDirectory); + } + + File.Copy(file.ResolvedPath, Path.Combine(destinationDirectory, Path.GetFileName(file.ResolvedPath)), overwrite: true); } } + + private static string DetermineFileDestinationDirectory(LibraryAsset file, string outputPath, bool nativeSubdirectories) + { + var destinationDirectory = outputPath; + + if (nativeSubdirectories) + { + destinationDirectory = Path.Combine(outputPath, GetNativeRelativeSubdirectory(file.RelativePath)); + } + + return destinationDirectory; + } + + private static string GetNativeRelativeSubdirectory(string filepath) + { + string directoryPath = Path.GetDirectoryName(filepath); + + string[] parts = directoryPath.Split(new string[] { "native" }, 2, StringSplitOptions.None); + + if (parts.Length != 2) + { + throw new Exception("Unrecognized Native Directory Format: " + filepath); + } + + string candidate = parts[1]; + candidate = candidate.TrimStart(new char[] { '/', '\\' }); + + return candidate; + } } }