diff --git a/TestAssets/ProjectModelServer/DthTestProjects/src/EmptyNetCoreApp/Program.cs b/TestAssets/ProjectModelServer/DthTestProjects/src/EmptyNetCoreApp/Program.cs
new file mode 100644
index 000000000..9e6dde0c3
--- /dev/null
+++ b/TestAssets/ProjectModelServer/DthTestProjects/src/EmptyNetCoreApp/Program.cs
@@ -0,0 +1,13 @@
+using System;
+
+namespace Misc.DthTestProjects.SimpleConsoleApp
+{
+ public class Program
+ {
+ public int Main(string[] args)
+ {
+ Console.WriteLine("Hello, world.");
+ return 0;
+ }
+ }
+}
diff --git a/TestAssets/ProjectModelServer/DthTestProjects/src/EmptyNetCoreApp/project.json b/TestAssets/ProjectModelServer/DthTestProjects/src/EmptyNetCoreApp/project.json
new file mode 100644
index 000000000..3621ef882
--- /dev/null
+++ b/TestAssets/ProjectModelServer/DthTestProjects/src/EmptyNetCoreApp/project.json
@@ -0,0 +1,15 @@
+{
+ "dependencies": {},
+ "frameworks": {
+ "netcoreapp1.0": {
+ "imports": "dnxcore50",
+ "dependencies": {
+ "Microsoft.NETCore.App": {
+ "type": "platform",
+ "version": "1.0.0-rc2-23931"
+ },
+ "Newtonsoft.Json": "8.0.3"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/TestAssets/TestProjects/DependencyContextValidator/DependencyContextValidator/.noautobuild b/TestAssets/TestProjects/DependencyContextValidator/DependencyContextValidator/.noautobuild
new file mode 100644
index 000000000..e69de29bb
diff --git a/TestAssets/TestProjects/DependencyContextValidator/DependencyContextValidator/Validator.cs b/TestAssets/TestProjects/DependencyContextValidator/DependencyContextValidator/Validator.cs
index 4195d928d..b34b4c93b 100644
--- a/TestAssets/TestProjects/DependencyContextValidator/DependencyContextValidator/Validator.cs
+++ b/TestAssets/TestProjects/DependencyContextValidator/DependencyContextValidator/Validator.cs
@@ -44,6 +44,7 @@ namespace Microsoft.Extensions.DependencyModel
var resolvedPaths = compilationLibrary.ResolveReferencePaths();
foreach (var resolvedPath in resolvedPaths)
{
+ Console.WriteLine($"Compilation {compilationLibrary.Name}:{Path.GetFileName(resolvedPath)}");
if (!File.Exists(resolvedPath))
{
Error($"Compilataion library resolved to non existent path {resolvedPath}");
@@ -55,8 +56,10 @@ namespace Microsoft.Extensions.DependencyModel
foreach (var runtimeLibrary in context.RuntimeLibraries)
{
CheckMetadata(runtimeLibrary);
- foreach (var assembly in runtimeLibrary.GetDefaultNativeAssets(context)) {}
- foreach (var native in runtimeLibrary.GetDefaultAssemblyNames(context)) {}
+ foreach (var native in runtimeLibrary.GetDefaultNativeAssets(context)) {}
+ foreach (var assembly in runtimeLibrary.GetDefaultAssemblyNames(context)) {
+ Console.WriteLine($"Runtime {runtimeLibrary.Name}:{assembly.Name}");
+ }
}
foreach (var native in context.GetDefaultNativeAssets()) {}
diff --git a/TestAssets/TestProjects/DependencyContextValidator/DependencyContextValidator/project.json b/TestAssets/TestProjects/DependencyContextValidator/DependencyContextValidator/project.json
index 5501c0f42..c160bb47f 100644
--- a/TestAssets/TestProjects/DependencyContextValidator/DependencyContextValidator/project.json
+++ b/TestAssets/TestProjects/DependencyContextValidator/DependencyContextValidator/project.json
@@ -1,15 +1,19 @@
{
"version": "1.0.0-*",
"dependencies": {
- "NETStandard.Library": "1.5.0-rc2-23931",
"Microsoft.Extensions.DependencyModel": {
"target": "project",
"version": "1.0.0-*"
}
},
"frameworks": {
- "netstandardapp1.5": {
- "imports": "dnxcore50"
+ "netstandard1.5": {
+ "imports": "dnxcore50",
+ "dependencies": {
+ "NETStandard.Library": "1.5.0-rc2-23931",
+ }
+ },
+ "net451": {
}
}
}
diff --git a/TestAssets/TestProjects/DependencyContextValidator/TestAppFullClr/.noautobuild b/TestAssets/TestProjects/DependencyContextValidator/TestAppFullClr/.noautobuild
new file mode 100644
index 000000000..e69de29bb
diff --git a/TestAssets/TestProjects/DependencyContextValidator/TestAppFullClr/Program.cs b/TestAssets/TestProjects/DependencyContextValidator/TestAppFullClr/Program.cs
new file mode 100644
index 000000000..28b8f8435
--- /dev/null
+++ b/TestAssets/TestProjects/DependencyContextValidator/TestAppFullClr/Program.cs
@@ -0,0 +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.Diagnostics;
+
+namespace TestApp
+{
+ public class Program
+ {
+ public static void Main(string[] args)
+ {
+ Microsoft.Extensions.DependencyModel.DependencyContextValidator.Validate(true);
+ }
+ }
+}
diff --git a/TestAssets/TestProjects/DependencyContextValidator/TestAppFullClr/project.json b/TestAssets/TestProjects/DependencyContextValidator/TestAppFullClr/project.json
new file mode 100644
index 000000000..c5331b23d
--- /dev/null
+++ b/TestAssets/TestProjects/DependencyContextValidator/TestAppFullClr/project.json
@@ -0,0 +1,14 @@
+{
+ "version": "1.0.0-*",
+ "compilationOptions": {
+ "emitEntryPoint": true,
+ "preserveCompilationContext": true
+ },
+ "dependencies": {
+ "DependencyContextValidator": "1.0.0-*"
+ },
+ "frameworks": {
+ "net451": {
+ }
+ }
+}
diff --git a/TestAssets/TestProjects/DependencyContextValidator/TestAppPortable/.noautobuild b/TestAssets/TestProjects/DependencyContextValidator/TestAppPortable/.noautobuild
new file mode 100644
index 000000000..e69de29bb
diff --git a/TestAssets/TestProjects/DependencyContextValidator/TestAppPortable/Program.cs b/TestAssets/TestProjects/DependencyContextValidator/TestAppPortable/Program.cs
new file mode 100644
index 000000000..28b8f8435
--- /dev/null
+++ b/TestAssets/TestProjects/DependencyContextValidator/TestAppPortable/Program.cs
@@ -0,0 +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.Diagnostics;
+
+namespace TestApp
+{
+ public class Program
+ {
+ public static void Main(string[] args)
+ {
+ Microsoft.Extensions.DependencyModel.DependencyContextValidator.Validate(true);
+ }
+ }
+}
diff --git a/TestAssets/TestProjects/DependencyContextValidator/TestAppPortable/project.json b/TestAssets/TestProjects/DependencyContextValidator/TestAppPortable/project.json
new file mode 100644
index 000000000..f3fc18046
--- /dev/null
+++ b/TestAssets/TestProjects/DependencyContextValidator/TestAppPortable/project.json
@@ -0,0 +1,19 @@
+{
+ "version": "1.0.0-*",
+ "compilationOptions": {
+ "emitEntryPoint": true,
+ "preserveCompilationContext": true
+ },
+ "dependencies": {
+ "Microsoft.NETCore.App": {
+ "type": "platform",
+ "version": "1.0.0-rc2-23931"
+ },
+ "DependencyContextValidator": "1.0.0-*"
+ },
+ "frameworks": {
+ "netstandard1.5": {
+ "imports" : "dnxcore50"
+ }
+ }
+}
diff --git a/TestAssets/TestProjects/DependencyContextValidator/TestAppPortableDeps/.noautobuild b/TestAssets/TestProjects/DependencyContextValidator/TestAppPortableDeps/.noautobuild
new file mode 100644
index 000000000..e69de29bb
diff --git a/TestAssets/TestProjects/DependencyContextValidator/TestAppPortableDeps/Program.cs b/TestAssets/TestProjects/DependencyContextValidator/TestAppPortableDeps/Program.cs
new file mode 100644
index 000000000..28b8f8435
--- /dev/null
+++ b/TestAssets/TestProjects/DependencyContextValidator/TestAppPortableDeps/Program.cs
@@ -0,0 +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.Diagnostics;
+
+namespace TestApp
+{
+ public class Program
+ {
+ public static void Main(string[] args)
+ {
+ Microsoft.Extensions.DependencyModel.DependencyContextValidator.Validate(true);
+ }
+ }
+}
diff --git a/TestAssets/TestProjects/DependencyContextValidator/TestAppPortableDeps/project.json b/TestAssets/TestProjects/DependencyContextValidator/TestAppPortableDeps/project.json
new file mode 100644
index 000000000..2036c6d1a
--- /dev/null
+++ b/TestAssets/TestProjects/DependencyContextValidator/TestAppPortableDeps/project.json
@@ -0,0 +1,18 @@
+{
+ "version": "1.0.0-*",
+ "compilationOptions": {
+ "emitEntryPoint": true,
+ },
+ "dependencies": {
+ "Microsoft.NETCore.App": {
+ "type": "platform",
+ "version": "1.0.0-rc2-23931"
+ },
+ "DependencyContextValidator": "1.0.0-*"
+ },
+ "frameworks": {
+ "netstandard1.5": {
+ "imports" : "dnxcore50"
+ }
+ }
+}
diff --git a/TestAssets/TestProjects/PortableTests/PortableAppCompilationContext/.noautobuild b/TestAssets/TestProjects/PortableTests/PortableAppCompilationContext/.noautobuild
new file mode 100644
index 000000000..e69de29bb
diff --git a/TestAssets/TestProjects/PortableTests/PortableAppCompilationContext/Program.cs b/TestAssets/TestProjects/PortableTests/PortableAppCompilationContext/Program.cs
new file mode 100644
index 000000000..fbe8e9b0e
--- /dev/null
+++ b/TestAssets/TestProjects/PortableTests/PortableAppCompilationContext/Program.cs
@@ -0,0 +1,12 @@
+using System;
+
+namespace PortableApp
+{
+ public static class Program
+ {
+ public static void Main(string[] args)
+ {
+ Console.WriteLine("Hello, World!");
+ }
+ }
+}
diff --git a/TestAssets/TestProjects/PortableTests/PortableAppCompilationContext/project.json b/TestAssets/TestProjects/PortableTests/PortableAppCompilationContext/project.json
new file mode 100644
index 000000000..54c2fde9b
--- /dev/null
+++ b/TestAssets/TestProjects/PortableTests/PortableAppCompilationContext/project.json
@@ -0,0 +1,21 @@
+{
+ "compilationOptions": {
+ "emitEntryPoint": true,
+ "preserveCompilationContext": true
+ },
+ "dependencies": {},
+ "frameworks": {
+ "netstandard1.5": {
+ "imports": [
+ "dnxcore50",
+ "portable-net45+win8"
+ ],
+ "dependencies": {
+ "Microsoft.NETCore.App": {
+ "type": "platform",
+ "version": "1.0.0-rc2-23931"
+ }
+ }
+ }
+ }
+}
diff --git a/packaging/windows/clisdk/bundle.wxs b/packaging/windows/clisdk/bundle.wxs
index ffa1ca597..cfd89df67 100644
--- a/packaging/windows/clisdk/bundle.wxs
+++ b/packaging/windows/clisdk/bundle.wxs
@@ -4,6 +4,7 @@
xmlns:swid="http://schemas.microsoft.com/wix/TagExtension"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
+
+
+
+
@@ -45,6 +62,23 @@
+
+
+
diff --git a/packaging/windows/inc/crtvariables.wxi b/packaging/windows/inc/crtvariables.wxi
new file mode 100644
index 000000000..12263d2bf
--- /dev/null
+++ b/packaging/windows/inc/crtvariables.wxi
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/packaging/windows/sharedframework/bundle.wxs b/packaging/windows/sharedframework/bundle.wxs
index 8c5a9b845..85cb613ff 100644
--- a/packaging/windows/sharedframework/bundle.wxs
+++ b/packaging/windows/sharedframework/bundle.wxs
@@ -4,6 +4,7 @@
xmlns:swid="http://schemas.microsoft.com/wix/TagExtension"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
+
+
+
+
@@ -38,6 +55,23 @@
+
+
+
diff --git a/scripts/dotnet-cli-build/CompileTargets.cs b/scripts/dotnet-cli-build/CompileTargets.cs
index 79fccf0b3..5f9a577c4 100644
--- a/scripts/dotnet-cli-build/CompileTargets.cs
+++ b/scripts/dotnet-cli-build/CompileTargets.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
+using System.Linq;
using System.Runtime.InteropServices;
using Microsoft.DotNet.Cli.Build.Framework;
using Microsoft.Extensions.PlatformAbstractions;
@@ -9,6 +10,8 @@ using static Microsoft.DotNet.Cli.Build.FS;
using static Microsoft.DotNet.Cli.Build.Framework.BuildHelpers;
using System.Text.RegularExpressions;
using System.Reflection.PortableExecutable;
+using Newtonsoft.Json.Linq;
+using Newtonsoft.Json;
namespace Microsoft.DotNet.Cli.Build
{
@@ -243,6 +246,9 @@ namespace Microsoft.DotNet.Cli.Build
outputDir: Dirs.Stage1);
CleanOutputDir(Path.Combine(Dirs.Stage1, "sdk"));
+ FS.CopyRecursive(Dirs.Stage1, Dirs.Stage1Symbols);
+
+ RemovePdbsFromDir(Path.Combine(Dirs.Stage1, "sdk"));
return result;
}
@@ -293,13 +299,23 @@ namespace Microsoft.DotNet.Cli.Build
}
CleanOutputDir(Path.Combine(Dirs.Stage2, "sdk"));
+ FS.CopyRecursive(Dirs.Stage2, Dirs.Stage2Symbols);
+
+ RemovePdbsFromDir(Path.Combine(Dirs.Stage2, "sdk"));
return c.Success();
}
private static void CleanOutputDir(string directory)
{
- FS.RmFilesInDirRecursive(directory, "vbc.exe");
+ foreach (var file in FilesToClean)
+ {
+ FS.RmFilesInDirRecursive(directory, file);
+ }
+ }
+
+ private static void RemovePdbsFromDir(string directory)
+ {
FS.RmFilesInDirRecursive(directory, "*.pdb");
}
@@ -352,6 +368,7 @@ namespace Microsoft.DotNet.Cli.Build
// Rename the .deps file
var destinationDeps = Path.Combine(SharedFrameworkNameAndVersionRoot, $"{SharedFrameworkName}.deps.json");
File.Move(Path.Combine(SharedFrameworkNameAndVersionRoot, "framework.deps.json"), destinationDeps);
+ ChangeEntryPointLibraryName(destinationDeps, null);
// Generate RID fallback graph
string runtimeGraphGeneratorRuntime = null;
@@ -445,7 +462,7 @@ namespace Microsoft.DotNet.Cli.Build
"--output",
outputDir,
"--framework",
- "netstandard1.5")
+ "netstandard1.5")
.Execute()
.EnsureSuccessful();
@@ -468,6 +485,7 @@ namespace Microsoft.DotNet.Cli.Build
File.Delete(Path.Combine(binaryToCorehostifyOutDir, $"{binaryToCorehostify}.exe"));
File.Copy(compilersDeps, Path.Combine(outputDir, binaryToCorehostify + ".deps.json"));
File.Copy(compilersRuntimeConfig, Path.Combine(outputDir, binaryToCorehostify + ".runtimeconfig.json"));
+ ChangeEntryPointLibraryName(Path.Combine(outputDir, binaryToCorehostify + ".deps.json"), binaryToCorehostify);
}
catch (Exception ex)
{
@@ -577,6 +595,42 @@ namespace Microsoft.DotNet.Cli.Build
return c.Success();
}
+ private static void ChangeEntryPointLibraryName(string depsFile, string newName)
+ {
+ JToken deps;
+ using (var file = File.OpenText(depsFile))
+ using (JsonTextReader reader = new JsonTextReader(file))
+ {
+ deps = JObject.ReadFrom(reader);
+ }
+
+ var target = deps["targets"][deps["runtimeTarget"]["name"].Value()];
+ var library = target.Children().First();
+ var version = library.Name.Substring(library.Name.IndexOf('/') + 1);
+ if (newName == null)
+ {
+ library.Remove();
+ }
+ else
+ {
+ library.Replace(new JProperty(newName + '/' + version, library.Value));
+ }
+ library = deps["libraries"].Children().First();
+ if (newName == null)
+ {
+ library.Remove();
+ }
+ else
+ {
+ library.Replace(new JProperty(newName + '/' + version, library.Value));
+ }
+ using (var file = File.CreateText(depsFile))
+ using (var writer = new JsonTextWriter(file) { Formatting = Formatting.Indented})
+ {
+ deps.WriteTo(writer);
+ }
+ }
+
private static void DeleteMainPublishOutput(string path, string name)
{
File.Delete(Path.Combine(path, $"{name}{Constants.ExeSuffix}"));
diff --git a/scripts/dotnet-cli-build/MsiTargets.cs b/scripts/dotnet-cli-build/MsiTargets.cs
index 06214fc8c..aa5156be0 100644
--- a/scripts/dotnet-cli-build/MsiTargets.cs
+++ b/scripts/dotnet-cli-build/MsiTargets.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
+using System.Net.Http;
using System.Runtime.InteropServices;
using Microsoft.DotNet.Cli.Build.Framework;
using Microsoft.Extensions.PlatformAbstractions;
@@ -14,11 +15,13 @@ namespace Microsoft.DotNet.Cli.Build
{
private const string ENGINE = "engine.exe";
+ private const string WixVersion = "3.10.2";
+
private static string WixRoot
{
get
{
- return Path.Combine(Dirs.Output, "WixTools");
+ return Path.Combine(Dirs.Output, $"WixTools.{WixVersion}");
}
}
@@ -54,14 +57,24 @@ namespace Microsoft.DotNet.Cli.Build
Directory.CreateDirectory(WixRoot);
c.Info("Downloading WixTools..");
- // Download Wix version 3.10.2 - https://wix.codeplex.com/releases/view/619491
- Cmd("powershell", "-NoProfile", "-NoLogo",
- $"Invoke-WebRequest -Uri https://wix.codeplex.com/downloads/get/1540241 -Method Get -OutFile {WixRoot}\\WixTools.zip")
- .Execute()
- .EnsureSuccessful();
+
+ DownloadFile($"https://dotnetcli.blob.core.windows.net/build/wix/wix.{WixVersion}.zip", Path.Combine(WixRoot, "WixTools.zip"));
c.Info("Extracting WixTools..");
- ZipFile.ExtractToDirectory($"{WixRoot}\\WixTools.zip", WixRoot);
+ ZipFile.ExtractToDirectory(Path.Combine(WixRoot, "WixTools.zip"), WixRoot);
+ }
+
+ private static void DownloadFile(string uri, string destinationPath)
+ {
+ using (var httpClient = new HttpClient())
+ {
+ var getTask = httpClient.GetStreamAsync(uri);
+
+ using (var outStream = File.OpenWrite(destinationPath))
+ {
+ getTask.Result.CopyTo(outStream);
+ }
+ }
}
[Target]
diff --git a/scripts/dotnet-cli-build/PackageTargets.cs b/scripts/dotnet-cli-build/PackageTargets.cs
index 40bc5e3bc..75ba0fb3d 100644
--- a/scripts/dotnet-cli-build/PackageTargets.cs
+++ b/scripts/dotnet-cli-build/PackageTargets.cs
@@ -175,6 +175,8 @@ namespace Microsoft.DotNet.Cli.Build
CreateZipFromDirectory(c.BuildContext.Get("CombinedFrameworkSDKHostRoot"), c.BuildContext.Get("CombinedFrameworkSDKHostCompressedFile"));
CreateZipFromDirectory(c.BuildContext.Get("CombinedFrameworkHostRoot"), c.BuildContext.Get("CombinedFrameworkHostCompressedFile"));
+ CreateZipFromDirectory(Path.Combine(Dirs.Stage2Symbols, "sdk"), c.BuildContext.Get("SdkSymbolsCompressedFile"));
+
return c.Success();
}
@@ -185,6 +187,8 @@ namespace Microsoft.DotNet.Cli.Build
CreateTarBallFromDirectory(c.BuildContext.Get("CombinedFrameworkSDKHostRoot"), c.BuildContext.Get("CombinedFrameworkSDKHostCompressedFile"));
CreateTarBallFromDirectory(c.BuildContext.Get("CombinedFrameworkHostRoot"), c.BuildContext.Get("CombinedFrameworkHostCompressedFile"));
+ CreateTarBallFromDirectory(Path.Combine(Dirs.Stage2Symbols, "sdk"), c.BuildContext.Get("SdkSymbolsCompressedFile"));
+
return c.Success();
}
diff --git a/scripts/dotnet-cli-build/PrepareTargets.cs b/scripts/dotnet-cli-build/PrepareTargets.cs
index ac44561eb..778bda8b4 100644
--- a/scripts/dotnet-cli-build/PrepareTargets.cs
+++ b/scripts/dotnet-cli-build/PrepareTargets.cs
@@ -130,6 +130,7 @@ namespace Microsoft.DotNet.Cli.Build
AddInstallerArtifactToContext(c, "dotnet-sharedframework", "SharedFramework", sharedFrameworkVersion);
AddInstallerArtifactToContext(c, "dotnet-dev", "CombinedFrameworkSDKHost", cliVersion);
AddInstallerArtifactToContext(c, "dotnet", "CombinedFrameworkHost", sharedFrameworkVersion);
+ AddInstallerArtifactToContext(c, "dotnet-sdk-debug", "SdkSymbols", cliVersion);
return c.Success();
}
@@ -205,8 +206,8 @@ namespace Microsoft.DotNet.Cli.Build
{
var dotnet = DotNetCli.Stage0;
- dotnet.Restore("--verbosity", "verbose").WorkingDirectory(Path.Combine(c.BuildContext.BuildDirectory, "src")).Execute().EnsureSuccessful();
- dotnet.Restore("--verbosity", "verbose", "--infer-runtimes").WorkingDirectory(Path.Combine(c.BuildContext.BuildDirectory, "tools")).Execute().EnsureSuccessful();
+ dotnet.Restore("--verbosity", "verbose", "--disable-parallel", "--infer-runtimes").WorkingDirectory(Path.Combine(c.BuildContext.BuildDirectory, "src")).Execute().EnsureSuccessful();
+ dotnet.Restore("--verbosity", "verbose", "--disable-parallel", "--infer-runtimes").WorkingDirectory(Path.Combine(c.BuildContext.BuildDirectory, "tools")).Execute().EnsureSuccessful();
return c.Success();
}
diff --git a/scripts/dotnet-cli-build/PublishTargets.cs b/scripts/dotnet-cli-build/PublishTargets.cs
index 10f4bb6a7..8ed4997a3 100644
--- a/scripts/dotnet-cli-build/PublishTargets.cs
+++ b/scripts/dotnet-cli-build/PublishTargets.cs
@@ -68,7 +68,8 @@ namespace Microsoft.DotNet.Cli.Build
[Target(
nameof(PublishTargets.PublishCombinedHostFrameworkArchiveToAzure),
- nameof(PublishTargets.PublishCombinedHostFrameworkSdkArchiveToAzure))]
+ nameof(PublishTargets.PublishCombinedHostFrameworkSdkArchiveToAzure),
+ nameof(PublishTargets.PublishSDKSymbolsArchiveToAzure))]
public static BuildTargetResult PublishArchivesToAzure(BuildTargetContext c) => c.Success();
[Target(
@@ -176,6 +177,17 @@ namespace Microsoft.DotNet.Cli.Build
return c.Success();
}
+ [Target]
+ public static BuildTargetResult PublishSDKSymbolsArchiveToAzure(BuildTargetContext c)
+ {
+ var version = CliNuGetVersion;
+ var archiveFile = c.BuildContext.Get("SdkSymbolsCompressedFile");
+
+ AzurePublisherTool.PublishArchiveAndLatest(archiveFile, Channel, version);
+
+ return c.Success();
+ }
+
[Target]
public static BuildTargetResult PublishCombinedHostFrameworkArchiveToAzure(BuildTargetContext c)
{
diff --git a/scripts/dotnet-cli-build/Utils/Dirs.cs b/scripts/dotnet-cli-build/Utils/Dirs.cs
index 62ebe8f73..cec5db1cb 100644
--- a/scripts/dotnet-cli-build/Utils/Dirs.cs
+++ b/scripts/dotnet-cli-build/Utils/Dirs.cs
@@ -17,8 +17,10 @@ namespace Microsoft.DotNet.Cli.Build
public static readonly string Packages = Path.Combine(Output, "packages");
public static readonly string Stage1 = Path.Combine(Output, "stage1");
public static readonly string Stage1Compilation = Path.Combine(Output, "stage1compilation");
+ public static readonly string Stage1Symbols = Path.Combine(Output, "stage1symbols");
public static readonly string Stage2 = Path.Combine(Output, "stage2");
public static readonly string Stage2Compilation = Path.Combine(Output, "stage2compilation");
+ public static readonly string Stage2Symbols = Path.Combine(Output, "stage2symbols");
public static readonly string Corehost = Path.Combine(Output, "corehost");
public static readonly string TestOutput = Path.Combine(Output, "tests");
public static readonly string TestArtifacts = Path.Combine(TestOutput, "artifacts");
diff --git a/scripts/dotnet-cli-build/Utils/FS.cs b/scripts/dotnet-cli-build/Utils/FS.cs
index d425c7ce2..80cddcff2 100644
--- a/scripts/dotnet-cli-build/Utils/FS.cs
+++ b/scripts/dotnet-cli-build/Utils/FS.cs
@@ -111,7 +111,7 @@ namespace Microsoft.DotNet.Cli.Build
if (string.Equals(Path.GetFileName(candidate), "bin") ||
string.Equals(Path.GetFileName(candidate), "obj"))
{
- Directory.Delete(candidate, recursive: true);
+ Utils.DeleteDirectory(candidate);
}
else
{
diff --git a/scripts/dotnet-cli-build/Utils/Utils.cs b/scripts/dotnet-cli-build/Utils/Utils.cs
index bd7e5ad71..799bda56f 100644
--- a/scripts/dotnet-cli-build/Utils/Utils.cs
+++ b/scripts/dotnet-cli-build/Utils/Utils.cs
@@ -96,8 +96,24 @@ namespace Microsoft.DotNet.Cli.Build
File.SetAttributes(file, FileAttributes.Normal);
File.Delete(file);
}
- System.Threading.Thread.Sleep(1);
- Directory.Delete(path, true);
+ var retry = 5;
+ while (retry >= 0)
+ {
+ try
+ {
+ Directory.Delete(path, true);
+ return;
+ }
+ catch (IOException ex)
+ {
+ if (retry == 0)
+ {
+ throw;
+ }
+ System.Threading.Thread.Sleep(200);
+ retry--;
+ }
+ }
}
}
diff --git a/scripts/update-dependencies/BuildContextProperties.cs b/scripts/update-dependencies/BuildContextProperties.cs
new file mode 100644
index 000000000..6cd488398
--- /dev/null
+++ b/scripts/update-dependencies/BuildContextProperties.cs
@@ -0,0 +1,30 @@
+// 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.Cli.Build.Framework;
+
+namespace Microsoft.DotNet.Scripts
+{
+ public static class BuildContextProperties
+ {
+ public static List GetDependencyInfos(this BuildTargetContext c)
+ {
+ const string propertyName = "DependencyInfos";
+
+ List dependencyInfos;
+ object dependencyInfosObj;
+ if (c.BuildContext.Properties.TryGetValue(propertyName, out dependencyInfosObj))
+ {
+ dependencyInfos = (List)dependencyInfosObj;
+ }
+ else
+ {
+ dependencyInfos = new List();
+ c.BuildContext[propertyName] = dependencyInfos;
+ }
+
+ return dependencyInfos;
+ }
+ }
+}
diff --git a/scripts/update-dependencies/Config.cs b/scripts/update-dependencies/Config.cs
index c0e446ec3..7772bba52 100644
--- a/scripts/update-dependencies/Config.cs
+++ b/scripts/update-dependencies/Config.cs
@@ -23,6 +23,7 @@ namespace Microsoft.DotNet.Scripts
/// GITHUB_UPSTREAM_OWNER - The owner of the GitHub base repo to create the PR to. (ex. "dotnet")
/// GITHUB_PROJECT - The repo name under the ORIGIN and UPSTREAM owners. (ex. "cli")
/// GITHUB_UPSTREAM_BRANCH - The branch in the GitHub base repo to create the PR to. (ex. "rel/1.0.0")
+ /// GITHUB_PULL_REQUEST_NOTIFICATIONS - A semi-colon ';' separated list of GitHub users to notify on the PR.
///
public class Config
{
@@ -36,6 +37,7 @@ namespace Microsoft.DotNet.Scripts
public string GitHubUpstreamOwner { get; set; }
public string GitHubProject { get; set; }
public string GitHubUpstreamBranch { get; set; }
+ public string[] GitHubPullRequestNotifications { get; set; }
private static Config Read()
{
@@ -52,18 +54,20 @@ namespace Microsoft.DotNet.Scripts
GitHubUpstreamOwner = GetEnvironmentVariable("GITHUB_UPSTREAM_OWNER", "dotnet"),
GitHubProject = GetEnvironmentVariable("GITHUB_PROJECT", "cli"),
GitHubUpstreamBranch = GetEnvironmentVariable("GITHUB_UPSTREAM_BRANCH", "rel/1.0.0"),
+ GitHubPullRequestNotifications = GetEnvironmentVariable("GITHUB_PULL_REQUEST_NOTIFICATIONS", "")
+ .Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)
};
}
private static string GetEnvironmentVariable(string name, string defaultValue = null)
{
string value = Environment.GetEnvironmentVariable(name);
- if (string.IsNullOrEmpty(value))
+ if (value == null)
{
value = defaultValue;
}
- if (string.IsNullOrEmpty(value))
+ if (value == null)
{
throw new BuildFailureException($"Can't find environment variable '{name}'.");
}
diff --git a/scripts/update-dependencies/DependencyInfo.cs b/scripts/update-dependencies/DependencyInfo.cs
new file mode 100644
index 000000000..68cf4f45d
--- /dev/null
+++ b/scripts/update-dependencies/DependencyInfo.cs
@@ -0,0 +1,15 @@
+// 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.
+
+namespace Microsoft.DotNet.Scripts
+{
+ public class DependencyInfo
+ {
+ public string Name { get; set; }
+ public string IdPattern { get; set; }
+ public string IdExclusionPattern { get; set; }
+ public string NewReleaseVersion { get; set; }
+
+ public bool IsUpdated { get; set; }
+ }
+}
diff --git a/scripts/update-dependencies/PushPRTargets.cs b/scripts/update-dependencies/PushPRTargets.cs
index 4d9ca44c1..2d989a79e 100644
--- a/scripts/update-dependencies/PushPRTargets.cs
+++ b/scripts/update-dependencies/PushPRTargets.cs
@@ -2,6 +2,7 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
+using System.Linq;
using Microsoft.DotNet.Cli.Build.Framework;
using Octokit;
@@ -14,8 +15,6 @@ namespace Microsoft.DotNet.Scripts
///
public static class PushPRTargets
{
- private const string PullRequestTitle = "Updating dependencies from last known good builds";
-
private static readonly Config s_config = Config.Instance;
[Target(nameof(CommitChanges), nameof(CreatePR))]
@@ -28,14 +27,31 @@ namespace Microsoft.DotNet.Scripts
[Target]
public static BuildTargetResult CommitChanges(BuildTargetContext c)
{
- Cmd("git", "add", ".")
- .Execute()
- .EnsureSuccessful();
+ CommandResult statusResult = Cmd("git", "status", "--porcelain")
+ .CaptureStdOut()
+ .Execute();
+ statusResult.EnsureSuccessful();
+
+ bool hasModifiedFiles = !string.IsNullOrWhiteSpace(statusResult.StdOut);
+ bool hasUpdatedDependencies = c.GetDependencyInfos().Where(d => d.IsUpdated).Any();
+
+ if (hasModifiedFiles != hasUpdatedDependencies)
+ {
+ return c.Failed($"'git status' does not match DependencyInfo information. Git has modified files: {hasModifiedFiles}. DependencyInfo is updated: {hasUpdatedDependencies}.");
+ }
+
+ if (!hasUpdatedDependencies)
+ {
+ c.Warn("Dependencies are currently up to date");
+ return c.Success();
+ }
string userName = s_config.UserName;
string email = s_config.Email;
- Cmd("git", "commit", "-m", PullRequestTitle, "--author", $"{userName} <{email}>")
+ string commitMessage = GetCommitMessage(c);
+
+ Cmd("git", "commit", "-a", "-m", commitMessage, "--author", $"{userName} <{email}>")
.EnvironmentVariable("GIT_COMMITTER_NAME", userName)
.EnvironmentVariable("GIT_COMMITTER_EMAIL", email)
.Execute()
@@ -79,12 +95,19 @@ namespace Microsoft.DotNet.Scripts
public static BuildTargetResult CreatePR(BuildTargetContext c)
{
string remoteBranchName = c.GetRemoteBranchName();
+ string commitMessage = c.GetCommitMessage();
NewPullRequest prInfo = new NewPullRequest(
- PullRequestTitle,
+ commitMessage,
s_config.GitHubOriginOwner + ":" + remoteBranchName,
s_config.GitHubUpstreamBranch);
+ string[] prNotifications = s_config.GitHubPullRequestNotifications;
+ if (prNotifications.Length > 0)
+ {
+ prInfo.Body = $"/cc @{string.Join(" @", prNotifications)}";
+ }
+
GitHubClient gitHub = new GitHubClient(new ProductHeaderValue("dotnetDependencyUpdater"));
gitHub.Credentials = new Credentials(s_config.Password);
@@ -104,5 +127,36 @@ namespace Microsoft.DotNet.Scripts
{
c.BuildContext["RemoteBranchName"] = value;
}
+
+ private static string GetCommitMessage(this BuildTargetContext c)
+ {
+ const string commitMessagePropertyName = "CommitMessage";
+
+ string message;
+ object messageObject;
+ if (c.BuildContext.Properties.TryGetValue(commitMessagePropertyName, out messageObject))
+ {
+ message = (string)messageObject;
+ }
+ else
+ {
+ DependencyInfo[] updatedDependencies = c.GetDependencyInfos()
+ .Where(d => d.IsUpdated)
+ .ToArray();
+
+ string updatedDependencyNames = string.Join(", ", updatedDependencies.Select(d => d.Name));
+ string updatedDependencyVersions = string.Join(", ", updatedDependencies.Select(d => d.NewReleaseVersion));
+
+ message = $"Updating {updatedDependencyNames} to {updatedDependencyVersions}";
+ if (updatedDependencies.Count() > 1)
+ {
+ message += " respectively";
+ }
+
+ c.BuildContext[commitMessagePropertyName] = message;
+ }
+
+ return message;
+ }
}
}
diff --git a/scripts/update-dependencies/UpdateFilesTargets.cs b/scripts/update-dependencies/UpdateFilesTargets.cs
index 31527ce59..cc4f75bc5 100644
--- a/scripts/update-dependencies/UpdateFilesTargets.cs
+++ b/scripts/update-dependencies/UpdateFilesTargets.cs
@@ -34,7 +34,7 @@ namespace Microsoft.DotNet.Scripts
const string coreFxIdPattern = @"^(?i)((System\..*)|(NETStandard\.Library)|(Microsoft\.CSharp)|(Microsoft\.NETCore.*)|(Microsoft\.TargetingPack\.Private\.(CoreCLR|NETNative))|(Microsoft\.Win32\..*)|(Microsoft\.VisualBasic))$";
const string coreFxIdExclusionPattern = @"System.CommandLine";
- List dependencyInfos = c.GetDependencyInfo();
+ List dependencyInfos = c.GetDependencyInfos();
dependencyInfos.Add(new DependencyInfo()
{
Name = "CoreFx",
@@ -46,26 +46,7 @@ namespace Microsoft.DotNet.Scripts
return c.Success();
}
- private static List GetDependencyInfo(this BuildTargetContext c)
- {
- const string propertyName = "DependencyInfo";
-
- List dependencyInfos;
- object dependencyInfosObj;
- if (c.BuildContext.Properties.TryGetValue(propertyName, out dependencyInfosObj))
- {
- dependencyInfos = (List)dependencyInfosObj;
- }
- else
- {
- dependencyInfos = new List();
- c.BuildContext[propertyName] = dependencyInfos;
- }
-
- return dependencyInfos;
- }
-
- [Target(nameof(ReplaceProjectJson), nameof(ReplaceCrossGen))]
+ [Target(nameof(ReplaceProjectJson), nameof(ReplaceCrossGen), nameof(ReplaceCoreHostPackaging))]
public static BuildTargetResult ReplaceVersions(BuildTargetContext c) => c.Success();
///
@@ -74,7 +55,7 @@ namespace Microsoft.DotNet.Scripts
[Target]
public static BuildTargetResult ReplaceProjectJson(BuildTargetContext c)
{
- List dependencyInfos = c.GetDependencyInfo();
+ List dependencyInfos = c.GetDependencyInfos();
IEnumerable projectJsonFiles = Enumerable.Union(
Directory.GetFiles(Dirs.RepoRoot, "project.json", SearchOption.AllDirectories),
@@ -157,6 +138,9 @@ namespace Microsoft.DotNet.Scripts
dependencyProperty.Value = newVersion;
}
+ // mark the DependencyInfo as updated so we can tell which dependencies were updated
+ dependencyInfo.IsUpdated = true;
+
return true;
}
}
@@ -194,40 +178,68 @@ namespace Microsoft.DotNet.Scripts
.SelectMany(o => o.Children());
}
- private class DependencyInfo
- {
- public string Name { get; set; }
- public string IdPattern { get; set; }
- public string IdExclusionPattern { get; set; }
- public string NewReleaseVersion { get; set; }
- }
-
///
/// Replaces version number that is hard-coded in the CrossGen script.
///
[Target]
public static BuildTargetResult ReplaceCrossGen(BuildTargetContext c)
{
- DependencyInfo coreFXInfo = c.GetDependencyInfo().Single(d => d.Name == "CoreFx");
-
- string compileTargetsPath = Path.Combine(Dirs.RepoRoot, @"scripts\dotnet-cli-build\CompileTargets.cs");
- string compileTargetsContent = File.ReadAllText(compileTargetsPath);
-
- Regex regex = new Regex(@"CoreCLRVersion = ""(?\d.\d.\d)-(?.*)"";");
- compileTargetsContent = regex.Replace(compileTargetsContent, m =>
+ ReplaceFileContents(@"scripts\dotnet-cli-build\CompileTargets.cs", compileTargetsContent =>
{
- string replacedValue = m.Value;
- Group releaseGroup = m.Groups["release"];
+ DependencyInfo coreFXInfo = c.GetCoreFXDependency();
+ Regex regex = new Regex(@"CoreCLRVersion = ""(?\d.\d.\d)-(?.*)"";");
- replacedValue = replacedValue.Remove(releaseGroup.Index - m.Index, releaseGroup.Length);
- replacedValue = replacedValue.Insert(releaseGroup.Index - m.Index, coreFXInfo.NewReleaseVersion);
-
- return replacedValue;
+ return regex.ReplaceGroupValue(compileTargetsContent, "release", coreFXInfo.NewReleaseVersion);
});
- File.WriteAllText(compileTargetsPath, compileTargetsContent, Encoding.UTF8);
-
return c.Success();
}
+
+ ///
+ /// Replaces version number that is hard-coded in the corehost packaging dir.props file.
+ ///
+ [Target]
+ public static BuildTargetResult ReplaceCoreHostPackaging(BuildTargetContext c)
+ {
+ ReplaceFileContents(@"src\corehost\packaging\dir.props", contents =>
+ {
+ DependencyInfo coreFXInfo = c.GetCoreFXDependency();
+ Regex regex = new Regex(@"Microsoft\.NETCore\.Platforms\\(?\d\.\d\.\d)-(?.*)\\runtime\.json");
+
+ return regex.ReplaceGroupValue(contents, "release", coreFXInfo.NewReleaseVersion);
+ });
+
+ return c.Success();
+ }
+
+ private static DependencyInfo GetCoreFXDependency(this BuildTargetContext c)
+ {
+ return c.GetDependencyInfos().Single(d => d.Name == "CoreFx");
+ }
+
+ private static void ReplaceFileContents(string repoRelativePath, Func replacement)
+ {
+ string fullPath = Path.Combine(Dirs.RepoRoot, repoRelativePath);
+ string contents = File.ReadAllText(fullPath);
+
+ contents = replacement(contents);
+
+ File.WriteAllText(fullPath, contents, Encoding.UTF8);
+ }
+
+ private static string ReplaceGroupValue(this Regex regex, string input, string groupName, string newValue)
+ {
+ return regex.Replace(input, m =>
+ {
+ string replacedValue = m.Value;
+ Group group = m.Groups[groupName];
+ int startIndex = group.Index - m.Index;
+
+ replacedValue = replacedValue.Remove(startIndex, group.Length);
+ replacedValue = replacedValue.Insert(startIndex, newValue);
+
+ return replacedValue;
+ });
+ }
}
}
diff --git a/scripts/update-dependencies/project.json b/scripts/update-dependencies/project.json
index 1a2b48caf..63e87a442 100644
--- a/scripts/update-dependencies/project.json
+++ b/scripts/update-dependencies/project.json
@@ -9,7 +9,7 @@
"Microsoft.CSharp": "4.0.1-rc2-23931",
"System.Runtime.Serialization.Primitives": "4.1.1-rc2-23931",
"Microsoft.DotNet.Cli.Build.Framework": "1.0.0-*",
- "NuGet.Versioning": "3.5.0-beta-1123",
+ "NuGet.Versioning": "3.5.0-beta-1130",
"Newtonsoft.Json": "7.0.1",
"Octokit": "0.18.0",
"Microsoft.Net.Http": "2.2.29"
diff --git a/src/Microsoft.DotNet.Cli.Utils/project.json b/src/Microsoft.DotNet.Cli.Utils/project.json
index 6519d4aa7..07a1fd577 100644
--- a/src/Microsoft.DotNet.Cli.Utils/project.json
+++ b/src/Microsoft.DotNet.Cli.Utils/project.json
@@ -7,10 +7,10 @@
"dependencies": {
"Microsoft.DotNet.ProjectModel": "1.0.0-*",
"Microsoft.Extensions.PlatformAbstractions": "1.0.0-rc2-20100",
- "NuGet.Versioning": "3.5.0-beta-1123",
- "NuGet.Packaging": "3.5.0-beta-1123",
- "NuGet.Frameworks": "3.5.0-beta-1123",
- "NuGet.ProjectModel": "3.5.0-beta-1123"
+ "NuGet.Versioning": "3.5.0-beta-1130",
+ "NuGet.Packaging": "3.5.0-beta-1130",
+ "NuGet.Frameworks": "3.5.0-beta-1130",
+ "NuGet.ProjectModel": "3.5.0-beta-1130"
},
"frameworks": {
"net451": {
diff --git a/src/Microsoft.DotNet.ProjectModel/Compilation/LibraryExporter.cs b/src/Microsoft.DotNet.ProjectModel/Compilation/LibraryExporter.cs
index ce43b4b0b..8fc68ba34 100644
--- a/src/Microsoft.DotNet.ProjectModel/Compilation/LibraryExporter.cs
+++ b/src/Microsoft.DotNet.ProjectModel/Compilation/LibraryExporter.cs
@@ -424,7 +424,7 @@ namespace Microsoft.DotNet.ProjectModel.Compilation
private IEnumerable PopulateAssets(TargetLibraryWithAssets library, IEnumerable section)
{
- foreach (var assemblyPath in section)
+ foreach (var assemblyPath in section.Where(a => !PackageDependencyProvider.IsPlaceholderFile(a.Path)))
{
yield return LibraryAsset.CreateFromRelativePath(library.Path, assemblyPath.Path);
}
diff --git a/src/Microsoft.DotNet.ProjectModel/Project.cs b/src/Microsoft.DotNet.ProjectModel/Project.cs
index 2df027c5b..9e1c26437 100644
--- a/src/Microsoft.DotNet.ProjectModel/Project.cs
+++ b/src/Microsoft.DotNet.ProjectModel/Project.cs
@@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.IO;
+using System.Linq;
using Microsoft.DotNet.ProjectModel.Files;
using Microsoft.DotNet.ProjectModel.Graph;
using NuGet.Frameworks;
@@ -91,7 +92,7 @@ namespace Microsoft.DotNet.ProjectModel
public string RawRuntimeOptions { get; set; }
public bool IsTestProject => !string.IsNullOrEmpty(TestRunner);
-
+
public IEnumerable GetTargetFrameworks()
{
return _targetFrameworks.Values;
diff --git a/src/Microsoft.DotNet.ProjectModel/ProjectContext.cs b/src/Microsoft.DotNet.ProjectModel/ProjectContext.cs
index 7fe2e7622..b64c0dcef 100644
--- a/src/Microsoft.DotNet.ProjectModel/ProjectContext.cs
+++ b/src/Microsoft.DotNet.ProjectModel/ProjectContext.cs
@@ -145,11 +145,8 @@ namespace Microsoft.DotNet.ProjectModel
{
return this;
}
-
- // Check if there are any runtime targets (i.e. are we portable)
- var standalone = LockFile.Targets
- .Where(t => t.TargetFramework.Equals(TargetFramework))
- .Any(t => !string.IsNullOrEmpty(t.RuntimeIdentifier));
+
+ var standalone = !ProjectFile.Dependencies.Any(d => d.Type.Equals(LibraryDependencyType.Platform));
var context = CreateBuilder(ProjectFile.ProjectFilePath, TargetFramework)
.WithRuntimeIdentifiers(standalone ? runtimeIdentifiers : Enumerable.Empty())
diff --git a/src/Microsoft.DotNet.ProjectModel/project.json b/src/Microsoft.DotNet.ProjectModel/project.json
index 8bcb9120e..125830412 100644
--- a/src/Microsoft.DotNet.ProjectModel/project.json
+++ b/src/Microsoft.DotNet.ProjectModel/project.json
@@ -6,7 +6,7 @@
"description": "Types to model a .NET Project",
"dependencies": {
"System.Reflection.Metadata": "1.3.0-rc2-23931",
- "NuGet.Packaging": "3.5.0-beta-1123",
+ "NuGet.Packaging": "3.5.0-beta-1130",
"Microsoft.Extensions.FileSystemGlobbing": "1.0.0-rc2-15996",
"Microsoft.Extensions.JsonParser.Sources": {
"type": "build",
@@ -32,9 +32,6 @@
"System.IO": {
"type": "build"
}
- },
- "dependencies": {
- "System.Linq": "4.0.1-rc3-23727"
}
},
"netstandard1.5": {
diff --git a/src/Microsoft.Extensions.DependencyModel/DependencyContextExtensions.cs b/src/Microsoft.Extensions.DependencyModel/DependencyContextExtensions.cs
index fd0e7ed39..59f73ea61 100644
--- a/src/Microsoft.Extensions.DependencyModel/DependencyContextExtensions.cs
+++ b/src/Microsoft.Extensions.DependencyModel/DependencyContextExtensions.cs
@@ -12,41 +12,101 @@ namespace Microsoft.Extensions.DependencyModel
public static IEnumerable GetDefaultNativeAssets(this DependencyContext self)
{
+ if (self == null)
+ {
+ throw new ArgumentNullException(nameof(self));
+ }
return self.RuntimeLibraries.SelectMany(library => library.GetDefaultNativeAssets(self));
}
public static IEnumerable GetRuntimeNativeAssets(this DependencyContext self, string runtimeIdentifier)
{
+ if (self == null)
+ {
+ throw new ArgumentNullException(nameof(self));
+ }
+ if (runtimeIdentifier == null)
+ {
+ throw new ArgumentNullException(nameof(runtimeIdentifier));
+ }
return self.RuntimeLibraries.SelectMany(library => library.GetRuntimeNativeAssets(self, runtimeIdentifier));
}
public static IEnumerable GetDefaultNativeAssets(this RuntimeLibrary self, DependencyContext context)
{
+ if (self == null)
+ {
+ throw new ArgumentNullException(nameof(self));
+ }
return ResolveAssets(context, string.Empty, self.NativeLibraryGroups);
}
public static IEnumerable GetRuntimeNativeAssets(this RuntimeLibrary self, DependencyContext context, string runtimeIdentifier)
{
+ if (self == null)
+ {
+ throw new ArgumentNullException(nameof(self));
+ }
+ if (context == null)
+ {
+ throw new ArgumentNullException(nameof(context));
+ }
+ if (runtimeIdentifier == null)
+ {
+ throw new ArgumentNullException(nameof(runtimeIdentifier));
+ }
return ResolveAssets(context, runtimeIdentifier, self.NativeLibraryGroups);
}
public static IEnumerable GetDefaultAssemblyNames(this DependencyContext self)
{
+ if (self == null)
+ {
+ throw new ArgumentNullException(nameof(self));
+ }
return self.RuntimeLibraries.SelectMany(library => library.GetDefaultAssemblyNames(self));
}
public static IEnumerable GetRuntimeAssemblyNames(this DependencyContext self, string runtimeIdentifier)
{
+ if (self == null)
+ {
+ throw new ArgumentNullException(nameof(self));
+ }
+ if (runtimeIdentifier == null)
+ {
+ throw new ArgumentNullException(nameof(runtimeIdentifier));
+ }
return self.RuntimeLibraries.SelectMany(library => library.GetRuntimeAssemblyNames(self, runtimeIdentifier));
}
public static IEnumerable GetDefaultAssemblyNames(this RuntimeLibrary self, DependencyContext context)
{
+ if (self == null)
+ {
+ throw new ArgumentNullException(nameof(self));
+ }
+ if (context == null)
+ {
+ throw new ArgumentNullException(nameof(context));
+ }
return ResolveAssets(context, string.Empty, self.RuntimeAssemblyGroups).Select(GetAssemblyName);
}
public static IEnumerable GetRuntimeAssemblyNames(this RuntimeLibrary self, DependencyContext context, string runtimeIdentifier)
{
+ if (self == null)
+ {
+ throw new ArgumentNullException(nameof(self));
+ }
+ if (context == null)
+ {
+ throw new ArgumentNullException(nameof(context));
+ }
+ if (runtimeIdentifier == null)
+ {
+ throw new ArgumentNullException(nameof(runtimeIdentifier));
+ }
return ResolveAssets(context, runtimeIdentifier, self.RuntimeAssemblyGroups).Select(GetAssemblyName);
}
diff --git a/src/Microsoft.Extensions.DependencyModel/DependencyContextJsonReader.cs b/src/Microsoft.Extensions.DependencyModel/DependencyContextJsonReader.cs
index 13bee633d..57a0573a2 100644
--- a/src/Microsoft.Extensions.DependencyModel/DependencyContextJsonReader.cs
+++ b/src/Microsoft.Extensions.DependencyModel/DependencyContextJsonReader.cs
@@ -141,7 +141,8 @@ namespace Microsoft.Extensions.DependencyModel
}
return new CompilationOptions(
- compilationOptionsObject[DependencyContextStrings.DefinesPropertyName]?.Values() ?? Enumerable.Empty(),
+ compilationOptionsObject[DependencyContextStrings.DefinesPropertyName]?.Values().ToArray() ?? Enumerable.Empty(),
+ // ToArray is here to prevent IEnumerable holding to json object graph
compilationOptionsObject[DependencyContextStrings.LanguageVersionPropertyName]?.Value(),
compilationOptionsObject[DependencyContextStrings.PlatformPropertyName]?.Value(),
compilationOptionsObject[DependencyContextStrings.AllowUnsafePropertyName]?.Value(),
diff --git a/src/dotnet/commands/dotnet-projectmodel-server/Models/DependencyDescription.cs b/src/dotnet/commands/dotnet-projectmodel-server/Models/DependencyDescription.cs
index 07aa58a64..32c3854e5 100644
--- a/src/dotnet/commands/dotnet-projectmodel-server/Models/DependencyDescription.cs
+++ b/src/dotnet/commands/dotnet-projectmodel-server/Models/DependencyDescription.cs
@@ -5,6 +5,7 @@ using System.Collections.Generic;
using System.Linq;
using Microsoft.DotNet.ProjectModel.Compilation;
using Microsoft.DotNet.ProjectModel.Graph;
+using NuGet.Versioning;
namespace Microsoft.DotNet.ProjectModel.Server.Models
{
@@ -23,7 +24,7 @@ namespace Microsoft.DotNet.ProjectModel.Server.Models
public string Type { get; private set; }
public bool Resolved { get; private set; }
-
+
public IEnumerable Dependencies { get; private set; }
public IEnumerable Errors { get; private set; }
@@ -60,7 +61,7 @@ namespace Microsoft.DotNet.ProjectModel.Server.Models
{
Name = library.Identity.Name,
DisplayName = library.Identity.Name,
- Version = library.Identity.Version?.ToNormalizedString(),
+ Version = (library.Identity.Version ?? new NuGetVersion("1.0.0")).ToNormalizedString(),
Type = library.Identity.Type.Value,
Resolved = library.Resolved,
Path = library.Path,
diff --git a/src/dotnet/commands/dotnet-publish/PublishCommand.cs b/src/dotnet/commands/dotnet-publish/PublishCommand.cs
index abe835442..5c42f70e5 100644
--- a/src/dotnet/commands/dotnet-publish/PublishCommand.cs
+++ b/src/dotnet/commands/dotnet-publish/PublishCommand.cs
@@ -131,22 +131,26 @@ namespace Microsoft.DotNet.Tools.Publish
var isPortable = string.IsNullOrEmpty(context.RuntimeIdentifier);
// Collect all exports and organize them
- var exports = exporter.GetAllExports()
+ var packageExports = exporter.GetAllExports()
.Where(e => e.Library.Identity.Type.Equals(LibraryType.Package))
.ToDictionary(e => e.Library.Identity.Name);
- var collectExclusionList = isPortable ? GetExclusionList(context, exports) : new HashSet();
+ var collectExclusionList = isPortable ? GetExclusionList(context, packageExports) : new HashSet();
- foreach (var export in exporter.GetAllExports().Where(e => !collectExclusionList.Contains(e.Library.Identity.Name)))
+ var exports = exporter.GetAllExports();
+ foreach (var export in exports.Where(e => !collectExclusionList.Contains(e.Library.Identity.Name)))
{
Reporter.Verbose.WriteLine($"Publishing {export.Library.Identity.ToString().Green().Bold()} ...");
PublishAssetGroups(export.RuntimeAssemblyGroups, outputPath, nativeSubdirectories: false, includeRuntimeGroups: isPortable);
PublishAssetGroups(export.NativeLibraryGroups, outputPath, nativeSubdirectories, includeRuntimeGroups: isPortable);
export.RuntimeAssets.StructuredCopyTo(outputPath, outputPaths.IntermediateOutputDirectoryPath);
+ }
- if (options.PreserveCompilationContext.GetValueOrDefault())
+ if (options.PreserveCompilationContext.GetValueOrDefault())
+ {
+ foreach (var export in exports)
{
- PublishRefs(export, outputPath);
+ PublishRefs(export, outputPath, !collectExclusionList.Contains(export.Library.Identity.Name));
}
}
@@ -248,19 +252,19 @@ namespace Microsoft.DotNet.Tools.Publish
}
}
- private static void PublishRefs(LibraryExport export, string outputPath)
+ private static void PublishRefs(LibraryExport export, string outputPath, bool deduplicate)
{
var refsPath = Path.Combine(outputPath, "refs");
if (!Directory.Exists(refsPath))
{
Directory.CreateDirectory(refsPath);
}
-
+
// Do not copy compilation assembly if it's in runtime assemblies
var runtimeAssemblies = new HashSet(export.RuntimeAssemblyGroups.GetDefaultAssets());
foreach (var compilationAssembly in export.CompilationAssemblies)
{
- if (!runtimeAssemblies.Contains(compilationAssembly))
+ if (!deduplicate || !runtimeAssemblies.Contains(compilationAssembly))
{
var destFileName = Path.Combine(refsPath, Path.GetFileName(compilationAssembly.ResolvedPath));
File.Copy(compilationAssembly.ResolvedPath, destFileName, overwrite: true);
@@ -358,67 +362,16 @@ namespace Microsoft.DotNet.Tools.Publish
private IEnumerable SelectContexts(string projectPath, NuGetFramework framework, string runtime)
{
- var allContexts = ProjectContext.CreateContextForEachTarget(projectPath).ToList();
- var frameworks = framework == null ?
- allContexts.Select(c => c.TargetFramework).Distinct().ToArray() :
- new[] { framework };
+ var allContexts = framework == null ?
+ ProjectContext.CreateContextForEachFramework(projectPath) :
+ new[] { ProjectContext.Create(projectPath, framework) };
- if (string.IsNullOrEmpty(runtime))
- {
- // For each framework, find the best matching RID item
- var candidates = PlatformServices.Default.Runtime.GetAllCandidateRuntimeIdentifiers();
- return frameworks.Select(f => FindBestTarget(f, allContexts, candidates));
- }
- else
- {
- return frameworks.SelectMany(f => allContexts.Where(c =>
- Equals(c.TargetFramework, f) &&
- string.Equals(c.RuntimeIdentifier, runtime, StringComparison.Ordinal)));
- }
+ var runtimes = !string.IsNullOrEmpty(runtime) ?
+ new [] {runtime} :
+ PlatformServices.Default.Runtime.GetAllCandidateRuntimeIdentifiers();
+ return allContexts.Select(c => c.CreateRuntimeContext(runtimes));
}
-
- private ProjectContext FindBestTarget(NuGetFramework f, List allContexts, IEnumerable candidates)
- {
- foreach (var candidate in candidates)
- {
- var target = allContexts.FirstOrDefault(c =>
- Equals(c.TargetFramework, f) &&
- string.Equals(c.RuntimeIdentifier, candidate, StringComparison.Ordinal));
- if (target != null)
- {
- return target;
- }
- }
-
- // No RID-specific target found, use the RID-less target and publish portable
- return allContexts.FirstOrDefault(c =>
- Equals(c.TargetFramework, f) &&
- string.IsNullOrEmpty(c.RuntimeIdentifier));
- }
-
- ///
- /// Return the matching framework/runtime ProjectContext.
- /// If 'framework' or 'runtimeIdentifier' is null or empty then it matches with any.
- ///
- private static IEnumerable GetMatchingProjectContexts(IEnumerable contexts, NuGetFramework framework, string runtimeIdentifier)
- {
- foreach (var context in contexts)
- {
- if (context.TargetFramework == null || string.IsNullOrEmpty(context.RuntimeIdentifier))
- {
- continue;
- }
-
- if (string.IsNullOrEmpty(runtimeIdentifier) || string.Equals(runtimeIdentifier, context.RuntimeIdentifier, StringComparison.OrdinalIgnoreCase))
- {
- if (framework == null || framework.Equals(context.TargetFramework))
- {
- yield return context;
- }
- }
- }
- }
-
+
private static void CopyContents(ProjectContext context, string outputPath)
{
var contentFiles = context.ProjectFile.Files.GetContentFiles();
diff --git a/src/dotnet/project.json b/src/dotnet/project.json
index b09efdd7b..3878fe1ba 100644
--- a/src/dotnet/project.json
+++ b/src/dotnet/project.json
@@ -17,10 +17,10 @@
],
"dependencies": {
"NuGet.Commands": {
- "version": "3.5.0-beta-1123",
+ "version": "3.5.0-beta-1130",
"exclude": "compile"
},
- "NuGet.CommandLine.XPlat": "3.5.0-beta-1123",
+ "NuGet.CommandLine.XPlat": "3.5.0-beta-1130",
"Newtonsoft.Json": "7.0.1",
"System.Text.Encoding.CodePages": "4.0.1-rc2-23931",
"System.Diagnostics.FileVersionInfo": "4.0.0-rc2-23931",
diff --git a/test/Installer/testmsi.ps1 b/test/Installer/testmsi.ps1
index d1b82f67b..f3d12cdbb 100644
--- a/test/Installer/testmsi.ps1
+++ b/test/Installer/testmsi.ps1
@@ -42,6 +42,7 @@ pushd "$Stage2Dir"
try {
.\dotnet restore `
+ --infer-runtimes `
$testDir `
-f https://www.myget.org/F/dotnet-buildtools/api/v3/index.json | Out-Host
diff --git a/test/Microsoft.DotNet.Cli.Utils.Tests/project.json b/test/Microsoft.DotNet.Cli.Utils.Tests/project.json
index bd59f0d4b..f2613b8aa 100644
--- a/test/Microsoft.DotNet.Cli.Utils.Tests/project.json
+++ b/test/Microsoft.DotNet.Cli.Utils.Tests/project.json
@@ -6,10 +6,10 @@
"dependencies": {
"Microsoft.NETCore.App": "1.0.0-rc2-23931",
"System.Runtime.Serialization.Primitives": "4.1.1-rc2-23931",
- "NuGet.Versioning": "3.5.0-beta-1123",
- "NuGet.Packaging": "3.5.0-beta-1123",
- "NuGet.Frameworks": "3.5.0-beta-1123",
- "NuGet.ProjectModel": "3.5.0-beta-1123",
+ "NuGet.Versioning": "3.5.0-beta-1130",
+ "NuGet.Packaging": "3.5.0-beta-1130",
+ "NuGet.Frameworks": "3.5.0-beta-1130",
+ "NuGet.ProjectModel": "3.5.0-beta-1130",
"Microsoft.DotNet.ProjectModel": {
"target": "project"
},
diff --git a/test/Microsoft.DotNet.Tools.Tests.Utilities/TestBase.cs b/test/Microsoft.DotNet.Tools.Tests.Utilities/TestBase.cs
index 0d5f4a0a0..a72b7b18f 100644
--- a/test/Microsoft.DotNet.Tools.Tests.Utilities/TestBase.cs
+++ b/test/Microsoft.DotNet.Tools.Tests.Utilities/TestBase.cs
@@ -103,7 +103,7 @@ namespace Microsoft.DotNet.Tools.Test.Utilities
string.Equals("on", val, StringComparison.OrdinalIgnoreCase));
}
- protected void TestExecutable(string outputDir,
+ protected CommandResult TestExecutable(string outputDir,
string executableName,
string expectedOutput)
{
@@ -123,9 +123,13 @@ namespace Microsoft.DotNet.Tools.Test.Utilities
var result = executableCommand.ExecuteWithCapturedOutput(string.Join(" ", args));
- result.Should().HaveStdOut(expectedOutput);
+ if (!string.IsNullOrEmpty(expectedOutput))
+ {
+ result.Should().HaveStdOut(expectedOutput);
+ }
result.Should().NotHaveStdErr();
result.Should().Pass();
+ return result;
}
protected void TestOutputExecutable(
diff --git a/test/Microsoft.Extensions.DependencyModel.Tests/FunctionalTests.cs b/test/Microsoft.Extensions.DependencyModel.Tests/FunctionalTests.cs
new file mode 100644
index 000000000..e051f178a
--- /dev/null
+++ b/test/Microsoft.Extensions.DependencyModel.Tests/FunctionalTests.cs
@@ -0,0 +1,133 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.DotNet.Cli.Utils;
+using Microsoft.DotNet.TestFramework;
+using Microsoft.DotNet.Tools.Test.Utilities;
+using FluentAssertions;
+using Xunit;
+
+namespace Microsoft.Extensions.DependencyModel
+{
+ public class FunctionalTests : TestBase
+ {
+ private readonly string _testProjectsRoot;
+
+ public FunctionalTests()
+ {
+ _testProjectsRoot = Path.Combine(AppContext.BaseDirectory, "TestAssets", "TestProjects");
+ }
+
+ [Theory]
+ [InlineData("TestApp", true)]
+ [InlineData("TestAppPortable", true)]
+ [InlineData("TestAppDeps", false)]
+ [InlineData("TestAppPortableDeps", false)]
+ public void RunTest(string appname, bool checkCompilation)
+ {
+ var testProjectPath = Path.Combine(RepoRoot, "TestAssets", "TestProjects", "DependencyContextValidator", appname);
+ var testProject = Path.Combine(testProjectPath, "project.json");
+
+ var runCommand = new RunCommand(testProject);
+ var result = runCommand.ExecuteWithCapturedOutput();
+ result.Should().Pass();
+ ValidateRuntimeLibrarites(result, appname);
+ if (checkCompilation)
+ {
+ ValidateCompilationLibraries(result, appname);
+ }
+ }
+
+ [Theory]
+ [InlineData("TestApp", false, true)]
+ [InlineData("TestAppPortable", true, true)]
+ [InlineData("TestAppDeps", false, false)]
+ [InlineData("TestAppPortableDeps", true, false)]
+ public void PublishTest(string appname, bool portable, bool checkCompilation)
+ {
+ var testProjectPath = Path.Combine(RepoRoot, "TestAssets", "TestProjects", "DependencyContextValidator", appname);
+ var testProject = Path.Combine(testProjectPath, "project.json");
+
+ var publishCommand = new PublishCommand(testProject);
+ publishCommand.Execute().Should().Pass();
+
+ var exeName = portable ? publishCommand.GetPortableOutputName() : publishCommand.GetOutputExecutable();
+
+ var result = TestExecutable(publishCommand.GetOutputDirectory(portable).FullName, exeName, string.Empty);
+ ValidateRuntimeLibrarites(result, appname);
+ if (checkCompilation)
+ {
+ ValidateCompilationLibraries(result, appname);
+ }
+ }
+
+ [WindowsOnlyFact]
+ public void RunTestFullClr()
+ {
+ var testProjectPath = Path.Combine(RepoRoot, "TestAssets", "TestProjects", "DependencyContextValidator", "TestAppFullClr");
+ var testProject = Path.Combine(testProjectPath, "project.json");
+
+ var runCommand = new RunCommand(testProject);
+ var result = runCommand.ExecuteWithCapturedOutput();
+ result.Should().Pass();
+ ValidateRuntimeLibraritesFullClr(result, "TestAppFullClr");
+ ValidateCompilationLibrariesFullClr(result, "TestAppFullClr");
+ }
+
+ [WindowsOnlyFact]
+ public void PublishTestFullClr()
+ {
+ var testProjectPath = Path.Combine(RepoRoot, "TestAssets", "TestProjects", "DependencyContextValidator", "TestAppFullClr");
+ var testProject = Path.Combine(testProjectPath, "project.json");
+
+ var publishCommand = new PublishCommand(testProject);
+ publishCommand.Execute().Should().Pass();
+
+ var result = TestExecutable(publishCommand.GetOutputDirectory().FullName, publishCommand.GetOutputExecutable(), string.Empty);
+ ValidateRuntimeLibraritesFullClr(result, "TestAppFullClr");
+ ValidateCompilationLibrariesFullClr(result, "TestAppFullClr");
+ }
+
+ private void ValidateRuntimeLibraritesFullClr(CommandResult result, string appname)
+ {
+ // entry assembly
+ result.Should().HaveStdOutContaining($"Runtime {appname}:{appname}");
+ // project dependency
+ result.Should().HaveStdOutContaining("Runtime DependencyContextValidator:DependencyContextValidator");
+ }
+
+ private void ValidateCompilationLibrariesFullClr(CommandResult result, string appname)
+ {
+ // entry assembly
+ result.Should().HaveStdOutContaining($"Compilation {appname}:{appname}.exe");
+ // project dependency
+ result.Should().HaveStdOutContaining("Compilation DependencyContextValidator:DependencyContextValidator.dll");
+ // system assembly
+ result.Should().HaveStdOutContaining("Compilation mscorlib:mscorlib.dll");
+ }
+
+
+ private void ValidateRuntimeLibrarites(CommandResult result, string appname)
+ {
+ // entry assembly
+ result.Should().HaveStdOutContaining($"Runtime {appname}:{appname}");
+ // project dependency
+ result.Should().HaveStdOutContaining("Runtime DependencyContextValidator:DependencyContextValidator");
+ // system assembly
+ result.Should().HaveStdOutContaining("Runtime System.Linq:System.Linq");
+ }
+
+ private void ValidateCompilationLibraries(CommandResult result, string appname)
+ {
+ // entry assembly
+ result.Should().HaveStdOutContaining($"Compilation {appname}:{appname}.dll");
+ // project dependency
+ result.Should().HaveStdOutContaining("Compilation DependencyContextValidator:DependencyContextValidator.dll");
+ // system assembly
+ result.Should().HaveStdOutContaining("Compilation System.Linq:System.Linq.dll");
+ }
+
+ }
+}
diff --git a/test/Microsoft.Extensions.DependencyModel.Tests/project.json b/test/Microsoft.Extensions.DependencyModel.Tests/project.json
index 82a324b4f..b1ca04ba3 100644
--- a/test/Microsoft.Extensions.DependencyModel.Tests/project.json
+++ b/test/Microsoft.Extensions.DependencyModel.Tests/project.json
@@ -9,6 +9,9 @@
"Microsoft.DotNet.Tools.Tests.Utilities": {
"target": "project"
},
+ "Microsoft.DotNet.Cli.Utils": {
+ "target": "project"
+ },
"FluentAssertions": "4.0.0",
"moq.netcore": "4.4.0-beta8",
"xunit": "2.1.0",
diff --git a/test/dotnet-compile.Tests/CompilerTests.cs b/test/dotnet-compile.Tests/CompilerTests.cs
index 3151c0230..efbb5abf9 100644
--- a/test/dotnet-compile.Tests/CompilerTests.cs
+++ b/test/dotnet-compile.Tests/CompilerTests.cs
@@ -147,26 +147,6 @@ namespace Microsoft.DotNet.Tools.Compiler.Tests
result.StdOut.Should().Contain("MyNamespace.Util");
}
- [Fact]
- public void EmbeddedDependencyContextIsValidOnBuild()
- {
- var testProjectPath = Path.Combine(RepoRoot, "TestAssets", "TestProjects", "DependencyContextValidator", "TestApp");
- var testProject = Path.Combine(testProjectPath, "project.json");
-
- var runCommand = new RunCommand(testProject);
- runCommand.Execute().Should().Pass();
- }
-
- [Fact]
- public void DepsDependencyContextIsValidOnBuild()
- {
- var testProjectPath = Path.Combine(RepoRoot, "TestAssets", "TestProjects", "DependencyContextValidator", "TestAppDeps");
- var testProject = Path.Combine(testProjectPath, "project.json");
-
- var runCommand = new RunCommand(testProject);
- runCommand.Execute().Should().Pass();
- }
-
[Fact]
public void CanSetOutputAssemblyNameForLibraries()
{
diff --git a/test/dotnet-projectmodel-server.Tests/DthTests.cs b/test/dotnet-projectmodel-server.Tests/DthTests.cs
index 92df20c70..4a36cd9f0 100644
--- a/test/dotnet-projectmodel-server.Tests/DthTests.cs
+++ b/test/dotnet-projectmodel-server.Tests/DthTests.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
@@ -412,13 +413,47 @@ namespace Microsoft.DotNet.ProjectModel.Server.Tests
}
}
}
-
+
+ [Fact]
+ public void AddMSBuildReferenceBeforeRestore()
+ {
+ var tam = new TestAssetsManager(
+ Path.Combine(RepoRoot, "TestAssets", "ProjectModelServer", "MSBuildReferencesProjects"));
+
+ // var appName = "EmptyNetCoreApp";
+ var projectPath = tam.CreateTestInstance("ValidCase01").WithLockFiles().TestRoot;
+ projectPath = Path.Combine(projectPath, "src", "MainApp");
+
+ var projectFilePath = Path.Combine(projectPath, Project.FileName);
+ var projectJson = JsonConvert.DeserializeObject(File.ReadAllText(projectFilePath));
+
+ ((JObject)projectJson["frameworks"]["net46"]["dependencies"])
+ .Add("ClassLibrary4", JToken.FromObject(new { target = "project" }));
+
+ File.WriteAllText(projectFilePath, JsonConvert.SerializeObject(projectJson));
+
+ using (var server = new DthTestServer(_loggerFactory))
+ using (var client = new DthTestClient(server, _loggerFactory))
+ {
+ client.Initialize(projectPath);
+ var messages = client.DrainAllMessages();
+ messages.AssertDoesNotContain(MessageTypes.Error);
+ // PrintAllMessages(new[] { messages.RetrieveSingleMessage(MessageTypes.Dependencies) });
+ messages.RetrieveSingleMessage(MessageTypes.Dependencies)
+ .RetrieveDependency("ClassLibrary4")
+ .AssertProperty