From a71112ce8f895f524740a591be5f8e00b7a88c40 Mon Sep 17 00:00:00 2001 From: Pavel Krymets Date: Wed, 17 Feb 2016 10:08:27 -0800 Subject: [PATCH] Asset refactoring and content files --- Microsoft.DotNet.Cli.sln | 36 ++- .../TestAppWithContentPackage/NuGet.Config | 6 + .../Packages/SharedContentA.1.0.0.nupkg | Bin 0 -> 114163 bytes .../TestAppWithContentPackage/Program.cs | 19 ++ .../TestAppWithContentPackage.xproj | 19 ++ .../TestAppWithContentPackage/project.json | 14 + .../Executable.cs | 67 ++-- .../LibraryExporterExtensions.cs | 5 +- ...icrosoft.DotNet.InternalAbstractions.xproj | 18 ++ .../ProjectJsonWorkspace.cs | 26 +- .../Compilation/LibraryAsset.cs | 26 +- .../Compilation/LibraryAssetExtension.cs | 44 +++ .../Compilation/LibraryExport.cs | 11 +- .../Compilation/LibraryExportBuilder.cs | 173 ++++++++++ .../Compilation/LibraryExporter.cs | 189 ++++++----- .../Preprocessor/PPFileParameters.cs | 22 ++ .../Preprocessor/PPFilePreprocessor.cs | 53 ++++ .../Preprocessor/PPFileTokenizer.cs | 124 ++++++++ .../Graph/BuildAction.cs | 86 +++++ .../Graph/LockFileReader.cs | 31 +- .../Graph/LockFileTargetContentFile.cs | 20 ++ .../Graph/LockFileTargetLibrary.cs | 2 + .../PackageDescription.cs | 2 + .../ProjectExtensions.cs | 32 ++ .../ProjectReader.cs | 2 +- .../commands/dotnet-build/CompileContext.cs | 2 +- .../commands/dotnet-compile/CompilerUtil.cs | 27 +- .../dotnet-compile/ManagedCompiler.cs | 13 +- .../Helpers/ProjectExtensions.cs | 5 +- .../InternalModels/ProjectContextSnapshot.cs | 3 +- .../commands/dotnet-publish/PublishCommand.cs | 5 +- .../LibraryExporterPackageTests.cs | 299 ++++++++++++++++++ .../PreprocessorTests.cs | 53 ++++ test/dotnet-compile.Tests/CompilerTests.cs | 40 +++ 34 files changed, 1301 insertions(+), 173 deletions(-) create mode 100644 TestAssets/TestProjects/TestAppWithContentPackage/NuGet.Config create mode 100644 TestAssets/TestProjects/TestAppWithContentPackage/Packages/SharedContentA.1.0.0.nupkg create mode 100644 TestAssets/TestProjects/TestAppWithContentPackage/Program.cs create mode 100644 TestAssets/TestProjects/TestAppWithContentPackage/TestAppWithContentPackage.xproj create mode 100644 TestAssets/TestProjects/TestAppWithContentPackage/project.json create mode 100644 src/Microsoft.DotNet.InternalAbstractions/Microsoft.DotNet.InternalAbstractions.xproj create mode 100644 src/Microsoft.DotNet.ProjectModel/Compilation/LibraryAssetExtension.cs create mode 100644 src/Microsoft.DotNet.ProjectModel/Compilation/LibraryExportBuilder.cs create mode 100644 src/Microsoft.DotNet.ProjectModel/Compilation/Preprocessor/PPFileParameters.cs create mode 100644 src/Microsoft.DotNet.ProjectModel/Compilation/Preprocessor/PPFilePreprocessor.cs create mode 100644 src/Microsoft.DotNet.ProjectModel/Compilation/Preprocessor/PPFileTokenizer.cs create mode 100644 src/Microsoft.DotNet.ProjectModel/Graph/BuildAction.cs create mode 100644 src/Microsoft.DotNet.ProjectModel/Graph/LockFileTargetContentFile.cs create mode 100644 src/Microsoft.DotNet.ProjectModel/ProjectExtensions.cs create mode 100644 test/Microsoft.DotNet.ProjectModel.Tests/LibraryExporterPackageTests.cs create mode 100644 test/Microsoft.DotNet.ProjectModel.Tests/PreprocessorTests.cs diff --git a/Microsoft.DotNet.Cli.sln b/Microsoft.DotNet.Cli.sln index f7171285b..203948f0c 100644 --- a/Microsoft.DotNet.Cli.sln +++ b/Microsoft.DotNet.Cli.sln @@ -82,6 +82,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Installer", "Installer", "{ EndProject Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.DotNet.Cli.Msi.Tests", "test\Installer\Microsoft.DotNet.Cli.Msi.Tests\Microsoft.DotNet.Cli.Msi.Tests.xproj", "{0B31C336-149D-471A-B7B1-27B0F1E80F83}" EndProject +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.Extensions.DependencyModel.Tests", "..\cli1\test\Microsoft.Extensions.DependencyModel.Tests\Microsoft.Extensions.DependencyModel.Tests.xproj", "{4A4711D8-4312-49FC-87B5-4F183F4C6A51}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -526,22 +528,22 @@ Global {BD4F0750-4E81-4AD2-90B5-E470881792C3}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU {BD4F0750-4E81-4AD2-90B5-E470881792C3}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU {BD4F0750-4E81-4AD2-90B5-E470881792C3}.RelWithDebInfo|x64.Build.0 = Release|Any CPU - {0745410A-6629-47EB-AAB5-08D6288CAD72}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0745410A-6629-47EB-AAB5-08D6288CAD72}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0745410A-6629-47EB-AAB5-08D6288CAD72}.Debug|x64.ActiveCfg = Debug|Any CPU - {0745410A-6629-47EB-AAB5-08D6288CAD72}.Debug|x64.Build.0 = Debug|Any CPU - {0745410A-6629-47EB-AAB5-08D6288CAD72}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU - {0745410A-6629-47EB-AAB5-08D6288CAD72}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU - {0745410A-6629-47EB-AAB5-08D6288CAD72}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU - {0745410A-6629-47EB-AAB5-08D6288CAD72}.MinSizeRel|x64.Build.0 = Debug|Any CPU - {0745410A-6629-47EB-AAB5-08D6288CAD72}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0745410A-6629-47EB-AAB5-08D6288CAD72}.Release|Any CPU.Build.0 = Release|Any CPU - {0745410A-6629-47EB-AAB5-08D6288CAD72}.Release|x64.ActiveCfg = Release|Any CPU - {0745410A-6629-47EB-AAB5-08D6288CAD72}.Release|x64.Build.0 = Release|Any CPU - {0745410A-6629-47EB-AAB5-08D6288CAD72}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU - {0745410A-6629-47EB-AAB5-08D6288CAD72}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU - {0745410A-6629-47EB-AAB5-08D6288CAD72}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU - {0745410A-6629-47EB-AAB5-08D6288CAD72}.RelWithDebInfo|x64.Build.0 = Release|Any CPU + {4A4711D8-4312-49FC-87B5-4F183F4C6A51}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4A4711D8-4312-49FC-87B5-4F183F4C6A51}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4A4711D8-4312-49FC-87B5-4F183F4C6A51}.Debug|x64.ActiveCfg = Debug|Any CPU + {4A4711D8-4312-49FC-87B5-4F183F4C6A51}.Debug|x64.Build.0 = Debug|Any CPU + {4A4711D8-4312-49FC-87B5-4F183F4C6A51}.MinSizeRel|Any CPU.ActiveCfg = Debug|Any CPU + {4A4711D8-4312-49FC-87B5-4F183F4C6A51}.MinSizeRel|Any CPU.Build.0 = Debug|Any CPU + {4A4711D8-4312-49FC-87B5-4F183F4C6A51}.MinSizeRel|x64.ActiveCfg = Debug|Any CPU + {4A4711D8-4312-49FC-87B5-4F183F4C6A51}.MinSizeRel|x64.Build.0 = Debug|Any CPU + {4A4711D8-4312-49FC-87B5-4F183F4C6A51}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4A4711D8-4312-49FC-87B5-4F183F4C6A51}.Release|Any CPU.Build.0 = Release|Any CPU + {4A4711D8-4312-49FC-87B5-4F183F4C6A51}.Release|x64.ActiveCfg = Release|Any CPU + {4A4711D8-4312-49FC-87B5-4F183F4C6A51}.Release|x64.Build.0 = Release|Any CPU + {4A4711D8-4312-49FC-87B5-4F183F4C6A51}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU + {4A4711D8-4312-49FC-87B5-4F183F4C6A51}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU + {4A4711D8-4312-49FC-87B5-4F183F4C6A51}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU + {4A4711D8-4312-49FC-87B5-4F183F4C6A51}.RelWithDebInfo|x64.Build.0 = Release|Any CPU {0B31C336-149D-471A-B7B1-27B0F1E80F83}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {0B31C336-149D-471A-B7B1-27B0F1E80F83}.Debug|Any CPU.Build.0 = Debug|Any CPU {0B31C336-149D-471A-B7B1-27B0F1E80F83}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -591,7 +593,7 @@ Global {947DD232-8D9B-4B78-9C6A-94F807D2DD58} = {713CBFBB-5392-438D-B766-A9A585EF1BB8} {947DD232-8D9B-4B78-9C6A-94F807D22222} = {713CBFBB-5392-438D-B766-A9A585EF1BB8} {BD4F0750-4E81-4AD2-90B5-E470881792C3} = {ED2FE3E2-F7E7-4389-8231-B65123F2076F} - {0745410A-6629-47EB-AAB5-08D6288CAD72} = {17735A9D-BFD9-4585-A7CB-3208CA6EA8A7} + {4A4711D8-4312-49FC-87B5-4F183F4C6A51} = {17735A9D-BFD9-4585-A7CB-3208CA6EA8A7} {0E3300A4-DF54-40BF-87D8-E7658330C288} = {17735A9D-BFD9-4585-A7CB-3208CA6EA8A7} {0B31C336-149D-471A-B7B1-27B0F1E80F83} = {0E3300A4-DF54-40BF-87D8-E7658330C288} EndGlobalSection diff --git a/TestAssets/TestProjects/TestAppWithContentPackage/NuGet.Config b/TestAssets/TestProjects/TestAppWithContentPackage/NuGet.Config new file mode 100644 index 000000000..4a43c6b88 --- /dev/null +++ b/TestAssets/TestProjects/TestAppWithContentPackage/NuGet.Config @@ -0,0 +1,6 @@ + + + + + + diff --git a/TestAssets/TestProjects/TestAppWithContentPackage/Packages/SharedContentA.1.0.0.nupkg b/TestAssets/TestProjects/TestAppWithContentPackage/Packages/SharedContentA.1.0.0.nupkg new file mode 100644 index 0000000000000000000000000000000000000000..22c50bfed60b85f5fa973e1e70d4ca31b7dd1411 GIT binary patch literal 114163 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 Y6j73egTH^90P^JyG1{;KvNZ$zKL*X0Q2+n{ literal 0 HcmV?d00001 diff --git a/TestAssets/TestProjects/TestAppWithContentPackage/Program.cs b/TestAssets/TestProjects/TestAppWithContentPackage/Program.cs new file mode 100644 index 000000000..b71b81142 --- /dev/null +++ b/TestAssets/TestProjects/TestAppWithContentPackage/Program.cs @@ -0,0 +1,19 @@ +using System; +using System.Reflection; + +namespace TestAppWithContentPackage +{ + public class Program + { + public static int Main(string[] args) + { + foreach (var name in Assembly.GetEntryAssembly().GetManifestResourceNames()) + { + Console.WriteLine(name); + } + Console.WriteLine(typeof(Foo).FullName); + Console.WriteLine(typeof(MyNamespace.Util).FullName); + return 0; + } + } +} diff --git a/TestAssets/TestProjects/TestAppWithContentPackage/TestAppWithContentPackage.xproj b/TestAssets/TestProjects/TestAppWithContentPackage/TestAppWithContentPackage.xproj new file mode 100644 index 000000000..718199108 --- /dev/null +++ b/TestAssets/TestProjects/TestAppWithContentPackage/TestAppWithContentPackage.xproj @@ -0,0 +1,19 @@ + + + + 14.0.24720 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + ea239e10-75e8-4305-966e-fec926a5aee6 + TestAppWithContentPackage + ..\..\..\artifacts\obj\$(MSBuildProjectName) + ..\..\..\artifacts\bin\$(MSBuildProjectName)\ + + + + 2.0 + + + \ No newline at end of file diff --git a/TestAssets/TestProjects/TestAppWithContentPackage/project.json b/TestAssets/TestProjects/TestAppWithContentPackage/project.json new file mode 100644 index 000000000..d9dd13dfc --- /dev/null +++ b/TestAssets/TestProjects/TestAppWithContentPackage/project.json @@ -0,0 +1,14 @@ +{ + "version": "1.0.0-*", + "compilationOptions": { + "emitEntryPoint": true + }, + + "dependencies": { + "NETStandard.Library": "1.0.0-rc2-23811", + "SharedContentA": "1.0.0-*" + }, + "frameworks": { + "dnxcore50": { } + } +} \ No newline at end of file diff --git a/src/Microsoft.DotNet.Compiler.Common/Executable.cs b/src/Microsoft.DotNet.Compiler.Common/Executable.cs index 7cbc53ec4..31f92825f 100644 --- a/src/Microsoft.DotNet.Compiler.Common/Executable.cs +++ b/src/Microsoft.DotNet.Compiler.Common/Executable.cs @@ -20,14 +20,20 @@ namespace Microsoft.Dotnet.Cli.Compiler.Common { private readonly ProjectContext _context; + private readonly LibraryExporter _exporter; + private readonly OutputPaths _outputPaths; - private readonly LibraryExporter _exporter; + private readonly string _runtimeOutputPath; + + private readonly string _intermediateOutputPath; public Executable(ProjectContext context, OutputPaths outputPaths, LibraryExporter exporter) { _context = context; _outputPaths = outputPaths; + _runtimeOutputPath = outputPaths.RuntimeOutputPath; + _intermediateOutputPath = outputPaths.IntermediateOutputDirectoryPath; _exporter = exporter; } @@ -38,68 +44,75 @@ namespace Microsoft.Dotnet.Cli.Compiler.Common throw new InvalidOperationException($"Can not make output runnable for framework {_context.TargetFramework}, because it doesn't have runtime target"); } - var outputPath = _outputPaths.RuntimeOutputPath; - - CopyContentFiles(outputPath); - - ExportRuntimeAssets(outputPath); + CopyContentFiles(); + ExportRuntimeAssets(); } - private void ExportRuntimeAssets(string outputPath) + private void ExportRuntimeAssets() { if (_context.TargetFramework.IsDesktop()) { - MakeCompilationOutputRunnableForFullFramework(outputPath); + MakeCompilationOutputRunnableForFullFramework(); } else { - MakeCompilationOutputRunnableForCoreCLR(outputPath); + MakeCompilationOutputRunnableForCoreCLR(); } } - private void MakeCompilationOutputRunnableForFullFramework( - string outputPath) + private void MakeCompilationOutputRunnableForFullFramework() { - CopyAllDependencies(outputPath, _exporter.GetDependencies()); + var dependencies = _exporter.GetDependencies(); + CopyAssemblies(dependencies); + CopyAssets(dependencies); GenerateBindingRedirects(_exporter); } - private void MakeCompilationOutputRunnableForCoreCLR(string outputPath) + private void MakeCompilationOutputRunnableForCoreCLR() { - WriteDepsFileAndCopyProjectDependencies(_exporter, _context.ProjectFile.Name, outputPath); + WriteDepsFileAndCopyProjectDependencies(_exporter); // TODO: Pick a host based on the RID - CoreHost.CopyTo(outputPath, _context.ProjectFile.Name + Constants.ExeSuffix); + CoreHost.CopyTo(_runtimeOutputPath, _context.ProjectFile.Name + Constants.ExeSuffix); } - private void CopyContentFiles(string outputPath) + private void CopyContentFiles() { var contentFiles = new ContentFiles(_context); - contentFiles.StructuredCopyTo(outputPath); + contentFiles.StructuredCopyTo(_runtimeOutputPath); } - private static void CopyAllDependencies(string outputPath, IEnumerable libraryExports) + private void CopyAssemblies(IEnumerable libraryExports) { foreach (var libraryExport in libraryExports) { - libraryExport.RuntimeAssemblies.CopyTo(outputPath); - libraryExport.NativeLibraries.CopyTo(outputPath); - libraryExport.RuntimeAssets.StructuredCopyTo(outputPath); + libraryExport.RuntimeAssemblies.CopyTo(_runtimeOutputPath); + libraryExport.NativeLibraries.CopyTo(_runtimeOutputPath); } } - private static void WriteDepsFileAndCopyProjectDependencies( - LibraryExporter exporter, - string projectFileName, - string outputPath) + private void CopyAssets(IEnumerable libraryExports) + { + foreach (var libraryExport in libraryExports) + { + libraryExport.RuntimeAssets.StructuredCopyTo( + _runtimeOutputPath, + _intermediateOutputPath); + } + } + + private void WriteDepsFileAndCopyProjectDependencies(LibraryExporter exporter) { exporter .GetDependencies(LibraryType.Package) - .WriteDepsTo(Path.Combine(outputPath, projectFileName + FileNameSuffixes.Deps)); + .WriteDepsTo(Path.Combine(_runtimeOutputPath, _context.ProjectFile.Name + FileNameSuffixes.Deps)); var projectExports = exporter.GetDependencies(LibraryType.Project); + CopyAssemblies(projectExports); + CopyAssets(projectExports); - CopyAllDependencies(outputPath, projectExports); + var packageExports = exporter.GetDependencies(LibraryType.Package); + CopyAssets(packageExports); } public void GenerateBindingRedirects(LibraryExporter exporter) diff --git a/src/Microsoft.DotNet.Compiler.Common/LibraryExporterExtensions.cs b/src/Microsoft.DotNet.Compiler.Common/LibraryExporterExtensions.cs index bf7e7403f..c4e088401 100644 --- a/src/Microsoft.DotNet.Compiler.Common/LibraryExporterExtensions.cs +++ b/src/Microsoft.DotNet.Compiler.Common/LibraryExporterExtensions.cs @@ -53,7 +53,7 @@ namespace Microsoft.DotNet.Cli.Compiler.Common } } - public static void StructuredCopyTo(this IEnumerable assets, string destinationPath) + public static void StructuredCopyTo(this IEnumerable assets, string destinationPath, string tempLocation) { if (!Directory.Exists(destinationPath)) { @@ -63,8 +63,9 @@ namespace Microsoft.DotNet.Cli.Compiler.Common foreach (var asset in assets) { var targetName = ResolveTargetName(destinationPath, asset); + var transformedFile = asset.GetTransformedFile(tempLocation); - File.Copy(asset.ResolvedPath, targetName, overwrite: true); + File.Copy(transformedFile, targetName, overwrite: true); } } diff --git a/src/Microsoft.DotNet.InternalAbstractions/Microsoft.DotNet.InternalAbstractions.xproj b/src/Microsoft.DotNet.InternalAbstractions/Microsoft.DotNet.InternalAbstractions.xproj new file mode 100644 index 000000000..b898305b0 --- /dev/null +++ b/src/Microsoft.DotNet.InternalAbstractions/Microsoft.DotNet.InternalAbstractions.xproj @@ -0,0 +1,18 @@ + + + + 14.0.24720 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + bd4f0750-4e81-4ad2-90b5-e470881792c3 + Microsoft.DotNet.InternalAbstractions + ..\..\artifacts\obj\$(MSBuildProjectName) + ..\..\artifacts\bin\$(MSBuildProjectName)\ + + + 2.0 + + + \ No newline at end of file diff --git a/src/Microsoft.DotNet.ProjectModel.Workspaces/ProjectJsonWorkspace.cs b/src/Microsoft.DotNet.ProjectModel.Workspaces/ProjectJsonWorkspace.cs index 8560e426e..9dbdedf8a 100644 --- a/src/Microsoft.DotNet.ProjectModel.Workspaces/ProjectJsonWorkspace.cs +++ b/src/Microsoft.DotNet.ProjectModel.Workspaces/ProjectJsonWorkspace.cs @@ -13,6 +13,7 @@ using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.CodeAnalysis.Text; using Microsoft.DotNet.Cli.Compiler.Common; +using Microsoft.DotNet.ProjectModel.Compilation; using NuGet.Frameworks; namespace Microsoft.DotNet.ProjectModel.Workspaces @@ -78,7 +79,10 @@ namespace Microsoft.DotNet.ProjectModel.Workspaces foreach (var file in project.ProjectFile.Files.SourceFiles) { - AddSourceFile(projectInfo, file); + using (var stream = File.OpenRead(file)) + { + AddSourceFile(projectInfo, file, stream); + } } var exporter = project.CreateExporter(configuration); @@ -104,24 +108,24 @@ namespace Microsoft.DotNet.ProjectModel.Workspaces foreach (var file in dependency.SourceReferences) { - AddSourceFile(projectInfo, file); + using (var stream = file.GetTransformedStream()) + { + AddSourceFile(projectInfo, file.ResolvedPath, stream); + } } } return projectInfo.Id; } - private void AddSourceFile(ProjectInfo projectInfo, string file) + private void AddSourceFile(ProjectInfo projectInfo, string file, Stream stream) { - using (var stream = File.OpenRead(file)) - { - var sourceText = SourceText.From(stream, encoding: Encoding.UTF8); - var id = DocumentId.CreateNewId(projectInfo.Id); - var version = VersionStamp.Create(); + var sourceText = SourceText.From(stream, encoding: Encoding.UTF8); + var id = DocumentId.CreateNewId(projectInfo.Id); + var version = VersionStamp.Create(); - var loader = TextLoader.From(TextAndVersion.Create(sourceText, version)); - OnDocumentAdded(DocumentInfo.Create(id, file, filePath: file, loader: loader)); - } + var loader = TextLoader.From(TextAndVersion.Create(sourceText, version)); + OnDocumentAdded(DocumentInfo.Create(id, file, filePath: file, loader: loader)); } private MetadataReference GetMetadataReference(string path) diff --git a/src/Microsoft.DotNet.ProjectModel/Compilation/LibraryAsset.cs b/src/Microsoft.DotNet.ProjectModel/Compilation/LibraryAsset.cs index d7740a94d..6186f26e5 100644 --- a/src/Microsoft.DotNet.ProjectModel/Compilation/LibraryAsset.cs +++ b/src/Microsoft.DotNet.ProjectModel/Compilation/LibraryAsset.cs @@ -3,7 +3,9 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; +using Microsoft.DotNet.ProjectModel.Utilities; using Microsoft.Extensions.Internal; namespace Microsoft.DotNet.ProjectModel.Compilation @@ -13,12 +15,14 @@ namespace Microsoft.DotNet.ProjectModel.Compilation public string Name { get; } public string RelativePath { get; } public string ResolvedPath { get; } + public Action Transform { get; set; } - public LibraryAsset(string name, string relativePath, string resolvedPath) + public LibraryAsset(string name, string relativePath, string resolvedPath, Action transform = null) { Name = name; RelativePath = relativePath; ResolvedPath = resolvedPath; + Transform = transform; } public bool Equals(LibraryAsset other) @@ -42,5 +46,25 @@ namespace Microsoft.DotNet.ProjectModel.Compilation combiner.Add(ResolvedPath); return combiner.CombinedHash; } + + public static LibraryAsset CreateFromRelativePath(string basePath, string relativePath, Action transform = null) + { + return new LibraryAsset( + Path.GetFileNameWithoutExtension(relativePath), + relativePath, + Path.Combine(basePath, relativePath), + transform); + } + + public static LibraryAsset CreateFromAbsolutePath(string basePath, string absolutePath, Action transform = null) + { + var relativePath = absolutePath.Replace(PathUtility.EnsureTrailingSlash(basePath), string.Empty); + + return new LibraryAsset( + Path.GetFileNameWithoutExtension(relativePath), + relativePath, + absolutePath, + transform); + } } } diff --git a/src/Microsoft.DotNet.ProjectModel/Compilation/LibraryAssetExtension.cs b/src/Microsoft.DotNet.ProjectModel/Compilation/LibraryAssetExtension.cs new file mode 100644 index 000000000..93b466639 --- /dev/null +++ b/src/Microsoft.DotNet.ProjectModel/Compilation/LibraryAssetExtension.cs @@ -0,0 +1,44 @@ +// 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; + +namespace Microsoft.DotNet.ProjectModel.Compilation +{ + public static class LibraryAssetExtensions + { + public static string GetTransformedFile(this LibraryAsset asset, string tempLocation, string tempName = null) + { + if (asset.Transform == null) + { + return asset.ResolvedPath; + } + + tempName = tempName ?? Path.GetFileName(asset.RelativePath); + using (var input = File.OpenRead(asset.ResolvedPath)) + { + var transformedName = Path.Combine(tempLocation, tempName); + using (var output = File.OpenWrite(transformedName)) + { + asset.Transform(input, output); + } + return transformedName; + } + } + + public static Stream GetTransformedStream(this LibraryAsset asset) + { + if (asset.Transform == null) + { + return File.OpenRead(asset.ResolvedPath); + } + + using (var input = File.OpenRead(asset.ResolvedPath)) + { + var output = new MemoryStream(); + asset.Transform(input, output); + return output; + } + } + } +} diff --git a/src/Microsoft.DotNet.ProjectModel/Compilation/LibraryExport.cs b/src/Microsoft.DotNet.ProjectModel/Compilation/LibraryExport.cs index 1db48a791..0380fc56a 100644 --- a/src/Microsoft.DotNet.ProjectModel/Compilation/LibraryExport.cs +++ b/src/Microsoft.DotNet.ProjectModel/Compilation/LibraryExport.cs @@ -34,10 +34,15 @@ namespace Microsoft.DotNet.ProjectModel.Compilation /// public IEnumerable CompilationAssemblies { get; } + /// + /// Get a list of embedded resource files provided by this export. + /// + public IEnumerable EmbeddedResources { get; } + /// /// Gets a list of fully-qualified paths to source code file references /// - public IEnumerable SourceReferences { get; } + public IEnumerable SourceReferences { get; } /// /// Get a list of analyzers provided by this export. @@ -46,10 +51,11 @@ namespace Microsoft.DotNet.ProjectModel.Compilation public LibraryExport(LibraryDescription library, IEnumerable compileAssemblies, - IEnumerable sourceReferences, + IEnumerable sourceReferences, IEnumerable runtimeAssemblies, IEnumerable runtimeAssets, IEnumerable nativeLibraries, + IEnumerable embeddedResources, IEnumerable analyzers) { Library = library; @@ -58,6 +64,7 @@ namespace Microsoft.DotNet.ProjectModel.Compilation RuntimeAssemblies = runtimeAssemblies; RuntimeAssets = runtimeAssets; NativeLibraries = nativeLibraries; + EmbeddedResources = embeddedResources; AnalyzerReferences = analyzers; } diff --git a/src/Microsoft.DotNet.ProjectModel/Compilation/LibraryExportBuilder.cs b/src/Microsoft.DotNet.ProjectModel/Compilation/LibraryExportBuilder.cs new file mode 100644 index 000000000..42d98c897 --- /dev/null +++ b/src/Microsoft.DotNet.ProjectModel/Compilation/LibraryExportBuilder.cs @@ -0,0 +1,173 @@ +// 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; +using System.Collections.Generic; + +namespace Microsoft.DotNet.ProjectModel.Compilation +{ + public class LibraryExportBuilder + { + private IList _runtimeAssemblies; + + private IList _runtimeAssets; + + private IList _compilationAssemblies; + + private IList _compilationAssets; + + private IList _debugAssets; + + private IList _sourceReferences; + + private IList _nativeLibraries; + + private IList _embeddedResources; + + private IList _analyzerReferences; + + public LibraryDescription Library { get; set; } + + public IEnumerable RuntimeAssemblies => _runtimeAssemblies; + + public IEnumerable RuntimeAssets => _runtimeAssets; + + public IEnumerable CompilationAssemblies => _compilationAssemblies; + + public IEnumerable CompilationAssets => _compilationAssets; + + public IEnumerable SourceReferences => _sourceReferences; + + public IEnumerable NativeLibraries => _nativeLibraries; + + public IEnumerable EmbeddedResources => _embeddedResources; + + public IEnumerable AnalyzerReferences => _analyzerReferences; + + public static LibraryExportBuilder Create(LibraryDescription library = null) + { + return new LibraryExportBuilder().WithLibrary(library); + } + + public LibraryExport Build() + { + if (Library == null) + { + throw new InvalidOperationException("Cannot build LibraryExport withoud Library set"); + } + return new LibraryExport( + Library, + CompilationAssemblies ?? EmptyArray.Value, + SourceReferences ?? EmptyArray.Value, + RuntimeAssemblies ?? EmptyArray.Value, + RuntimeAssets ?? EmptyArray.Value, + NativeLibraries ?? EmptyArray.Value, + EmbeddedResources ?? EmptyArray.Value, + AnalyzerReferences ?? EmptyArray.Value); + } + + public LibraryExportBuilder WithLibrary(LibraryDescription libraryDescription) + { + Library = libraryDescription; + return this; + } + + public LibraryExportBuilder WithRuntimeAssemblies(IEnumerable assets) + { + Replace(ref _runtimeAssemblies, assets); + return this; + } + + public LibraryExportBuilder WithRuntimeAssets(IEnumerable assets) + { + Replace(ref _runtimeAssets, assets); + return this; + } + + public LibraryExportBuilder WithCompilationAssemblies(IEnumerable assets) + { + Replace(ref _compilationAssemblies, assets); + return this; + } + + public LibraryExportBuilder WithSourceReferences(IEnumerable assets) + { + Replace(ref _sourceReferences, assets); + return this; + } + + public LibraryExportBuilder WithNativeLibraries(IEnumerable assets) + { + Replace(ref _nativeLibraries, assets); + return this; + } + + public LibraryExportBuilder WithEmbedddedResources(IEnumerable assets) + { + Replace(ref _embeddedResources, assets); + return this; + } + + public LibraryExportBuilder WithAnalyzerReference(IEnumerable assets) + { + Replace(ref _analyzerReferences, assets); + return this; + } + + public LibraryExportBuilder AddRuntimeAssembly(LibraryAsset asset) + { + Add(ref _runtimeAssemblies, asset); + return this; + } + + public LibraryExportBuilder AddRuntimeAsset(LibraryAsset asset) + { + Add(ref _runtimeAssets, asset); + return this; + } + + public LibraryExportBuilder AddCompilationAssembly(LibraryAsset asset) + { + Add(ref _compilationAssemblies, asset); + return this; + } + + public LibraryExportBuilder AddSourceReference(LibraryAsset asset) + { + Add(ref _sourceReferences, asset); + return this; + } + + public LibraryExportBuilder AddNativeLibrary(LibraryAsset asset) + { + Add(ref _compilationAssets, asset); + return this; + } + + public LibraryExportBuilder AddEmbedddedResource(LibraryAsset asset) + { + Add(ref _embeddedResources, asset); + return this; + } + + public LibraryExportBuilder AddAnalyzerReference(AnalyzerReference asset) + { + Add(ref _analyzerReferences, asset); + return this; + } + + private void Replace(ref IList list, IEnumerable enumerable) + { + list = new List(enumerable); + } + + private void Add(ref IList list, T item) + { + if (list == null) + { + list = new List(); + } + list.Add(item); + } + } +} \ No newline at end of file diff --git a/src/Microsoft.DotNet.ProjectModel/Compilation/LibraryExporter.cs b/src/Microsoft.DotNet.ProjectModel/Compilation/LibraryExporter.cs index 706d16ab0..ea5989e83 100644 --- a/src/Microsoft.DotNet.ProjectModel/Compilation/LibraryExporter.cs +++ b/src/Microsoft.DotNet.ProjectModel/Compilation/LibraryExporter.cs @@ -6,9 +6,12 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; +using Microsoft.DotNet.ProjectModel.Compilation.Preprocessor; +using Microsoft.DotNet.ProjectModel.Files; using Microsoft.DotNet.ProjectModel.Graph; using Microsoft.DotNet.ProjectModel.Resolution; using Microsoft.DotNet.ProjectModel.Utilities; +using Microsoft.DotNet.Tools.Compiler; using NuGet.Frameworks; namespace Microsoft.DotNet.ProjectModel.Compilation @@ -89,7 +92,7 @@ namespace Microsoft.DotNet.ProjectModel.Compilation } var compilationAssemblies = new List(); - var sourceReferences = new List(); + var sourceReferences = new List(); var analyzerReferences = new List(); var libraryExport = GetExport(library); @@ -111,13 +114,15 @@ namespace Microsoft.DotNet.ProjectModel.Compilation analyzerReferences.AddRange(libraryExport.AnalyzerReferences); } - yield return new LibraryExport(library, - compilationAssemblies, - sourceReferences, - libraryExport.RuntimeAssemblies, - libraryExport.RuntimeAssets, - libraryExport.NativeLibraries, - analyzerReferences); + yield return LibraryExportBuilder.Create(library) + .WithCompilationAssemblies(compilationAssemblies) + .WithSourceReferences(sourceReferences) + .WithRuntimeAssemblies(libraryExport.RuntimeAssemblies) + .WithRuntimeAssets(libraryExport.RuntimeAssets) + .WithNativeLibraries(libraryExport.NativeLibraries) + .WithEmbedddedResources(libraryExport.EmbeddedResources) + .WithAnalyzerReference(analyzerReferences) + .Build(); } } @@ -131,13 +136,7 @@ namespace Microsoft.DotNet.ProjectModel.Compilation if (!library.Resolved) { // For a unresolved project reference returns a export with empty asset. - return new LibraryExport(library: library, - compileAssemblies: Enumerable.Empty(), - sourceReferences: Enumerable.Empty(), - nativeLibraries: Enumerable.Empty(), - runtimeAssets: Enumerable.Empty(), - runtimeAssemblies: EmptyArray.Value, - analyzers: EmptyArray.Value); + return LibraryExportBuilder.Create(library).Build(); } if (Equals(LibraryType.Package, library.Identity.Type)) @@ -156,32 +155,57 @@ namespace Microsoft.DotNet.ProjectModel.Compilation private LibraryExport ExportPackage(PackageDescription package) { - var nativeLibraries = new List(); - PopulateAssets(package, package.NativeLibraries, nativeLibraries); + var builder = LibraryExportBuilder.Create(package); + builder.WithNativeLibraries(PopulateAssets(package, package.NativeLibraries)); + builder.WithRuntimeAssemblies(PopulateAssets(package, package.RuntimeAssemblies)); + builder.WithCompilationAssemblies(PopulateAssets(package, package.CompileTimeAssemblies)); + builder.WithSourceReferences(GetSharedSources(package)); + builder.WithAnalyzerReference(GetAnalyzerReferences(package)); - var runtimeAssemblies = new List(); - PopulateAssets(package, package.RuntimeAssemblies, runtimeAssemblies); - - var compileAssemblies = new List(); - PopulateAssets(package, package.CompileTimeAssemblies, compileAssemblies); - - var sourceReferences = new List(); - foreach (var sharedSource in GetSharedSources(package)) + if (package.ContentFiles.Any()) { - sourceReferences.Add(sharedSource); + var parameters = PPFileParameters.CreateForProject(_rootProject.Project); + Action transform = (input, output) => PPFilePreprocessor.Preprocess(input, output, parameters); + + var sourceCodeLanguage = _rootProject.Project.GetSourceCodeLanguage(); + var languageGroups = package.ContentFiles.GroupBy(file => file.CodeLanguage); + var selectedGroup = languageGroups.FirstOrDefault(g => g.Key == sourceCodeLanguage) ?? + languageGroups.FirstOrDefault(g => g.Key == null); + if (selectedGroup != null) + { + foreach (var contentFile in selectedGroup) + { + if (contentFile.CodeLanguage != null && + string.Compare(contentFile.CodeLanguage, sourceCodeLanguage, StringComparison.OrdinalIgnoreCase) != 0) + { + continue; + } + + var fileTransform = contentFile.PPOutputPath != null ? transform : null; + + var fullPath = Path.Combine(package.Path, contentFile.Path); + if (contentFile.BuildAction == BuildAction.Compile) + { + builder.AddSourceReference(LibraryAsset.CreateFromRelativePath(package.Path, contentFile.Path, fileTransform)); + } + else if (contentFile.BuildAction == BuildAction.EmbeddedResource) + { + builder.AddEmbedddedResource(LibraryAsset.CreateFromRelativePath(package.Path, contentFile.Path, fileTransform)); + } + if (contentFile.CopyToOutput) + { + builder.AddRuntimeAsset(new LibraryAsset(contentFile.Path, contentFile.OutputPath, fullPath, fileTransform)); + } + } + } } - var analyzers = GetAnalyzerReferences(package); - - return new LibraryExport(package, compileAssemblies, - sourceReferences, runtimeAssemblies, EmptyArray.Value, nativeLibraries, analyzers); + return builder.Build(); } private LibraryExport ExportProject(ProjectDescription project) { - var compileAssemblies = new List(); - var runtimeAssets = new List(); - var sourceReferences = new List(); + var builder = LibraryExportBuilder.Create(project); if (!string.IsNullOrEmpty(project.TargetFrameworkInfo?.AssemblyPath)) { @@ -194,50 +218,61 @@ namespace Microsoft.DotNet.ProjectModel.Compilation null, Path.GetFullPath(Path.Combine(project.Project.ProjectDirectory, assemblyPath))); - compileAssemblies.Add(compileAsset); - runtimeAssets.Add(new LibraryAsset(Path.GetFileName(pdbPath), Path.GetFileName(pdbPath), pdbPath)); + builder.AddCompilationAssembly(compileAsset); + builder.AddRuntimeAsset(new LibraryAsset(Path.GetFileName(pdbPath), Path.GetFileName(pdbPath), pdbPath)); } else if (project.Project.Files.SourceFiles.Any()) { var outputPaths = project.GetOutputPaths(_buildBasePath, _solutionRootPath, _configuration, _runtime); - CompilationOutputFiles files; - if (project == _rootProject && - !string.IsNullOrWhiteSpace(_runtime) && - project.Project.HasRuntimeOutput(_configuration)) + var compilationAssembly = outputPaths.CompilationFiles.Assembly; + var compilationAssemblyAsset = LibraryAsset.CreateFromAbsolutePath( + outputPaths.CompilationFiles.BasePath, + compilationAssembly); + + builder.AddCompilationAssembly(compilationAssemblyAsset); + + if (ExportsRuntime(project)) { - files = outputPaths.RuntimeFiles; + var runtimeAssemblyAsset = LibraryAsset.CreateFromAbsolutePath( + outputPaths.RuntimeFiles.BasePath, + outputPaths.RuntimeFiles.Assembly); + + builder.AddRuntimeAssembly(runtimeAssemblyAsset); + builder.WithRuntimeAssets(CollectAssets(outputPaths.RuntimeFiles)); } else { - files = outputPaths.CompilationFiles; - } - - var assemblyPath = files.Assembly; - compileAssemblies.Add(new LibraryAsset(project.Identity.Name, null, assemblyPath)); - - foreach (var path in files.All()) - { - if (string.Equals(assemblyPath, path)) - { - continue; - } - - runtimeAssets.Add(new LibraryAsset(Path.GetFileName(path), path.Replace(files.BasePath, string.Empty), path)); + builder.AddRuntimeAssembly(compilationAssemblyAsset); + builder.WithRuntimeAssets(CollectAssets(outputPaths.CompilationFiles)); } } - // Add shared sources - foreach (var sharedFile in project.Project.Files.SharedFiles) + builder.WithSourceReferences(project.Project.Files.SharedFiles.Select(f => + LibraryAsset.CreateFromAbsolutePath(project.Path, f) + )); + + return builder.Build(); + } + + private IEnumerable CollectAssets(CompilationOutputFiles files) + { + var assemblyPath = files.Assembly; + foreach (var path in files.All()) { - sourceReferences.Add(sharedFile); + if (string.Equals(assemblyPath, path)) + { + continue; + } + yield return LibraryAsset.CreateFromAbsolutePath(files.BasePath, path); } + } - // No support for ref or native in projects, so runtimeAssemblies is - // just the same as compileAssemblies and nativeLibraries are empty - // Also no support for analyzer projects - return new LibraryExport(project, compileAssemblies, sourceReferences, - compileAssemblies, runtimeAssets, EmptyArray.Value, EmptyArray.Value); + private bool ExportsRuntime(ProjectDescription project) + { + return project == _rootProject && + !string.IsNullOrWhiteSpace(_runtime) && + project.Project.HasRuntimeOutput(_configuration); } private static string ResolvePath(Project project, string configuration, string path) @@ -258,25 +293,24 @@ namespace Microsoft.DotNet.ProjectModel.Compilation { // We assume the path is to an assembly. Framework libraries only export compile-time stuff // since they assume the runtime library is present already - return new LibraryExport( - library, - string.IsNullOrEmpty(library.Path) ? - EmptyArray.Value : - new[] { new LibraryAsset(library.Identity.Name, library.Path, library.Path) }, - EmptyArray.Value, - EmptyArray.Value, - EmptyArray.Value, - EmptyArray.Value, - EmptyArray.Value); + var builder = LibraryExportBuilder.Create(library); + if (!string.IsNullOrEmpty(library.Path)) + { + builder.WithCompilationAssemblies(new [] + { + new LibraryAsset(library.Identity.Name, null, library.Path) + }); + } + return builder.Build(); } - private IEnumerable GetSharedSources(PackageDescription package) + private IEnumerable GetSharedSources(PackageDescription package) { return package .Library .Files .Where(path => path.StartsWith("shared" + Path.DirectorySeparatorChar)) - .Select(path => Path.Combine(package.Path, path)); + .Select(path => LibraryAsset.CreateFromRelativePath(package.Path, path)); } private IEnumerable GetAnalyzerReferences(PackageDescription package) @@ -348,14 +382,11 @@ namespace Microsoft.DotNet.ProjectModel.Compilation } - private void PopulateAssets(PackageDescription package, IEnumerable section, IList assets) + private IEnumerable PopulateAssets(PackageDescription package, IEnumerable section) { foreach (var assemblyPath in section) { - assets.Add(new LibraryAsset( - Path.GetFileNameWithoutExtension(assemblyPath), - assemblyPath, - Path.Combine(package.Path, assemblyPath))); + yield return LibraryAsset.CreateFromRelativePath(package.Path, assemblyPath.Path); } } diff --git a/src/Microsoft.DotNet.ProjectModel/Compilation/Preprocessor/PPFileParameters.cs b/src/Microsoft.DotNet.ProjectModel/Compilation/Preprocessor/PPFileParameters.cs new file mode 100644 index 000000000..eca04ad66 --- /dev/null +++ b/src/Microsoft.DotNet.ProjectModel/Compilation/Preprocessor/PPFileParameters.cs @@ -0,0 +1,22 @@ +// 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; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Microsoft.DotNet.ProjectModel.Compilation.Preprocessor +{ + public class PPFileParameters + { + public static IDictionary CreateForProject(Project project) + { + return new Dictionary() + { + {"rootnamespace", project.Name }, + {"assemblyname", project.Name } + }; + } + } +} diff --git a/src/Microsoft.DotNet.ProjectModel/Compilation/Preprocessor/PPFilePreprocessor.cs b/src/Microsoft.DotNet.ProjectModel/Compilation/Preprocessor/PPFilePreprocessor.cs new file mode 100644 index 000000000..c2d597c97 --- /dev/null +++ b/src/Microsoft.DotNet.ProjectModel/Compilation/Preprocessor/PPFilePreprocessor.cs @@ -0,0 +1,53 @@ +// 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; +using System.Collections.Generic; +using System.IO; + +namespace Microsoft.DotNet.Tools.Compiler +{ + public class PPFilePreprocessor + { + public static void Preprocess(Stream input, Stream output, IDictionary parameters) + { + string text; + using (var streamReader = new StreamReader(input)) + { + text = streamReader.ReadToEnd(); + } + var tokenizer = new PPFileTokenizer(text); + using (var streamWriter = new StreamWriter(output)) + { + while (true) + { + var token = tokenizer.Read(); + if (token == null) + { + break; + } + + if (token.Category == PPFileTokenizer.TokenCategory.Variable) + { + var replaced = ReplaceToken(token.Value, parameters); + streamWriter.Write(replaced); + } + else + { + streamWriter.Write(token.Value); + } + } + } + } + + private static string ReplaceToken(string name, IDictionary parameters) + { + string value; + if (!parameters.TryGetValue(name, out value)) + { + throw new InvalidOperationException($"The replacement token '{name}' has no value."); + } + return value; + } + } +} diff --git a/src/Microsoft.DotNet.ProjectModel/Compilation/Preprocessor/PPFileTokenizer.cs b/src/Microsoft.DotNet.ProjectModel/Compilation/Preprocessor/PPFileTokenizer.cs new file mode 100644 index 000000000..8567aeb48 --- /dev/null +++ b/src/Microsoft.DotNet.ProjectModel/Compilation/Preprocessor/PPFileTokenizer.cs @@ -0,0 +1,124 @@ +// 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.Globalization; +using System.Text; + +namespace Microsoft.DotNet.Tools.Compiler +{ + public class PPFileTokenizer + { + private readonly string _text; + private int _index; + + public PPFileTokenizer(string text) + { + _text = text; + _index = 0; + } + + /// + /// Gets the next token. + /// + /// The parsed token. Or null if no more tokens are available. + public Token Read() + { + if (_index >= _text.Length) + { + return null; + } + + if (_text[_index] == '$') + { + _index++; + return ParseTokenAfterDollarSign(); + } + return ParseText(); + } + + private static bool IsWordChar(char ch) + { + // See http://msdn.microsoft.com/en-us/library/20bw873z.aspx#WordCharacter + var c = CharUnicodeInfo.GetUnicodeCategory(ch); + return c == UnicodeCategory.LowercaseLetter || + c == UnicodeCategory.UppercaseLetter || + c == UnicodeCategory.TitlecaseLetter || + c == UnicodeCategory.OtherLetter || + c == UnicodeCategory.ModifierLetter || + c == UnicodeCategory.DecimalDigitNumber || + c == UnicodeCategory.ConnectorPunctuation; + } + + // Parses and returns the next token after a $ is just read. + // _index is one char after the $. + private Token ParseTokenAfterDollarSign() + { + var sb = new StringBuilder(); + while (_index < _text.Length) + { + var ch = _text[_index]; + if (ch == '$') + { + ++_index; + if (sb.Length == 0) + { + // escape sequence "$$" is encountered + return new Token(TokenCategory.Text, "$"); + } + // matching $ is read. So the token is a variable. + return new Token(TokenCategory.Variable, sb.ToString()); + } + if (IsWordChar(ch)) + { + sb.Append(ch); + ++_index; + } + else + { + // non word char encountered. So the current token + // is not a variable after all. + sb.Insert(0, '$'); + sb.Append(ch); + ++_index; + return new Token(TokenCategory.Text, sb.ToString()); + } + } + + // no matching $ is found and the end of text is reached. + // So the current token is a text. + sb.Insert(0, '$'); + return new Token(TokenCategory.Text, sb.ToString()); + } + + private Token ParseText() + { + var sb = new StringBuilder(); + while (_index < _text.Length + && _text[_index] != '$') + { + sb.Append(_text[_index]); + _index++; + } + + return new Token(TokenCategory.Text, sb.ToString()); + } + + public class Token + { + public string Value { get; private set; } + public TokenCategory Category { get; private set; } + + public Token(TokenCategory category, string value) + { + Category = category; + Value = value; + } + } + + public enum TokenCategory + { + Text, + Variable + } + } +} diff --git a/src/Microsoft.DotNet.ProjectModel/Graph/BuildAction.cs b/src/Microsoft.DotNet.ProjectModel/Graph/BuildAction.cs new file mode 100644 index 000000000..8d59abbb0 --- /dev/null +++ b/src/Microsoft.DotNet.ProjectModel/Graph/BuildAction.cs @@ -0,0 +1,86 @@ +// 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; +using System.Collections.Generic; + +namespace Microsoft.DotNet.ProjectModel.Graph +{ + public struct BuildAction : IEquatable + { + public static readonly BuildAction Compile = new BuildAction(nameof(Compile)); + public static readonly BuildAction EmbeddedResource = new BuildAction(nameof(EmbeddedResource)); + public static readonly BuildAction Resource = new BuildAction(nameof(Resource)); + + // Default value + public static readonly BuildAction None = new BuildAction(nameof(None)); + + public string Value { get; } + + private BuildAction(string value) + { + Value = value; + } + + public static bool TryParse(string value, out BuildAction type) + { + // We only support values we know about + if (string.Equals(Compile.Value, value, StringComparison.OrdinalIgnoreCase)) + { + type = Compile; + return true; + } + else if (string.Equals(EmbeddedResource.Value, value, StringComparison.OrdinalIgnoreCase)) + { + type = EmbeddedResource; + return true; + } + else if (string.Equals(Resource.Value, value, StringComparison.OrdinalIgnoreCase)) + { + type = Resource; + return true; + } + else if (string.Equals(None.Value, value, StringComparison.OrdinalIgnoreCase)) + { + type = None; + return true; + } + type = None; + return false; + } + + public override string ToString() + { + return $"BuildAction.{Value}"; + } + + public bool Equals(BuildAction other) + { + return string.Equals(other.Value, Value, StringComparison.OrdinalIgnoreCase); + } + + public override bool Equals(object obj) + { + return obj is BuildAction && Equals((BuildAction)obj); + } + + public static bool operator ==(BuildAction left, BuildAction right) + { + return Equals(left, right); + } + + public static bool operator !=(BuildAction left, BuildAction right) + { + return !Equals(left, right); + } + + public override int GetHashCode() + { + if (string.IsNullOrEmpty(Value)) + { + return 0; + } + return StringComparer.OrdinalIgnoreCase.GetHashCode(Value); + } + } +} \ No newline at end of file diff --git a/src/Microsoft.DotNet.ProjectModel/Graph/LockFileReader.cs b/src/Microsoft.DotNet.ProjectModel/Graph/LockFileReader.cs index 9f3592b02..3985e20fd 100644 --- a/src/Microsoft.DotNet.ProjectModel/Graph/LockFileReader.cs +++ b/src/Microsoft.DotNet.ProjectModel/Graph/LockFileReader.cs @@ -166,10 +166,39 @@ namespace Microsoft.DotNet.ProjectModel.Graph library.CompileTimeAssemblies = ReadObject(jobject.ValueAsJsonObject("compile"), ReadFileItem); library.ResourceAssemblies = ReadObject(jobject.ValueAsJsonObject("resource"), ReadFileItem); library.NativeLibraries = ReadObject(jobject.ValueAsJsonObject("native"), ReadFileItem); - + library.ContentFiles = ReadObject(jobject.ValueAsJsonObject("contentFiles"), ReadContentFile); return library; } + private static LockFileContentFile ReadContentFile(string property, JsonValue json) + { + var contentFile = new LockFileContentFile() + { + Path = property + }; + + var jsonObject = json as JsonObject; + if (jsonObject != null) + { + + BuildAction action; + BuildAction.TryParse(jsonObject.ValueAsString("buildAction"), out action); + + contentFile.BuildAction = action; + var codeLanguage = jsonObject.ValueAsString("codeLanguage"); + if (codeLanguage == "any") + { + codeLanguage = null; + } + contentFile.CodeLanguage = codeLanguage; + contentFile.OutputPath = jsonObject.ValueAsString("outputPath"); + contentFile.PPOutputPath = jsonObject.ValueAsString("ppOutputPath"); + contentFile.CopyToOutput = ReadBool(jsonObject, "copyToOutput", false); + } + + return contentFile; + } + private static ProjectFileDependencyGroup ReadProjectFileDependencyGroup(string property, JsonValue json) { return new ProjectFileDependencyGroup( diff --git a/src/Microsoft.DotNet.ProjectModel/Graph/LockFileTargetContentFile.cs b/src/Microsoft.DotNet.ProjectModel/Graph/LockFileTargetContentFile.cs new file mode 100644 index 000000000..72eecd0c1 --- /dev/null +++ b/src/Microsoft.DotNet.ProjectModel/Graph/LockFileTargetContentFile.cs @@ -0,0 +1,20 @@ +// 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. + +namespace Microsoft.DotNet.ProjectModel.Graph +{ + public class LockFileContentFile + { + public string Path { get; set; } + + public string OutputPath { get; set; } + + public string PPOutputPath { get; set; } + + public BuildAction BuildAction { get; set; } + + public string CodeLanguage { get; set; } + + public bool CopyToOutput { get; set; } = false; + } +} \ No newline at end of file diff --git a/src/Microsoft.DotNet.ProjectModel/Graph/LockFileTargetLibrary.cs b/src/Microsoft.DotNet.ProjectModel/Graph/LockFileTargetLibrary.cs index 7339fed39..eb593e3a4 100644 --- a/src/Microsoft.DotNet.ProjectModel/Graph/LockFileTargetLibrary.cs +++ b/src/Microsoft.DotNet.ProjectModel/Graph/LockFileTargetLibrary.cs @@ -30,5 +30,7 @@ namespace Microsoft.DotNet.ProjectModel.Graph public IList ResourceAssemblies { get; set; } = new List(); public IList NativeLibraries { get; set; } = new List(); + + public IList ContentFiles { get; set; } = new List(); } } diff --git a/src/Microsoft.DotNet.ProjectModel/PackageDescription.cs b/src/Microsoft.DotNet.ProjectModel/PackageDescription.cs index b66d8a941..5327a4896 100644 --- a/src/Microsoft.DotNet.ProjectModel/PackageDescription.cs +++ b/src/Microsoft.DotNet.ProjectModel/PackageDescription.cs @@ -42,6 +42,8 @@ namespace Microsoft.DotNet.ProjectModel public IEnumerable NativeLibraries => Target.NativeLibraries; + public IEnumerable ContentFiles => Target.ContentFiles; + private IEnumerable FilterPlaceholders(IList items) { return items.Where(a => !PackageDependencyProvider.IsPlaceholderFile(a)); diff --git a/src/Microsoft.DotNet.ProjectModel/ProjectExtensions.cs b/src/Microsoft.DotNet.ProjectModel/ProjectExtensions.cs new file mode 100644 index 000000000..2c5d9c69c --- /dev/null +++ b/src/Microsoft.DotNet.ProjectModel/ProjectExtensions.cs @@ -0,0 +1,32 @@ +// 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; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Microsoft.DotNet.ProjectModel +{ + public static class ProjectExtensions + { + private static readonly KeyValuePair[] _compilerNameToLanguageId = + { + new KeyValuePair("csc", "cs"), + new KeyValuePair("vbc", "vb"), + new KeyValuePair("fsc", "fs") + }; + + public static string GetSourceCodeLanguage(this Project project) + { + foreach (var kvp in _compilerNameToLanguageId) + { + if (kvp.Key == project.CompilerName) + { + return kvp.Value; + } + } + return null; + } + } +} diff --git a/src/Microsoft.DotNet.ProjectModel/ProjectReader.cs b/src/Microsoft.DotNet.ProjectModel/ProjectReader.cs index 744023c1a..1336d21dc 100644 --- a/src/Microsoft.DotNet.ProjectModel/ProjectReader.cs +++ b/src/Microsoft.DotNet.ProjectModel/ProjectReader.cs @@ -141,7 +141,7 @@ namespace Microsoft.DotNet.ProjectModel project.ProjectUrl = rawProject.ValueAsString("projectUrl"); project.LicenseUrl = rawProject.ValueAsString("licenseUrl"); project.IconUrl = rawProject.ValueAsString("iconUrl"); - project.CompilerName = rawProject.ValueAsString("compilerName"); + project.CompilerName = rawProject.ValueAsString("compilerName") ?? "csc"; project.TestRunner = rawProject.ValueAsString("testRunner"); project.Authors = rawProject.ValueAsStringArray("authors") ?? EmptyArray.Value; diff --git a/src/dotnet/commands/dotnet-build/CompileContext.cs b/src/dotnet/commands/dotnet-build/CompileContext.cs index 91010bb3b..e66a08fd6 100644 --- a/src/dotnet/commands/dotnet-build/CompileContext.cs +++ b/src/dotnet/commands/dotnet-build/CompileContext.cs @@ -255,7 +255,7 @@ namespace Microsoft.DotNet.Tools.Build private void CollectCompilerNamePreconditions(ProjectContext project, IncrementalPreconditions preconditions) { - var projectCompiler = CompilerUtil.ResolveCompilerName(project); + var projectCompiler = project.ProjectFile.CompilerName; if (!KnownCompilers.Any(knownCompiler => knownCompiler.Equals(projectCompiler, StringComparison.Ordinal))) { diff --git a/src/dotnet/commands/dotnet-compile/CompilerUtil.cs b/src/dotnet/commands/dotnet-compile/CompilerUtil.cs index bc7f13a32..dda381ee7 100644 --- a/src/dotnet/commands/dotnet-compile/CompilerUtil.cs +++ b/src/dotnet/commands/dotnet-compile/CompilerUtil.cs @@ -6,7 +6,6 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; - using Microsoft.DotNet.ProjectModel; using Microsoft.DotNet.Cli.Compiler.Common; using Microsoft.DotNet.ProjectModel.Compilation; @@ -20,34 +19,12 @@ namespace Microsoft.DotNet.Tools.Compiler { public static class CompilerUtil { - public static string ResolveCompilerName(ProjectContext context) - { - var compilerName = context.ProjectFile.CompilerName; - compilerName = compilerName ?? "csc"; - - return compilerName; - } - - private static readonly KeyValuePair[] s_compilerNameToLanguageId = - { - new KeyValuePair("csc", "cs"), - new KeyValuePair("vbc", "vb"), - new KeyValuePair("fsc", "fs") - }; - public static string ResolveLanguageId(ProjectContext context) { var languageId = context.ProjectFile.AnalyzerOptions?.LanguageId; if (languageId == null) { - var compilerName = ResolveCompilerName(context); - foreach (var kvp in s_compilerNameToLanguageId) - { - if (kvp.Key == compilerName) - { - languageId = kvp.Value; - } - } + languageId = context.ProjectFile.GetSourceCodeLanguage(); } return languageId; @@ -166,7 +143,7 @@ namespace Microsoft.DotNet.Tools.Compiler //used in incremental precondition checks public static IEnumerable GetCommandsInvokedByCompile(ProjectContext project) { - return new List {ResolveCompilerName(project), "compile"}; + return new List {project.ProjectFile.CompilerName, "compile"}; } } } \ No newline at end of file diff --git a/src/dotnet/commands/dotnet-compile/ManagedCompiler.cs b/src/dotnet/commands/dotnet-compile/ManagedCompiler.cs index 960b2b97a..674542dca 100644 --- a/src/dotnet/commands/dotnet-compile/ManagedCompiler.cs +++ b/src/dotnet/commands/dotnet-compile/ManagedCompiler.cs @@ -8,6 +8,7 @@ using System.Linq; using Microsoft.DotNet.Cli.Compiler.Common; using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.ProjectModel; +using Microsoft.DotNet.ProjectModel.Compilation; using Microsoft.DotNet.ProjectModel.Utilities; using Microsoft.Extensions.DependencyModel; @@ -90,7 +91,15 @@ namespace Microsoft.DotNet.Tools.Compiler foreach (var dependency in dependencies) { references.AddRange(dependency.CompilationAssemblies.Select(r => r.ResolvedPath)); - compilerArgs.AddRange(dependency.SourceReferences.Select(s => $"{s}")); + + compilerArgs.AddRange(dependency.SourceReferences.Select(s => s.GetTransformedFile(intermediateOutputPath))); + + foreach (var resourceFile in dependency.EmbeddedResources) + { + var transformedResource = resourceFile.GetTransformedFile(intermediateOutputPath); + var resourceName = ResourceManifestName.CreateManifestName(Path.GetFileName(resourceFile.ResolvedPath), context.ProjectFile.Name); + compilerArgs.Add($"--resource:\"{transformedResource}\",{resourceName}"); + } // Add analyzer references compilerArgs.AddRange(dependency.AnalyzerReferences @@ -126,7 +135,7 @@ namespace Microsoft.DotNet.Tools.Compiler var sourceFiles = CompilerUtil.GetCompilationSources(context); compilerArgs.AddRange(sourceFiles); - var compilerName = CompilerUtil.ResolveCompilerName(context); + var compilerName = context.ProjectFile.CompilerName; // Write RSP file var rsp = Path.Combine(intermediateOutputPath, $"dotnet-compile.rsp"); diff --git a/src/dotnet/commands/dotnet-projectmodel-server/Helpers/ProjectExtensions.cs b/src/dotnet/commands/dotnet-projectmodel-server/Helpers/ProjectExtensions.cs index c7eb9b30e..ef28bbc23 100644 --- a/src/dotnet/commands/dotnet-projectmodel-server/Helpers/ProjectExtensions.cs +++ b/src/dotnet/commands/dotnet-projectmodel-server/Helpers/ProjectExtensions.cs @@ -1,4 +1,7 @@ -using System; +// 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; using System.Collections.Generic; using System.IO; diff --git a/src/dotnet/commands/dotnet-projectmodel-server/InternalModels/ProjectContextSnapshot.cs b/src/dotnet/commands/dotnet-projectmodel-server/InternalModels/ProjectContextSnapshot.cs index 167115a64..195bf5ba1 100644 --- a/src/dotnet/commands/dotnet-projectmodel-server/InternalModels/ProjectContextSnapshot.cs +++ b/src/dotnet/commands/dotnet-projectmodel-server/InternalModels/ProjectContextSnapshot.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Microsoft.DotNet.ProjectModel.Compilation; using Microsoft.DotNet.ProjectModel.Server.Helpers; using Microsoft.DotNet.ProjectModel.Server.Models; using Microsoft.DotNet.Cli.Compiler.Common; @@ -45,7 +46,7 @@ namespace Microsoft.DotNet.ProjectModel.Server // both will be listed as dependencies. Prefix "fx/" will be added to ReferenceAssembly type dependency. foreach (var export in allExports.Values) { - allSourceFiles.AddRange(export.SourceReferences); + allSourceFiles.AddRange(export.SourceReferences.Select(f => f.ResolvedPath)); allFileReferences.AddRange(export.CompilationAssemblies.Select(asset => asset.ResolvedPath)); var diagnostics = diagnosticsLookup[export.Library].ToList(); diff --git a/src/dotnet/commands/dotnet-publish/PublishCommand.cs b/src/dotnet/commands/dotnet-publish/PublishCommand.cs index 0f0f2316a..ffd8f4988 100644 --- a/src/dotnet/commands/dotnet-publish/PublishCommand.cs +++ b/src/dotnet/commands/dotnet-publish/PublishCommand.cs @@ -87,10 +87,11 @@ namespace Microsoft.DotNet.Tools.Publish Reporter.Output.WriteLine($"Publishing {context.RootProject.Identity.Name.Yellow()} for {context.TargetFramework.DotNetFrameworkName.Yellow()}/{context.RuntimeIdentifier.Yellow()}"); var options = context.ProjectFile.GetCompilerOptions(context.TargetFramework, configuration); + var outputPaths = context.GetOutputPaths(configuration, buildBasePath, outputPath); if (string.IsNullOrEmpty(outputPath)) { - outputPath = Path.Combine(context.GetOutputPaths(configuration, buildBasePath, outputPath).RuntimeOutputPath, PublishSubfolderName); + outputPath = Path.Combine(outputPaths.RuntimeOutputPath, PublishSubfolderName); } var contextVariables = new Dictionary @@ -148,7 +149,7 @@ namespace Microsoft.DotNet.Tools.Publish PublishFiles(export.RuntimeAssemblies, outputPath, nativeSubdirectories: false); PublishFiles(export.NativeLibraries, outputPath, nativeSubdirectories); - export.RuntimeAssets.StructuredCopyTo(outputPath); + export.RuntimeAssets.StructuredCopyTo(outputPath, outputPaths.IntermediateOutputDirectoryPath); if (options.PreserveCompilationContext.GetValueOrDefault()) { diff --git a/test/Microsoft.DotNet.ProjectModel.Tests/LibraryExporterPackageTests.cs b/test/Microsoft.DotNet.ProjectModel.Tests/LibraryExporterPackageTests.cs new file mode 100644 index 000000000..1fe4cbb7b --- /dev/null +++ b/test/Microsoft.DotNet.ProjectModel.Tests/LibraryExporterPackageTests.cs @@ -0,0 +1,299 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using Microsoft.DotNet.ProjectModel.Compilation; +using Microsoft.DotNet.ProjectModel.Graph; +using Microsoft.DotNet.ProjectModel.Resolution; +using Microsoft.DotNet.Tools.Test.Utilities; +using FluentAssertions; +using Xunit; + +namespace Microsoft.DotNet.ProjectModel.Tests +{ + public class LibraryExporterPackageTests + { + private const string PackagePath = "PackagePath"; + + private LibraryExport ExportSingle(LibraryDescription description = null) + { + var rootProject = new Project() + { + Name = "RootProject", + CompilerName = "csc" + }; + + var rootProjectDescription = new ProjectDescription( + new LibraryRange(), + rootProject, + new LibraryRange[] { }, + new TargetFrameworkInformation(), + true); + + if (description == null) + { + description = rootProjectDescription; + } + else + { + description.Parents.Add(rootProjectDescription); + } + + var libraryManager = new LibraryManager(new[] { description }, new DiagnosticMessage[] { }, ""); + var allExports = new LibraryExporter(rootProjectDescription, libraryManager, "config", "runtime", "basepath", "solutionroot").GetAllExports(); + var export = allExports.Single(); + return export; + } + + private PackageDescription CreateDescription(LockFileTargetLibrary target = null, LockFilePackageLibrary package = null) + { + return new PackageDescription(PackagePath, + package ?? new LockFilePackageLibrary(), + target ?? new LockFileTargetLibrary(), + new List(), true); + } + + [Fact] + private void ExportsPackageNativeLibraries() + { + var description = CreateDescription( + new LockFileTargetLibrary() + { + NativeLibraries = new List() + { + { new LockFileItem() { Path = "lib/Native.so" } } + } + }); + + var result = ExportSingle(description); + result.NativeLibraries.Should().HaveCount(1); + + var libraryAsset = result.NativeLibraries.First(); + libraryAsset.Name.Should().Be("Native"); + libraryAsset.Transform.Should().BeNull(); + libraryAsset.RelativePath.Should().Be("lib/Native.so"); + libraryAsset.ResolvedPath.Should().Be(Path.Combine(PackagePath, "lib/Native.so")); + } + + [Fact] + private void ExportsPackageCompilationAssebmlies() + { + var description = CreateDescription( + new LockFileTargetLibrary() + { + CompileTimeAssemblies = new List() + { + { new LockFileItem() { Path = "ref/Native.dll" } } + } + }); + + var result = ExportSingle(description); + result.CompilationAssemblies.Should().HaveCount(1); + + var libraryAsset = result.CompilationAssemblies.First(); + libraryAsset.Name.Should().Be("Native"); + libraryAsset.Transform.Should().BeNull(); + libraryAsset.RelativePath.Should().Be("ref/Native.dll"); + libraryAsset.ResolvedPath.Should().Be(Path.Combine(PackagePath, "ref/Native.dll")); + } + + [Fact] + private void ExportsPackageRuntimeAssebmlies() + { + var description = CreateDescription( + new LockFileTargetLibrary() + { + RuntimeAssemblies = new List() + { + { new LockFileItem() { Path = "ref/Native.dll" } } + } + }); + + var result = ExportSingle(description); + result.RuntimeAssemblies.Should().HaveCount(1); + + var libraryAsset = result.RuntimeAssemblies.First(); + libraryAsset.Name.Should().Be("Native"); + libraryAsset.Transform.Should().BeNull(); + libraryAsset.RelativePath.Should().Be("ref/Native.dll"); + libraryAsset.ResolvedPath.Should().Be(Path.Combine(PackagePath, "ref/Native.dll")); + } + + [Fact] + private void ExportsSources() + { + var description = CreateDescription( + package: new LockFilePackageLibrary() + { + Files = new List() + { + Path.Combine("shared", "file.cs") + } + }); + + var result = ExportSingle(description); + result.SourceReferences.Should().HaveCount(1); + + var libraryAsset = result.SourceReferences.First(); + libraryAsset.Name.Should().Be("file"); + libraryAsset.Transform.Should().BeNull(); + libraryAsset.RelativePath.Should().Be(Path.Combine("shared", "file.cs")); + libraryAsset.ResolvedPath.Should().Be(Path.Combine(PackagePath, "shared", "file.cs")); + } + + [Fact] + private void ExportsCopyToOutputContentFiles() + { + var description = CreateDescription( + new LockFileTargetLibrary() + { + ContentFiles = new List() + { + new LockFileContentFile() + { + CopyToOutput = true, + Path = Path.Combine("content", "file.txt"), + OutputPath = Path.Combine("Out","Path.txt"), + PPOutputPath = "something" + } + } + }); + + var result = ExportSingle(description); + result.RuntimeAssets.Should().HaveCount(1); + + var libraryAsset = result.RuntimeAssets.First(); + libraryAsset.Transform.Should().NotBeNull(); + libraryAsset.RelativePath.Should().Be(Path.Combine("Out", "Path.txt")); + libraryAsset.ResolvedPath.Should().Be(Path.Combine(PackagePath, "content", "file.txt")); + } + + + [Fact] + private void ExportsResourceContentFiles() + { + var description = CreateDescription( + new LockFileTargetLibrary() + { + ContentFiles = new List() + { + new LockFileContentFile() + { + BuildAction = BuildAction.EmbeddedResource, + Path = Path.Combine("content", "file.txt"), + PPOutputPath = "something" + } + } + }); + + var result = ExportSingle(description); + result.EmbeddedResources.Should().HaveCount(1); + + var libraryAsset = result.EmbeddedResources.First(); + libraryAsset.Transform.Should().NotBeNull(); + libraryAsset.RelativePath.Should().Be(Path.Combine("content", "file.txt")); + libraryAsset.ResolvedPath.Should().Be(Path.Combine(PackagePath, "content", "file.txt")); + } + + [Fact] + private void ExportsCompileContentFiles() + { + var description = CreateDescription( + new LockFileTargetLibrary() + { + ContentFiles = new List() + { + new LockFileContentFile() + { + BuildAction = BuildAction.Compile, + Path = Path.Combine("content", "file.cs"), + PPOutputPath = "something" + } + } + }); + + var result = ExportSingle(description); + result.SourceReferences.Should().HaveCount(1); + + var libraryAsset = result.SourceReferences.First(); + libraryAsset.Transform.Should().NotBeNull(); + libraryAsset.RelativePath.Should().Be(Path.Combine("content", "file.cs")); + libraryAsset.ResolvedPath.Should().Be(Path.Combine(PackagePath, "content", "file.cs")); + } + + + + [Fact] + private void SelectsContentFilesOfProjectCodeLanguage() + { + var description = CreateDescription( + new LockFileTargetLibrary() + { + ContentFiles = new List() + { + new LockFileContentFile() + { + BuildAction = BuildAction.Compile, + Path = Path.Combine("content", "file.cs"), + PPOutputPath = "something", + CodeLanguage = "cs" + }, + new LockFileContentFile() + { + BuildAction = BuildAction.Compile, + Path = Path.Combine("content", "file.vb"), + PPOutputPath = "something", + CodeLanguage = "vb" + }, + new LockFileContentFile() + { + BuildAction = BuildAction.Compile, + Path = Path.Combine("content", "file.any"), + PPOutputPath = "something", + } + } + }); + + var result = ExportSingle(description); + result.SourceReferences.Should().HaveCount(1); + + var libraryAsset = result.SourceReferences.First(); + libraryAsset.Transform.Should().NotBeNull(); + libraryAsset.RelativePath.Should().Be(Path.Combine("content", "file.cs")); + libraryAsset.ResolvedPath.Should().Be(Path.Combine(PackagePath, "content", "file.cs")); + } + + [Fact] + private void SelectsContentFilesWithNoLanguageIfProjectLanguageNotMathed() + { + var description = CreateDescription( + new LockFileTargetLibrary() + { + ContentFiles = new List() + { + new LockFileContentFile() + { + BuildAction = BuildAction.Compile, + Path = Path.Combine("content", "file.vb"), + PPOutputPath = "something", + CodeLanguage = "vb" + }, + new LockFileContentFile() + { + BuildAction = BuildAction.Compile, + Path = Path.Combine("content", "file.any"), + PPOutputPath = "something", + } + } + }); + + var result = ExportSingle(description); + result.SourceReferences.Should().HaveCount(1); + + var libraryAsset = result.SourceReferences.First(); + libraryAsset.Transform.Should().NotBeNull(); + libraryAsset.RelativePath.Should().Be(Path.Combine("content", "file.any")); + libraryAsset.ResolvedPath.Should().Be(Path.Combine(PackagePath, "content", "file.any")); + } + } +} diff --git a/test/Microsoft.DotNet.ProjectModel.Tests/PreprocessorTests.cs b/test/Microsoft.DotNet.ProjectModel.Tests/PreprocessorTests.cs new file mode 100644 index 000000000..5a0fec8db --- /dev/null +++ b/test/Microsoft.DotNet.ProjectModel.Tests/PreprocessorTests.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using FluentAssertions; +using Xunit; +using Microsoft.DotNet.Tools.Compiler; + +namespace Microsoft.DotNet.ProjectModel.Tests +{ + public class PreprocessorTests + { + private string Preprocess(string text, IDictionary parameters) + { + using (var input = new MemoryStream(Encoding.UTF8.GetBytes(text))) + { + using (var output = new MemoryStream()) + { + PPFilePreprocessor.Preprocess(input, output, parameters); + return Encoding.UTF8.GetString(output.ToArray()); + } + } + } + + [Theory] + [InlineData("$a$", "AValue")] + [InlineData("$a", "$a")] + [InlineData("a$", "a$")] + [InlineData("$$a$", "$a$")] + [InlineData("$a$$b$", "AValueBValue")] + [InlineData("$$a$$$$b$$", "$a$$b$")] + + public void ProcessesCorrectly(string input, string output) + { + var parameters = new Dictionary() + { + { "a", "AValue" }, + { "b", "BValue" } + }; + var result = Preprocess(input, parameters); + result.Should().Be(output); + } + + [Fact] + public void ThrowsOnParameterNotFound() + { + var ex = Assert.Throws(() => Preprocess("$a$", new Dictionary())); + ex.Message.Should().Contain("a"); + } + } +} diff --git a/test/dotnet-compile.Tests/CompilerTests.cs b/test/dotnet-compile.Tests/CompilerTests.cs index c0ed48edb..4c4057e7e 100644 --- a/test/dotnet-compile.Tests/CompilerTests.cs +++ b/test/dotnet-compile.Tests/CompilerTests.cs @@ -3,7 +3,9 @@ using System; using System.IO; +using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.Tools.Test.Utilities; +using FluentAssertions; using Xunit; namespace Microsoft.DotNet.Tools.Compiler.Tests @@ -106,6 +108,44 @@ namespace Microsoft.DotNet.Tools.Compiler.Tests buildCommand.Execute().Should().Pass(); } + [Fact] + public void ContentFilesAreCopied() + { + var testInstance = TestAssetsManager.CreateTestInstance("TestAppWithContentPackage") + .WithLockFiles(); + + var root = testInstance.TestRoot; + + // run compile + var outputDir = Path.Combine(root, "bin"); + var testProject = ProjectUtils.GetProjectJson(root, "TestAppWithContentPackage"); + var buildCommand = new BuildCommand(testProject, output: outputDir, framework: DefaultFramework); + var result = buildCommand.ExecuteWithCapturedOutput(); + result.Should().Pass(); + + result = Command.Create(Path.Combine(outputDir, buildCommand.GetOutputExecutableName()), new string [0]) + .CaptureStdErr() + .CaptureStdOut() + .Execute(); + result.Should().Pass(); + + // verify the output xml file + new DirectoryInfo(outputDir).Sub("scripts").Should() + .Exist() + .And.HaveFile("run.cmd"); + new DirectoryInfo(outputDir).Should() + .HaveFile("config.xml"); + // verify embedded resources + result.StdOut.Should().Contain("TestAppWithContentPackage.dnf.png"); + result.StdOut.Should().Contain("TestAppWithContentPackage.ui.png"); + // verify 'all' language files not included + result.StdOut.Should().NotContain("TestAppWithContentPackage.dnf_all.png"); + result.StdOut.Should().NotContain("TestAppWithContentPackage.ui_all.png"); + // verify classes + result.StdOut.Should().Contain("TestAppWithContentPackage.Foo"); + result.StdOut.Should().Contain("MyNamespace.Util"); + } + private void CopyProjectToTempDir(string projectDir, TempDirectory tempDir) { // copy all the files to temp dir