From fb2326bb5096cc26d278c7207e3dfcb735ad899d Mon Sep 17 00:00:00 2001 From: Mihai Codoban Date: Sat, 19 Mar 2016 12:13:14 -0700 Subject: [PATCH 01/27] Reuse lock file when creating a runtime context --- src/Microsoft.DotNet.ProjectModel/ProjectContext.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.DotNet.ProjectModel/ProjectContext.cs b/src/Microsoft.DotNet.ProjectModel/ProjectContext.cs index b920e857c..7fe2e7622 100644 --- a/src/Microsoft.DotNet.ProjectModel/ProjectContext.cs +++ b/src/Microsoft.DotNet.ProjectModel/ProjectContext.cs @@ -151,7 +151,11 @@ namespace Microsoft.DotNet.ProjectModel .Where(t => t.TargetFramework.Equals(TargetFramework)) .Any(t => !string.IsNullOrEmpty(t.RuntimeIdentifier)); - var context = Create(ProjectFile.ProjectFilePath, TargetFramework, standalone ? runtimeIdentifiers : Enumerable.Empty()); + var context = CreateBuilder(ProjectFile.ProjectFilePath, TargetFramework) + .WithRuntimeIdentifiers(standalone ? runtimeIdentifiers : Enumerable.Empty()) + .WithLockFile(LockFile) + .Build(); + if (standalone && context.RuntimeIdentifier == null) { // We are standalone, but don't support this runtime From 552ac6282f7fdca24bc347ba0f6cf6f411daeebe Mon Sep 17 00:00:00 2001 From: Mihai Codoban Date: Tue, 22 Mar 2016 21:00:07 -0700 Subject: [PATCH 02/27] Update lock file format project libraries can have a msbuildProject element --- .../Graph/LockFileProjectLibrary.cs | 2 ++ .../Graph/LockFileReader.cs | 15 +++++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/Microsoft.DotNet.ProjectModel/Graph/LockFileProjectLibrary.cs b/src/Microsoft.DotNet.ProjectModel/Graph/LockFileProjectLibrary.cs index 7a1b9d632..bdc459235 100644 --- a/src/Microsoft.DotNet.ProjectModel/Graph/LockFileProjectLibrary.cs +++ b/src/Microsoft.DotNet.ProjectModel/Graph/LockFileProjectLibrary.cs @@ -12,5 +12,7 @@ namespace Microsoft.DotNet.ProjectModel.Graph public NuGetVersion Version { get; set; } public string Path { get; set; } + + public string MSBuildProject { get; set; } } } \ No newline at end of file diff --git a/src/Microsoft.DotNet.ProjectModel/Graph/LockFileReader.cs b/src/Microsoft.DotNet.ProjectModel/Graph/LockFileReader.cs index cb9d176dd..49b2c1f0f 100644 --- a/src/Microsoft.DotNet.ProjectModel/Graph/LockFileReader.cs +++ b/src/Microsoft.DotNet.ProjectModel/Graph/LockFileReader.cs @@ -105,12 +105,19 @@ namespace Microsoft.DotNet.ProjectModel.Graph } else if (type == "project") { - lockFile.ProjectLibraries.Add(new LockFileProjectLibrary + var projectLibrary = new LockFileProjectLibrary { Name = name, - Version = version, - Path = ReadString(value.Value("path")) - }); + Version = version + }; + + var pathValue = value.Value("path"); + projectLibrary.Path = pathValue == null ? null : ReadString(pathValue); + + var buildTimeDependencyValue = value.Value("msbuildProject"); + projectLibrary.MSBuildProject = buildTimeDependencyValue == null ? null : ReadString(buildTimeDependencyValue); + + lockFile.ProjectLibraries.Add(projectLibrary); } } } From 06ff80392e3af4695e1e3cc6073d9325b031f082 Mon Sep 17 00:00:00 2001 From: Mihai Codoban Date: Tue, 22 Mar 2016 21:00:45 -0700 Subject: [PATCH 03/27] Patch Lock File with export file --- .../Graph/ExportFile.cs | 22 +++ .../Graph/LockFile.cs | 4 +- .../Graph/LockFilePatcher.cs | 140 ++++++++++++++++++ .../Graph/LockFileReader.cs | 57 ++++++- 4 files changed, 212 insertions(+), 11 deletions(-) create mode 100644 src/Microsoft.DotNet.ProjectModel/Graph/ExportFile.cs create mode 100644 src/Microsoft.DotNet.ProjectModel/Graph/LockFilePatcher.cs diff --git a/src/Microsoft.DotNet.ProjectModel/Graph/ExportFile.cs b/src/Microsoft.DotNet.ProjectModel/Graph/ExportFile.cs new file mode 100644 index 000000000..933742559 --- /dev/null +++ b/src/Microsoft.DotNet.ProjectModel/Graph/ExportFile.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; +using System.Linq; + +namespace Microsoft.DotNet.ProjectModel.Graph +{ + public class ExportFile + { + public static readonly string ExportFileName = "project.fragment.lock.json"; + + public int Version { get; } + public string ExportFilePath { get; } + + public IList Exports { get; } + + public ExportFile(string exportFilePath, int version, IList exports) + { + ExportFilePath = exportFilePath; + Version = version; + Exports = exports.Any() ? exports : new List(0); + } + } +} \ No newline at end of file diff --git a/src/Microsoft.DotNet.ProjectModel/Graph/LockFile.cs b/src/Microsoft.DotNet.ProjectModel/Graph/LockFile.cs index 99e41df88..9f9db6459 100644 --- a/src/Microsoft.DotNet.ProjectModel/Graph/LockFile.cs +++ b/src/Microsoft.DotNet.ProjectModel/Graph/LockFile.cs @@ -4,9 +4,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; -using Microsoft.DotNet.ProjectModel.Utilities; -using NuGet.Versioning; namespace Microsoft.DotNet.ProjectModel.Graph { @@ -22,6 +19,7 @@ namespace Microsoft.DotNet.ProjectModel.Graph public IList PackageLibraries { get; set; } = new List(); public IList ProjectLibraries { get; set; } = new List(); public IList Targets { get; set; } = new List(); + public ExportFile ExportFile { get; set; } public LockFile(string lockFilePath) { diff --git a/src/Microsoft.DotNet.ProjectModel/Graph/LockFilePatcher.cs b/src/Microsoft.DotNet.ProjectModel/Graph/LockFilePatcher.cs new file mode 100644 index 000000000..76b1b4f93 --- /dev/null +++ b/src/Microsoft.DotNet.ProjectModel/Graph/LockFilePatcher.cs @@ -0,0 +1,140 @@ +// 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; + +namespace Microsoft.DotNet.ProjectModel.Graph +{ + public class LockFilePatcher + { + private readonly LockFile _lockFile; + private Dictionary> _msbuildTargetLibraries; + + public LockFilePatcher(LockFile lockFile) + { + _lockFile = lockFile; + + var msbuildProjectLibraries = lockFile.ProjectLibraries.Where(IsMSBuildProjectLibrary); + _msbuildTargetLibraries = msbuildProjectLibraries.ToDictionary(GetProjectLibraryKey, l => GetTargetsForLibrary(_lockFile, l)); + } + + public void PatchIfNecessary() + { + var exportFilePath = GetExportFilePath(_lockFile.LockFilePath); + + if (File.Exists(exportFilePath)) + { + var exportFile = LockFileReader.ReadExportFile(exportFilePath); + PatchLockWithExport(exportFile); + } + else + { + ThrowIfAnyMsbuildLibrariesPresent(); + } + } + + public void ThrowIfAnyMsbuildLibrariesPresent() + { + if (_msbuildTargetLibraries.Any()) + { + throw new LockFilePatchingException($"Lock file {_lockFile} contains msbuild projects but there is no export file"); + } + } + + private void PatchLockWithExport(ExportFile exportFile) + { + if (_lockFile.Version != exportFile.Version) + { + throw new LockFilePatchingException($"Export file {exportFile.ExportFilePath} has a different version than the lock file {_lockFile.LockFilePath}"); + } + + var exportDict = exportFile.Exports.ToDictionary(GetTargetLibraryKey); + + var uncoveredLibraries = _msbuildTargetLibraries.Keys.Except(exportDict.Keys); + if (uncoveredLibraries.Any()) + { + throw new LockFilePatchingException($"Export {exportFile.ExportFilePath} does not provide exports for all the msbuild projects in {_lockFile.LockFilePath}"); + } + + foreach(var exportKey in exportDict.Keys) + { + var export = exportDict[exportKey]; + var librariesToPatch = _msbuildTargetLibraries[exportKey]; + + if (export.TargetFramework == null) + { + throw new LockFilePatchingException($"Export library {export.Name} could not be resolved during nuget restore"); + } + + foreach (var libraryToPatch in librariesToPatch) + { + Patch(libraryToPatch, export); + } + } + + _lockFile.ExportFile = exportFile; + } + + private static void Patch(LockFileTargetLibrary libraryToPatch, LockFileTargetLibrary export) + { + libraryToPatch.CompileTimeAssemblies = export.CompileTimeAssemblies; + libraryToPatch.ContentFiles = export.ContentFiles; + libraryToPatch.FrameworkAssemblies = export.FrameworkAssemblies; + libraryToPatch.NativeLibraries = export.NativeLibraries; + libraryToPatch.ResourceAssemblies = export.ResourceAssemblies; + libraryToPatch.RuntimeAssemblies = export.RuntimeAssemblies; + } + + private static bool IsMSBuildProjectLibrary(LockFileProjectLibrary projectLibrary) + { + var hasMSbuildProjectValue = !string.IsNullOrEmpty(projectLibrary.MSBuildProject); + var doesNotHavePathValue = string.IsNullOrEmpty(projectLibrary.Path); + + return doesNotHavePathValue && hasMSbuildProjectValue; + } + + private static IList GetTargetsForLibrary(LockFile lockFile, LockFileProjectLibrary library) + { + return lockFile.Targets + .SelectMany( + t => t.Libraries + .Where( + l => string.Equals(GetProjectLibraryKey(library), (GetTargetLibraryKey(l))) + ) + ) + .ToList(); + } + + private static object TypeName(LockFileTargetLibrary library) + { + return library.Name + "/" + library.Version + "/" + library.Type; + } + + private static string GetTargetLibraryKey(LockFileTargetLibrary library) + { + return library.Name + "/" + library.Version; + } + + private static string GetProjectLibraryKey(LockFileProjectLibrary library) + { + return library.Name + "/" + library.Version; + } + + private static string GetExportFilePath(string masterLockFilePath) + { + var parentDirectory = Directory.GetParent(masterLockFilePath).FullName; + return Path.Combine(parentDirectory, ExportFile.ExportFileName); + } + } + + internal class LockFilePatchingException : Exception + { + public LockFilePatchingException(string message) : base(message) + { + } + } + +} diff --git a/src/Microsoft.DotNet.ProjectModel/Graph/LockFileReader.cs b/src/Microsoft.DotNet.ProjectModel/Graph/LockFileReader.cs index 49b2c1f0f..78dcc08db 100644 --- a/src/Microsoft.DotNet.ProjectModel/Graph/LockFileReader.cs +++ b/src/Microsoft.DotNet.ProjectModel/Graph/LockFileReader.cs @@ -15,13 +15,13 @@ namespace Microsoft.DotNet.ProjectModel.Graph { public static class LockFileReader { - public static LockFile Read(string lockFilePath) + public static LockFile Read(string lockFilePath, bool patchWithExportFile = true) { using (var stream = ResilientFileStreamOpener.OpenFile(lockFilePath)) { try { - return Read(lockFilePath, stream); + return Read(lockFilePath, stream, patchWithExportFile); } catch (FileFormatException ex) { @@ -34,21 +34,32 @@ namespace Microsoft.DotNet.ProjectModel.Graph } } - public static LockFile Read(string lockFilePath, Stream stream) + public static LockFile Read(string lockFilePath, Stream stream, bool patchWithExportFile = true) { try { var reader = new StreamReader(stream); var jobject = JsonDeserializer.Deserialize(reader) as JsonObject; - if (jobject != null) - { - return ReadLockFile(lockFilePath, jobject); - } - else + if (jobject == null) { throw new InvalidDataException(); } + + var lockFile = ReadLockFile(lockFilePath, jobject); + + var patcher = new LockFilePatcher(lockFile); + + if (patchWithExportFile) + { + patcher.PatchIfNecessary(); + } + else + { + patcher.ThrowIfAnyMsbuildLibrariesPresent(); + } + + return lockFile; } catch { @@ -60,6 +71,36 @@ namespace Microsoft.DotNet.ProjectModel.Graph } } + public static ExportFile ReadExportFile(string fragmentLockFilePath) + { + using (var stream = ResilientFileStreamOpener.OpenFile(fragmentLockFilePath)) + { + try + { + var rootJObject = JsonDeserializer.Deserialize(new StreamReader(stream)) as JsonObject; + + if (rootJObject == null) + { + throw new InvalidDataException(); + } + + var version = ReadInt(rootJObject, "version", defaultValue: int.MinValue); + var exports = ReadObject(rootJObject.ValueAsJsonObject("exports"), ReadTargetLibrary); + + return new ExportFile(fragmentLockFilePath, version, exports); + + } + catch (FileFormatException ex) + { + throw ex.WithFilePath(fragmentLockFilePath); + } + catch (Exception ex) + { + throw FileFormatException.Create(ex, fragmentLockFilePath); + } + } + } + private static LockFile ReadLockFile(string lockFilePath, JsonObject cursor) { var lockFile = new LockFile(lockFilePath); From ca2707292e9a255120e807a9256067ce03d44dd6 Mon Sep 17 00:00:00 2001 From: Mihai Codoban Date: Wed, 23 Mar 2016 15:26:36 -0700 Subject: [PATCH 04/27] Add MSBuildProjectDescription --- .../Compilation/LibraryExporter.cs | 60 ++++++------- .../DependencyContextBuilder.cs | 2 +- .../Graph/LibraryType.cs | 2 + .../Graph/LockFilePatcher.cs | 16 +--- .../Graph/LockFileReader.cs | 4 + .../MSBuildProjectDescription.cs | 53 +++++++++++ .../PackageDescription.cs | 48 +++++----- .../ProjectContextBuilder.cs | 22 +++-- .../Resolution/MSBuildDependencyProvider.cs | 88 +++++++++++++++++++ .../TargetLibraryWithAssets.cs | 51 +++++++++++ .../commands/dotnet-build/CompileContext.cs | 5 ++ .../RuntimeGraphManager.cs | 2 +- 12 files changed, 276 insertions(+), 77 deletions(-) create mode 100644 src/Microsoft.DotNet.ProjectModel/MSBuildProjectDescription.cs create mode 100644 src/Microsoft.DotNet.ProjectModel/Resolution/MSBuildDependencyProvider.cs create mode 100644 src/Microsoft.DotNet.ProjectModel/TargetLibraryWithAssets.cs diff --git a/src/Microsoft.DotNet.ProjectModel/Compilation/LibraryExporter.cs b/src/Microsoft.DotNet.ProjectModel/Compilation/LibraryExporter.cs index d83638068..f3c84cf07 100644 --- a/src/Microsoft.DotNet.ProjectModel/Compilation/LibraryExporter.cs +++ b/src/Microsoft.DotNet.ProjectModel/Compilation/LibraryExporter.cs @@ -140,11 +140,12 @@ namespace Microsoft.DotNet.ProjectModel.Compilation return LibraryExportBuilder.Create(library).Build(); } - if (Equals(LibraryType.Package, library.Identity.Type)) + var libraryType = library.Identity.Type; + if (Equals(LibraryType.Package, libraryType) || Equals(LibraryType.MSBuildProject, libraryType)) { - return ExportPackage((PackageDescription)library); + return ExportPackage((TargetLibraryWithAssets)library); } - else if (Equals(LibraryType.Project, library.Identity.Type)) + else if (Equals(LibraryType.Project, libraryType)) { return ExportProject((ProjectDescription)library); } @@ -154,22 +155,22 @@ namespace Microsoft.DotNet.ProjectModel.Compilation } } - private LibraryExport ExportPackage(PackageDescription package) + private LibraryExport ExportPackage(TargetLibraryWithAssets library) { - var builder = LibraryExportBuilder.Create(package); - builder.AddNativeLibraryGroup(new LibraryAssetGroup(PopulateAssets(package, package.NativeLibraries))); - builder.AddRuntimeAssemblyGroup(new LibraryAssetGroup(PopulateAssets(package, package.RuntimeAssemblies))); - builder.WithCompilationAssemblies(PopulateAssets(package, package.CompileTimeAssemblies)); - builder.WithSourceReferences(GetSharedSources(package)); - builder.WithAnalyzerReference(GetAnalyzerReferences(package)); + var builder = LibraryExportBuilder.Create(library); + builder.AddNativeLibraryGroup(new LibraryAssetGroup(PopulateAssets(library, library.NativeLibraries))); + builder.AddRuntimeAssemblyGroup(new LibraryAssetGroup(PopulateAssets(library, library.RuntimeAssemblies))); + builder.WithCompilationAssemblies(PopulateAssets(library, library.CompileTimeAssemblies)); + builder.WithSourceReferences(GetSharedSources(library)); + builder.WithAnalyzerReference(GetAnalyzerReferences(library)); - if (package.ContentFiles.Any()) + if (library.ContentFiles.Any()) { var parameters = PPFileParameters.CreateForProject(_rootProject.Project); Action transform = (input, output) => PPFilePreprocessor.Preprocess(input, output, parameters); var sourceCodeLanguage = _rootProject.Project.GetSourceCodeLanguage(); - var languageGroups = package.ContentFiles.GroupBy(file => file.CodeLanguage); + var languageGroups = library.ContentFiles.GroupBy(file => file.CodeLanguage); var selectedGroup = languageGroups.FirstOrDefault(g => g.Key == sourceCodeLanguage) ?? languageGroups.FirstOrDefault(g => g.Key == null); if (selectedGroup != null) @@ -184,14 +185,14 @@ namespace Microsoft.DotNet.ProjectModel.Compilation var fileTransform = contentFile.PPOutputPath != null ? transform : null; - var fullPath = Path.Combine(package.Path, contentFile.Path); + var fullPath = Path.Combine(library.Path, contentFile.Path); if (contentFile.BuildAction == BuildAction.Compile) { - builder.AddSourceReference(LibraryAsset.CreateFromRelativePath(package.Path, contentFile.Path, fileTransform)); + builder.AddSourceReference(LibraryAsset.CreateFromRelativePath(library.Path, contentFile.Path, fileTransform)); } else if (contentFile.BuildAction == BuildAction.EmbeddedResource) { - builder.AddEmbedddedResource(LibraryAsset.CreateFromRelativePath(package.Path, contentFile.Path, fileTransform)); + builder.AddEmbedddedResource(LibraryAsset.CreateFromRelativePath(library.Path, contentFile.Path, fileTransform)); } if (contentFile.CopyToOutput) { @@ -200,9 +201,9 @@ namespace Microsoft.DotNet.ProjectModel.Compilation } } } - if (package.RuntimeTargets.Any()) + if (library.RuntimeTargets.Any()) { - foreach (var targetGroup in package.RuntimeTargets.GroupBy(t => t.Runtime)) + foreach (var targetGroup in library.RuntimeTargets.GroupBy(t => t.Runtime)) { var runtime = new List(); var native = new List(); @@ -211,11 +212,11 @@ namespace Microsoft.DotNet.ProjectModel.Compilation { if (string.Equals(lockFileRuntimeTarget.AssetType, "native", StringComparison.OrdinalIgnoreCase)) { - native.Add(LibraryAsset.CreateFromRelativePath(package.Path, lockFileRuntimeTarget.Path)); + native.Add(LibraryAsset.CreateFromRelativePath(library.Path, lockFileRuntimeTarget.Path)); } else if (string.Equals(lockFileRuntimeTarget.AssetType, "runtime", StringComparison.OrdinalIgnoreCase)) { - runtime.Add(LibraryAsset.CreateFromRelativePath(package.Path, lockFileRuntimeTarget.Path)); + runtime.Add(LibraryAsset.CreateFromRelativePath(library.Path, lockFileRuntimeTarget.Path)); } } @@ -339,22 +340,14 @@ namespace Microsoft.DotNet.ProjectModel.Compilation return builder.Build(); } - private IEnumerable GetSharedSources(PackageDescription package) + private IEnumerable GetSharedSources(TargetLibraryWithAssets library) { - return package - .Library - .Files - .Where(path => path.StartsWith("shared" + Path.DirectorySeparatorChar)) - .Select(path => LibraryAsset.CreateFromRelativePath(package.Path, path)); + return library.GetSharedSources().Select(path => LibraryAsset.CreateFromRelativePath(library.Path, path)); } - private IEnumerable GetAnalyzerReferences(PackageDescription package) + private IEnumerable GetAnalyzerReferences(TargetLibraryWithAssets package) { - var analyzers = package - .Library - .Files - .Where(path => path.StartsWith("analyzers" + Path.DirectorySeparatorChar) && - path.EndsWith(".dll")); + var analyzers = package.GetAnalyzerReferences(); var analyzerRefs = new List(); // See https://docs.nuget.org/create/analyzers-conventions for the analyzer @@ -416,12 +409,11 @@ namespace Microsoft.DotNet.ProjectModel.Compilation return analyzerRefs; } - - private IEnumerable PopulateAssets(PackageDescription package, IEnumerable section) + private IEnumerable PopulateAssets(TargetLibraryWithAssets library, IEnumerable section) { foreach (var assemblyPath in section) { - yield return LibraryAsset.CreateFromRelativePath(package.Path, assemblyPath.Path); + yield return LibraryAsset.CreateFromRelativePath(library.Path, assemblyPath.Path); } } diff --git a/src/Microsoft.DotNet.ProjectModel/DependencyContextBuilder.cs b/src/Microsoft.DotNet.ProjectModel/DependencyContextBuilder.cs index b5111adbb..21b105ae5 100644 --- a/src/Microsoft.DotNet.ProjectModel/DependencyContextBuilder.cs +++ b/src/Microsoft.DotNet.ProjectModel/DependencyContextBuilder.cs @@ -115,7 +115,7 @@ namespace Microsoft.Extensions.DependencyModel { var type = export.Library.Identity.Type; - var serviceable = (export.Library as PackageDescription)?.Library.IsServiceable ?? false; + var serviceable = (export.Library as PackageDescription)?.PackageLibrary.IsServiceable ?? false; var libraryDependencies = new HashSet(); foreach (var libraryDependency in export.Library.Dependencies) diff --git a/src/Microsoft.DotNet.ProjectModel/Graph/LibraryType.cs b/src/Microsoft.DotNet.ProjectModel/Graph/LibraryType.cs index 1398b0a88..4a18dccbe 100644 --- a/src/Microsoft.DotNet.ProjectModel/Graph/LibraryType.cs +++ b/src/Microsoft.DotNet.ProjectModel/Graph/LibraryType.cs @@ -11,11 +11,13 @@ namespace Microsoft.DotNet.ProjectModel.Graph public static readonly LibraryType Package = new LibraryType(nameof(Package)); public static readonly LibraryType Project = new LibraryType(nameof(Project)); public static readonly LibraryType ReferenceAssembly = new LibraryType(nameof(ReferenceAssembly)); + public static readonly LibraryType MSBuildProject = new LibraryType(nameof(MSBuildProject)); // Default value public static readonly LibraryType Unspecified = new LibraryType(); public string Value { get; } + private LibraryType(string value) { diff --git a/src/Microsoft.DotNet.ProjectModel/Graph/LockFilePatcher.cs b/src/Microsoft.DotNet.ProjectModel/Graph/LockFilePatcher.cs index 76b1b4f93..cecc63974 100644 --- a/src/Microsoft.DotNet.ProjectModel/Graph/LockFilePatcher.cs +++ b/src/Microsoft.DotNet.ProjectModel/Graph/LockFilePatcher.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; +using Microsoft.DotNet.ProjectModel.Resolution; namespace Microsoft.DotNet.ProjectModel.Graph { @@ -17,7 +18,7 @@ namespace Microsoft.DotNet.ProjectModel.Graph { _lockFile = lockFile; - var msbuildProjectLibraries = lockFile.ProjectLibraries.Where(IsMSBuildProjectLibrary); + var msbuildProjectLibraries = lockFile.ProjectLibraries.Where(MSBuildDependencyProvider.IsMSBuildProjectLibrary); _msbuildTargetLibraries = msbuildProjectLibraries.ToDictionary(GetProjectLibraryKey, l => GetTargetsForLibrary(_lockFile, l)); } @@ -64,11 +65,6 @@ namespace Microsoft.DotNet.ProjectModel.Graph var export = exportDict[exportKey]; var librariesToPatch = _msbuildTargetLibraries[exportKey]; - if (export.TargetFramework == null) - { - throw new LockFilePatchingException($"Export library {export.Name} could not be resolved during nuget restore"); - } - foreach (var libraryToPatch in librariesToPatch) { Patch(libraryToPatch, export); @@ -88,13 +84,7 @@ namespace Microsoft.DotNet.ProjectModel.Graph libraryToPatch.RuntimeAssemblies = export.RuntimeAssemblies; } - private static bool IsMSBuildProjectLibrary(LockFileProjectLibrary projectLibrary) - { - var hasMSbuildProjectValue = !string.IsNullOrEmpty(projectLibrary.MSBuildProject); - var doesNotHavePathValue = string.IsNullOrEmpty(projectLibrary.Path); - - return doesNotHavePathValue && hasMSbuildProjectValue; - } + private static IList GetTargetsForLibrary(LockFile lockFile, LockFileProjectLibrary library) { diff --git a/src/Microsoft.DotNet.ProjectModel/Graph/LockFileReader.cs b/src/Microsoft.DotNet.ProjectModel/Graph/LockFileReader.cs index 78dcc08db..b3306e500 100644 --- a/src/Microsoft.DotNet.ProjectModel/Graph/LockFileReader.cs +++ b/src/Microsoft.DotNet.ProjectModel/Graph/LockFileReader.cs @@ -61,6 +61,10 @@ namespace Microsoft.DotNet.ProjectModel.Graph return lockFile; } + catch (LockFilePatchingException exception) + { + throw; + } catch { // Ran into parsing errors, mark it as unlocked and out-of-date diff --git a/src/Microsoft.DotNet.ProjectModel/MSBuildProjectDescription.cs b/src/Microsoft.DotNet.ProjectModel/MSBuildProjectDescription.cs new file mode 100644 index 000000000..a87041620 --- /dev/null +++ b/src/Microsoft.DotNet.ProjectModel/MSBuildProjectDescription.cs @@ -0,0 +1,53 @@ +// 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.Graph; + +namespace Microsoft.DotNet.ProjectModel +{ + /// + /// Represents an MSBuild project. + /// It has been invisibly built by MSBuild, so it behaves like a package: can provide all assets up front + /// + public class MSBuildProjectDescription : TargetLibraryWithAssets + { + public MSBuildProjectDescription( + string path, + LockFileProjectLibrary projectLibrary, + LockFileTargetLibrary lockFileLibrary, + Project projectFile, + IEnumerable dependencies, + bool compatible, + bool resolved) + : base( + new LibraryIdentity(projectLibrary.Name, projectLibrary.Version, LibraryType.MSBuildProject), + string.Empty, //msbuild projects don't have hashes + path, + lockFileLibrary, + dependencies, + resolved: resolved, + compatible: compatible, + framework: null) + { + ProjectFile = projectFile; + ProjectLibrary = projectLibrary; + } + + public LockFileProjectLibrary ProjectLibrary { get; } + + public Project ProjectFile { get; } + + public override IEnumerable GetSharedSources() + { + return Enumerable.Empty(); + } + + public override IEnumerable GetAnalyzerReferences() + { + return Enumerable.Empty(); + } + } +} diff --git a/src/Microsoft.DotNet.ProjectModel/PackageDescription.cs b/src/Microsoft.DotNet.ProjectModel/PackageDescription.cs index ab050b72b..bc539e877 100644 --- a/src/Microsoft.DotNet.ProjectModel/PackageDescription.cs +++ b/src/Microsoft.DotNet.ProjectModel/PackageDescription.cs @@ -1,15 +1,16 @@ // 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; using System.Collections.Generic; using System.Linq; using Microsoft.DotNet.ProjectModel.Graph; using Microsoft.DotNet.ProjectModel.Resolution; +using System; namespace Microsoft.DotNet.ProjectModel { - public class PackageDescription : LibraryDescription + public class PackageDescription : TargetLibraryWithAssets { public PackageDescription( string path, @@ -22,34 +23,39 @@ namespace Microsoft.DotNet.ProjectModel new LibraryIdentity(package.Name, package.Version, LibraryType.Package), "sha512-" + package.Sha512, path, - dependencies: dependencies, - framework: null, + lockFileLibrary, + dependencies, resolved: resolved, - compatible: compatible) + compatible: compatible, + framework: null) { - Library = package; - Target = lockFileLibrary; + PackageLibrary = package; } - private LockFileTargetLibrary Target { get; } + public LockFilePackageLibrary PackageLibrary { get; } - public LockFilePackageLibrary Library { get; } + public override IEnumerable RuntimeAssemblies => FilterPlaceholders(base.RuntimeAssemblies); - public IEnumerable RuntimeAssemblies => FilterPlaceholders(Target.RuntimeAssemblies); + public override IEnumerable CompileTimeAssemblies => FilterPlaceholders(base.CompileTimeAssemblies); - public IEnumerable CompileTimeAssemblies => FilterPlaceholders(Target.CompileTimeAssemblies); - - public IEnumerable ResourceAssemblies => Target.ResourceAssemblies; - - public IEnumerable NativeLibraries => Target.NativeLibraries; - - public IEnumerable ContentFiles => Target.ContentFiles; - - public IEnumerable RuntimeTargets => Target.RuntimeTargets; - - private IEnumerable FilterPlaceholders(IList items) + private static IEnumerable FilterPlaceholders(IEnumerable items) { return items.Where(a => !PackageDependencyProvider.IsPlaceholderFile(a)); } + + public override IEnumerable GetSharedSources() + { + return PackageLibrary + .Files + .Where(path => path.StartsWith("shared" + System.IO.Path.DirectorySeparatorChar)); + } + + public override IEnumerable GetAnalyzerReferences() + { + return PackageLibrary + .Files + .Where(path => path.StartsWith("analyzers" + System.IO.Path.DirectorySeparatorChar) && + path.EndsWith(".dll")); + } } } diff --git a/src/Microsoft.DotNet.ProjectModel/ProjectContextBuilder.cs b/src/Microsoft.DotNet.ProjectModel/ProjectContextBuilder.cs index 6e2d6b58f..ab5400914 100644 --- a/src/Microsoft.DotNet.ProjectModel/ProjectContextBuilder.cs +++ b/src/Microsoft.DotNet.ProjectModel/ProjectContextBuilder.cs @@ -192,8 +192,9 @@ namespace Microsoft.DotNet.ProjectModel target = SelectTarget(LockFile); if (target != null) { - var packageResolver = new PackageDependencyProvider(PackagesDirectory, frameworkReferenceResolver); - ScanLibraries(target, lockFileLookup, libraries, packageResolver, projectResolver); + var nugetPackageResolver = new PackageDependencyProvider(PackagesDirectory, frameworkReferenceResolver); + var msbuildProjectResolver = new MSBuildDependencyProvider(ProjectResolver); + ScanLibraries(target, lockFileLookup, libraries, msbuildProjectResolver, nugetPackageResolver, projectResolver); } } @@ -342,7 +343,7 @@ namespace Microsoft.DotNet.ProjectModel } } - private void ScanLibraries(LockFileTarget target, LockFileLookup lockFileLookup, Dictionary libraries, PackageDependencyProvider packageResolver, ProjectDependencyProvider projectDependencyProvider) + private void ScanLibraries(LockFileTarget target, LockFileLookup lockFileLookup, Dictionary libraries, MSBuildDependencyProvider msbuildResolver, PackageDependencyProvider packageResolver, ProjectDependencyProvider projectResolver) { foreach (var library in target.Libraries) { @@ -355,11 +356,18 @@ namespace Microsoft.DotNet.ProjectModel if (projectLibrary != null) { - var path = Path.GetFullPath(Path.Combine(ProjectDirectory, projectLibrary.Path)); - description = projectDependencyProvider.GetDescription(library.Name, path, library, ProjectResolver); + if (MSBuildDependencyProvider.IsMSBuildProjectLibrary(projectLibrary)) + { + description = msbuildResolver.GetDescription(TargetFramework, projectLibrary, library); + type = LibraryType.MSBuildProject; + } + else + { + var path = Path.GetFullPath(Path.Combine(ProjectDirectory, projectLibrary.Path)); + description = projectResolver.GetDescription(library.Name, path, library, ProjectResolver); + type = LibraryType.Project; + } } - - type = LibraryType.Project; } else { diff --git a/src/Microsoft.DotNet.ProjectModel/Resolution/MSBuildDependencyProvider.cs b/src/Microsoft.DotNet.ProjectModel/Resolution/MSBuildDependencyProvider.cs new file mode 100644 index 000000000..33949c3ca --- /dev/null +++ b/src/Microsoft.DotNet.ProjectModel/Resolution/MSBuildDependencyProvider.cs @@ -0,0 +1,88 @@ +// 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.Graph; +using NuGet.Frameworks; + +namespace Microsoft.DotNet.ProjectModel.Resolution +{ + public class MSBuildDependencyProvider + { + private readonly Func _projectResolver; + + public MSBuildDependencyProvider(Func projectResolver) + { + _projectResolver = projectResolver; + } + + public MSBuildProjectDescription GetDescription(NuGetFramework targetFramework, LockFileProjectLibrary projectLibrary, LockFileTargetLibrary targetLibrary) + { + var compatible = targetLibrary.FrameworkAssemblies.Any() || + targetLibrary.CompileTimeAssemblies.Any() || + targetLibrary.RuntimeAssemblies.Any(); + + var dependencies = new List(targetLibrary.Dependencies.Count + targetLibrary.FrameworkAssemblies.Count); + PopulateDependencies(dependencies, targetLibrary, targetFramework); + + var path = Path.GetDirectoryName(Path.GetFullPath(projectLibrary.MSBuildProject)); + var exists = Directory.Exists(path); + + var projectFile = projectLibrary.Path == null ? null : _projectResolver(projectLibrary.Path); + + var msbuildPackageDescription = new MSBuildProjectDescription( + path, + projectLibrary, + targetLibrary, + projectFile, + dependencies, + compatible, + resolved: compatible && exists); + + return msbuildPackageDescription; + } + + private void PopulateDependencies( + List dependencies, + LockFileTargetLibrary targetLibrary, + NuGetFramework targetFramework) + { + foreach (var dependency in targetLibrary.Dependencies) + { + dependencies.Add(new LibraryRange( + dependency.Id, + dependency.VersionRange, + LibraryType.Unspecified, + LibraryDependencyType.Default)); + } + + if (!targetFramework.IsPackageBased) + { + // Only add framework assemblies for non-package based frameworks. + foreach (var frameworkAssembly in targetLibrary.FrameworkAssemblies) + { + dependencies.Add(new LibraryRange( + frameworkAssembly, + LibraryType.ReferenceAssembly, + LibraryDependencyType.Default)); + } + } + } + + public static bool IsMSBuildProjectLibrary(LockFileProjectLibrary projectLibrary) + { + var msbuildProjectPath = projectLibrary.MSBuildProject; + if (msbuildProjectPath == null) + { + return false; + } + + var extension = Path.GetExtension(msbuildProjectPath); + + return !string.Equals(extension, ".xproj", StringComparison.OrdinalIgnoreCase); + } + } +} diff --git a/src/Microsoft.DotNet.ProjectModel/TargetLibraryWithAssets.cs b/src/Microsoft.DotNet.ProjectModel/TargetLibraryWithAssets.cs new file mode 100644 index 000000000..5fd7babc5 --- /dev/null +++ b/src/Microsoft.DotNet.ProjectModel/TargetLibraryWithAssets.cs @@ -0,0 +1,51 @@ +// 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.Collections.Generic; +using Microsoft.DotNet.ProjectModel.Graph; +using NuGet.Frameworks; + +namespace Microsoft.DotNet.ProjectModel +{ + public abstract class TargetLibraryWithAssets : LibraryDescription + { + public TargetLibraryWithAssets( + LibraryIdentity libraryIdentity, + string sha512, + string path, + LockFileTargetLibrary lockFileLibrary, + IEnumerable dependencies, + bool compatible, + bool resolved, + NuGetFramework framework = null) + : base( + libraryIdentity, + sha512, + path, + dependencies: dependencies, + framework: null, + resolved: resolved, + compatible: compatible) + { + TargetLibrary = lockFileLibrary; + } + + private LockFileTargetLibrary TargetLibrary { get; } + + public virtual IEnumerable RuntimeAssemblies => TargetLibrary.RuntimeAssemblies; + + public virtual IEnumerable CompileTimeAssemblies => TargetLibrary.CompileTimeAssemblies; + + public virtual IEnumerable ResourceAssemblies => TargetLibrary.ResourceAssemblies; + + public virtual IEnumerable NativeLibraries => TargetLibrary.NativeLibraries; + + public virtual IEnumerable ContentFiles => TargetLibrary.ContentFiles; + + public virtual IEnumerable RuntimeTargets => TargetLibrary.RuntimeTargets; + + public abstract IEnumerable GetSharedSources(); + + public abstract IEnumerable GetAnalyzerReferences(); + } +} diff --git a/src/dotnet/commands/dotnet-build/CompileContext.cs b/src/dotnet/commands/dotnet-build/CompileContext.cs index db5b0429a..15c1e5dec 100644 --- a/src/dotnet/commands/dotnet-build/CompileContext.cs +++ b/src/dotnet/commands/dotnet-build/CompileContext.cs @@ -603,6 +603,11 @@ namespace Microsoft.DotNet.Tools.Build } compilerIO.Inputs.Add(project.LockFile.LockFilePath); + + if (project.LockFile.ExportFile != null) + { + compilerIO.Inputs.Add(project.LockFile.ExportFile.ExportFilePath); + } } private static void AddDependencies(ProjectDependenciesFacade dependencies, CompilerIO compilerIO) diff --git a/tools/RuntimeGraphGenerator/RuntimeGraphManager.cs b/tools/RuntimeGraphGenerator/RuntimeGraphManager.cs index f1c0629c1..81d9da1c1 100644 --- a/tools/RuntimeGraphGenerator/RuntimeGraphManager.cs +++ b/tools/RuntimeGraphGenerator/RuntimeGraphManager.cs @@ -21,7 +21,7 @@ namespace Microsoft.DotNet.ProjectModel { if (export.Library.Identity.Type == LibraryType.Package) { - var runtimeJson = ((PackageDescription) export.Library).Library.Files.FirstOrDefault(f => f == RuntimeJsonFileName); + var runtimeJson = ((PackageDescription) export.Library).PackageLibrary.Files.FirstOrDefault(f => f == RuntimeJsonFileName); if (runtimeJson != null) { var runtimeJsonFullName = Path.Combine(export.Library.Path, runtimeJson); From 90240a431bb058ff08279bf0e00d38b059560913 Mon Sep 17 00:00:00 2001 From: Mihai Codoban Date: Fri, 25 Mar 2016 16:14:57 -0700 Subject: [PATCH 05/27] Compute msbuild project path relative to root project path --- .../ProjectContextBuilder.cs | 2 +- .../Resolution/MSBuildDependencyProvider.cs | 24 +++++++++++++++---- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/Microsoft.DotNet.ProjectModel/ProjectContextBuilder.cs b/src/Microsoft.DotNet.ProjectModel/ProjectContextBuilder.cs index ab5400914..aeb423a46 100644 --- a/src/Microsoft.DotNet.ProjectModel/ProjectContextBuilder.cs +++ b/src/Microsoft.DotNet.ProjectModel/ProjectContextBuilder.cs @@ -193,7 +193,7 @@ namespace Microsoft.DotNet.ProjectModel if (target != null) { var nugetPackageResolver = new PackageDependencyProvider(PackagesDirectory, frameworkReferenceResolver); - var msbuildProjectResolver = new MSBuildDependencyProvider(ProjectResolver); + var msbuildProjectResolver = new MSBuildDependencyProvider(Project ,ProjectResolver); ScanLibraries(target, lockFileLookup, libraries, msbuildProjectResolver, nugetPackageResolver, projectResolver); } } diff --git a/src/Microsoft.DotNet.ProjectModel/Resolution/MSBuildDependencyProvider.cs b/src/Microsoft.DotNet.ProjectModel/Resolution/MSBuildDependencyProvider.cs index 33949c3ca..e67e1c313 100644 --- a/src/Microsoft.DotNet.ProjectModel/Resolution/MSBuildDependencyProvider.cs +++ b/src/Microsoft.DotNet.ProjectModel/Resolution/MSBuildDependencyProvider.cs @@ -12,10 +12,12 @@ namespace Microsoft.DotNet.ProjectModel.Resolution { public class MSBuildDependencyProvider { + private readonly Project _rootProject; private readonly Func _projectResolver; - public MSBuildDependencyProvider(Func projectResolver) + public MSBuildDependencyProvider(Project rootProject, Func projectResolver) { + _rootProject = rootProject; _projectResolver = projectResolver; } @@ -28,13 +30,13 @@ namespace Microsoft.DotNet.ProjectModel.Resolution var dependencies = new List(targetLibrary.Dependencies.Count + targetLibrary.FrameworkAssemblies.Count); PopulateDependencies(dependencies, targetLibrary, targetFramework); - var path = Path.GetDirectoryName(Path.GetFullPath(projectLibrary.MSBuildProject)); - var exists = Directory.Exists(path); + var msbuildProjectPath = GetMSbuildProjectPath(projectLibrary); + var exists = Directory.Exists(msbuildProjectPath); var projectFile = projectLibrary.Path == null ? null : _projectResolver(projectLibrary.Path); var msbuildPackageDescription = new MSBuildProjectDescription( - path, + msbuildProjectPath, projectLibrary, targetLibrary, projectFile, @@ -45,6 +47,20 @@ namespace Microsoft.DotNet.ProjectModel.Resolution return msbuildPackageDescription; } + private string GetMSbuildProjectPath(LockFileProjectLibrary projectLibrary) + { + if (_rootProject == null) + { + throw new InvalidOperationException("Root xproj project does not exist. Cannot compute the path of its referenced csproj projects."); + } + + var rootProjectPath = Path.GetDirectoryName(_rootProject.ProjectFilePath); + var msbuildProjectFilePath = Path.Combine(rootProjectPath, projectLibrary.MSBuildProject); + var msbuildProjectPath = Path.GetDirectoryName(Path.GetFullPath(msbuildProjectFilePath)); + + return msbuildProjectPath; + } + private void PopulateDependencies( List dependencies, LockFileTargetLibrary targetLibrary, From b2aae7546a3808730c7c9b74f761e8b38a9c3132 Mon Sep 17 00:00:00 2001 From: Mihai Codoban Date: Thu, 24 Mar 2016 21:52:46 -0700 Subject: [PATCH 06/27] Add lock file patching tests --- .../project.fragment.lock.json | 25 +++++ .../invalid_missing-exports/project.json | 22 ++++ .../invalid_missing-exports/project.lock.json | 61 +++++++++++ .../project.fragment.lock.json | 35 ++++++ .../project.json | 22 ++++ .../project.lock.json | 61 +++++++++++ .../invalid_nofragment/project.json | 22 ++++ .../invalid_nofragment/project.lock.json | 61 +++++++++++ .../valid/project.fragment.lock.json | 35 ++++++ .../ExportFileSamples/valid/project.json | 22 ++++ .../ExportFileSamples/valid/project.lock.json | 61 +++++++++++ .../Graph/LockFilePatcher.cs | 2 - .../Graph/LockFileReader.cs | 2 +- .../LockFilePatchingTests.cs | 101 ++++++++++++++++++ 14 files changed, 529 insertions(+), 3 deletions(-) create mode 100644 TestAssets/LockFileSamples/ExportFileSamples/invalid_missing-exports/project.fragment.lock.json create mode 100644 TestAssets/LockFileSamples/ExportFileSamples/invalid_missing-exports/project.json create mode 100644 TestAssets/LockFileSamples/ExportFileSamples/invalid_missing-exports/project.lock.json create mode 100644 TestAssets/LockFileSamples/ExportFileSamples/invalid_missmatching-versions/project.fragment.lock.json create mode 100644 TestAssets/LockFileSamples/ExportFileSamples/invalid_missmatching-versions/project.json create mode 100644 TestAssets/LockFileSamples/ExportFileSamples/invalid_missmatching-versions/project.lock.json create mode 100644 TestAssets/LockFileSamples/ExportFileSamples/invalid_nofragment/project.json create mode 100644 TestAssets/LockFileSamples/ExportFileSamples/invalid_nofragment/project.lock.json create mode 100644 TestAssets/LockFileSamples/ExportFileSamples/valid/project.fragment.lock.json create mode 100644 TestAssets/LockFileSamples/ExportFileSamples/valid/project.json create mode 100644 TestAssets/LockFileSamples/ExportFileSamples/valid/project.lock.json create mode 100644 test/Microsoft.DotNet.ProjectModel.Tests/LockFilePatchingTests.cs diff --git a/TestAssets/LockFileSamples/ExportFileSamples/invalid_missing-exports/project.fragment.lock.json b/TestAssets/LockFileSamples/ExportFileSamples/invalid_missing-exports/project.fragment.lock.json new file mode 100644 index 000000000..d803c7d2c --- /dev/null +++ b/TestAssets/LockFileSamples/ExportFileSamples/invalid_missing-exports/project.fragment.lock.json @@ -0,0 +1,25 @@ +{ + "version": 2, + "exports": { + "ClassLibrary2/1.0.0": { + "type": "project", + "framework": ".NETFramework,Version=v4.6", + "compile": { + "bin/Debug/ClassLibrary2.dll": {} + }, + "runtime": { + "bin/Debug/ClassLibrary2.dll": {} + } + }, + "ClassLibrary3/1.0.0": { + "type": "project", + "framework": ".NETFramework,Version=v4.6", + "compile": { + "bin/Debug/ClassLibrary3.dll": {} + }, + "runtime": { + "bin/Debug/ClassLibrary3.dll": {} + } + } + } +} \ No newline at end of file diff --git a/TestAssets/LockFileSamples/ExportFileSamples/invalid_missing-exports/project.json b/TestAssets/LockFileSamples/ExportFileSamples/invalid_missing-exports/project.json new file mode 100644 index 000000000..1323d5f29 --- /dev/null +++ b/TestAssets/LockFileSamples/ExportFileSamples/invalid_missing-exports/project.json @@ -0,0 +1,22 @@ +{ + "version": "1.0.0-*", + "compilationOptions": { + "emitEntryPoint": true + }, + + "frameworks": { + "net46": { + "dependencies": { + "ClassLibrary1": { + "target": "project" + }, + "ClassLibrary2": { + "target": "project" + }, + "ClassLibrary3": { + "target": "project" + } + } + } + } +} diff --git a/TestAssets/LockFileSamples/ExportFileSamples/invalid_missing-exports/project.lock.json b/TestAssets/LockFileSamples/ExportFileSamples/invalid_missing-exports/project.lock.json new file mode 100644 index 000000000..244c3771b --- /dev/null +++ b/TestAssets/LockFileSamples/ExportFileSamples/invalid_missing-exports/project.lock.json @@ -0,0 +1,61 @@ +{ + "locked": false, + "version": 2, + "targets": { + ".NETFramework,Version=v4.6": { + "ClassLibrary1/1.0.0": { + "type": "project" + }, + "ClassLibrary2/1.0.0": { + "type": "project" + }, + "ClassLibrary3/1.0.0": { + "type": "project" + } + }, + ".NETFramework,Version=v4.6/win7-x64": { + "ClassLibrary1/1.0.0": { + "type": "project" + }, + "ClassLibrary2/1.0.0": { + "type": "project" + }, + "ClassLibrary3/1.0.0": { + "type": "project" + } + }, + ".NETFramework,Version=v4.6/win7-x86": { + "ClassLibrary1/1.0.0": { + "type": "project" + }, + "ClassLibrary2/1.0.0": { + "type": "project" + }, + "ClassLibrary3/1.0.0": { + "type": "project" + } + } + }, + "libraries": { + "ClassLibrary1/1.0.0": { + "type": "project", + "msbuildProject": "../../ClassLibrary1/ClassLibrary1.csproj" + }, + "ClassLibrary2/1.0.0": { + "type": "project", + "msbuildProject": "../../ClassLibrary2/ClassLibrary2.csproj" + }, + "ClassLibrary3/1.0.0": { + "type": "project", + "msbuildProject": "../../ClassLibrary3/ClassLibrary3.csproj" + } + }, + "projectFileDependencyGroups": { + "": [], + ".NETFramework,Version=v4.6": [ + "ClassLibrary1", + "ClassLibrary2", + "ClassLibrary3" + ] + } +} \ No newline at end of file diff --git a/TestAssets/LockFileSamples/ExportFileSamples/invalid_missmatching-versions/project.fragment.lock.json b/TestAssets/LockFileSamples/ExportFileSamples/invalid_missmatching-versions/project.fragment.lock.json new file mode 100644 index 000000000..7b6738e49 --- /dev/null +++ b/TestAssets/LockFileSamples/ExportFileSamples/invalid_missmatching-versions/project.fragment.lock.json @@ -0,0 +1,35 @@ +{ + "version": 3, + "exports": { + "ClassLibrary1/1.0.0": { + "type": "project", + "framework": ".NETFramework,Version=v4.5.2", + "compile": { + "bin/Debug/ClassLibrary1.dll": {} + }, + "runtime": { + "bin/Debug/ClassLibrary1.dll": {} + } + }, + "ClassLibrary2/1.0.0": { + "type": "project", + "framework": ".NETFramework,Version=v4.6", + "compile": { + "bin/Debug/ClassLibrary2.dll": {} + }, + "runtime": { + "bin/Debug/ClassLibrary2.dll": {} + } + }, + "ClassLibrary3/1.0.0": { + "type": "project", + "framework": ".NETFramework,Version=v4.6", + "compile": { + "bin/Debug/ClassLibrary3.dll": {} + }, + "runtime": { + "bin/Debug/ClassLibrary3.dll": {} + } + } + } +} \ No newline at end of file diff --git a/TestAssets/LockFileSamples/ExportFileSamples/invalid_missmatching-versions/project.json b/TestAssets/LockFileSamples/ExportFileSamples/invalid_missmatching-versions/project.json new file mode 100644 index 000000000..1323d5f29 --- /dev/null +++ b/TestAssets/LockFileSamples/ExportFileSamples/invalid_missmatching-versions/project.json @@ -0,0 +1,22 @@ +{ + "version": "1.0.0-*", + "compilationOptions": { + "emitEntryPoint": true + }, + + "frameworks": { + "net46": { + "dependencies": { + "ClassLibrary1": { + "target": "project" + }, + "ClassLibrary2": { + "target": "project" + }, + "ClassLibrary3": { + "target": "project" + } + } + } + } +} diff --git a/TestAssets/LockFileSamples/ExportFileSamples/invalid_missmatching-versions/project.lock.json b/TestAssets/LockFileSamples/ExportFileSamples/invalid_missmatching-versions/project.lock.json new file mode 100644 index 000000000..244c3771b --- /dev/null +++ b/TestAssets/LockFileSamples/ExportFileSamples/invalid_missmatching-versions/project.lock.json @@ -0,0 +1,61 @@ +{ + "locked": false, + "version": 2, + "targets": { + ".NETFramework,Version=v4.6": { + "ClassLibrary1/1.0.0": { + "type": "project" + }, + "ClassLibrary2/1.0.0": { + "type": "project" + }, + "ClassLibrary3/1.0.0": { + "type": "project" + } + }, + ".NETFramework,Version=v4.6/win7-x64": { + "ClassLibrary1/1.0.0": { + "type": "project" + }, + "ClassLibrary2/1.0.0": { + "type": "project" + }, + "ClassLibrary3/1.0.0": { + "type": "project" + } + }, + ".NETFramework,Version=v4.6/win7-x86": { + "ClassLibrary1/1.0.0": { + "type": "project" + }, + "ClassLibrary2/1.0.0": { + "type": "project" + }, + "ClassLibrary3/1.0.0": { + "type": "project" + } + } + }, + "libraries": { + "ClassLibrary1/1.0.0": { + "type": "project", + "msbuildProject": "../../ClassLibrary1/ClassLibrary1.csproj" + }, + "ClassLibrary2/1.0.0": { + "type": "project", + "msbuildProject": "../../ClassLibrary2/ClassLibrary2.csproj" + }, + "ClassLibrary3/1.0.0": { + "type": "project", + "msbuildProject": "../../ClassLibrary3/ClassLibrary3.csproj" + } + }, + "projectFileDependencyGroups": { + "": [], + ".NETFramework,Version=v4.6": [ + "ClassLibrary1", + "ClassLibrary2", + "ClassLibrary3" + ] + } +} \ No newline at end of file diff --git a/TestAssets/LockFileSamples/ExportFileSamples/invalid_nofragment/project.json b/TestAssets/LockFileSamples/ExportFileSamples/invalid_nofragment/project.json new file mode 100644 index 000000000..1323d5f29 --- /dev/null +++ b/TestAssets/LockFileSamples/ExportFileSamples/invalid_nofragment/project.json @@ -0,0 +1,22 @@ +{ + "version": "1.0.0-*", + "compilationOptions": { + "emitEntryPoint": true + }, + + "frameworks": { + "net46": { + "dependencies": { + "ClassLibrary1": { + "target": "project" + }, + "ClassLibrary2": { + "target": "project" + }, + "ClassLibrary3": { + "target": "project" + } + } + } + } +} diff --git a/TestAssets/LockFileSamples/ExportFileSamples/invalid_nofragment/project.lock.json b/TestAssets/LockFileSamples/ExportFileSamples/invalid_nofragment/project.lock.json new file mode 100644 index 000000000..244c3771b --- /dev/null +++ b/TestAssets/LockFileSamples/ExportFileSamples/invalid_nofragment/project.lock.json @@ -0,0 +1,61 @@ +{ + "locked": false, + "version": 2, + "targets": { + ".NETFramework,Version=v4.6": { + "ClassLibrary1/1.0.0": { + "type": "project" + }, + "ClassLibrary2/1.0.0": { + "type": "project" + }, + "ClassLibrary3/1.0.0": { + "type": "project" + } + }, + ".NETFramework,Version=v4.6/win7-x64": { + "ClassLibrary1/1.0.0": { + "type": "project" + }, + "ClassLibrary2/1.0.0": { + "type": "project" + }, + "ClassLibrary3/1.0.0": { + "type": "project" + } + }, + ".NETFramework,Version=v4.6/win7-x86": { + "ClassLibrary1/1.0.0": { + "type": "project" + }, + "ClassLibrary2/1.0.0": { + "type": "project" + }, + "ClassLibrary3/1.0.0": { + "type": "project" + } + } + }, + "libraries": { + "ClassLibrary1/1.0.0": { + "type": "project", + "msbuildProject": "../../ClassLibrary1/ClassLibrary1.csproj" + }, + "ClassLibrary2/1.0.0": { + "type": "project", + "msbuildProject": "../../ClassLibrary2/ClassLibrary2.csproj" + }, + "ClassLibrary3/1.0.0": { + "type": "project", + "msbuildProject": "../../ClassLibrary3/ClassLibrary3.csproj" + } + }, + "projectFileDependencyGroups": { + "": [], + ".NETFramework,Version=v4.6": [ + "ClassLibrary1", + "ClassLibrary2", + "ClassLibrary3" + ] + } +} \ No newline at end of file diff --git a/TestAssets/LockFileSamples/ExportFileSamples/valid/project.fragment.lock.json b/TestAssets/LockFileSamples/ExportFileSamples/valid/project.fragment.lock.json new file mode 100644 index 000000000..415fc75d8 --- /dev/null +++ b/TestAssets/LockFileSamples/ExportFileSamples/valid/project.fragment.lock.json @@ -0,0 +1,35 @@ +{ + "version": 2, + "exports": { + "ClassLibrary1/1.0.0": { + "type": "project", + "framework": ".NETFramework,Version=v4.5.2", + "compile": { + "bin/Debug/ClassLibrary1.dll": {} + }, + "runtime": { + "bin/Debug/ClassLibrary1.dll": {} + } + }, + "ClassLibrary2/1.0.0": { + "type": "project", + "framework": ".NETFramework,Version=v4.6", + "compile": { + "bin/Debug/ClassLibrary2.dll": {} + }, + "runtime": { + "bin/Debug/ClassLibrary2.dll": {} + } + }, + "ClassLibrary3/1.0.0": { + "type": "project", + "framework": ".NETFramework,Version=v4.6", + "compile": { + "bin/Debug/ClassLibrary3.dll": {} + }, + "runtime": { + "bin/Debug/ClassLibrary3.dll": {} + } + } + } +} \ No newline at end of file diff --git a/TestAssets/LockFileSamples/ExportFileSamples/valid/project.json b/TestAssets/LockFileSamples/ExportFileSamples/valid/project.json new file mode 100644 index 000000000..1323d5f29 --- /dev/null +++ b/TestAssets/LockFileSamples/ExportFileSamples/valid/project.json @@ -0,0 +1,22 @@ +{ + "version": "1.0.0-*", + "compilationOptions": { + "emitEntryPoint": true + }, + + "frameworks": { + "net46": { + "dependencies": { + "ClassLibrary1": { + "target": "project" + }, + "ClassLibrary2": { + "target": "project" + }, + "ClassLibrary3": { + "target": "project" + } + } + } + } +} diff --git a/TestAssets/LockFileSamples/ExportFileSamples/valid/project.lock.json b/TestAssets/LockFileSamples/ExportFileSamples/valid/project.lock.json new file mode 100644 index 000000000..244c3771b --- /dev/null +++ b/TestAssets/LockFileSamples/ExportFileSamples/valid/project.lock.json @@ -0,0 +1,61 @@ +{ + "locked": false, + "version": 2, + "targets": { + ".NETFramework,Version=v4.6": { + "ClassLibrary1/1.0.0": { + "type": "project" + }, + "ClassLibrary2/1.0.0": { + "type": "project" + }, + "ClassLibrary3/1.0.0": { + "type": "project" + } + }, + ".NETFramework,Version=v4.6/win7-x64": { + "ClassLibrary1/1.0.0": { + "type": "project" + }, + "ClassLibrary2/1.0.0": { + "type": "project" + }, + "ClassLibrary3/1.0.0": { + "type": "project" + } + }, + ".NETFramework,Version=v4.6/win7-x86": { + "ClassLibrary1/1.0.0": { + "type": "project" + }, + "ClassLibrary2/1.0.0": { + "type": "project" + }, + "ClassLibrary3/1.0.0": { + "type": "project" + } + } + }, + "libraries": { + "ClassLibrary1/1.0.0": { + "type": "project", + "msbuildProject": "../../ClassLibrary1/ClassLibrary1.csproj" + }, + "ClassLibrary2/1.0.0": { + "type": "project", + "msbuildProject": "../../ClassLibrary2/ClassLibrary2.csproj" + }, + "ClassLibrary3/1.0.0": { + "type": "project", + "msbuildProject": "../../ClassLibrary3/ClassLibrary3.csproj" + } + }, + "projectFileDependencyGroups": { + "": [], + ".NETFramework,Version=v4.6": [ + "ClassLibrary1", + "ClassLibrary2", + "ClassLibrary3" + ] + } +} \ No newline at end of file diff --git a/src/Microsoft.DotNet.ProjectModel/Graph/LockFilePatcher.cs b/src/Microsoft.DotNet.ProjectModel/Graph/LockFilePatcher.cs index cecc63974..1754890ea 100644 --- a/src/Microsoft.DotNet.ProjectModel/Graph/LockFilePatcher.cs +++ b/src/Microsoft.DotNet.ProjectModel/Graph/LockFilePatcher.cs @@ -84,8 +84,6 @@ namespace Microsoft.DotNet.ProjectModel.Graph libraryToPatch.RuntimeAssemblies = export.RuntimeAssemblies; } - - private static IList GetTargetsForLibrary(LockFile lockFile, LockFileProjectLibrary library) { return lockFile.Targets diff --git a/src/Microsoft.DotNet.ProjectModel/Graph/LockFileReader.cs b/src/Microsoft.DotNet.ProjectModel/Graph/LockFileReader.cs index b3306e500..84fea0ada 100644 --- a/src/Microsoft.DotNet.ProjectModel/Graph/LockFileReader.cs +++ b/src/Microsoft.DotNet.ProjectModel/Graph/LockFileReader.cs @@ -61,7 +61,7 @@ namespace Microsoft.DotNet.ProjectModel.Graph return lockFile; } - catch (LockFilePatchingException exception) + catch (LockFilePatchingException) { throw; } diff --git a/test/Microsoft.DotNet.ProjectModel.Tests/LockFilePatchingTests.cs b/test/Microsoft.DotNet.ProjectModel.Tests/LockFilePatchingTests.cs new file mode 100644 index 000000000..35eea7c4d --- /dev/null +++ b/test/Microsoft.DotNet.ProjectModel.Tests/LockFilePatchingTests.cs @@ -0,0 +1,101 @@ +// 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.IO; +using System.Linq; +using FluentAssertions; +using Xunit; +using Microsoft.DotNet.ProjectModel.Graph; +using Microsoft.DotNet.Tools.Test.Utilities; + +namespace Microsoft.DotNet.ProjectModel.Tests +{ + public class LockFilePatchingTests : TestBase + { + + private string ExportFilesRoot=> Path.Combine(RepoRoot, "TestAssets", "LockFileSamples", "ExportFileSamples"); + + [Fact] + public void TestValidPatching() + { + var lockFilePath = GetLockFilePath("valid"); + var lockFile = LockFileReader.Read(lockFilePath); + + var exportFile = lockFile.ExportFile; + + exportFile.Should().NotBeNull(); + exportFile.Exports.Count.Should().Be(3); + exportFile.Exports.Should().OnlyHaveUniqueItems(); + + // check export structure + for (int i = 0; i < 3; i++) + { + var export = exportFile.Exports.ToList().ElementAt(i); + + export.TargetFramework.Should().NotBeNull(); + + AssertTargetLibrary(i + 1, export); + } + + lockFile.Targets.Count.Should().Be(3); + + // check lock file structure is similar to export structure + foreach (var target in lockFile.Targets) + { + target.Libraries.Count.Should().Be(3); + + for (int i = 0; i < 3; i++) + { + var targetLibrary = target.Libraries.ElementAt(i); + AssertTargetLibrary(i + 1, targetLibrary); + } + } + } + + [Fact] + public void TestMissingExportFileThrows() + { + var lockFilePath = GetLockFilePath("invalid_nofragment"); + + Assert.Throws(() => LockFileReader.Read(lockFilePath)); + } + + [Fact] + public void TestMissingExportsThrow() + { + var lockFilePath = GetLockFilePath("invalid_missing-exports"); + + Assert.Throws(() => LockFileReader.Read(lockFilePath)); + } + + [Fact] + public void TestMissmatchingFileVersionsThrows() + { + var lockFilePath = GetLockFilePath("invalid_missmatching-versions"); + + Assert.Throws(() => LockFileReader.Read(lockFilePath)); + } + + private static void AssertTargetLibrary(int i, LockFileTargetLibrary export) + { + export.Type.Should().Be("project"); + + export.Name.Should().Be("ClassLibrary" + i); + export.Version.ToNormalizedString().Should().Be("1.0.0"); + + var dll = $"bin/Debug/ClassLibrary{i}.dll"; + dll = dll.Replace('/', Path.DirectorySeparatorChar); + + export.CompileTimeAssemblies.Count.Should().Be(1); + export.CompileTimeAssemblies.ElementAt(0).Path.Should().Be(dll); + + export.RuntimeAssemblies.Count.Should().Be(1); + export.RuntimeAssemblies.ElementAt(0).Path.Should().Be(dll); + } + + private string GetLockFilePath(string exportSample) + { + return Path.Combine(ExportFilesRoot, exportSample, "project.lock.json"); + } + } +} From 698c82915e7802d60905616b6edd58ea27ba55ee Mon Sep 17 00:00:00 2001 From: Mihai Codoban Date: Mon, 28 Mar 2016 18:11:49 -0700 Subject: [PATCH 07/27] Move methods back to client code --- .../Compilation/LibraryExporter.cs | 25 ++++++++++++++----- .../MSBuildProjectDescription.cs | 10 -------- .../PackageDescription.cs | 15 ----------- .../TargetLibraryWithAssets.cs | 4 --- 4 files changed, 19 insertions(+), 35 deletions(-) diff --git a/src/Microsoft.DotNet.ProjectModel/Compilation/LibraryExporter.cs b/src/Microsoft.DotNet.ProjectModel/Compilation/LibraryExporter.cs index f3c84cf07..ce43b4b0b 100644 --- a/src/Microsoft.DotNet.ProjectModel/Compilation/LibraryExporter.cs +++ b/src/Microsoft.DotNet.ProjectModel/Compilation/LibraryExporter.cs @@ -161,8 +161,12 @@ namespace Microsoft.DotNet.ProjectModel.Compilation builder.AddNativeLibraryGroup(new LibraryAssetGroup(PopulateAssets(library, library.NativeLibraries))); builder.AddRuntimeAssemblyGroup(new LibraryAssetGroup(PopulateAssets(library, library.RuntimeAssemblies))); builder.WithCompilationAssemblies(PopulateAssets(library, library.CompileTimeAssemblies)); - builder.WithSourceReferences(GetSharedSources(library)); - builder.WithAnalyzerReference(GetAnalyzerReferences(library)); + + if (library.Identity.Type.Equals(LibraryType.Package)) + { + builder.WithSourceReferences(GetSharedSources((PackageDescription) library)); + builder.WithAnalyzerReference(GetAnalyzerReferences((PackageDescription) library)); + } if (library.ContentFiles.Any()) { @@ -340,14 +344,23 @@ namespace Microsoft.DotNet.ProjectModel.Compilation return builder.Build(); } - private IEnumerable GetSharedSources(TargetLibraryWithAssets library) + private IEnumerable GetSharedSources(PackageDescription package) { - return library.GetSharedSources().Select(path => LibraryAsset.CreateFromRelativePath(library.Path, path)); + return package + .PackageLibrary + .Files + .Where(path => path.StartsWith("shared" + Path.DirectorySeparatorChar)) + .Select(path => LibraryAsset.CreateFromRelativePath(package.Path, path)); } - private IEnumerable GetAnalyzerReferences(TargetLibraryWithAssets package) + private IEnumerable GetAnalyzerReferences(PackageDescription package) { - var analyzers = package.GetAnalyzerReferences(); + var analyzers = package + .PackageLibrary + .Files + .Where(path => path.StartsWith("analyzers" + Path.DirectorySeparatorChar) && + path.EndsWith(".dll")); + var analyzerRefs = new List(); // See https://docs.nuget.org/create/analyzers-conventions for the analyzer diff --git a/src/Microsoft.DotNet.ProjectModel/MSBuildProjectDescription.cs b/src/Microsoft.DotNet.ProjectModel/MSBuildProjectDescription.cs index a87041620..4209c0802 100644 --- a/src/Microsoft.DotNet.ProjectModel/MSBuildProjectDescription.cs +++ b/src/Microsoft.DotNet.ProjectModel/MSBuildProjectDescription.cs @@ -39,15 +39,5 @@ namespace Microsoft.DotNet.ProjectModel public LockFileProjectLibrary ProjectLibrary { get; } public Project ProjectFile { get; } - - public override IEnumerable GetSharedSources() - { - return Enumerable.Empty(); - } - - public override IEnumerable GetAnalyzerReferences() - { - return Enumerable.Empty(); - } } } diff --git a/src/Microsoft.DotNet.ProjectModel/PackageDescription.cs b/src/Microsoft.DotNet.ProjectModel/PackageDescription.cs index bc539e877..3aebd3409 100644 --- a/src/Microsoft.DotNet.ProjectModel/PackageDescription.cs +++ b/src/Microsoft.DotNet.ProjectModel/PackageDescription.cs @@ -42,20 +42,5 @@ namespace Microsoft.DotNet.ProjectModel { return items.Where(a => !PackageDependencyProvider.IsPlaceholderFile(a)); } - - public override IEnumerable GetSharedSources() - { - return PackageLibrary - .Files - .Where(path => path.StartsWith("shared" + System.IO.Path.DirectorySeparatorChar)); - } - - public override IEnumerable GetAnalyzerReferences() - { - return PackageLibrary - .Files - .Where(path => path.StartsWith("analyzers" + System.IO.Path.DirectorySeparatorChar) && - path.EndsWith(".dll")); - } } } diff --git a/src/Microsoft.DotNet.ProjectModel/TargetLibraryWithAssets.cs b/src/Microsoft.DotNet.ProjectModel/TargetLibraryWithAssets.cs index 5fd7babc5..31a8b48da 100644 --- a/src/Microsoft.DotNet.ProjectModel/TargetLibraryWithAssets.cs +++ b/src/Microsoft.DotNet.ProjectModel/TargetLibraryWithAssets.cs @@ -43,9 +43,5 @@ namespace Microsoft.DotNet.ProjectModel public virtual IEnumerable ContentFiles => TargetLibrary.ContentFiles; public virtual IEnumerable RuntimeTargets => TargetLibrary.RuntimeTargets; - - public abstract IEnumerable GetSharedSources(); - - public abstract IEnumerable GetAnalyzerReferences(); } } From e23f08e7ac3959f904ac3a98d0950db31d36c1d0 Mon Sep 17 00:00:00 2001 From: Troy Dai Date: Sun, 27 Mar 2016 22:43:37 -0700 Subject: [PATCH 08/27] Update projectmodel server Reflecting the xproj reference changes in ProjectModel --- .../MSBuildReferencesProjects/.gitignore | 3 + .../BasicCase01/ClassLibrary1/Class1.cs | 12 ++++ .../ClassLibrary1/ClassLibrary1.csproj | 62 +++++++++++++++++++ .../ClassLibrary1/Properties/AssemblyInfo.cs | 36 +++++++++++ .../BasicCase01/ClassLibrary1/packages.config | 4 ++ .../BasicCase01/ClassLibrary2/Class1.cs | 12 ++++ .../ClassLibrary2/ClassLibrary2.csproj | 61 ++++++++++++++++++ .../ClassLibrary2/Properties/AssemblyInfo.cs | 36 +++++++++++ .../BasicCase01/ClassLibrary3/Class1.cs | 12 ++++ .../ClassLibrary3/ClassLibrary3.csproj | 61 ++++++++++++++++++ .../ClassLibrary3/Properties/AssemblyInfo.cs | 36 +++++++++++ .../BasicCase01/ConsoleApp13.sln | 53 ++++++++++++++++ .../BasicCase01/global.json | 3 + .../src/ConsoleApp13/ConsoleApp13.xproj | 24 +++++++ .../BasicCase01/src/ConsoleApp13/Program.cs | 15 +++++ .../ConsoleApp13/Properties/AssemblyInfo.cs | 19 ++++++ .../ConsoleApp13/project.fragment.lock.json | 36 +++++++++++ .../BasicCase01/src/ConsoleApp13/project.json | 22 +++++++ .../src/ConsoleApp13/project.lock.json | 61 ++++++++++++++++++ .../MSBuildProjectDescription.cs | 1 - .../PackageDescription.cs | 2 - .../InternalModels/ProjectContextSnapshot.cs | 14 ++--- .../Models/DependencyDescription.cs | 15 ++++- .../Models/ProjectReferenceDescription.cs | 51 ++++++++------- .../DthTests.cs | 58 ++++++++++++++++- 25 files changed, 671 insertions(+), 38 deletions(-) create mode 100644 TestAssets/ProjectModelServer/MSBuildReferencesProjects/.gitignore create mode 100644 TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary1/Class1.cs create mode 100644 TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary1/ClassLibrary1.csproj create mode 100644 TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary1/Properties/AssemblyInfo.cs create mode 100644 TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary1/packages.config create mode 100644 TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary2/Class1.cs create mode 100644 TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary2/ClassLibrary2.csproj create mode 100644 TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary2/Properties/AssemblyInfo.cs create mode 100644 TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary3/Class1.cs create mode 100644 TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary3/ClassLibrary3.csproj create mode 100644 TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary3/Properties/AssemblyInfo.cs create mode 100644 TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ConsoleApp13.sln create mode 100644 TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/global.json create mode 100644 TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/src/ConsoleApp13/ConsoleApp13.xproj create mode 100644 TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/src/ConsoleApp13/Program.cs create mode 100644 TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/src/ConsoleApp13/Properties/AssemblyInfo.cs create mode 100644 TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/src/ConsoleApp13/project.fragment.lock.json create mode 100644 TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/src/ConsoleApp13/project.json create mode 100644 TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/src/ConsoleApp13/project.lock.json diff --git a/TestAssets/ProjectModelServer/MSBuildReferencesProjects/.gitignore b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/.gitignore new file mode 100644 index 000000000..497f0e325 --- /dev/null +++ b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/.gitignore @@ -0,0 +1,3 @@ +# Negates the lock file +# MSBuiild references' project model server tests requires these lock files, since they can't be created without VS tooling. +!project.lock.json diff --git a/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary1/Class1.cs b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary1/Class1.cs new file mode 100644 index 000000000..08281c64a --- /dev/null +++ b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary1/Class1.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ClassLibrary1 +{ + public class Class1 + { + } +} diff --git a/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary1/ClassLibrary1.csproj b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary1/ClassLibrary1.csproj new file mode 100644 index 000000000..7364cb64d --- /dev/null +++ b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary1/ClassLibrary1.csproj @@ -0,0 +1,62 @@ + + + + + Debug + AnyCPU + {FD073258-550B-4E57-86AE-DC4874015EB1} + Library + Properties + ClassLibrary1 + ClassLibrary1 + v4.5.2 + 512 + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\packages\Newtonsoft.Json.8.0.3\lib\net45\Newtonsoft.Json.dll + True + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary1/Properties/AssemblyInfo.cs b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary1/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..6437643a7 --- /dev/null +++ b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary1/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("ClassLibrary1")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("ClassLibrary1")] +[assembly: AssemblyCopyright("Copyright © 2016")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("fd073258-550b-4e57-86ae-dc4874015eb1")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary1/packages.config b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary1/packages.config new file mode 100644 index 000000000..1975352b1 --- /dev/null +++ b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary1/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary2/Class1.cs b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary2/Class1.cs new file mode 100644 index 000000000..ad2fff55e --- /dev/null +++ b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary2/Class1.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ClassLibrary2 +{ + public class Class1 + { + } +} diff --git a/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary2/ClassLibrary2.csproj b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary2/ClassLibrary2.csproj new file mode 100644 index 000000000..fb17ee317 --- /dev/null +++ b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary2/ClassLibrary2.csproj @@ -0,0 +1,61 @@ + + + + + Debug + AnyCPU + 0f2d2a48-e867-496c-85a7-e97b64cfeda4 + Library + Properties + ClassLibrary2 + ClassLibrary2 + v4.6 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary2/Properties/AssemblyInfo.cs b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary2/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..b40cfab4c --- /dev/null +++ b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary2/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("ClassLibrary2")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("ClassLibrary2")] +[assembly: AssemblyCopyright("Copyright © 2016")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("0f2d2a48-e867-496c-85a7-e97b64cfeda4")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary3/Class1.cs b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary3/Class1.cs new file mode 100644 index 000000000..21384c5b2 --- /dev/null +++ b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary3/Class1.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ClassLibrary3 +{ + public class Class1 + { + } +} diff --git a/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary3/ClassLibrary3.csproj b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary3/ClassLibrary3.csproj new file mode 100644 index 000000000..0bcde3dfe --- /dev/null +++ b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary3/ClassLibrary3.csproj @@ -0,0 +1,61 @@ + + + + + Debug + AnyCPU + 428e95cb-8435-414b-a313-9d734c633b3e + Library + Properties + ClassLibrary3 + ClassLibrary3 + v4.6 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary3/Properties/AssemblyInfo.cs b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary3/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..0eadf724e --- /dev/null +++ b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary3/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("ClassLibrary3")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("ClassLibrary3")] +[assembly: AssemblyCopyright("Copyright © 2016")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("428e95cb-8435-414b-a313-9d734c633b3e")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ConsoleApp13.sln b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ConsoleApp13.sln new file mode 100644 index 000000000..1ac8ff099 --- /dev/null +++ b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ConsoleApp13.sln @@ -0,0 +1,53 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25029.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{1443ACE0-3065-4C20-AD59-D561798AE0A5}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{0AE82780-22C8-4DC8-8F1E-86977FDD092F}" + ProjectSection(SolutionItems) = preProject + global.json = global.json + EndProjectSection +EndProject +Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "ConsoleApp13", "src\ConsoleApp13\ConsoleApp13.xproj", "{767D3038-AC3A-4722-B21F-F85F2CBC3AA3}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClassLibrary1", "ClassLibrary1\ClassLibrary1.csproj", "{FD073258-550B-4E57-86AE-DC4874015EB1}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClassLibrary2", "ClassLibrary2\ClassLibrary2.csproj", "{0F2D2A48-E867-496C-85A7-E97B64CFEDA4}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClassLibrary3", "ClassLibrary3\ClassLibrary3.csproj", "{428E95CB-8435-414B-A313-9D734C633B3E}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {767D3038-AC3A-4722-B21F-F85F2CBC3AA3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {767D3038-AC3A-4722-B21F-F85F2CBC3AA3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {767D3038-AC3A-4722-B21F-F85F2CBC3AA3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {767D3038-AC3A-4722-B21F-F85F2CBC3AA3}.Release|Any CPU.Build.0 = Release|Any CPU + {FD073258-550B-4E57-86AE-DC4874015EB1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FD073258-550B-4E57-86AE-DC4874015EB1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FD073258-550B-4E57-86AE-DC4874015EB1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FD073258-550B-4E57-86AE-DC4874015EB1}.Release|Any CPU.Build.0 = Release|Any CPU + {0F2D2A48-E867-496C-85A7-E97B64CFEDA4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0F2D2A48-E867-496C-85A7-E97B64CFEDA4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0F2D2A48-E867-496C-85A7-E97B64CFEDA4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0F2D2A48-E867-496C-85A7-E97B64CFEDA4}.Release|Any CPU.Build.0 = Release|Any CPU + {428E95CB-8435-414B-A313-9D734C633B3E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {428E95CB-8435-414B-A313-9D734C633B3E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {428E95CB-8435-414B-A313-9D734C633B3E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {428E95CB-8435-414B-A313-9D734C633B3E}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {767D3038-AC3A-4722-B21F-F85F2CBC3AA3} = {1443ACE0-3065-4C20-AD59-D561798AE0A5} + {FD073258-550B-4E57-86AE-DC4874015EB1} = {1443ACE0-3065-4C20-AD59-D561798AE0A5} + {0F2D2A48-E867-496C-85A7-E97B64CFEDA4} = {1443ACE0-3065-4C20-AD59-D561798AE0A5} + {428E95CB-8435-414B-A313-9D734C633B3E} = {1443ACE0-3065-4C20-AD59-D561798AE0A5} + EndGlobalSection +EndGlobal diff --git a/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/global.json b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/global.json new file mode 100644 index 000000000..5e6422e6d --- /dev/null +++ b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/global.json @@ -0,0 +1,3 @@ +{ + "projects": [ "src", "test" ] +} diff --git a/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/src/ConsoleApp13/ConsoleApp13.xproj b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/src/ConsoleApp13/ConsoleApp13.xproj new file mode 100644 index 000000000..ec559dc46 --- /dev/null +++ b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/src/ConsoleApp13/ConsoleApp13.xproj @@ -0,0 +1,24 @@ + + + + 14.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + 767d3038-ac3a-4722-b21f-f85f2cbc3aa3 + ConsoleApp13 + ..\..\artifacts\obj\$(MSBuildProjectName) + ..\..\artifacts\ + v4.6 + + + 2.0 + + + + + + + + \ No newline at end of file diff --git a/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/src/ConsoleApp13/Program.cs b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/src/ConsoleApp13/Program.cs new file mode 100644 index 000000000..6723332b1 --- /dev/null +++ b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/src/ConsoleApp13/Program.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace ConsoleApp13 +{ + public class Program + { + public static void Main(string[] args) + { + var q = new ClassLibrary1.Class1(); + } + } +} diff --git a/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/src/ConsoleApp13/Properties/AssemblyInfo.cs b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/src/ConsoleApp13/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..83e8803f8 --- /dev/null +++ b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/src/ConsoleApp13/Properties/AssemblyInfo.cs @@ -0,0 +1,19 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("ConsoleApp13")] +[assembly: AssemblyTrademark("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("767d3038-ac3a-4722-b21f-f85f2cbc3aa3")] diff --git a/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/src/ConsoleApp13/project.fragment.lock.json b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/src/ConsoleApp13/project.fragment.lock.json new file mode 100644 index 000000000..1efff4670 --- /dev/null +++ b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/src/ConsoleApp13/project.fragment.lock.json @@ -0,0 +1,36 @@ +{ + "version": 2, + "exports": { + "ClassLibrary1/1.0.0": { + "type": "project", + "framework": ".NETFramework,Version=v4.5.2", + "compile": { + "bin/Debug/ClassLibrary1.dll": {} + }, + "runtime": { + "../packages/Newtonsoft.Json.8.0.3/lib/net45/Newtonsoft.Json.dll": {}, + "bin/Debug/ClassLibrary1.dll": {} + } + }, + "ClassLibrary2/1.0.0": { + "type": "project", + "framework": ".NETFramework,Version=v4.6", + "compile": { + "bin/Debug/ClassLibrary2.dll": {} + }, + "runtime": { + "bin/Debug/ClassLibrary2.dll": {} + } + }, + "ClassLibrary3/1.0.0": { + "type": "project", + "framework": ".NETFramework,Version=v4.6", + "compile": { + "bin/Debug/ClassLibrary3.dll": {} + }, + "runtime": { + "bin/Debug/ClassLibrary3.dll": {} + } + } + } +} \ No newline at end of file diff --git a/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/src/ConsoleApp13/project.json b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/src/ConsoleApp13/project.json new file mode 100644 index 000000000..1323d5f29 --- /dev/null +++ b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/src/ConsoleApp13/project.json @@ -0,0 +1,22 @@ +{ + "version": "1.0.0-*", + "compilationOptions": { + "emitEntryPoint": true + }, + + "frameworks": { + "net46": { + "dependencies": { + "ClassLibrary1": { + "target": "project" + }, + "ClassLibrary2": { + "target": "project" + }, + "ClassLibrary3": { + "target": "project" + } + } + } + } +} diff --git a/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/src/ConsoleApp13/project.lock.json b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/src/ConsoleApp13/project.lock.json new file mode 100644 index 000000000..244c3771b --- /dev/null +++ b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/src/ConsoleApp13/project.lock.json @@ -0,0 +1,61 @@ +{ + "locked": false, + "version": 2, + "targets": { + ".NETFramework,Version=v4.6": { + "ClassLibrary1/1.0.0": { + "type": "project" + }, + "ClassLibrary2/1.0.0": { + "type": "project" + }, + "ClassLibrary3/1.0.0": { + "type": "project" + } + }, + ".NETFramework,Version=v4.6/win7-x64": { + "ClassLibrary1/1.0.0": { + "type": "project" + }, + "ClassLibrary2/1.0.0": { + "type": "project" + }, + "ClassLibrary3/1.0.0": { + "type": "project" + } + }, + ".NETFramework,Version=v4.6/win7-x86": { + "ClassLibrary1/1.0.0": { + "type": "project" + }, + "ClassLibrary2/1.0.0": { + "type": "project" + }, + "ClassLibrary3/1.0.0": { + "type": "project" + } + } + }, + "libraries": { + "ClassLibrary1/1.0.0": { + "type": "project", + "msbuildProject": "../../ClassLibrary1/ClassLibrary1.csproj" + }, + "ClassLibrary2/1.0.0": { + "type": "project", + "msbuildProject": "../../ClassLibrary2/ClassLibrary2.csproj" + }, + "ClassLibrary3/1.0.0": { + "type": "project", + "msbuildProject": "../../ClassLibrary3/ClassLibrary3.csproj" + } + }, + "projectFileDependencyGroups": { + "": [], + ".NETFramework,Version=v4.6": [ + "ClassLibrary1", + "ClassLibrary2", + "ClassLibrary3" + ] + } +} \ No newline at end of file diff --git a/src/Microsoft.DotNet.ProjectModel/MSBuildProjectDescription.cs b/src/Microsoft.DotNet.ProjectModel/MSBuildProjectDescription.cs index 4209c0802..f36e57f00 100644 --- a/src/Microsoft.DotNet.ProjectModel/MSBuildProjectDescription.cs +++ b/src/Microsoft.DotNet.ProjectModel/MSBuildProjectDescription.cs @@ -1,7 +1,6 @@ // 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.Graph; diff --git a/src/Microsoft.DotNet.ProjectModel/PackageDescription.cs b/src/Microsoft.DotNet.ProjectModel/PackageDescription.cs index 3aebd3409..b52e0aa54 100644 --- a/src/Microsoft.DotNet.ProjectModel/PackageDescription.cs +++ b/src/Microsoft.DotNet.ProjectModel/PackageDescription.cs @@ -1,12 +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.IO; using System.Collections.Generic; using System.Linq; using Microsoft.DotNet.ProjectModel.Graph; using Microsoft.DotNet.ProjectModel.Resolution; -using System; namespace Microsoft.DotNet.ProjectModel { diff --git a/src/dotnet/commands/dotnet-projectmodel-server/InternalModels/ProjectContextSnapshot.cs b/src/dotnet/commands/dotnet-projectmodel-server/InternalModels/ProjectContextSnapshot.cs index 684d2e403..694d2ef93 100644 --- a/src/dotnet/commands/dotnet-projectmodel-server/InternalModels/ProjectContextSnapshot.cs +++ b/src/dotnet/commands/dotnet-projectmodel-server/InternalModels/ProjectContextSnapshot.cs @@ -4,11 +4,11 @@ using System; using System.Collections.Generic; using System.Linq; -using Microsoft.DotNet.ProjectModel.Compilation; using Microsoft.DotNet.ProjectModel.Server.Helpers; using Microsoft.DotNet.ProjectModel.Server.Models; using Microsoft.DotNet.Cli.Compiler.Common; using NuGet.Frameworks; +using Microsoft.DotNet.ProjectModel.Graph; namespace Microsoft.DotNet.ProjectModel.Server { @@ -51,15 +51,13 @@ namespace Microsoft.DotNet.ProjectModel.Server var description = DependencyDescription.Create(export.Library, diagnostics, allExports); allDependencies[description.Name] = description; - var projectDescription = export.Library as ProjectDescription; - if (projectDescription != null) + var projectReferene = ProjectReferenceDescription.Create(export.Library); + if (projectReferene != null && export.Library.Identity.Name != context.ProjectFile.Name) { - if (projectDescription.Identity.Name != context.ProjectFile.Name) - { - allProjectReferences.Add(ProjectReferenceDescription.Create(projectDescription)); - } + allProjectReferences.Add(projectReferene); } - else + + if (export.Library.Identity.Type != LibraryType.Project) { allFileReferences.AddRange(export.CompilationAssemblies.Select(asset => asset.ResolvedPath)); } diff --git a/src/dotnet/commands/dotnet-projectmodel-server/Models/DependencyDescription.cs b/src/dotnet/commands/dotnet-projectmodel-server/Models/DependencyDescription.cs index c30be87d9..9b8e95011 100644 --- a/src/dotnet/commands/dotnet-projectmodel-server/Models/DependencyDescription.cs +++ b/src/dotnet/commands/dotnet-projectmodel-server/Models/DependencyDescription.cs @@ -5,13 +5,12 @@ using System.Collections.Generic; using System.Linq; using Microsoft.DotNet.ProjectModel.Compilation; using Microsoft.DotNet.ProjectModel.Graph; -using Microsoft.DotNet.ProjectModel.Server.Helpers; namespace Microsoft.DotNet.ProjectModel.Server.Models { public class DependencyDescription { - private DependencyDescription() { } + protected DependencyDescription() { } public string Name { get; private set; } @@ -24,6 +23,8 @@ namespace Microsoft.DotNet.ProjectModel.Server.Models public string Type { get; private set; } public bool Resolved { get; private set; } + + public string MSBuildProjectPath { get; private set; } public IEnumerable Dependencies { get; private set; } @@ -57,7 +58,7 @@ namespace Microsoft.DotNet.ProjectModel.Server.Models List diagnostics, IDictionary exportsLookup) { - return new DependencyDescription + var result = new DependencyDescription { Name = library.Identity.Name, DisplayName = library.Identity.Name, @@ -71,6 +72,14 @@ namespace Microsoft.DotNet.ProjectModel.Server.Models Warnings = diagnostics.Where(d => d.Severity == DiagnosticMessageSeverity.Warning) .Select(d => new DiagnosticMessageView(d)) }; + + var msbuildLibrary = library as MSBuildProjectDescription; + if (msbuildLibrary != null) + { + result.MSBuildProjectPath = msbuildLibrary.ProjectLibrary.MSBuildProject; + } + + return result; } private static DependencyItem GetDependencyItem(LibraryRange dependency, diff --git a/src/dotnet/commands/dotnet-projectmodel-server/Models/ProjectReferenceDescription.cs b/src/dotnet/commands/dotnet-projectmodel-server/Models/ProjectReferenceDescription.cs index b0cb6ffc0..24bc4e263 100644 --- a/src/dotnet/commands/dotnet-projectmodel-server/Models/ProjectReferenceDescription.cs +++ b/src/dotnet/commands/dotnet-projectmodel-server/Models/ProjectReferenceDescription.cs @@ -1,8 +1,6 @@ // 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 NuGet.Frameworks; - namespace Microsoft.DotNet.ProjectModel.Server.Models { internal class ProjectReferenceDescription @@ -12,7 +10,7 @@ namespace Microsoft.DotNet.ProjectModel.Server.Models public FrameworkData Framework { get; set; } public string Name { get; set; } public string Path { get; set; } - public string WrappedProjectPath { get; set; } + public string MSBuildProjectPath { get; set; } public override bool Equals(object obj) { @@ -20,36 +18,43 @@ namespace Microsoft.DotNet.ProjectModel.Server.Models return other != null && string.Equals(Name, other.Name) && string.Equals(Path, other.Path) && - string.Equals(WrappedProjectPath, other.WrappedProjectPath); + string.Equals(MSBuildProjectPath, other.MSBuildProjectPath); } public override int GetHashCode() { return base.GetHashCode(); } - - public static ProjectReferenceDescription Create(ProjectDescription description) + + /// + /// Create a ProjectReferenceDescription from given LibraryDescription. If the library doesn't + /// represent a project reference returns null. + /// + public static ProjectReferenceDescription Create(LibraryDescription library) { - var targetFrameworkInformation = description.TargetFrameworkInfo; - - string wrappedProjectPath = null; - if (!string.IsNullOrEmpty(targetFrameworkInformation?.WrappedProject) && - description.Project != null) + if (library is ProjectDescription) { - wrappedProjectPath = System.IO.Path.Combine( - description.Project.ProjectDirectory, - targetFrameworkInformation.WrappedProject); - - wrappedProjectPath = System.IO.Path.GetFullPath(wrappedProjectPath); + return new ProjectReferenceDescription + { + Framework = library.Framework.ToPayload(), + Name = library.Identity.Name, + Path = library.Path + }; } - - return new ProjectReferenceDescription + else if (library is MSBuildProjectDescription) { - Framework = description.Framework.ToPayload(), - Name = description.Identity.Name, - Path = description.Path, - WrappedProjectPath = wrappedProjectPath, - }; + return new ProjectReferenceDescription + { + Framework = library.Framework.ToPayload(), + Name = library.Identity.Name, + Path = library.Path, + MSBuildProjectPath = ((MSBuildProjectDescription)library).ProjectLibrary.MSBuildProject + }; + } + else + { + return null; + } } } } diff --git a/test/dotnet-projectmodel-server.Tests/DthTests.cs b/test/dotnet-projectmodel-server.Tests/DthTests.cs index 1d10084ab..90e8805e9 100644 --- a/test/dotnet-projectmodel-server.Tests/DthTests.cs +++ b/test/dotnet-projectmodel-server.Tests/DthTests.cs @@ -2,6 +2,7 @@ // 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.IO; using System.Linq; using System.Threading; @@ -149,7 +150,7 @@ namespace Microsoft.DotNet.ProjectModel.Server.Tests .RetrieveArraryElementAs(0) .AssertProperty("Name", expectedUnresolvedDependency) .AssertProperty("Path", expectedUnresolvedProjectPath) - .AssertProperty("WrappedProjectPath", prop => !prop.HasValues); + .AssertProperty("MSBuildProjectPath", prop => !prop.HasValues); } else if (referenceType == "Package") { @@ -412,5 +413,60 @@ namespace Microsoft.DotNet.ProjectModel.Server.Tests } } } + + [Fact] + public void MSBuildReferenceTest() + { + var testProject = Path.Combine(RepoRoot, "TestAssets", + "ProjectModelServer", + "MSBuildReferencesProjects", + "BasicCase01", + "src", + "ConsoleApp13"); + + using (var server = new DthTestServer(_loggerFactory)) + using (var client = new DthTestClient(server, _loggerFactory)) + { + client.Initialize(testProject); + var messages = client.DrainAllMessages(); + + var classLibraries = new HashSet(new string[] { "ClassLibrary1", "ClassLibrary2", "ClassLibrary3" }); + var dependencies = messages.RetrieveSingleMessage(MessageTypes.Dependencies); + foreach (var each in classLibraries) + { + dependencies.RetrieveDependency(each) + .AssertProperty("Type", LibraryType.MSBuildProject.ToString()) + .AssertProperty("MSBuildProjectPath", Path.Combine("..", "..", each, $"{each}.csproj")) + .AssertProperty("Resolved", true) + .AssertProperty("Name", each) + .AssertProperty("Errors", array => array.Count == 0) + .AssertProperty("Warnings", array => array.Count == 0); + } + + var references = messages.RetrieveSingleMessage(MessageTypes.References) + .RetrievePayloadAs(); + + var projectReferences = references.RetrievePropertyAs("ProjectReferences"); + Assert.Equal(3, projectReferences.Count); + for (int i = 0; i < 3; ++i) + { + var projectRef = projectReferences.RetrieveArraryElementAs(i); + var name = projectRef["Name"].Value(); + + Assert.True(classLibraries.Contains(name)); + projectRef.AssertProperty("Path", path => path.Contains(Path.Combine("BasicCase01", name))) + .AssertProperty("MSBuildProjectPath", Path.Combine("..", "..", name, $"{name}.csproj")); + } + + var fileReferences = references.RetrievePropertyAs("FileReferences") + .Select(each => each.Value()) + .ToArray(); + Assert.Equal(3, fileReferences.Length); + foreach (var each in classLibraries) + { + fileReferences.Contains(Path.Combine("BasicCase01", "ClassLibrary1", "bin", "Debug", $"{each}.dll")); + } + } + } } } From d2984e3cfc1845df27fc350eb75df897f6ae956f Mon Sep 17 00:00:00 2001 From: Troy Dai Date: Mon, 28 Mar 2016 22:58:29 -0700 Subject: [PATCH 09/27] Minor fixes to ProjectModelServer changes --- .../InternalModels/ProjectContextSnapshot.cs | 2 +- .../dotnet-projectmodel-server/Models/DependencyDescription.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dotnet/commands/dotnet-projectmodel-server/InternalModels/ProjectContextSnapshot.cs b/src/dotnet/commands/dotnet-projectmodel-server/InternalModels/ProjectContextSnapshot.cs index 694d2ef93..01cb47e25 100644 --- a/src/dotnet/commands/dotnet-projectmodel-server/InternalModels/ProjectContextSnapshot.cs +++ b/src/dotnet/commands/dotnet-projectmodel-server/InternalModels/ProjectContextSnapshot.cs @@ -4,11 +4,11 @@ using System; using System.Collections.Generic; using System.Linq; +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; -using Microsoft.DotNet.ProjectModel.Graph; namespace Microsoft.DotNet.ProjectModel.Server { diff --git a/src/dotnet/commands/dotnet-projectmodel-server/Models/DependencyDescription.cs b/src/dotnet/commands/dotnet-projectmodel-server/Models/DependencyDescription.cs index 9b8e95011..6d60288a8 100644 --- a/src/dotnet/commands/dotnet-projectmodel-server/Models/DependencyDescription.cs +++ b/src/dotnet/commands/dotnet-projectmodel-server/Models/DependencyDescription.cs @@ -10,7 +10,7 @@ namespace Microsoft.DotNet.ProjectModel.Server.Models { public class DependencyDescription { - protected DependencyDescription() { } + private DependencyDescription() { } public string Name { get; private set; } From 090336d785004d566a4ecd6ae9a95914d2e3673d Mon Sep 17 00:00:00 2001 From: Mihai Codoban Date: Tue, 29 Mar 2016 11:32:33 -0700 Subject: [PATCH 10/27] Make pm server tests pass on windows --- .../DthTests.cs | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/test/dotnet-projectmodel-server.Tests/DthTests.cs b/test/dotnet-projectmodel-server.Tests/DthTests.cs index 90e8805e9..8e4b41531 100644 --- a/test/dotnet-projectmodel-server.Tests/DthTests.cs +++ b/test/dotnet-projectmodel-server.Tests/DthTests.cs @@ -436,7 +436,7 @@ namespace Microsoft.DotNet.ProjectModel.Server.Tests { dependencies.RetrieveDependency(each) .AssertProperty("Type", LibraryType.MSBuildProject.ToString()) - .AssertProperty("MSBuildProjectPath", Path.Combine("..", "..", each, $"{each}.csproj")) + .AssertProperty("MSBuildProjectPath", AssertPathsEqual(Path.Combine("..", "..", each, $"{each}.csproj"))) .AssertProperty("Resolved", true) .AssertProperty("Name", each) .AssertProperty("Errors", array => array.Count == 0) @@ -455,18 +455,36 @@ namespace Microsoft.DotNet.ProjectModel.Server.Tests Assert.True(classLibraries.Contains(name)); projectRef.AssertProperty("Path", path => path.Contains(Path.Combine("BasicCase01", name))) - .AssertProperty("MSBuildProjectPath", Path.Combine("..", "..", name, $"{name}.csproj")); + .AssertProperty("MSBuildProjectPath", AssertPathsEqual(Path.Combine("..", "..", name, $"{name}.csproj"))); } var fileReferences = references.RetrievePropertyAs("FileReferences") .Select(each => each.Value()) .ToArray(); - Assert.Equal(3, fileReferences.Length); + Assert.Equal(7, fileReferences.Length); foreach (var each in classLibraries) { fileReferences.Contains(Path.Combine("BasicCase01", "ClassLibrary1", "bin", "Debug", $"{each}.dll")); } } } + + private static Func AssertPathsEqual(string expectedString) + { + return + (string t) => + { + if (t.Contains('/')) + { + t = t.Replace('/', Path.DirectorySeparatorChar); + } + else if (t.Contains('\\')) + { + t = t.Replace('\\', Path.DirectorySeparatorChar); + } + + return string.Equals(t, expectedString); + }; + } } } From ded82caccd23b0bbeb3cd996f294dfc83d724542 Mon Sep 17 00:00:00 2001 From: Mihai Codoban Date: Tue, 29 Mar 2016 14:15:26 -0700 Subject: [PATCH 11/27] Publish can skip Build --- src/dotnet/commands/dotnet-publish/Program.cs | 2 + .../commands/dotnet-publish/PublishCommand.cs | 64 +++++++++++-------- .../Commands/PublishCommand.cs | 7 +- test/dotnet-publish.Tests/PublishTests.cs | 25 ++++++++ 4 files changed, 68 insertions(+), 30 deletions(-) diff --git a/src/dotnet/commands/dotnet-publish/Program.cs b/src/dotnet/commands/dotnet-publish/Program.cs index e06e484a9..849fec5fd 100644 --- a/src/dotnet/commands/dotnet-publish/Program.cs +++ b/src/dotnet/commands/dotnet-publish/Program.cs @@ -28,6 +28,7 @@ namespace Microsoft.DotNet.Tools.Publish var configuration = app.Option("-c|--configuration ", "Configuration under which to build", CommandOptionType.SingleValue); var projectPath = app.Argument("", "The project to publish, defaults to the current directory. Can be a path to a project.json or a project directory"); var nativeSubdirectories = app.Option("--native-subdirectory", "Temporary mechanism to include subdirectories from native assets of dependency packages in output", CommandOptionType.NoValue); + var noBuild = app.Option("--no-build", "Do not build projects before publishing", CommandOptionType.NoValue); app.OnExecute(() => { @@ -41,6 +42,7 @@ namespace Microsoft.DotNet.Tools.Publish publish.NativeSubdirectories = nativeSubdirectories.HasValue(); publish.ProjectPath = projectPath.Value; publish.VersionSuffix = versionSuffix.Value(); + publish.ShouldBuild = !noBuild.HasValue(); if (string.IsNullOrEmpty(publish.ProjectPath)) { diff --git a/src/dotnet/commands/dotnet-publish/PublishCommand.cs b/src/dotnet/commands/dotnet-publish/PublishCommand.cs index 9fb175ed7..017ab486f 100644 --- a/src/dotnet/commands/dotnet-publish/PublishCommand.cs +++ b/src/dotnet/commands/dotnet-publish/PublishCommand.cs @@ -35,6 +35,7 @@ namespace Microsoft.DotNet.Tools.Publish public string VersionSuffix { get; set; } public int NumberOfProjects { get; private set; } public int NumberOfPublishedProjects { get; private set; } + public bool ShouldBuild { get; set; } public bool TryPrepareForPublish() { @@ -119,34 +120,7 @@ namespace Microsoft.DotNet.Tools.Publish } // Compile the project (and transitively, all it's dependencies) - var args = new List() { - "--framework", - $"{context.TargetFramework.DotNetFrameworkName}", - "--configuration", - configuration, - context.ProjectFile.ProjectDirectory - }; - - if (!string.IsNullOrEmpty(context.RuntimeIdentifier)) - { - args.Insert(0, context.RuntimeIdentifier); - args.Insert(0, "--runtime"); - } - - if (!string.IsNullOrEmpty(VersionSuffix)) - { - args.Add("--version-suffix"); - args.Add(VersionSuffix); - } - - if (!string.IsNullOrEmpty(buildBasePath)) - { - args.Add("--build-base-path"); - args.Add(buildBasePath); - } - - var result = Build.BuildCommand.Run(args.ToArray()); - if (result != 0) + if (ShouldBuild && !InvokeBuildOnProject(context, buildBasePath, configuration)) { return false; } @@ -206,6 +180,40 @@ namespace Microsoft.DotNet.Tools.Publish return true; } + private Boolean InvokeBuildOnProject(ProjectContext context, String buildBasePath, String configuration) + { + var args = new List() + { + "--framework", + $"{context.TargetFramework.DotNetFrameworkName}", + "--configuration", + configuration, + context.ProjectFile.ProjectDirectory + }; + + if (!string.IsNullOrEmpty(context.RuntimeIdentifier)) + { + args.Insert(0, context.RuntimeIdentifier); + args.Insert(0, "--runtime"); + } + + if (!string.IsNullOrEmpty(VersionSuffix)) + { + args.Add("--version-suffix"); + args.Add(VersionSuffix); + } + + if (!string.IsNullOrEmpty(buildBasePath)) + { + args.Add("--build-base-path"); + args.Add(buildBasePath); + } + + var result = Build.BuildCommand.Run(args.ToArray()); + + return result == 0; + } + private HashSet GetExclusionList(ProjectContext context, Dictionary exports) { var exclusionList = new HashSet(); diff --git a/test/Microsoft.DotNet.Tools.Tests.Utilities/Commands/PublishCommand.cs b/test/Microsoft.DotNet.Tools.Tests.Utilities/Commands/PublishCommand.cs index 284d5be39..509530b9b 100644 --- a/test/Microsoft.DotNet.Tools.Tests.Utilities/Commands/PublishCommand.cs +++ b/test/Microsoft.DotNet.Tools.Tests.Utilities/Commands/PublishCommand.cs @@ -19,9 +19,10 @@ namespace Microsoft.DotNet.Tools.Test.Utilities private readonly string _framework; private readonly string _runtime; private readonly string _config; + private readonly bool _noBuild; private readonly string _output; - public PublishCommand(string projectPath, string framework = "", string runtime = "", string output = "", string config = "", bool forcePortable = false) + public PublishCommand(string projectPath, string framework = "", string runtime = "", string output = "", string config = "", bool forcePortable = false, bool noBuild = false) : base("dotnet") { _path = projectPath; @@ -30,6 +31,7 @@ namespace Microsoft.DotNet.Tools.Test.Utilities _runtime = runtime; _output = output; _config = config; + _noBuild = noBuild; } public override CommandResult Execute(string args = "") @@ -91,12 +93,13 @@ namespace Microsoft.DotNet.Tools.Test.Utilities private string BuildArgs() { - return $"{_path} {FrameworkOption} {RuntimeOption} {OutputOption} {ConfigOption}"; + return $"{_path} {FrameworkOption} {RuntimeOption} {OutputOption} {ConfigOption} {NoBuildFlag}"; } private string FrameworkOption => string.IsNullOrEmpty(_framework) ? "" : $"-f {_framework}"; private string RuntimeOption => string.IsNullOrEmpty(_runtime) ? "" : $"-r {_runtime}"; private string OutputOption => string.IsNullOrEmpty(_output) ? "" : $"-o \"{_output}\""; private string ConfigOption => string.IsNullOrEmpty(_config) ? "" : $"-c {_output}"; + private string NoBuildFlag => _noBuild ? "--no-build" :""; } } diff --git a/test/dotnet-publish.Tests/PublishTests.cs b/test/dotnet-publish.Tests/PublishTests.cs index 7aa760807..99a282b7f 100644 --- a/test/dotnet-publish.Tests/PublishTests.cs +++ b/test/dotnet-publish.Tests/PublishTests.cs @@ -176,6 +176,31 @@ namespace Microsoft.DotNet.Tools.Publish.Tests publishCommand.Execute().Should().Fail(); } + [Fact] + public void PublishFailsWhenProjectNotBuiltAndNoBuildFlagSet() + { + TestInstance instance = TestAssetsManager.CreateTestInstance("TestAppCompilationContext") + .WithLockFiles(); + + var testProject = _getProjectJson(instance.TestRoot, "TestApp"); + var publishCommand = new PublishCommand(testProject, noBuild: true); + + publishCommand.Execute().Should().Fail(); + } + + [Fact] + public void PublishSucceedsWhenProjectPreviouslyCompiledAndNoBuildFlagSet() + { + TestInstance instance = TestAssetsManager.CreateTestInstance("TestAppCompilationContext") + .WithLockFiles() + .WithBuildArtifacts(); + + var testProject = _getProjectJson(instance.TestRoot, "TestApp"); + var publishCommand = new PublishCommand(testProject, noBuild: true); + + publishCommand.Execute().Should().Pass(); + } + [Fact] public void PublishScriptsRun() { From 385a3d65da5b759a650b070e711e2bcbbe4fd50b Mon Sep 17 00:00:00 2001 From: Troy Dai Date: Wed, 30 Mar 2016 10:09:35 -0700 Subject: [PATCH 12/27] Fix MSBuildReferenceTest --- test/dotnet-projectmodel-server.Tests/DthTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/dotnet-projectmodel-server.Tests/DthTests.cs b/test/dotnet-projectmodel-server.Tests/DthTests.cs index 8e4b41531..c6d6857bf 100644 --- a/test/dotnet-projectmodel-server.Tests/DthTests.cs +++ b/test/dotnet-projectmodel-server.Tests/DthTests.cs @@ -461,7 +461,7 @@ namespace Microsoft.DotNet.ProjectModel.Server.Tests var fileReferences = references.RetrievePropertyAs("FileReferences") .Select(each => each.Value()) .ToArray(); - Assert.Equal(7, fileReferences.Length); + Assert.Equal(3, fileReferences.Length); foreach (var each in classLibraries) { fileReferences.Contains(Path.Combine("BasicCase01", "ClassLibrary1", "bin", "Debug", $"{each}.dll")); From d20e0d74f283cd9e467b5514e70bebc6f6a36228 Mon Sep 17 00:00:00 2001 From: Mihai Codoban Date: Wed, 30 Mar 2016 10:58:30 -0700 Subject: [PATCH 13/27] LockFilePatcher should only patch when lock file has holes in it If not, the export file is stale --- .../project.fragment.lock.json | 35 +++++++++++++++++++ .../valid_staleFragment/project.json | 10 ++++++ .../valid_staleFragment/project.lock.json | 13 +++++++ .../Graph/LockFilePatcher.cs | 2 +- .../LockFilePatchingTests.cs | 15 ++++++++ 5 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 TestAssets/LockFileSamples/ExportFileSamples/valid_staleFragment/project.fragment.lock.json create mode 100644 TestAssets/LockFileSamples/ExportFileSamples/valid_staleFragment/project.json create mode 100644 TestAssets/LockFileSamples/ExportFileSamples/valid_staleFragment/project.lock.json diff --git a/TestAssets/LockFileSamples/ExportFileSamples/valid_staleFragment/project.fragment.lock.json b/TestAssets/LockFileSamples/ExportFileSamples/valid_staleFragment/project.fragment.lock.json new file mode 100644 index 000000000..415fc75d8 --- /dev/null +++ b/TestAssets/LockFileSamples/ExportFileSamples/valid_staleFragment/project.fragment.lock.json @@ -0,0 +1,35 @@ +{ + "version": 2, + "exports": { + "ClassLibrary1/1.0.0": { + "type": "project", + "framework": ".NETFramework,Version=v4.5.2", + "compile": { + "bin/Debug/ClassLibrary1.dll": {} + }, + "runtime": { + "bin/Debug/ClassLibrary1.dll": {} + } + }, + "ClassLibrary2/1.0.0": { + "type": "project", + "framework": ".NETFramework,Version=v4.6", + "compile": { + "bin/Debug/ClassLibrary2.dll": {} + }, + "runtime": { + "bin/Debug/ClassLibrary2.dll": {} + } + }, + "ClassLibrary3/1.0.0": { + "type": "project", + "framework": ".NETFramework,Version=v4.6", + "compile": { + "bin/Debug/ClassLibrary3.dll": {} + }, + "runtime": { + "bin/Debug/ClassLibrary3.dll": {} + } + } + } +} \ No newline at end of file diff --git a/TestAssets/LockFileSamples/ExportFileSamples/valid_staleFragment/project.json b/TestAssets/LockFileSamples/ExportFileSamples/valid_staleFragment/project.json new file mode 100644 index 000000000..2959f5fbc --- /dev/null +++ b/TestAssets/LockFileSamples/ExportFileSamples/valid_staleFragment/project.json @@ -0,0 +1,10 @@ +{ + "version": "1.0.0-*", + "compilationOptions": { + "emitEntryPoint": true + }, + + "frameworks": { + "net46": { } + } +} diff --git a/TestAssets/LockFileSamples/ExportFileSamples/valid_staleFragment/project.lock.json b/TestAssets/LockFileSamples/ExportFileSamples/valid_staleFragment/project.lock.json new file mode 100644 index 000000000..e7b45e57d --- /dev/null +++ b/TestAssets/LockFileSamples/ExportFileSamples/valid_staleFragment/project.lock.json @@ -0,0 +1,13 @@ +{ + "locked": false, + "version": 2, + "targets": { + ".NETFramework,Version=v4.6": { } + }, + "libraries": { + }, + "projectFileDependencyGroups": { + "": [], + ".NETFramework,Version=v4.6": [] + } +} \ No newline at end of file diff --git a/src/Microsoft.DotNet.ProjectModel/Graph/LockFilePatcher.cs b/src/Microsoft.DotNet.ProjectModel/Graph/LockFilePatcher.cs index 1754890ea..a0f7c0c0e 100644 --- a/src/Microsoft.DotNet.ProjectModel/Graph/LockFilePatcher.cs +++ b/src/Microsoft.DotNet.ProjectModel/Graph/LockFilePatcher.cs @@ -26,7 +26,7 @@ namespace Microsoft.DotNet.ProjectModel.Graph { var exportFilePath = GetExportFilePath(_lockFile.LockFilePath); - if (File.Exists(exportFilePath)) + if (File.Exists(exportFilePath) && _msbuildTargetLibraries.Any()) { var exportFile = LockFileReader.ReadExportFile(exportFilePath); PatchLockWithExport(exportFile); diff --git a/test/Microsoft.DotNet.ProjectModel.Tests/LockFilePatchingTests.cs b/test/Microsoft.DotNet.ProjectModel.Tests/LockFilePatchingTests.cs index 35eea7c4d..6e3b69295 100644 --- a/test/Microsoft.DotNet.ProjectModel.Tests/LockFilePatchingTests.cs +++ b/test/Microsoft.DotNet.ProjectModel.Tests/LockFilePatchingTests.cs @@ -52,6 +52,21 @@ namespace Microsoft.DotNet.ProjectModel.Tests } } + [Fact] + public void TestFragmentExistsButNoHolesInLockFile() + { + var lockFilePath = GetLockFilePath("valid_staleFragment"); + var lockFile = LockFileReader.Read(lockFilePath); + + var exportFile = lockFile.ExportFile; + + exportFile.Should().BeNull(); + + lockFile.Targets.Count.Should().Be(1); + + lockFile.Targets[0].Libraries.Count.Should().Be(0); + } + [Fact] public void TestMissingExportFileThrows() { From 829fab595e12d511759cf3c1af3e3b417bcd5347 Mon Sep 17 00:00:00 2001 From: Mihai Codoban Date: Wed, 30 Mar 2016 11:09:28 -0700 Subject: [PATCH 14/27] Fix extract method code The VS code generator is too opinionated on CLR types :) --- src/dotnet/commands/dotnet-publish/PublishCommand.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dotnet/commands/dotnet-publish/PublishCommand.cs b/src/dotnet/commands/dotnet-publish/PublishCommand.cs index 017ab486f..abe835442 100644 --- a/src/dotnet/commands/dotnet-publish/PublishCommand.cs +++ b/src/dotnet/commands/dotnet-publish/PublishCommand.cs @@ -180,7 +180,7 @@ namespace Microsoft.DotNet.Tools.Publish return true; } - private Boolean InvokeBuildOnProject(ProjectContext context, String buildBasePath, String configuration) + private bool InvokeBuildOnProject(ProjectContext context, string buildBasePath, string configuration) { var args = new List() { From 90baecdd51d4a614a737d53b63dfabd6dfb719cb Mon Sep 17 00:00:00 2001 From: Troy Dai Date: Wed, 30 Mar 2016 11:10:06 -0700 Subject: [PATCH 15/27] Rename BasicCase01 -> ValieCase01 --- .../{BasicCase01 => ValidCase01}/ClassLibrary1/Class1.cs | 0 .../ClassLibrary1/ClassLibrary1.csproj | 0 .../ClassLibrary1/Properties/AssemblyInfo.cs | 0 .../ClassLibrary1/packages.config | 0 .../{BasicCase01 => ValidCase01}/ClassLibrary2/Class1.cs | 0 .../ClassLibrary2/ClassLibrary2.csproj | 0 .../ClassLibrary2/Properties/AssemblyInfo.cs | 0 .../{BasicCase01 => ValidCase01}/ClassLibrary3/Class1.cs | 0 .../ClassLibrary3/ClassLibrary3.csproj | 0 .../ClassLibrary3/Properties/AssemblyInfo.cs | 0 .../{BasicCase01 => ValidCase01}/ConsoleApp13.sln | 0 .../{BasicCase01 => ValidCase01}/global.json | 0 .../src/MainApp}/ConsoleApp13.xproj | 0 .../ConsoleApp13 => ValidCase01/src/MainApp}/Program.cs | 0 .../src/MainApp}/Properties/AssemblyInfo.cs | 0 .../src/MainApp}/project.fragment.lock.json | 0 .../ConsoleApp13 => ValidCase01/src/MainApp}/project.json | 0 .../src/MainApp}/project.lock.json | 0 test/dotnet-projectmodel-server.Tests/DthTests.cs | 8 ++++---- 19 files changed, 4 insertions(+), 4 deletions(-) rename TestAssets/ProjectModelServer/MSBuildReferencesProjects/{BasicCase01 => ValidCase01}/ClassLibrary1/Class1.cs (100%) rename TestAssets/ProjectModelServer/MSBuildReferencesProjects/{BasicCase01 => ValidCase01}/ClassLibrary1/ClassLibrary1.csproj (100%) rename TestAssets/ProjectModelServer/MSBuildReferencesProjects/{BasicCase01 => ValidCase01}/ClassLibrary1/Properties/AssemblyInfo.cs (100%) rename TestAssets/ProjectModelServer/MSBuildReferencesProjects/{BasicCase01 => ValidCase01}/ClassLibrary1/packages.config (100%) rename TestAssets/ProjectModelServer/MSBuildReferencesProjects/{BasicCase01 => ValidCase01}/ClassLibrary2/Class1.cs (100%) rename TestAssets/ProjectModelServer/MSBuildReferencesProjects/{BasicCase01 => ValidCase01}/ClassLibrary2/ClassLibrary2.csproj (100%) rename TestAssets/ProjectModelServer/MSBuildReferencesProjects/{BasicCase01 => ValidCase01}/ClassLibrary2/Properties/AssemblyInfo.cs (100%) rename TestAssets/ProjectModelServer/MSBuildReferencesProjects/{BasicCase01 => ValidCase01}/ClassLibrary3/Class1.cs (100%) rename TestAssets/ProjectModelServer/MSBuildReferencesProjects/{BasicCase01 => ValidCase01}/ClassLibrary3/ClassLibrary3.csproj (100%) rename TestAssets/ProjectModelServer/MSBuildReferencesProjects/{BasicCase01 => ValidCase01}/ClassLibrary3/Properties/AssemblyInfo.cs (100%) rename TestAssets/ProjectModelServer/MSBuildReferencesProjects/{BasicCase01 => ValidCase01}/ConsoleApp13.sln (100%) rename TestAssets/ProjectModelServer/MSBuildReferencesProjects/{BasicCase01 => ValidCase01}/global.json (100%) rename TestAssets/ProjectModelServer/MSBuildReferencesProjects/{BasicCase01/src/ConsoleApp13 => ValidCase01/src/MainApp}/ConsoleApp13.xproj (100%) rename TestAssets/ProjectModelServer/MSBuildReferencesProjects/{BasicCase01/src/ConsoleApp13 => ValidCase01/src/MainApp}/Program.cs (100%) rename TestAssets/ProjectModelServer/MSBuildReferencesProjects/{BasicCase01/src/ConsoleApp13 => ValidCase01/src/MainApp}/Properties/AssemblyInfo.cs (100%) rename TestAssets/ProjectModelServer/MSBuildReferencesProjects/{BasicCase01/src/ConsoleApp13 => ValidCase01/src/MainApp}/project.fragment.lock.json (100%) rename TestAssets/ProjectModelServer/MSBuildReferencesProjects/{BasicCase01/src/ConsoleApp13 => ValidCase01/src/MainApp}/project.json (100%) rename TestAssets/ProjectModelServer/MSBuildReferencesProjects/{BasicCase01/src/ConsoleApp13 => ValidCase01/src/MainApp}/project.lock.json (100%) diff --git a/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary1/Class1.cs b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/ValidCase01/ClassLibrary1/Class1.cs similarity index 100% rename from TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary1/Class1.cs rename to TestAssets/ProjectModelServer/MSBuildReferencesProjects/ValidCase01/ClassLibrary1/Class1.cs diff --git a/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary1/ClassLibrary1.csproj b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/ValidCase01/ClassLibrary1/ClassLibrary1.csproj similarity index 100% rename from TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary1/ClassLibrary1.csproj rename to TestAssets/ProjectModelServer/MSBuildReferencesProjects/ValidCase01/ClassLibrary1/ClassLibrary1.csproj diff --git a/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary1/Properties/AssemblyInfo.cs b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/ValidCase01/ClassLibrary1/Properties/AssemblyInfo.cs similarity index 100% rename from TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary1/Properties/AssemblyInfo.cs rename to TestAssets/ProjectModelServer/MSBuildReferencesProjects/ValidCase01/ClassLibrary1/Properties/AssemblyInfo.cs diff --git a/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary1/packages.config b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/ValidCase01/ClassLibrary1/packages.config similarity index 100% rename from TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary1/packages.config rename to TestAssets/ProjectModelServer/MSBuildReferencesProjects/ValidCase01/ClassLibrary1/packages.config diff --git a/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary2/Class1.cs b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/ValidCase01/ClassLibrary2/Class1.cs similarity index 100% rename from TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary2/Class1.cs rename to TestAssets/ProjectModelServer/MSBuildReferencesProjects/ValidCase01/ClassLibrary2/Class1.cs diff --git a/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary2/ClassLibrary2.csproj b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/ValidCase01/ClassLibrary2/ClassLibrary2.csproj similarity index 100% rename from TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary2/ClassLibrary2.csproj rename to TestAssets/ProjectModelServer/MSBuildReferencesProjects/ValidCase01/ClassLibrary2/ClassLibrary2.csproj diff --git a/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary2/Properties/AssemblyInfo.cs b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/ValidCase01/ClassLibrary2/Properties/AssemblyInfo.cs similarity index 100% rename from TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary2/Properties/AssemblyInfo.cs rename to TestAssets/ProjectModelServer/MSBuildReferencesProjects/ValidCase01/ClassLibrary2/Properties/AssemblyInfo.cs diff --git a/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary3/Class1.cs b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/ValidCase01/ClassLibrary3/Class1.cs similarity index 100% rename from TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary3/Class1.cs rename to TestAssets/ProjectModelServer/MSBuildReferencesProjects/ValidCase01/ClassLibrary3/Class1.cs diff --git a/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary3/ClassLibrary3.csproj b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/ValidCase01/ClassLibrary3/ClassLibrary3.csproj similarity index 100% rename from TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary3/ClassLibrary3.csproj rename to TestAssets/ProjectModelServer/MSBuildReferencesProjects/ValidCase01/ClassLibrary3/ClassLibrary3.csproj diff --git a/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary3/Properties/AssemblyInfo.cs b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/ValidCase01/ClassLibrary3/Properties/AssemblyInfo.cs similarity index 100% rename from TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ClassLibrary3/Properties/AssemblyInfo.cs rename to TestAssets/ProjectModelServer/MSBuildReferencesProjects/ValidCase01/ClassLibrary3/Properties/AssemblyInfo.cs diff --git a/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ConsoleApp13.sln b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/ValidCase01/ConsoleApp13.sln similarity index 100% rename from TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/ConsoleApp13.sln rename to TestAssets/ProjectModelServer/MSBuildReferencesProjects/ValidCase01/ConsoleApp13.sln diff --git a/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/global.json b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/ValidCase01/global.json similarity index 100% rename from TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/global.json rename to TestAssets/ProjectModelServer/MSBuildReferencesProjects/ValidCase01/global.json diff --git a/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/src/ConsoleApp13/ConsoleApp13.xproj b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/ValidCase01/src/MainApp/ConsoleApp13.xproj similarity index 100% rename from TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/src/ConsoleApp13/ConsoleApp13.xproj rename to TestAssets/ProjectModelServer/MSBuildReferencesProjects/ValidCase01/src/MainApp/ConsoleApp13.xproj diff --git a/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/src/ConsoleApp13/Program.cs b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/ValidCase01/src/MainApp/Program.cs similarity index 100% rename from TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/src/ConsoleApp13/Program.cs rename to TestAssets/ProjectModelServer/MSBuildReferencesProjects/ValidCase01/src/MainApp/Program.cs diff --git a/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/src/ConsoleApp13/Properties/AssemblyInfo.cs b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/ValidCase01/src/MainApp/Properties/AssemblyInfo.cs similarity index 100% rename from TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/src/ConsoleApp13/Properties/AssemblyInfo.cs rename to TestAssets/ProjectModelServer/MSBuildReferencesProjects/ValidCase01/src/MainApp/Properties/AssemblyInfo.cs diff --git a/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/src/ConsoleApp13/project.fragment.lock.json b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/ValidCase01/src/MainApp/project.fragment.lock.json similarity index 100% rename from TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/src/ConsoleApp13/project.fragment.lock.json rename to TestAssets/ProjectModelServer/MSBuildReferencesProjects/ValidCase01/src/MainApp/project.fragment.lock.json diff --git a/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/src/ConsoleApp13/project.json b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/ValidCase01/src/MainApp/project.json similarity index 100% rename from TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/src/ConsoleApp13/project.json rename to TestAssets/ProjectModelServer/MSBuildReferencesProjects/ValidCase01/src/MainApp/project.json diff --git a/TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/src/ConsoleApp13/project.lock.json b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/ValidCase01/src/MainApp/project.lock.json similarity index 100% rename from TestAssets/ProjectModelServer/MSBuildReferencesProjects/BasicCase01/src/ConsoleApp13/project.lock.json rename to TestAssets/ProjectModelServer/MSBuildReferencesProjects/ValidCase01/src/MainApp/project.lock.json diff --git a/test/dotnet-projectmodel-server.Tests/DthTests.cs b/test/dotnet-projectmodel-server.Tests/DthTests.cs index c6d6857bf..98573a548 100644 --- a/test/dotnet-projectmodel-server.Tests/DthTests.cs +++ b/test/dotnet-projectmodel-server.Tests/DthTests.cs @@ -420,9 +420,9 @@ namespace Microsoft.DotNet.ProjectModel.Server.Tests var testProject = Path.Combine(RepoRoot, "TestAssets", "ProjectModelServer", "MSBuildReferencesProjects", - "BasicCase01", + "ValidCase01", "src", - "ConsoleApp13"); + "MainApp"); using (var server = new DthTestServer(_loggerFactory)) using (var client = new DthTestClient(server, _loggerFactory)) @@ -454,7 +454,7 @@ namespace Microsoft.DotNet.ProjectModel.Server.Tests var name = projectRef["Name"].Value(); Assert.True(classLibraries.Contains(name)); - projectRef.AssertProperty("Path", path => path.Contains(Path.Combine("BasicCase01", name))) + projectRef.AssertProperty("Path", path => path.Contains(Path.Combine("ValidCase01", name))) .AssertProperty("MSBuildProjectPath", AssertPathsEqual(Path.Combine("..", "..", name, $"{name}.csproj"))); } @@ -464,7 +464,7 @@ namespace Microsoft.DotNet.ProjectModel.Server.Tests Assert.Equal(3, fileReferences.Length); foreach (var each in classLibraries) { - fileReferences.Contains(Path.Combine("BasicCase01", "ClassLibrary1", "bin", "Debug", $"{each}.dll")); + fileReferences.Contains(Path.Combine("ValidCase01", "ClassLibrary1", "bin", "Debug", $"{each}.dll")); } } } From 0767f13d4928eb3c1771205f6c734062dccc09f8 Mon Sep 17 00:00:00 2001 From: Mihai Codoban Date: Wed, 30 Mar 2016 11:18:01 -0700 Subject: [PATCH 16/27] Rename lock file samples --- .../invalid_missing-exports/project.fragment.lock.json | 0 .../ExportFiles}/invalid_missing-exports/project.json | 0 .../ExportFiles}/invalid_missing-exports/project.lock.json | 0 .../invalid_missmatching-versions/project.fragment.lock.json | 0 .../ExportFiles}/invalid_missmatching-versions/project.json | 0 .../invalid_missmatching-versions/project.lock.json | 0 .../ExportFiles}/invalid_nofragment/project.json | 0 .../ExportFiles}/invalid_nofragment/project.lock.json | 0 .../ExportFiles}/valid/project.fragment.lock.json | 0 .../ExportFiles}/valid/project.json | 0 .../ExportFiles}/valid/project.lock.json | 0 .../ExportFiles}/valid_staleFragment/project.fragment.lock.json | 0 .../ExportFiles}/valid_staleFragment/project.json | 0 .../ExportFiles}/valid_staleFragment/project.lock.json | 0 .../LockFilePatchingTests.cs | 2 +- 15 files changed, 1 insertion(+), 1 deletion(-) rename TestAssets/{LockFileSamples/ExportFileSamples => LockFiles/ExportFiles}/invalid_missing-exports/project.fragment.lock.json (100%) rename TestAssets/{LockFileSamples/ExportFileSamples => LockFiles/ExportFiles}/invalid_missing-exports/project.json (100%) rename TestAssets/{LockFileSamples/ExportFileSamples => LockFiles/ExportFiles}/invalid_missing-exports/project.lock.json (100%) rename TestAssets/{LockFileSamples/ExportFileSamples => LockFiles/ExportFiles}/invalid_missmatching-versions/project.fragment.lock.json (100%) rename TestAssets/{LockFileSamples/ExportFileSamples => LockFiles/ExportFiles}/invalid_missmatching-versions/project.json (100%) rename TestAssets/{LockFileSamples/ExportFileSamples => LockFiles/ExportFiles}/invalid_missmatching-versions/project.lock.json (100%) rename TestAssets/{LockFileSamples/ExportFileSamples => LockFiles/ExportFiles}/invalid_nofragment/project.json (100%) rename TestAssets/{LockFileSamples/ExportFileSamples => LockFiles/ExportFiles}/invalid_nofragment/project.lock.json (100%) rename TestAssets/{LockFileSamples/ExportFileSamples => LockFiles/ExportFiles}/valid/project.fragment.lock.json (100%) rename TestAssets/{LockFileSamples/ExportFileSamples => LockFiles/ExportFiles}/valid/project.json (100%) rename TestAssets/{LockFileSamples/ExportFileSamples => LockFiles/ExportFiles}/valid/project.lock.json (100%) rename TestAssets/{LockFileSamples/ExportFileSamples => LockFiles/ExportFiles}/valid_staleFragment/project.fragment.lock.json (100%) rename TestAssets/{LockFileSamples/ExportFileSamples => LockFiles/ExportFiles}/valid_staleFragment/project.json (100%) rename TestAssets/{LockFileSamples/ExportFileSamples => LockFiles/ExportFiles}/valid_staleFragment/project.lock.json (100%) diff --git a/TestAssets/LockFileSamples/ExportFileSamples/invalid_missing-exports/project.fragment.lock.json b/TestAssets/LockFiles/ExportFiles/invalid_missing-exports/project.fragment.lock.json similarity index 100% rename from TestAssets/LockFileSamples/ExportFileSamples/invalid_missing-exports/project.fragment.lock.json rename to TestAssets/LockFiles/ExportFiles/invalid_missing-exports/project.fragment.lock.json diff --git a/TestAssets/LockFileSamples/ExportFileSamples/invalid_missing-exports/project.json b/TestAssets/LockFiles/ExportFiles/invalid_missing-exports/project.json similarity index 100% rename from TestAssets/LockFileSamples/ExportFileSamples/invalid_missing-exports/project.json rename to TestAssets/LockFiles/ExportFiles/invalid_missing-exports/project.json diff --git a/TestAssets/LockFileSamples/ExportFileSamples/invalid_missing-exports/project.lock.json b/TestAssets/LockFiles/ExportFiles/invalid_missing-exports/project.lock.json similarity index 100% rename from TestAssets/LockFileSamples/ExportFileSamples/invalid_missing-exports/project.lock.json rename to TestAssets/LockFiles/ExportFiles/invalid_missing-exports/project.lock.json diff --git a/TestAssets/LockFileSamples/ExportFileSamples/invalid_missmatching-versions/project.fragment.lock.json b/TestAssets/LockFiles/ExportFiles/invalid_missmatching-versions/project.fragment.lock.json similarity index 100% rename from TestAssets/LockFileSamples/ExportFileSamples/invalid_missmatching-versions/project.fragment.lock.json rename to TestAssets/LockFiles/ExportFiles/invalid_missmatching-versions/project.fragment.lock.json diff --git a/TestAssets/LockFileSamples/ExportFileSamples/invalid_missmatching-versions/project.json b/TestAssets/LockFiles/ExportFiles/invalid_missmatching-versions/project.json similarity index 100% rename from TestAssets/LockFileSamples/ExportFileSamples/invalid_missmatching-versions/project.json rename to TestAssets/LockFiles/ExportFiles/invalid_missmatching-versions/project.json diff --git a/TestAssets/LockFileSamples/ExportFileSamples/invalid_missmatching-versions/project.lock.json b/TestAssets/LockFiles/ExportFiles/invalid_missmatching-versions/project.lock.json similarity index 100% rename from TestAssets/LockFileSamples/ExportFileSamples/invalid_missmatching-versions/project.lock.json rename to TestAssets/LockFiles/ExportFiles/invalid_missmatching-versions/project.lock.json diff --git a/TestAssets/LockFileSamples/ExportFileSamples/invalid_nofragment/project.json b/TestAssets/LockFiles/ExportFiles/invalid_nofragment/project.json similarity index 100% rename from TestAssets/LockFileSamples/ExportFileSamples/invalid_nofragment/project.json rename to TestAssets/LockFiles/ExportFiles/invalid_nofragment/project.json diff --git a/TestAssets/LockFileSamples/ExportFileSamples/invalid_nofragment/project.lock.json b/TestAssets/LockFiles/ExportFiles/invalid_nofragment/project.lock.json similarity index 100% rename from TestAssets/LockFileSamples/ExportFileSamples/invalid_nofragment/project.lock.json rename to TestAssets/LockFiles/ExportFiles/invalid_nofragment/project.lock.json diff --git a/TestAssets/LockFileSamples/ExportFileSamples/valid/project.fragment.lock.json b/TestAssets/LockFiles/ExportFiles/valid/project.fragment.lock.json similarity index 100% rename from TestAssets/LockFileSamples/ExportFileSamples/valid/project.fragment.lock.json rename to TestAssets/LockFiles/ExportFiles/valid/project.fragment.lock.json diff --git a/TestAssets/LockFileSamples/ExportFileSamples/valid/project.json b/TestAssets/LockFiles/ExportFiles/valid/project.json similarity index 100% rename from TestAssets/LockFileSamples/ExportFileSamples/valid/project.json rename to TestAssets/LockFiles/ExportFiles/valid/project.json diff --git a/TestAssets/LockFileSamples/ExportFileSamples/valid/project.lock.json b/TestAssets/LockFiles/ExportFiles/valid/project.lock.json similarity index 100% rename from TestAssets/LockFileSamples/ExportFileSamples/valid/project.lock.json rename to TestAssets/LockFiles/ExportFiles/valid/project.lock.json diff --git a/TestAssets/LockFileSamples/ExportFileSamples/valid_staleFragment/project.fragment.lock.json b/TestAssets/LockFiles/ExportFiles/valid_staleFragment/project.fragment.lock.json similarity index 100% rename from TestAssets/LockFileSamples/ExportFileSamples/valid_staleFragment/project.fragment.lock.json rename to TestAssets/LockFiles/ExportFiles/valid_staleFragment/project.fragment.lock.json diff --git a/TestAssets/LockFileSamples/ExportFileSamples/valid_staleFragment/project.json b/TestAssets/LockFiles/ExportFiles/valid_staleFragment/project.json similarity index 100% rename from TestAssets/LockFileSamples/ExportFileSamples/valid_staleFragment/project.json rename to TestAssets/LockFiles/ExportFiles/valid_staleFragment/project.json diff --git a/TestAssets/LockFileSamples/ExportFileSamples/valid_staleFragment/project.lock.json b/TestAssets/LockFiles/ExportFiles/valid_staleFragment/project.lock.json similarity index 100% rename from TestAssets/LockFileSamples/ExportFileSamples/valid_staleFragment/project.lock.json rename to TestAssets/LockFiles/ExportFiles/valid_staleFragment/project.lock.json diff --git a/test/Microsoft.DotNet.ProjectModel.Tests/LockFilePatchingTests.cs b/test/Microsoft.DotNet.ProjectModel.Tests/LockFilePatchingTests.cs index 6e3b69295..59dc3812f 100644 --- a/test/Microsoft.DotNet.ProjectModel.Tests/LockFilePatchingTests.cs +++ b/test/Microsoft.DotNet.ProjectModel.Tests/LockFilePatchingTests.cs @@ -13,7 +13,7 @@ namespace Microsoft.DotNet.ProjectModel.Tests public class LockFilePatchingTests : TestBase { - private string ExportFilesRoot=> Path.Combine(RepoRoot, "TestAssets", "LockFileSamples", "ExportFileSamples"); + private string ExportFilesRoot=> Path.Combine(RepoRoot, "TestAssets", "LockFiles", "ExportFiles"); [Fact] public void TestValidPatching() From a293c438ffcdd747f023e29774987c94ccd6d28e Mon Sep 17 00:00:00 2001 From: Troy Dai Date: Wed, 30 Mar 2016 11:32:38 -0700 Subject: [PATCH 17/27] Change variable name in DthTests --- test/dotnet-projectmodel-server.Tests/DthTests.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/dotnet-projectmodel-server.Tests/DthTests.cs b/test/dotnet-projectmodel-server.Tests/DthTests.cs index 98573a548..e2bb777e8 100644 --- a/test/dotnet-projectmodel-server.Tests/DthTests.cs +++ b/test/dotnet-projectmodel-server.Tests/DthTests.cs @@ -432,13 +432,13 @@ namespace Microsoft.DotNet.ProjectModel.Server.Tests var classLibraries = new HashSet(new string[] { "ClassLibrary1", "ClassLibrary2", "ClassLibrary3" }); var dependencies = messages.RetrieveSingleMessage(MessageTypes.Dependencies); - foreach (var each in classLibraries) + foreach (var classLibrary in classLibraries) { - dependencies.RetrieveDependency(each) + dependencies.RetrieveDependency(classLibrary) .AssertProperty("Type", LibraryType.MSBuildProject.ToString()) - .AssertProperty("MSBuildProjectPath", AssertPathsEqual(Path.Combine("..", "..", each, $"{each}.csproj"))) + .AssertProperty("MSBuildProjectPath", AssertPathsEqual(Path.Combine("..", "..", classLibrary, $"{classLibrary}.csproj"))) .AssertProperty("Resolved", true) - .AssertProperty("Name", each) + .AssertProperty("Name", classLibrary) .AssertProperty("Errors", array => array.Count == 0) .AssertProperty("Warnings", array => array.Count == 0); } From 45ef209ac495c05832f47bc5debf9c167f3784c0 Mon Sep 17 00:00:00 2001 From: Mihai Codoban Date: Wed, 30 Mar 2016 11:41:16 -0700 Subject: [PATCH 18/27] Patching test does not depend on target library ordering --- .../LockFilePatchingTests.cs | 54 ++++++++++--------- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/test/Microsoft.DotNet.ProjectModel.Tests/LockFilePatchingTests.cs b/test/Microsoft.DotNet.ProjectModel.Tests/LockFilePatchingTests.cs index 59dc3812f..aa2e1ebd2 100644 --- a/test/Microsoft.DotNet.ProjectModel.Tests/LockFilePatchingTests.cs +++ b/test/Microsoft.DotNet.ProjectModel.Tests/LockFilePatchingTests.cs @@ -1,19 +1,21 @@ // 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; using System.Linq; using FluentAssertions; using Xunit; using Microsoft.DotNet.ProjectModel.Graph; using Microsoft.DotNet.Tools.Test.Utilities; +using NuGet.ProjectModel; namespace Microsoft.DotNet.ProjectModel.Tests { public class LockFilePatchingTests : TestBase { - private string ExportFilesRoot=> Path.Combine(RepoRoot, "TestAssets", "LockFiles", "ExportFiles"); + private static string ExportFilesRoot=> Path.Combine(RepoRoot, "TestAssets", "LockFiles", "ExportFiles"); [Fact] public void TestValidPatching() @@ -28,13 +30,10 @@ namespace Microsoft.DotNet.ProjectModel.Tests exportFile.Exports.Should().OnlyHaveUniqueItems(); // check export structure - for (int i = 0; i < 3; i++) + foreach (var export in exportFile.Exports) { - var export = exportFile.Exports.ToList().ElementAt(i); - export.TargetFramework.Should().NotBeNull(); - - AssertTargetLibrary(i + 1, export); + AssertTargetLibrary(export); } lockFile.Targets.Count.Should().Be(3); @@ -44,10 +43,9 @@ namespace Microsoft.DotNet.ProjectModel.Tests { target.Libraries.Count.Should().Be(3); - for (int i = 0; i < 3; i++) + foreach (var library in target.Libraries) { - var targetLibrary = target.Libraries.ElementAt(i); - AssertTargetLibrary(i + 1, targetLibrary); + AssertTargetLibrary(library); } } } @@ -91,24 +89,32 @@ namespace Microsoft.DotNet.ProjectModel.Tests Assert.Throws(() => LockFileReader.Read(lockFilePath)); } - private static void AssertTargetLibrary(int i, LockFileTargetLibrary export) + private static int LibraryNumberFromName(Microsoft.DotNet.ProjectModel.Graph.LockFileTargetLibrary library) { - export.Type.Should().Be("project"); - - export.Name.Should().Be("ClassLibrary" + i); - export.Version.ToNormalizedString().Should().Be("1.0.0"); - - var dll = $"bin/Debug/ClassLibrary{i}.dll"; - dll = dll.Replace('/', Path.DirectorySeparatorChar); - - export.CompileTimeAssemblies.Count.Should().Be(1); - export.CompileTimeAssemblies.ElementAt(0).Path.Should().Be(dll); - - export.RuntimeAssemblies.Count.Should().Be(1); - export.RuntimeAssemblies.ElementAt(0).Path.Should().Be(dll); + var libraryName = library.Name; + return (int)char.GetNumericValue(libraryName[libraryName.Length - 1]); } - private string GetLockFilePath(string exportSample) + private static void AssertTargetLibrary(Microsoft.DotNet.ProjectModel.Graph.LockFileTargetLibrary library) + { + var libraryNumber = LibraryNumberFromName(library); + + library.Type.Should().Be("project"); + + library.Name.Should().Be("ClassLibrary" + libraryNumber); + library.Version.ToNormalizedString().Should().Be("1.0.0"); + + var dll = $"bin/Debug/ClassLibrary{libraryNumber}.dll"; + dll = dll.Replace('/', Path.DirectorySeparatorChar); + + library.CompileTimeAssemblies.Count.Should().Be(1); + library.CompileTimeAssemblies.ElementAt(0).Path.Should().Be(dll); + + library.RuntimeAssemblies.Count.Should().Be(1); + library.RuntimeAssemblies.ElementAt(0).Path.Should().Be(dll); + } + + private static string GetLockFilePath(string exportSample) { return Path.Combine(ExportFilesRoot, exportSample, "project.lock.json"); } From ec5f88e99479eb656a1b51b6e04cf35460b7f35a Mon Sep 17 00:00:00 2001 From: Mihai Codoban Date: Wed, 30 Mar 2016 11:48:18 -0700 Subject: [PATCH 19/27] Split test in two --- .../LockFilePatchingTests.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/test/Microsoft.DotNet.ProjectModel.Tests/LockFilePatchingTests.cs b/test/Microsoft.DotNet.ProjectModel.Tests/LockFilePatchingTests.cs index aa2e1ebd2..2688643ee 100644 --- a/test/Microsoft.DotNet.ProjectModel.Tests/LockFilePatchingTests.cs +++ b/test/Microsoft.DotNet.ProjectModel.Tests/LockFilePatchingTests.cs @@ -18,7 +18,7 @@ namespace Microsoft.DotNet.ProjectModel.Tests private static string ExportFilesRoot=> Path.Combine(RepoRoot, "TestAssets", "LockFiles", "ExportFiles"); [Fact] - public void TestValidPatching() + public void TestExportFileIsParsed() { var lockFilePath = GetLockFilePath("valid"); var lockFile = LockFileReader.Read(lockFilePath); @@ -35,8 +35,13 @@ namespace Microsoft.DotNet.ProjectModel.Tests export.TargetFramework.Should().NotBeNull(); AssertTargetLibrary(export); } + } - lockFile.Targets.Count.Should().Be(3); + [Fact] + public void TestLockFileIsPatchedWithExportData() + { + var lockFilePath = GetLockFilePath("valid"); + var lockFile = LockFileReader.Read(lockFilePath); // check lock file structure is similar to export structure foreach (var target in lockFile.Targets) From 9cc3d088f0f3daf9be091a44f3944b657ef7d20a Mon Sep 17 00:00:00 2001 From: Mihai Codoban Date: Wed, 30 Mar 2016 14:00:45 -0700 Subject: [PATCH 20/27] MSBuildProjectDescriptions has dedicated property for the csproj path --- .../MSBuildProjectDescription.cs | 21 ++++++++++--------- .../Resolution/MSBuildDependencyProvider.cs | 6 +++--- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/Microsoft.DotNet.ProjectModel/MSBuildProjectDescription.cs b/src/Microsoft.DotNet.ProjectModel/MSBuildProjectDescription.cs index f36e57f00..05252a7dd 100644 --- a/src/Microsoft.DotNet.ProjectModel/MSBuildProjectDescription.cs +++ b/src/Microsoft.DotNet.ProjectModel/MSBuildProjectDescription.cs @@ -9,17 +9,19 @@ namespace Microsoft.DotNet.ProjectModel { /// /// Represents an MSBuild project. - /// It has been invisibly built by MSBuild, so it behaves like a package: can provide all assets up front + /// It has been built by MSBuild, so it behaves like a package: can provide all assets up front + /// + /// The Path represents the path to the project.json, if there is one near the csproj file. /// public class MSBuildProjectDescription : TargetLibraryWithAssets { public MSBuildProjectDescription( - string path, - LockFileProjectLibrary projectLibrary, - LockFileTargetLibrary lockFileLibrary, - Project projectFile, - IEnumerable dependencies, - bool compatible, + string path, + string msbuildProjectPath, + LockFileProjectLibrary projectLibrary, + LockFileTargetLibrary lockFileLibrary, + IEnumerable dependencies, + bool compatible, bool resolved) : base( new LibraryIdentity(projectLibrary.Name, projectLibrary.Version, LibraryType.MSBuildProject), @@ -31,12 +33,11 @@ namespace Microsoft.DotNet.ProjectModel compatible: compatible, framework: null) { - ProjectFile = projectFile; ProjectLibrary = projectLibrary; + MsbuildProjectPath = msbuildProjectPath; } public LockFileProjectLibrary ProjectLibrary { get; } - - public Project ProjectFile { get; } + public string MsbuildProjectPath { get; set; } } } diff --git a/src/Microsoft.DotNet.ProjectModel/Resolution/MSBuildDependencyProvider.cs b/src/Microsoft.DotNet.ProjectModel/Resolution/MSBuildDependencyProvider.cs index e67e1c313..f117c39bb 100644 --- a/src/Microsoft.DotNet.ProjectModel/Resolution/MSBuildDependencyProvider.cs +++ b/src/Microsoft.DotNet.ProjectModel/Resolution/MSBuildDependencyProvider.cs @@ -36,12 +36,12 @@ namespace Microsoft.DotNet.ProjectModel.Resolution var projectFile = projectLibrary.Path == null ? null : _projectResolver(projectLibrary.Path); var msbuildPackageDescription = new MSBuildProjectDescription( + projectLibrary.Path, msbuildProjectPath, projectLibrary, targetLibrary, - projectFile, - dependencies, - compatible, + dependencies, + compatible, resolved: compatible && exists); return msbuildPackageDescription; From 54278c294ef42746f4a0442967a33a8c6fa74a02 Mon Sep 17 00:00:00 2001 From: Mihai Codoban Date: Wed, 30 Mar 2016 14:51:43 -0700 Subject: [PATCH 21/27] Transform lock file reader exceptions into diagnostics --- .../ErrorCodes.DotNet.cs | 3 ++ .../ProjectContextBuilder.cs | 48 +++++++++++++++++-- 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/src/Microsoft.DotNet.ProjectModel/ErrorCodes.DotNet.cs b/src/Microsoft.DotNet.ProjectModel/ErrorCodes.DotNet.cs index 095bbf9b2..83e229eef 100644 --- a/src/Microsoft.DotNet.ProjectModel/ErrorCodes.DotNet.cs +++ b/src/Microsoft.DotNet.ProjectModel/ErrorCodes.DotNet.cs @@ -13,5 +13,8 @@ namespace Microsoft.DotNet.ProjectModel // Multiple libraries marked as "platform" public static readonly string DOTNET1013 = nameof(DOTNET1013); + + // Failed to read lock file + public static readonly string DOTNET1014 = nameof(DOTNET1014); } } diff --git a/src/Microsoft.DotNet.ProjectModel/ProjectContextBuilder.cs b/src/Microsoft.DotNet.ProjectModel/ProjectContextBuilder.cs index aeb423a46..e3315dafe 100644 --- a/src/Microsoft.DotNet.ProjectModel/ProjectContextBuilder.cs +++ b/src/Microsoft.DotNet.ProjectModel/ProjectContextBuilder.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Text; using Microsoft.DotNet.ProjectModel.Graph; using Microsoft.DotNet.ProjectModel.Resolution; using Microsoft.Extensions.Internal; @@ -138,6 +139,8 @@ namespace Microsoft.DotNet.ProjectModel public ProjectContext Build() { + var diagnostics = new List(); + ProjectDirectory = Project?.ProjectDirectory ?? ProjectDirectory; if (GlobalSettings == null && ProjectDirectory != null) @@ -159,7 +162,7 @@ namespace Microsoft.DotNet.ProjectModel LockFileLookup lockFileLookup = null; EnsureProjectLoaded(); - LockFile = LockFile ?? LockFileResolver(ProjectDirectory); + ReadLockFile(diagnostics); var validLockFile = true; string lockFileValidationMessage = null; @@ -193,7 +196,7 @@ namespace Microsoft.DotNet.ProjectModel if (target != null) { var nugetPackageResolver = new PackageDependencyProvider(PackagesDirectory, frameworkReferenceResolver); - var msbuildProjectResolver = new MSBuildDependencyProvider(Project ,ProjectResolver); + var msbuildProjectResolver = new MSBuildDependencyProvider(Project, ProjectResolver); ScanLibraries(target, lockFileLookup, libraries, msbuildProjectResolver, nugetPackageResolver, projectResolver); } } @@ -204,8 +207,6 @@ namespace Microsoft.DotNet.ProjectModel // Resolve the dependencies ResolveDependencies(libraries, referenceAssemblyDependencyResolver, out requiresFrameworkAssemblies); - var diagnostics = new List(); - // REVIEW: Should this be in NuGet (possibly stored in the lock file?) if (LockFile == null) { @@ -270,6 +271,45 @@ namespace Microsoft.DotNet.ProjectModel LockFile); } + private void ReadLockFile(ICollection diagnostics) + { + try + { + LockFile = LockFile ?? LockFileResolver(ProjectDirectory); + } + catch (FileFormatException e) + { + var lockFilePath = ""; + if (LockFile != null) + { + lockFilePath = LockFile.LockFilePath; + } + else if (Project != null) + { + lockFilePath = Path.Combine(Project.ProjectDirectory, LockFile.FileName); + } + + diagnostics.Add(new DiagnosticMessage( + ErrorCodes.DOTNET1014, + ComposeMessageFromInnerExceptions(e), + lockFilePath, + DiagnosticMessageSeverity.Error)); + } + } + + private static string ComposeMessageFromInnerExceptions(Exception exception) + { + var sb = new StringBuilder(); + + while (exception != null) + { + sb.AppendLine(exception.Message); + exception = exception.InnerException; + } + + return sb.ToString(); + } + private void ResolveDependencies(Dictionary libraries, ReferenceAssemblyDependencyResolver referenceAssemblyDependencyResolver, out bool requiresFrameworkAssemblies) From 52cabf9cbf5a2c345df06a8e1a91a84e7a205ace Mon Sep 17 00:00:00 2001 From: Troy Dai Date: Wed, 30 Mar 2016 14:56:18 -0700 Subject: [PATCH 22/27] Remove unnecessary assertion in DthTests The count of file references is different on different platform. It is not essential to the test since there are assertion to test required references' existence. --- test/dotnet-projectmodel-server.Tests/DthTests.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/test/dotnet-projectmodel-server.Tests/DthTests.cs b/test/dotnet-projectmodel-server.Tests/DthTests.cs index e2bb777e8..c8424a23c 100644 --- a/test/dotnet-projectmodel-server.Tests/DthTests.cs +++ b/test/dotnet-projectmodel-server.Tests/DthTests.cs @@ -461,7 +461,6 @@ namespace Microsoft.DotNet.ProjectModel.Server.Tests var fileReferences = references.RetrievePropertyAs("FileReferences") .Select(each => each.Value()) .ToArray(); - Assert.Equal(3, fileReferences.Length); foreach (var each in classLibraries) { fileReferences.Contains(Path.Combine("ValidCase01", "ClassLibrary1", "bin", "Debug", $"{each}.dll")); From 2e78b9ae603d15e10f4c28ca12c1ede3e596628f Mon Sep 17 00:00:00 2001 From: Mihai Codoban Date: Wed, 30 Mar 2016 14:58:22 -0700 Subject: [PATCH 23/27] Revert "MSBuildProjectDescriptions has dedicated property for the csproj path" This reverts commit a95e20d96480dac3010c8403e04bd716fba2cc5b. --- .../MSBuildProjectDescription.cs | 21 +++++++++---------- .../Resolution/MSBuildDependencyProvider.cs | 6 +++--- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/Microsoft.DotNet.ProjectModel/MSBuildProjectDescription.cs b/src/Microsoft.DotNet.ProjectModel/MSBuildProjectDescription.cs index 05252a7dd..f36e57f00 100644 --- a/src/Microsoft.DotNet.ProjectModel/MSBuildProjectDescription.cs +++ b/src/Microsoft.DotNet.ProjectModel/MSBuildProjectDescription.cs @@ -9,19 +9,17 @@ namespace Microsoft.DotNet.ProjectModel { /// /// Represents an MSBuild project. - /// It has been built by MSBuild, so it behaves like a package: can provide all assets up front - /// - /// The Path represents the path to the project.json, if there is one near the csproj file. + /// It has been invisibly built by MSBuild, so it behaves like a package: can provide all assets up front /// public class MSBuildProjectDescription : TargetLibraryWithAssets { public MSBuildProjectDescription( - string path, - string msbuildProjectPath, - LockFileProjectLibrary projectLibrary, - LockFileTargetLibrary lockFileLibrary, - IEnumerable dependencies, - bool compatible, + string path, + LockFileProjectLibrary projectLibrary, + LockFileTargetLibrary lockFileLibrary, + Project projectFile, + IEnumerable dependencies, + bool compatible, bool resolved) : base( new LibraryIdentity(projectLibrary.Name, projectLibrary.Version, LibraryType.MSBuildProject), @@ -33,11 +31,12 @@ namespace Microsoft.DotNet.ProjectModel compatible: compatible, framework: null) { + ProjectFile = projectFile; ProjectLibrary = projectLibrary; - MsbuildProjectPath = msbuildProjectPath; } public LockFileProjectLibrary ProjectLibrary { get; } - public string MsbuildProjectPath { get; set; } + + public Project ProjectFile { get; } } } diff --git a/src/Microsoft.DotNet.ProjectModel/Resolution/MSBuildDependencyProvider.cs b/src/Microsoft.DotNet.ProjectModel/Resolution/MSBuildDependencyProvider.cs index f117c39bb..e67e1c313 100644 --- a/src/Microsoft.DotNet.ProjectModel/Resolution/MSBuildDependencyProvider.cs +++ b/src/Microsoft.DotNet.ProjectModel/Resolution/MSBuildDependencyProvider.cs @@ -36,12 +36,12 @@ namespace Microsoft.DotNet.ProjectModel.Resolution var projectFile = projectLibrary.Path == null ? null : _projectResolver(projectLibrary.Path); var msbuildPackageDescription = new MSBuildProjectDescription( - projectLibrary.Path, msbuildProjectPath, projectLibrary, targetLibrary, - dependencies, - compatible, + projectFile, + dependencies, + compatible, resolved: compatible && exists); return msbuildPackageDescription; From fd3a7a0a5f64a47d3c3de5d562d7c037aee715ef Mon Sep 17 00:00:00 2001 From: Troy Dai Date: Wed, 30 Mar 2016 15:09:43 -0700 Subject: [PATCH 24/27] Rename xproj in ValidCase01 --- .../ValidCase01/src/MainApp/{ConsoleApp13.xproj => MainApp.xproj} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename TestAssets/ProjectModelServer/MSBuildReferencesProjects/ValidCase01/src/MainApp/{ConsoleApp13.xproj => MainApp.xproj} (100%) diff --git a/TestAssets/ProjectModelServer/MSBuildReferencesProjects/ValidCase01/src/MainApp/ConsoleApp13.xproj b/TestAssets/ProjectModelServer/MSBuildReferencesProjects/ValidCase01/src/MainApp/MainApp.xproj similarity index 100% rename from TestAssets/ProjectModelServer/MSBuildReferencesProjects/ValidCase01/src/MainApp/ConsoleApp13.xproj rename to TestAssets/ProjectModelServer/MSBuildReferencesProjects/ValidCase01/src/MainApp/MainApp.xproj From b7ca1d14bd34e3526c88458bcd1db6d9bb36221a Mon Sep 17 00:00:00 2001 From: Mihai Codoban Date: Wed, 30 Mar 2016 16:26:00 -0700 Subject: [PATCH 25/27] Distinguish between the msbuild project path and csproj file path --- .../MSBuildProjectDescription.cs | 7 +++++++ .../Resolution/MSBuildDependencyProvider.cs | 14 ++++++++------ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/Microsoft.DotNet.ProjectModel/MSBuildProjectDescription.cs b/src/Microsoft.DotNet.ProjectModel/MSBuildProjectDescription.cs index f36e57f00..71e613ea4 100644 --- a/src/Microsoft.DotNet.ProjectModel/MSBuildProjectDescription.cs +++ b/src/Microsoft.DotNet.ProjectModel/MSBuildProjectDescription.cs @@ -10,11 +10,15 @@ namespace Microsoft.DotNet.ProjectModel /// /// Represents an MSBuild project. /// It has been invisibly built by MSBuild, so it behaves like a package: can provide all assets up front + /// + /// Path points to the project's directory + /// MSBuildPRojectPath points to the csproj file /// public class MSBuildProjectDescription : TargetLibraryWithAssets { public MSBuildProjectDescription( string path, + string msbuildProjectPath, LockFileProjectLibrary projectLibrary, LockFileTargetLibrary lockFileLibrary, Project projectFile, @@ -31,12 +35,15 @@ namespace Microsoft.DotNet.ProjectModel compatible: compatible, framework: null) { + MSBuildProjectPath = msbuildProjectPath; ProjectFile = projectFile; ProjectLibrary = projectLibrary; } public LockFileProjectLibrary ProjectLibrary { get; } + public string MSBuildProjectPath { get; set; } + public Project ProjectFile { get; } } } diff --git a/src/Microsoft.DotNet.ProjectModel/Resolution/MSBuildDependencyProvider.cs b/src/Microsoft.DotNet.ProjectModel/Resolution/MSBuildDependencyProvider.cs index e67e1c313..ea9bda755 100644 --- a/src/Microsoft.DotNet.ProjectModel/Resolution/MSBuildDependencyProvider.cs +++ b/src/Microsoft.DotNet.ProjectModel/Resolution/MSBuildDependencyProvider.cs @@ -30,13 +30,16 @@ namespace Microsoft.DotNet.ProjectModel.Resolution var dependencies = new List(targetLibrary.Dependencies.Count + targetLibrary.FrameworkAssemblies.Count); PopulateDependencies(dependencies, targetLibrary, targetFramework); - var msbuildProjectPath = GetMSbuildProjectPath(projectLibrary); - var exists = Directory.Exists(msbuildProjectPath); + var msbuildProjectFilePath = GetMSBuildProjectFilePath(projectLibrary); + var msbuildProjectDirectoryPath = Path.GetDirectoryName(msbuildProjectFilePath); + + var exists = Directory.Exists(msbuildProjectDirectoryPath); var projectFile = projectLibrary.Path == null ? null : _projectResolver(projectLibrary.Path); var msbuildPackageDescription = new MSBuildProjectDescription( - msbuildProjectPath, + msbuildProjectDirectoryPath, + msbuildProjectFilePath, projectLibrary, targetLibrary, projectFile, @@ -47,7 +50,7 @@ namespace Microsoft.DotNet.ProjectModel.Resolution return msbuildPackageDescription; } - private string GetMSbuildProjectPath(LockFileProjectLibrary projectLibrary) + private string GetMSBuildProjectFilePath(LockFileProjectLibrary projectLibrary) { if (_rootProject == null) { @@ -56,9 +59,8 @@ namespace Microsoft.DotNet.ProjectModel.Resolution var rootProjectPath = Path.GetDirectoryName(_rootProject.ProjectFilePath); var msbuildProjectFilePath = Path.Combine(rootProjectPath, projectLibrary.MSBuildProject); - var msbuildProjectPath = Path.GetDirectoryName(Path.GetFullPath(msbuildProjectFilePath)); - return msbuildProjectPath; + return Path.GetFullPath(msbuildProjectFilePath); } private void PopulateDependencies( From 8a3ddc9c8a8c5b2308496176f7a23ebfec61d1b7 Mon Sep 17 00:00:00 2001 From: Troy Dai Date: Wed, 30 Mar 2016 15:54:40 -0700 Subject: [PATCH 26/27] Remove MSBuildProjectPath property --- .../Models/DependencyDescription.cs | 8 ++---- .../Models/ProjectReferenceDescription.cs | 7 ++--- .../DthTests.cs | 28 +++++-------------- 3 files changed, 12 insertions(+), 31 deletions(-) diff --git a/src/dotnet/commands/dotnet-projectmodel-server/Models/DependencyDescription.cs b/src/dotnet/commands/dotnet-projectmodel-server/Models/DependencyDescription.cs index 6d60288a8..07aa58a64 100644 --- a/src/dotnet/commands/dotnet-projectmodel-server/Models/DependencyDescription.cs +++ b/src/dotnet/commands/dotnet-projectmodel-server/Models/DependencyDescription.cs @@ -24,8 +24,6 @@ namespace Microsoft.DotNet.ProjectModel.Server.Models public bool Resolved { get; private set; } - public string MSBuildProjectPath { get; private set; } - public IEnumerable Dependencies { get; private set; } public IEnumerable Errors { get; private set; } @@ -72,13 +70,13 @@ namespace Microsoft.DotNet.ProjectModel.Server.Models Warnings = diagnostics.Where(d => d.Severity == DiagnosticMessageSeverity.Warning) .Select(d => new DiagnosticMessageView(d)) }; - + var msbuildLibrary = library as MSBuildProjectDescription; if (msbuildLibrary != null) { - result.MSBuildProjectPath = msbuildLibrary.ProjectLibrary.MSBuildProject; + result.Path = msbuildLibrary.MSBuildProjectPath; } - + return result; } diff --git a/src/dotnet/commands/dotnet-projectmodel-server/Models/ProjectReferenceDescription.cs b/src/dotnet/commands/dotnet-projectmodel-server/Models/ProjectReferenceDescription.cs index 24bc4e263..224837488 100644 --- a/src/dotnet/commands/dotnet-projectmodel-server/Models/ProjectReferenceDescription.cs +++ b/src/dotnet/commands/dotnet-projectmodel-server/Models/ProjectReferenceDescription.cs @@ -10,15 +10,13 @@ namespace Microsoft.DotNet.ProjectModel.Server.Models public FrameworkData Framework { get; set; } public string Name { get; set; } public string Path { get; set; } - public string MSBuildProjectPath { get; set; } public override bool Equals(object obj) { var other = obj as ProjectReferenceDescription; return other != null && string.Equals(Name, other.Name) && - string.Equals(Path, other.Path) && - string.Equals(MSBuildProjectPath, other.MSBuildProjectPath); + string.Equals(Path, other.Path); } public override int GetHashCode() @@ -47,8 +45,7 @@ namespace Microsoft.DotNet.ProjectModel.Server.Models { Framework = library.Framework.ToPayload(), Name = library.Identity.Name, - Path = library.Path, - MSBuildProjectPath = ((MSBuildProjectDescription)library).ProjectLibrary.MSBuildProject + Path = ((MSBuildProjectDescription)library).MSBuildProjectPath, }; } else diff --git a/test/dotnet-projectmodel-server.Tests/DthTests.cs b/test/dotnet-projectmodel-server.Tests/DthTests.cs index c8424a23c..92df20c70 100644 --- a/test/dotnet-projectmodel-server.Tests/DthTests.cs +++ b/test/dotnet-projectmodel-server.Tests/DthTests.cs @@ -149,8 +149,7 @@ namespace Microsoft.DotNet.ProjectModel.Server.Tests .AssertJArrayCount(1) .RetrieveArraryElementAs(0) .AssertProperty("Name", expectedUnresolvedDependency) - .AssertProperty("Path", expectedUnresolvedProjectPath) - .AssertProperty("MSBuildProjectPath", prop => !prop.HasValues); + .AssertProperty("Path", expectedUnresolvedProjectPath); } else if (referenceType == "Package") { @@ -432,11 +431,12 @@ namespace Microsoft.DotNet.ProjectModel.Server.Tests var classLibraries = new HashSet(new string[] { "ClassLibrary1", "ClassLibrary2", "ClassLibrary3" }); var dependencies = messages.RetrieveSingleMessage(MessageTypes.Dependencies); + var testProjectRoot = Path.Combine(RepoRoot, "TestAssets", "ProjectModelServer", "MSBuildReferencesProjects", "ValidCase01"); foreach (var classLibrary in classLibraries) - { + { dependencies.RetrieveDependency(classLibrary) .AssertProperty("Type", LibraryType.MSBuildProject.ToString()) - .AssertProperty("MSBuildProjectPath", AssertPathsEqual(Path.Combine("..", "..", classLibrary, $"{classLibrary}.csproj"))) + .AssertProperty("Path", NormalizePathString(Path.Combine(testProjectRoot, classLibrary, $"{classLibrary}.csproj"))) .AssertProperty("Resolved", true) .AssertProperty("Name", classLibrary) .AssertProperty("Errors", array => array.Count == 0) @@ -454,8 +454,7 @@ namespace Microsoft.DotNet.ProjectModel.Server.Tests var name = projectRef["Name"].Value(); Assert.True(classLibraries.Contains(name)); - projectRef.AssertProperty("Path", path => path.Contains(Path.Combine("ValidCase01", name))) - .AssertProperty("MSBuildProjectPath", AssertPathsEqual(Path.Combine("..", "..", name, $"{name}.csproj"))); + projectRef.AssertProperty("Path", NormalizePathString(Path.Combine(testProjectRoot, name, $"{name}.csproj"))); } var fileReferences = references.RetrievePropertyAs("FileReferences") @@ -468,22 +467,9 @@ namespace Microsoft.DotNet.ProjectModel.Server.Tests } } - private static Func AssertPathsEqual(string expectedString) + private static string NormalizePathString(string original) { - return - (string t) => - { - if (t.Contains('/')) - { - t = t.Replace('/', Path.DirectorySeparatorChar); - } - else if (t.Contains('\\')) - { - t = t.Replace('\\', Path.DirectorySeparatorChar); - } - - return string.Equals(t, expectedString); - }; + return original.Replace('/', Path.DirectorySeparatorChar).Replace('\\', Path.DirectorySeparatorChar); } } } From 4c84e686d0351bc86c396c543ac4bd13fcbd8a18 Mon Sep 17 00:00:00 2001 From: Mihai Codoban Date: Wed, 30 Mar 2016 18:22:35 -0700 Subject: [PATCH 27/27] Avoid duplicate messages --- .../ProjectContextBuilder.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.DotNet.ProjectModel/ProjectContextBuilder.cs b/src/Microsoft.DotNet.ProjectModel/ProjectContextBuilder.cs index e3315dafe..4548a0ad4 100644 --- a/src/Microsoft.DotNet.ProjectModel/ProjectContextBuilder.cs +++ b/src/Microsoft.DotNet.ProjectModel/ProjectContextBuilder.cs @@ -300,13 +300,19 @@ namespace Microsoft.DotNet.ProjectModel private static string ComposeMessageFromInnerExceptions(Exception exception) { var sb = new StringBuilder(); + var messages = new HashSet(); while (exception != null) { - sb.AppendLine(exception.Message); + messages.Add(exception.Message); exception = exception.InnerException; } + foreach (var message in messages) + { + sb.AppendLine(message); + } + return sb.ToString(); }