Asset refactoring and content files
This commit is contained in:
parent
388bb7260c
commit
a71112ce8f
34 changed files with 1301 additions and 173 deletions
|
@ -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
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<packageSources>
|
||||
<add key="Local" value="Packages" />
|
||||
</packageSources>
|
||||
</configuration>
|
Binary file not shown.
19
TestAssets/TestProjects/TestAppWithContentPackage/Program.cs
Normal file
19
TestAssets/TestProjects/TestAppWithContentPackage/Program.cs
Normal file
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0.24720" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0.24720</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>ea239e10-75e8-4305-966e-fec926a5aee6</ProjectGuid>
|
||||
<RootNamespace>TestAppWithContentPackage</RootNamespace>
|
||||
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
|
||||
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
</Project>
|
|
@ -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": { }
|
||||
}
|
||||
}
|
|
@ -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<LibraryExport> libraryExports)
|
||||
private void CopyAssemblies(IEnumerable<LibraryExport> 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<LibraryExport> 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)
|
||||
|
|
|
@ -53,7 +53,7 @@ namespace Microsoft.DotNet.Cli.Compiler.Common
|
|||
}
|
||||
}
|
||||
|
||||
public static void StructuredCopyTo(this IEnumerable<LibraryAsset> assets, string destinationPath)
|
||||
public static void StructuredCopyTo(this IEnumerable<LibraryAsset> 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0.24720" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0.24720</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>bd4f0750-4e81-4ad2-90b5-e470881792c3</ProjectGuid>
|
||||
<RootNamespace>Microsoft.DotNet.InternalAbstractions</RootNamespace>
|
||||
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
|
||||
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
</Project>
|
|
@ -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)
|
||||
|
|
|
@ -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<Stream, Stream> Transform { get; set; }
|
||||
|
||||
public LibraryAsset(string name, string relativePath, string resolvedPath)
|
||||
public LibraryAsset(string name, string relativePath, string resolvedPath, Action<Stream, Stream> 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<Stream, Stream> transform = null)
|
||||
{
|
||||
return new LibraryAsset(
|
||||
Path.GetFileNameWithoutExtension(relativePath),
|
||||
relativePath,
|
||||
Path.Combine(basePath, relativePath),
|
||||
transform);
|
||||
}
|
||||
|
||||
public static LibraryAsset CreateFromAbsolutePath(string basePath, string absolutePath, Action<Stream, Stream> transform = null)
|
||||
{
|
||||
var relativePath = absolutePath.Replace(PathUtility.EnsureTrailingSlash(basePath), string.Empty);
|
||||
|
||||
return new LibraryAsset(
|
||||
Path.GetFileNameWithoutExtension(relativePath),
|
||||
relativePath,
|
||||
absolutePath,
|
||||
transform);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -34,10 +34,15 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
|
|||
/// </summary>
|
||||
public IEnumerable<LibraryAsset> CompilationAssemblies { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get a list of embedded resource files provided by this export.
|
||||
/// </summary>
|
||||
public IEnumerable<LibraryAsset> EmbeddedResources { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of fully-qualified paths to source code file references
|
||||
/// </summary>
|
||||
public IEnumerable<string> SourceReferences { get; }
|
||||
public IEnumerable<LibraryAsset> SourceReferences { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get a list of analyzers provided by this export.
|
||||
|
@ -46,10 +51,11 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
|
|||
|
||||
public LibraryExport(LibraryDescription library,
|
||||
IEnumerable<LibraryAsset> compileAssemblies,
|
||||
IEnumerable<string> sourceReferences,
|
||||
IEnumerable<LibraryAsset> sourceReferences,
|
||||
IEnumerable<LibraryAsset> runtimeAssemblies,
|
||||
IEnumerable<LibraryAsset> runtimeAssets,
|
||||
IEnumerable<LibraryAsset> nativeLibraries,
|
||||
IEnumerable<LibraryAsset> embeddedResources,
|
||||
IEnumerable<AnalyzerReference> analyzers)
|
||||
{
|
||||
Library = library;
|
||||
|
@ -58,6 +64,7 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
|
|||
RuntimeAssemblies = runtimeAssemblies;
|
||||
RuntimeAssets = runtimeAssets;
|
||||
NativeLibraries = nativeLibraries;
|
||||
EmbeddedResources = embeddedResources;
|
||||
AnalyzerReferences = analyzers;
|
||||
}
|
||||
|
||||
|
|
|
@ -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<LibraryAsset> _runtimeAssemblies;
|
||||
|
||||
private IList<LibraryAsset> _runtimeAssets;
|
||||
|
||||
private IList<LibraryAsset> _compilationAssemblies;
|
||||
|
||||
private IList<LibraryAsset> _compilationAssets;
|
||||
|
||||
private IList<LibraryAsset> _debugAssets;
|
||||
|
||||
private IList<LibraryAsset> _sourceReferences;
|
||||
|
||||
private IList<LibraryAsset> _nativeLibraries;
|
||||
|
||||
private IList<LibraryAsset> _embeddedResources;
|
||||
|
||||
private IList<AnalyzerReference> _analyzerReferences;
|
||||
|
||||
public LibraryDescription Library { get; set; }
|
||||
|
||||
public IEnumerable<LibraryAsset> RuntimeAssemblies => _runtimeAssemblies;
|
||||
|
||||
public IEnumerable<LibraryAsset> RuntimeAssets => _runtimeAssets;
|
||||
|
||||
public IEnumerable<LibraryAsset> CompilationAssemblies => _compilationAssemblies;
|
||||
|
||||
public IEnumerable<LibraryAsset> CompilationAssets => _compilationAssets;
|
||||
|
||||
public IEnumerable<LibraryAsset> SourceReferences => _sourceReferences;
|
||||
|
||||
public IEnumerable<LibraryAsset> NativeLibraries => _nativeLibraries;
|
||||
|
||||
public IEnumerable<LibraryAsset> EmbeddedResources => _embeddedResources;
|
||||
|
||||
public IEnumerable<AnalyzerReference> 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<LibraryAsset>.Value,
|
||||
SourceReferences ?? EmptyArray<LibraryAsset>.Value,
|
||||
RuntimeAssemblies ?? EmptyArray<LibraryAsset>.Value,
|
||||
RuntimeAssets ?? EmptyArray<LibraryAsset>.Value,
|
||||
NativeLibraries ?? EmptyArray<LibraryAsset>.Value,
|
||||
EmbeddedResources ?? EmptyArray<LibraryAsset>.Value,
|
||||
AnalyzerReferences ?? EmptyArray<AnalyzerReference>.Value);
|
||||
}
|
||||
|
||||
public LibraryExportBuilder WithLibrary(LibraryDescription libraryDescription)
|
||||
{
|
||||
Library = libraryDescription;
|
||||
return this;
|
||||
}
|
||||
|
||||
public LibraryExportBuilder WithRuntimeAssemblies(IEnumerable<LibraryAsset> assets)
|
||||
{
|
||||
Replace(ref _runtimeAssemblies, assets);
|
||||
return this;
|
||||
}
|
||||
|
||||
public LibraryExportBuilder WithRuntimeAssets(IEnumerable<LibraryAsset> assets)
|
||||
{
|
||||
Replace(ref _runtimeAssets, assets);
|
||||
return this;
|
||||
}
|
||||
|
||||
public LibraryExportBuilder WithCompilationAssemblies(IEnumerable<LibraryAsset> assets)
|
||||
{
|
||||
Replace(ref _compilationAssemblies, assets);
|
||||
return this;
|
||||
}
|
||||
|
||||
public LibraryExportBuilder WithSourceReferences(IEnumerable<LibraryAsset> assets)
|
||||
{
|
||||
Replace(ref _sourceReferences, assets);
|
||||
return this;
|
||||
}
|
||||
|
||||
public LibraryExportBuilder WithNativeLibraries(IEnumerable<LibraryAsset> assets)
|
||||
{
|
||||
Replace(ref _nativeLibraries, assets);
|
||||
return this;
|
||||
}
|
||||
|
||||
public LibraryExportBuilder WithEmbedddedResources(IEnumerable<LibraryAsset> assets)
|
||||
{
|
||||
Replace(ref _embeddedResources, assets);
|
||||
return this;
|
||||
}
|
||||
|
||||
public LibraryExportBuilder WithAnalyzerReference(IEnumerable<AnalyzerReference> 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<T>(ref IList<T> list, IEnumerable<T> enumerable)
|
||||
{
|
||||
list = new List<T>(enumerable);
|
||||
}
|
||||
|
||||
private void Add<T>(ref IList<T> list, T item)
|
||||
{
|
||||
if (list == null)
|
||||
{
|
||||
list = new List<T>();
|
||||
}
|
||||
list.Add(item);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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<LibraryAsset>();
|
||||
var sourceReferences = new List<string>();
|
||||
var sourceReferences = new List<LibraryAsset>();
|
||||
var analyzerReferences = new List<AnalyzerReference>();
|
||||
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<LibraryAsset>(),
|
||||
sourceReferences: Enumerable.Empty<string>(),
|
||||
nativeLibraries: Enumerable.Empty<LibraryAsset>(),
|
||||
runtimeAssets: Enumerable.Empty<LibraryAsset>(),
|
||||
runtimeAssemblies: EmptyArray<LibraryAsset>.Value,
|
||||
analyzers: EmptyArray<AnalyzerReference>.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<LibraryAsset>();
|
||||
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<LibraryAsset>();
|
||||
PopulateAssets(package, package.RuntimeAssemblies, runtimeAssemblies);
|
||||
|
||||
var compileAssemblies = new List<LibraryAsset>();
|
||||
PopulateAssets(package, package.CompileTimeAssemblies, compileAssemblies);
|
||||
|
||||
var sourceReferences = new List<string>();
|
||||
foreach (var sharedSource in GetSharedSources(package))
|
||||
if (package.ContentFiles.Any())
|
||||
{
|
||||
sourceReferences.Add(sharedSource);
|
||||
var parameters = PPFileParameters.CreateForProject(_rootProject.Project);
|
||||
Action<Stream, Stream> 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<LibraryAsset>.Value, nativeLibraries, analyzers);
|
||||
return builder.Build();
|
||||
}
|
||||
|
||||
private LibraryExport ExportProject(ProjectDescription project)
|
||||
{
|
||||
var compileAssemblies = new List<LibraryAsset>();
|
||||
var runtimeAssets = new List<LibraryAsset>();
|
||||
var sourceReferences = new List<string>();
|
||||
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<LibraryAsset> 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<LibraryAsset>.Value, EmptyArray<AnalyzerReference>.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<LibraryAsset>.Value :
|
||||
new[] { new LibraryAsset(library.Identity.Name, library.Path, library.Path) },
|
||||
EmptyArray<string>.Value,
|
||||
EmptyArray<LibraryAsset>.Value,
|
||||
EmptyArray<LibraryAsset>.Value,
|
||||
EmptyArray<LibraryAsset>.Value,
|
||||
EmptyArray<AnalyzerReference>.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<string> GetSharedSources(PackageDescription package)
|
||||
private IEnumerable<LibraryAsset> 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<AnalyzerReference> GetAnalyzerReferences(PackageDescription package)
|
||||
|
@ -348,14 +382,11 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
|
|||
}
|
||||
|
||||
|
||||
private void PopulateAssets(PackageDescription package, IEnumerable<LockFileItem> section, IList<LibraryAsset> assets)
|
||||
private IEnumerable<LibraryAsset> PopulateAssets(PackageDescription package, IEnumerable<LockFileItem> 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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<string, string> CreateForProject(Project project)
|
||||
{
|
||||
return new Dictionary<string, string>()
|
||||
{
|
||||
{"rootnamespace", project.Name },
|
||||
{"assemblyname", project.Name }
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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<string, string> 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<string, string> parameters)
|
||||
{
|
||||
string value;
|
||||
if (!parameters.TryGetValue(name, out value))
|
||||
{
|
||||
throw new InvalidOperationException($"The replacement token '{name}' has no value.");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the next token.
|
||||
/// </summary>
|
||||
/// <returns>The parsed token. Or null if no more tokens are available.</returns>
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
86
src/Microsoft.DotNet.ProjectModel/Graph/BuildAction.cs
Normal file
86
src/Microsoft.DotNet.ProjectModel/Graph/BuildAction.cs
Normal file
|
@ -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<BuildAction>
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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(
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -30,5 +30,7 @@ namespace Microsoft.DotNet.ProjectModel.Graph
|
|||
public IList<LockFileItem> ResourceAssemblies { get; set; } = new List<LockFileItem>();
|
||||
|
||||
public IList<LockFileItem> NativeLibraries { get; set; } = new List<LockFileItem>();
|
||||
|
||||
public IList<LockFileContentFile> ContentFiles { get; set; } = new List<LockFileContentFile>();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,6 +42,8 @@ namespace Microsoft.DotNet.ProjectModel
|
|||
|
||||
public IEnumerable<LockFileItem> NativeLibraries => Target.NativeLibraries;
|
||||
|
||||
public IEnumerable<LockFileContentFile> ContentFiles => Target.ContentFiles;
|
||||
|
||||
private IEnumerable<LockFileItem> FilterPlaceholders(IList<LockFileItem> items)
|
||||
{
|
||||
return items.Where(a => !PackageDependencyProvider.IsPlaceholderFile(a));
|
||||
|
|
32
src/Microsoft.DotNet.ProjectModel/ProjectExtensions.cs
Normal file
32
src/Microsoft.DotNet.ProjectModel/ProjectExtensions.cs
Normal file
|
@ -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<string, string>[] _compilerNameToLanguageId =
|
||||
{
|
||||
new KeyValuePair<string, string>("csc", "cs"),
|
||||
new KeyValuePair<string, string>("vbc", "vb"),
|
||||
new KeyValuePair<string, string>("fsc", "fs")
|
||||
};
|
||||
|
||||
public static string GetSourceCodeLanguage(this Project project)
|
||||
{
|
||||
foreach (var kvp in _compilerNameToLanguageId)
|
||||
{
|
||||
if (kvp.Key == project.CompilerName)
|
||||
{
|
||||
return kvp.Value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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<string>.Value;
|
||||
|
|
|
@ -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)))
|
||||
{
|
||||
|
|
|
@ -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<string, string>[] s_compilerNameToLanguageId =
|
||||
{
|
||||
new KeyValuePair<string, string>("csc", "cs"),
|
||||
new KeyValuePair<string, string>("vbc", "vb"),
|
||||
new KeyValuePair<string, string>("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<string> GetCommandsInvokedByCompile(ProjectContext project)
|
||||
{
|
||||
return new List<string> {ResolveCompilerName(project), "compile"};
|
||||
return new List<string> {project.ProjectFile.CompilerName, "compile"};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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<string, string>
|
||||
|
@ -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())
|
||||
{
|
||||
|
|
|
@ -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<LibraryRange>(), true);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
private void ExportsPackageNativeLibraries()
|
||||
{
|
||||
var description = CreateDescription(
|
||||
new LockFileTargetLibrary()
|
||||
{
|
||||
NativeLibraries = new List<LockFileItem>()
|
||||
{
|
||||
{ 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<LockFileItem>()
|
||||
{
|
||||
{ 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<LockFileItem>()
|
||||
{
|
||||
{ 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<string>()
|
||||
{
|
||||
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<LockFileContentFile>()
|
||||
{
|
||||
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<LockFileContentFile>()
|
||||
{
|
||||
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<LockFileContentFile>()
|
||||
{
|
||||
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<LockFileContentFile>()
|
||||
{
|
||||
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<LockFileContentFile>()
|
||||
{
|
||||
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"));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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<string, string> 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<string, string>()
|
||||
{
|
||||
{ "a", "AValue" },
|
||||
{ "b", "BValue" }
|
||||
};
|
||||
var result = Preprocess(input, parameters);
|
||||
result.Should().Be(output);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ThrowsOnParameterNotFound()
|
||||
{
|
||||
var ex = Assert.Throws<InvalidOperationException>(() => Preprocess("$a$", new Dictionary<string, string>()));
|
||||
ex.Message.Should().Contain("a");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue