Changing the code to read tools from csproj because the tools section in assets.json is no longer being populated.

This commit is contained in:
Livar Cunha 2016-10-04 18:58:04 -07:00
parent 1570e0fde4
commit facbef52ff
7 changed files with 159 additions and 103 deletions

View file

@ -0,0 +1,45 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.Build.Evaluation;
using NuGet.ProjectModel;
namespace Microsoft.DotNet.Cli.CommandResolution
{
internal class CSProjProject : IProject
{
private Project _project;
public CSProjProject(string csProjPath)
{
var globalProperties = new Dictionary<string, string>()
{
{ "MSBuildExtensionsPath", AppContext.BaseDirectory }
};
_project = new Project(csProjPath, globalProperties, null);
}
public LockFile GetLockFile()
{
var intermediateOutputPath = _project
.AllEvaluatedProperties
.FirstOrDefault(p => p.Name.Equals("BaseIntermediateOutputPath"))
.EvaluatedValue;
var lockFilePath = Path.Combine(intermediateOutputPath, "project.assets.json");
return new LockFileFormat().Read(lockFilePath);
}
public IEnumerable<SingleProjectInfo> GetTools()
{
var toolsReferences = _project.AllEvaluatedItems.Where(i => i.ItemType.Equals("DotNetCliToolsReference"));
var tools = toolsReferences.Select(t => new SingleProjectInfo(
t.EvaluatedInclude,
t.GetMetadataValue("Version"),
Enumerable.Empty<ResourceAssemblyInfo>()));
return tools;
}
}
}

View file

@ -0,0 +1,12 @@
using System.Collections.Generic;
using NuGet.ProjectModel;
namespace Microsoft.DotNet.Cli.CommandResolution
{
internal interface IProject
{
LockFile GetLockFile();
IEnumerable<SingleProjectInfo> GetTools();
}
}

View file

@ -1,63 +0,0 @@
// 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.Build.Evaluation;
using NuGet.ProjectModel;
namespace Microsoft.DotNet.Cli.CommandResolution
{
internal class LockFilePathCalculator
{
public string GetLockFilePath(string projectDirectory)
{
return ResolveLockFilePathUsingCSProj(projectDirectory) ??
ReturnProjectLockJson(projectDirectory);
}
private string ResolveLockFilePathUsingCSProj(string projectDirectory)
{
string csProjPath = GetCSProjPath(projectDirectory);
if(csProjPath == null)
{
return null;
}
var globalProperties = new Dictionary<string, string>()
{
{ "MSBuildExtensionsPath", AppContext.BaseDirectory }
};
Project project = new Project(csProjPath, globalProperties, null);
// TODO: This is temporary. We should use ProjectLockFile property, but for some reason, it is coming up as project.lock.json
// instead of the path to project.assets.json.
var lockFilePath = project.AllEvaluatedProperties.FirstOrDefault(p => p.Name.Equals("BaseIntermediateOutputPath")).EvaluatedValue;
return Path.Combine(lockFilePath, "project.assets.json");
}
private string ReturnProjectLockJson(string projectDirectory)
{
return Path.Combine(projectDirectory, LockFileFormat.LockFileName);
}
private string GetCSProjPath(string projectDirectory)
{
string[] projectFiles = Directory.GetFiles(projectDirectory, "*.*proj");
if (projectFiles.Length == 0)
{
return null;
}
else if (projectFiles.Length > 1)
{
throw new InvalidOperationException(
$"Specify which project file to use because this '{projectDirectory}' contains more than one project file.");
}
return projectFiles[0];
}
}
}

View file

@ -0,0 +1,50 @@
// 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.IO;
namespace Microsoft.DotNet.Cli.CommandResolution
{
internal class ProjectFactory
{
public IProject GetProject(string projectDirectory)
{
return GetCsProjProject(projectDirectory) ??
GetProjectJsonProject(projectDirectory);
}
private IProject GetCsProjProject(string projectDirectory)
{
string csProjPath = GetCSProjPath(projectDirectory);
if(csProjPath == null)
{
return null;
}
return new CSProjProject(csProjPath);
}
private IProject GetProjectJsonProject(string projectDirectory)
{
return new ProjectJsonProject(projectDirectory);
}
private string GetCSProjPath(string projectDirectory)
{
string[] projectFiles = Directory.GetFiles(projectDirectory, "*.*proj");
if (projectFiles.Length == 0)
{
return null;
}
else if (projectFiles.Length > 1)
{
throw new InvalidOperationException(
$"Specify which project file to use because this '{projectDirectory}' contains more than one project file.");
}
return projectFiles[0];
}
}
}

View file

@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using NuGet.ProjectModel;
namespace Microsoft.DotNet.Cli.CommandResolution
{
internal class ProjectJsonProject : IProject
{
private LockFile _lockFile;
public ProjectJsonProject(string projectDirectory)
{
var lockFilePath = Path.Combine(projectDirectory, LockFileFormat.LockFileName);
_lockFile = new LockFileFormat().Read(lockFilePath);
}
public LockFile GetLockFile()
{
return _lockFile;
}
public IEnumerable<SingleProjectInfo> GetTools()
{
var tools = _lockFile.Tools.Where(t => t.Name.Contains(".NETCoreApp")).SelectMany(t => t.Libraries);
return tools.Select(t => new SingleProjectInfo(
t.Name,
t.Version.ToFullString(),
Enumerable.Empty<ResourceAssemblyInfo>()));
}
}
}

View file

@ -53,19 +53,19 @@ namespace Microsoft.DotNet.Cli.CommandResolution
IEnumerable<string> args,
string projectDirectory)
{
var lockFilePathCalculator = new LockFilePathCalculator();
var lockFile = new LockFileFormat().Read(lockFilePathCalculator.GetLockFilePath(projectDirectory));
var tools = lockFile.Tools.Where(t => t.Name.Contains(".NETCoreApp")).SelectMany(t => t.Libraries);
var projectFactory = new ProjectFactory();
var project = projectFactory.GetProject(projectDirectory);
var tools = project.GetTools();
return ResolveCommandSpecFromAllToolLibraries(
tools,
commandName,
args,
lockFile);
project.GetLockFile());
}
private CommandSpec ResolveCommandSpecFromAllToolLibraries(
IEnumerable<LockFileTargetLibrary> toolsLibraries,
IEnumerable<SingleProjectInfo> toolsLibraries,
string commandName,
IEnumerable<string> args,
LockFile lockFile)
@ -84,7 +84,7 @@ namespace Microsoft.DotNet.Cli.CommandResolution
}
private CommandSpec ResolveCommandSpecFromToolLibrary(
LockFileTargetLibrary toolLibraryRange,
SingleProjectInfo toolLibraryRange,
string commandName,
IEnumerable<string> args,
LockFile lockFile)
@ -120,7 +120,7 @@ namespace Microsoft.DotNet.Cli.CommandResolution
}
private LockFile GetToolLockFile(
LockFileTargetLibrary toolLibrary,
SingleProjectInfo toolLibrary,
string nugetPackagesRoot)
{
var lockFilePath = GetToolLockFilePath(toolLibrary, nugetPackagesRoot);
@ -145,36 +145,19 @@ namespace Microsoft.DotNet.Cli.CommandResolution
}
private string GetToolLockFilePath(
LockFileTargetLibrary toolLibrary,
SingleProjectInfo toolLibrary,
string nugetPackagesRoot)
{
var toolPathCalculator = new ToolPathCalculator(nugetPackagesRoot);
return toolPathCalculator.GetBestLockFilePath(
toolLibrary.Name,
new VersionRange(toolLibrary.Version),
new VersionRange(new NuGetVersion(toolLibrary.Version)),
s_toolPackageFramework);
}
private ProjectContext GetProjectContextFromDirectoryForFirstTarget(string projectRootPath)
{
if (projectRootPath == null)
{
return null;
}
if (!File.Exists(Path.Combine(projectRootPath, Project.FileName)))
{
return null;
}
var projectContext = ProjectContext.CreateContextForEachTarget(projectRootPath).FirstOrDefault();
return projectContext;
}
private string GetToolDepsFilePath(
LockFileTargetLibrary toolLibrary,
SingleProjectInfo toolLibrary,
LockFile toolLockFile,
string depsPathRoot)
{
@ -190,7 +173,7 @@ namespace Microsoft.DotNet.Cli.CommandResolution
private void EnsureToolJsonDepsFileExists(
LockFile toolLockFile,
string depsPath,
LockFileTargetLibrary toolLibrary)
SingleProjectInfo toolLibrary)
{
if (!File.Exists(depsPath))
{
@ -199,20 +182,15 @@ namespace Microsoft.DotNet.Cli.CommandResolution
}
// Need to unit test this, so public
public void GenerateDepsJsonFile(
internal void GenerateDepsJsonFile(
LockFile toolLockFile,
string depsPath,
LockFileTargetLibrary toolLibrary)
SingleProjectInfo toolLibrary)
{
Reporter.Verbose.WriteLine($"Generating deps.json at: {depsPath}");
var singleProjectInfo = new SingleProjectInfo(
toolLibrary.Name,
toolLibrary.Version.ToFullString(),
Enumerable.Empty<ResourceAssemblyInfo>());
var dependencyContext = new DepsJsonBuilder()
.Build(singleProjectInfo, null, toolLockFile, s_toolPackageFramework, null);
.Build(toolLibrary, null, toolLockFile, s_toolPackageFramework, null);
var tempDepsFile = Path.GetTempFileName();
using (var fileStream = File.Open(tempDepsFile, FileMode.Open, FileAccess.Write))

View file

@ -222,10 +222,10 @@ namespace Microsoft.DotNet.Tests
File.WriteAllText(depsJsonFile, "temp");
var projectToolsCommandResolver = SetupProjectToolsCommandResolver();
projectToolsCommandResolver.GenerateDepsJsonFile(lockFile, depsJsonFile, new LockFileTargetLibrary {
Name = "dotnet-portable",
Version = new NuGetVersion("1.0.0")
});
projectToolsCommandResolver.GenerateDepsJsonFile(
lockFile,
depsJsonFile,
new SingleProjectInfo("dotnet-portable", "1.0.0", Enumerable.Empty<ResourceAssemblyInfo>()));
File.ReadAllText(depsJsonFile).Should().Be("temp");
File.Delete(depsJsonFile);