Merge pull request #2493 from dotnet/ajbaaska/project-model-fix
Updates to project.json schema
This commit is contained in:
commit
563f6497fd
49 changed files with 1600 additions and 277 deletions
13
TestAssets/TestProjects/EndToEndTestApp/Program.cs
Normal file
13
TestAssets/TestProjects/EndToEndTestApp/Program.cs
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace ConsoleApplication
|
||||||
|
{
|
||||||
|
public class Program
|
||||||
|
{
|
||||||
|
public static int Main(string[] args)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Hello World!");
|
||||||
|
return 100;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
0
TestAssets/TestProjects/EndToEndTestApp/copy/file.txt
Normal file
0
TestAssets/TestProjects/EndToEndTestApp/copy/file.txt
Normal file
0
TestAssets/TestProjects/EndToEndTestApp/copy/fileex.txt
Normal file
0
TestAssets/TestProjects/EndToEndTestApp/copy/fileex.txt
Normal file
31
TestAssets/TestProjects/EndToEndTestApp/project.json
Normal file
31
TestAssets/TestProjects/EndToEndTestApp/project.json
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
{
|
||||||
|
"version": "1.0.0-*",
|
||||||
|
"buildOptions": {
|
||||||
|
"emitEntryPoint": true,
|
||||||
|
"embed": {
|
||||||
|
"include": "*.resx",
|
||||||
|
"mappings": {
|
||||||
|
"myresource.resx": "resource2.resx"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"copyToOutput": {
|
||||||
|
"include": "copy/*.txt",
|
||||||
|
"excludeFiles": "copy/fileex.txt"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.NETCore.App": "1.0.0-rc2-*"
|
||||||
|
},
|
||||||
|
"packOptions": {
|
||||||
|
"files": {
|
||||||
|
"includeFiles": "packfiles/pack1.txt",
|
||||||
|
"mappings": {
|
||||||
|
"newpath/": "packfiles/pack2.txt"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"publishOptions": "testpublishfile.txt",
|
||||||
|
"frameworks": {
|
||||||
|
"netcoreapp1.0": { }
|
||||||
|
}
|
||||||
|
}
|
4
TestAssets/TestProjects/EndToEndTestApp/resource1.resx
Normal file
4
TestAssets/TestProjects/EndToEndTestApp/resource1.resx
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
Some content
|
||||||
|
</root>
|
4
TestAssets/TestProjects/EndToEndTestApp/resource2.resx
Normal file
4
TestAssets/TestProjects/EndToEndTestApp/resource2.resx
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
Some content
|
||||||
|
</root>
|
|
@ -6,17 +6,17 @@ using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
using Microsoft.DotNet.Cli.Compiler.Common;
|
|
||||||
using Microsoft.DotNet.Cli.Utils;
|
using Microsoft.DotNet.Cli.Utils;
|
||||||
using Microsoft.DotNet.Files;
|
using Microsoft.DotNet.Files;
|
||||||
using Microsoft.DotNet.ProjectModel;
|
using Microsoft.DotNet.ProjectModel;
|
||||||
using Microsoft.DotNet.ProjectModel.Compilation;
|
using Microsoft.DotNet.ProjectModel.Compilation;
|
||||||
|
using Microsoft.DotNet.ProjectModel.Files;
|
||||||
using Microsoft.DotNet.ProjectModel.Graph;
|
using Microsoft.DotNet.ProjectModel.Graph;
|
||||||
|
using Microsoft.DotNet.Tools.Common;
|
||||||
using Microsoft.Extensions.DependencyModel;
|
using Microsoft.Extensions.DependencyModel;
|
||||||
using NuGet.Frameworks;
|
using NuGet.Frameworks;
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System.Reflection.PortableExecutable;
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
namespace Microsoft.DotNet.Cli.Compiler.Common
|
namespace Microsoft.DotNet.Cli.Compiler.Common
|
||||||
{
|
{
|
||||||
|
@ -88,8 +88,21 @@ namespace Microsoft.DotNet.Cli.Compiler.Common
|
||||||
private void CopyContentFiles()
|
private void CopyContentFiles()
|
||||||
{
|
{
|
||||||
var contentFiles = new ContentFiles(_context);
|
var contentFiles = new ContentFiles(_context);
|
||||||
|
|
||||||
|
if (_compilerOptions.CopyToOutputInclude != null)
|
||||||
|
{
|
||||||
|
var includeEntries = IncludeFilesResolver.GetIncludeFiles(
|
||||||
|
_compilerOptions.CopyToOutputInclude,
|
||||||
|
PathUtility.EnsureTrailingSlash(_runtimeOutputPath),
|
||||||
|
diagnostics: null);
|
||||||
|
|
||||||
|
contentFiles.StructuredCopyTo(_runtimeOutputPath, includeEntries);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
contentFiles.StructuredCopyTo(_runtimeOutputPath);
|
contentFiles.StructuredCopyTo(_runtimeOutputPath);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void CopyAssemblies(IEnumerable<LibraryExport> libraryExports)
|
private void CopyAssemblies(IEnumerable<LibraryExport> libraryExports)
|
||||||
{
|
{
|
||||||
|
|
|
@ -22,7 +22,7 @@ namespace Microsoft.DotNet.Cli.Compiler.Common
|
||||||
var baseOption = context.ProjectFile.GetCompilerOptions(framework, configurationName);
|
var baseOption = context.ProjectFile.GetCompilerOptions(framework, configurationName);
|
||||||
|
|
||||||
IReadOnlyList<string> defaultSuppresses;
|
IReadOnlyList<string> defaultSuppresses;
|
||||||
var compilerName = context.ProjectFile.CompilerName ?? "csc";
|
var compilerName = baseOption.CompilerName ?? "csc";
|
||||||
if (DefaultCompilerWarningSuppresses.Suppresses.TryGetValue(compilerName, out defaultSuppresses))
|
if (DefaultCompilerWarningSuppresses.Suppresses.TryGetValue(compilerName, out defaultSuppresses))
|
||||||
{
|
{
|
||||||
baseOption.SuppressWarnings = (baseOption.SuppressWarnings ?? Enumerable.Empty<string>()).Concat(defaultSuppresses).Distinct();
|
baseOption.SuppressWarnings = (baseOption.SuppressWarnings ?? Enumerable.Empty<string>()).Concat(defaultSuppresses).Distinct();
|
||||||
|
@ -46,22 +46,22 @@ namespace Microsoft.DotNet.Cli.Compiler.Common
|
||||||
// used in incremental compilation for the key file
|
// used in incremental compilation for the key file
|
||||||
public static CommonCompilerOptions ResolveCompilationOptions(this ProjectContext context, string configuration)
|
public static CommonCompilerOptions ResolveCompilationOptions(this ProjectContext context, string configuration)
|
||||||
{
|
{
|
||||||
var compilationOptions = context.GetLanguageSpecificCompilerOptions(context.TargetFramework, configuration);
|
var compilerOptions = context.GetLanguageSpecificCompilerOptions(context.TargetFramework, configuration);
|
||||||
|
|
||||||
// Path to strong naming key in environment variable overrides path in project.json
|
// Path to strong naming key in environment variable overrides path in project.json
|
||||||
var environmentKeyFile = Environment.GetEnvironmentVariable(EnvironmentNames.StrongNameKeyFile);
|
var environmentKeyFile = Environment.GetEnvironmentVariable(EnvironmentNames.StrongNameKeyFile);
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(environmentKeyFile))
|
if (!string.IsNullOrWhiteSpace(environmentKeyFile))
|
||||||
{
|
{
|
||||||
compilationOptions.KeyFile = environmentKeyFile;
|
compilerOptions.KeyFile = environmentKeyFile;
|
||||||
}
|
}
|
||||||
else if (!string.IsNullOrWhiteSpace(compilationOptions.KeyFile))
|
else if (!string.IsNullOrWhiteSpace(compilerOptions.KeyFile))
|
||||||
{
|
{
|
||||||
// Resolve full path to key file
|
// Resolve full path to key file
|
||||||
compilationOptions.KeyFile =
|
compilerOptions.KeyFile =
|
||||||
Path.GetFullPath(Path.Combine(context.ProjectFile.ProjectDirectory, compilationOptions.KeyFile));
|
Path.GetFullPath(Path.Combine(context.ProjectFile.ProjectDirectory, compilerOptions.KeyFile));
|
||||||
}
|
}
|
||||||
return compilationOptions;
|
return compilerOptions;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Microsoft.DotNet.ProjectModel;
|
using Microsoft.DotNet.ProjectModel;
|
||||||
|
using Microsoft.DotNet.ProjectModel.Files;
|
||||||
using Microsoft.DotNet.Tools.Common;
|
using Microsoft.DotNet.Tools.Common;
|
||||||
|
|
||||||
namespace Microsoft.DotNet.Files
|
namespace Microsoft.DotNet.Files
|
||||||
|
@ -60,6 +61,29 @@ namespace Microsoft.DotNet.Files
|
||||||
RemoveAttributeFromFiles(pathMap.Values, FileAttributes.ReadOnly);
|
RemoveAttributeFromFiles(pathMap.Values, FileAttributes.ReadOnly);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void StructuredCopyTo(string targetDirectory, IEnumerable<IncludeEntry> includeEntries)
|
||||||
|
{
|
||||||
|
if (includeEntries == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var targetDir in includeEntries
|
||||||
|
.Select(f => Path.GetDirectoryName(f.TargetPath))
|
||||||
|
.Distinct()
|
||||||
|
.Where(t => !Directory.Exists(t)))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(targetDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var file in includeEntries)
|
||||||
|
{
|
||||||
|
File.Copy(file.SourcePath, file.TargetPath, overwrite: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
RemoveAttributeFromFiles(includeEntries.Select(f => f.TargetPath), FileAttributes.ReadOnly);
|
||||||
|
}
|
||||||
|
|
||||||
private static void RemoveAttributeFromFiles(IEnumerable<string> files, FileAttributes attribute)
|
private static void RemoveAttributeFromFiles(IEnumerable<string> files, FileAttributes attribute)
|
||||||
{
|
{
|
||||||
foreach (var file in files)
|
foreach (var file in files)
|
||||||
|
|
|
@ -13,6 +13,7 @@ using Microsoft.CodeAnalysis.Host.Mef;
|
||||||
using Microsoft.CodeAnalysis.Text;
|
using Microsoft.CodeAnalysis.Text;
|
||||||
using Microsoft.DotNet.Cli.Compiler.Common;
|
using Microsoft.DotNet.Cli.Compiler.Common;
|
||||||
using Microsoft.DotNet.ProjectModel.Compilation;
|
using Microsoft.DotNet.ProjectModel.Compilation;
|
||||||
|
using Microsoft.DotNet.ProjectModel.Files;
|
||||||
using Microsoft.Extensions.PlatformAbstractions;
|
using Microsoft.Extensions.PlatformAbstractions;
|
||||||
using NuGet.Frameworks;
|
using NuGet.Frameworks;
|
||||||
|
|
||||||
|
@ -69,15 +70,26 @@ namespace Microsoft.DotNet.ProjectModel.Workspaces
|
||||||
// TODO: ctor argument?
|
// TODO: ctor argument?
|
||||||
var configuration = "Debug";
|
var configuration = "Debug";
|
||||||
|
|
||||||
var compilationOptions = project.GetLanguageSpecificCompilerOptions(project.TargetFramework, configuration);
|
var compilerOptions = project.GetLanguageSpecificCompilerOptions(project.TargetFramework, configuration);
|
||||||
|
|
||||||
var compilationSettings = ToCompilationSettings(compilationOptions, project.TargetFramework, project.ProjectFile.ProjectDirectory);
|
var compilationSettings = ToCompilationSettings(compilerOptions, project.TargetFramework, project.ProjectFile.ProjectDirectory);
|
||||||
|
|
||||||
OnParseOptionsChanged(projectInfo.Id, new CSharpParseOptions(compilationSettings.LanguageVersion, preprocessorSymbols: compilationSettings.Defines));
|
OnParseOptionsChanged(projectInfo.Id, new CSharpParseOptions(compilationSettings.LanguageVersion, preprocessorSymbols: compilationSettings.Defines));
|
||||||
|
|
||||||
OnCompilationOptionsChanged(projectInfo.Id, compilationSettings.CompilationOptions);
|
OnCompilationOptionsChanged(projectInfo.Id, compilationSettings.CompilationOptions);
|
||||||
|
|
||||||
foreach (var file in project.ProjectFile.Files.SourceFiles)
|
IEnumerable<string> sourceFiles = null;
|
||||||
|
if (compilerOptions.CompileInclude == null)
|
||||||
|
{
|
||||||
|
sourceFiles = project.ProjectFile.Files.SourceFiles;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var includeFiles = IncludeFilesResolver.GetIncludeFiles(compilerOptions.CompileInclude, "/", diagnostics: null);
|
||||||
|
sourceFiles = includeFiles.Select(f => f.SourcePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var file in sourceFiles)
|
||||||
{
|
{
|
||||||
using (var stream = File.OpenRead(file))
|
using (var stream = File.OpenRead(file))
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
// 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.
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Microsoft.DotNet.ProjectModel.Files;
|
||||||
|
|
||||||
namespace Microsoft.DotNet.ProjectModel
|
namespace Microsoft.DotNet.ProjectModel
|
||||||
{
|
{
|
||||||
|
@ -39,7 +39,15 @@ namespace Microsoft.DotNet.ProjectModel
|
||||||
|
|
||||||
public IEnumerable<string> AdditionalArguments { get; set; }
|
public IEnumerable<string> AdditionalArguments { get; set; }
|
||||||
|
|
||||||
public string OutputName { get;set; }
|
public string OutputName { get; set; }
|
||||||
|
|
||||||
|
public string CompilerName { get; set; }
|
||||||
|
|
||||||
|
public IncludeContext CompileInclude { get; set; }
|
||||||
|
|
||||||
|
public IncludeContext EmbedInclude { get; set; }
|
||||||
|
|
||||||
|
public IncludeContext CopyToOutputInclude { get; set; }
|
||||||
|
|
||||||
public override bool Equals(object obj)
|
public override bool Equals(object obj)
|
||||||
{
|
{
|
||||||
|
@ -60,7 +68,21 @@ namespace Microsoft.DotNet.ProjectModel
|
||||||
EnumerableEquals(Defines, other.Defines) &&
|
EnumerableEquals(Defines, other.Defines) &&
|
||||||
EnumerableEquals(SuppressWarnings, other.SuppressWarnings) &&
|
EnumerableEquals(SuppressWarnings, other.SuppressWarnings) &&
|
||||||
EnumerableEquals(AdditionalArguments, other.AdditionalArguments) &&
|
EnumerableEquals(AdditionalArguments, other.AdditionalArguments) &&
|
||||||
OutputName == other.OutputName;
|
OutputName == other.OutputName &&
|
||||||
|
CompilerName == other.CompilerName &&
|
||||||
|
IsEqual(CompileInclude, other.CompileInclude) &&
|
||||||
|
IsEqual(EmbedInclude, other.EmbedInclude) &&
|
||||||
|
IsEqual(CopyToOutputInclude, other.CopyToOutputInclude);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsEqual(IncludeContext first, IncludeContext second)
|
||||||
|
{
|
||||||
|
if (first == null || second == null)
|
||||||
|
{
|
||||||
|
return first == second;
|
||||||
|
}
|
||||||
|
|
||||||
|
return first.Equals(second);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool EnumerableEquals(IEnumerable<string> left, IEnumerable<string> right)
|
private static bool EnumerableEquals(IEnumerable<string> left, IEnumerable<string> right)
|
||||||
|
@ -161,6 +183,27 @@ namespace Microsoft.DotNet.ProjectModel
|
||||||
{
|
{
|
||||||
result.OutputName = option.OutputName;
|
result.OutputName = option.OutputName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (option.CompileInclude != null)
|
||||||
|
{
|
||||||
|
result.CompileInclude = option.CompileInclude;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (option.EmbedInclude != null)
|
||||||
|
{
|
||||||
|
result.EmbedInclude = option.EmbedInclude;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (option.CopyToOutputInclude != null)
|
||||||
|
{
|
||||||
|
result.CopyToOutputInclude = option.CopyToOutputInclude;
|
||||||
|
}
|
||||||
|
|
||||||
|
// compilerName set in the root cannot be overriden.
|
||||||
|
if (result.CompilerName == null)
|
||||||
|
{
|
||||||
|
result.CompilerName = option.CompilerName;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -279,6 +279,7 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
|
||||||
private LibraryExport ExportProject(ProjectDescription project)
|
private LibraryExport ExportProject(ProjectDescription project)
|
||||||
{
|
{
|
||||||
var builder = LibraryExportBuilder.Create(project);
|
var builder = LibraryExportBuilder.Create(project);
|
||||||
|
var compilerOptions = project.Project.GetCompilerOptions(project.TargetFrameworkInfo.FrameworkName, _configuration);
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(project.TargetFrameworkInfo?.AssemblyPath))
|
if (!string.IsNullOrEmpty(project.TargetFrameworkInfo?.AssemblyPath))
|
||||||
{
|
{
|
||||||
|
@ -298,7 +299,7 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
|
||||||
builder.AddRuntimeAsset(new LibraryAsset(Path.GetFileName(pdbPath), Path.GetFileName(pdbPath), pdbPath));
|
builder.AddRuntimeAsset(new LibraryAsset(Path.GetFileName(pdbPath), Path.GetFileName(pdbPath), pdbPath));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (project.Project.Files.SourceFiles.Any())
|
else if (HasSourceFiles(project))
|
||||||
{
|
{
|
||||||
var outputPaths = project.GetOutputPaths(_buildBasePath, _solutionRootPath, _configuration, _runtime);
|
var outputPaths = project.GetOutputPaths(_buildBasePath, _solutionRootPath, _configuration, _runtime);
|
||||||
|
|
||||||
|
@ -336,6 +337,20 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
|
||||||
return builder.Build();
|
return builder.Build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool HasSourceFiles(ProjectDescription project)
|
||||||
|
{
|
||||||
|
var compilerOptions = project.TargetFrameworkInfo.CompilerOptions;
|
||||||
|
|
||||||
|
if (compilerOptions.CompileInclude == null)
|
||||||
|
{
|
||||||
|
return project.Project.Files.SourceFiles.Any();
|
||||||
|
}
|
||||||
|
|
||||||
|
var includeFiles = IncludeFilesResolver.GetIncludeFiles(compilerOptions.CompileInclude, "/", diagnostics: null);
|
||||||
|
|
||||||
|
return includeFiles.Any();
|
||||||
|
}
|
||||||
|
|
||||||
private IEnumerable<LibraryAsset> CollectAssets(CompilationOutputFiles files)
|
private IEnumerable<LibraryAsset> CollectAssets(CompilationOutputFiles files)
|
||||||
{
|
{
|
||||||
var assemblyPath = files.Assembly;
|
var assemblyPath = files.Assembly;
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Microsoft.DotNet.ProjectModel.Files;
|
||||||
using Microsoft.DotNet.ProjectModel.Resources;
|
using Microsoft.DotNet.ProjectModel.Resources;
|
||||||
using NuGet.Frameworks;
|
using NuGet.Frameworks;
|
||||||
|
|
||||||
|
@ -27,8 +28,8 @@ namespace Microsoft.DotNet.ProjectModel
|
||||||
Framework = framework;
|
Framework = framework;
|
||||||
OutputExtension = FileNameSuffixes.DotNet.DynamicLib;
|
OutputExtension = FileNameSuffixes.DotNet.DynamicLib;
|
||||||
|
|
||||||
var compilationOptions = Project.GetCompilerOptions(framework, configuration);
|
var compilerOptions = Project.GetCompilerOptions(framework, configuration);
|
||||||
if (framework.IsDesktop() && compilationOptions.EmitEntryPoint.GetValueOrDefault())
|
if (framework.IsDesktop() && compilerOptions.EmitEntryPoint.GetValueOrDefault())
|
||||||
{
|
{
|
||||||
OutputExtension = FileNameSuffixes.DotNet.Exe;
|
OutputExtension = FileNameSuffixes.DotNet.Exe;
|
||||||
}
|
}
|
||||||
|
@ -40,9 +41,9 @@ namespace Microsoft.DotNet.ProjectModel
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
var compilationOptions = Project.GetCompilerOptions(Framework, Configuration);
|
var compilerOptions = Project.GetCompilerOptions(Framework, Configuration);
|
||||||
|
|
||||||
return Path.Combine(BasePath, compilationOptions.OutputName + OutputExtension);
|
return Path.Combine(BasePath, compilerOptions.OutputName + OutputExtension);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,14 +59,17 @@ namespace Microsoft.DotNet.ProjectModel
|
||||||
|
|
||||||
public virtual IEnumerable<ResourceFile> Resources()
|
public virtual IEnumerable<ResourceFile> Resources()
|
||||||
{
|
{
|
||||||
var resourceNames = Project.Files.ResourceFiles
|
var resourceCultureNames = GetResourceFiles()
|
||||||
.Select(f => ResourceUtility.GetResourceCultureName(f.Key))
|
.Select(f => ResourceUtility.GetResourceCultureName(f))
|
||||||
.Where(f => !string.IsNullOrEmpty(f))
|
.Where(f => !string.IsNullOrEmpty(f))
|
||||||
.Distinct();
|
.Distinct();
|
||||||
|
|
||||||
foreach (var resourceName in resourceNames)
|
foreach (var resourceCultureName in resourceCultureNames)
|
||||||
{
|
{
|
||||||
yield return new ResourceFile(Path.Combine(BasePath, resourceName, Project.Name + ".resources" + FileNameSuffixes.DotNet.DynamicLib), resourceName);
|
yield return new ResourceFile(
|
||||||
|
Path.Combine(
|
||||||
|
BasePath, resourceCultureName, Project.Name + ".resources" + FileNameSuffixes.DotNet.DynamicLib),
|
||||||
|
resourceCultureName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,8 +77,8 @@ namespace Microsoft.DotNet.ProjectModel
|
||||||
{
|
{
|
||||||
yield return Assembly;
|
yield return Assembly;
|
||||||
yield return PdbPath;
|
yield return PdbPath;
|
||||||
var compilationOptions = Project.GetCompilerOptions(Framework, Configuration);
|
var compilerOptions = Project.GetCompilerOptions(Framework, Configuration);
|
||||||
if (compilationOptions.GenerateXmlDocumentation == true)
|
if (compilerOptions.GenerateXmlDocumentation == true)
|
||||||
{
|
{
|
||||||
yield return Path.ChangeExtension(Assembly, "xml");
|
yield return Path.ChangeExtension(Assembly, "xml");
|
||||||
}
|
}
|
||||||
|
@ -83,5 +87,18 @@ namespace Microsoft.DotNet.ProjectModel
|
||||||
yield return resource.Path;
|
yield return resource.Path;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IEnumerable<string> GetResourceFiles()
|
||||||
|
{
|
||||||
|
var compilerOptions = Project.GetCompilerOptions(Framework, Configuration);
|
||||||
|
if (compilerOptions.EmbedInclude == null)
|
||||||
|
{
|
||||||
|
return Project.Files.ResourceFiles.Keys;
|
||||||
|
}
|
||||||
|
|
||||||
|
var includeFiles = IncludeFilesResolver.GetIncludeFiles(compilerOptions.EmbedInclude, "/", diagnostics: null);
|
||||||
|
|
||||||
|
return includeFiles.Select(f => f.SourcePath);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -16,5 +16,11 @@ namespace Microsoft.DotNet.ProjectModel
|
||||||
|
|
||||||
// Failed to read lock file
|
// Failed to read lock file
|
||||||
public static readonly string DOTNET1014 = nameof(DOTNET1014);
|
public static readonly string DOTNET1014 = nameof(DOTNET1014);
|
||||||
|
|
||||||
|
// The '{0}' option is deprecated. Use '{1}' instead.
|
||||||
|
public static readonly string DOTNET1015 = nameof(DOTNET1015);
|
||||||
|
|
||||||
|
// The '{0}' option in the root is deprecated. Use it in '{1}' instead.
|
||||||
|
public static readonly string DOTNET1016 = nameof(DOTNET1016);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
215
src/Microsoft.DotNet.ProjectModel/Files/IncludeContext.cs
Normal file
215
src/Microsoft.DotNet.ProjectModel/Files/IncludeContext.cs
Normal file
|
@ -0,0 +1,215 @@
|
||||||
|
// 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;
|
||||||
|
using System.Linq;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
|
namespace Microsoft.DotNet.ProjectModel.Files
|
||||||
|
{
|
||||||
|
public class IncludeContext
|
||||||
|
{
|
||||||
|
private static readonly char[] PatternSeparator = new[] { ';' };
|
||||||
|
|
||||||
|
public IncludeContext(
|
||||||
|
string sourceBasePath,
|
||||||
|
string option,
|
||||||
|
JObject rawObject,
|
||||||
|
string[] defaultBuiltInInclude,
|
||||||
|
string[] defaultBuiltInExclude)
|
||||||
|
{
|
||||||
|
if (sourceBasePath == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(sourceBasePath));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (option == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(option));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rawObject == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(rawObject));
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceBasePath = sourceBasePath;
|
||||||
|
Option = option;
|
||||||
|
var token = rawObject.Value<JToken>(option);
|
||||||
|
if (token.Type != JTokenType.Object)
|
||||||
|
{
|
||||||
|
IncludePatterns = new List<string>(ExtractValues(token));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IncludePatterns = CreateCollection(
|
||||||
|
sourceBasePath, "include", ExtractValues(token.Value<JToken>("include")), literalPath: false);
|
||||||
|
|
||||||
|
ExcludePatterns = CreateCollection(
|
||||||
|
sourceBasePath, "exclude", ExtractValues(token.Value<JToken>("exclude")), literalPath: false);
|
||||||
|
|
||||||
|
IncludeFiles = CreateCollection(
|
||||||
|
sourceBasePath, "includeFiles", ExtractValues(token.Value<JToken>("includeFiles")), literalPath: true);
|
||||||
|
|
||||||
|
ExcludeFiles = CreateCollection(
|
||||||
|
sourceBasePath, "excludeFiles", ExtractValues(token.Value<JToken>("excludeFiles")), literalPath: true);
|
||||||
|
|
||||||
|
var builtIns = token.Value<JToken>("builtIns") as JObject;
|
||||||
|
if (builtIns != null)
|
||||||
|
{
|
||||||
|
BuiltInsInclude = CreateCollection(
|
||||||
|
sourceBasePath, "include", ExtractValues(builtIns.Value<JToken>("include")), literalPath: false);
|
||||||
|
|
||||||
|
if (defaultBuiltInInclude != null && !BuiltInsInclude.Any())
|
||||||
|
{
|
||||||
|
BuiltInsInclude = defaultBuiltInInclude.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
BuiltInsExclude = CreateCollection(
|
||||||
|
sourceBasePath, "exclude", ExtractValues(builtIns.Value<JToken>("exclude")), literalPath: false);
|
||||||
|
|
||||||
|
if (defaultBuiltInExclude != null && !BuiltInsExclude.Any())
|
||||||
|
{
|
||||||
|
BuiltInsExclude = defaultBuiltInExclude.ToList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var mappings = token.Value<JToken>("mappings") as JObject;
|
||||||
|
if (mappings != null)
|
||||||
|
{
|
||||||
|
Mappings = new Dictionary<string, IncludeContext>();
|
||||||
|
|
||||||
|
foreach (var map in mappings)
|
||||||
|
{
|
||||||
|
Mappings.Add(
|
||||||
|
map.Key,
|
||||||
|
new IncludeContext(
|
||||||
|
sourceBasePath,
|
||||||
|
map.Key,
|
||||||
|
mappings,
|
||||||
|
defaultBuiltInInclude: null,
|
||||||
|
defaultBuiltInExclude: null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string SourceBasePath { get; }
|
||||||
|
|
||||||
|
public string Option { get; }
|
||||||
|
|
||||||
|
public List<string> IncludePatterns { get; }
|
||||||
|
|
||||||
|
public List<string> ExcludePatterns { get; }
|
||||||
|
|
||||||
|
public List<string> IncludeFiles { get; }
|
||||||
|
|
||||||
|
public List<string> ExcludeFiles { get; }
|
||||||
|
|
||||||
|
public List<string> BuiltInsInclude { get; }
|
||||||
|
|
||||||
|
public List<string> BuiltInsExclude { get; }
|
||||||
|
|
||||||
|
public IDictionary<string, IncludeContext> Mappings { get; }
|
||||||
|
|
||||||
|
public override bool Equals(object obj)
|
||||||
|
{
|
||||||
|
var other = obj as IncludeContext;
|
||||||
|
return other != null &&
|
||||||
|
SourceBasePath == other.SourceBasePath &&
|
||||||
|
Option == other.Option &&
|
||||||
|
EnumerableEquals(IncludePatterns, other.IncludePatterns) &&
|
||||||
|
EnumerableEquals(ExcludePatterns, other.ExcludePatterns) &&
|
||||||
|
EnumerableEquals(IncludeFiles, other.IncludeFiles) &&
|
||||||
|
EnumerableEquals(ExcludeFiles, other.ExcludeFiles) &&
|
||||||
|
EnumerableEquals(BuiltInsInclude, other.BuiltInsInclude) &&
|
||||||
|
EnumerableEquals(BuiltInsExclude, other.BuiltInsExclude) &&
|
||||||
|
EnumerableEquals(Mappings, other.Mappings);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
return base.GetHashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool EnumerableEquals<T>(IEnumerable<T> left, IEnumerable<T> right)
|
||||||
|
=> Enumerable.SequenceEqual(left ?? EmptyArray<T>.Value, right ?? EmptyArray<T>.Value);
|
||||||
|
|
||||||
|
private static string[] ExtractValues(JToken token)
|
||||||
|
{
|
||||||
|
if (token != null)
|
||||||
|
{
|
||||||
|
if (token.Type == JTokenType.String)
|
||||||
|
{
|
||||||
|
return new string[] { token.Value<string>() };
|
||||||
|
}
|
||||||
|
else if (token.Type == JTokenType.Array)
|
||||||
|
{
|
||||||
|
return token.Values<string>().ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new string[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static List<string> CreateCollection(
|
||||||
|
string projectDirectory,
|
||||||
|
string propertyName,
|
||||||
|
IEnumerable<string> patternsStrings,
|
||||||
|
bool literalPath)
|
||||||
|
{
|
||||||
|
var patterns = patternsStrings
|
||||||
|
.SelectMany(patternsString => GetSourcesSplit(patternsString))
|
||||||
|
.Select(patternString =>
|
||||||
|
patternString.Replace('/', Path.DirectorySeparatorChar).Replace('\\', Path.DirectorySeparatorChar));
|
||||||
|
|
||||||
|
foreach (var pattern in patterns)
|
||||||
|
{
|
||||||
|
if (Path.IsPathRooted(pattern))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException($"The '{propertyName}' property cannot be a rooted path.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (literalPath && pattern.Contains('*'))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException($"The '{propertyName}' property cannot contain wildcard characters.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new List<string>(patterns.Select(pattern => FolderToPattern(pattern, projectDirectory)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IEnumerable<string> GetSourcesSplit(string sourceDescription)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(sourceDescription))
|
||||||
|
{
|
||||||
|
return Enumerable.Empty<string>();
|
||||||
|
}
|
||||||
|
|
||||||
|
return sourceDescription.Split(PatternSeparator, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string FolderToPattern(string candidate, string projectDir)
|
||||||
|
{
|
||||||
|
// If it's already a pattern, no change is needed
|
||||||
|
if (candidate.Contains('*'))
|
||||||
|
{
|
||||||
|
return candidate;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the given string ends with a path separator, or it is an existing directory
|
||||||
|
// we convert this folder name to a pattern matching all files in the folder
|
||||||
|
if (candidate.EndsWith(@"\") ||
|
||||||
|
candidate.EndsWith("/") ||
|
||||||
|
Directory.Exists(Path.Combine(projectDir, candidate)))
|
||||||
|
{
|
||||||
|
return Path.Combine(candidate, "**", "*");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, it represents a single file
|
||||||
|
return candidate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
45
src/Microsoft.DotNet.ProjectModel/Files/IncludeEntry.cs
Normal file
45
src/Microsoft.DotNet.ProjectModel/Files/IncludeEntry.cs
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
// 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 Microsoft.Extensions.Internal;
|
||||||
|
|
||||||
|
namespace Microsoft.DotNet.ProjectModel.Files
|
||||||
|
{
|
||||||
|
public class IncludeEntry : IEquatable<IncludeEntry>
|
||||||
|
{
|
||||||
|
public string TargetPath { get; }
|
||||||
|
|
||||||
|
public string SourcePath { get; }
|
||||||
|
|
||||||
|
public bool IsCustomTarget { get; set; }
|
||||||
|
|
||||||
|
public IncludeEntry(string target, string source)
|
||||||
|
{
|
||||||
|
TargetPath = target;
|
||||||
|
SourcePath = source;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Equals(object obj)
|
||||||
|
{
|
||||||
|
return Equals((IncludeEntry)obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
var combiner = HashCodeCombiner.Start();
|
||||||
|
combiner.Add(TargetPath);
|
||||||
|
combiner.Add(SourcePath);
|
||||||
|
|
||||||
|
return combiner.CombinedHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Equals(IncludeEntry other)
|
||||||
|
{
|
||||||
|
return other != null &&
|
||||||
|
string.Equals(TargetPath, other.TargetPath, StringComparison.Ordinal) &&
|
||||||
|
string.Equals(SourcePath, other.SourcePath, StringComparison.Ordinal) &&
|
||||||
|
IsCustomTarget == other.IsCustomTarget;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
182
src/Microsoft.DotNet.ProjectModel/Files/IncludeFilesResolver.cs
Normal file
182
src/Microsoft.DotNet.ProjectModel/Files/IncludeFilesResolver.cs
Normal file
|
@ -0,0 +1,182 @@
|
||||||
|
// 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;
|
||||||
|
using System.Linq;
|
||||||
|
using Microsoft.DotNet.ProjectModel.Utilities;
|
||||||
|
using Microsoft.Extensions.FileSystemGlobbing;
|
||||||
|
|
||||||
|
namespace Microsoft.DotNet.ProjectModel.Files
|
||||||
|
{
|
||||||
|
public class IncludeFilesResolver
|
||||||
|
{
|
||||||
|
public static IEnumerable<IncludeEntry> GetIncludeFiles(IncludeContext context, string targetBasePath, IList<DiagnosticMessage> diagnostics)
|
||||||
|
{
|
||||||
|
return GetIncludeFiles(context, targetBasePath, diagnostics, flatten: false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<IncludeEntry> GetIncludeFiles(
|
||||||
|
IncludeContext context,
|
||||||
|
string targetBasePath,
|
||||||
|
IList<DiagnosticMessage> diagnostics,
|
||||||
|
bool flatten)
|
||||||
|
{
|
||||||
|
var sourceBasePath = PathUtility.EnsureTrailingSlash(context.SourceBasePath);
|
||||||
|
targetBasePath = PathUtility.GetPathWithDirectorySeparator(targetBasePath);
|
||||||
|
|
||||||
|
var includeEntries = new HashSet<IncludeEntry>();
|
||||||
|
|
||||||
|
// Check for illegal characters in target path
|
||||||
|
if (string.IsNullOrEmpty(targetBasePath))
|
||||||
|
{
|
||||||
|
diagnostics?.Add(new DiagnosticMessage(
|
||||||
|
ErrorCodes.NU1003,
|
||||||
|
$"Invalid '{context.Option}' section. The target '{targetBasePath}' is invalid, " +
|
||||||
|
"targets must either be a file name or a directory suffixed with '/'. " +
|
||||||
|
"The root directory of the package can be specified by using a single '/' character.",
|
||||||
|
sourceBasePath,
|
||||||
|
DiagnosticMessageSeverity.Error));
|
||||||
|
}
|
||||||
|
else if (targetBasePath.Split('/').Any(s => s.Equals(".") || s.Equals("..")))
|
||||||
|
{
|
||||||
|
diagnostics?.Add(new DiagnosticMessage(
|
||||||
|
ErrorCodes.NU1004,
|
||||||
|
$"Invalid '{context.Option}' section. " +
|
||||||
|
$"The target '{targetBasePath}' contains path-traversal characters ('.' or '..'). " +
|
||||||
|
"These characters are not permitted in target paths.",
|
||||||
|
sourceBasePath,
|
||||||
|
DiagnosticMessageSeverity.Error));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var files = GetIncludeFilesCore(
|
||||||
|
sourceBasePath,
|
||||||
|
context.IncludePatterns,
|
||||||
|
context.ExcludePatterns,
|
||||||
|
context.IncludeFiles,
|
||||||
|
context.ExcludeFiles,
|
||||||
|
context.BuiltInsInclude,
|
||||||
|
context.BuiltInsExclude);
|
||||||
|
|
||||||
|
var isFile = targetBasePath[targetBasePath.Length - 1] != Path.DirectorySeparatorChar;
|
||||||
|
if (isFile && files.Count() > 1)
|
||||||
|
{
|
||||||
|
// It's a file. But the glob matched multiple things
|
||||||
|
diagnostics?.Add(new DiagnosticMessage(
|
||||||
|
ErrorCodes.NU1005,
|
||||||
|
$"Invalid '{ProjectFilesCollection.PackIncludePropertyName}' section. " +
|
||||||
|
$"The target '{targetBasePath}' refers to a single file, but the corresponding pattern " +
|
||||||
|
"produces multiple files. To mark the target as a directory, suffix it with '/'.",
|
||||||
|
sourceBasePath,
|
||||||
|
DiagnosticMessageSeverity.Error));
|
||||||
|
}
|
||||||
|
else if (isFile && files.Any())
|
||||||
|
{
|
||||||
|
includeEntries.Add(new IncludeEntry(targetBasePath, files.First()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
targetBasePath = targetBasePath.Substring(0, targetBasePath.Length - 1);
|
||||||
|
|
||||||
|
foreach (var file in files)
|
||||||
|
{
|
||||||
|
string targetPath = null;
|
||||||
|
|
||||||
|
if (flatten)
|
||||||
|
{
|
||||||
|
targetPath = Path.Combine(targetBasePath, Path.GetFileName(file));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
targetPath = Path.Combine(targetBasePath, PathUtility.GetRelativePath(sourceBasePath, file));
|
||||||
|
}
|
||||||
|
|
||||||
|
includeEntries.Add(new IncludeEntry(targetPath, file));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (context.Mappings != null)
|
||||||
|
{
|
||||||
|
// Finally add all the mappings
|
||||||
|
foreach (var map in context.Mappings)
|
||||||
|
{
|
||||||
|
var targetPath = Path.Combine(targetBasePath, PathUtility.GetPathWithDirectorySeparator(map.Key));
|
||||||
|
|
||||||
|
foreach (var file in GetIncludeFiles(map.Value, targetPath, diagnostics, flatten))
|
||||||
|
{
|
||||||
|
file.IsCustomTarget = true;
|
||||||
|
|
||||||
|
// Prefer named targets over default ones
|
||||||
|
includeEntries.RemoveWhere(f => string.Equals(f.SourcePath, file.SourcePath));
|
||||||
|
includeEntries.Add(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return includeEntries;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IEnumerable<string> GetIncludeFilesCore(
|
||||||
|
string sourceBasePath,
|
||||||
|
List<string> includePatterns,
|
||||||
|
List<string> excludePatterns,
|
||||||
|
List<string> includeFiles,
|
||||||
|
List<string> excludeFiles,
|
||||||
|
List<string> builtInsInclude,
|
||||||
|
List<string> builtInsExclude)
|
||||||
|
{
|
||||||
|
var literalIncludedFiles = new List<string>();
|
||||||
|
|
||||||
|
if (includeFiles != null)
|
||||||
|
{
|
||||||
|
// literal included files are added at the last, but the search happens early
|
||||||
|
// so as to make the process fail early in case there is missing file. fail early
|
||||||
|
// helps to avoid unnecessary globing for performance optimization
|
||||||
|
foreach (var literalRelativePath in includeFiles)
|
||||||
|
{
|
||||||
|
var fullPath = Path.GetFullPath(Path.Combine(sourceBasePath, literalRelativePath));
|
||||||
|
|
||||||
|
if (!File.Exists(fullPath))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException(string.Format("Can't find file {0}", literalRelativePath));
|
||||||
|
}
|
||||||
|
|
||||||
|
literalIncludedFiles.Add(fullPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Globbing
|
||||||
|
var matcher = new Matcher();
|
||||||
|
if (builtInsInclude != null)
|
||||||
|
{
|
||||||
|
matcher.AddIncludePatterns(builtInsInclude);
|
||||||
|
}
|
||||||
|
if (includePatterns != null)
|
||||||
|
{
|
||||||
|
matcher.AddIncludePatterns(includePatterns);
|
||||||
|
}
|
||||||
|
if (builtInsExclude != null)
|
||||||
|
{
|
||||||
|
matcher.AddExcludePatterns(builtInsExclude);
|
||||||
|
}
|
||||||
|
if (excludePatterns != null)
|
||||||
|
{
|
||||||
|
matcher.AddExcludePatterns(excludePatterns);
|
||||||
|
}
|
||||||
|
|
||||||
|
var files = matcher.GetResultsInFullPath(sourceBasePath);
|
||||||
|
files = files.Concat(literalIncludedFiles).Distinct();
|
||||||
|
|
||||||
|
if (files.Any() && excludeFiles != null)
|
||||||
|
{
|
||||||
|
var literalExcludedFiles = excludeFiles.Select(file => Path.GetFullPath(Path.Combine(sourceBasePath, file)));
|
||||||
|
files = files.Except(literalExcludedFiles);
|
||||||
|
}
|
||||||
|
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -39,7 +39,7 @@ namespace Microsoft.DotNet.ProjectModel.Files
|
||||||
return new string[] { json.Value<string>() };
|
return new string[] { json.Value<string>() };
|
||||||
}
|
}
|
||||||
|
|
||||||
if(json.Type == JTokenType.Array)
|
if (json.Type == JTokenType.Array)
|
||||||
{
|
{
|
||||||
return json.Select(v => v.ToString()).ToArray();
|
return json.Select(v => v.ToString()).ToArray();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
// 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.
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
|
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
namespace Microsoft.DotNet.ProjectModel.Files
|
namespace Microsoft.DotNet.ProjectModel.Files
|
||||||
{
|
{
|
||||||
|
@ -27,18 +26,21 @@ namespace Microsoft.DotNet.ProjectModel.Files
|
||||||
JToken propertyNameToken;
|
JToken propertyNameToken;
|
||||||
if (!rawProject.TryGetValue(propertyName, out propertyNameToken))
|
if (!rawProject.TryGetValue(propertyName, out propertyNameToken))
|
||||||
{
|
{
|
||||||
return CreateCollection(projectDirectory, propertyName, defaultPatterns, literalPath);
|
return IncludeContext.CreateCollection(
|
||||||
|
projectDirectory, propertyName, defaultPatterns, literalPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (propertyNameToken.Type == JTokenType.String)
|
if (propertyNameToken.Type == JTokenType.String)
|
||||||
{
|
{
|
||||||
return CreateCollection(projectDirectory, propertyName, new string[] { propertyNameToken.Value<string>() }, literalPath);
|
return IncludeContext.CreateCollection(
|
||||||
|
projectDirectory, propertyName, new string[] { propertyNameToken.Value<string>() }, literalPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (propertyNameToken.Type == JTokenType.Array)
|
if (propertyNameToken.Type == JTokenType.Array)
|
||||||
{
|
{
|
||||||
var valuesInArray = propertyNameToken.Values<string>();
|
var valuesInArray = propertyNameToken.Values<string>();
|
||||||
return CreateCollection(projectDirectory, propertyName, valuesInArray.Select(s => s.ToString()), literalPath);
|
return IncludeContext.CreateCollection(
|
||||||
|
projectDirectory, propertyName, valuesInArray.Select(s => s.ToString()), literalPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
@ -48,59 +50,5 @@ namespace Microsoft.DotNet.ProjectModel.Files
|
||||||
|
|
||||||
throw FileFormatException.Create("Value must be either string or array.", rawProject.Value<JToken>(propertyName), projectFilePath);
|
throw FileFormatException.Create("Value must be either string or array.", rawProject.Value<JToken>(propertyName), projectFilePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IEnumerable<string> CreateCollection(string projectDirectory, string propertyName, IEnumerable<string> patternsStrings, bool literalPath)
|
|
||||||
{
|
|
||||||
var patterns = patternsStrings.SelectMany(patternsString => GetSourcesSplit(patternsString))
|
|
||||||
.Select(patternString => patternString.Replace('/', Path.DirectorySeparatorChar).Replace('\\', Path.DirectorySeparatorChar));
|
|
||||||
|
|
||||||
foreach (var pattern in patterns)
|
|
||||||
{
|
|
||||||
if (Path.IsPathRooted(pattern))
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException($"The '{propertyName}' property cannot be a rooted path.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (literalPath && pattern.Contains('*'))
|
|
||||||
{
|
|
||||||
throw new InvalidOperationException($"The '{propertyName}' property cannot contain wildcard characters.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new List<string>(patterns.Select(pattern => FolderToPattern(pattern, projectDirectory)));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static IEnumerable<string> GetSourcesSplit(string sourceDescription)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(sourceDescription))
|
|
||||||
{
|
|
||||||
return Enumerable.Empty<string>();
|
|
||||||
}
|
|
||||||
|
|
||||||
return sourceDescription.Split(PatternSeparator, StringSplitOptions.RemoveEmptyEntries);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string FolderToPattern(string candidate, string projectDir)
|
|
||||||
{
|
|
||||||
// This conversion is needed to support current template
|
|
||||||
|
|
||||||
// If it's already a pattern, no change is needed
|
|
||||||
if (candidate.Contains('*'))
|
|
||||||
{
|
|
||||||
return candidate;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the given string ends with a path separator, or it is an existing directory
|
|
||||||
// we convert this folder name to a pattern matching all files in the folder
|
|
||||||
if (candidate.EndsWith(@"\") ||
|
|
||||||
candidate.EndsWith("/") ||
|
|
||||||
Directory.Exists(Path.Combine(projectDir, candidate)))
|
|
||||||
{
|
|
||||||
return Path.Combine(candidate, "**", "*");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, it represents a single file
|
|
||||||
return candidate;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
// 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.
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
namespace Microsoft.DotNet.ProjectModel.Files
|
namespace Microsoft.DotNet.ProjectModel.Files
|
||||||
|
|
32
src/Microsoft.DotNet.ProjectModel/PackOptions.cs
Normal file
32
src/Microsoft.DotNet.ProjectModel/PackOptions.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 Microsoft.DotNet.ProjectModel.Files;
|
||||||
|
|
||||||
|
namespace Microsoft.DotNet.ProjectModel
|
||||||
|
{
|
||||||
|
public class PackOptions
|
||||||
|
{
|
||||||
|
public string[] Tags { get; set; }
|
||||||
|
|
||||||
|
public string[] Owners { get; set; }
|
||||||
|
|
||||||
|
public string ReleaseNotes { get; set; }
|
||||||
|
|
||||||
|
public string IconUrl { get; set; }
|
||||||
|
|
||||||
|
public string ProjectUrl { get; set; }
|
||||||
|
|
||||||
|
public string LicenseUrl { get; set; }
|
||||||
|
|
||||||
|
public bool RequireLicenseAcceptance { get; set; }
|
||||||
|
|
||||||
|
public string RepositoryType { get; set; }
|
||||||
|
|
||||||
|
public string RepositoryUrl { get; set; }
|
||||||
|
|
||||||
|
public string Summary { get; set; }
|
||||||
|
|
||||||
|
public IncludeContext PackInclude { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,7 +4,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
|
||||||
using Microsoft.DotNet.ProjectModel.Files;
|
using Microsoft.DotNet.ProjectModel.Files;
|
||||||
using Microsoft.DotNet.ProjectModel.Graph;
|
using Microsoft.DotNet.ProjectModel.Graph;
|
||||||
using NuGet.Frameworks;
|
using NuGet.Frameworks;
|
||||||
|
@ -47,16 +46,10 @@ namespace Microsoft.DotNet.ProjectModel
|
||||||
|
|
||||||
public string Copyright { get; set; }
|
public string Copyright { get; set; }
|
||||||
|
|
||||||
public string Summary { get; set; }
|
|
||||||
|
|
||||||
public string Language { get; set; }
|
public string Language { get; set; }
|
||||||
|
|
||||||
public string ReleaseNotes { get; set; }
|
|
||||||
|
|
||||||
public string[] Authors { get; set; }
|
public string[] Authors { get; set; }
|
||||||
|
|
||||||
public string[] Owners { get; set; }
|
|
||||||
|
|
||||||
public bool EmbedInteropTypes { get; set; }
|
public bool EmbedInteropTypes { get; set; }
|
||||||
|
|
||||||
public NuGetVersion Version { get; set; }
|
public NuGetVersion Version { get; set; }
|
||||||
|
@ -69,28 +62,24 @@ namespace Microsoft.DotNet.ProjectModel
|
||||||
|
|
||||||
public string EntryPoint { get; set; }
|
public string EntryPoint { get; set; }
|
||||||
|
|
||||||
public string ProjectUrl { get; set; }
|
|
||||||
|
|
||||||
public string LicenseUrl { get; set; }
|
|
||||||
|
|
||||||
public string IconUrl { get; set; }
|
|
||||||
|
|
||||||
public bool RequireLicenseAcceptance { get; set; }
|
|
||||||
|
|
||||||
public string[] Tags { get; set; }
|
|
||||||
|
|
||||||
public string CompilerName { get; set; }
|
|
||||||
|
|
||||||
public string TestRunner { get; set; }
|
public string TestRunner { get; set; }
|
||||||
|
|
||||||
public ProjectFilesCollection Files { get; set; }
|
public ProjectFilesCollection Files { get; set; }
|
||||||
|
|
||||||
|
public PackOptions PackOptions { get; set; }
|
||||||
|
|
||||||
|
public RuntimeOptions RuntimeOptions { get; set; }
|
||||||
|
|
||||||
public IDictionary<string, string> Commands { get; } = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
public IDictionary<string, string> Commands { get; } = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
public IDictionary<string, IEnumerable<string>> Scripts { get; } = new Dictionary<string, IEnumerable<string>>(StringComparer.OrdinalIgnoreCase);
|
public IDictionary<string, IEnumerable<string>> Scripts { get; } = new Dictionary<string, IEnumerable<string>>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
public string RawRuntimeOptions { get; set; }
|
public string RawRuntimeOptions { get; set; }
|
||||||
|
|
||||||
|
public IncludeContext PublishOptions { get; set; }
|
||||||
|
|
||||||
|
public List<DiagnosticMessage> Diagnostics { get; } = new List<DiagnosticMessage>();
|
||||||
|
|
||||||
public bool IsTestProject => !string.IsNullOrEmpty(TestRunner);
|
public bool IsTestProject => !string.IsNullOrEmpty(TestRunner);
|
||||||
|
|
||||||
public IEnumerable<TargetFrameworkInformation> GetTargetFrameworks()
|
public IEnumerable<TargetFrameworkInformation> GetTargetFrameworks()
|
||||||
|
@ -134,10 +123,10 @@ namespace Microsoft.DotNet.ProjectModel
|
||||||
|
|
||||||
public bool HasRuntimeOutput(string configuration)
|
public bool HasRuntimeOutput(string configuration)
|
||||||
{
|
{
|
||||||
var compilationOptions = GetCompilerOptions(targetFramework: null, configurationName: configuration);
|
var compilerOptions = GetCompilerOptions(targetFramework: null, configurationName: configuration);
|
||||||
|
|
||||||
// TODO: Make this opt in via another mechanism
|
// TODO: Make this opt in via another mechanism
|
||||||
return compilationOptions.EmitEntryPoint.GetValueOrDefault() || IsTestProject;
|
return compilerOptions.EmitEntryPoint.GetValueOrDefault() || IsTestProject;
|
||||||
}
|
}
|
||||||
|
|
||||||
private CommonCompilerOptions GetCompilerOptions()
|
private CommonCompilerOptions GetCompilerOptions()
|
||||||
|
|
|
@ -337,6 +337,11 @@ namespace Microsoft.DotNet.ProjectModel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Project != null)
|
||||||
|
{
|
||||||
|
diagnostics.AddRange(Project.Diagnostics);
|
||||||
|
}
|
||||||
|
|
||||||
// Create a library manager
|
// Create a library manager
|
||||||
var libraryManager = new LibraryManager(libraries.Values.ToList(), diagnostics, Project?.ProjectFilePath);
|
var libraryManager = new LibraryManager(libraries.Values.ToList(), diagnostics, Project?.ProjectFilePath);
|
||||||
|
|
||||||
|
@ -567,9 +572,8 @@ namespace Microsoft.DotNet.ProjectModel
|
||||||
|
|
||||||
private Project ResolveProject(string projectDirectory)
|
private Project ResolveProject(string projectDirectory)
|
||||||
{
|
{
|
||||||
// TODO: Handle diagnostics
|
|
||||||
Project project;
|
Project project;
|
||||||
if (ProjectReader.TryGetProject(projectDirectory, out project, diagnostics: null, settings: Settings))
|
if (ProjectReader.TryGetProject(projectDirectory, out project, settings: Settings))
|
||||||
{
|
{
|
||||||
return project;
|
return project;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ namespace Microsoft.DotNet.ProjectModel
|
||||||
{
|
{
|
||||||
foreach (var kvp in _compilerNameToLanguageId)
|
foreach (var kvp in _compilerNameToLanguageId)
|
||||||
{
|
{
|
||||||
if (kvp.Key == project.CompilerName)
|
if (kvp.Key == (project._defaultCompilerOptions.CompilerName))
|
||||||
{
|
{
|
||||||
return kvp.Value;
|
return kvp.Value;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ namespace Microsoft.DotNet.ProjectModel
|
||||||
{
|
{
|
||||||
public class ProjectReader
|
public class ProjectReader
|
||||||
{
|
{
|
||||||
public static bool TryGetProject(string path, out Project project, ICollection<DiagnosticMessage> diagnostics = null, ProjectReaderSettings settings = null)
|
public static bool TryGetProject(string path, out Project project, ProjectReaderSettings settings = null)
|
||||||
{
|
{
|
||||||
project = null;
|
project = null;
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ namespace Microsoft.DotNet.ProjectModel
|
||||||
using (var stream = File.OpenRead(projectPath))
|
using (var stream = File.OpenRead(projectPath))
|
||||||
{
|
{
|
||||||
var reader = new ProjectReader();
|
var reader = new ProjectReader();
|
||||||
project = reader.ReadProject(stream, projectName, projectPath, diagnostics, settings);
|
project = reader.ReadProject(stream, projectName, projectPath, settings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
@ -62,9 +62,7 @@ namespace Microsoft.DotNet.ProjectModel
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Project GetProject(string projectPath, ProjectReaderSettings settings = null) => GetProject(projectPath, new List<DiagnosticMessage>(), settings);
|
public static Project GetProject(string projectPath, ProjectReaderSettings settings = null)
|
||||||
|
|
||||||
public static Project GetProject(string projectPath, ICollection<DiagnosticMessage> diagnostics, ProjectReaderSettings settings = null)
|
|
||||||
{
|
{
|
||||||
if (!projectPath.EndsWith(Project.FileName))
|
if (!projectPath.EndsWith(Project.FileName))
|
||||||
{
|
{
|
||||||
|
@ -75,11 +73,11 @@ namespace Microsoft.DotNet.ProjectModel
|
||||||
|
|
||||||
using (var stream = new FileStream(projectPath, FileMode.Open, FileAccess.Read, FileShare.Read))
|
using (var stream = new FileStream(projectPath, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||||
{
|
{
|
||||||
return new ProjectReader().ReadProject(stream, name, projectPath, diagnostics, settings);
|
return new ProjectReader().ReadProject(stream, name, projectPath, settings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Project ReadProject(Stream stream, string projectName, string projectPath, ICollection<DiagnosticMessage> diagnostics, ProjectReaderSettings settings = null)
|
public Project ReadProject(Stream stream, string projectName, string projectPath, ProjectReaderSettings settings = null)
|
||||||
{
|
{
|
||||||
settings = settings ?? new ProjectReaderSettings();
|
settings = settings ?? new ProjectReaderSettings();
|
||||||
var project = new Project();
|
var project = new Project();
|
||||||
|
@ -146,25 +144,13 @@ namespace Microsoft.DotNet.ProjectModel
|
||||||
}
|
}
|
||||||
|
|
||||||
project.Description = rawProject.Value<string>("description");
|
project.Description = rawProject.Value<string>("description");
|
||||||
project.Summary = rawProject.Value<string>("summary");
|
|
||||||
project.Copyright = rawProject.Value<string>("copyright");
|
project.Copyright = rawProject.Value<string>("copyright");
|
||||||
project.Title = rawProject.Value<string>("title");
|
project.Title = rawProject.Value<string>("title");
|
||||||
project.EntryPoint = rawProject.Value<string>("entryPoint");
|
project.EntryPoint = rawProject.Value<string>("entryPoint");
|
||||||
project.ProjectUrl = rawProject.Value<string>("projectUrl");
|
|
||||||
project.LicenseUrl = rawProject.Value<string>("licenseUrl");
|
|
||||||
project.IconUrl = rawProject.Value<string>("iconUrl");
|
|
||||||
project.CompilerName = rawProject.Value<string>("compilerName") ?? "csc";
|
|
||||||
project.TestRunner = rawProject.Value<string>("testRunner");
|
project.TestRunner = rawProject.Value<string>("testRunner");
|
||||||
|
|
||||||
project.Authors =
|
project.Authors =
|
||||||
rawProject.Value<JToken>("authors")?.Values<string>().ToArray() ?? EmptyArray<string>.Value;
|
rawProject.Value<JToken>("authors")?.Values<string>().ToArray() ?? EmptyArray<string>.Value;
|
||||||
project.Owners = rawProject.Value<JToken>("owners")?.Values<string>().ToArray() ?? EmptyArray<string>.Value;
|
|
||||||
project.Tags = rawProject.Value<JToken>("tags")?.Values<string>().ToArray() ?? EmptyArray<string>.Value;
|
|
||||||
|
|
||||||
project.Language = rawProject.Value<string>("language");
|
project.Language = rawProject.Value<string>("language");
|
||||||
project.ReleaseNotes = rawProject.Value<string>("releaseNotes");
|
|
||||||
|
|
||||||
project.RequireLicenseAcceptance = rawProject.Value<bool>("requireLicenseAcceptance");
|
|
||||||
|
|
||||||
// REVIEW: Move this to the dependencies node?
|
// REVIEW: Move this to the dependencies node?
|
||||||
project.EmbedInteropTypes = rawProject.Value<bool>("embedInteropTypes");
|
project.EmbedInteropTypes = rawProject.Value<bool>("embedInteropTypes");
|
||||||
|
@ -215,7 +201,11 @@ namespace Microsoft.DotNet.ProjectModel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BuildTargetFrameworksAndConfigurations(project, rawProject, diagnostics);
|
project.PackOptions = GetPackOptions(rawProject, project) ?? new PackOptions();
|
||||||
|
project.RuntimeOptions = GetRuntimeOptions(rawProject) ?? new RuntimeOptions();
|
||||||
|
project.PublishOptions = GetPublishInclude(rawProject, project);
|
||||||
|
|
||||||
|
BuildTargetFrameworksAndConfigurations(project, rawProject);
|
||||||
|
|
||||||
PopulateDependencies(
|
PopulateDependencies(
|
||||||
project.ProjectFilePath,
|
project.ProjectFilePath,
|
||||||
|
@ -351,11 +341,11 @@ namespace Microsoft.DotNet.ProjectModel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void BuildTargetFrameworksAndConfigurations(Project project, JObject projectJsonObject, ICollection<DiagnosticMessage> diagnostics)
|
private void BuildTargetFrameworksAndConfigurations(Project project, JObject projectJsonObject)
|
||||||
{
|
{
|
||||||
// Get the shared compilationOptions
|
// Get the shared compilationOptions
|
||||||
project._defaultCompilerOptions =
|
project._defaultCompilerOptions =
|
||||||
GetCompilationOptions(projectJsonObject, project) ?? new CommonCompilerOptions();
|
GetCompilationOptions(projectJsonObject, project) ?? new CommonCompilerOptions { CompilerName = "csc" };
|
||||||
|
|
||||||
project._defaultTargetFrameworkConfiguration = new TargetFrameworkInformation
|
project._defaultTargetFrameworkConfiguration = new TargetFrameworkInformation
|
||||||
{
|
{
|
||||||
|
@ -423,7 +413,7 @@ namespace Microsoft.DotNet.ProjectModel
|
||||||
if (!success)
|
if (!success)
|
||||||
{
|
{
|
||||||
var lineInfo = (IJsonLineInfo)framework.Value;
|
var lineInfo = (IJsonLineInfo)framework.Value;
|
||||||
diagnostics?.Add(
|
project.Diagnostics?.Add(
|
||||||
new DiagnosticMessage(
|
new DiagnosticMessage(
|
||||||
ErrorCodes.NU1008,
|
ErrorCodes.NU1008,
|
||||||
$"\"{framework.Key}\" is an unsupported framework.",
|
$"\"{framework.Key}\" is an unsupported framework.",
|
||||||
|
@ -518,10 +508,42 @@ namespace Microsoft.DotNet.ProjectModel
|
||||||
|
|
||||||
private static CommonCompilerOptions GetCompilationOptions(JObject rawObject, Project project)
|
private static CommonCompilerOptions GetCompilationOptions(JObject rawObject, Project project)
|
||||||
{
|
{
|
||||||
var rawOptions = rawObject.Value<JToken>("compilationOptions") as JObject;
|
var compilerName = rawObject.Value<string>("compilerName");
|
||||||
|
if (compilerName != null)
|
||||||
|
{
|
||||||
|
var lineInfo = rawObject.Value<IJsonLineInfo>("compilerName");
|
||||||
|
project.Diagnostics?.Add(
|
||||||
|
new DiagnosticMessage(
|
||||||
|
ErrorCodes.DOTNET1016,
|
||||||
|
$"The 'compilerName' option in the root is deprecated. Use it in 'buildOptions' instead.",
|
||||||
|
project.ProjectFilePath,
|
||||||
|
DiagnosticMessageSeverity.Warning,
|
||||||
|
lineInfo.LineNumber,
|
||||||
|
lineInfo.LinePosition));
|
||||||
|
}
|
||||||
|
|
||||||
|
var rawOptions = rawObject.Value<JToken>("buildOptions") as JObject;
|
||||||
if (rawOptions == null)
|
if (rawOptions == null)
|
||||||
{
|
{
|
||||||
return null;
|
rawOptions = rawObject.Value<JToken>("compilationOptions") as JObject;
|
||||||
|
if (rawOptions == null)
|
||||||
|
{
|
||||||
|
return new CommonCompilerOptions
|
||||||
|
{
|
||||||
|
CompilerName = compilerName ?? "csc"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
var lineInfo = (IJsonLineInfo)rawOptions;
|
||||||
|
|
||||||
|
project.Diagnostics?.Add(
|
||||||
|
new DiagnosticMessage(
|
||||||
|
ErrorCodes.DOTNET1015,
|
||||||
|
$"The 'compilationOptions' option is deprecated. Use 'buildOptions' instead.",
|
||||||
|
project.ProjectFilePath,
|
||||||
|
DiagnosticMessageSeverity.Warning,
|
||||||
|
lineInfo.LineNumber,
|
||||||
|
lineInfo.LinePosition));
|
||||||
}
|
}
|
||||||
|
|
||||||
var analyzerOptionsJson = rawOptions.Value<JToken>("analyzerOptions") as JObject;
|
var analyzerOptionsJson = rawOptions.Value<JToken>("analyzerOptions") as JObject;
|
||||||
|
@ -571,10 +593,148 @@ namespace Microsoft.DotNet.ProjectModel
|
||||||
EmitEntryPoint = rawOptions.Value<bool?>("emitEntryPoint"),
|
EmitEntryPoint = rawOptions.Value<bool?>("emitEntryPoint"),
|
||||||
GenerateXmlDocumentation = rawOptions.Value<bool?>("xmlDoc"),
|
GenerateXmlDocumentation = rawOptions.Value<bool?>("xmlDoc"),
|
||||||
PreserveCompilationContext = rawOptions.Value<bool?>("preserveCompilationContext"),
|
PreserveCompilationContext = rawOptions.Value<bool?>("preserveCompilationContext"),
|
||||||
OutputName = rawOptions.Value<string>("outputName")
|
OutputName = rawOptions.Value<string>("outputName"),
|
||||||
|
CompilerName = rawOptions.Value<string>("compilerName") ?? compilerName ?? "csc",
|
||||||
|
CompileInclude = GetIncludeContext(
|
||||||
|
project,
|
||||||
|
rawOptions,
|
||||||
|
"compile",
|
||||||
|
defaultBuiltInInclude: ProjectFilesCollection.DefaultCompileBuiltInPatterns,
|
||||||
|
defaultBuiltInExclude: ProjectFilesCollection.DefaultBuiltInExcludePatterns),
|
||||||
|
EmbedInclude = GetIncludeContext(
|
||||||
|
project,
|
||||||
|
rawOptions,
|
||||||
|
"embed",
|
||||||
|
defaultBuiltInInclude: ProjectFilesCollection.DefaultResourcesBuiltInPatterns,
|
||||||
|
defaultBuiltInExclude: ProjectFilesCollection.DefaultBuiltInExcludePatterns),
|
||||||
|
CopyToOutputInclude = GetIncludeContext(
|
||||||
|
project,
|
||||||
|
rawOptions,
|
||||||
|
"copyToOutput",
|
||||||
|
defaultBuiltInInclude: null,
|
||||||
|
defaultBuiltInExclude: ProjectFilesCollection.DefaultPublishExcludePatterns)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static IncludeContext GetIncludeContext(
|
||||||
|
Project project,
|
||||||
|
JObject rawOptions,
|
||||||
|
string option,
|
||||||
|
string[] defaultBuiltInInclude,
|
||||||
|
string[] defaultBuiltInExclude)
|
||||||
|
{
|
||||||
|
var contextOption = rawOptions.Value<JToken>(option);
|
||||||
|
if (contextOption != null)
|
||||||
|
{
|
||||||
|
return new IncludeContext(
|
||||||
|
project.ProjectDirectory,
|
||||||
|
option,
|
||||||
|
rawOptions,
|
||||||
|
defaultBuiltInInclude,
|
||||||
|
defaultBuiltInExclude);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static PackOptions GetPackOptions(JObject rawProject, Project project)
|
||||||
|
{
|
||||||
|
var rawPackOptions = rawProject.Value<JToken>("packOptions") as JObject;
|
||||||
|
|
||||||
|
// Files to be packed along with the project
|
||||||
|
IncludeContext packInclude = null;
|
||||||
|
if (rawPackOptions != null && rawPackOptions.Value<JToken>("files") != null)
|
||||||
|
{
|
||||||
|
packInclude = new IncludeContext(
|
||||||
|
project.ProjectDirectory,
|
||||||
|
"files",
|
||||||
|
rawPackOptions,
|
||||||
|
defaultBuiltInInclude: null,
|
||||||
|
defaultBuiltInExclude: ProjectFilesCollection.DefaultBuiltInExcludePatterns);
|
||||||
|
}
|
||||||
|
|
||||||
|
var repository = GetPackOptionsValue<JToken>("repository", rawProject, rawPackOptions, project) as JObject;
|
||||||
|
|
||||||
|
return new PackOptions
|
||||||
|
{
|
||||||
|
ProjectUrl = GetPackOptionsValue<string>("projectUrl", rawProject, rawPackOptions, project),
|
||||||
|
LicenseUrl = GetPackOptionsValue<string>("licenseUrl", rawProject, rawPackOptions, project),
|
||||||
|
IconUrl = GetPackOptionsValue<string>("iconUrl", rawProject, rawPackOptions, project),
|
||||||
|
Owners = GetPackOptionsValue<JToken>("owners", rawProject, rawPackOptions, project)?.Values<string>().ToArray() ?? EmptyArray<string>.Value,
|
||||||
|
Tags = GetPackOptionsValue<JToken>("tags", rawProject, rawPackOptions, project)?.Values<string>().ToArray() ?? EmptyArray<string>.Value,
|
||||||
|
ReleaseNotes = GetPackOptionsValue<string>("releaseNotes", rawProject, rawPackOptions, project),
|
||||||
|
RequireLicenseAcceptance = GetPackOptionsValue<bool>("requireLicenseAcceptance", rawProject, rawPackOptions, project),
|
||||||
|
Summary = GetPackOptionsValue<string>("summary", rawProject, rawPackOptions, project),
|
||||||
|
RepositoryType = repository?.Value<string>("type"),
|
||||||
|
RepositoryUrl = repository?.Value<string>("url"),
|
||||||
|
PackInclude = packInclude
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static T GetPackOptionsValue<T>(
|
||||||
|
string option,
|
||||||
|
JObject rawProject,
|
||||||
|
JObject rawPackOptions,
|
||||||
|
Project project)
|
||||||
|
{
|
||||||
|
var rootValue = rawProject.Value<T>(option);
|
||||||
|
if (rawProject.GetValue(option) != null)
|
||||||
|
{
|
||||||
|
var lineInfo = rawProject.Value<IJsonLineInfo>(option);
|
||||||
|
project.Diagnostics?.Add(
|
||||||
|
new DiagnosticMessage(
|
||||||
|
ErrorCodes.DOTNET1016,
|
||||||
|
$"The '{option}' option in the root is deprecated. Use it in 'packOptions' instead.",
|
||||||
|
project.ProjectFilePath,
|
||||||
|
DiagnosticMessageSeverity.Warning,
|
||||||
|
lineInfo.LineNumber,
|
||||||
|
lineInfo.LinePosition));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rawPackOptions != null)
|
||||||
|
{
|
||||||
|
var packOptionValue = rawPackOptions.Value<T>(option);
|
||||||
|
if (packOptionValue != null)
|
||||||
|
{
|
||||||
|
return packOptionValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rootValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static RuntimeOptions GetRuntimeOptions(JObject rawProject)
|
||||||
|
{
|
||||||
|
var rawRuntimeOptions = rawProject.Value<JToken>("runtimeOptions") as JObject;
|
||||||
|
if (rawRuntimeOptions == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new RuntimeOptions
|
||||||
|
{
|
||||||
|
// Value<T>(null) will return default(T) which is false in this case.
|
||||||
|
GcServer = rawRuntimeOptions.Value<bool>("gcServer"),
|
||||||
|
GcConcurrent = rawRuntimeOptions.Value<bool>("gcConcurrent")
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IncludeContext GetPublishInclude(JObject rawProject, Project project)
|
||||||
|
{
|
||||||
|
var rawPublishOptions = rawProject.Value<JToken>("publishOptions");
|
||||||
|
if (rawPublishOptions != null)
|
||||||
|
{
|
||||||
|
return new IncludeContext(
|
||||||
|
project.ProjectDirectory,
|
||||||
|
"publishOptions",
|
||||||
|
rawProject,
|
||||||
|
defaultBuiltInInclude: null,
|
||||||
|
defaultBuiltInExclude: ProjectFilesCollection.DefaultPublishExcludePatterns);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private static string MakeDefaultTargetFrameworkDefine(NuGetFramework targetFramework)
|
private static string MakeDefaultTargetFrameworkDefine(NuGetFramework targetFramework)
|
||||||
{
|
{
|
||||||
var shortName = targetFramework.GetTwoDigitShortFolderName();
|
var shortName = targetFramework.GetTwoDigitShortFolderName();
|
||||||
|
|
12
src/Microsoft.DotNet.ProjectModel/RuntimeOptions.cs
Normal file
12
src/Microsoft.DotNet.ProjectModel/RuntimeOptions.cs
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
// 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
|
||||||
|
{
|
||||||
|
public class RuntimeOptions
|
||||||
|
{
|
||||||
|
public bool GcServer { get; set; }
|
||||||
|
|
||||||
|
public bool GcConcurrent { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -38,9 +38,9 @@ namespace Microsoft.DotNet.ProjectModel
|
||||||
extension = FileNameSuffixes.DotNet.DynamicLib;
|
extension = FileNameSuffixes.DotNet.DynamicLib;
|
||||||
}
|
}
|
||||||
|
|
||||||
var compilationOptions = Project.GetCompilerOptions(Framework, Configuration);
|
var compilerOptions = Project.GetCompilerOptions(Framework, Configuration);
|
||||||
|
|
||||||
return Path.Combine(BasePath, compilationOptions.OutputName + extension);
|
return Path.Combine(BasePath, compilerOptions.OutputName + extension);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -284,13 +284,14 @@ namespace Microsoft.DotNet.ProjectModel
|
||||||
if (currentEntry.IsInvalid)
|
if (currentEntry.IsInvalid)
|
||||||
{
|
{
|
||||||
Project project;
|
Project project;
|
||||||
if (!ProjectReader.TryGetProject(projectDirectory, out project, currentEntry.Diagnostics, _settings))
|
if (!ProjectReader.TryGetProject(projectDirectory, out project, _settings))
|
||||||
{
|
{
|
||||||
currentEntry.Reset();
|
currentEntry.Reset();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
currentEntry.Model = project;
|
currentEntry.Model = project;
|
||||||
|
currentEntry.Diagnostics.AddRange(project.Diagnostics);
|
||||||
currentEntry.FilePath = project.ProjectFilePath;
|
currentEntry.FilePath = project.ProjectFilePath;
|
||||||
currentEntry.UpdateLastWriteTimeUtc();
|
currentEntry.UpdateLastWriteTimeUtc();
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,7 @@ namespace Microsoft.DotNet.Tools.Build
|
||||||
|
|
||||||
var calculator = project.GetOutputPaths(_configuration, _buildBasePath, _outputPath);
|
var calculator = project.GetOutputPaths(_configuration, _buildBasePath, _outputPath);
|
||||||
var binariesOutputPath = calculator.CompilationOutputPath;
|
var binariesOutputPath = calculator.CompilationOutputPath;
|
||||||
|
var compilerOptions = project.ProjectFile.GetCompilerOptions(project.TargetFramework, _configuration);
|
||||||
|
|
||||||
// input: project.json
|
// input: project.json
|
||||||
inputs.Add(project.ProjectFile.ProjectFilePath);
|
inputs.Add(project.ProjectFile.ProjectFilePath);
|
||||||
|
@ -62,7 +63,7 @@ namespace Microsoft.DotNet.Tools.Build
|
||||||
AddLockFile(project, inputs);
|
AddLockFile(project, inputs);
|
||||||
|
|
||||||
// input: source files
|
// input: source files
|
||||||
inputs.AddRange(CompilerUtil.GetCompilationSources(project));
|
inputs.AddRange(CompilerUtil.GetCompilationSources(project, compilerOptions));
|
||||||
|
|
||||||
var allOutputPath = new HashSet<string>(calculator.CompilationFiles.All());
|
var allOutputPath = new HashSet<string>(calculator.CompilationFiles.All());
|
||||||
if (isRootProject && project.ProjectFile.HasRuntimeOutput(_configuration))
|
if (isRootProject && project.ProjectFile.HasRuntimeOutput(_configuration))
|
||||||
|
@ -84,10 +85,10 @@ namespace Microsoft.DotNet.Tools.Build
|
||||||
AddCompilationOptions(project, _configuration, inputs);
|
AddCompilationOptions(project, _configuration, inputs);
|
||||||
|
|
||||||
// input / output: resources with culture
|
// input / output: resources with culture
|
||||||
AddNonCultureResources(project, calculator.IntermediateOutputDirectoryPath, inputs, outputs);
|
AddNonCultureResources(project, calculator.IntermediateOutputDirectoryPath, inputs, outputs, compilerOptions);
|
||||||
|
|
||||||
// input / output: resources without culture
|
// input / output: resources without culture
|
||||||
AddCultureResources(project, binariesOutputPath, inputs, outputs);
|
AddCultureResources(project, binariesOutputPath, inputs, outputs, compilerOptions);
|
||||||
|
|
||||||
return new CompilerIO(inputs, outputs);
|
return new CompilerIO(inputs, outputs);
|
||||||
}
|
}
|
||||||
|
@ -121,9 +122,24 @@ namespace Microsoft.DotNet.Tools.Build
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void AddNonCultureResources(ProjectContext project, string intermediaryOutputPath, List<string> inputs, IList<string> outputs)
|
private static void AddNonCultureResources(
|
||||||
|
ProjectContext project,
|
||||||
|
string intermediaryOutputPath,
|
||||||
|
List<string> inputs,
|
||||||
|
IList<string> outputs,
|
||||||
|
CommonCompilerOptions compilationOptions)
|
||||||
{
|
{
|
||||||
foreach (var resourceIO in CompilerUtil.GetNonCultureResources(project.ProjectFile, intermediaryOutputPath))
|
List<CompilerUtil.NonCultureResgenIO> resources = null;
|
||||||
|
if (compilationOptions.EmbedInclude == null)
|
||||||
|
{
|
||||||
|
resources = CompilerUtil.GetNonCultureResources(project.ProjectFile, intermediaryOutputPath);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
resources = CompilerUtil.GetNonCultureResourcesFromIncludeEntries(project.ProjectFile, intermediaryOutputPath, compilationOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var resourceIO in resources)
|
||||||
{
|
{
|
||||||
inputs.Add(resourceIO.InputFile);
|
inputs.Add(resourceIO.InputFile);
|
||||||
|
|
||||||
|
@ -134,9 +150,24 @@ namespace Microsoft.DotNet.Tools.Build
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void AddCultureResources(ProjectContext project, string outputPath, List<string> inputs, List<string> outputs)
|
private static void AddCultureResources(
|
||||||
|
ProjectContext project,
|
||||||
|
string outputPath,
|
||||||
|
List<string> inputs,
|
||||||
|
List<string> outputs,
|
||||||
|
CommonCompilerOptions compilationOptions)
|
||||||
{
|
{
|
||||||
foreach (var cultureResourceIO in CompilerUtil.GetCultureResources(project.ProjectFile, outputPath))
|
List<CompilerUtil.CultureResgenIO> resources = null;
|
||||||
|
if (compilationOptions.EmbedInclude == null)
|
||||||
|
{
|
||||||
|
resources = CompilerUtil.GetCultureResources(project.ProjectFile, outputPath);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
resources = CompilerUtil.GetCultureResourcesFromIncludeEntries(project.ProjectFile, outputPath, compilationOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var cultureResourceIO in resources)
|
||||||
{
|
{
|
||||||
inputs.AddRange(cultureResourceIO.InputFileToMetadata.Keys);
|
inputs.AddRange(cultureResourceIO.InputFileToMetadata.Keys);
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,8 @@ namespace Microsoft.DotNet.Tools.Build
|
||||||
{
|
{
|
||||||
if (project.ProjectFile != null)
|
if (project.ProjectFile != null)
|
||||||
{
|
{
|
||||||
var projectCompiler = project.ProjectFile.CompilerName;
|
var compilerOptions = project.ProjectFile.GetCompilerOptions(project.TargetFramework, null);
|
||||||
|
var projectCompiler = compilerOptions.CompilerName;
|
||||||
|
|
||||||
if (!KnownCompilers.Any(knownCompiler => knownCompiler.Equals(projectCompiler, StringComparison.Ordinal)))
|
if (!KnownCompilers.Any(knownCompiler => knownCompiler.Equals(projectCompiler, StringComparison.Ordinal)))
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,6 +5,7 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Microsoft.DotNet.ProjectModel;
|
using Microsoft.DotNet.ProjectModel;
|
||||||
|
using Microsoft.DotNet.ProjectModel.Files;
|
||||||
using NuGet.Frameworks;
|
using NuGet.Frameworks;
|
||||||
|
|
||||||
namespace Microsoft.DotNet.Tools.Build
|
namespace Microsoft.DotNet.Tools.Build
|
||||||
|
@ -67,7 +68,7 @@ namespace Microsoft.DotNet.Tools.Build
|
||||||
}
|
}
|
||||||
|
|
||||||
var context = projectNode.ProjectContext;
|
var context = projectNode.ProjectContext;
|
||||||
if (!context.ProjectFile.Files.SourceFiles.Any())
|
if (!HasSourceFiles(context))
|
||||||
{
|
{
|
||||||
return CompilationResult.IncrementalSkip;
|
return CompilationResult.IncrementalSkip;
|
||||||
}
|
}
|
||||||
|
@ -82,5 +83,19 @@ namespace Microsoft.DotNet.Tools.Build
|
||||||
return CompilationResult.IncrementalSkip;
|
return CompilationResult.IncrementalSkip;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static bool HasSourceFiles(ProjectContext context)
|
||||||
|
{
|
||||||
|
var compilerOptions = context.ProjectFile.GetCompilerOptions(context.TargetFramework, null);
|
||||||
|
|
||||||
|
if (compilerOptions.CompileInclude == null)
|
||||||
|
{
|
||||||
|
return context.ProjectFile.Files.SourceFiles.Any();
|
||||||
|
}
|
||||||
|
|
||||||
|
var includeFiles = IncludeFilesResolver.GetIncludeFiles(compilerOptions.CompileInclude, "/", diagnostics: null);
|
||||||
|
|
||||||
|
return includeFiles.Any();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -46,9 +46,21 @@ namespace Microsoft.DotNet.Tools.Compiler
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static bool AddNonCultureResources(Project project, List<string> compilerArgs, string intermediateOutputPath)
|
protected static bool AddNonCultureResources(
|
||||||
|
Project project,
|
||||||
|
List<string> compilerArgs,
|
||||||
|
string intermediateOutputPath,
|
||||||
|
CommonCompilerOptions compilationOptions)
|
||||||
{
|
{
|
||||||
var resgenFiles = CompilerUtil.GetNonCultureResources(project, intermediateOutputPath);
|
List<CompilerUtil.NonCultureResgenIO> resgenFiles = null;
|
||||||
|
if (compilationOptions.EmbedInclude == null)
|
||||||
|
{
|
||||||
|
resgenFiles = CompilerUtil.GetNonCultureResources(project, intermediateOutputPath);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
resgenFiles = CompilerUtil.GetNonCultureResourcesFromIncludeEntries(project, intermediateOutputPath, compilationOptions);
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var resgenFile in resgenFiles)
|
foreach (var resgenFile in resgenFiles)
|
||||||
{
|
{
|
||||||
|
@ -80,10 +92,20 @@ namespace Microsoft.DotNet.Tools.Compiler
|
||||||
protected static bool GenerateCultureResourceAssemblies(
|
protected static bool GenerateCultureResourceAssemblies(
|
||||||
Project project,
|
Project project,
|
||||||
List<LibraryExport> dependencies,
|
List<LibraryExport> dependencies,
|
||||||
string outputPath)
|
string outputPath,
|
||||||
|
CommonCompilerOptions compilationOptions)
|
||||||
{
|
{
|
||||||
var referencePaths = CompilerUtil.GetReferencePathsForCultureResgen(dependencies);
|
var referencePaths = CompilerUtil.GetReferencePathsForCultureResgen(dependencies);
|
||||||
var cultureResgenFiles = CompilerUtil.GetCultureResources(project, outputPath);
|
|
||||||
|
List<CompilerUtil.CultureResgenIO> cultureResgenFiles = null;
|
||||||
|
if (compilationOptions.EmbedInclude == null)
|
||||||
|
{
|
||||||
|
cultureResgenFiles = CompilerUtil.GetCultureResources(project, outputPath);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cultureResgenFiles = CompilerUtil.GetCultureResourcesFromIncludeEntries(project, outputPath, compilationOptions);
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var resgenFile in cultureResgenFiles)
|
foreach (var resgenFile in cultureResgenFiles)
|
||||||
{
|
{
|
||||||
|
|
|
@ -9,6 +9,7 @@ using System.Linq;
|
||||||
using Microsoft.DotNet.ProjectModel;
|
using Microsoft.DotNet.ProjectModel;
|
||||||
using Microsoft.DotNet.Cli.Compiler.Common;
|
using Microsoft.DotNet.Cli.Compiler.Common;
|
||||||
using Microsoft.DotNet.ProjectModel.Compilation;
|
using Microsoft.DotNet.ProjectModel.Compilation;
|
||||||
|
using Microsoft.DotNet.ProjectModel.Files;
|
||||||
using Microsoft.DotNet.ProjectModel.Resources;
|
using Microsoft.DotNet.ProjectModel.Resources;
|
||||||
using Microsoft.DotNet.Tools.Common;
|
using Microsoft.DotNet.Tools.Common;
|
||||||
|
|
||||||
|
@ -53,7 +54,25 @@ namespace Microsoft.DotNet.Tools.Compiler
|
||||||
(from resourceFile in project.Files.ResourceFiles
|
(from resourceFile in project.Files.ResourceFiles
|
||||||
let inputFile = resourceFile.Key
|
let inputFile = resourceFile.Key
|
||||||
where string.IsNullOrEmpty(ResourceUtility.GetResourceCultureName(inputFile))
|
where string.IsNullOrEmpty(ResourceUtility.GetResourceCultureName(inputFile))
|
||||||
let metadataName = GetResourceFileMetadataName(project, resourceFile)
|
let metadataName = GetResourceFileMetadataName(project, resourceFile.Key, resourceFile.Value)
|
||||||
|
let outputFile = ResourceUtility.IsResxFile(inputFile) ? Path.Combine(intermediateOutputPath, metadataName) : null
|
||||||
|
select new NonCultureResgenIO(inputFile, outputFile, metadataName)
|
||||||
|
).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// used in incremental compilation
|
||||||
|
public static List<NonCultureResgenIO> GetNonCultureResourcesFromIncludeEntries(
|
||||||
|
Project project,
|
||||||
|
string intermediateOutputPath,
|
||||||
|
CommonCompilerOptions compilationOptions)
|
||||||
|
{
|
||||||
|
var includeFiles = IncludeFilesResolver.GetIncludeFiles(compilationOptions.EmbedInclude, "/", diagnostics: null);
|
||||||
|
return
|
||||||
|
(from resourceFile in includeFiles
|
||||||
|
let inputFile = resourceFile.SourcePath
|
||||||
|
where string.IsNullOrEmpty(ResourceUtility.GetResourceCultureName(inputFile))
|
||||||
|
let target = resourceFile.IsCustomTarget ? resourceFile.TargetPath : null
|
||||||
|
let metadataName = GetResourceFileMetadataName(project, resourceFile.SourcePath, target)
|
||||||
let outputFile = ResourceUtility.IsResxFile(inputFile) ? Path.Combine(intermediateOutputPath, metadataName) : null
|
let outputFile = ResourceUtility.IsResxFile(inputFile) ? Path.Combine(intermediateOutputPath, metadataName) : null
|
||||||
select new NonCultureResgenIO(inputFile, outputFile, metadataName)
|
select new NonCultureResgenIO(inputFile, outputFile, metadataName)
|
||||||
).ToList();
|
).ToList();
|
||||||
|
@ -80,7 +99,27 @@ namespace Microsoft.DotNet.Tools.Compiler
|
||||||
(from resourceFileGroup in project.Files.ResourceFiles.GroupBy(resourceFile => ResourceUtility.GetResourceCultureName(resourceFile.Key))
|
(from resourceFileGroup in project.Files.ResourceFiles.GroupBy(resourceFile => ResourceUtility.GetResourceCultureName(resourceFile.Key))
|
||||||
let culture = resourceFileGroup.Key
|
let culture = resourceFileGroup.Key
|
||||||
where !string.IsNullOrEmpty(culture)
|
where !string.IsNullOrEmpty(culture)
|
||||||
let inputFileToMetadata = resourceFileGroup.ToDictionary(r => r.Key, r => GetResourceFileMetadataName(project, r))
|
let inputFileToMetadata = resourceFileGroup.ToDictionary(r => r.Key, r => GetResourceFileMetadataName(project, r.Key, r.Value))
|
||||||
|
let resourceOutputPath = Path.Combine(outputPath, culture)
|
||||||
|
let outputFile = Path.Combine(resourceOutputPath, project.Name + ".resources.dll")
|
||||||
|
select new CultureResgenIO(culture, inputFileToMetadata, outputFile)
|
||||||
|
).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// used in incremental compilation
|
||||||
|
public static List<CultureResgenIO> GetCultureResourcesFromIncludeEntries(
|
||||||
|
Project project,
|
||||||
|
string outputPath,
|
||||||
|
CommonCompilerOptions compilationOptions)
|
||||||
|
{
|
||||||
|
var includeFiles = IncludeFilesResolver.GetIncludeFiles(compilationOptions.EmbedInclude, "/", diagnostics: null);
|
||||||
|
return
|
||||||
|
(from resourceFileGroup in includeFiles
|
||||||
|
.GroupBy(resourceFile => ResourceUtility.GetResourceCultureName(resourceFile.SourcePath))
|
||||||
|
let culture = resourceFileGroup.Key
|
||||||
|
where !string.IsNullOrEmpty(culture)
|
||||||
|
let inputFileToMetadata = resourceFileGroup.ToDictionary(
|
||||||
|
r => r.SourcePath, r => GetResourceFileMetadataName(project, r.SourcePath, r.IsCustomTarget ? r.TargetPath : null))
|
||||||
let resourceOutputPath = Path.Combine(outputPath, culture)
|
let resourceOutputPath = Path.Combine(outputPath, culture)
|
||||||
let outputFile = Path.Combine(resourceOutputPath, project.Name + ".resources.dll")
|
let outputFile = Path.Combine(resourceOutputPath, project.Name + ".resources.dll")
|
||||||
select new CultureResgenIO(culture, inputFileToMetadata, outputFile)
|
select new CultureResgenIO(culture, inputFileToMetadata, outputFile)
|
||||||
|
@ -93,14 +132,14 @@ namespace Microsoft.DotNet.Tools.Compiler
|
||||||
return dependencies.SelectMany(libraryExport => libraryExport.CompilationAssemblies).Select(r => r.ResolvedPath).ToList();
|
return dependencies.SelectMany(libraryExport => libraryExport.CompilationAssemblies).Select(r => r.ResolvedPath).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetResourceFileMetadataName(Project project, KeyValuePair<string, string> resourceFile)
|
public static string GetResourceFileMetadataName(Project project, string resourceFileSource, string resourceFileTarget)
|
||||||
{
|
{
|
||||||
string resourceName = null;
|
string resourceName = null;
|
||||||
string rootNamespace = null;
|
string rootNamespace = null;
|
||||||
|
|
||||||
string root = PathUtility.EnsureTrailingSlash(project.ProjectDirectory);
|
string root = PathUtility.EnsureTrailingSlash(project.ProjectDirectory);
|
||||||
string resourcePath = resourceFile.Key;
|
string resourcePath = resourceFileSource;
|
||||||
if (string.IsNullOrEmpty(resourceFile.Value))
|
if (string.IsNullOrEmpty(resourceFileTarget))
|
||||||
{
|
{
|
||||||
// No logical name, so use the file name
|
// No logical name, so use the file name
|
||||||
resourceName = ResourceUtility.GetResourceName(root, resourcePath);
|
resourceName = ResourceUtility.GetResourceName(root, resourcePath);
|
||||||
|
@ -108,7 +147,7 @@ namespace Microsoft.DotNet.Tools.Compiler
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
resourceName = ResourceManifestName.EnsureResourceExtension(resourceFile.Value, resourcePath);
|
resourceName = ResourceManifestName.EnsureResourceExtension(resourceFileTarget, resourcePath);
|
||||||
rootNamespace = null;
|
rootNamespace = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,12 +156,23 @@ namespace Microsoft.DotNet.Tools.Compiler
|
||||||
}
|
}
|
||||||
|
|
||||||
// used in incremental compilation
|
// used in incremental compilation
|
||||||
public static IEnumerable<string> GetCompilationSources(ProjectContext project) => project.ProjectFile.Files.SourceFiles;
|
public static IEnumerable<string> GetCompilationSources(ProjectContext project, CommonCompilerOptions compilerOptions)
|
||||||
|
{
|
||||||
|
if (compilerOptions.CompileInclude == null)
|
||||||
|
{
|
||||||
|
return project.ProjectFile.Files.SourceFiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
var includeFiles = IncludeFilesResolver.GetIncludeFiles(compilerOptions.CompileInclude, "/", diagnostics: null);
|
||||||
|
|
||||||
|
return includeFiles.Select(f => f.SourcePath);
|
||||||
|
}
|
||||||
|
|
||||||
//used in incremental precondition checks
|
//used in incremental precondition checks
|
||||||
public static IEnumerable<string> GetCommandsInvokedByCompile(ProjectContext project)
|
public static IEnumerable<string> GetCommandsInvokedByCompile(ProjectContext project)
|
||||||
{
|
{
|
||||||
return new List<string> {project.ProjectFile?.CompilerName, "compile"};
|
var compilerOptions = project.ProjectFile.GetCompilerOptions(project.TargetFramework, configurationName: null);
|
||||||
|
return new List<string> { compilerOptions.CompilerName, "compile" };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -143,15 +143,15 @@ namespace Microsoft.DotNet.Tools.Compiler
|
||||||
compilerArgs.Add($"--resource:\"{depsJsonFile}\",{compilationOptions.OutputName}.deps.json");
|
compilerArgs.Add($"--resource:\"{depsJsonFile}\",{compilationOptions.OutputName}.deps.json");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!AddNonCultureResources(context.ProjectFile, compilerArgs, intermediateOutputPath))
|
if (!AddNonCultureResources(context.ProjectFile, compilerArgs, intermediateOutputPath, compilationOptions))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Add project source files
|
// Add project source files
|
||||||
var sourceFiles = CompilerUtil.GetCompilationSources(context);
|
var sourceFiles = CompilerUtil.GetCompilationSources(context, compilationOptions);
|
||||||
compilerArgs.AddRange(sourceFiles);
|
compilerArgs.AddRange(sourceFiles);
|
||||||
|
|
||||||
var compilerName = context.ProjectFile.CompilerName;
|
var compilerName = compilationOptions.CompilerName;
|
||||||
|
|
||||||
// Write RSP file
|
// Write RSP file
|
||||||
var rsp = Path.Combine(intermediateOutputPath, $"dotnet-compile.rsp");
|
var rsp = Path.Combine(intermediateOutputPath, $"dotnet-compile.rsp");
|
||||||
|
@ -207,7 +207,7 @@ namespace Microsoft.DotNet.Tools.Compiler
|
||||||
|
|
||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
success &= GenerateCultureResourceAssemblies(context.ProjectFile, dependencies, outputPath);
|
success &= GenerateCultureResourceAssemblies(context.ProjectFile, dependencies, outputPath, compilationOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
return PrintSummary(diagnostics, sw, success);
|
return PrintSummary(diagnostics, sw, success);
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
// 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.
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using Microsoft.DotNet.Cli.Utils;
|
|
||||||
using Microsoft.DotNet.ProjectModel;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Microsoft.DotNet.ProjectModel;
|
||||||
|
using Microsoft.DotNet.ProjectModel.Files;
|
||||||
|
|
||||||
namespace Microsoft.DotNet.Tools.Pack
|
namespace Microsoft.DotNet.Tools.Pack
|
||||||
{
|
{
|
||||||
|
@ -32,7 +31,7 @@ namespace Microsoft.DotNet.Tools.Pack
|
||||||
|
|
||||||
public int Execute()
|
public int Execute()
|
||||||
{
|
{
|
||||||
if (_project.Files.SourceFiles.Any())
|
if (HasSourceFiles())
|
||||||
{
|
{
|
||||||
var argsBuilder = new List<string>();
|
var argsBuilder = new List<string>();
|
||||||
argsBuilder.Add("--configuration");
|
argsBuilder.Add("--configuration");
|
||||||
|
@ -59,5 +58,20 @@ namespace Microsoft.DotNet.Tools.Pack
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool HasSourceFiles()
|
||||||
|
{
|
||||||
|
var compilerOptions = _project.GetCompilerOptions(
|
||||||
|
_project.GetTargetFramework(targetFramework: null).FrameworkName, _configuration);
|
||||||
|
|
||||||
|
if (compilerOptions.CompileInclude == null)
|
||||||
|
{
|
||||||
|
return _project.Files.SourceFiles.Any();
|
||||||
|
}
|
||||||
|
|
||||||
|
var includeFiles = IncludeFilesResolver.GetIncludeFiles(compilerOptions.CompileInclude, "/", diagnostics: null);
|
||||||
|
|
||||||
|
return includeFiles.Any();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,16 +9,15 @@ using Microsoft.DotNet.Cli.Utils;
|
||||||
using Microsoft.DotNet.ProjectModel;
|
using Microsoft.DotNet.ProjectModel;
|
||||||
using Microsoft.DotNet.ProjectModel.Files;
|
using Microsoft.DotNet.ProjectModel.Files;
|
||||||
using Microsoft.DotNet.ProjectModel.Graph;
|
using Microsoft.DotNet.ProjectModel.Graph;
|
||||||
|
using Microsoft.DotNet.ProjectModel.Resources;
|
||||||
using Microsoft.DotNet.ProjectModel.Utilities;
|
using Microsoft.DotNet.ProjectModel.Utilities;
|
||||||
|
using Microsoft.DotNet.Tools.Pack;
|
||||||
using Microsoft.Extensions.FileSystemGlobbing;
|
using Microsoft.Extensions.FileSystemGlobbing;
|
||||||
using Microsoft.Extensions.FileSystemGlobbing.Abstractions;
|
using Microsoft.Extensions.FileSystemGlobbing.Abstractions;
|
||||||
using NuGet;
|
using NuGet;
|
||||||
using NuGet.Frameworks;
|
using NuGet.Frameworks;
|
||||||
using NuGet.Packaging.Core;
|
using NuGet.Packaging.Core;
|
||||||
using NuGet.Versioning;
|
using NuGet.Versioning;
|
||||||
using Microsoft.DotNet.Cli.Compiler.Common;
|
|
||||||
using Microsoft.DotNet.ProjectModel.Resources;
|
|
||||||
using Microsoft.DotNet.Tools.Pack;
|
|
||||||
using PackageBuilder = NuGet.PackageBuilder;
|
using PackageBuilder = NuGet.PackageBuilder;
|
||||||
|
|
||||||
namespace Microsoft.DotNet.Tools.Compiler
|
namespace Microsoft.DotNet.Tools.Compiler
|
||||||
|
@ -42,7 +41,6 @@ namespace Microsoft.DotNet.Tools.Compiler
|
||||||
|
|
||||||
public bool BuildPackage(IEnumerable<ProjectContext> contexts, List<DiagnosticMessage> packDiagnostics)
|
public bool BuildPackage(IEnumerable<ProjectContext> contexts, List<DiagnosticMessage> packDiagnostics)
|
||||||
{
|
{
|
||||||
|
|
||||||
Reporter.Output.WriteLine($"Producing nuget package \"{GetPackageName()}\" for {Project.Name}");
|
Reporter.Output.WriteLine($"Producing nuget package \"{GetPackageName()}\" for {Project.Name}");
|
||||||
|
|
||||||
PackageBuilder = CreatePackageBuilder(Project);
|
PackageBuilder = CreatePackageBuilder(Project);
|
||||||
|
@ -76,15 +74,26 @@ namespace Microsoft.DotNet.Tools.Compiler
|
||||||
|
|
||||||
var inputFolder = ArtifactPathsCalculator.InputPathForContext(context);
|
var inputFolder = ArtifactPathsCalculator.InputPathForContext(context);
|
||||||
|
|
||||||
var compilationOptions = Project.GetCompilerOptions(context.TargetFramework, Configuration);
|
var compilerOptions = Project.GetCompilerOptions(context.TargetFramework, Configuration);
|
||||||
var outputName = compilationOptions.OutputName;
|
var outputName = compilerOptions.OutputName;
|
||||||
var outputExtension =
|
var outputExtension =
|
||||||
context.TargetFramework.IsDesktop() && compilationOptions.EmitEntryPoint.GetValueOrDefault()
|
context.TargetFramework.IsDesktop() && compilerOptions.EmitEntryPoint.GetValueOrDefault()
|
||||||
? ".exe" : ".dll";
|
? ".exe" : ".dll";
|
||||||
|
|
||||||
var resourceCultures = context.ProjectFile.Files.ResourceFiles
|
IEnumerable<string> resourceCultures = null;
|
||||||
|
if (compilerOptions.EmbedInclude == null)
|
||||||
|
{
|
||||||
|
resourceCultures = context.ProjectFile.Files.ResourceFiles
|
||||||
.Select(resourceFile => ResourceUtility.GetResourceCultureName(resourceFile.Key))
|
.Select(resourceFile => ResourceUtility.GetResourceCultureName(resourceFile.Key))
|
||||||
.Distinct();
|
.Distinct();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var includeFiles = IncludeFilesResolver.GetIncludeFiles(compilerOptions.EmbedInclude, "/", diagnostics: null);
|
||||||
|
resourceCultures = includeFiles
|
||||||
|
.Select(file => ResourceUtility.GetResourceCultureName(file.SourcePath))
|
||||||
|
.Distinct();
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var culture in resourceCultures)
|
foreach (var culture in resourceCultures)
|
||||||
{
|
{
|
||||||
|
@ -112,7 +121,12 @@ namespace Microsoft.DotNet.Tools.Compiler
|
||||||
PackageBuilder.Files.Add(file);
|
PackageBuilder.Files.Add(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Project.Files.PackInclude != null && Project.Files.PackInclude.Any())
|
if (Project.PackOptions.PackInclude != null)
|
||||||
|
{
|
||||||
|
var files = IncludeFilesResolver.GetIncludeFiles(Project.PackOptions.PackInclude, "/", diagnostics: packDiagnostics, flatten: true);
|
||||||
|
PackageBuilder.Files.AddRange(GetPackageFiles(files, packDiagnostics));
|
||||||
|
}
|
||||||
|
else if (Project.Files.PackInclude != null && Project.Files.PackInclude.Any())
|
||||||
{
|
{
|
||||||
AddPackageFiles(Project.Files.PackInclude, packDiagnostics);
|
AddPackageFiles(Project.Files.PackInclude, packDiagnostics);
|
||||||
}
|
}
|
||||||
|
@ -237,6 +251,20 @@ namespace Microsoft.DotNet.Tools.Compiler
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static IEnumerable<PhysicalPackageFile> GetPackageFiles(
|
||||||
|
IEnumerable<IncludeEntry> includeFiles,
|
||||||
|
IList<DiagnosticMessage> diagnostics)
|
||||||
|
{
|
||||||
|
foreach (var entry in includeFiles)
|
||||||
|
{
|
||||||
|
yield return new PhysicalPackageFile()
|
||||||
|
{
|
||||||
|
SourcePath = PathUtility.GetPathWithDirectorySeparator(entry.SourcePath),
|
||||||
|
TargetPath = PathUtility.GetPathWithDirectorySeparator(entry.TargetPath)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void TryAddOutputFile(ProjectContext context,
|
protected void TryAddOutputFile(ProjectContext context,
|
||||||
string outputPath,
|
string outputPath,
|
||||||
string filePath)
|
string filePath)
|
||||||
|
@ -333,7 +361,7 @@ namespace Microsoft.DotNet.Tools.Compiler
|
||||||
{
|
{
|
||||||
var builder = new PackageBuilder();
|
var builder = new PackageBuilder();
|
||||||
builder.Authors.AddRange(project.Authors);
|
builder.Authors.AddRange(project.Authors);
|
||||||
builder.Owners.AddRange(project.Owners);
|
builder.Owners.AddRange(project.PackOptions.Owners);
|
||||||
|
|
||||||
if (builder.Authors.Count == 0)
|
if (builder.Authors.Count == 0)
|
||||||
{
|
{
|
||||||
|
@ -352,26 +380,26 @@ namespace Microsoft.DotNet.Tools.Compiler
|
||||||
builder.Id = project.Name;
|
builder.Id = project.Name;
|
||||||
builder.Version = project.Version;
|
builder.Version = project.Version;
|
||||||
builder.Title = project.Title;
|
builder.Title = project.Title;
|
||||||
builder.Summary = project.Summary;
|
builder.Summary = project.PackOptions.Summary;
|
||||||
builder.Copyright = project.Copyright;
|
builder.Copyright = project.Copyright;
|
||||||
builder.RequireLicenseAcceptance = project.RequireLicenseAcceptance;
|
builder.RequireLicenseAcceptance = project.PackOptions.RequireLicenseAcceptance;
|
||||||
builder.ReleaseNotes = project.ReleaseNotes;
|
builder.ReleaseNotes = project.PackOptions.ReleaseNotes;
|
||||||
builder.Language = project.Language;
|
builder.Language = project.Language;
|
||||||
builder.Tags.AddRange(project.Tags);
|
builder.Tags.AddRange(project.PackOptions.Tags);
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(project.IconUrl))
|
if (!string.IsNullOrEmpty(project.PackOptions.IconUrl))
|
||||||
{
|
{
|
||||||
builder.IconUrl = new Uri(project.IconUrl);
|
builder.IconUrl = new Uri(project.PackOptions.IconUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(project.ProjectUrl))
|
if (!string.IsNullOrEmpty(project.PackOptions.ProjectUrl))
|
||||||
{
|
{
|
||||||
builder.ProjectUrl = new Uri(project.ProjectUrl);
|
builder.ProjectUrl = new Uri(project.PackOptions.ProjectUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(project.LicenseUrl))
|
if (!string.IsNullOrEmpty(project.PackOptions.LicenseUrl))
|
||||||
{
|
{
|
||||||
builder.LicenseUrl = new Uri(project.LicenseUrl);
|
builder.LicenseUrl = new Uri(project.PackOptions.LicenseUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
return builder;
|
return builder;
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
// 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.
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
|
|
||||||
using Microsoft.DotNet.ProjectModel;
|
|
||||||
using NuGet;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using Microsoft.DotNet.ProjectModel;
|
||||||
|
using Microsoft.DotNet.ProjectModel.Files;
|
||||||
using Microsoft.DotNet.Tools.Pack;
|
using Microsoft.DotNet.Tools.Pack;
|
||||||
|
using NuGet;
|
||||||
|
|
||||||
namespace Microsoft.DotNet.Tools.Compiler
|
namespace Microsoft.DotNet.Tools.Compiler
|
||||||
{
|
{
|
||||||
|
@ -33,6 +34,11 @@ namespace Microsoft.DotNet.Tools.Compiler
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool GeneratePackage(string nupkg, List<DiagnosticMessage> packDiagnostics)
|
protected override bool GeneratePackage(string nupkg, List<DiagnosticMessage> packDiagnostics)
|
||||||
|
{
|
||||||
|
var compilerOptions = Project.GetCompilerOptions(
|
||||||
|
Project.GetTargetFramework(targetFramework: null).FrameworkName, Configuration);
|
||||||
|
|
||||||
|
if (compilerOptions.CompileInclude == null)
|
||||||
{
|
{
|
||||||
foreach (var path in Project.Files.SourceFiles)
|
foreach (var path in Project.Files.SourceFiles)
|
||||||
{
|
{
|
||||||
|
@ -44,6 +50,22 @@ namespace Microsoft.DotNet.Tools.Compiler
|
||||||
|
|
||||||
PackageBuilder.Files.Add(srcFile);
|
PackageBuilder.Files.Add(srcFile);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var includeFiles = IncludeFilesResolver.GetIncludeFiles(compilerOptions.CompileInclude, "/", diagnostics: null);
|
||||||
|
foreach (var entry in includeFiles)
|
||||||
|
{
|
||||||
|
var srcFile = new PhysicalPackageFile
|
||||||
|
{
|
||||||
|
SourcePath = entry.SourcePath,
|
||||||
|
TargetPath = Path.Combine("src", entry.TargetPath)
|
||||||
|
};
|
||||||
|
|
||||||
|
PackageBuilder.Files.Add(srcFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return base.GeneratePackage(nupkg, packDiagnostics);
|
return base.GeneratePackage(nupkg, packDiagnostics);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,10 +4,11 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Microsoft.DotNet.Cli.Compiler.Common;
|
||||||
|
using Microsoft.DotNet.ProjectModel.Files;
|
||||||
using Microsoft.DotNet.ProjectModel.Graph;
|
using Microsoft.DotNet.ProjectModel.Graph;
|
||||||
using Microsoft.DotNet.ProjectModel.Server.Helpers;
|
using Microsoft.DotNet.ProjectModel.Server.Helpers;
|
||||||
using Microsoft.DotNet.ProjectModel.Server.Models;
|
using Microsoft.DotNet.ProjectModel.Server.Models;
|
||||||
using Microsoft.DotNet.Cli.Compiler.Common;
|
|
||||||
using NuGet.Frameworks;
|
using NuGet.Frameworks;
|
||||||
|
|
||||||
namespace Microsoft.DotNet.ProjectModel.Server
|
namespace Microsoft.DotNet.ProjectModel.Server
|
||||||
|
@ -37,7 +38,7 @@ namespace Microsoft.DotNet.ProjectModel.Server
|
||||||
.GetAllExports()
|
.GetAllExports()
|
||||||
.ToDictionary(export => export.Library.Identity.Name);
|
.ToDictionary(export => export.Library.Identity.Name);
|
||||||
|
|
||||||
var allSourceFiles = new List<string>(context.ProjectFile.Files.SourceFiles);
|
var allSourceFiles = new List<string>(GetSourceFiles(context, configuration));
|
||||||
var allFileReferences = new List<string>();
|
var allFileReferences = new List<string>();
|
||||||
var allProjectReferences = new List<ProjectReferenceDescription>();
|
var allProjectReferences = new List<ProjectReferenceDescription>();
|
||||||
var allDependencies = new Dictionary<string, DependencyDescription>();
|
var allDependencies = new Dictionary<string, DependencyDescription>();
|
||||||
|
@ -74,5 +75,19 @@ namespace Microsoft.DotNet.ProjectModel.Server
|
||||||
|
|
||||||
return snapshot;
|
return snapshot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static IEnumerable<string> GetSourceFiles(ProjectContext context, string configuration)
|
||||||
|
{
|
||||||
|
var compilerOptions = context.ProjectFile.GetCompilerOptions(context.TargetFramework, configuration);
|
||||||
|
|
||||||
|
if (compilerOptions.CompileInclude == null)
|
||||||
|
{
|
||||||
|
return context.ProjectFile.Files.SourceFiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
var includeFiles = IncludeFilesResolver.GetIncludeFiles(compilerOptions.CompileInclude, "/", diagnostics: null);
|
||||||
|
|
||||||
|
return includeFiles.Select(f => f.SourcePath);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ using Microsoft.DotNet.Cli.Utils;
|
||||||
using Microsoft.DotNet.Files;
|
using Microsoft.DotNet.Files;
|
||||||
using Microsoft.DotNet.ProjectModel;
|
using Microsoft.DotNet.ProjectModel;
|
||||||
using Microsoft.DotNet.ProjectModel.Compilation;
|
using Microsoft.DotNet.ProjectModel.Compilation;
|
||||||
|
using Microsoft.DotNet.ProjectModel.Files;
|
||||||
using Microsoft.DotNet.ProjectModel.Graph;
|
using Microsoft.DotNet.ProjectModel.Graph;
|
||||||
using Microsoft.DotNet.ProjectModel.Utilities;
|
using Microsoft.DotNet.ProjectModel.Utilities;
|
||||||
using Microsoft.DotNet.Tools.Common;
|
using Microsoft.DotNet.Tools.Common;
|
||||||
|
@ -179,7 +180,20 @@ namespace Microsoft.DotNet.Tools.Publish
|
||||||
}
|
}
|
||||||
|
|
||||||
var contentFiles = new ContentFiles(context);
|
var contentFiles = new ContentFiles(context);
|
||||||
|
|
||||||
|
if (context.ProjectFile.PublishOptions != null)
|
||||||
|
{
|
||||||
|
var includeEntries = IncludeFilesResolver.GetIncludeFiles(
|
||||||
|
context.ProjectFile.PublishOptions,
|
||||||
|
PathUtility.EnsureTrailingSlash(outputPath),
|
||||||
|
diagnostics: null);
|
||||||
|
|
||||||
|
contentFiles.StructuredCopyTo(outputPath, includeEntries);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
contentFiles.StructuredCopyTo(outputPath);
|
contentFiles.StructuredCopyTo(outputPath);
|
||||||
|
}
|
||||||
|
|
||||||
// Publish a host if this is an application
|
// Publish a host if this is an application
|
||||||
if (options.EmitEntryPoint.GetValueOrDefault() && !string.IsNullOrEmpty(context.RuntimeIdentifier))
|
if (options.EmitEntryPoint.GetValueOrDefault() && !string.IsNullOrEmpty(context.RuntimeIdentifier))
|
||||||
|
@ -446,51 +460,6 @@ namespace Microsoft.DotNet.Tools.Publish
|
||||||
return contexts.Select(c => Workspace.GetRuntimeContext(c, rids));
|
return contexts.Select(c => Workspace.GetRuntimeContext(c, rids));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void CopyContents(ProjectContext context, string outputPath)
|
|
||||||
{
|
|
||||||
var contentFiles = context.ProjectFile.Files.GetContentFiles();
|
|
||||||
Copy(contentFiles, context.ProjectDirectory, outputPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void Copy(IEnumerable<string> contentFiles, string sourceDirectory, string targetDirectory)
|
|
||||||
{
|
|
||||||
if (contentFiles == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(contentFiles));
|
|
||||||
}
|
|
||||||
|
|
||||||
sourceDirectory = PathUtility.EnsureTrailingSlash(sourceDirectory);
|
|
||||||
targetDirectory = PathUtility.EnsureTrailingSlash(targetDirectory);
|
|
||||||
|
|
||||||
foreach (var contentFilePath in contentFiles)
|
|
||||||
{
|
|
||||||
Reporter.Verbose.WriteLine($"Publishing {contentFilePath.Green().Bold()} ...");
|
|
||||||
|
|
||||||
var fileName = Path.GetFileName(contentFilePath);
|
|
||||||
|
|
||||||
var targetFilePath = contentFilePath.Replace(sourceDirectory, targetDirectory);
|
|
||||||
var targetFileParentFolder = Path.GetDirectoryName(targetFilePath);
|
|
||||||
|
|
||||||
// Create directory before copying a file
|
|
||||||
if (!Directory.Exists(targetFileParentFolder))
|
|
||||||
{
|
|
||||||
Directory.CreateDirectory(targetFileParentFolder);
|
|
||||||
}
|
|
||||||
|
|
||||||
File.Copy(
|
|
||||||
contentFilePath,
|
|
||||||
targetFilePath,
|
|
||||||
overwrite: true);
|
|
||||||
|
|
||||||
// clear read-only bit if set
|
|
||||||
var fileAttributes = File.GetAttributes(targetFilePath);
|
|
||||||
if ((fileAttributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
|
|
||||||
{
|
|
||||||
File.SetAttributes(targetFilePath, fileAttributes & ~FileAttributes.ReadOnly);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void RunScripts(ProjectContext context, string name, Dictionary<string, string> contextVariables)
|
private static void RunScripts(ProjectContext context, string name, Dictionary<string, string> contextVariables)
|
||||||
{
|
{
|
||||||
foreach (var script in context.ProjectFile.Scripts.GetOrEmpty(name))
|
foreach (var script in context.ProjectFile.Scripts.GetOrEmpty(name))
|
||||||
|
|
|
@ -83,7 +83,6 @@ namespace Microsoft.DotNet.ProjectModel.Tests
|
||||||
stream,
|
stream,
|
||||||
ProjectName,
|
ProjectName,
|
||||||
ProjectFilePath,
|
ProjectFilePath,
|
||||||
new List<DiagnosticMessage>(),
|
|
||||||
settings);
|
settings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,216 @@
|
||||||
|
// 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;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using FluentAssertions;
|
||||||
|
using Microsoft.DotNet.ProjectModel.Files;
|
||||||
|
using Microsoft.DotNet.ProjectModel.Utilities;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.DotNet.ProjectModel.Tests
|
||||||
|
{
|
||||||
|
public class GivenThatIWantToCreateIncludeEntriesFromJson
|
||||||
|
{
|
||||||
|
private const string ProjectName = "some project name";
|
||||||
|
private readonly string ProjectFilePath = PathUtility.EnsureTrailingSlash(AppContext.BaseDirectory);
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void PackInclude_is_null_when_it_is_not_set_in_the_ProjectJson()
|
||||||
|
{
|
||||||
|
var json = new JObject();
|
||||||
|
var project = GetProject(json);
|
||||||
|
|
||||||
|
project.PackOptions.PackInclude.Should().BeNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void It_sets_PackInclude_when_packInclude_is_set_in_the_ProjectJson()
|
||||||
|
{
|
||||||
|
const string somePackTarget = "some pack target";
|
||||||
|
const string somePackValue = "ff/files/file1.txt";
|
||||||
|
|
||||||
|
var json = JObject.Parse(string.Format(@"{{
|
||||||
|
'packOptions': {{
|
||||||
|
'files': {{
|
||||||
|
'mappings': {{
|
||||||
|
'{0}': {{
|
||||||
|
'includeFiles': '{1}'
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
}}}}", somePackTarget, somePackValue));
|
||||||
|
|
||||||
|
CreateFile(somePackValue);
|
||||||
|
var project = GetProject(json);
|
||||||
|
|
||||||
|
var packInclude = GetIncludeFiles(project.PackOptions.PackInclude, "/").FirstOrDefault();
|
||||||
|
|
||||||
|
packInclude.TargetPath.Should().Be(somePackTarget);
|
||||||
|
packInclude.SourcePath.Should().Contain(PathUtility.GetPathWithDirectorySeparator(somePackValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void It_parses_compile_and_includes_files_successfully()
|
||||||
|
{
|
||||||
|
var json = JObject.Parse(@"{
|
||||||
|
'buildOptions': {
|
||||||
|
'compile': {
|
||||||
|
'includeFiles': [ 'files/file1.cs', 'files/file2.cs' ],
|
||||||
|
'exclude': 'files/*ex.cs'
|
||||||
|
}
|
||||||
|
}}");
|
||||||
|
|
||||||
|
CreateFile("files/file1.cs");
|
||||||
|
CreateFile("files/file2.cs");
|
||||||
|
CreateFile("files/file1ex.cs");
|
||||||
|
CreateFile("files/file2ex.cs");
|
||||||
|
|
||||||
|
var project = GetProject(json);
|
||||||
|
|
||||||
|
var compileInclude = GetIncludeFiles(project.GetCompilerOptions(null, null).CompileInclude, "/").ToArray();
|
||||||
|
|
||||||
|
compileInclude.Should().HaveCount(2);
|
||||||
|
|
||||||
|
compileInclude.Should().Contain(
|
||||||
|
entry => entry.TargetPath == PathUtility.GetPathWithDirectorySeparator("files/file1.cs") &&
|
||||||
|
entry.SourcePath.Contains(PathUtility.GetPathWithDirectorySeparator("files/file1.cs")));
|
||||||
|
|
||||||
|
compileInclude.Should().Contain(
|
||||||
|
entry => entry.TargetPath == PathUtility.GetPathWithDirectorySeparator("files/file2.cs") &&
|
||||||
|
entry.SourcePath.Contains(PathUtility.GetPathWithDirectorySeparator("files/file2.cs")));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void It_parses_namedResources_successfully()
|
||||||
|
{
|
||||||
|
const string someString = "some string";
|
||||||
|
const string someResourcePattern = "files/*.resx";
|
||||||
|
|
||||||
|
var json = JObject.Parse(string.Format(@"{{
|
||||||
|
'buildOptions': {{
|
||||||
|
'embed': {{
|
||||||
|
'mappings': {{
|
||||||
|
'{0}': {{
|
||||||
|
'include': '{1}'
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
}}}}", someString, someResourcePattern));
|
||||||
|
|
||||||
|
CreateFile("files/Resource.resx");
|
||||||
|
|
||||||
|
var project = GetProject(json);
|
||||||
|
|
||||||
|
var embedInclude = GetIncludeFiles(project.GetCompilerOptions(null, null).EmbedInclude, "/").FirstOrDefault();
|
||||||
|
|
||||||
|
embedInclude.TargetPath.Should().Be(someString);
|
||||||
|
embedInclude.SourcePath.Should().Contain(PathUtility.GetPathWithDirectorySeparator("files/Resource.resx"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void It_parses_copyToOutput_and_includes_files_successfully()
|
||||||
|
{
|
||||||
|
var json = JObject.Parse(@"{
|
||||||
|
'buildOptions': {
|
||||||
|
'copyToOutput': {
|
||||||
|
'include': 'files/*.txt',
|
||||||
|
'exclude': 'files/p*.txt',
|
||||||
|
'excludeFiles': 'files/file1ex.txt',
|
||||||
|
}
|
||||||
|
}}");
|
||||||
|
|
||||||
|
CreateFile("files/file1.txt");
|
||||||
|
CreateFile("files/file2.txt");
|
||||||
|
CreateFile("files/file1ex.txt");
|
||||||
|
|
||||||
|
var project = GetProject(json);
|
||||||
|
|
||||||
|
var copyToOutputInclude = GetIncludeFiles(project.GetCompilerOptions(null, null).CopyToOutputInclude, "/").ToArray();
|
||||||
|
|
||||||
|
copyToOutputInclude.Should().HaveCount(2);
|
||||||
|
|
||||||
|
copyToOutputInclude.Should().Contain(
|
||||||
|
entry => entry.TargetPath == PathUtility.GetPathWithDirectorySeparator("files/file1.txt") &&
|
||||||
|
entry.SourcePath.Contains(PathUtility.GetPathWithDirectorySeparator("files/file1.txt")));
|
||||||
|
|
||||||
|
copyToOutputInclude.Should().Contain(
|
||||||
|
entry => entry.TargetPath == PathUtility.GetPathWithDirectorySeparator("files/file2.txt") &&
|
||||||
|
entry.SourcePath.Contains(PathUtility.GetPathWithDirectorySeparator("files/file2.txt")));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void It_parses_PublishOptions_and_includes_files_successfully()
|
||||||
|
{
|
||||||
|
var json = JObject.Parse(@"{
|
||||||
|
'publishOptions': {
|
||||||
|
'include': 'files/p*.txt',
|
||||||
|
'exclude': 'files/*ex.txt',
|
||||||
|
'includeFiles': 'files/pfile2ex.txt'
|
||||||
|
}}");
|
||||||
|
|
||||||
|
CreateFile("files/pfile1.txt");
|
||||||
|
CreateFile("files/pfile1ex.txt");
|
||||||
|
CreateFile("files/pfile2ex.txt");
|
||||||
|
|
||||||
|
var project = GetProject(json);
|
||||||
|
|
||||||
|
var publishOptions = GetIncludeFiles(project.PublishOptions, "/").ToArray();
|
||||||
|
|
||||||
|
publishOptions.Should().HaveCount(2);
|
||||||
|
|
||||||
|
publishOptions.Should().Contain(
|
||||||
|
entry => entry.TargetPath == PathUtility.GetPathWithDirectorySeparator("files/pfile1.txt") &&
|
||||||
|
entry.SourcePath.Contains(PathUtility.GetPathWithDirectorySeparator("files/pfile1.txt")));
|
||||||
|
|
||||||
|
publishOptions.Should().Contain(
|
||||||
|
entry => entry.TargetPath == PathUtility.GetPathWithDirectorySeparator("files/pfile2ex.txt") &&
|
||||||
|
entry.SourcePath.Contains(PathUtility.GetPathWithDirectorySeparator("files/pfile2ex.txt")));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Project GetProject(JObject json, ProjectReaderSettings settings = null)
|
||||||
|
{
|
||||||
|
using (var stream = new MemoryStream())
|
||||||
|
{
|
||||||
|
using (var sw = new StreamWriter(stream, Encoding.UTF8, 256, true))
|
||||||
|
{
|
||||||
|
using (var writer = new JsonTextWriter(sw))
|
||||||
|
{
|
||||||
|
writer.Formatting = Formatting.Indented;
|
||||||
|
json.WriteTo(writer);
|
||||||
|
}
|
||||||
|
|
||||||
|
stream.Position = 0;
|
||||||
|
var projectReader = new ProjectReader();
|
||||||
|
return projectReader.ReadProject(
|
||||||
|
stream,
|
||||||
|
ProjectName,
|
||||||
|
ProjectFilePath,
|
||||||
|
settings);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private IEnumerable<IncludeEntry> GetIncludeFiles(IncludeContext context, string targetBasePath)
|
||||||
|
{
|
||||||
|
return IncludeFilesResolver.GetIncludeFiles(context, targetBasePath, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CreateFile(string filePath)
|
||||||
|
{
|
||||||
|
filePath = Path.Combine(ProjectFilePath, filePath);
|
||||||
|
var dirName = Path.GetDirectoryName(filePath);
|
||||||
|
if (!Directory.Exists(dirName))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(dirName);
|
||||||
|
}
|
||||||
|
|
||||||
|
File.Create(filePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,6 +22,7 @@ namespace Microsoft.DotNet.ProjectModel.Tests
|
||||||
private const string ProjectName = "some project name";
|
private const string ProjectName = "some project name";
|
||||||
private const string SomeLanguageVersion = "some language version";
|
private const string SomeLanguageVersion = "some language version";
|
||||||
private const string SomeOutputName = "some output name";
|
private const string SomeOutputName = "some output name";
|
||||||
|
private const string SomeCompilerName = "some compiler name";
|
||||||
private const string SomePlatform = "some platform";
|
private const string SomePlatform = "some platform";
|
||||||
private const string SomeKeyFile = "some key file";
|
private const string SomeKeyFile = "some key file";
|
||||||
private const string SomeDebugType = "some debug type";
|
private const string SomeDebugType = "some debug type";
|
||||||
|
@ -49,6 +50,7 @@ namespace Microsoft.DotNet.ProjectModel.Tests
|
||||||
_jsonCompilationOptions.Add("additionalArguments", new JArray(_someAdditionalArguments));
|
_jsonCompilationOptions.Add("additionalArguments", new JArray(_someAdditionalArguments));
|
||||||
_jsonCompilationOptions.Add("languageVersion", SomeLanguageVersion);
|
_jsonCompilationOptions.Add("languageVersion", SomeLanguageVersion);
|
||||||
_jsonCompilationOptions.Add("outputName", SomeOutputName);
|
_jsonCompilationOptions.Add("outputName", SomeOutputName);
|
||||||
|
_jsonCompilationOptions.Add("compilerName", SomeCompilerName);
|
||||||
_jsonCompilationOptions.Add("platform", SomePlatform);
|
_jsonCompilationOptions.Add("platform", SomePlatform);
|
||||||
_jsonCompilationOptions.Add("keyFile", SomeKeyFile);
|
_jsonCompilationOptions.Add("keyFile", SomeKeyFile);
|
||||||
_jsonCompilationOptions.Add("debugType", SomeDebugType);
|
_jsonCompilationOptions.Add("debugType", SomeDebugType);
|
||||||
|
@ -68,6 +70,7 @@ namespace Microsoft.DotNet.ProjectModel.Tests
|
||||||
AdditionalArguments = _someAdditionalArguments,
|
AdditionalArguments = _someAdditionalArguments,
|
||||||
LanguageVersion = SomeLanguageVersion,
|
LanguageVersion = SomeLanguageVersion,
|
||||||
OutputName = SomeOutputName,
|
OutputName = SomeOutputName,
|
||||||
|
CompilerName = SomeCompilerName,
|
||||||
Platform = SomePlatform,
|
Platform = SomePlatform,
|
||||||
KeyFile = SomeKeyFile,
|
KeyFile = SomeKeyFile,
|
||||||
DebugType = SomeDebugType,
|
DebugType = SomeDebugType,
|
||||||
|
@ -168,18 +171,18 @@ namespace Microsoft.DotNet.ProjectModel.Tests
|
||||||
public void It_leaves_marketing_information_empty_when_it_is_not_set_in_the_ProjectJson()
|
public void It_leaves_marketing_information_empty_when_it_is_not_set_in_the_ProjectJson()
|
||||||
{
|
{
|
||||||
_emptyProject.Description.Should().BeNull();
|
_emptyProject.Description.Should().BeNull();
|
||||||
_emptyProject.Summary.Should().BeNull();
|
_emptyProject.PackOptions.Summary.Should().BeNull();
|
||||||
_emptyProject.Copyright.Should().BeNull();
|
_emptyProject.Copyright.Should().BeNull();
|
||||||
_emptyProject.Title.Should().BeNull();
|
_emptyProject.Title.Should().BeNull();
|
||||||
_emptyProject.EntryPoint.Should().BeNull();
|
_emptyProject.EntryPoint.Should().BeNull();
|
||||||
_emptyProject.ProjectUrl.Should().BeNull();
|
_emptyProject.PackOptions.ProjectUrl.Should().BeNull();
|
||||||
_emptyProject.LicenseUrl.Should().BeNull();
|
_emptyProject.PackOptions.LicenseUrl.Should().BeNull();
|
||||||
_emptyProject.IconUrl.Should().BeNull();
|
_emptyProject.PackOptions.IconUrl.Should().BeNull();
|
||||||
_emptyProject.Authors.Should().BeEmpty();
|
_emptyProject.Authors.Should().BeEmpty();
|
||||||
_emptyProject.Owners.Should().BeEmpty();
|
_emptyProject.PackOptions.Owners.Should().BeEmpty();
|
||||||
_emptyProject.Tags.Should().BeEmpty();
|
_emptyProject.PackOptions.Tags.Should().BeEmpty();
|
||||||
_emptyProject.Language.Should().BeNull();
|
_emptyProject.Language.Should().BeNull();
|
||||||
_emptyProject.ReleaseNotes.Should().BeNull();
|
_emptyProject.PackOptions.ReleaseNotes.Should().BeNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
@ -216,24 +219,105 @@ namespace Microsoft.DotNet.ProjectModel.Tests
|
||||||
var project = GetProject(json);
|
var project = GetProject(json);
|
||||||
|
|
||||||
project.Description.Should().Be(someDescription);
|
project.Description.Should().Be(someDescription);
|
||||||
project.Summary.Should().Be(someSummary);
|
project.PackOptions.Summary.Should().Be(someSummary);
|
||||||
project.Copyright.Should().Be(someCopyright);
|
project.Copyright.Should().Be(someCopyright);
|
||||||
project.Title.Should().Be(someTitle);
|
project.Title.Should().Be(someTitle);
|
||||||
project.EntryPoint.Should().Be(someEntryPoint);
|
project.EntryPoint.Should().Be(someEntryPoint);
|
||||||
project.ProjectUrl.Should().Be(someProjectUrl);
|
project.PackOptions.ProjectUrl.Should().Be(someProjectUrl);
|
||||||
project.LicenseUrl.Should().Be(someLicenseUrl);
|
project.PackOptions.LicenseUrl.Should().Be(someLicenseUrl);
|
||||||
project.IconUrl.Should().Be(someIconUrl);
|
project.PackOptions.IconUrl.Should().Be(someIconUrl);
|
||||||
project.Authors.Should().Contain(authors);
|
project.Authors.Should().Contain(authors);
|
||||||
project.Owners.Should().Contain(owners);
|
project.PackOptions.Owners.Should().Contain(owners);
|
||||||
project.Tags.Should().Contain(tags);
|
project.PackOptions.Tags.Should().Contain(tags);
|
||||||
project.Language.Should().Be(someLanguage);
|
project.Language.Should().Be(someLanguage);
|
||||||
project.ReleaseNotes.Should().Be(someReleaseNotes);
|
project.PackOptions.ReleaseNotes.Should().Be(someReleaseNotes);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void It_sets_the_marketing_information_when_it_is_set_in_the_ProjectJson_PackOptions()
|
||||||
|
{
|
||||||
|
const string someDescription = "some description";
|
||||||
|
const string someSummary = "some summary";
|
||||||
|
const string someCopyright = "some copyright";
|
||||||
|
const string someTitle = "some title";
|
||||||
|
const string someEntryPoint = "some entry point";
|
||||||
|
const string someProjectUrl = "some project url";
|
||||||
|
const string someLicenseUrl = "some license url";
|
||||||
|
const string someIconUrl = "some icon url";
|
||||||
|
const string someLanguage = "some language";
|
||||||
|
const string someReleaseNotes = "someReleaseNotes";
|
||||||
|
var authors = new[] { "some author", "and another author" };
|
||||||
|
var owners = new[] { "some owner", "a second owner" };
|
||||||
|
var tags = new[] { "tag1", "tag2" };
|
||||||
|
|
||||||
|
var json = new JObject();
|
||||||
|
var packOptions = new JObject();
|
||||||
|
|
||||||
|
json.Add("description", someDescription);
|
||||||
|
json.Add("copyright", someCopyright);
|
||||||
|
json.Add("title", someTitle);
|
||||||
|
json.Add("entryPoint", someEntryPoint);
|
||||||
|
json.Add("authors", new JArray(authors));
|
||||||
|
json.Add("language", someLanguage);
|
||||||
|
packOptions.Add("summary", someSummary);
|
||||||
|
packOptions.Add("projectUrl", someProjectUrl);
|
||||||
|
packOptions.Add("licenseUrl", someLicenseUrl);
|
||||||
|
packOptions.Add("iconUrl", someIconUrl);
|
||||||
|
packOptions.Add("owners", new JArray(owners));
|
||||||
|
packOptions.Add("tags", new JArray(tags));
|
||||||
|
packOptions.Add("releaseNotes", someReleaseNotes);
|
||||||
|
json.Add("packOptions", packOptions);
|
||||||
|
|
||||||
|
var project = GetProject(json);
|
||||||
|
|
||||||
|
project.Description.Should().Be(someDescription);
|
||||||
|
project.PackOptions.Summary.Should().Be(someSummary);
|
||||||
|
project.Copyright.Should().Be(someCopyright);
|
||||||
|
project.Title.Should().Be(someTitle);
|
||||||
|
project.EntryPoint.Should().Be(someEntryPoint);
|
||||||
|
project.PackOptions.ProjectUrl.Should().Be(someProjectUrl);
|
||||||
|
project.PackOptions.LicenseUrl.Should().Be(someLicenseUrl);
|
||||||
|
project.PackOptions.IconUrl.Should().Be(someIconUrl);
|
||||||
|
project.Authors.Should().Contain(authors);
|
||||||
|
project.PackOptions.Owners.Should().Contain(owners);
|
||||||
|
project.PackOptions.Tags.Should().Contain(tags);
|
||||||
|
project.Language.Should().Be(someLanguage);
|
||||||
|
project.PackOptions.ReleaseNotes.Should().Be(someReleaseNotes);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void It_warns_when_deprecated_schema_is_used()
|
||||||
|
{
|
||||||
|
var json = new JObject();
|
||||||
|
|
||||||
|
json.Add("compilerName", "some compiler");
|
||||||
|
json.Add("compilationOptions", new JObject());
|
||||||
|
json.Add("projectUrl", "some project url");
|
||||||
|
|
||||||
|
var project = GetProject(json);
|
||||||
|
|
||||||
|
project.Diagnostics.Should().HaveCount(3);
|
||||||
|
|
||||||
|
project.Diagnostics.Should().Contain(m =>
|
||||||
|
m.ErrorCode == ErrorCodes.DOTNET1015 &&
|
||||||
|
m.Severity == DiagnosticMessageSeverity.Warning &&
|
||||||
|
m.Message == "The 'compilationOptions' option is deprecated. Use 'buildOptions' instead.");
|
||||||
|
|
||||||
|
project.Diagnostics.Should().Contain(m =>
|
||||||
|
m.ErrorCode == ErrorCodes.DOTNET1016 &&
|
||||||
|
m.Severity == DiagnosticMessageSeverity.Warning &&
|
||||||
|
m.Message == "The 'projectUrl' option in the root is deprecated. Use it in 'packOptions' instead.");
|
||||||
|
|
||||||
|
project.Diagnostics.Should().Contain(m =>
|
||||||
|
m.ErrorCode == ErrorCodes.DOTNET1016 &&
|
||||||
|
m.Severity == DiagnosticMessageSeverity.Warning &&
|
||||||
|
m.Message == "The 'compilerName' option in the root is deprecated. Use it in 'buildOptions' instead.");
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void It_sets_the_compilerName_to_csc_when_one_is_not_set_in_the_ProjectJson()
|
public void It_sets_the_compilerName_to_csc_when_one_is_not_set_in_the_ProjectJson()
|
||||||
{
|
{
|
||||||
_emptyProject.CompilerName.Should().Be("csc");
|
_emptyProject.GetCompilerOptions(targetFramework: null, configurationName: null).CompilerName.Should().Be("csc");
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
@ -244,7 +328,7 @@ namespace Microsoft.DotNet.ProjectModel.Tests
|
||||||
json.Add("compilerName", compilerName);
|
json.Add("compilerName", compilerName);
|
||||||
var project = GetProject(json);
|
var project = GetProject(json);
|
||||||
|
|
||||||
project.CompilerName.Should().Be(compilerName);
|
project.GetCompilerOptions(targetFramework: null, configurationName: null).CompilerName.Should().Be(compilerName);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
@ -267,7 +351,7 @@ namespace Microsoft.DotNet.ProjectModel.Tests
|
||||||
[Fact]
|
[Fact]
|
||||||
public void It_sets_requireLicenseAcceptance_to_false_when_one_is_not_set_in_the_ProjectJson()
|
public void It_sets_requireLicenseAcceptance_to_false_when_one_is_not_set_in_the_ProjectJson()
|
||||||
{
|
{
|
||||||
_emptyProject.RequireLicenseAcceptance.Should().BeFalse();
|
_emptyProject.PackOptions.RequireLicenseAcceptance.Should().BeFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
@ -277,7 +361,7 @@ namespace Microsoft.DotNet.ProjectModel.Tests
|
||||||
json.Add("requireLicenseAcceptance", true);
|
json.Add("requireLicenseAcceptance", true);
|
||||||
var project = GetProject(json);
|
var project = GetProject(json);
|
||||||
|
|
||||||
project.RequireLicenseAcceptance.Should().BeTrue();
|
project.PackOptions.RequireLicenseAcceptance.Should().BeTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
@ -287,7 +371,7 @@ namespace Microsoft.DotNet.ProjectModel.Tests
|
||||||
json.Add("requireLicenseAcceptance", false);
|
json.Add("requireLicenseAcceptance", false);
|
||||||
var project = GetProject(json);
|
var project = GetProject(json);
|
||||||
|
|
||||||
project.RequireLicenseAcceptance.Should().BeFalse();
|
project.PackOptions.RequireLicenseAcceptance.Should().BeFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
@ -405,7 +489,8 @@ namespace Microsoft.DotNet.ProjectModel.Tests
|
||||||
{
|
{
|
||||||
_emptyProject.GetCompilerOptions(null, null).Should().Be(new CommonCompilerOptions
|
_emptyProject.GetCompilerOptions(null, null).Should().Be(new CommonCompilerOptions
|
||||||
{
|
{
|
||||||
OutputName = ProjectName
|
OutputName = ProjectName,
|
||||||
|
CompilerName = "csc"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -471,6 +556,17 @@ namespace Microsoft.DotNet.ProjectModel.Tests
|
||||||
project.GetCompilerOptions(null, null).Should().Be(_commonCompilerOptions);
|
project.GetCompilerOptions(null, null).Should().Be(_commonCompilerOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void It_sets_buildOptions_when_it_is_set_in_the_compilationOptions_in_the_ProjectJson()
|
||||||
|
{
|
||||||
|
var json = new JObject();
|
||||||
|
json.Add("buildOptions", _jsonCompilationOptions);
|
||||||
|
|
||||||
|
var project = GetProject(json);
|
||||||
|
|
||||||
|
project.GetCompilerOptions(null, null).Should().Be(_commonCompilerOptions);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void It_merges_configuration_sections_set_in_the_ProjectJson()
|
public void It_merges_configuration_sections_set_in_the_ProjectJson()
|
||||||
{
|
{
|
||||||
|
@ -874,7 +970,6 @@ namespace Microsoft.DotNet.ProjectModel.Tests
|
||||||
stream,
|
stream,
|
||||||
ProjectName,
|
ProjectName,
|
||||||
ProjectFilePath,
|
ProjectFilePath,
|
||||||
new List<DiagnosticMessage>(),
|
|
||||||
settings);
|
settings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -336,7 +336,10 @@ namespace Microsoft.DotNet.ProjectModel.Tests
|
||||||
var rootProject = new Project()
|
var rootProject = new Project()
|
||||||
{
|
{
|
||||||
Name = "RootProject",
|
Name = "RootProject",
|
||||||
|
_defaultCompilerOptions = new CommonCompilerOptions
|
||||||
|
{
|
||||||
CompilerName = "csc"
|
CompilerName = "csc"
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var rootProjectDescription = new ProjectDescription(
|
var rootProjectDescription = new ProjectDescription(
|
||||||
|
|
|
@ -147,6 +147,48 @@ namespace Microsoft.DotNet.Tools.Compiler.Tests
|
||||||
result.StdOut.Should().Contain("MyNamespace.Util");
|
result.StdOut.Should().Contain("MyNamespace.Util");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void EmbeddedResourcesAreCopied()
|
||||||
|
{
|
||||||
|
var testInstance = TestAssetsManager.CreateTestInstance("EndToEndTestApp")
|
||||||
|
.WithLockFiles()
|
||||||
|
.WithBuildArtifacts();
|
||||||
|
|
||||||
|
var root = testInstance.TestRoot;
|
||||||
|
|
||||||
|
// run compile
|
||||||
|
var outputDir = Path.Combine(root, "bin");
|
||||||
|
var testProject = ProjectUtils.GetProjectJson(root, "EndToEndTestApp");
|
||||||
|
var buildCommand = new BuildCommand(testProject, output: outputDir, framework: DefaultFramework);
|
||||||
|
var result = buildCommand.ExecuteWithCapturedOutput();
|
||||||
|
result.Should().Pass();
|
||||||
|
|
||||||
|
var objDirInfo = new DirectoryInfo(Path.Combine(root, "obj", "Debug", DefaultFramework));
|
||||||
|
objDirInfo.Should().HaveFile("EndToEndTestApp.resource1.resources");
|
||||||
|
objDirInfo.Should().HaveFile("myresource.resources");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void CopyToOutputFilesAreCopied()
|
||||||
|
{
|
||||||
|
var testInstance = TestAssetsManager.CreateTestInstance("EndToEndTestApp")
|
||||||
|
.WithLockFiles()
|
||||||
|
.WithBuildArtifacts();
|
||||||
|
|
||||||
|
var root = testInstance.TestRoot;
|
||||||
|
|
||||||
|
// run compile
|
||||||
|
var outputDir = Path.Combine(root, "bin");
|
||||||
|
var testProject = ProjectUtils.GetProjectJson(root, "EndToEndTestApp");
|
||||||
|
var buildCommand = new BuildCommand(testProject, output: outputDir, framework: DefaultFramework);
|
||||||
|
var result = buildCommand.ExecuteWithCapturedOutput();
|
||||||
|
result.Should().Pass();
|
||||||
|
|
||||||
|
var outputDirInfo = new DirectoryInfo(Path.Combine(outputDir, "copy"));
|
||||||
|
outputDirInfo.Should().HaveFile("file.txt");
|
||||||
|
outputDirInfo.Should().NotHaveFile("fileex.txt");
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void CanSetOutputAssemblyNameForLibraries()
|
public void CanSetOutputAssemblyNameForLibraries()
|
||||||
{
|
{
|
||||||
|
|
|
@ -95,6 +95,24 @@ namespace Microsoft.DotNet.Tools.Compiler.Tests
|
||||||
zip.Entries.Should().Contain(e => e.FullName == "lib/netstandard1.5/TestLibraryWithConfiguration.dll");
|
zip.Entries.Should().Contain(e => e.FullName == "lib/netstandard1.5/TestLibraryWithConfiguration.dll");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void HasIncludedFiles()
|
||||||
|
{
|
||||||
|
var testInstance = TestAssetsManager.CreateTestInstance("EndToEndTestApp")
|
||||||
|
.WithLockFiles()
|
||||||
|
.WithBuildArtifacts();
|
||||||
|
|
||||||
|
var cmd = new PackCommand(Path.Combine(testInstance.TestRoot, Project.FileName));
|
||||||
|
cmd.Execute().Should().Pass();
|
||||||
|
|
||||||
|
var outputPackage = Path.Combine(testInstance.TestRoot, "bin", "Debug", "EndToEndTestApp.1.0.0.nupkg");
|
||||||
|
File.Exists(outputPackage).Should().BeTrue(outputPackage);
|
||||||
|
|
||||||
|
var zip = ZipFile.Open(outputPackage, ZipArchiveMode.Read);
|
||||||
|
zip.Entries.Should().Contain(e => e.FullName == "pack1.txt");
|
||||||
|
zip.Entries.Should().Contain(e => e.FullName == "newpath/pack2.txt");
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void PackAddsCorrectFilesForProjectsWithOutputNameSpecified()
|
public void PackAddsCorrectFilesForProjectsWithOutputNameSpecified()
|
||||||
{
|
{
|
||||||
|
|
|
@ -116,6 +116,21 @@ namespace Microsoft.DotNet.Tools.Publish.Tests
|
||||||
publishCommand.GetOutputDirectory().Should().HaveFile("testcontentfile.txt");
|
publishCommand.GetOutputDirectory().Should().HaveFile("testcontentfile.txt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ProjectWithPublishOptionsTest()
|
||||||
|
{
|
||||||
|
var instance = TestAssetsManager.CreateTestInstance("EndToEndTestApp")
|
||||||
|
.WithLockFiles()
|
||||||
|
.WithBuildArtifacts();
|
||||||
|
|
||||||
|
var testProject = _getProjectJson(instance.TestRoot, "EndToEndTestApp");
|
||||||
|
|
||||||
|
var publishCommand = new PublishCommand(testProject);
|
||||||
|
|
||||||
|
publishCommand.Execute().Should().Pass();
|
||||||
|
publishCommand.GetOutputDirectory().Should().HaveFile("testpublishfile.txt");
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void FailWhenNoRestoreTest()
|
public void FailWhenNoRestoreTest()
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue