From 8fb38d36377c9529f3ee2ed01db0596ee3e87325 Mon Sep 17 00:00:00 2001 From: Prafull Bhosale Date: Wed, 12 Oct 2016 13:17:56 -0700 Subject: [PATCH] Add Project References to ProjectContext --- .../IProjectContext.cs | 1 + .../DotNetDependencyProvider.cs | 52 ++++++++++++------- .../DotNetProjectContext.cs | 14 +++++ .../MsBuildProjectContext.cs | 13 +++++ .../MsBuildProjectDependencyProvider.cs | 12 +++++ .../DotNet/DotNetDependencyProviderTests.cs | 43 +++++++++++++-- .../MsBuildProjectDependencyProviderTests.cs | 21 ++++---- 7 files changed, 123 insertions(+), 33 deletions(-) diff --git a/src/Microsoft.Extensions.ProjectModel.Abstractions.Sources/IProjectContext.cs b/src/Microsoft.Extensions.ProjectModel.Abstractions.Sources/IProjectContext.cs index 972f85caff..de53669917 100644 --- a/src/Microsoft.Extensions.ProjectModel.Abstractions.Sources/IProjectContext.cs +++ b/src/Microsoft.Extensions.ProjectModel.Abstractions.Sources/IProjectContext.cs @@ -29,5 +29,6 @@ namespace Microsoft.Extensions.ProjectModel string FindProperty(string propertyName); IEnumerable PackageDependencies { get;} IEnumerable CompilationAssemblies { get; } + IEnumerable ProjectReferences { get; } } } \ No newline at end of file diff --git a/src/Microsoft.Extensions.ProjectModel.DotNet.Sources/DotNetDependencyProvider.cs b/src/Microsoft.Extensions.ProjectModel.DotNet.Sources/DotNetDependencyProvider.cs index 429a2a6a68..137acba5b6 100644 --- a/src/Microsoft.Extensions.ProjectModel.DotNet.Sources/DotNetDependencyProvider.cs +++ b/src/Microsoft.Extensions.ProjectModel.DotNet.Sources/DotNetDependencyProvider.cs @@ -17,6 +17,7 @@ namespace Microsoft.Extensions.ProjectModel private List _packageDependencies; private List _resolvedReferences; private string _configuration; + private List _projectReferences; public DotNetDependencyProvider(ProjectContext context, string configuration = Constants.DefaultConfiguration) { @@ -30,6 +31,11 @@ namespace Microsoft.Extensions.ProjectModel DiscoverDependencies(); } + public IEnumerable GetProjectReferences() + { + return _projectReferences; + } + public IEnumerable GetPackageDependencies() { return _packageDependencies; @@ -55,31 +61,41 @@ namespace Microsoft.Extensions.ProjectModel throw new InvalidOperationException("Couldn't resolve dependencies when target framework is not specified."); } - var exports = exporter.GetAllExports(); - var nugetPackages = new Dictionary(StringComparer.OrdinalIgnoreCase); + var exports = exporter.GetDependencies(); _resolvedReferences = new List(); + _packageDependencies = new List(); + _projectReferences = new List(); foreach (var export in exports) { var library = export.Library; - - var description = new DependencyDescription( - library.Identity.Name, - library.Identity.Version.ToString(), - export.Library.Path, - framework.DotNetFrameworkName, - library.Identity.Type.Value, - library.Resolved); - - foreach (var dependency in export.Library.Dependencies) + var project = library as ProjectDescription; + if (project != null) { - var dep = new Dependency(dependency.Name, version: string.Empty); - description.AddDependency(dep); + _projectReferences.Add(project.Project.ProjectFilePath); + } + else + { + var description = new DependencyDescription( + library.Identity.Name, + library.Identity.Version.ToString(), + export.Library.Path, + framework.DotNetFrameworkName, + library.Identity.Type.Value, + library.Resolved); + + foreach (var dependency in export.Library.Dependencies) + { + var dep = new Dependency(dependency.Name, version: string.Empty); + description.AddDependency(dep); + } + + + var itemSpec = $"{framework.DotNetFrameworkName}/{library.Identity.Name}/{library.Identity.Version.ToString()}"; + _packageDependencies.Add(description); } - var itemSpec = $"{framework.DotNetFrameworkName}/{library.Identity.Name}/{library.Identity.Version.ToString()}"; - nugetPackages[itemSpec] = description; - + // For resolved references we need to include all type of dependencies. if (library.Resolved) { foreach (var asset in export.CompilationAssemblies) @@ -91,8 +107,6 @@ namespace Microsoft.Extensions.ProjectModel } } } - - _packageDependencies = nugetPackages.Values.ToList(); } } } diff --git a/src/Microsoft.Extensions.ProjectModel.DotNet.Sources/DotNetProjectContext.cs b/src/Microsoft.Extensions.ProjectModel.DotNet.Sources/DotNetProjectContext.cs index e038e6b42c..b8d9bb476f 100644 --- a/src/Microsoft.Extensions.ProjectModel.DotNet.Sources/DotNetProjectContext.cs +++ b/src/Microsoft.Extensions.ProjectModel.DotNet.Sources/DotNetProjectContext.cs @@ -22,6 +22,7 @@ namespace Microsoft.Extensions.ProjectModel private IEnumerable _packageDependencies; private IEnumerable _compilationAssemblies; + private IEnumerable _projectReferences; public DotNetProjectContext(ProjectContext projectContext, string configuration, string outputPath) { @@ -118,6 +119,19 @@ namespace Microsoft.Extensions.ProjectModel } } + public IEnumerable ProjectReferences + { + get + { + if (_projectReferences == null) + { + _projectReferences = _dependencyProvider.Value.GetProjectReferences(); + } + + return _projectReferences; + } + } + /// /// Returns string values of top-level keys in the project.json file /// diff --git a/src/Microsoft.Extensions.ProjectModel.MsBuild.Sources/MsBuildProjectContext.cs b/src/Microsoft.Extensions.ProjectModel.MsBuild.Sources/MsBuildProjectContext.cs index 8e46ac8beb..2c9bc7a732 100644 --- a/src/Microsoft.Extensions.ProjectModel.MsBuild.Sources/MsBuildProjectContext.cs +++ b/src/Microsoft.Extensions.ProjectModel.MsBuild.Sources/MsBuildProjectContext.cs @@ -20,6 +20,7 @@ namespace Microsoft.Extensions.ProjectModel private readonly MsBuildProjectDependencyProvider _dependencyProvider; private IEnumerable _packageDependencies; private IEnumerable _compilationAssemblies; + private IEnumerable _projectReferences; protected ProjectInstance Project { get; } protected string Name { get; } @@ -114,5 +115,17 @@ namespace Microsoft.Extensions.ProjectModel } } + public IEnumerable ProjectReferences + { + get + { + if (_projectReferences == null) + { + _projectReferences = _dependencyProvider.GetProjectReferences(); + } + + return _projectReferences; + } + } } } \ No newline at end of file diff --git a/src/Microsoft.Extensions.ProjectModel.MsBuild.Sources/MsBuildProjectDependencyProvider.cs b/src/Microsoft.Extensions.ProjectModel.MsBuild.Sources/MsBuildProjectDependencyProvider.cs index 8c4345e158..5afad1590a 100644 --- a/src/Microsoft.Extensions.ProjectModel.MsBuild.Sources/MsBuildProjectDependencyProvider.cs +++ b/src/Microsoft.Extensions.ProjectModel.MsBuild.Sources/MsBuildProjectDependencyProvider.cs @@ -25,6 +25,18 @@ namespace Microsoft.Extensions.ProjectModel _projectInstance = projectInstance; } + public IEnumerable GetProjectReferences() + { + var projectPaths = _projectInstance + .GetItems("ProjectReference") + .Select(reference => reference.EvaluatedInclude); + + return projectPaths + .Select(path => Path.IsPathRooted(path) + ? path + : Path.Combine(_projectInstance.Directory, path)); + } + public IEnumerable GetPackageDependencies() { var packageItems = _projectInstance.GetItems(PackageDependencyItemType); diff --git a/test/Microsoft.Extensions.ProjectModel.Tests/DotNet/DotNetDependencyProviderTests.cs b/test/Microsoft.Extensions.ProjectModel.Tests/DotNet/DotNetDependencyProviderTests.cs index e5fe160a69..18b6c0b9bc 100644 --- a/test/Microsoft.Extensions.ProjectModel.Tests/DotNet/DotNetDependencyProviderTests.cs +++ b/test/Microsoft.Extensions.ProjectModel.Tests/DotNet/DotNetDependencyProviderTests.cs @@ -13,7 +13,33 @@ namespace Microsoft.Extensions.ProjectModel.DotNet { public class DotNetDependencyProviderTests { + private const string globalJson = @" +{ + ""projects"": [ ""demo"", ""demoLib""] +}"; + private const string projectJson = @" +{ + ""buildOptions"": { + }, + ""dependencies"": { + ""Microsoft.AspNetCore.Mvc"": ""1.0.0-*"", + ""demoLib"": ""1.0.0-*"", + }, + ""frameworks"": { + ""netcoreapp1.0"": { + ""dependencies"": { + ""Microsoft.NETCore.App"": { + ""version"": ""1.0.0"", + ""type"": ""platform"" + } + } + } + }, +} +"; + + private const string libProjectJson = @" { ""buildOptions"": { }, @@ -45,13 +71,20 @@ namespace Microsoft.Extensions.ProjectModel.DotNet using (var fileProvider = new TemporaryFileProvider()) { Directory.CreateDirectory(Path.Combine(fileProvider.Root, "demo")); - fileProvider.Add($"demo{Path.DirectorySeparatorChar}project.json", projectJson); - fileProvider.Add($"demo{Path.DirectorySeparatorChar}First.cs", "namespace demo { class First{} }"); + Directory.CreateDirectory(Path.Combine(fileProvider.Root, "demoLib")); + + fileProvider.Add($"global.json", globalJson); + + fileProvider.Add($"demo/project.json", projectJson); + fileProvider.Add($"demo/First.cs", "namespace demo { class First{} }"); + + fileProvider.Add($"demoLib/project.json", libProjectJson); + fileProvider.Add($"demoLib/Second.cs", "namespace demoLib { class First{} }"); var muxer = new Muxer().MuxerPath; var result = Command - .Create(muxer, new[] { "restore", Path.Combine(fileProvider.Root, "demo") }) + .Create(muxer, new[] { "restore", fileProvider.Root }) .OnErrorLine(l => _output.WriteLine(l)) .OnOutputLine(l => _output.WriteLine(l)) .Execute(); @@ -77,7 +110,9 @@ namespace Microsoft.Extensions.ProjectModel.DotNet .First(); Assert.True(Directory.Exists(mvcPackage.Path)); - Assert.True(mvcPackage.Path.EndsWith($"Microsoft.AspNetCore.Mvc{Path.DirectorySeparatorChar}1.0.0", StringComparison.OrdinalIgnoreCase)); + Assert.True(mvcPackage.Path.EndsWith($"Microsoft.AspNetCore.Mvc/1.0.0", StringComparison.OrdinalIgnoreCase)); + + Assert.True(context.ProjectReferences.First().Equals(Path.Combine(fileProvider.Root, "demoLib", "project.json"))); } } } diff --git a/test/Microsoft.Extensions.ProjectModel.Tests/MsBuild/MsBuildProjectDependencyProviderTests.cs b/test/Microsoft.Extensions.ProjectModel.Tests/MsBuild/MsBuildProjectDependencyProviderTests.cs index 9caea9c562..7b4eedc203 100644 --- a/test/Microsoft.Extensions.ProjectModel.Tests/MsBuild/MsBuildProjectDependencyProviderTests.cs +++ b/test/Microsoft.Extensions.ProjectModel.Tests/MsBuild/MsBuildProjectDependencyProviderTests.cs @@ -53,7 +53,7 @@ namespace Microsoft.Extensions.ProjectModel.MsBuild - + @@ -109,14 +109,14 @@ namespace Microsoft.Extensions.ProjectModel.MsBuild fileProvider.Add("NuGet.config", NugetConfigTxt); // Add Root Project - fileProvider.Add($"Root{Path.DirectorySeparatorChar}test.csproj", RootProjectTxt); - fileProvider.Add($"Root{Path.DirectorySeparatorChar}One.cs", "public class Abc {}"); - fileProvider.Add($"Root{Path.DirectorySeparatorChar}Two.cs", "public class Abc2 {}"); - fileProvider.Add($"Root{Path.DirectorySeparatorChar}Excluded.cs", "public class Abc {}"); + fileProvider.Add($"Root/test.csproj", RootProjectTxt); + fileProvider.Add($"Root/One.cs", "public class Abc {}"); + fileProvider.Add($"Root/Two.cs", "public class Abc2 {}"); + fileProvider.Add($"Root/Excluded.cs", "public class Abc {}"); // Add Class Library project - fileProvider.Add($"Library1{Path.DirectorySeparatorChar}library.csproj", LibraryProjectTxt); - fileProvider.Add($"Library1{Path.DirectorySeparatorChar}Three.cs", "public class Abc3 {}"); + fileProvider.Add($"Library1/Library1.csproj", LibraryProjectTxt); + fileProvider.Add($"Library1/Three.cs", "public class Abc3 {}"); var testContext = _fixture.GetMsBuildContext(); @@ -152,9 +152,8 @@ namespace Microsoft.Extensions.ProjectModel.MsBuild .FirstOrDefault(); Assert.NotNull(lib1Dll); - var expectedPath = Path.Combine(fileProvider.Root, "Root", "bin", "Debug", "netcoreapp1.0", "lib1.dll"); - Assert.Equal(expectedPath, lib1Dll.ResolvedPath, ignoreCase: true); - + Assert.True(File.Exists(lib1Dll.ResolvedPath)); + // This reference doesn't resolve so should not be available here. Assert.False(compilationAssemblies.Any(assembly => assembly.Name.Equals("xyz", StringComparison.OrdinalIgnoreCase))); @@ -165,6 +164,8 @@ namespace Microsoft.Extensions.ProjectModel.MsBuild Assert.NotNull(mvcPackage); Assert.True(mvcPackage.Dependencies.Any(dependency => dependency.Name.Equals("Microsoft.Extensions.DependencyInjection", StringComparison.OrdinalIgnoreCase))); + + Assert.True(context.ProjectReferences.First().Equals(Path.Combine(fileProvider.Root, "Library1", "Library1.csproj"))); } } }