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.Linq;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.DotNet.Cli.Compiler.Common;
|
||||
using Microsoft.DotNet.Cli.Utils;
|
||||
using Microsoft.DotNet.Files;
|
||||
using Microsoft.DotNet.ProjectModel;
|
||||
using Microsoft.DotNet.ProjectModel.Compilation;
|
||||
using Microsoft.DotNet.ProjectModel.Files;
|
||||
using Microsoft.DotNet.ProjectModel.Graph;
|
||||
using Microsoft.DotNet.Tools.Common;
|
||||
using Microsoft.Extensions.DependencyModel;
|
||||
using NuGet.Frameworks;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using System.Reflection.PortableExecutable;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Microsoft.DotNet.Cli.Compiler.Common
|
||||
{
|
||||
|
@ -88,7 +88,20 @@ namespace Microsoft.DotNet.Cli.Compiler.Common
|
|||
private void CopyContentFiles()
|
||||
{
|
||||
var contentFiles = new ContentFiles(_context);
|
||||
contentFiles.StructuredCopyTo(_runtimeOutputPath);
|
||||
|
||||
if (_compilerOptions.CopyToOutputInclude != null)
|
||||
{
|
||||
var includeEntries = IncludeFilesResolver.GetIncludeFiles(
|
||||
_compilerOptions.CopyToOutputInclude,
|
||||
PathUtility.EnsureTrailingSlash(_runtimeOutputPath),
|
||||
diagnostics: null);
|
||||
|
||||
contentFiles.StructuredCopyTo(_runtimeOutputPath, includeEntries);
|
||||
}
|
||||
else
|
||||
{
|
||||
contentFiles.StructuredCopyTo(_runtimeOutputPath);
|
||||
}
|
||||
}
|
||||
|
||||
private void CopyAssemblies(IEnumerable<LibraryExport> libraryExports)
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace Microsoft.DotNet.Cli.Compiler.Common
|
|||
var baseOption = context.ProjectFile.GetCompilerOptions(framework, configurationName);
|
||||
|
||||
IReadOnlyList<string> defaultSuppresses;
|
||||
var compilerName = context.ProjectFile.CompilerName ?? "csc";
|
||||
var compilerName = baseOption.CompilerName ?? "csc";
|
||||
if (DefaultCompilerWarningSuppresses.Suppresses.TryGetValue(compilerName, out defaultSuppresses))
|
||||
{
|
||||
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
|
||||
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
|
||||
var environmentKeyFile = Environment.GetEnvironmentVariable(EnvironmentNames.StrongNameKeyFile);
|
||||
|
||||
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
|
||||
compilationOptions.KeyFile =
|
||||
Path.GetFullPath(Path.Combine(context.ProjectFile.ProjectDirectory, compilationOptions.KeyFile));
|
||||
compilerOptions.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.Linq;
|
||||
using Microsoft.DotNet.ProjectModel;
|
||||
using Microsoft.DotNet.ProjectModel.Files;
|
||||
using Microsoft.DotNet.Tools.Common;
|
||||
|
||||
namespace Microsoft.DotNet.Files
|
||||
|
@ -60,6 +61,29 @@ namespace Microsoft.DotNet.Files
|
|||
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)
|
||||
{
|
||||
foreach (var file in files)
|
||||
|
|
|
@ -13,6 +13,7 @@ using Microsoft.CodeAnalysis.Host.Mef;
|
|||
using Microsoft.CodeAnalysis.Text;
|
||||
using Microsoft.DotNet.Cli.Compiler.Common;
|
||||
using Microsoft.DotNet.ProjectModel.Compilation;
|
||||
using Microsoft.DotNet.ProjectModel.Files;
|
||||
using Microsoft.Extensions.PlatformAbstractions;
|
||||
using NuGet.Frameworks;
|
||||
|
||||
|
@ -69,15 +70,26 @@ namespace Microsoft.DotNet.ProjectModel.Workspaces
|
|||
// TODO: ctor argument?
|
||||
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));
|
||||
|
||||
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))
|
||||
{
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.DotNet.ProjectModel.Files;
|
||||
|
||||
namespace Microsoft.DotNet.ProjectModel
|
||||
{
|
||||
|
@ -39,7 +39,15 @@ namespace Microsoft.DotNet.ProjectModel
|
|||
|
||||
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)
|
||||
{
|
||||
|
@ -60,7 +68,21 @@ namespace Microsoft.DotNet.ProjectModel
|
|||
EnumerableEquals(Defines, other.Defines) &&
|
||||
EnumerableEquals(SuppressWarnings, other.SuppressWarnings) &&
|
||||
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)
|
||||
|
@ -161,6 +183,27 @@ namespace Microsoft.DotNet.ProjectModel
|
|||
{
|
||||
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;
|
||||
|
|
|
@ -279,6 +279,7 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
|
|||
private LibraryExport ExportProject(ProjectDescription project)
|
||||
{
|
||||
var builder = LibraryExportBuilder.Create(project);
|
||||
var compilerOptions = project.Project.GetCompilerOptions(project.TargetFrameworkInfo.FrameworkName, _configuration);
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
else if (project.Project.Files.SourceFiles.Any())
|
||||
else if (HasSourceFiles(project))
|
||||
{
|
||||
var outputPaths = project.GetOutputPaths(_buildBasePath, _solutionRootPath, _configuration, _runtime);
|
||||
|
||||
|
@ -336,6 +337,20 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
|
|||
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)
|
||||
{
|
||||
var assemblyPath = files.Assembly;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Microsoft.DotNet.ProjectModel.Files;
|
||||
using Microsoft.DotNet.ProjectModel.Resources;
|
||||
using NuGet.Frameworks;
|
||||
|
||||
|
@ -27,8 +28,8 @@ namespace Microsoft.DotNet.ProjectModel
|
|||
Framework = framework;
|
||||
OutputExtension = FileNameSuffixes.DotNet.DynamicLib;
|
||||
|
||||
var compilationOptions = Project.GetCompilerOptions(framework, configuration);
|
||||
if (framework.IsDesktop() && compilationOptions.EmitEntryPoint.GetValueOrDefault())
|
||||
var compilerOptions = Project.GetCompilerOptions(framework, configuration);
|
||||
if (framework.IsDesktop() && compilerOptions.EmitEntryPoint.GetValueOrDefault())
|
||||
{
|
||||
OutputExtension = FileNameSuffixes.DotNet.Exe;
|
||||
}
|
||||
|
@ -40,9 +41,9 @@ namespace Microsoft.DotNet.ProjectModel
|
|||
{
|
||||
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()
|
||||
{
|
||||
var resourceNames = Project.Files.ResourceFiles
|
||||
.Select(f => ResourceUtility.GetResourceCultureName(f.Key))
|
||||
var resourceCultureNames = GetResourceFiles()
|
||||
.Select(f => ResourceUtility.GetResourceCultureName(f))
|
||||
.Where(f => !string.IsNullOrEmpty(f))
|
||||
.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 PdbPath;
|
||||
var compilationOptions = Project.GetCompilerOptions(Framework, Configuration);
|
||||
if (compilationOptions.GenerateXmlDocumentation == true)
|
||||
var compilerOptions = Project.GetCompilerOptions(Framework, Configuration);
|
||||
if (compilerOptions.GenerateXmlDocumentation == true)
|
||||
{
|
||||
yield return Path.ChangeExtension(Assembly, "xml");
|
||||
}
|
||||
|
@ -83,5 +87,18 @@ namespace Microsoft.DotNet.ProjectModel
|
|||
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
|
||||
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,11 +39,11 @@ namespace Microsoft.DotNet.ProjectModel.Files
|
|||
return new string[] { json.Value<string>() };
|
||||
}
|
||||
|
||||
if(json.Type == JTokenType.Array)
|
||||
if (json.Type == JTokenType.Array)
|
||||
{
|
||||
return json.Select(v => v.ToString()).ToArray();
|
||||
}
|
||||
return new string[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,11 +1,10 @@
|
|||
// 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 Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Microsoft.DotNet.ProjectModel.Files
|
||||
{
|
||||
|
@ -27,18 +26,21 @@ namespace Microsoft.DotNet.ProjectModel.Files
|
|||
JToken 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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
|
@ -48,59 +50,5 @@ namespace Microsoft.DotNet.ProjectModel.Files
|
|||
|
||||
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.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
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.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Microsoft.DotNet.ProjectModel.Files;
|
||||
using Microsoft.DotNet.ProjectModel.Graph;
|
||||
using NuGet.Frameworks;
|
||||
|
@ -47,16 +46,10 @@ namespace Microsoft.DotNet.ProjectModel
|
|||
|
||||
public string Copyright { get; set; }
|
||||
|
||||
public string Summary { get; set; }
|
||||
|
||||
public string Language { get; set; }
|
||||
|
||||
public string ReleaseNotes { get; set; }
|
||||
|
||||
public string[] Authors { get; set; }
|
||||
|
||||
public string[] Owners { get; set; }
|
||||
|
||||
public bool EmbedInteropTypes { get; set; }
|
||||
|
||||
public NuGetVersion Version { get; set; }
|
||||
|
@ -69,28 +62,24 @@ namespace Microsoft.DotNet.ProjectModel
|
|||
|
||||
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 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, IEnumerable<string>> Scripts { get; } = new Dictionary<string, IEnumerable<string>>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
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 IEnumerable<TargetFrameworkInformation> GetTargetFrameworks()
|
||||
|
@ -134,10 +123,10 @@ namespace Microsoft.DotNet.ProjectModel
|
|||
|
||||
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
|
||||
return compilationOptions.EmitEntryPoint.GetValueOrDefault() || IsTestProject;
|
||||
return compilerOptions.EmitEntryPoint.GetValueOrDefault() || IsTestProject;
|
||||
}
|
||||
|
||||
private CommonCompilerOptions GetCompilerOptions()
|
||||
|
|
|
@ -337,6 +337,11 @@ namespace Microsoft.DotNet.ProjectModel
|
|||
}
|
||||
}
|
||||
|
||||
if (Project != null)
|
||||
{
|
||||
diagnostics.AddRange(Project.Diagnostics);
|
||||
}
|
||||
|
||||
// Create a library manager
|
||||
var libraryManager = new LibraryManager(libraries.Values.ToList(), diagnostics, Project?.ProjectFilePath);
|
||||
|
||||
|
@ -567,9 +572,8 @@ namespace Microsoft.DotNet.ProjectModel
|
|||
|
||||
private Project ResolveProject(string projectDirectory)
|
||||
{
|
||||
// TODO: Handle diagnostics
|
||||
Project project;
|
||||
if (ProjectReader.TryGetProject(projectDirectory, out project, diagnostics: null, settings: Settings))
|
||||
if (ProjectReader.TryGetProject(projectDirectory, out project, settings: Settings))
|
||||
{
|
||||
return project;
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace Microsoft.DotNet.ProjectModel
|
|||
{
|
||||
foreach (var kvp in _compilerNameToLanguageId)
|
||||
{
|
||||
if (kvp.Key == project.CompilerName)
|
||||
if (kvp.Key == (project._defaultCompilerOptions.CompilerName))
|
||||
{
|
||||
return kvp.Value;
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace Microsoft.DotNet.ProjectModel
|
|||
{
|
||||
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;
|
||||
|
||||
|
@ -51,7 +51,7 @@ namespace Microsoft.DotNet.ProjectModel
|
|||
using (var stream = File.OpenRead(projectPath))
|
||||
{
|
||||
var reader = new ProjectReader();
|
||||
project = reader.ReadProject(stream, projectName, projectPath, diagnostics, settings);
|
||||
project = reader.ReadProject(stream, projectName, projectPath, settings);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
@ -62,9 +62,7 @@ namespace Microsoft.DotNet.ProjectModel
|
|||
return true;
|
||||
}
|
||||
|
||||
public static Project GetProject(string projectPath, ProjectReaderSettings settings = null) => GetProject(projectPath, new List<DiagnosticMessage>(), settings);
|
||||
|
||||
public static Project GetProject(string projectPath, ICollection<DiagnosticMessage> diagnostics, ProjectReaderSettings settings = null)
|
||||
public static Project GetProject(string projectPath, ProjectReaderSettings settings = null)
|
||||
{
|
||||
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))
|
||||
{
|
||||
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();
|
||||
var project = new Project();
|
||||
|
@ -146,25 +144,13 @@ namespace Microsoft.DotNet.ProjectModel
|
|||
}
|
||||
|
||||
project.Description = rawProject.Value<string>("description");
|
||||
project.Summary = rawProject.Value<string>("summary");
|
||||
project.Copyright = rawProject.Value<string>("copyright");
|
||||
project.Title = rawProject.Value<string>("title");
|
||||
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.Authors =
|
||||
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.ReleaseNotes = rawProject.Value<string>("releaseNotes");
|
||||
|
||||
project.RequireLicenseAcceptance = rawProject.Value<bool>("requireLicenseAcceptance");
|
||||
|
||||
// REVIEW: Move this to the dependencies node?
|
||||
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(
|
||||
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
|
||||
project._defaultCompilerOptions =
|
||||
GetCompilationOptions(projectJsonObject, project) ?? new CommonCompilerOptions();
|
||||
GetCompilationOptions(projectJsonObject, project) ?? new CommonCompilerOptions { CompilerName = "csc" };
|
||||
|
||||
project._defaultTargetFrameworkConfiguration = new TargetFrameworkInformation
|
||||
{
|
||||
|
@ -423,7 +413,7 @@ namespace Microsoft.DotNet.ProjectModel
|
|||
if (!success)
|
||||
{
|
||||
var lineInfo = (IJsonLineInfo)framework.Value;
|
||||
diagnostics?.Add(
|
||||
project.Diagnostics?.Add(
|
||||
new DiagnosticMessage(
|
||||
ErrorCodes.NU1008,
|
||||
$"\"{framework.Key}\" is an unsupported framework.",
|
||||
|
@ -518,10 +508,42 @@ namespace Microsoft.DotNet.ProjectModel
|
|||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
|
@ -571,10 +593,148 @@ namespace Microsoft.DotNet.ProjectModel
|
|||
EmitEntryPoint = rawOptions.Value<bool?>("emitEntryPoint"),
|
||||
GenerateXmlDocumentation = rawOptions.Value<bool?>("xmlDoc"),
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
Project project;
|
||||
if (!ProjectReader.TryGetProject(projectDirectory, out project, currentEntry.Diagnostics, _settings))
|
||||
if (!ProjectReader.TryGetProject(projectDirectory, out project, _settings))
|
||||
{
|
||||
currentEntry.Reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
currentEntry.Model = project;
|
||||
currentEntry.Diagnostics.AddRange(project.Diagnostics);
|
||||
currentEntry.FilePath = project.ProjectFilePath;
|
||||
currentEntry.UpdateLastWriteTimeUtc();
|
||||
}
|
||||
|
|
|
@ -54,6 +54,7 @@ namespace Microsoft.DotNet.Tools.Build
|
|||
|
||||
var calculator = project.GetOutputPaths(_configuration, _buildBasePath, _outputPath);
|
||||
var binariesOutputPath = calculator.CompilationOutputPath;
|
||||
var compilerOptions = project.ProjectFile.GetCompilerOptions(project.TargetFramework, _configuration);
|
||||
|
||||
// input: project.json
|
||||
inputs.Add(project.ProjectFile.ProjectFilePath);
|
||||
|
@ -62,7 +63,7 @@ namespace Microsoft.DotNet.Tools.Build
|
|||
AddLockFile(project, inputs);
|
||||
|
||||
// input: source files
|
||||
inputs.AddRange(CompilerUtil.GetCompilationSources(project));
|
||||
inputs.AddRange(CompilerUtil.GetCompilationSources(project, compilerOptions));
|
||||
|
||||
var allOutputPath = new HashSet<string>(calculator.CompilationFiles.All());
|
||||
if (isRootProject && project.ProjectFile.HasRuntimeOutput(_configuration))
|
||||
|
@ -84,10 +85,10 @@ namespace Microsoft.DotNet.Tools.Build
|
|||
AddCompilationOptions(project, _configuration, inputs);
|
||||
|
||||
// input / output: resources with culture
|
||||
AddNonCultureResources(project, calculator.IntermediateOutputDirectoryPath, inputs, outputs);
|
||||
AddNonCultureResources(project, calculator.IntermediateOutputDirectoryPath, inputs, outputs, compilerOptions);
|
||||
|
||||
// input / output: resources without culture
|
||||
AddCultureResources(project, binariesOutputPath, inputs, outputs);
|
||||
AddCultureResources(project, binariesOutputPath, inputs, outputs, compilerOptions);
|
||||
|
||||
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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
|
|
@ -68,7 +68,8 @@ namespace Microsoft.DotNet.Tools.Build
|
|||
{
|
||||
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)))
|
||||
{
|
||||
|
|
|
@ -5,6 +5,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.DotNet.ProjectModel;
|
||||
using Microsoft.DotNet.ProjectModel.Files;
|
||||
using NuGet.Frameworks;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Build
|
||||
|
@ -67,7 +68,7 @@ namespace Microsoft.DotNet.Tools.Build
|
|||
}
|
||||
|
||||
var context = projectNode.ProjectContext;
|
||||
if (!context.ProjectFile.Files.SourceFiles.Any())
|
||||
if (!HasSourceFiles(context))
|
||||
{
|
||||
return CompilationResult.IncrementalSkip;
|
||||
}
|
||||
|
@ -82,5 +83,19 @@ namespace Microsoft.DotNet.Tools.Build
|
|||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -80,10 +92,20 @@ namespace Microsoft.DotNet.Tools.Compiler
|
|||
protected static bool GenerateCultureResourceAssemblies(
|
||||
Project project,
|
||||
List<LibraryExport> dependencies,
|
||||
string outputPath)
|
||||
string outputPath,
|
||||
CommonCompilerOptions compilationOptions)
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -9,6 +9,7 @@ using System.Linq;
|
|||
using Microsoft.DotNet.ProjectModel;
|
||||
using Microsoft.DotNet.Cli.Compiler.Common;
|
||||
using Microsoft.DotNet.ProjectModel.Compilation;
|
||||
using Microsoft.DotNet.ProjectModel.Files;
|
||||
using Microsoft.DotNet.ProjectModel.Resources;
|
||||
using Microsoft.DotNet.Tools.Common;
|
||||
|
||||
|
@ -49,11 +50,29 @@ namespace Microsoft.DotNet.Tools.Compiler
|
|||
// used in incremental compilation
|
||||
public static List<NonCultureResgenIO> GetNonCultureResources(Project project, string intermediateOutputPath)
|
||||
{
|
||||
return
|
||||
return
|
||||
(from resourceFile in project.Files.ResourceFiles
|
||||
let inputFile = resourceFile.Key
|
||||
let inputFile = resourceFile.Key
|
||||
where string.IsNullOrEmpty(ResourceUtility.GetResourceCultureName(inputFile))
|
||||
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 metadataName = GetResourceFileMetadataName(project, resourceFile)
|
||||
let target = resourceFile.IsCustomTarget ? resourceFile.TargetPath : null
|
||||
let metadataName = GetResourceFileMetadataName(project, resourceFile.SourcePath, target)
|
||||
let outputFile = ResourceUtility.IsResxFile(inputFile) ? Path.Combine(intermediateOutputPath, metadataName) : null
|
||||
select new NonCultureResgenIO(inputFile, outputFile, metadataName)
|
||||
).ToList();
|
||||
|
@ -78,9 +97,29 @@ namespace Microsoft.DotNet.Tools.Compiler
|
|||
{
|
||||
return
|
||||
(from resourceFileGroup in project.Files.ResourceFiles.GroupBy(resourceFile => ResourceUtility.GetResourceCultureName(resourceFile.Key))
|
||||
let culture = resourceFileGroup.Key
|
||||
where !string.IsNullOrEmpty(culture)
|
||||
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.Key, r => GetResourceFileMetadataName(project, r))
|
||||
let inputFileToMetadata = resourceFileGroup.ToDictionary(
|
||||
r => r.SourcePath, r => GetResourceFileMetadataName(project, r.SourcePath, r.IsCustomTarget ? r.TargetPath : null))
|
||||
let resourceOutputPath = Path.Combine(outputPath, culture)
|
||||
let outputFile = Path.Combine(resourceOutputPath, project.Name + ".resources.dll")
|
||||
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();
|
||||
}
|
||||
|
||||
public static string GetResourceFileMetadataName(Project project, KeyValuePair<string, string> resourceFile)
|
||||
public static string GetResourceFileMetadataName(Project project, string resourceFileSource, string resourceFileTarget)
|
||||
{
|
||||
string resourceName = null;
|
||||
string rootNamespace = null;
|
||||
|
||||
string root = PathUtility.EnsureTrailingSlash(project.ProjectDirectory);
|
||||
string resourcePath = resourceFile.Key;
|
||||
if (string.IsNullOrEmpty(resourceFile.Value))
|
||||
string resourcePath = resourceFileSource;
|
||||
if (string.IsNullOrEmpty(resourceFileTarget))
|
||||
{
|
||||
// No logical name, so use the file name
|
||||
resourceName = ResourceUtility.GetResourceName(root, resourcePath);
|
||||
|
@ -108,7 +147,7 @@ namespace Microsoft.DotNet.Tools.Compiler
|
|||
}
|
||||
else
|
||||
{
|
||||
resourceName = ResourceManifestName.EnsureResourceExtension(resourceFile.Value, resourcePath);
|
||||
resourceName = ResourceManifestName.EnsureResourceExtension(resourceFileTarget, resourcePath);
|
||||
rootNamespace = null;
|
||||
}
|
||||
|
||||
|
@ -117,12 +156,23 @@ namespace Microsoft.DotNet.Tools.Compiler
|
|||
}
|
||||
|
||||
// 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
|
||||
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");
|
||||
}
|
||||
|
||||
if (!AddNonCultureResources(context.ProjectFile, compilerArgs, intermediateOutputPath))
|
||||
if (!AddNonCultureResources(context.ProjectFile, compilerArgs, intermediateOutputPath, compilationOptions))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// Add project source files
|
||||
var sourceFiles = CompilerUtil.GetCompilationSources(context);
|
||||
var sourceFiles = CompilerUtil.GetCompilationSources(context, compilationOptions);
|
||||
compilerArgs.AddRange(sourceFiles);
|
||||
|
||||
var compilerName = context.ProjectFile.CompilerName;
|
||||
var compilerName = compilationOptions.CompilerName;
|
||||
|
||||
// Write RSP file
|
||||
var rsp = Path.Combine(intermediateOutputPath, $"dotnet-compile.rsp");
|
||||
|
@ -207,7 +207,7 @@ namespace Microsoft.DotNet.Tools.Compiler
|
|||
|
||||
if (success)
|
||||
{
|
||||
success &= GenerateCultureResourceAssemblies(context.ProjectFile, dependencies, outputPath);
|
||||
success &= GenerateCultureResourceAssemblies(context.ProjectFile, dependencies, outputPath, compilationOptions);
|
||||
}
|
||||
|
||||
return PrintSummary(diagnostics, sw, success);
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Microsoft.DotNet.Cli.Utils;
|
||||
using Microsoft.DotNet.ProjectModel;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.DotNet.ProjectModel;
|
||||
using Microsoft.DotNet.ProjectModel.Files;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Pack
|
||||
{
|
||||
|
@ -32,7 +31,7 @@ namespace Microsoft.DotNet.Tools.Pack
|
|||
|
||||
public int Execute()
|
||||
{
|
||||
if (_project.Files.SourceFiles.Any())
|
||||
if (HasSourceFiles())
|
||||
{
|
||||
var argsBuilder = new List<string>();
|
||||
argsBuilder.Add("--configuration");
|
||||
|
@ -59,5 +58,20 @@ namespace Microsoft.DotNet.Tools.Pack
|
|||
|
||||
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.Files;
|
||||
using Microsoft.DotNet.ProjectModel.Graph;
|
||||
using Microsoft.DotNet.ProjectModel.Resources;
|
||||
using Microsoft.DotNet.ProjectModel.Utilities;
|
||||
using Microsoft.DotNet.Tools.Pack;
|
||||
using Microsoft.Extensions.FileSystemGlobbing;
|
||||
using Microsoft.Extensions.FileSystemGlobbing.Abstractions;
|
||||
using NuGet;
|
||||
using NuGet.Frameworks;
|
||||
using NuGet.Packaging.Core;
|
||||
using NuGet.Versioning;
|
||||
using Microsoft.DotNet.Cli.Compiler.Common;
|
||||
using Microsoft.DotNet.ProjectModel.Resources;
|
||||
using Microsoft.DotNet.Tools.Pack;
|
||||
using PackageBuilder = NuGet.PackageBuilder;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Compiler
|
||||
|
@ -42,7 +41,6 @@ namespace Microsoft.DotNet.Tools.Compiler
|
|||
|
||||
public bool BuildPackage(IEnumerable<ProjectContext> contexts, List<DiagnosticMessage> packDiagnostics)
|
||||
{
|
||||
|
||||
Reporter.Output.WriteLine($"Producing nuget package \"{GetPackageName()}\" for {Project.Name}");
|
||||
|
||||
PackageBuilder = CreatePackageBuilder(Project);
|
||||
|
@ -76,15 +74,26 @@ namespace Microsoft.DotNet.Tools.Compiler
|
|||
|
||||
var inputFolder = ArtifactPathsCalculator.InputPathForContext(context);
|
||||
|
||||
var compilationOptions = Project.GetCompilerOptions(context.TargetFramework, Configuration);
|
||||
var outputName = compilationOptions.OutputName;
|
||||
var compilerOptions = Project.GetCompilerOptions(context.TargetFramework, Configuration);
|
||||
var outputName = compilerOptions.OutputName;
|
||||
var outputExtension =
|
||||
context.TargetFramework.IsDesktop() && compilationOptions.EmitEntryPoint.GetValueOrDefault()
|
||||
context.TargetFramework.IsDesktop() && compilerOptions.EmitEntryPoint.GetValueOrDefault()
|
||||
? ".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))
|
||||
.Distinct();
|
||||
}
|
||||
else
|
||||
{
|
||||
var includeFiles = IncludeFilesResolver.GetIncludeFiles(compilerOptions.EmbedInclude, "/", diagnostics: null);
|
||||
resourceCultures = includeFiles
|
||||
.Select(file => ResourceUtility.GetResourceCultureName(file.SourcePath))
|
||||
.Distinct();
|
||||
}
|
||||
|
||||
foreach (var culture in resourceCultures)
|
||||
{
|
||||
|
@ -112,7 +121,12 @@ namespace Microsoft.DotNet.Tools.Compiler
|
|||
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);
|
||||
}
|
||||
|
@ -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,
|
||||
string outputPath,
|
||||
string filePath)
|
||||
|
@ -333,7 +361,7 @@ namespace Microsoft.DotNet.Tools.Compiler
|
|||
{
|
||||
var builder = new PackageBuilder();
|
||||
builder.Authors.AddRange(project.Authors);
|
||||
builder.Owners.AddRange(project.Owners);
|
||||
builder.Owners.AddRange(project.PackOptions.Owners);
|
||||
|
||||
if (builder.Authors.Count == 0)
|
||||
{
|
||||
|
@ -352,26 +380,26 @@ namespace Microsoft.DotNet.Tools.Compiler
|
|||
builder.Id = project.Name;
|
||||
builder.Version = project.Version;
|
||||
builder.Title = project.Title;
|
||||
builder.Summary = project.Summary;
|
||||
builder.Summary = project.PackOptions.Summary;
|
||||
builder.Copyright = project.Copyright;
|
||||
builder.RequireLicenseAcceptance = project.RequireLicenseAcceptance;
|
||||
builder.ReleaseNotes = project.ReleaseNotes;
|
||||
builder.RequireLicenseAcceptance = project.PackOptions.RequireLicenseAcceptance;
|
||||
builder.ReleaseNotes = project.PackOptions.ReleaseNotes;
|
||||
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;
|
||||
|
|
|
@ -1,11 +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.
|
||||
|
||||
using Microsoft.DotNet.ProjectModel;
|
||||
using NuGet;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Microsoft.DotNet.ProjectModel;
|
||||
using Microsoft.DotNet.ProjectModel.Files;
|
||||
using Microsoft.DotNet.Tools.Pack;
|
||||
using NuGet;
|
||||
|
||||
namespace Microsoft.DotNet.Tools.Compiler
|
||||
{
|
||||
|
@ -34,16 +35,37 @@ namespace Microsoft.DotNet.Tools.Compiler
|
|||
|
||||
protected override bool GeneratePackage(string nupkg, List<DiagnosticMessage> packDiagnostics)
|
||||
{
|
||||
foreach (var path in Project.Files.SourceFiles)
|
||||
{
|
||||
var srcFile = new PhysicalPackageFile
|
||||
{
|
||||
SourcePath = path,
|
||||
TargetPath = Path.Combine("src", Common.PathUtility.GetRelativePath(Project.ProjectDirectory, path))
|
||||
};
|
||||
var compilerOptions = Project.GetCompilerOptions(
|
||||
Project.GetTargetFramework(targetFramework: null).FrameworkName, Configuration);
|
||||
|
||||
PackageBuilder.Files.Add(srcFile);
|
||||
if (compilerOptions.CompileInclude == null)
|
||||
{
|
||||
foreach (var path in Project.Files.SourceFiles)
|
||||
{
|
||||
var srcFile = new PhysicalPackageFile
|
||||
{
|
||||
SourcePath = path,
|
||||
TargetPath = Path.Combine("src", Common.PathUtility.GetRelativePath(Project.ProjectDirectory, path))
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,10 +4,11 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.DotNet.Cli.Compiler.Common;
|
||||
using Microsoft.DotNet.ProjectModel.Files;
|
||||
using Microsoft.DotNet.ProjectModel.Graph;
|
||||
using Microsoft.DotNet.ProjectModel.Server.Helpers;
|
||||
using Microsoft.DotNet.ProjectModel.Server.Models;
|
||||
using Microsoft.DotNet.Cli.Compiler.Common;
|
||||
using NuGet.Frameworks;
|
||||
|
||||
namespace Microsoft.DotNet.ProjectModel.Server
|
||||
|
@ -37,7 +38,7 @@ namespace Microsoft.DotNet.ProjectModel.Server
|
|||
.GetAllExports()
|
||||
.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 allProjectReferences = new List<ProjectReferenceDescription>();
|
||||
var allDependencies = new Dictionary<string, DependencyDescription>();
|
||||
|
@ -74,5 +75,19 @@ namespace Microsoft.DotNet.ProjectModel.Server
|
|||
|
||||
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.ProjectModel;
|
||||
using Microsoft.DotNet.ProjectModel.Compilation;
|
||||
using Microsoft.DotNet.ProjectModel.Files;
|
||||
using Microsoft.DotNet.ProjectModel.Graph;
|
||||
using Microsoft.DotNet.ProjectModel.Utilities;
|
||||
using Microsoft.DotNet.Tools.Common;
|
||||
|
@ -179,7 +180,20 @@ namespace Microsoft.DotNet.Tools.Publish
|
|||
}
|
||||
|
||||
var contentFiles = new ContentFiles(context);
|
||||
contentFiles.StructuredCopyTo(outputPath);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// Publish a host if this is an application
|
||||
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));
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
foreach (var script in context.ProjectFile.Scripts.GetOrEmpty(name))
|
||||
|
|
|
@ -83,7 +83,6 @@ namespace Microsoft.DotNet.ProjectModel.Tests
|
|||
stream,
|
||||
ProjectName,
|
||||
ProjectFilePath,
|
||||
new List<DiagnosticMessage>(),
|
||||
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 SomeLanguageVersion = "some language version";
|
||||
private const string SomeOutputName = "some output name";
|
||||
private const string SomeCompilerName = "some compiler name";
|
||||
private const string SomePlatform = "some platform";
|
||||
private const string SomeKeyFile = "some key file";
|
||||
private const string SomeDebugType = "some debug type";
|
||||
|
@ -49,6 +50,7 @@ namespace Microsoft.DotNet.ProjectModel.Tests
|
|||
_jsonCompilationOptions.Add("additionalArguments", new JArray(_someAdditionalArguments));
|
||||
_jsonCompilationOptions.Add("languageVersion", SomeLanguageVersion);
|
||||
_jsonCompilationOptions.Add("outputName", SomeOutputName);
|
||||
_jsonCompilationOptions.Add("compilerName", SomeCompilerName);
|
||||
_jsonCompilationOptions.Add("platform", SomePlatform);
|
||||
_jsonCompilationOptions.Add("keyFile", SomeKeyFile);
|
||||
_jsonCompilationOptions.Add("debugType", SomeDebugType);
|
||||
|
@ -68,6 +70,7 @@ namespace Microsoft.DotNet.ProjectModel.Tests
|
|||
AdditionalArguments = _someAdditionalArguments,
|
||||
LanguageVersion = SomeLanguageVersion,
|
||||
OutputName = SomeOutputName,
|
||||
CompilerName = SomeCompilerName,
|
||||
Platform = SomePlatform,
|
||||
KeyFile = SomeKeyFile,
|
||||
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()
|
||||
{
|
||||
_emptyProject.Description.Should().BeNull();
|
||||
_emptyProject.Summary.Should().BeNull();
|
||||
_emptyProject.PackOptions.Summary.Should().BeNull();
|
||||
_emptyProject.Copyright.Should().BeNull();
|
||||
_emptyProject.Title.Should().BeNull();
|
||||
_emptyProject.EntryPoint.Should().BeNull();
|
||||
_emptyProject.ProjectUrl.Should().BeNull();
|
||||
_emptyProject.LicenseUrl.Should().BeNull();
|
||||
_emptyProject.IconUrl.Should().BeNull();
|
||||
_emptyProject.PackOptions.ProjectUrl.Should().BeNull();
|
||||
_emptyProject.PackOptions.LicenseUrl.Should().BeNull();
|
||||
_emptyProject.PackOptions.IconUrl.Should().BeNull();
|
||||
_emptyProject.Authors.Should().BeEmpty();
|
||||
_emptyProject.Owners.Should().BeEmpty();
|
||||
_emptyProject.Tags.Should().BeEmpty();
|
||||
_emptyProject.PackOptions.Owners.Should().BeEmpty();
|
||||
_emptyProject.PackOptions.Tags.Should().BeEmpty();
|
||||
_emptyProject.Language.Should().BeNull();
|
||||
_emptyProject.ReleaseNotes.Should().BeNull();
|
||||
_emptyProject.PackOptions.ReleaseNotes.Should().BeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -216,24 +219,105 @@ namespace Microsoft.DotNet.ProjectModel.Tests
|
|||
var project = GetProject(json);
|
||||
|
||||
project.Description.Should().Be(someDescription);
|
||||
project.Summary.Should().Be(someSummary);
|
||||
project.PackOptions.Summary.Should().Be(someSummary);
|
||||
project.Copyright.Should().Be(someCopyright);
|
||||
project.Title.Should().Be(someTitle);
|
||||
project.EntryPoint.Should().Be(someEntryPoint);
|
||||
project.ProjectUrl.Should().Be(someProjectUrl);
|
||||
project.LicenseUrl.Should().Be(someLicenseUrl);
|
||||
project.IconUrl.Should().Be(someIconUrl);
|
||||
project.PackOptions.ProjectUrl.Should().Be(someProjectUrl);
|
||||
project.PackOptions.LicenseUrl.Should().Be(someLicenseUrl);
|
||||
project.PackOptions.IconUrl.Should().Be(someIconUrl);
|
||||
project.Authors.Should().Contain(authors);
|
||||
project.Owners.Should().Contain(owners);
|
||||
project.Tags.Should().Contain(tags);
|
||||
project.PackOptions.Owners.Should().Contain(owners);
|
||||
project.PackOptions.Tags.Should().Contain(tags);
|
||||
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]
|
||||
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]
|
||||
|
@ -244,7 +328,7 @@ namespace Microsoft.DotNet.ProjectModel.Tests
|
|||
json.Add("compilerName", compilerName);
|
||||
var project = GetProject(json);
|
||||
|
||||
project.CompilerName.Should().Be(compilerName);
|
||||
project.GetCompilerOptions(targetFramework: null, configurationName: null).CompilerName.Should().Be(compilerName);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -267,7 +351,7 @@ namespace Microsoft.DotNet.ProjectModel.Tests
|
|||
[Fact]
|
||||
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]
|
||||
|
@ -277,7 +361,7 @@ namespace Microsoft.DotNet.ProjectModel.Tests
|
|||
json.Add("requireLicenseAcceptance", true);
|
||||
var project = GetProject(json);
|
||||
|
||||
project.RequireLicenseAcceptance.Should().BeTrue();
|
||||
project.PackOptions.RequireLicenseAcceptance.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -287,7 +371,7 @@ namespace Microsoft.DotNet.ProjectModel.Tests
|
|||
json.Add("requireLicenseAcceptance", false);
|
||||
var project = GetProject(json);
|
||||
|
||||
project.RequireLicenseAcceptance.Should().BeFalse();
|
||||
project.PackOptions.RequireLicenseAcceptance.Should().BeFalse();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -405,7 +489,8 @@ namespace Microsoft.DotNet.ProjectModel.Tests
|
|||
{
|
||||
_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);
|
||||
}
|
||||
|
||||
[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]
|
||||
public void It_merges_configuration_sections_set_in_the_ProjectJson()
|
||||
{
|
||||
|
@ -874,7 +970,6 @@ namespace Microsoft.DotNet.ProjectModel.Tests
|
|||
stream,
|
||||
ProjectName,
|
||||
ProjectFilePath,
|
||||
new List<DiagnosticMessage>(),
|
||||
settings);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -336,7 +336,10 @@ namespace Microsoft.DotNet.ProjectModel.Tests
|
|||
var rootProject = new Project()
|
||||
{
|
||||
Name = "RootProject",
|
||||
CompilerName = "csc"
|
||||
_defaultCompilerOptions = new CommonCompilerOptions
|
||||
{
|
||||
CompilerName = "csc"
|
||||
}
|
||||
};
|
||||
|
||||
var rootProjectDescription = new ProjectDescription(
|
||||
|
|
|
@ -147,6 +147,48 @@ namespace Microsoft.DotNet.Tools.Compiler.Tests
|
|||
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]
|
||||
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");
|
||||
}
|
||||
|
||||
[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]
|
||||
public void PackAddsCorrectFilesForProjectsWithOutputNameSpecified()
|
||||
{
|
||||
|
|
|
@ -116,6 +116,21 @@ namespace Microsoft.DotNet.Tools.Publish.Tests
|
|||
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]
|
||||
public void FailWhenNoRestoreTest()
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue