Merge branch 'master' of https://github.com/dotnet/cli into package_build
This commit is contained in:
commit
e95acaa27d
19 changed files with 233 additions and 141 deletions
|
@ -3,7 +3,7 @@
|
||||||
## Building/Running
|
## Building/Running
|
||||||
|
|
||||||
1. Run `build.cmd` or `build.sh` from the root
|
1. Run `build.cmd` or `build.sh` from the root
|
||||||
2. Use `artifacts/{os}-{arch}/state2/dotnet` to try out the `dotnet` command. You can also add `artifacts/{os}-{arch}/state2` to the PATH if you want to run `dotnet` from anywhere.
|
2. Use `artifacts/{os}-{arch}/stage2/dotnet` to try out the `dotnet` command. You can also add `artifacts/{os}-{arch}/stage2` to the PATH if you want to run `dotnet` from anywhere.
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
|
|
|
@ -130,7 +130,7 @@ namespace Microsoft.DotNet.Cli.Utils
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
var sw = Stopwatch.StartNew();
|
var sw = Stopwatch.StartNew();
|
||||||
Console.WriteLine($"> {_process.StartInfo.FileName} {_process.StartInfo.Arguments}");
|
Reporter.Output.WriteLine($"> {_process.StartInfo.FileName} {_process.StartInfo.Arguments}".White());
|
||||||
#endif
|
#endif
|
||||||
_process.Start();
|
_process.Start();
|
||||||
_process.BeginOutputReadLine();
|
_process.BeginOutputReadLine();
|
||||||
|
@ -139,7 +139,15 @@ namespace Microsoft.DotNet.Cli.Utils
|
||||||
var exitCode = await _processTcs.Task;
|
var exitCode = await _processTcs.Task;
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
Console.WriteLine($"> {_process.StartInfo.FileName} {_process.StartInfo.Arguments} exited with {exitCode} in {sw.ElapsedMilliseconds} ms.");
|
var message = $"> {_process.StartInfo.FileName} {_process.StartInfo.Arguments} exited with {exitCode} in {sw.ElapsedMilliseconds} ms.";
|
||||||
|
if (exitCode == 0)
|
||||||
|
{
|
||||||
|
Reporter.Output.WriteLine(message.Green().Bold());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Reporter.Output.WriteLine(message.Red().Bold());
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return new CommandResult(
|
return new CommandResult(
|
||||||
|
|
|
@ -17,6 +17,10 @@
|
||||||
"Microsoft.DotNet.Cli.Utils": {
|
"Microsoft.DotNet.Cli.Utils": {
|
||||||
"type": "build",
|
"type": "build",
|
||||||
"version": "1.0.0-*"
|
"version": "1.0.0-*"
|
||||||
|
},
|
||||||
|
"Microsoft.Extensions.CommandLineUtils.Sources": {
|
||||||
|
"type": "build",
|
||||||
|
"version": "1.0.0-*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"frameworks": {
|
"frameworks": {
|
||||||
|
|
|
@ -66,7 +66,11 @@ namespace Microsoft.DotNet.Tools.Compiler
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
Console.Error.WriteLine(ex);
|
||||||
|
#else
|
||||||
Console.Error.WriteLine(ex.Message);
|
Console.Error.WriteLine(ex.Message);
|
||||||
|
#endif
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -163,7 +167,7 @@ namespace Microsoft.DotNet.Tools.Compiler
|
||||||
|
|
||||||
// Get compilation options
|
// Get compilation options
|
||||||
var compilationOptions = context.ProjectFile.GetCompilerOptions(context.TargetFramework, configuration);
|
var compilationOptions = context.ProjectFile.GetCompilerOptions(context.TargetFramework, configuration);
|
||||||
var outputName = Path.Combine(outputPath, context.ProjectFile.Name + ".dll");
|
var outputName = Path.Combine(outputPath, context.ProjectFile.Name + (compilationOptions.EmitEntryPoint.GetValueOrDefault() ? ".exe" : ".dll"));
|
||||||
|
|
||||||
var bootstrappingWithMono = !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("BOOTSTRAPPING_WITH_MONO"));
|
var bootstrappingWithMono = !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("BOOTSTRAPPING_WITH_MONO"));
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,11 @@ namespace Microsoft.DotNet.Tools.Publish
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
Console.Error.WriteLine(ex);
|
||||||
|
#else
|
||||||
Console.Error.WriteLine(ex.Message);
|
Console.Error.WriteLine(ex.Message);
|
||||||
|
#endif
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -109,6 +113,10 @@ namespace Microsoft.DotNet.Tools.Publish
|
||||||
// Use a library exporter to collect publish assets
|
// Use a library exporter to collect publish assets
|
||||||
var exporter = context.CreateExporter(configuration);
|
var exporter = context.CreateExporter(configuration);
|
||||||
|
|
||||||
|
// Copy things marked as copy to output (which we don't have yet)
|
||||||
|
// so does copy too many things
|
||||||
|
CopyContents(context, outputPath);
|
||||||
|
|
||||||
foreach (var export in exporter.GetAllExports())
|
foreach (var export in exporter.GetAllExports())
|
||||||
{
|
{
|
||||||
Reporter.Output.WriteLine($"Publishing {export.Library.Identity.ToString().Green().Bold()} ...");
|
Reporter.Output.WriteLine($"Publishing {export.Library.Identity.ToString().Green().Bold()} ...");
|
||||||
|
@ -119,7 +127,7 @@ namespace Microsoft.DotNet.Tools.Publish
|
||||||
|
|
||||||
// Publishing for windows, TODO(anurse): Publish for Mac/Linux/etc.
|
// Publishing for windows, TODO(anurse): Publish for Mac/Linux/etc.
|
||||||
int exitCode;
|
int exitCode;
|
||||||
if (context.RuntimeIdentifier.Equals("win7-x64"))
|
if (context.RuntimeIdentifier.StartsWith("win"))
|
||||||
{
|
{
|
||||||
exitCode = PublishForWindows(context, outputPath);
|
exitCode = PublishForWindows(context, outputPath);
|
||||||
}
|
}
|
||||||
|
@ -161,7 +169,6 @@ namespace Microsoft.DotNet.Tools.Publish
|
||||||
|
|
||||||
// Use the 'command' field to generate the name
|
// Use the 'command' field to generate the name
|
||||||
var outputExe = Path.Combine(outputPath, context.ProjectFile.Name);
|
var outputExe = Path.Combine(outputPath, context.ProjectFile.Name);
|
||||||
var outputDll = Path.Combine(outputPath, context.ProjectFile.Name + ".dll");
|
|
||||||
|
|
||||||
// Write a script that can be used to launch with CoreRun
|
// Write a script that can be used to launch with CoreRun
|
||||||
var script = $@"#!/usr/bin/env bash
|
var script = $@"#!/usr/bin/env bash
|
||||||
|
@ -183,14 +190,15 @@ exec ""$DIR/corerun"" ""$DIR/{context.ProjectFile.Name}.exe"" $*";
|
||||||
.GetAwaiter()
|
.GetAwaiter()
|
||||||
.GetResult();
|
.GetResult();
|
||||||
|
|
||||||
File.Copy(outputDll, Path.ChangeExtension(outputDll, ".exe"));
|
|
||||||
File.Delete(outputDll);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int PublishForWindows(ProjectContext context, string outputPath)
|
private static int PublishForWindows(ProjectContext context, string outputPath)
|
||||||
{
|
{
|
||||||
|
if (context.TargetFramework.IsDesktop())
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
// Locate Hosts
|
// Locate Hosts
|
||||||
string hostsPath = Environment.GetEnvironmentVariable(Constants.HostsPathEnvironmentVariable);
|
string hostsPath = Environment.GetEnvironmentVariable(Constants.HostsPathEnvironmentVariable);
|
||||||
if (string.IsNullOrEmpty(hostsPath))
|
if (string.IsNullOrEmpty(hostsPath))
|
||||||
|
@ -216,13 +224,80 @@ exec ""$DIR/corerun"" ""$DIR/{context.ProjectFile.Name}.exe"" $*";
|
||||||
File.Copy(coreConsole, Path.Combine(outputPath, Constants.CoreConsoleName), overwrite: true);
|
File.Copy(coreConsole, Path.Combine(outputPath, Constants.CoreConsoleName), overwrite: true);
|
||||||
File.Copy(coreRun, Path.Combine(outputPath, Constants.CoreRunName), overwrite: true);
|
File.Copy(coreRun, Path.Combine(outputPath, Constants.CoreRunName), overwrite: true);
|
||||||
|
|
||||||
// Use the 'command' field to generate the name
|
|
||||||
var outputExe = Path.Combine(outputPath, context.ProjectFile.Name + Constants.ExeSuffix);
|
var outputExe = Path.Combine(outputPath, context.ProjectFile.Name + Constants.ExeSuffix);
|
||||||
File.Copy(coreConsole, outputExe, overwrite: true);
|
|
||||||
|
|
||||||
|
// Rename the {app}.exe to {app}.dll
|
||||||
|
File.Copy(outputExe, Path.ChangeExtension(outputExe, ".dll"), overwrite: true);
|
||||||
|
|
||||||
|
// Change coreconsole.exe to the {app}.exe name
|
||||||
|
File.Copy(coreConsole, outputExe, overwrite: true);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void CopyContents(ProjectContext context, string outputPath)
|
||||||
|
{
|
||||||
|
var sourceFiles = context.ProjectFile.Files.GetFilesForBundling();
|
||||||
|
Copy(sourceFiles, context.ProjectDirectory, outputPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void Copy(IEnumerable<string> sourceFiles, string sourceDirectory, string targetDirectory)
|
||||||
|
{
|
||||||
|
if (sourceFiles == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(sourceFiles));
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceDirectory = EnsureTrailingSlash(sourceDirectory);
|
||||||
|
targetDirectory = EnsureTrailingSlash(targetDirectory);
|
||||||
|
|
||||||
|
foreach (var sourceFilePath in sourceFiles)
|
||||||
|
{
|
||||||
|
var fileName = Path.GetFileName(sourceFilePath);
|
||||||
|
|
||||||
|
var targetFilePath = sourceFilePath.Replace(sourceDirectory, targetDirectory);
|
||||||
|
var targetFileParentFolder = Path.GetDirectoryName(targetFilePath);
|
||||||
|
|
||||||
|
// Create directory before copying a file
|
||||||
|
if (!Directory.Exists(targetFileParentFolder))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(targetFileParentFolder);
|
||||||
|
}
|
||||||
|
|
||||||
|
File.Copy(
|
||||||
|
sourceFilePath,
|
||||||
|
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 string EnsureTrailingSlash(string path)
|
||||||
|
{
|
||||||
|
return EnsureTrailingCharacter(path, Path.DirectorySeparatorChar);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string EnsureTrailingCharacter(string path, char trailingCharacter)
|
||||||
|
{
|
||||||
|
if (path == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(path));
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the path is empty, we want to return the original string instead of a single trailing character.
|
||||||
|
if (path.Length == 0 || path[path.Length - 1] == trailingCharacter)
|
||||||
|
{
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
return path + trailingCharacter;
|
||||||
|
}
|
||||||
|
|
||||||
private static void PublishFiles(IEnumerable<string> files, string outputPath)
|
private static void PublishFiles(IEnumerable<string> files, string outputPath)
|
||||||
{
|
{
|
||||||
foreach (var file in files)
|
foreach (var file in files)
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using Microsoft.Dnx.Runtime.Common.CommandLine;
|
|
||||||
|
|
||||||
namespace Microsoft.DotNet.Cli.Utils
|
|
||||||
{
|
|
||||||
// Stupid-simple console manager
|
|
||||||
internal static class Reporter
|
|
||||||
{
|
|
||||||
public static AnsiConsole Output { get; } = AnsiConsole.GetOutput(RuntimeInformation.IsOSPlatform(OSPlatform.Windows));
|
|
||||||
public static AnsiConsole Error { get; } = AnsiConsole.GetError(RuntimeInformation.IsOSPlatform(OSPlatform.Windows));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -166,12 +166,13 @@ namespace Microsoft.Extensions.ProjectModel.Compilation
|
||||||
|
|
||||||
private string GetOutputPath(ProjectDescription project)
|
private string GetOutputPath(ProjectDescription project)
|
||||||
{
|
{
|
||||||
|
var compilationOptions = project.Project.GetCompilerOptions(project.Framework, _configuration);
|
||||||
return Path.Combine(
|
return Path.Combine(
|
||||||
project.Project.ProjectDirectory,
|
project.Project.ProjectDirectory,
|
||||||
"bin", // This can't access the Constant in Cli Utils. But the output path stuff is temporary right now anyway
|
"bin", // This can't access the Constant in Cli Utils. But the output path stuff is temporary right now anyway
|
||||||
_configuration,
|
_configuration,
|
||||||
project.Framework.GetTwoDigitShortFolderName(),
|
project.Framework.GetTwoDigitShortFolderName(),
|
||||||
project.Project.Name + ".dll");
|
project.Project.Name + (compilationOptions.EmitEntryPoint.GetValueOrDefault() ? ".exe" : ".dll"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string ResolvePath(Project project, string configuration, string path)
|
private static string ResolvePath(Project project, string configuration, string path)
|
||||||
|
|
|
@ -12,7 +12,7 @@ namespace Microsoft.Extensions.ProjectModel.Files
|
||||||
public class ProjectFilesCollection
|
public class ProjectFilesCollection
|
||||||
{
|
{
|
||||||
public static readonly string[] DefaultCompileBuiltInPatterns = new[] { @"**/*.cs" };
|
public static readonly string[] DefaultCompileBuiltInPatterns = new[] { @"**/*.cs" };
|
||||||
public static readonly string[] DefaultPublishExcludePatterns = new[] { @"obj/**/*.*", @"bin/**/*.*", @"**/.*/**", @"**/global.json" };
|
public static readonly string[] DefaultPublishExcludePatterns = new[] { @"obj/**/*.*", @"bin/**/*.*", @"**/.*/**", @"**/global.json", @"**/project.json", @"**/project.lock.json" };
|
||||||
public static readonly string[] DefaultPreprocessPatterns = new[] { @"compiler/preprocess/**/*.cs" };
|
public static readonly string[] DefaultPreprocessPatterns = new[] { @"compiler/preprocess/**/*.cs" };
|
||||||
public static readonly string[] DefaultSharedPatterns = new[] { @"compiler/shared/**/*.cs" };
|
public static readonly string[] DefaultSharedPatterns = new[] { @"compiler/shared/**/*.cs" };
|
||||||
public static readonly string[] DefaultResourcesBuiltInPatterns = new[] { @"compiler/resources/**/*", "**/*.resx" };
|
public static readonly string[] DefaultResourcesBuiltInPatterns = new[] { @"compiler/resources/**/*", "**/*.resx" };
|
||||||
|
@ -138,17 +138,15 @@ namespace Microsoft.Extensions.ProjectModel.Files
|
||||||
get { return SharedPatternsGroup.SearchFiles(_projectDirectory).Distinct(); }
|
get { return SharedPatternsGroup.SearchFiles(_projectDirectory).Distinct(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<string> GetFilesForBundling(bool includeSource, IEnumerable<string> additionalExcludePatterns)
|
public IEnumerable<string> GetFilesForBundling(IEnumerable<string> additionalExcludePatterns = null)
|
||||||
{
|
{
|
||||||
var patternGroup = new PatternGroup(ContentPatternsGroup.IncludePatterns,
|
var patternGroup = new PatternGroup(ContentPatternsGroup.IncludePatterns,
|
||||||
ContentPatternsGroup.ExcludePatterns.Concat(additionalExcludePatterns),
|
ContentPatternsGroup.ExcludePatterns.Concat(additionalExcludePatterns ?? new List<string>()),
|
||||||
ContentPatternsGroup.IncludeLiterals);
|
ContentPatternsGroup.IncludeLiterals);
|
||||||
if (!includeSource)
|
|
||||||
|
foreach (var excludedGroup in ContentPatternsGroup.ExcludePatternsGroup)
|
||||||
{
|
{
|
||||||
foreach (var excludedGroup in ContentPatternsGroup.ExcludePatternsGroup)
|
patternGroup.ExcludeGroup(excludedGroup);
|
||||||
{
|
|
||||||
patternGroup.ExcludeGroup(excludedGroup);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return patternGroup.SearchFiles(_projectDirectory);
|
return patternGroup.SearchFiles(_projectDirectory);
|
||||||
|
|
|
@ -22,12 +22,12 @@ namespace Microsoft.Extensions.ProjectModel.Graph
|
||||||
public static bool TryParse(string value, out LibraryType type)
|
public static bool TryParse(string value, out LibraryType type)
|
||||||
{
|
{
|
||||||
// We only support values we know about
|
// We only support values we know about
|
||||||
if(string.Equals(Package.Value, value, StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(Package.Value, value, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
type = Package;
|
type = Package;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if(string.Equals(Project.Value, value, StringComparison.OrdinalIgnoreCase))
|
else if (string.Equals(Project.Value, value, StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
type = Project;
|
type = Project;
|
||||||
return true;
|
return true;
|
||||||
|
@ -80,6 +80,10 @@ namespace Microsoft.Extensions.ProjectModel.Graph
|
||||||
|
|
||||||
public override int GetHashCode()
|
public override int GetHashCode()
|
||||||
{
|
{
|
||||||
|
if (string.IsNullOrEmpty(Value))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
return StringComparer.OrdinalIgnoreCase.GetHashCode(Value);
|
return StringComparer.OrdinalIgnoreCase.GetHashCode(Value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Microsoft.Extensions.Internal;
|
||||||
using Microsoft.Extensions.ProjectModel.Graph;
|
using Microsoft.Extensions.ProjectModel.Graph;
|
||||||
using NuGet.Frameworks;
|
using NuGet.Frameworks;
|
||||||
|
|
||||||
|
@ -14,7 +16,6 @@ namespace Microsoft.Extensions.ProjectModel
|
||||||
public class LibraryDescription
|
public class LibraryDescription
|
||||||
{
|
{
|
||||||
public LibraryDescription(
|
public LibraryDescription(
|
||||||
LibraryRange requestedRange,
|
|
||||||
LibraryIdentity identity,
|
LibraryIdentity identity,
|
||||||
string path,
|
string path,
|
||||||
IEnumerable<LibraryRange> dependencies,
|
IEnumerable<LibraryRange> dependencies,
|
||||||
|
@ -23,7 +24,6 @@ namespace Microsoft.Extensions.ProjectModel
|
||||||
bool compatible)
|
bool compatible)
|
||||||
{
|
{
|
||||||
Path = path;
|
Path = path;
|
||||||
RequestedRange = requestedRange;
|
|
||||||
Identity = identity;
|
Identity = identity;
|
||||||
Dependencies = dependencies ?? Enumerable.Empty<LibraryRange>();
|
Dependencies = dependencies ?? Enumerable.Empty<LibraryRange>();
|
||||||
Framework = framework;
|
Framework = framework;
|
||||||
|
@ -31,9 +31,9 @@ namespace Microsoft.Extensions.ProjectModel
|
||||||
Compatible = compatible;
|
Compatible = compatible;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LibraryRange RequestedRange { get; }
|
|
||||||
public LibraryIdentity Identity { get; }
|
public LibraryIdentity Identity { get; }
|
||||||
public List<LibraryDescription> Parents { get; set; } = new List<LibraryDescription>();
|
public HashSet<LibraryRange> RequestedRanges { get; } = new HashSet<LibraryRange>(new LibraryRangeEqualityComparer());
|
||||||
|
public List<LibraryDescription> Parents { get; } = new List<LibraryDescription>();
|
||||||
public string Path { get; }
|
public string Path { get; }
|
||||||
public IEnumerable<LibraryRange> Dependencies { get; }
|
public IEnumerable<LibraryRange> Dependencies { get; }
|
||||||
public bool Compatible { get; }
|
public bool Compatible { get; }
|
||||||
|
@ -45,5 +45,29 @@ namespace Microsoft.Extensions.ProjectModel
|
||||||
{
|
{
|
||||||
return $"{Identity} = {Path}";
|
return $"{Identity} = {Path}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For diagnostics, we don't want to duplicate requested dependencies so we
|
||||||
|
// dedupe dependencies defined in project.json
|
||||||
|
private class LibraryRangeEqualityComparer : IEqualityComparer<LibraryRange>
|
||||||
|
{
|
||||||
|
public bool Equals(LibraryRange x, LibraryRange y)
|
||||||
|
{
|
||||||
|
return x.Equals(y) &&
|
||||||
|
x.SourceColumn == y.SourceColumn &&
|
||||||
|
x.SourceLine == y.SourceLine &&
|
||||||
|
string.Equals(x.SourceFilePath, y.SourceFilePath, StringComparison.Ordinal);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GetHashCode(LibraryRange obj)
|
||||||
|
{
|
||||||
|
var combiner = HashCodeCombiner.Start();
|
||||||
|
combiner.Add(obj);
|
||||||
|
combiner.Add(obj.SourceFilePath);
|
||||||
|
combiner.Add(obj.SourceLine);
|
||||||
|
combiner.Add(obj.SourceColumn);
|
||||||
|
|
||||||
|
return combiner.CombinedHash;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,19 +6,17 @@ namespace Microsoft.Extensions.ProjectModel
|
||||||
public class PackageDescription : LibraryDescription
|
public class PackageDescription : LibraryDescription
|
||||||
{
|
{
|
||||||
public PackageDescription(
|
public PackageDescription(
|
||||||
LibraryRange requestedRange,
|
|
||||||
string path,
|
string path,
|
||||||
LockFilePackageLibrary package,
|
LockFilePackageLibrary package,
|
||||||
LockFileTargetLibrary lockFileLibrary,
|
LockFileTargetLibrary lockFileLibrary,
|
||||||
IEnumerable<LibraryRange> dependencies,
|
IEnumerable<LibraryRange> dependencies,
|
||||||
bool compatible)
|
bool compatible)
|
||||||
: base(
|
: base(
|
||||||
requestedRange,
|
|
||||||
new LibraryIdentity(package.Name, package.Version, LibraryType.Package),
|
new LibraryIdentity(package.Name, package.Version, LibraryType.Package),
|
||||||
path,
|
path,
|
||||||
dependencies: dependencies,
|
dependencies: dependencies,
|
||||||
framework: null,
|
framework: null,
|
||||||
resolved: true,
|
resolved: compatible,
|
||||||
compatible: compatible)
|
compatible: compatible)
|
||||||
{
|
{
|
||||||
Library = package;
|
Library = package;
|
||||||
|
|
|
@ -110,7 +110,7 @@ namespace Microsoft.Extensions.ProjectModel
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a library manager
|
// Create a library manager
|
||||||
var libraryManager = new LibraryManager(Project.ProjectFilePath, libraries.Values.ToList(), diagnostics);
|
var libraryManager = new LibraryManager(libraries.Values.ToList(), diagnostics);
|
||||||
|
|
||||||
return new ProjectContext(
|
return new ProjectContext(
|
||||||
GlobalSettings,
|
GlobalSettings,
|
||||||
|
@ -153,6 +153,7 @@ namespace Microsoft.Extensions.ProjectModel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dep.RequestedRanges.Add(dependency);
|
||||||
dep.Parents.Add(library);
|
dep.Parents.Add(library);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,6 @@ namespace Microsoft.Extensions.ProjectModel
|
||||||
// Create an unresolved project description
|
// Create an unresolved project description
|
||||||
public ProjectDescription(string name, string path)
|
public ProjectDescription(string name, string path)
|
||||||
: base(
|
: base(
|
||||||
new LibraryRange(name, LibraryType.Unspecified),
|
|
||||||
new LibraryIdentity(name, LibraryType.Project),
|
new LibraryIdentity(name, LibraryType.Project),
|
||||||
path,
|
path,
|
||||||
Enumerable.Empty<LibraryRange>(),
|
Enumerable.Empty<LibraryRange>(),
|
||||||
|
@ -28,7 +27,6 @@ namespace Microsoft.Extensions.ProjectModel
|
||||||
TargetFrameworkInformation targetFrameworkInfo,
|
TargetFrameworkInformation targetFrameworkInfo,
|
||||||
bool resolved) :
|
bool resolved) :
|
||||||
base(
|
base(
|
||||||
libraryRange,
|
|
||||||
new LibraryIdentity(project.Name, project.Version, LibraryType.Project),
|
new LibraryIdentity(project.Name, project.Version, LibraryType.Project),
|
||||||
project.ProjectFilePath,
|
project.ProjectFilePath,
|
||||||
dependencies,
|
dependencies,
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using NuGet.Frameworks;
|
using System.Linq;
|
||||||
|
using Microsoft.Extensions.ProjectModel.Graph;
|
||||||
using NuGet.Versioning;
|
using NuGet.Versioning;
|
||||||
|
|
||||||
namespace Microsoft.Extensions.ProjectModel.Resolution
|
namespace Microsoft.Extensions.ProjectModel.Resolution
|
||||||
|
@ -12,13 +14,10 @@ namespace Microsoft.Extensions.ProjectModel.Resolution
|
||||||
{
|
{
|
||||||
private readonly IList<LibraryDescription> _libraries;
|
private readonly IList<LibraryDescription> _libraries;
|
||||||
private readonly IList<DiagnosticMessage> _diagnostics;
|
private readonly IList<DiagnosticMessage> _diagnostics;
|
||||||
private readonly string _projectPath;
|
|
||||||
|
|
||||||
public LibraryManager(string projectPath,
|
public LibraryManager(IList<LibraryDescription> libraries,
|
||||||
IList<LibraryDescription> libraries,
|
|
||||||
IList<DiagnosticMessage> diagnostics)
|
IList<DiagnosticMessage> diagnostics)
|
||||||
{
|
{
|
||||||
_projectPath = projectPath;
|
|
||||||
_libraries = libraries;
|
_libraries = libraries;
|
||||||
_diagnostics = diagnostics;
|
_diagnostics = diagnostics;
|
||||||
}
|
}
|
||||||
|
@ -39,72 +38,110 @@ namespace Microsoft.Extensions.ProjectModel.Resolution
|
||||||
|
|
||||||
foreach (var library in GetLibraries())
|
foreach (var library in GetLibraries())
|
||||||
{
|
{
|
||||||
string projectPath = library.RequestedRange.SourceFilePath ?? _projectPath;
|
|
||||||
|
|
||||||
if (!library.Resolved)
|
if (!library.Resolved)
|
||||||
{
|
{
|
||||||
string message;
|
string message;
|
||||||
string errorCode;
|
string errorCode;
|
||||||
if (library.Compatible)
|
if (library.Compatible)
|
||||||
{
|
{
|
||||||
errorCode = ErrorCodes.NU1001;
|
foreach (var range in library.RequestedRanges)
|
||||||
message = $"The dependency {library.RequestedRange.Name} {library.RequestedRange.VersionRange} could not be resolved.";
|
{
|
||||||
|
errorCode = ErrorCodes.NU1001;
|
||||||
|
message = $"The dependency {range.Name} {range.VersionRange} could not be resolved.";
|
||||||
|
|
||||||
|
AddDiagnostics(messages, library, message, errorCode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
errorCode = ErrorCodes.NU1002;
|
errorCode = ErrorCodes.NU1002;
|
||||||
var projectName = Directory.GetParent(_projectPath).Name;
|
message = $"The dependency {library.Identity} does not support framework {library.Framework}.";
|
||||||
message = $"The dependency {library.Identity} in project {projectName} does not support framework {library.Framework}.";
|
|
||||||
}
|
|
||||||
|
|
||||||
messages.Add(
|
AddDiagnostics(messages, library, message, errorCode);
|
||||||
new DiagnosticMessage(
|
}
|
||||||
errorCode,
|
|
||||||
message,
|
|
||||||
projectPath,
|
|
||||||
DiagnosticMessageSeverity.Error,
|
|
||||||
library.RequestedRange.SourceLine,
|
|
||||||
library.RequestedRange.SourceColumn,
|
|
||||||
library));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Skip libraries that aren't specified in a project.json
|
foreach (var range in library.RequestedRanges)
|
||||||
if (string.IsNullOrEmpty(library.RequestedRange.SourceFilePath))
|
|
||||||
{
|
{
|
||||||
continue;
|
// Skip libraries that aren't specified in a project.json
|
||||||
}
|
if (string.IsNullOrEmpty(range.SourceFilePath))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (library.RequestedRange.VersionRange == null)
|
if (range.VersionRange == null)
|
||||||
{
|
{
|
||||||
// TODO: Show errors/warnings for things without versions
|
// TODO: Show errors/warnings for things without versions
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we ended up with a declared version that isn't what was asked for directly
|
// If we ended up with a declared version that isn't what was asked for directly
|
||||||
// then report a warning
|
// then report a warning
|
||||||
// Case 1: Non floating version and the minimum doesn't match what was specified
|
// Case 1: Non floating version and the minimum doesn't match what was specified
|
||||||
// Case 2: Floating version that fell outside of the range
|
// Case 2: Floating version that fell outside of the range
|
||||||
if ((!library.RequestedRange.VersionRange.IsFloating &&
|
if ((!range.VersionRange.IsFloating &&
|
||||||
library.RequestedRange.VersionRange.MinVersion != library.Identity.Version) ||
|
range.VersionRange.MinVersion != library.Identity.Version) ||
|
||||||
(library.RequestedRange.VersionRange.IsFloating &&
|
(range.VersionRange.IsFloating &&
|
||||||
!library.RequestedRange.VersionRange.EqualsFloating(library.Identity.Version)))
|
!range.VersionRange.Float.Satisfies(library.Identity.Version)))
|
||||||
{
|
{
|
||||||
var message = string.Format("Dependency specified was {0} but ended up with {1}.", library.RequestedRange, library.Identity);
|
var message = $"Dependency specified was {range} but ended up with {library.Identity}.";
|
||||||
messages.Add(
|
|
||||||
new DiagnosticMessage(
|
foreach (var source in GetRangesWithSourceLocations(library))
|
||||||
ErrorCodes.NU1007,
|
{
|
||||||
message,
|
messages.Add(
|
||||||
projectPath,
|
new DiagnosticMessage(
|
||||||
DiagnosticMessageSeverity.Warning,
|
ErrorCodes.NU1007,
|
||||||
library.RequestedRange.SourceLine,
|
message,
|
||||||
library.RequestedRange.SourceColumn,
|
source.SourceFilePath,
|
||||||
library));
|
DiagnosticMessageSeverity.Warning,
|
||||||
|
source.SourceLine,
|
||||||
|
source.SourceColumn,
|
||||||
|
library));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return messages;
|
return messages;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void AddDiagnostics(List<DiagnosticMessage> messages, LibraryDescription library, string message, string errorCode)
|
||||||
|
{
|
||||||
|
// A (in project.json) -> B (unresolved) (not in project.json)
|
||||||
|
foreach (var source in GetRangesWithSourceLocations(library).Distinct())
|
||||||
|
{
|
||||||
|
messages.Add(
|
||||||
|
new DiagnosticMessage(
|
||||||
|
errorCode,
|
||||||
|
message,
|
||||||
|
source.SourceFilePath,
|
||||||
|
DiagnosticMessageSeverity.Error,
|
||||||
|
source.SourceLine,
|
||||||
|
source.SourceColumn,
|
||||||
|
library));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private IEnumerable<LibraryRange> GetRangesWithSourceLocations(LibraryDescription library)
|
||||||
|
{
|
||||||
|
foreach (var range in library.RequestedRanges)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(range.SourceFilePath))
|
||||||
|
{
|
||||||
|
yield return range;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var parent in library.Parents)
|
||||||
|
{
|
||||||
|
foreach (var relevantPath in GetRangesWithSourceLocations(parent))
|
||||||
|
{
|
||||||
|
yield return relevantPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -36,7 +36,6 @@ namespace Microsoft.Extensions.ProjectModel.Resolution
|
||||||
var path = _packagePathResolver.GetInstallPath(package.Name, package.Version);
|
var path = _packagePathResolver.GetInstallPath(package.Name, package.Version);
|
||||||
|
|
||||||
var packageDescription = new PackageDescription(
|
var packageDescription = new PackageDescription(
|
||||||
new LibraryRange(package.Name, new VersionRange(package.Version), LibraryType.Package, LibraryDependencyType.Default),
|
|
||||||
path,
|
path,
|
||||||
package,
|
package,
|
||||||
targetLibrary,
|
targetLibrary,
|
||||||
|
|
|
@ -41,7 +41,6 @@ namespace Microsoft.Extensions.ProjectModel.Resolution
|
||||||
if (version == null || version.Version == assemblyVersion)
|
if (version == null || version.Version == assemblyVersion)
|
||||||
{
|
{
|
||||||
return new LibraryDescription(
|
return new LibraryDescription(
|
||||||
libraryRange,
|
|
||||||
new LibraryIdentity(libraryRange.Name, new NuGetVersion(assemblyVersion), LibraryType.ReferenceAssembly),
|
new LibraryIdentity(libraryRange.Name, new NuGetVersion(assemblyVersion), LibraryType.ReferenceAssembly),
|
||||||
path,
|
path,
|
||||||
Enumerable.Empty<LibraryRange>(),
|
Enumerable.Empty<LibraryRange>(),
|
||||||
|
|
|
@ -12,7 +12,6 @@ namespace Microsoft.Extensions.ProjectModel.Resolution
|
||||||
public static LibraryDescription GetDescription(LibraryRange libraryRange, NuGetFramework targetFramework)
|
public static LibraryDescription GetDescription(LibraryRange libraryRange, NuGetFramework targetFramework)
|
||||||
{
|
{
|
||||||
return new LibraryDescription(
|
return new LibraryDescription(
|
||||||
libraryRange,
|
|
||||||
new LibraryIdentity(libraryRange.Name, libraryRange.VersionRange?.MinVersion, libraryRange.Target),
|
new LibraryIdentity(libraryRange.Name, libraryRange.VersionRange?.MinVersion, libraryRange.Target),
|
||||||
path: null,
|
path: null,
|
||||||
dependencies: Enumerable.Empty<LibraryRange>(),
|
dependencies: Enumerable.Empty<LibraryRange>(),
|
||||||
|
|
|
@ -1,45 +0,0 @@
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace NuGet.Versioning
|
|
||||||
{
|
|
||||||
public static class VersioningExtensions
|
|
||||||
{
|
|
||||||
public static bool EqualsFloating(this VersionRange self, NuGetVersion version)
|
|
||||||
{
|
|
||||||
if(!self.IsFloating)
|
|
||||||
{
|
|
||||||
return Equals(self.MinVersion, version);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (self.Float.FloatBehavior)
|
|
||||||
{
|
|
||||||
case NuGetVersionFloatBehavior.Prerelease:
|
|
||||||
return self.MinVersion.Version == version.Version &&
|
|
||||||
version.Release.StartsWith(self.MinVersion.Release, StringComparison.OrdinalIgnoreCase);
|
|
||||||
|
|
||||||
case NuGetVersionFloatBehavior.Revision:
|
|
||||||
return self.MinVersion.Major == version.Major &&
|
|
||||||
self.MinVersion.Minor == version.Minor &&
|
|
||||||
self.MinVersion.Patch == version.Patch &&
|
|
||||||
self.MinVersion.Revision == version.Revision;
|
|
||||||
|
|
||||||
case NuGetVersionFloatBehavior.Patch:
|
|
||||||
return self.MinVersion.Major == version.Major &&
|
|
||||||
self.MinVersion.Minor == version.Minor &&
|
|
||||||
self.MinVersion.Patch == version.Patch;
|
|
||||||
|
|
||||||
case NuGetVersionFloatBehavior.Minor:
|
|
||||||
return self.MinVersion.Major == version.Major &&
|
|
||||||
self.MinVersion.Minor == version.Minor;
|
|
||||||
|
|
||||||
case NuGetVersionFloatBehavior.Major:
|
|
||||||
return self.MinVersion.Major == version.Major;
|
|
||||||
|
|
||||||
case NuGetVersionFloatBehavior.None:
|
|
||||||
return self.MinVersion == version;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Add table
Add a link
Reference in a new issue