Merge branch 'master' of https://github.com/dotnet/cli into package_build

This commit is contained in:
Sridhar Periyasamy 2015-10-20 10:43:39 -07:00
commit e95acaa27d
19 changed files with 233 additions and 141 deletions

View file

@ -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

View file

@ -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(

View file

@ -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": {

View file

@ -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"));

View file

@ -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)

View file

@ -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));
}
}

View file

@ -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)

View file

@ -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);

View file

@ -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);
} }
} }

View file

@ -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;
}
}
} }
} }

View file

@ -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;

View file

@ -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);
} }
} }

View file

@ -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,

View file

@ -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;
}
}
}
} }
} }

View file

@ -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,

View file

@ -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>(),

View file

@ -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>(),

View file

@ -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;
}
}
}
}