Merge branch 'rel/1.0.0' into clitest3verb

This commit is contained in:
Faizan Ahmad 2016-10-06 17:50:59 +05:30
commit 3f271e1215
116 changed files with 2571 additions and 469 deletions

View file

@ -21,5 +21,11 @@
</PackageReference> </PackageReference>
</ItemGroup> </ItemGroup>
<ItemGroup>
<DotNetCliToolReference Include="dotnet-portable">
<Version>1.0.0</Version>
</DotNetCliToolReference>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildExtensionsPath)\Microsoft.CSharp.targets" />
</Project> </Project>

View file

@ -0,0 +1,17 @@
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" />
<PropertyGroup>
<OutputType>Library</OutputType>
<TargetFrameworkIdentifier>.NETStandard</TargetFrameworkIdentifier>
<TargetFrameworkVersion>v1.5</TargetFrameworkVersion>
</PropertyGroup>
<ItemGroup>
<Compile Include="**\*.cs" Exclude="$(GlobalExclude)" />
<EmbeddedResource Include="**\*.resx" Exclude="$(GlobalExclude)" />
<None Include="project.json" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View file

@ -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.
using System;
namespace TestLibrary
{
public static class ProjectC
{
public static string GetMessage()
{
return "This string came from CsprojLibrary1";
}
}
}

View file

@ -0,0 +1,11 @@
{
"dependencies": {},
"frameworks": {
"netstandard1.5": {
"dependencies": {
"Microsoft.NETCore.Sdk": "1.0.0-alpha-20160923-4",
"NETStandard.Library": "1.6.0"
}
}
}
}

View file

@ -0,0 +1,17 @@
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" />
<PropertyGroup>
<OutputType>Library</OutputType>
<TargetFrameworkIdentifier>.NETStandard</TargetFrameworkIdentifier>
<TargetFrameworkVersion>v1.5</TargetFrameworkVersion>
</PropertyGroup>
<ItemGroup>
<Compile Include="**\*.cs" Exclude="$(GlobalExclude)" />
<EmbeddedResource Include="**\*.resx" Exclude="$(GlobalExclude)" />
<None Include="project.json" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View file

@ -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.
using System;
namespace TestLibrary
{
public static class ProjectC
{
public static string GetMessage()
{
return "This string came from CsprojLibrary2";
}
}
}

View file

@ -0,0 +1,11 @@
{
"dependencies": {},
"frameworks": {
"netstandard1.5": {
"dependencies": {
"Microsoft.NETCore.Sdk": "1.0.0-alpha-20160923-4",
"NETStandard.Library": "1.6.0"
}
}
}
}

View file

@ -0,0 +1,17 @@
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" />
<PropertyGroup>
<OutputType>Library</OutputType>
<TargetFrameworkIdentifier>.NETStandard</TargetFrameworkIdentifier>
<TargetFrameworkVersion>v1.5</TargetFrameworkVersion>
</PropertyGroup>
<ItemGroup>
<Compile Include="**\*.cs" Exclude="$(GlobalExclude)" />
<EmbeddedResource Include="**\*.resx" Exclude="$(GlobalExclude)" />
<None Include="project.json" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View file

@ -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.
using System;
namespace TestLibrary
{
public static class ProjectC
{
public static string GetMessage()
{
return "This string came from CsprojLibrary3";
}
}
}

View file

@ -0,0 +1,11 @@
{
"dependencies": {},
"frameworks": {
"netstandard1.5": {
"dependencies": {
"Microsoft.NETCore.Sdk": "1.0.0-alpha-20160923-4",
"NETStandard.Library": "1.6.0"
}
}
}
}

View file

@ -11,7 +11,7 @@ namespace TestApp
public static int Main(string[] args) public static int Main(string[] args)
{ {
Console.WriteLine("This string came from ProjectA"); Console.WriteLine("This string came from ProjectA");
return 100; return 0;
} }
} }
} }

View file

@ -16,8 +16,8 @@
<SchemaVersion>2.0</SchemaVersion> <SchemaVersion>2.0</SchemaVersion>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\ClassLibrary1\ClassLibrary1.csproj" /> <ProjectReference Include="..\CsprojLibrary1\CsprojLibrary1.csproj" />
<ProjectReference Include="..\..\ClassLibrary2\ClassLibrary2.csproj" /> <ProjectReference Include="..\CsprojLibrary2\CsprojLibrary2.csproj" />
</ItemGroup> </ItemGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" /> <Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
</Project> </Project>

View file

@ -18,10 +18,10 @@
"target": "project", "target": "project",
"version": "1.0.0-*" "version": "1.0.0-*"
}, },
"ClassLibrary1": { "CsprojLibrary1": {
"target": "project" "target": "project"
}, },
"ClassLibrary2": { "CsprojLibrary2": {
"target": "project" "target": "project"
}, },
"NETStandard.Library": "1.6.0" "NETStandard.Library": "1.6.0"

View file

@ -16,8 +16,8 @@
<SchemaVersion>2.0</SchemaVersion> <SchemaVersion>2.0</SchemaVersion>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\ClassLibrary2\ClassLibrary2.csproj" /> <ProjectReference Include="..\CsprojLibrary2\CsprojLibrary2.csproj" />
<ProjectReference Include="..\..\ClassLibrary3\ClassLibrary3.csproj" /> <ProjectReference Include="..\CsprojLibrary3\CsprojLibrary3.csproj" />
</ItemGroup> </ItemGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" /> <Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
</Project> </Project>

View file

@ -10,10 +10,10 @@
] ]
}, },
"dependencies": { "dependencies": {
"ClassLibrary2": { "CsprojLibrary2": {
"target": "project" "target": "project"
}, },
"ClassLibrary3": { "CsprojLibrary3": {
"target": "project" "target": "project"
}, },
"NETStandard.Library": "1.6.0" "NETStandard.Library": "1.6.0"

View file

@ -0,0 +1,19 @@
// 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 int Main(string[] args)
{
Console.WriteLine("This string came from ProjectF");
string helperStr = TestLibrary.ProjectG.GetMessage();
Console.WriteLine(helperStr);
return 0;
}
}
}

View file

@ -0,0 +1,20 @@
{
"version": "1.0.0-*",
"buildOptions": {
"emitEntryPoint": true,
"preserveCompilationContext": true
},
"dependencies": {
"ProjectG": {
"target": "project",
"version": "1.0.0-*"
},
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.1"
}
},
"frameworks": {
"netcoreapp1.0": {}
}
}

View file

@ -5,7 +5,7 @@ using System;
namespace TestLibrary namespace TestLibrary
{ {
public static class ProjectE public static class ProjectG
{ {
public static string GetMessage() public static string GetMessage()
{ {

View file

@ -0,0 +1,4 @@
{
"projects": [ "src", "src with spaces", "src without projects" ]
}

View file

@ -0,0 +1,19 @@
// 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 int Main(string[] args)
{
Console.WriteLine("This string came from ProjectJ");
string helperStr = TestLibrary.ProjectI.GetMessage();
Console.WriteLine(helperStr);
return 0;
}
}
}

View file

@ -0,0 +1,20 @@
{
"version": "1.0.0-*",
"buildOptions": {
"emitEntryPoint": true,
"preserveCompilationContext": true
},
"dependencies": {
"ProjectI": {
"target": "project",
"version": "1.0.0-*"
},
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.1"
}
},
"frameworks": {
"netcoreapp1.0": {}
}
}

View file

@ -0,0 +1,19 @@
// 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 int Main(string[] args)
{
Console.WriteLine("This string came from ProjectH");
string helperStr = TestLibrary.ProjectI.GetMessage();
Console.WriteLine(helperStr);
return 0;
}
}
}

View file

@ -0,0 +1,20 @@
{
"version": "1.0.0-*",
"buildOptions": {
"emitEntryPoint": true,
"preserveCompilationContext": true
},
"dependencies": {
"ProjectI": {
"target": "project",
"version": "1.0.0-*"
},
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.1"
}
},
"frameworks": {
"netcoreapp1.0": {}
}
}

View file

@ -5,11 +5,11 @@ using System;
namespace TestLibrary namespace TestLibrary
{ {
public static class ProjectE public static class ProjectI
{ {
public static string GetMessage() public static string GetMessage()
{ {
return "This string came from ProjectF"; return "This string came from ProjectI";
} }
} }
} }

View file

@ -10,10 +10,6 @@
] ]
}, },
"dependencies": { "dependencies": {
"ProjectG": {
"target": "project",
"version": "1.0.0-*"
},
"NETStandard.Library": "1.6.0" "NETStandard.Library": "1.6.0"
}, },
"frameworks": { "frameworks": {

View file

@ -9,7 +9,7 @@
"include": "testcontentfile2.txt" "include": "testcontentfile2.txt"
}, },
"out/": { "out/": {
"include": ["project.json", "Program.cs"], "include": ["Program.cs"],
"exclude": ["Program.cs"], "exclude": ["Program.cs"],
"includeFiles": ["Program.cs"], "includeFiles": ["Program.cs"],
"excludeFiles": ["Program.cs"] "excludeFiles": ["Program.cs"]

View file

@ -0,0 +1,12 @@
using System;
namespace ConsoleApplication
{
public class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Hello World!");
}
}
}

Binary file not shown.

View file

@ -0,0 +1,16 @@
{
"version": "1.0.0-*",
"buildOptions": {
"emitEntryPoint": true,
"keyFile": "./key.snk"
},
"dependencies": {
"Microsoft.NETCore.App": {
"version": "1.0.1",
"type": "platform"
},
},
"frameworks": {
"netcoreapp1.0": {}
}
}

View file

@ -202,7 +202,7 @@
<!-- Generate .version file --> <!-- Generate .version file -->
<WriteLinesToFile File="$(SdkOutputDirectory)/.version" <WriteLinesToFile File="$(SdkOutputDirectory)/.version"
Lines="$(CommitHash);$(SdkVersion)" Lines="$(CommitHash);$(SdkVersion);$(Rid)"
Overwrite="true" /> Overwrite="true" />
<ItemGroup> <ItemGroup>

View file

@ -97,11 +97,13 @@
AccountKey="$(CloudDropAccessToken)" AccountKey="$(CloudDropAccessToken)"
AccountName="$(CloudDropAccountName)" AccountName="$(CloudDropAccountName)"
ContainerName="$(ContainerName)" ContainerName="$(ContainerName)"
Items="@(CliVersionBadgeToUpload)" /> Items="@(CliVersionBadgeToUpload)"
Overwrite="$(OverwriteOnPublish)" />
<SetBlobPropertiesBasedOnFileType <SetBlobPropertiesBasedOnFileType
AccountKey="$(CloudDropAccessToken)" AccountKey="$(CloudDropAccessToken)"
AccountName="$(CloudDropAccountName)" AccountName="$(CloudDropAccountName)"
ContainerName="$(ContainerName)"
Items="@(CliVersionBadgeToUpload)" /> Items="@(CliVersionBadgeToUpload)" />
</Target> </Target>
</Project> </Project>

View file

@ -18,9 +18,12 @@
<SdkGenerateMsiPowershellScript>$(RepoRoot)/packaging/windows/clisdk/generatemsi.ps1</SdkGenerateMsiPowershellScript> <SdkGenerateMsiPowershellScript>$(RepoRoot)/packaging/windows/clisdk/generatemsi.ps1</SdkGenerateMsiPowershellScript>
<SdkGenerateBundlePowershellScript>$(RepoRoot)/packaging/windows/clisdk/generatebundle.ps1</SdkGenerateBundlePowershellScript> <SdkGenerateBundlePowershellScript>$(RepoRoot)/packaging/windows/clisdk/generatebundle.ps1</SdkGenerateBundlePowershellScript>
<SdkGenerateNupkgPowershellScript>$(RepoRoot)/packaging/windows/clisdk/generatenupkg.ps1</SdkGenerateNupkgPowershellScript>
<SdkInstallerFile>$(InstallerOutputDirectory)/$(ArtifactNameWithVersionSdk)$(InstallerExtension)</SdkInstallerFile> <SdkInstallerFile>$(InstallerOutputDirectory)/$(ArtifactNameWithVersionSdk)$(InstallerExtension)</SdkInstallerFile>
<CombinedFrameworkSdkHostInstallerFile>$(InstallerOutputDirectory)/$(ArtifactNameWithVersionCombinedHostHostFxrFrameworkSdk)$(BundleExtension)</CombinedFrameworkSdkHostInstallerFile> <CombinedFrameworkSdkHostInstallerFile>$(InstallerOutputDirectory)/$(ArtifactNameWithVersionCombinedHostHostFxrFrameworkSdk)$(BundleExtension)</CombinedFrameworkSdkHostInstallerFile>
<SdkInstallerNuspecFile>$(RepoRoot)/packaging/windows/clisdk/VS.Redist.Common.Net.Core.SDK.$(Architecture).nuspec</SdkInstallerNuspecFile>
<SdkInstallerNupkgFile>$(InstallerOutputDirectory)/VS.Redist.Common.Net.Core.SDK.$(Architecture).$(NugetVersion).nupkg</SdkInstallerNupkgFile>
</PropertyGroup> </PropertyGroup>
<!-- Consumed By Publish --> <!-- Consumed By Publish -->
@ -113,6 +116,21 @@
'$(Architecture)'" /> '$(Architecture)'" />
</Target> </Target>
<Target Name="GenerateSdkNupkg"
DependsOnTargets="Init;Layout;MsiTargetsSetupInputOutputs;GenerateSdkBundle"
Condition=" '$(OS)' == 'Windows_NT'"
Inputs="$(CombinedFrameworkSdkHostInstallerFile);
$(SdkInstallerNuspecFile);
$(SdkGenerateNupkgPowershellScript)"
Outputs="$(SdkInstallerNupkgFile)">
<Exec Command="powershell -NoProfile -NoLogo $(SdkGenerateNupkgPowershellScript)
'$(CombinedFrameworkSdkHostInstallerFile)'
'$(NugetVersion)'
'$(SdkInstallerNuspecFile)'
'$(SdkInstallerNupkgFile)'" />
</Target>
<Target Name="TestSdkMsi" <Target Name="TestSdkMsi"
Inputs="$(SdkInstallerFile)" Inputs="$(SdkInstallerFile)"
Outputs="$(SdkMsiTestedSentinel)" Outputs="$(SdkMsiTestedSentinel)"
@ -137,6 +155,7 @@
AcquireWix; AcquireWix;
GenerateSdkMsi; GenerateSdkMsi;
GenerateSdkBundle; GenerateSdkBundle;
GenerateSdkNupkg;
TestSdkMsi" TestSdkMsi"
Condition=" '$(OS)' == 'Windows_NT'" /> Condition=" '$(OS)' == 'Windows_NT'" />

View file

@ -18,6 +18,9 @@ namespace Microsoft.DotNet.Cli.Build
[Required] [Required]
public string AccountKey { get; set; } public string AccountKey { get; set; }
[Required]
public string ContainerName { get; set; }
[Required] [Required]
public ITaskItem[] Items { get; set; } public ITaskItem[] Items { get; set; }
@ -25,9 +28,9 @@ namespace Microsoft.DotNet.Cli.Build
{ {
get get
{ {
if(_azurePublisher == null) if (_azurePublisher == null)
{ {
_azurePublisher = new AzurePublisher(AccountName, AccountKey); _azurePublisher = new AzurePublisher(AccountName, AccountKey, ContainerName);
} }
return _azurePublisher; return _azurePublisher;
@ -42,7 +45,7 @@ namespace Microsoft.DotNet.Cli.Build
return false; return false;
} }
foreach(var item in Items) foreach (var item in Items)
{ {
string relativeBlobPath = item.GetMetadata("RelativeBlobPath"); string relativeBlobPath = item.GetMetadata("RelativeBlobPath");
if (string.IsNullOrEmpty(relativeBlobPath)) if (string.IsNullOrEmpty(relativeBlobPath))
@ -53,7 +56,7 @@ namespace Microsoft.DotNet.Cli.Build
} }
AzurePublisherTool.SetBlobPropertiesBasedOnFileType(relativeBlobPath); AzurePublisherTool.SetBlobPropertiesBasedOnFileType(relativeBlobPath);
} }
return true; return true;
} }

View file

@ -22,42 +22,44 @@ namespace Microsoft.DotNet.Cli.Build
Sdk, Sdk,
} }
private const string s_dotnetBlobRootUrl = "https://dotnetcli.blob.core.windows.net/" + s_dotnetBlobContainerName;
private const string s_dotnetBlobContainerName = "dotnet"; private const string s_dotnetBlobContainerName = "dotnet";
private string _connectionString { get; set; } private string _connectionString { get; set; }
private string _containerName { get; set; }
private CloudBlobContainer _blobContainer { get; set; } private CloudBlobContainer _blobContainer { get; set; }
public AzurePublisher() public AzurePublisher(string containerName = s_dotnetBlobContainerName)
{ {
_connectionString = EnvVars.EnsureVariable("CONNECTION_STRING").Trim('"'); _connectionString = EnvVars.EnsureVariable("CONNECTION_STRING").Trim('"');
_blobContainer = GetDotnetBlobContainer(_connectionString); _containerName = containerName;
_blobContainer = GetDotnetBlobContainer(_connectionString, containerName);
} }
public AzurePublisher(string accountName, string accountKey) public AzurePublisher(string accountName, string accountKey, string containerName = s_dotnetBlobContainerName)
{ {
_blobContainer = GetDotnetBlobContainer(accountName, accountKey); _containerName = containerName;
_blobContainer = GetDotnetBlobContainer(accountName, accountKey, containerName);
} }
private CloudBlobContainer GetDotnetBlobContainer(string connectionString) private CloudBlobContainer GetDotnetBlobContainer(string connectionString, string containerName)
{ {
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionString); CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionString);
return GetDotnetBlobContainer(storageAccount); return GetDotnetBlobContainer(storageAccount, containerName);
} }
private CloudBlobContainer GetDotnetBlobContainer(string accountName, string accountKey) private CloudBlobContainer GetDotnetBlobContainer(string accountName, string accountKey, string containerName)
{ {
var storageCredentials = new StorageCredentials(accountName, accountKey); var storageCredentials = new StorageCredentials(accountName, accountKey);
var storageAccount = new CloudStorageAccount(storageCredentials, true); var storageAccount = new CloudStorageAccount(storageCredentials, true);
return GetDotnetBlobContainer(storageAccount); return GetDotnetBlobContainer(storageAccount, containerName);
} }
private CloudBlobContainer GetDotnetBlobContainer(CloudStorageAccount storageAccount) private CloudBlobContainer GetDotnetBlobContainer(CloudStorageAccount storageAccount, string containerName)
{ {
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient(); CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
return blobClient.GetContainerReference(s_dotnetBlobContainerName); return blobClient.GetContainerReference(containerName);
} }
public string UploadFile(string file, Product product, string version) public string UploadFile(string file, Product product, string version)
@ -126,7 +128,7 @@ namespace Microsoft.DotNet.Cli.Build
BlobContinuationToken continuationToken = new BlobContinuationToken(); BlobContinuationToken continuationToken = new BlobContinuationToken();
var blobFiles = blobDir.ListBlobsSegmentedAsync(continuationToken).Result; var blobFiles = blobDir.ListBlobsSegmentedAsync(continuationToken).Result;
return blobFiles.Results.Select(bf => bf.Uri.PathAndQuery.Replace($"/{s_dotnetBlobContainerName}/", string.Empty)); return blobFiles.Results.Select(bf => bf.Uri.PathAndQuery.Replace($"/{_containerName}/", string.Empty));
} }
public string AcquireLeaseOnBlob( public string AcquireLeaseOnBlob(
@ -219,35 +221,9 @@ namespace Microsoft.DotNet.Cli.Build
_blobContainer.GetBlockBlobReference(path).DeleteAsync().Wait(); _blobContainer.GetBlockBlobReference(path).DeleteAsync().Wait();
} }
public static string CalculateFullUrlForFile(string file, Product product, string version)
{
return $"{s_dotnetBlobRootUrl}/{CalculateRelativePathForFile(file, product, version)}";
}
private static string CalculateRelativePathForFile(string file, Product product, string version) private static string CalculateRelativePathForFile(string file, Product product, string version)
{ {
return $"{product}/{version}/{Path.GetFileName(file)}"; return $"{product}/{version}/{Path.GetFileName(file)}";
} }
public static async Task DownloadFile(string blobFilePath, string localDownloadPath)
{
var blobUrl = $"{s_dotnetBlobRootUrl}/{blobFilePath}";
using (var client = new HttpClient())
{
var request = new HttpRequestMessage(HttpMethod.Get, blobUrl);
var sendTask = client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
var response = sendTask.Result.EnsureSuccessStatusCode();
var httpStream = await response.Content.ReadAsStreamAsync();
using (var fileStream = File.Create(localDownloadPath))
using (var reader = new StreamReader(httpStream))
{
httpStream.CopyTo(fileStream);
fileStream.Flush();
}
}
}
} }
} }

View file

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>VS.Redist.Common.Net.Core.SDK.x64</id>
<version>1.0.0</version>
<title>VS.Redist.Common.Net.Core.SDK.x64</title>
<authors>Microsoft</authors>
<owners>Microsoft</owners>
<licenseUrl>https://www.microsoft.com/net/dotnet_library_license.htm</licenseUrl>
<projectUrl>https://github.com/dotnet/cli</projectUrl>
<requireLicenseAcceptance>true</requireLicenseAcceptance>
<description>Windows Installers (x64) for .Net Core SDK</description>
<copyright>© Microsoft Corporation. All rights reserved.</copyright>
</metadata>
<files>
<file src="[DOTNET_BUNDLE]" target="[DOTNET_BUNDLE]" />
</files>
</package>

View file

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>VS.Redist.Common.Net.Core.SDK.x86</id>
<version>1.0.0</version>
<title>VS.Redist.Common.Net.Core.SDK.x86</title>
<authors>Microsoft</authors>
<owners>Microsoft</owners>
<licenseUrl>https://www.microsoft.com/net/dotnet_library_license.htm</licenseUrl>
<projectUrl>https://github.com/dotnet/cli</projectUrl>
<requireLicenseAcceptance>true</requireLicenseAcceptance>
<description>Windows Installer (x86) for .Net Core SDK</description>
<copyright>© Microsoft Corporation. All rights reserved.</copyright>
</metadata>
<files>
<file src="[DOTNET_BUNDLE]" target="[DOTNET_BUNDLE]" />
</files>
</package>

View file

@ -0,0 +1,74 @@
# 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.
# This script is used to generate a nuget package with the windows installer bundle.
# The generated nupkg file is used to deliver the CLI payload to Visual Studio.
param(
[Parameter(Mandatory=$true)][string]$SdkBundlePath,
[Parameter(Mandatory=$true)][string]$NugetVersion,
[Parameter(Mandatory=$true)][string]$NuspecFile,
[Parameter(Mandatory=$true)][string]$NupkgFile
)
. "$PSScriptRoot\..\..\..\scripts\common\_common.ps1"
$RepoRoot = Convert-Path "$PSScriptRoot\..\..\.."
$NuGetDir = Join-Path $RepoRoot ".nuget"
$NuGetExe = Join-Path $NuGetDir "nuget.exe"
$OutputDirectory = [System.IO.Path]::GetDirectoryName($SdkBundlePath)
function DownloadNugetExe
{
if (-not (Test-Path $NuGetDir))
{
New-Item -ItemType Directory -Force -Path $NuGetDir | Out-Null
}
if (-not (Test-Path $NuGetExe)) {
Write-Host 'Downloading nuget.exe to ' + $NuGetExe
wget https://dist.nuget.org/win-x86-commandline/v3.5.0-rc1/NuGet.exe -OutFile $NuGetExe
}
}
function GenerateNupkg
{
if (-not (Test-Path $NuspecFile))
{
Write-Host 'Error nuspec not found - $NuspecFile'
}
$SdkBundleName = [System.IO.Path]::GetFileName($SdkBundlePath)
$NuspecFileName = [System.IO.Path]::GetFileName($NuspecFile)
$TempNuspecFile = [System.IO.Path]::Combine($OutputDirectory, $NuspecFileName)
(Get-Content $NuspecFile) -replace '\[DOTNET_BUNDLE\]', $SdkBundleName | Set-Content $TempNuspecFile
& $NuGetExe pack $TempNuspecFile -Version $NugetVersion -OutputDirectory $OutputDirectory
}
if(!(Test-Path $SdkBundlePath))
{
throw "$SdkBundlePath not found"
}
Write-Host "Creating nupkg for Sdk installer"
DownloadNugetExe
if(Test-Path $NupkgFile)
{
Remove-Item -Force $NupkgFile
}
if(-Not (GenerateNupkg))
{
Exit -1
}
if(!(Test-Path $NupkgFile))
{
throw "$NupkgFile not generated"
}
Write-Host -ForegroundColor Green "Successfully created installer nupkg - $NupkgFile"
exit $LastExitCode

View file

@ -1,23 +1,24 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<Include xmlns="http://schemas.microsoft.com/wix/2006/wi"> <Include xmlns="http://schemas.microsoft.com/wix/2006/wi">
<!-- These values were generated by running 'heat payload' against the CRTs downloaded from the fwlinks --> <!-- These values were generated by running 'heat payload' against the CRTs downloaded from the download center links(DLC) -->
<!-- The DLC links are owned by the .Net Core team (contact leecow@microsoft.com) and CRTs that they point to should never be changed -->
<?define Crt_CertificatePublicKey="52868DFCA6E3AF2632389E6C1EE7D0468D3797D0"?> <?define Crt_CertificatePublicKey="371DD003A37769487A2A89A5A9DDB3026451B906"?>
<?define Crt_CertificateThumbprint="3BDA323E552DB1FDE5F4FBEE75D6D5B2B187EEDC"?> <?define Crt_CertificateThumbprint="98ED99A67886D020C564923B7DF25E9AC019DF26"?>
<?define Crt_Description="Microsoft Visual C++ 2015 Redistributable ($(var.Platform)) - 14.0.23506"?> <?define Crt_Description="Microsoft Visual C++ 2015 Redistributable ($(var.Platform)) - 14.0.24215"?>
<?define Crt_ProductName="Microsoft Visual C++ 2015 Redistributable ($(var.Platform)) - 14.0.23506"?> <?define Crt_ProductName="Microsoft Visual C++ 2015 Redistributable ($(var.Platform)) - 14.0.24215"?>
<?define Crt_Version="14.0.23506.0"?> <?define Crt_Version="14.0.24215.1"?>
<?define Crt_VersionRegistyKeyValue="v14.0.23506.00"?> <?define Crt_VersionRegistyKeyValue="v14.0.24215.01"?>
<?if $(var.Platform)=x86?> <?if $(var.Platform)=x86?>
<?define Crt_DownloadUrl="http://go.microsoft.com/fwlink/?LinkID=615459&amp;clcid=0x409"?> <?define Crt_DownloadUrl="https://download.microsoft.com/download/1/F/0/1F01DD22-748C-41A7-89DE-54D64355CDA6/vc_redist.x86.exe"?>
<?define Crt_Hash="17B381D3ADB22F00E4AB47CBD91CE0A5B1CCBC70"?> <?define Crt_Hash="72211BD2E7DFC91EA7C8FAC549C49C0543BA791B"?>
<?define Crt_Size="13977352"?> <?define Crt_Size="14456872"?>
<?elseif $(var.Platform)=x64?> <?elseif $(var.Platform)=x64?>
<?define Crt_DownloadUrl="http://go.microsoft.com/fwlink/?LinkID=615460&amp;clcid=0x409"?> <?define Crt_DownloadUrl="https://download.microsoft.com/download/1/F/0/1F01DD22-748C-41A7-89DE-54D64355CDA6/vc_redist.x64.exe"?>
<?define Crt_Hash="9A19A51D1F40CD5CD5ECB6E4E4F978F18DA8212A"?> <?define Crt_Hash="10B1683EA3FF5F36F225769244BF7E7813D54AD0"?>
<?define Crt_Size="14773216"?> <?define Crt_Size="15301888"?>
<?else?> <?else?>
<?error Invalid Platform ($(var.Platform))?> <?error Invalid Platform ($(var.Platform))?>
<?endif?> <?endif?>

View file

@ -63,7 +63,28 @@ namespace Microsoft.DotNet.Cli.Utils
string outputPath = null, string outputPath = null,
string applicationName = null) string applicationName = null)
{ {
var commandSpec = CommandResolver.TryResolveCommandSpec(commandName, return Create(
new DefaultCommandResolverPolicy(),
commandName,
args,
framework,
configuration,
outputPath,
applicationName);
}
public static Command Create(
ICommandResolverPolicy commandResolverPolicy,
string commandName,
IEnumerable<string> args,
NuGetFramework framework = null,
string configuration = Constants.DefaultConfiguration,
string outputPath = null,
string applicationName = null)
{
var commandSpec = CommandResolver.TryResolveCommandSpec(
commandResolverPolicy,
commandName,
args, args,
framework, framework,
configuration: configuration, configuration: configuration,

View file

@ -2,8 +2,13 @@ using Microsoft.DotNet.PlatformAbstractions;
namespace Microsoft.DotNet.Cli.Utils namespace Microsoft.DotNet.Cli.Utils
{ {
public class DefaultCommandResolverPolicy public class DefaultCommandResolverPolicy : ICommandResolverPolicy
{ {
public CompositeCommandResolver CreateCommandResolver()
{
return Create();
}
public static CompositeCommandResolver Create() public static CompositeCommandResolver Create()
{ {
var environment = new EnvironmentProvider(); var environment = new EnvironmentProvider();
@ -37,7 +42,6 @@ namespace Microsoft.DotNet.Cli.Utils
compositeCommandResolver.AddCommandResolver(new MuxerCommandResolver()); compositeCommandResolver.AddCommandResolver(new MuxerCommandResolver());
compositeCommandResolver.AddCommandResolver(new RootedCommandResolver()); compositeCommandResolver.AddCommandResolver(new RootedCommandResolver());
compositeCommandResolver.AddCommandResolver(new ProjectToolsCommandResolver(packagedCommandSpecFactory));
compositeCommandResolver.AddCommandResolver(new AppBaseDllCommandResolver()); compositeCommandResolver.AddCommandResolver(new AppBaseDllCommandResolver());
compositeCommandResolver.AddCommandResolver( compositeCommandResolver.AddCommandResolver(
new AppBaseCommandResolver(environment, platformCommandSpecFactory)); new AppBaseCommandResolver(environment, platformCommandSpecFactory));

View file

@ -0,0 +1,7 @@
namespace Microsoft.DotNet.Cli.Utils
{
public interface ICommandResolverPolicy
{
CompositeCommandResolver CreateCommandResolver();
}
}

View file

@ -80,7 +80,7 @@ namespace Microsoft.DotNet.Cli.Utils
var projectContext = ProjectContext.Create( var projectContext = ProjectContext.Create(
projectRootPath, projectRootPath,
framework, framework,
RuntimeEnvironmentRidExtensions.GetAllCandidateRuntimeIdentifiers()); DotnetRuntimeIdentifiers.InferCurrentRuntimeIdentifiers());
if (projectContext.RuntimeIdentifier == null) if (projectContext.RuntimeIdentifier == null)
{ {

View file

@ -142,7 +142,7 @@ namespace Microsoft.DotNet.Cli.Utils
return ProjectContext.Create( return ProjectContext.Create(
projectRootPath, projectRootPath,
framework, framework,
RuntimeEnvironmentRidExtensions.GetAllCandidateRuntimeIdentifiers()); DotnetRuntimeIdentifiers.InferCurrentRuntimeIdentifiers());
} }

View file

@ -5,7 +5,7 @@ using NuGet.Frameworks;
namespace Microsoft.DotNet.Cli.Utils namespace Microsoft.DotNet.Cli.Utils
{ {
internal static class CommandResolver internal class CommandResolver
{ {
public static CommandSpec TryResolveCommandSpec( public static CommandSpec TryResolveCommandSpec(
string commandName, string commandName,
@ -14,6 +14,25 @@ namespace Microsoft.DotNet.Cli.Utils
string configuration = Constants.DefaultConfiguration, string configuration = Constants.DefaultConfiguration,
string outputPath = null, string outputPath = null,
string applicationName = null) string applicationName = null)
{
return TryResolveCommandSpec(
new DefaultCommandResolverPolicy(),
commandName,
args,
framework,
configuration,
outputPath,
applicationName);
}
public static CommandSpec TryResolveCommandSpec(
ICommandResolverPolicy commandResolverPolicy,
string commandName,
IEnumerable<string> args,
NuGetFramework framework = null,
string configuration = Constants.DefaultConfiguration,
string outputPath = null,
string applicationName = null)
{ {
var commandResolverArgs = new CommandResolverArguments var commandResolverArgs = new CommandResolverArguments
{ {
@ -26,7 +45,7 @@ namespace Microsoft.DotNet.Cli.Utils
ApplicationName = applicationName ApplicationName = applicationName
}; };
var defaultCommandResolver = DefaultCommandResolverPolicy.Create(); var defaultCommandResolver = commandResolverPolicy.CreateCommandResolver();
return defaultCommandResolver.Resolve(commandResolverArgs); return defaultCommandResolver.Resolve(commandResolverArgs);
} }

View file

@ -12,11 +12,19 @@ namespace Microsoft.DotNet.Cli.Utils
{ {
private static string SdkRootFolder => Path.Combine(typeof(DotnetFiles).GetTypeInfo().Assembly.Location, ".."); private static string SdkRootFolder => Path.Combine(typeof(DotnetFiles).GetTypeInfo().Assembly.Location, "..");
private static Lazy<DotnetVersionFile> s_versionFileObject =
new Lazy<DotnetVersionFile>(() => new DotnetVersionFile(VersionFile));
/// <summary> /// <summary>
/// The CLI ships with a .version file that stores the commit information and CLI version /// The CLI ships with a .version file that stores the commit information and CLI version
/// </summary> /// </summary>
public static string VersionFile => Path.GetFullPath(Path.Combine(SdkRootFolder, ".version")); public static string VersionFile => Path.GetFullPath(Path.Combine(SdkRootFolder, ".version"));
internal static DotnetVersionFile VersionFileObject
{
get { return s_versionFileObject.Value; }
}
public static string NuGetPackagesArchive => public static string NuGetPackagesArchive =>
Path.GetFullPath(Path.Combine(SdkRootFolder, "nuGetPackagesArchive.lzma")); Path.GetFullPath(Path.Combine(SdkRootFolder, "nuGetPackagesArchive.lzma"));

View file

@ -0,0 +1,35 @@
// 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.InternalAbstractions;
namespace Microsoft.DotNet.Cli.Utils
{
internal static class DotnetRuntimeIdentifiers
{
public static IEnumerable<string> InferCurrentRuntimeIdentifiers()
{
IEnumerable<string> fallbackIdentifiers = null;
// If the machine's RID isn't supported by the shared framework (i.e. the CLI
// is being used on a newer version of an OS), add the RID that the CLI was built
// with as a fallback. The RID the CLI was built with will have the correct
// runtime.* NuGet packages available.
// For example, when a user is using osx.10.12, but we only support osx.10.10 and
// osx.10.11, the project.json "runtimes" section cannot contain osx.10.12, since
// that RID isn't contained in the runtime graph - users will get a restore error.
FrameworkDependencyFile fxDepsFile = new FrameworkDependencyFile();
if (!fxDepsFile.SupportsCurrentRuntime())
{
string buildRid = DotnetFiles.VersionFileObject.BuildRid;
if (!string.IsNullOrEmpty(buildRid))
{
fallbackIdentifiers = new string[] { buildRid };
}
}
return RuntimeEnvironmentRidExtensions.GetAllCandidateRuntimeIdentifiers(fallbackIdentifiers);
}
}
}

View file

@ -0,0 +1,61 @@
// 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 System.IO;
namespace Microsoft.DotNet.Cli.Utils
{
internal class DotnetVersionFile
{
public bool Exists { get; set; }
public string CommitSha { get; set; }
public string BuildNumber { get; set; }
/// <summary>
/// The runtime identifier (rid) that this CLI was built for.
/// </summary>
/// <remarks>
/// This is different than RuntimeEnvironment.GetRuntimeIdentifier() because the
/// BuildRid is a RID that is guaranteed to exist and works on the current machine. The
/// RuntimeEnvironment.GetRuntimeIdentifier() may be for a new version of the OS that
/// doesn't have full support yet.
/// </remarks>
public string BuildRid { get; set; }
public DotnetVersionFile(string versionFilePath)
{
Exists = File.Exists(versionFilePath);
if (Exists)
{
IEnumerable<string> lines = File.ReadLines(versionFilePath);
int index = 0;
foreach (string line in lines)
{
if (index == 0)
{
CommitSha = line.Substring(0, 10);
}
else if (index == 1)
{
BuildNumber = line;
}
else if (index == 2)
{
BuildRid = line;
}
else
{
break;
}
index++;
}
}
}
}
}

View file

@ -0,0 +1,45 @@
// 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 Microsoft.DotNet.PlatformAbstractions;
using Microsoft.Extensions.DependencyModel;
namespace Microsoft.DotNet.Cli.Utils
{
/// <summary>
/// Represents the .deps.json file in the shared framework
/// that the CLI is running against.
/// </summary>
internal class FrameworkDependencyFile
{
private readonly string _depsFilePath;
public FrameworkDependencyFile()
{
_depsFilePath = Muxer.GetDataFromAppDomain("FX_DEPS_FILE");
}
public bool SupportsCurrentRuntime()
{
return IsRuntimeSupported(RuntimeEnvironment.GetRuntimeIdentifier());
}
public bool IsRuntimeSupported(string runtimeIdentifier)
{
DependencyContext fxDependencyContext = CreateDependencyContext();
return fxDependencyContext.RuntimeGraph.Any(g => g.Runtime == runtimeIdentifier);
}
private DependencyContext CreateDependencyContext()
{
using (Stream depsFileStream = File.OpenRead(_depsFilePath))
using (DependencyContextJsonReader reader = new DependencyContextJsonReader())
{
return reader.Read(depsFileStream);
}
}
}
}

View file

@ -2,4 +2,6 @@ using System.Reflection;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
[assembly: AssemblyMetadataAttribute("Serviceable", "True")] [assembly: AssemblyMetadataAttribute("Serviceable", "True")]
[assembly: InternalsVisibleTo("dotnet, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.DotNet.Tools.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
[assembly: InternalsVisibleTo("Microsoft.DotNet.Cli.Utils.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")] [assembly: InternalsVisibleTo("Microsoft.DotNet.Cli.Utils.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]

View file

@ -8,7 +8,7 @@
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<ProjectGuid>e5ed47ef-bf25-4da9-a7fe-290c642cbf0f</ProjectGuid> <ProjectGuid>e5ed47ef-bf25-4da9-a7fe-290c642cbf0f</ProjectGuid>
<RootNamespace>Microsoft.DotNet.Configurer</RootNamespace> <RootNamespace>Microsoft.DotNet.Configurer</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath> <BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin</OutputPath> <OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin</OutputPath>
</PropertyGroup> </PropertyGroup>

View file

@ -12,14 +12,14 @@ namespace Microsoft.DotNet.ProjectJsonMigration
new MigrateRootOptionsRule(), new MigrateRootOptionsRule(),
new MigrateTFMRule(), new MigrateTFMRule(),
new MigrateBuildOptionsRule(), new MigrateBuildOptionsRule(),
new MigrateJsonPropertiesRule(),
new MigratePackOptionsRule(), new MigratePackOptionsRule(),
new MigrateRuntimeOptionsRule(), new MigrateRuntimeOptionsRule(),
new MigratePublishOptionsRule(), new MigratePublishOptionsRule(),
new MigrateProjectDependenciesRule(), new MigrateProjectDependenciesRule(),
new MigratePackageDependenciesAndToolsRule(),
new MigrateConfigurationsRule(), new MigrateConfigurationsRule(),
new MigrateScriptsRule(), new MigrateScriptsRule(),
new TemporaryMutateProjectJsonRule(),
new WorkaroundOptionsRule(),
new SaveOutputProjectRule() new SaveOutputProjectRule()
}; };

View file

@ -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.
using NuGet.Frameworks;
namespace Microsoft.DotNet.ProjectJsonMigration
{
public static class MigrationNuGetFrameworkExtensions
{
public static string GetMSBuildCondition(this NuGetFramework framework)
{
return $" '$(TargetFramework)' == '{framework.GetTwoDigitShortFolderName()}' ";
}
}
}

View file

@ -18,7 +18,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration
public ProjectPropertyGroupElement CommonPropertyGroup { get; } public ProjectPropertyGroupElement CommonPropertyGroup { get; }
public IEnumerable<ProjectContext> ProjectContexts { get; } public List<ProjectContext> ProjectContexts { get; }
public ProjectContext DefaultProjectContext public ProjectContext DefaultProjectContext
{ {
@ -36,7 +36,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration
ProjectRootElement projectXproj=null) ProjectRootElement projectXproj=null)
{ {
ProjectXproj = projectXproj; ProjectXproj = projectXproj;
ProjectContexts = projectContexts; ProjectContexts = projectContexts.ToList();
OutputMSBuildProject = outputMSBuildProject; OutputMSBuildProject = outputMSBuildProject;
CommonItemGroup = commonItemGroup; CommonItemGroup = commonItemGroup;
CommonPropertyGroup = commonPropertyGroup; CommonPropertyGroup = commonPropertyGroup;

View file

@ -23,7 +23,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration
ProjectDirectory = projectDirectory; ProjectDirectory = projectDirectory;
OutputDirectory = outputDirectory; OutputDirectory = outputDirectory;
SdkPackageVersion = sdkPackageVersion; SdkPackageVersion = sdkPackageVersion;
MSBuildProjectTemplate = msBuildProjectTemplate; MSBuildProjectTemplate = msBuildProjectTemplate != null ? msBuildProjectTemplate.DeepClone() : null;
ProjectXProjFilePath = projectXprojFilePath; ProjectXProjFilePath = projectXprojFilePath;
} }
} }

View file

@ -11,7 +11,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration
public ProjectDependency(string name, string projectFilePath) public ProjectDependency(string name, string projectFilePath)
{ {
Name = name; Name = name;
ProjectFilePath = projectFilePath; ProjectFilePath = System.IO.Path.GetFullPath(projectFilePath);
} }
} }
} }

View file

@ -5,15 +5,17 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using Microsoft.Build.Construction; using Microsoft.Build.Construction;
using Microsoft.DotNet.ProjectModel; using Microsoft.DotNet.ProjectModel;
using Microsoft.DotNet.ProjectModel.Graph;
using System.Linq; using System.Linq;
using System.IO; using System.IO;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using Microsoft.DotNet.Tools.Common; using Microsoft.DotNet.Tools.Common;
using NuGet.Frameworks;
using NuGet.LibraryModel; using NuGet.LibraryModel;
namespace Microsoft.DotNet.ProjectJsonMigration namespace Microsoft.DotNet.ProjectJsonMigration
{ {
public class ProjectDependencyFinder internal class ProjectDependencyFinder
{ {
public IEnumerable<ProjectDependency> ResolveProjectDependencies(string projectDir, string xprojFile = null) public IEnumerable<ProjectDependency> ResolveProjectDependencies(string projectDir, string xprojFile = null)
{ {
@ -31,25 +33,75 @@ namespace Microsoft.DotNet.ProjectJsonMigration
public IEnumerable<ProjectDependency> ResolveProjectDependencies( public IEnumerable<ProjectDependency> ResolveProjectDependencies(
IEnumerable<ProjectContext> projectContexts, IEnumerable<ProjectContext> projectContexts,
IEnumerable<string> preResolvedProjects=null) IEnumerable<string> preResolvedProjects = null)
{ {
foreach(var projectContext in projectContexts) foreach (var projectContext in projectContexts)
{ {
foreach(var projectDependency in ResolveProjectDependencies(projectContext, preResolvedProjects)) foreach (var projectDependency in ResolveProjectDependencies(projectContext, preResolvedProjects))
{ {
yield return projectDependency; yield return projectDependency;
} }
} }
} }
public IEnumerable<ProjectDependency> ResolveProjectDependencies( public IEnumerable<ProjectDependency> ResolveProjectDependenciesForFramework(
ProjectContext projectContext, Project project,
NuGetFramework framework,
IEnumerable<string> preResolvedProjects=null) IEnumerable<string> preResolvedProjects=null)
{ {
preResolvedProjects = preResolvedProjects ?? new HashSet<string>(); preResolvedProjects = preResolvedProjects ?? new HashSet<string>();
var projectExports = projectContext.CreateExporter("_").GetDependencies();
var possibleProjectDependencies = var possibleProjectDependencies =
FindPossibleProjectDependencies(project.ProjectFilePath);
var projectDependencies = new List<ProjectDependency>();
IEnumerable<ProjectLibraryDependency> projectFileDependenciesForFramework;
if (framework == null)
{
projectFileDependenciesForFramework = project.Dependencies;
}
else
{
projectFileDependenciesForFramework = project.GetTargetFramework(framework).Dependencies;
}
foreach (var projectFileDependency in projectFileDependenciesForFramework)
{
var dependencyName = projectFileDependency.Name;
ProjectDependency projectDependency;
if (preResolvedProjects.Contains(dependencyName))
{
continue;
}
if (!possibleProjectDependencies.TryGetValue(dependencyName, out projectDependency))
{
if (projectFileDependency.LibraryRange.TypeConstraint == LibraryDependencyTarget.Project)
{
MigrationErrorCodes
.MIGRATE1014($"Unresolved project dependency ({dependencyName})").Throw();
}
else
{
continue;
}
}
projectDependencies.Add(projectDependency);
}
return projectDependencies;
}
public IEnumerable<ProjectDependency> ResolveProjectDependencies(ProjectContext projectContext, IEnumerable<string> preResolvedProjects=null)
{
preResolvedProjects = preResolvedProjects ?? new HashSet<string>();
var projectExports = projectContext.CreateExporter("_").GetDependencies();
var possibleProjectDependencies =
FindPossibleProjectDependencies(projectContext.ProjectFile.ProjectFilePath); FindPossibleProjectDependencies(projectContext.ProjectFile.ProjectFilePath);
var projectDependencies = new List<ProjectDependency>(); var projectDependencies = new List<ProjectDependency>();
@ -58,10 +110,14 @@ namespace Microsoft.DotNet.ProjectJsonMigration
var projectExportName = projectExport.Library.Identity.Name; var projectExportName = projectExport.Library.Identity.Name;
ProjectDependency projectDependency; ProjectDependency projectDependency;
if (preResolvedProjects.Contains(projectExportName))
{
continue;
}
if (!possibleProjectDependencies.TryGetValue(projectExportName, out projectDependency)) if (!possibleProjectDependencies.TryGetValue(projectExportName, out projectDependency))
{ {
if (projectExport.Library.Identity.Type.Equals(LibraryType.Project) if (projectExport.Library.Identity.Type.Equals(LibraryType.Project))
&& !preResolvedProjects.Contains(projectExportName))
{ {
MigrationErrorCodes MigrationErrorCodes
.MIGRATE1014($"Unresolved project dependency ({projectExportName})").Throw(); .MIGRATE1014($"Unresolved project dependency ({projectExportName})").Throw();
@ -218,7 +274,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration
return projects; return projects;
} }
private static List<string> GetGlobalPaths(string rootPath) internal static List<string> GetGlobalPaths(string rootPath)
{ {
var paths = new List<string>(); var paths = new List<string>();
@ -301,7 +357,8 @@ namespace Microsoft.DotNet.ProjectJsonMigration
var projects = settings["projects"]; var projects = settings["projects"];
var dependencies = settings["dependencies"] as JObject; var dependencies = settings["dependencies"] as JObject;
globalSettings.ProjectPaths = projects == null ? new string[] { } : projects.Select(a => a.Value<string>()).ToArray();; globalSettings.ProjectPaths = projects == null ? new string[] { } :
projects.Select(a => a.Value<string>()).ToArray();
globalSettings.PackagesPath = settings.Value<string>("packages"); globalSettings.PackagesPath = settings.Value<string>("packages");
globalSettings.FilePath = globalJsonPath; globalSettings.FilePath = globalJsonPath;
} }

View file

@ -16,13 +16,6 @@ namespace Microsoft.DotNet.ProjectJsonMigration
{ {
public class ProjectMigrator public class ProjectMigrator
{ {
// TODO: Migrate PackOptions
// TODO: Migrate Multi-TFM projects
// TODO: Tests
// TODO: Out of Scope
// - Globs that resolve to directories: /some/path/**/somedir
// - Migrating Deprecated project.jsons
private readonly IMigrationRule _ruleSet; private readonly IMigrationRule _ruleSet;
private readonly ProjectDependencyFinder _projectDependencyFinder = new ProjectDependencyFinder(); private readonly ProjectDependencyFinder _projectDependencyFinder = new ProjectDependencyFinder();
@ -39,6 +32,28 @@ namespace Microsoft.DotNet.ProjectJsonMigration
{ {
throw new ArgumentNullException(); throw new ArgumentNullException();
} }
Exception exc = null;
IEnumerable<ProjectDependency> projectDependencies = null;
var tempMSBuildProjectTemplate = rootSettings.MSBuildProjectTemplate.DeepClone();
try
{
projectDependencies = ResolveTransitiveClosureProjectDependencies(
rootSettings.ProjectDirectory,
rootSettings.ProjectXProjFilePath);
}
catch (Exception e)
{
exc = e;
}
// Verify up front so we can prefer these errors over an unresolved project dependency
VerifyInputs(ComputeMigrationRuleInputs(rootSettings), rootSettings);
if (exc != null)
{
throw exc;
}
MigrateProject(rootSettings); MigrateProject(rootSettings);
@ -47,26 +62,40 @@ namespace Microsoft.DotNet.ProjectJsonMigration
return; return;
} }
var projectDependencies = ResolveTransitiveClosureProjectDependencies(rootSettings.ProjectDirectory, rootSettings.ProjectXProjFilePath);
foreach(var project in projectDependencies) foreach(var project in projectDependencies)
{ {
var projectDir = Path.GetDirectoryName(project.ProjectFilePath); var projectDir = Path.GetDirectoryName(project.ProjectFilePath);
var settings = new MigrationSettings(projectDir, var settings = new MigrationSettings(projectDir,
projectDir, projectDir,
rootSettings.SdkPackageVersion, rootSettings.SdkPackageVersion,
rootSettings.MSBuildProjectTemplate); tempMSBuildProjectTemplate);
MigrateProject(settings); MigrateProject(settings);
} }
} }
private void DeleteProjectJsons(MigrationSettings rootsettings, IEnumerable<ProjectDependency> projectDependencies)
{
try
{
File.Delete(Path.Combine(rootsettings.ProjectDirectory, "project.json"));
} catch {}
foreach (var projectDependency in projectDependencies)
{
try
{
File.Delete(projectDependency.ProjectFilePath);
} catch { }
}
}
private IEnumerable<ProjectDependency> ResolveTransitiveClosureProjectDependencies(string rootProject, string xprojFile) private IEnumerable<ProjectDependency> ResolveTransitiveClosureProjectDependencies(string rootProject, string xprojFile)
{ {
HashSet<ProjectDependency> projectsMap = new HashSet<ProjectDependency>(new ProjectDependencyComparer()); HashSet<ProjectDependency> projectsMap = new HashSet<ProjectDependency>(new ProjectDependencyComparer());
var projectDependencies = _projectDependencyFinder.ResolveProjectDependencies(rootProject, xprojFile); var projectDependencies = _projectDependencyFinder.ResolveProjectDependencies(rootProject, xprojFile);
Queue<ProjectDependency> projectsQueue = new Queue<ProjectDependency>(projectDependencies); Queue<ProjectDependency> projectsQueue = new Queue<ProjectDependency>(projectDependencies);
while(projectsQueue.Count() != 0) while (projectsQueue.Count() != 0)
{ {
var projectDependency = projectsQueue.Dequeue(); var projectDependency = projectsQueue.Dequeue();
@ -80,7 +109,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration
var projectDir = Path.GetDirectoryName(projectDependency.ProjectFilePath); var projectDir = Path.GetDirectoryName(projectDependency.ProjectFilePath);
projectDependencies = _projectDependencyFinder.ResolveProjectDependencies(projectDir); projectDependencies = _projectDependencyFinder.ResolveProjectDependencies(projectDir);
foreach(var project in projectDependencies) foreach (var project in projectDependencies)
{ {
projectsQueue.Enqueue(project); projectsQueue.Enqueue(project);
} }
@ -111,7 +140,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration
{ {
var projectContexts = ProjectContext.CreateContextForEachFramework(migrationSettings.ProjectDirectory); var projectContexts = ProjectContext.CreateContextForEachFramework(migrationSettings.ProjectDirectory);
var xprojFile = migrationSettings.ProjectXProjFilePath ?? _projectDependencyFinder.FindXprojFile(migrationSettings.ProjectDirectory); var xprojFile = migrationSettings.ProjectXProjFilePath ?? _projectDependencyFinder.FindXprojFile(migrationSettings.ProjectDirectory);
ProjectRootElement xproj = null; ProjectRootElement xproj = null;
if (xprojFile != null) if (xprojFile != null)
{ {

View file

@ -4,3 +4,4 @@
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
[assembly:InternalsVisibleTo("Microsoft.DotNet.ProjectJsonMigration.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100039ac461fa5c82c7dd2557400c4fd4e9dcdf7ac47e3d572548c04cd4673e004916610f4ea5cbf86f2b1ca1cb824f2a7b3976afecfcf4eb72d9a899aa6786effa10c30399e6580ed848231fec48374e41b3acf8811931343fc2f73acf72dae745adbcb7063cc4b50550618383202875223fc75401351cd89c44bf9b50e7fa3796")] [assembly:InternalsVisibleTo("Microsoft.DotNet.ProjectJsonMigration.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100039ac461fa5c82c7dd2557400c4fd4e9dcdf7ac47e3d572548c04cd4673e004916610f4ea5cbf86f2b1ca1cb824f2a7b3976afecfcf4eb72d9a899aa6786effa10c30399e6580ed848231fec48374e41b3acf8811931343fc2f73acf72dae745adbcb7063cc4b50550618383202875223fc75401351cd89c44bf9b50e7fa3796")]
[assembly: InternalsVisibleTo("dotnet, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]

View file

@ -26,12 +26,17 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Rules
private AddPropertyTransform<CommonCompilerOptions>[] KeyFileTransforms private AddPropertyTransform<CommonCompilerOptions>[] KeyFileTransforms
=> new [] => new []
{ {
new AddPropertyTransform<CommonCompilerOptions>("AssemblyOriginatorKeyFile", new AddPropertyTransform<CommonCompilerOptions>("KeyOriginatorFile",
compilerOptions => compilerOptions.KeyFile, compilerOptions => compilerOptions.KeyFile,
compilerOptions => !string.IsNullOrEmpty(compilerOptions.KeyFile)), compilerOptions => !string.IsNullOrEmpty(compilerOptions.KeyFile)),
new AddPropertyTransform<CommonCompilerOptions>("SignAssembly", new AddPropertyTransform<CommonCompilerOptions>("SignAssembly",
"true", "true",
compilerOptions => !string.IsNullOrEmpty(compilerOptions.KeyFile)) compilerOptions => !string.IsNullOrEmpty(compilerOptions.KeyFile))
.WithMSBuildCondition(" '$(OS)' == 'Windows_NT' "),
new AddPropertyTransform<CommonCompilerOptions>("PublicSign",
"true",
compilerOptions => !string.IsNullOrEmpty(compilerOptions.KeyFile) && (compilerOptions.PublicSign == null))
.WithMSBuildCondition(" '$(OS)' != 'Windows_NT' ")
}; };
private AddPropertyTransform<CommonCompilerOptions> DefineTransform => new AddPropertyTransform<CommonCompilerOptions>( private AddPropertyTransform<CommonCompilerOptions> DefineTransform => new AddPropertyTransform<CommonCompilerOptions>(

View file

@ -0,0 +1,52 @@
// 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 System.IO;
using Microsoft.DotNet.ProjectJsonMigration.Transforms;
using Microsoft.Build.Construction;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace Microsoft.DotNet.ProjectJsonMigration.Rules
{
public class MigrateJsonPropertiesRule : IMigrationRule
{
private Dictionary<string, ConditionalTransform<JToken, ProjectPropertyElement>> _propertyMappings
= new Dictionary<string, ConditionalTransform<JToken, ProjectPropertyElement>>
{
["userSecretsId"] = new AddPropertyTransform<JToken>("UserSecretsId",
j => j.Value<string>(),
j => !string.IsNullOrEmpty(j.Value<string>()))
};
private readonly ITransformApplicator _transformApplicator;
public MigrateJsonPropertiesRule(ITransformApplicator transformApplicator = null)
{
_transformApplicator = transformApplicator ?? new TransformApplicator();
}
public void Apply(MigrationSettings migrationSettings, MigrationRuleInputs migrationRuleInputs)
{
var propertyGroup = migrationRuleInputs.CommonPropertyGroup;
var projectFile = migrationRuleInputs.DefaultProjectContext.ProjectFile.ProjectFilePath;
using (var stream = new FileStream(projectFile, FileMode.Open))
using (var streamReader = new StreamReader(stream))
using (var jsonReader = new JsonTextReader(streamReader))
{
var rawProject = JObject.Load(jsonReader);
foreach (var prop in _propertyMappings)
{
var token = rawProject.GetValue(prop.Key);
if (token != null)
{
_transformApplicator.Execute(prop.Value.Transform(token), propertyGroup);
}
}
}
}
}
}

View file

@ -0,0 +1,254 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.Build.Construction;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.ProjectJsonMigration.Transforms;
using Microsoft.DotNet.ProjectModel;
using Microsoft.DotNet.ProjectModel.Graph;
using Microsoft.DotNet.Tools.Common;
using NuGet.Frameworks;
using NuGet.LibraryModel;
namespace Microsoft.DotNet.ProjectJsonMigration.Rules
{
public class MigratePackageDependenciesAndToolsRule : IMigrationRule
{
private readonly ITransformApplicator _transformApplicator;
private readonly ProjectDependencyFinder _projectDependencyFinder;
private string _projectDirectory;
public MigratePackageDependenciesAndToolsRule(ITransformApplicator transformApplicator = null)
{
_transformApplicator = transformApplicator ?? new TransformApplicator();
_projectDependencyFinder = new ProjectDependencyFinder();
}
public void Apply(MigrationSettings migrationSettings, MigrationRuleInputs migrationRuleInputs)
{
CleanExistingPackageReferences(migrationRuleInputs.OutputMSBuildProject);
_projectDirectory = migrationSettings.ProjectDirectory;
var project = migrationRuleInputs.DefaultProjectContext.ProjectFile;
var tfmDependencyMap = new Dictionary<string, IEnumerable<ProjectLibraryDependency>>();
var targetFrameworks = project.GetTargetFrameworks();
// Inject Sdk dependency
_transformApplicator.Execute(
PackageDependencyInfoTransform.Transform(
new PackageDependencyInfo
{
Name = ConstantPackageNames.CSdkPackageName,
Version = migrationSettings.SdkPackageVersion
}), migrationRuleInputs.CommonItemGroup);
// Migrate Direct Deps first
MigrateDependencies(
project,
migrationRuleInputs.OutputMSBuildProject,
null,
project.Dependencies,
migrationRuleInputs.ProjectXproj);
MigrationTrace.Instance.WriteLine($"Migrating {targetFrameworks.Count()} target frameworks");
foreach (var targetFramework in targetFrameworks)
{
MigrationTrace.Instance.WriteLine($"Migrating framework {targetFramework.FrameworkName.GetShortFolderName()}");
MigrateImports(migrationRuleInputs.CommonItemGroup, targetFramework);
MigrateDependencies(
project,
migrationRuleInputs.OutputMSBuildProject,
targetFramework.FrameworkName,
targetFramework.Dependencies,
migrationRuleInputs.ProjectXproj);
}
// Tools
MigrateTools(project, migrationRuleInputs.OutputMSBuildProject);
}
private void MigrateImports(ProjectItemGroupElement commonItemGroup, TargetFrameworkInformation targetFramework)
{
var transform = ImportsTransformation.Transform(targetFramework);
if (transform != null)
{
transform.Condition = targetFramework.FrameworkName.GetMSBuildCondition();
_transformApplicator.Execute(transform, commonItemGroup);
}
}
private void CleanExistingPackageReferences(ProjectRootElement outputMSBuildProject)
{
var packageRefs = outputMSBuildProject.Items.Where(i => i.ItemType == "PackageReference").ToList();
foreach (var packageRef in packageRefs)
{
var parent = packageRef.Parent;
packageRef.Parent.RemoveChild(packageRef);
parent.RemoveIfEmpty();
}
}
private void MigrateTools(
Project project,
ProjectRootElement output)
{
if (project.Tools == null || !project.Tools.Any())
{
return;
}
var itemGroup = output.AddItemGroup();
foreach (var tool in project.Tools)
{
_transformApplicator.Execute(ToolTransform.Transform(tool), itemGroup);
}
}
private void MigrateDependencies(
Project project,
ProjectRootElement output,
NuGetFramework framework,
IEnumerable<ProjectLibraryDependency> dependencies,
ProjectRootElement xproj)
{
var projectDependencies = new HashSet<string>(GetAllProjectReferenceNames(project, framework, xproj));
var packageDependencies = dependencies.Where(d => !projectDependencies.Contains(d.Name));
string condition = framework?.GetMSBuildCondition() ?? "";
var itemGroup = output.ItemGroups.FirstOrDefault(i => i.Condition == condition)
?? output.AddItemGroup();
itemGroup.Condition = condition;
foreach (var packageDependency in packageDependencies)
{
MigrationTrace.Instance.WriteLine(packageDependency.Name);
AddItemTransform<ProjectLibraryDependency> transform;
if (packageDependency.LibraryRange.TypeConstraint == LibraryDependencyTarget.Reference)
{
transform = FrameworkDependencyTransform;
}
else
{
transform = PackageDependencyTransform();
if (packageDependency.Type == LibraryDependencyType.Build)
{
Console.WriteLine("Build type!!!");
transform = transform.WithMetadata("PrivateAssets", "all");
}
else if (packageDependency.SuppressParent != LibraryIncludeFlagUtils.DefaultSuppressParent)
{
var metadataValue = ReadLibraryIncludeFlags(packageDependency.SuppressParent);
transform = transform.WithMetadata("PrivateAssets", metadataValue);
}
if (packageDependency.IncludeType != LibraryIncludeFlags.All)
{
var metadataValue = ReadLibraryIncludeFlags(packageDependency.IncludeType);
transform = transform.WithMetadata("IncludeAssets", metadataValue);
}
}
_transformApplicator.Execute(transform.Transform(packageDependency), itemGroup);
}
}
private string ReadLibraryIncludeFlags(LibraryIncludeFlags includeFlags)
{
if ((includeFlags & LibraryIncludeFlags.All) == LibraryIncludeFlags.All)
{
return "All";
}
var flagString = "";
var allFlagsAndNames = new List<Tuple<string, LibraryIncludeFlags>>
{
Tuple.Create("Analyzers", LibraryIncludeFlags.Analyzers),
Tuple.Create("Build", LibraryIncludeFlags.Build),
Tuple.Create("Compile", LibraryIncludeFlags.Compile),
Tuple.Create("ContentFiles", LibraryIncludeFlags.ContentFiles),
Tuple.Create("Native", LibraryIncludeFlags.Native),
Tuple.Create("Runtime", LibraryIncludeFlags.Runtime)
};
foreach (var flagAndName in allFlagsAndNames)
{
var name = flagAndName.Item1;
var flag = flagAndName.Item2;
if ((includeFlags & flag) == flag)
{
if (!string.IsNullOrEmpty(flagString))
{
flagString += ";";
}
flagString += name;
}
}
return flagString;
}
private IEnumerable<string> GetAllProjectReferenceNames(Project project, NuGetFramework framework, ProjectRootElement xproj)
{
var csprojReferenceItems = _projectDependencyFinder.ResolveXProjProjectDependencies(xproj);
var migratedXProjDependencyPaths = csprojReferenceItems.SelectMany(p => p.Includes());
var migratedXProjDependencyNames = new HashSet<string>(migratedXProjDependencyPaths.Select(p => Path.GetFileNameWithoutExtension(
PathUtility.GetPathWithDirectorySeparator(p))));
var projectDependencies = _projectDependencyFinder.ResolveProjectDependenciesForFramework(
project,
framework,
preResolvedProjects: migratedXProjDependencyNames);
return projectDependencies.Select(p => p.Name).Concat(migratedXProjDependencyNames);
}
private AddItemTransform<ProjectLibraryDependency> FrameworkDependencyTransform => new AddItemTransform<ProjectLibraryDependency>(
"Reference",
dep => dep.Name,
dep => "",
dep => true);
private Func<AddItemTransform<ProjectLibraryDependency>> PackageDependencyTransform => () => new AddItemTransform<ProjectLibraryDependency>(
"PackageReference",
dep => dep.Name,
dep => "",
dep => true)
.WithMetadata("Version", r => r.LibraryRange.VersionRange.OriginalString);
private AddItemTransform<PackageDependencyInfo> PackageDependencyInfoTransform => new AddItemTransform<PackageDependencyInfo>(
"PackageReference",
dep => dep.Name,
dep => "",
dep => true)
.WithMetadata("Version", r => r.Version);
private AddItemTransform<ProjectLibraryDependency> ToolTransform => new AddItemTransform<ProjectLibraryDependency>(
"DotNetCliToolReference",
dep => dep.Name,
dep => "",
dep => true)
.WithMetadata("Version", r => r.LibraryRange.VersionRange.OriginalString);
private AddItemTransform<TargetFrameworkInformation> ImportsTransformation => new AddItemTransform<TargetFrameworkInformation>(
"PackageTargetFallback",
t => $"$(PackageTargetFallback);{string.Join(";", t.Imports)}",
t => "",
t => t.Imports.OrEmptyIfNull().Any());
private class PackageDependencyInfo
{
public string Name {get; set;}
public string Version {get; set;}
}
}
}

View file

@ -1,93 +0,0 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
using System.IO;
using System.Linq;
using Newtonsoft.Json.Linq;
namespace Microsoft.DotNet.ProjectJsonMigration.Rules
{
/// <summary>
/// This rule is temporary while project.json still exists in the new project system.
/// It renames your existing project.json (if output directory is the current project directory),
/// creates a copy, then mutates that copy.
///
/// Mutations:
/// - inject a dependency on the Microsoft.SDK targets
/// - removing the "runtimes" node.
/// </summary>
public class TemporaryMutateProjectJsonRule : IMigrationRule
{
public void Apply(MigrationSettings migrationSettings, MigrationRuleInputs migrationRuleInputs)
{
bool shouldRenameOldProject = PathsAreEqual(migrationSettings.OutputDirectory, migrationSettings.ProjectDirectory);
if (!shouldRenameOldProject && File.Exists(Path.Combine(migrationSettings.OutputDirectory, "project.json")))
{
// TODO: should there be a setting to overwrite anything in output directory?
throw new Exception("Existing project.json found in output directory.");
}
var sourceProjectFile = Path.Combine(migrationSettings.ProjectDirectory, "project.json");
var destinationProjectFile = Path.Combine(migrationSettings.OutputDirectory, "project.json");
if (shouldRenameOldProject)
{
var renamedProjectFile = Path.Combine(migrationSettings.ProjectDirectory, "project.migrated.json");
File.Move(sourceProjectFile, renamedProjectFile);
sourceProjectFile = renamedProjectFile;
}
var json = CreateDestinationProjectFile(sourceProjectFile, destinationProjectFile);
InjectSdkReference(json, ConstantPackageNames.CSdkPackageName, migrationSettings.SdkPackageVersion);
RemoveRuntimesNode(json);
File.WriteAllText(destinationProjectFile, json.ToString());
}
private JObject CreateDestinationProjectFile(string sourceProjectFile, string destinationProjectFile)
{
File.Copy(sourceProjectFile, destinationProjectFile);
return JObject.Parse(File.ReadAllText(destinationProjectFile));
}
private void InjectSdkReference(JObject json, string sdkPackageName, string sdkPackageVersion)
{
JToken dependenciesNode;
if (json.TryGetValue("dependencies", out dependenciesNode))
{
var dependenciesNodeObject = dependenciesNode.Value<JObject>();
dependenciesNodeObject.Add(sdkPackageName, sdkPackageVersion);
}
else
{
var dependenciesNodeObject = new JObject();
dependenciesNodeObject.Add(sdkPackageName, sdkPackageVersion);
json.Add("dependencies", dependenciesNodeObject);
}
}
private void RemoveRuntimesNode(JObject json)
{
json.Remove("runtimes");
}
private bool PathsAreEqual(params string[] paths)
{
var normalizedPaths = paths.Select(path => Path.GetFullPath(path).TrimEnd(Path.DirectorySeparatorChar)).ToList();
for (int i=1; i<normalizedPaths.Count(); ++i)
{
var path1 = normalizedPaths[i - 1];
var path2 = normalizedPaths[i];
if (!string.Equals(path1, path2, StringComparison.Ordinal))
{
return false;
}
}
return true;
}
}
}

View file

@ -1,29 +0,0 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using Microsoft.DotNet.ProjectJsonMigration.Transforms;
namespace Microsoft.DotNet.ProjectJsonMigration.Rules
{
public class WorkaroundOptionsRule : IMigrationRule
{
private readonly ITransformApplicator _transformApplicator;
private AddPropertyTransform<object> ProjectLockFileTransform =>
new AddPropertyTransform<object>("ProjectLockFile",
frameworks => "$(MSBuildProjectDirectory)/project.lock.json",
frameworks => true);
public WorkaroundOptionsRule(ITransformApplicator transformApplicator = null)
{
_transformApplicator = transformApplicator ?? new TransformApplicator();
}
public void Apply(MigrationSettings migrationSettings, MigrationRuleInputs migrationRuleInputs)
{
var propertyGroup = migrationRuleInputs.CommonPropertyGroup;
_transformApplicator.Execute(ProjectLockFileTransform.Transform(string.Empty), propertyGroup);
}
}
}

View file

@ -14,6 +14,8 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Transforms
private readonly string _propertyValue; private readonly string _propertyValue;
private readonly Func<T,string> _propertyValueFunc; private readonly Func<T,string> _propertyValueFunc;
private string _msbuildCondition = null;
public AddPropertyTransform(string propertyName, string propertyValue, Func<T,bool> condition) public AddPropertyTransform(string propertyName, string propertyValue, Func<T,bool> condition)
: base(condition) : base(condition)
{ {
@ -28,13 +30,24 @@ namespace Microsoft.DotNet.ProjectJsonMigration.Transforms
_propertyValueFunc = propertyValueFunc; _propertyValueFunc = propertyValueFunc;
} }
public AddPropertyTransform<T> WithMSBuildCondition(string condition)
{
_msbuildCondition = condition;
return this;
}
public override ProjectPropertyElement ConditionallyTransform(T source) public override ProjectPropertyElement ConditionallyTransform(T source)
{ {
string propertyValue = GetPropertyValue(source); string propertyValue = GetPropertyValue(source);
var property = _propertyObjectGenerator.CreatePropertyElement(PropertyName); var property = _propertyObjectGenerator.CreatePropertyElement(PropertyName);
property.Value = propertyValue; property.Value = propertyValue;
if (!string.IsNullOrEmpty(_msbuildCondition))
{
property.Condition = _msbuildCondition;
}
return property; return property;
} }

View file

@ -278,6 +278,11 @@ namespace Microsoft.DotNet.ProjectModel
var dependencyValue = dependency.Value; var dependencyValue = dependency.Value;
var dependencyTypeValue = LibraryDependencyType.Default; var dependencyTypeValue = LibraryDependencyType.Default;
var dependencyIncludeFlagsValue = LibraryIncludeFlags.All;
var dependencyExcludeFlagsValue = LibraryIncludeFlags.None;
var suppressParentFlagsValue = LibraryIncludeFlagUtils.DefaultSuppressParent;
var target = isGacOrFrameworkReference ? LibraryDependencyTarget.Reference : LibraryDependencyTarget.All; var target = isGacOrFrameworkReference ? LibraryDependencyTarget.Reference : LibraryDependencyTarget.All;
string dependencyVersionAsString = null; string dependencyVersionAsString = null;
@ -298,6 +303,23 @@ namespace Microsoft.DotNet.ProjectModel
var targetStr = dependencyValue.Value<string>("target"); var targetStr = dependencyValue.Value<string>("target");
target = LibraryDependencyTargetUtils.Parse(targetStr); target = LibraryDependencyTargetUtils.Parse(targetStr);
} }
IEnumerable<string> strings;
if (TryGetStringEnumerable(dependencyValue["include"], out strings))
{
dependencyIncludeFlagsValue = LibraryIncludeFlagUtils.GetFlags(strings);
}
if (TryGetStringEnumerable(dependencyValue["exclude"], out strings))
{
dependencyExcludeFlagsValue = LibraryIncludeFlagUtils.GetFlags(strings);
}
if (TryGetStringEnumerable(dependencyValue["suppressParent"], out strings))
{
// This overrides any settings that came from the type property.
suppressParentFlagsValue = LibraryIncludeFlagUtils.GetFlags(strings);
}
} }
else if (dependencyValue.Type == JTokenType.String) else if (dependencyValue.Type == JTokenType.String)
{ {
@ -327,6 +349,9 @@ namespace Microsoft.DotNet.ProjectModel
} }
} }
// the dependency flags are: Include flags - Exclude flags
var includeFlags = dependencyIncludeFlagsValue & ~dependencyExcludeFlagsValue;
var lineInfo = (IJsonLineInfo)dependencyValue; var lineInfo = (IJsonLineInfo)dependencyValue;
results.Add(new ProjectLibraryDependency results.Add(new ProjectLibraryDependency
{ {
@ -335,6 +360,8 @@ namespace Microsoft.DotNet.ProjectModel
dependencyVersionRange, dependencyVersionRange,
target), target),
Type = dependencyTypeValue, Type = dependencyTypeValue,
IncludeType = includeFlags,
SuppressParent = suppressParentFlagsValue,
SourceFilePath = projectPath, SourceFilePath = projectPath,
SourceLine = lineInfo.LineNumber, SourceLine = lineInfo.LineNumber,
SourceColumn = lineInfo.LinePosition SourceColumn = lineInfo.LinePosition
@ -472,7 +499,8 @@ namespace Microsoft.DotNet.ProjectModel
Dependencies = new List<ProjectLibraryDependency>(), Dependencies = new List<ProjectLibraryDependency>(),
CompilerOptions = compilerOptions, CompilerOptions = compilerOptions,
Line = lineInfo.LineNumber, Line = lineInfo.LineNumber,
Column = lineInfo.LinePosition Column = lineInfo.LinePosition,
Imports = GetImports(frameworkValue)
}; };
var frameworkDependencies = new List<ProjectLibraryDependency>(); var frameworkDependencies = new List<ProjectLibraryDependency>();
@ -508,6 +536,26 @@ namespace Microsoft.DotNet.ProjectModel
return true; return true;
} }
private IEnumerable<string> GetImports(JObject frameworkValue)
{
var prop = frameworkValue.Property("imports");
if (prop == null)
{
return Enumerable.Empty<string>();
}
if (prop.Type == JTokenType.Array)
{
return prop.Value<IEnumerable<string>>();
}
else if (prop.Type == JTokenType.String)
{
return new [] { prop.Value<string>() };
}
return null;
}
private static CommonCompilerOptions GetCompilationOptions(JObject rawObject, Project project) private static CommonCompilerOptions GetCompilationOptions(JObject rawObject, Project project)
{ {
var compilerName = rawObject.Value<string>("compilerName"); var compilerName = rawObject.Value<string>("compilerName");
@ -819,5 +867,29 @@ namespace Microsoft.DotNet.ProjectModel
lineInfo.LineNumber, lineInfo.LineNumber,
lineInfo.LinePosition)); lineInfo.LinePosition));
} }
private static bool TryGetStringEnumerable(JToken token, out IEnumerable<string> result)
{
IEnumerable<string> values;
if (token == null)
{
result = null;
return false;
}
else if (token.Type == JTokenType.String)
{
values = new[]
{
token.Value<string>()
};
}
else
{
values = token.Value<string[]>();
}
result = values
.SelectMany(value => value.Split(new[] { ' ', ',' }, StringSplitOptions.RemoveEmptyEntries));
return true;
}
} }
} }

View file

@ -13,20 +13,6 @@ namespace Microsoft.DotNet.InternalAbstractions
// We should clean this up. Filed #619 to track. // We should clean this up. Filed #619 to track.
public static class RuntimeEnvironmentRidExtensions public static class RuntimeEnvironmentRidExtensions
{ {
// Work around NuGet/Home#1941
public static IEnumerable<string> GetOverrideRestoreRuntimeIdentifiers()
{
if (RuntimeEnvironment.OperatingSystemPlatform != Platform.Windows)
{
yield return RuntimeEnvironment.GetRuntimeIdentifier();
}
else
{
yield return "win7-x86";
yield return "win7-x64";
}
}
// Gets the identfier that is used for restore by default (this is different from the actual RID, but only on Windows) // Gets the identfier that is used for restore by default (this is different from the actual RID, but only on Windows)
public static string GetLegacyRestoreRuntimeIdentifier() public static string GetLegacyRestoreRuntimeIdentifier()
{ {
@ -43,36 +29,56 @@ namespace Microsoft.DotNet.InternalAbstractions
public static IEnumerable<string> GetAllCandidateRuntimeIdentifiers() public static IEnumerable<string> GetAllCandidateRuntimeIdentifiers()
{ {
return GetAllCandidateRuntimeIdentifiers(null);
}
public static IEnumerable<string> GetAllCandidateRuntimeIdentifiers(IEnumerable<string> fallbackIdentifiers = null)
{
List<string> result = new List<string>();
if (RuntimeEnvironment.OperatingSystemPlatform != Platform.Windows) if (RuntimeEnvironment.OperatingSystemPlatform != Platform.Windows)
{ {
yield return RuntimeEnvironment.GetRuntimeIdentifier(); result.Add(RuntimeEnvironment.GetRuntimeIdentifier());
} }
else else
{ {
var arch = RuntimeEnvironment.RuntimeArchitecture.ToLowerInvariant(); var arch = RuntimeEnvironment.RuntimeArchitecture.ToLowerInvariant();
if (RuntimeEnvironment.OperatingSystemVersion.StartsWith("6.1", StringComparison.Ordinal)) if (RuntimeEnvironment.OperatingSystemVersion.StartsWith("6.1", StringComparison.Ordinal))
{ {
yield return "win7-" + arch; result.Add("win7-" + arch);
} }
else if (RuntimeEnvironment.OperatingSystemVersion.StartsWith("6.2", StringComparison.Ordinal)) else if (RuntimeEnvironment.OperatingSystemVersion.StartsWith("6.2", StringComparison.Ordinal))
{ {
yield return "win8-" + arch; result.Add("win8-" + arch);
yield return "win7-" + arch; result.Add("win7-" + arch);
} }
else if (RuntimeEnvironment.OperatingSystemVersion.StartsWith("6.3", StringComparison.Ordinal)) else if (RuntimeEnvironment.OperatingSystemVersion.StartsWith("6.3", StringComparison.Ordinal))
{ {
yield return "win81-" + arch; result.Add("win81-" + arch);
yield return "win8-" + arch; result.Add("win8-" + arch);
yield return "win7-" + arch; result.Add("win7-" + arch);
} }
else if (RuntimeEnvironment.OperatingSystemVersion.StartsWith("10.0", StringComparison.Ordinal)) else if (RuntimeEnvironment.OperatingSystemVersion.StartsWith("10.0", StringComparison.Ordinal))
{ {
yield return "win10-" + arch; result.Add("win10-" + arch);
yield return "win81-" + arch; result.Add("win81-" + arch);
yield return "win8-" + arch; result.Add("win8-" + arch);
yield return "win7-" + arch; result.Add("win7-" + arch);
} }
} }
if (fallbackIdentifiers != null)
{
foreach (string fallbackIdentifier in fallbackIdentifiers)
{
if (!result.Contains(fallbackIdentifier))
{
result.Add(fallbackIdentifier);
}
}
}
return result;
} }
} }
} }

View file

@ -22,5 +22,7 @@ namespace Microsoft.DotNet.ProjectModel
public string WrappedProject { get; set; } public string WrappedProject { get; set; }
public string AssemblyPath { get; set; } public string AssemblyPath { get; set; }
public IEnumerable<string> Imports { get; set; }
} }
} }

View file

@ -4,7 +4,6 @@
using System; using System;
using System.IO; using System.IO;
using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.InternalAbstractions;
using Microsoft.DotNet.ProjectModel; using Microsoft.DotNet.ProjectModel;
using System.Linq; using System.Linq;
using NuGet.Frameworks; using NuGet.Frameworks;
@ -28,7 +27,7 @@ namespace Microsoft.DotNet.Tools.Test
var projectPath = GetProjectPath(dotnetTestParams.ProjectOrAssemblyPath); var projectPath = GetProjectPath(dotnetTestParams.ProjectOrAssemblyPath);
var runtimeIdentifiers = !string.IsNullOrEmpty(dotnetTestParams.Runtime) var runtimeIdentifiers = !string.IsNullOrEmpty(dotnetTestParams.Runtime)
? new[] {dotnetTestParams.Runtime} ? new[] {dotnetTestParams.Runtime}
: RuntimeEnvironmentRidExtensions.GetAllCandidateRuntimeIdentifiers(); : DotnetRuntimeIdentifiers.InferCurrentRuntimeIdentifiers();
var exitCode = 0; var exitCode = 0;
// Create a workspace // Create a workspace

View file

@ -0,0 +1,315 @@
// 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 System.Security.Cryptography;
using System.Text;
using Microsoft.Extensions.DependencyModel;
using NuGet.Frameworks;
using NuGet.Packaging;
using NuGet.Packaging.Core;
using NuGet.ProjectModel;
namespace Microsoft.DotNet.Cli.CommandResolution
{
internal class DepsJsonBuilder
{
private readonly VersionFolderPathResolver _versionFolderPathResolver;
public DepsJsonBuilder()
{
// This resolver is only used for building file names, so that base path is not required.
_versionFolderPathResolver = new VersionFolderPathResolver(path: null);
}
public DependencyContext Build(
SingleProjectInfo mainProjectInfo,
CompilationOptions compilationOptions,
LockFile lockFile,
NuGetFramework framework,
string runtime)
{
bool includeCompilationLibraries = compilationOptions != null;
LockFileTarget lockFileTarget = lockFile.GetTarget(framework, runtime);
IEnumerable<LockFileTargetLibrary> runtimeExports = lockFileTarget.GetRuntimeLibraries();
IEnumerable<LockFileTargetLibrary> compilationExports =
includeCompilationLibraries ?
lockFileTarget.GetCompileLibraries() :
Enumerable.Empty<LockFileTargetLibrary>();
var dependencyLookup = compilationExports
.Concat(runtimeExports)
.Distinct()
.Select(library => new Dependency(library.Name, library.Version.ToString()))
.ToDictionary(dependency => dependency.Name, StringComparer.OrdinalIgnoreCase);
var libraryLookup = lockFile.Libraries.ToDictionary(l => l.Name, StringComparer.OrdinalIgnoreCase);
var runtimeSignature = GenerateRuntimeSignature(runtimeExports);
IEnumerable<RuntimeLibrary> runtimeLibraries =
GetLibraries(runtimeExports, libraryLookup, dependencyLookup, runtime: true).Cast<RuntimeLibrary>();
IEnumerable<CompilationLibrary> compilationLibraries;
if (includeCompilationLibraries)
{
CompilationLibrary projectCompilationLibrary = GetProjectCompilationLibrary(
mainProjectInfo,
lockFile,
lockFileTarget,
dependencyLookup);
compilationLibraries = new[] { projectCompilationLibrary }
.Concat(
GetLibraries(compilationExports, libraryLookup, dependencyLookup, runtime: false)
.Cast<CompilationLibrary>());
}
else
{
compilationLibraries = Enumerable.Empty<CompilationLibrary>();
}
return new DependencyContext(
new TargetInfo(framework.DotNetFrameworkName, runtime, runtimeSignature, lockFileTarget.IsPortable()),
compilationOptions ?? CompilationOptions.Default,
compilationLibraries,
runtimeLibraries,
new RuntimeFallbacks[] { });
}
private static string GenerateRuntimeSignature(IEnumerable<LockFileTargetLibrary> runtimeExports)
{
var sha1 = SHA1.Create();
var builder = new StringBuilder();
var packages = runtimeExports
.Where(libraryExport => libraryExport.Type == "package");
var separator = "|";
foreach (var libraryExport in packages)
{
builder.Append(libraryExport.Name);
builder.Append(separator);
builder.Append(libraryExport.Version.ToString());
builder.Append(separator);
}
var hash = sha1.ComputeHash(Encoding.UTF8.GetBytes(builder.ToString()));
builder.Clear();
foreach (var hashByte in hash)
{
builder.AppendFormat("{0:x2}", hashByte);
}
return builder.ToString();
}
private List<Dependency> GetProjectDependencies(
LockFile lockFile,
LockFileTarget lockFileTarget,
Dictionary<string, Dependency> dependencyLookup)
{
List<Dependency> dependencies = new List<Dependency>();
IEnumerable<ProjectFileDependencyGroup> projectFileDependencies = lockFile
.ProjectFileDependencyGroups
.Where(dg => dg.FrameworkName == string.Empty ||
dg.FrameworkName == lockFileTarget.TargetFramework.DotNetFrameworkName);
foreach (string projectFileDependency in projectFileDependencies.SelectMany(dg => dg.Dependencies))
{
int separatorIndex = projectFileDependency.IndexOf(' ');
string dependencyName = separatorIndex > 0 ?
projectFileDependency.Substring(0, separatorIndex) :
projectFileDependency;
Dependency dependency;
if (dependencyLookup.TryGetValue(dependencyName, out dependency))
{
dependencies.Add(dependency);
}
}
return dependencies;
}
private RuntimeLibrary GetProjectRuntimeLibrary(
SingleProjectInfo projectInfo,
LockFile lockFile,
LockFileTarget lockFileTarget,
Dictionary<string, Dependency> dependencyLookup)
{
RuntimeAssetGroup[] runtimeAssemblyGroups = new[] { new RuntimeAssetGroup(string.Empty, projectInfo.GetOutputName()) };
List<Dependency> dependencies = GetProjectDependencies(lockFile, lockFileTarget, dependencyLookup);
ResourceAssembly[] resourceAssemblies = projectInfo
.ResourceAssemblies
.Select(r => new ResourceAssembly(r.RelativePath, r.Culture))
.ToArray();
return new RuntimeLibrary(
type: "project",
name: projectInfo.Name,
version: projectInfo.Version,
hash: string.Empty,
runtimeAssemblyGroups: runtimeAssemblyGroups,
nativeLibraryGroups: new RuntimeAssetGroup[] { },
resourceAssemblies: resourceAssemblies,
dependencies: dependencies.ToArray(),
serviceable: false);
}
private CompilationLibrary GetProjectCompilationLibrary(
SingleProjectInfo projectInfo,
LockFile lockFile,
LockFileTarget lockFileTarget,
Dictionary<string, Dependency> dependencyLookup)
{
List<Dependency> dependencies = GetProjectDependencies(lockFile, lockFileTarget, dependencyLookup);
return new CompilationLibrary(
type: "project",
name: projectInfo.Name,
version: projectInfo.Version,
hash: string.Empty,
assemblies: new[] { projectInfo.GetOutputName() },
dependencies: dependencies.ToArray(),
serviceable: false);
}
private IEnumerable<Library> GetLibraries(
IEnumerable<LockFileTargetLibrary> exports,
IDictionary<string, LockFileLibrary> libraryLookup,
IDictionary<string, Dependency> dependencyLookup,
bool runtime)
{
return exports.Select(export => GetLibrary(export, libraryLookup, dependencyLookup, runtime));
}
private Library GetLibrary(
LockFileTargetLibrary export,
IDictionary<string, LockFileLibrary> libraryLookup,
IDictionary<string, Dependency> dependencyLookup,
bool runtime)
{
var type = export.Type;
// TEMPORARY: All packages are serviceable in RC2
// See https://github.com/dotnet/cli/issues/2569
var serviceable = export.Type == "package";
var libraryDependencies = new HashSet<Dependency>();
foreach (PackageDependency libraryDependency in export.Dependencies)
{
Dependency dependency;
if (dependencyLookup.TryGetValue(libraryDependency.Id, out dependency))
{
libraryDependencies.Add(dependency);
}
}
string hash = string.Empty;
string path = null;
string hashPath = null;
LockFileLibrary library;
if (libraryLookup.TryGetValue(export.Name, out library))
{
if (!string.IsNullOrEmpty(library.Sha512))
{
hash = "sha512-" + library.Sha512;
hashPath = _versionFolderPathResolver.GetHashFileName(export.Name, export.Version);
}
path = library.Path;
}
if (runtime)
{
return new RuntimeLibrary(
type.ToLowerInvariant(),
export.Name,
export.Version.ToString(),
hash,
CreateRuntimeAssemblyGroups(export),
CreateNativeLibraryGroups(export),
export.ResourceAssemblies.FilterPlaceHolderFiles().Select(CreateResourceAssembly),
libraryDependencies,
serviceable,
path,
hashPath);
}
else
{
IEnumerable<string> assemblies = export
.CompileTimeAssemblies
.FilterPlaceHolderFiles()
.Select(libraryAsset => libraryAsset.Path);
return new CompilationLibrary(
type.ToString().ToLowerInvariant(),
export.Name,
export.Version.ToString(),
hash,
assemblies,
libraryDependencies,
serviceable,
path,
hashPath);
}
}
private IReadOnlyList<RuntimeAssetGroup> CreateRuntimeAssemblyGroups(LockFileTargetLibrary export)
{
List<RuntimeAssetGroup> assemblyGroups = new List<RuntimeAssetGroup>();
assemblyGroups.Add(
new RuntimeAssetGroup(
string.Empty,
export.RuntimeAssemblies.FilterPlaceHolderFiles().Select(a => a.Path)));
foreach (var runtimeTargetsGroup in export.GetRuntimeTargetsGroups("runtime"))
{
assemblyGroups.Add(
new RuntimeAssetGroup(
runtimeTargetsGroup.Key,
runtimeTargetsGroup.Select(t => t.Path)));
}
return assemblyGroups;
}
private IReadOnlyList<RuntimeAssetGroup> CreateNativeLibraryGroups(LockFileTargetLibrary export)
{
List<RuntimeAssetGroup> nativeGroups = new List<RuntimeAssetGroup>();
nativeGroups.Add(
new RuntimeAssetGroup(
string.Empty,
export.NativeLibraries.FilterPlaceHolderFiles().Select(a => a.Path)));
foreach (var runtimeTargetsGroup in export.GetRuntimeTargetsGroups("native"))
{
nativeGroups.Add(
new RuntimeAssetGroup(
runtimeTargetsGroup.Key,
runtimeTargetsGroup.Select(t => t.Path)));
}
return nativeGroups;
}
private ResourceAssembly CreateResourceAssembly(LockFileItem resourceAssembly)
{
string locale;
if (!resourceAssembly.Properties.TryGetValue("locale", out locale))
{
locale = null;
}
return new ResourceAssembly(resourceAssembly.Path, locale);
}
}
}

View file

@ -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.
using System.Collections.Generic;
using NuGet.ProjectModel;
namespace Microsoft.DotNet.Cli.CommandResolution
{
internal interface IProject
{
LockFile GetLockFile();
IEnumerable<SingleProjectInfo> GetTools();
}
}

View file

@ -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;
using System.Collections.Generic;
using System.Linq;
using NuGet.Packaging.Core;
using NuGet.ProjectModel;
namespace Microsoft.DotNet.Cli.CommandResolution
{
internal static class LockFileTargetExtensions
{
public static bool IsPortable(this LockFileTarget lockFileTarget)
{
return string.IsNullOrEmpty(lockFileTarget.RuntimeIdentifier) &&
lockFileTarget.GetPlatformLibrary() != null;
}
public static LockFileTargetLibrary GetPlatformLibrary(this LockFileTarget lockFileTarget)
{
// TODO: https://github.com/dotnet/sdk/issues/17 get this from the lock file
var platformPackageName = "Microsoft.NETCore.App";
var platformLibrary = lockFileTarget
.Libraries
.FirstOrDefault(e => e.Name.Equals(platformPackageName, StringComparison.OrdinalIgnoreCase));
return platformLibrary;
}
public static HashSet<string> GetPlatformExclusionList(
this LockFileTarget lockFileTarget,
IDictionary<string, LockFileTargetLibrary> libraryLookup)
{
var platformLibrary = lockFileTarget.GetPlatformLibrary();
var exclusionList = new HashSet<string>();
exclusionList.Add(platformLibrary.Name);
CollectDependencies(libraryLookup, platformLibrary.Dependencies, exclusionList);
return exclusionList;
}
public static IEnumerable<LockFileTargetLibrary> GetRuntimeLibraries(this LockFileTarget lockFileTarget)
{
IEnumerable<LockFileTargetLibrary> runtimeLibraries = lockFileTarget.Libraries;
Dictionary<string, LockFileTargetLibrary> libraryLookup =
runtimeLibraries.ToDictionary(e => e.Name, StringComparer.OrdinalIgnoreCase);
HashSet<string> allExclusionList = new HashSet<string>();
if (lockFileTarget.IsPortable())
{
allExclusionList.UnionWith(lockFileTarget.GetPlatformExclusionList(libraryLookup));
}
return runtimeLibraries.Filter(allExclusionList).ToArray();
}
public static IEnumerable<LockFileTargetLibrary> GetCompileLibraries(this LockFileTarget lockFileTarget)
{
return lockFileTarget.Libraries;
}
public static IEnumerable<LockFileTargetLibrary> Filter(
this IEnumerable<LockFileTargetLibrary> libraries,
HashSet<string> exclusionList)
{
return libraries.Where(e => !exclusionList.Contains(e.Name));
}
public static IEnumerable<IGrouping<string, LockFileRuntimeTarget>> GetRuntimeTargetsGroups(
this LockFileTargetLibrary library,
string assetType)
{
return library.RuntimeTargets
.FilterPlaceHolderFiles()
.Cast<LockFileRuntimeTarget>()
.Where(t => string.Equals(t.AssetType, assetType, StringComparison.OrdinalIgnoreCase))
.GroupBy(t => t.Runtime);
}
private static void CollectDependencies(
IDictionary<string, LockFileTargetLibrary> libraryLookup,
IEnumerable<PackageDependency> dependencies,
HashSet<string> exclusionList)
{
foreach (PackageDependency dependency in dependencies)
{
LockFileTargetLibrary library = libraryLookup[dependency.Id];
if (library.Version.Equals(dependency.VersionRange.MinVersion))
{
if (exclusionList.Add(library.Name))
{
CollectDependencies(libraryLookup, library.Dependencies, exclusionList);
}
}
}
}
}
}

View file

@ -0,0 +1,48 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.Build.Evaluation;
using NuGet.ProjectModel;
namespace Microsoft.DotNet.Cli.CommandResolution
{
internal class MSBuildProject : IProject
{
private Project _project;
public MSBuildProject(string msBuildProjectPath)
{
var globalProperties = new Dictionary<string, string>()
{
{ "MSBuildExtensionsPath", AppContext.BaseDirectory }
};
_project = new Project(msBuildProjectPath, globalProperties, null);
}
public LockFile GetLockFile()
{
var intermediateOutputPath = _project
.AllEvaluatedProperties
.FirstOrDefault(p => p.Name.Equals("BaseIntermediateOutputPath"))
.EvaluatedValue;
var lockFilePath = Path.Combine(intermediateOutputPath, "project.assets.json");
return new LockFileFormat().Read(lockFilePath);
}
public IEnumerable<SingleProjectInfo> GetTools()
{
var toolsReferences = _project.AllEvaluatedItems.Where(i => i.ItemType.Equals("DotNetCliToolReference"));
var tools = toolsReferences.Select(t => new SingleProjectInfo(
t.EvaluatedInclude,
t.GetMetadataValue("Version"),
Enumerable.Empty<ResourceAssemblyInfo>()));
return tools;
}
}
}

View file

@ -0,0 +1,25 @@
// 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 NuGet.Packaging.Core;
using NuGet.ProjectModel;
namespace Microsoft.DotNet.Cli.CommandResolution
{
internal static class NuGetUtils
{
public static bool IsPlaceholderFile(string path)
{
return string.Equals(Path.GetFileName(path), PackagingCoreConstants.EmptyFolder, StringComparison.Ordinal);
}
public static IEnumerable<LockFileItem> FilterPlaceHolderFiles(this IEnumerable<LockFileItem> files)
{
return files.Where(f => !IsPlaceholderFile(f.Path));
}
}
}

View file

@ -0,0 +1,50 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
using System.IO;
namespace Microsoft.DotNet.Cli.CommandResolution
{
internal class ProjectFactory
{
public IProject GetProject(string projectDirectory)
{
return GetMSBuildProj(projectDirectory) ??
GetProjectJsonProject(projectDirectory);
}
private IProject GetMSBuildProj(string projectDirectory)
{
string msBuildProjectPath = GetMSBuildProjPath(projectDirectory);
if(msBuildProjectPath == null)
{
return null;
}
return new MSBuildProject(msBuildProjectPath);
}
private IProject GetProjectJsonProject(string projectDirectory)
{
return new ProjectJsonProject(projectDirectory);
}
private string GetMSBuildProjPath(string projectDirectory)
{
string[] projectFiles = Directory.GetFiles(projectDirectory, "*.*proj");
if (projectFiles.Length == 0)
{
return null;
}
else if (projectFiles.Length > 1)
{
throw new InvalidOperationException(
$"Specify which project file to use because this '{projectDirectory}' contains more than one project file.");
}
return projectFiles[0];
}
}
}

View file

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

View file

@ -1,17 +1,21 @@
using System; // 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.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.InternalAbstractions; using Microsoft.DotNet.InternalAbstractions;
using Microsoft.DotNet.ProjectModel; using Microsoft.DotNet.ProjectModel;
using Microsoft.DotNet.Tools.Common; using Microsoft.DotNet.Tools.Common;
using Microsoft.Extensions.DependencyModel; using Microsoft.Extensions.DependencyModel;
using NuGet.Frameworks; using NuGet.Frameworks;
using NuGet.LibraryModel;
using NuGet.ProjectModel; using NuGet.ProjectModel;
using NuGet.Versioning;
using FileFormatException = Microsoft.DotNet.ProjectModel.FileFormatException; using FileFormatException = Microsoft.DotNet.ProjectModel.FileFormatException;
namespace Microsoft.DotNet.Cli.Utils namespace Microsoft.DotNet.Cli.CommandResolution
{ {
public class ProjectToolsCommandResolver : ICommandResolver public class ProjectToolsCommandResolver : ICommandResolver
{ {
@ -20,9 +24,6 @@ namespace Microsoft.DotNet.Cli.Utils
private static readonly CommandResolutionStrategy s_commandResolutionStrategy = private static readonly CommandResolutionStrategy s_commandResolutionStrategy =
CommandResolutionStrategy.ProjectToolsPackage; CommandResolutionStrategy.ProjectToolsPackage;
private static readonly string s_currentRuntimeIdentifier = RuntimeEnvironmentRidExtensions.GetLegacyRestoreRuntimeIdentifier();
private List<string> _allowedCommandExtensions; private List<string> _allowedCommandExtensions;
private IPackagedCommandSpecFactory _packagedCommandSpecFactory; private IPackagedCommandSpecFactory _packagedCommandSpecFactory;
@ -55,31 +56,26 @@ namespace Microsoft.DotNet.Cli.Utils
IEnumerable<string> args, IEnumerable<string> args,
string projectDirectory) string projectDirectory)
{ {
var projectContext = GetProjectContextFromDirectoryForFirstTarget(projectDirectory); var projectFactory = new ProjectFactory();
var project = projectFactory.GetProject(projectDirectory);
if (projectContext == null) var tools = project.GetTools();
{
return null;
}
var toolsLibraries = projectContext.ProjectFile.Tools.OrEmptyIfNull();
return ResolveCommandSpecFromAllToolLibraries( return ResolveCommandSpecFromAllToolLibraries(
toolsLibraries, tools,
commandName, commandName,
args, args,
projectContext); project.GetLockFile());
} }
private CommandSpec ResolveCommandSpecFromAllToolLibraries( private CommandSpec ResolveCommandSpecFromAllToolLibraries(
IEnumerable<LibraryDependency> toolsLibraries, IEnumerable<SingleProjectInfo> toolsLibraries,
string commandName, string commandName,
IEnumerable<string> args, IEnumerable<string> args,
ProjectContext projectContext) LockFile lockFile)
{ {
foreach (var toolLibrary in toolsLibraries) foreach (var toolLibrary in toolsLibraries)
{ {
var commandSpec = ResolveCommandSpecFromToolLibrary(toolLibrary.LibraryRange, commandName, args, projectContext); var commandSpec = ResolveCommandSpecFromToolLibrary(toolLibrary, commandName, args, lockFile);
if (commandSpec != null) if (commandSpec != null)
{ {
@ -91,17 +87,18 @@ namespace Microsoft.DotNet.Cli.Utils
} }
private CommandSpec ResolveCommandSpecFromToolLibrary( private CommandSpec ResolveCommandSpecFromToolLibrary(
LibraryRange toolLibraryRange, SingleProjectInfo toolLibraryRange,
string commandName, string commandName,
IEnumerable<string> args, IEnumerable<string> args,
ProjectContext projectContext) LockFile lockFile)
{ {
var nugetPackagesRoot = projectContext.PackagesDirectory; var nugetPackagesRoot = lockFile.PackageFolders.First().Path;
var lockFile = GetToolLockFile(toolLibraryRange, nugetPackagesRoot); var toolLockFile = GetToolLockFile(toolLibraryRange, nugetPackagesRoot);
var toolLibrary = lockFile.Targets var toolLibrary = toolLockFile.Targets
.FirstOrDefault(t => t.TargetFramework.GetShortFolderName().Equals(s_toolPackageFramework.GetShortFolderName())) .FirstOrDefault(
t => t.TargetFramework.GetShortFolderName().Equals(s_toolPackageFramework.GetShortFolderName()))
?.Libraries.FirstOrDefault(l => l.Name == toolLibraryRange.Name); ?.Libraries.FirstOrDefault(l => l.Name == toolLibraryRange.Name);
if (toolLibrary == null) if (toolLibrary == null)
@ -109,8 +106,8 @@ namespace Microsoft.DotNet.Cli.Utils
return null; return null;
} }
var depsFileRoot = Path.GetDirectoryName(lockFile.Path); var depsFileRoot = Path.GetDirectoryName(toolLockFile.Path);
var depsFilePath = GetToolDepsFilePath(toolLibraryRange, lockFile, depsFileRoot); var depsFilePath = GetToolDepsFilePath(toolLibraryRange, toolLockFile, depsFileRoot);
var normalizedNugetPackagesRoot = PathUtility.EnsureNoTrailingDirectorySeparator(nugetPackagesRoot); var normalizedNugetPackagesRoot = PathUtility.EnsureNoTrailingDirectorySeparator(nugetPackagesRoot);
@ -126,7 +123,7 @@ namespace Microsoft.DotNet.Cli.Utils
} }
private LockFile GetToolLockFile( private LockFile GetToolLockFile(
LibraryRange toolLibrary, SingleProjectInfo toolLibrary,
string nugetPackagesRoot) string nugetPackagesRoot)
{ {
var lockFilePath = GetToolLockFilePath(toolLibrary, nugetPackagesRoot); var lockFilePath = GetToolLockFilePath(toolLibrary, nugetPackagesRoot);
@ -151,36 +148,19 @@ namespace Microsoft.DotNet.Cli.Utils
} }
private string GetToolLockFilePath( private string GetToolLockFilePath(
LibraryRange toolLibrary, SingleProjectInfo toolLibrary,
string nugetPackagesRoot) string nugetPackagesRoot)
{ {
var toolPathCalculator = new ToolPathCalculator(nugetPackagesRoot); var toolPathCalculator = new ToolPathCalculator(nugetPackagesRoot);
return toolPathCalculator.GetBestLockFilePath( return toolPathCalculator.GetBestLockFilePath(
toolLibrary.Name, toolLibrary.Name,
toolLibrary.VersionRange, new VersionRange(new NuGetVersion(toolLibrary.Version)),
s_toolPackageFramework); s_toolPackageFramework);
} }
private ProjectContext GetProjectContextFromDirectoryForFirstTarget(string projectRootPath)
{
if (projectRootPath == null)
{
return null;
}
if (!File.Exists(Path.Combine(projectRootPath, Project.FileName)))
{
return null;
}
var projectContext = ProjectContext.CreateContextForEachTarget(projectRootPath).FirstOrDefault();
return projectContext;
}
private string GetToolDepsFilePath( private string GetToolDepsFilePath(
LibraryRange toolLibrary, SingleProjectInfo toolLibrary,
LockFile toolLockFile, LockFile toolLockFile,
string depsPathRoot) string depsPathRoot)
{ {
@ -188,42 +168,32 @@ namespace Microsoft.DotNet.Cli.Utils
depsPathRoot, depsPathRoot,
toolLibrary.Name + FileNameSuffixes.DepsJson); toolLibrary.Name + FileNameSuffixes.DepsJson);
EnsureToolJsonDepsFileExists(toolLockFile, depsJsonPath); EnsureToolJsonDepsFileExists(toolLockFile, depsJsonPath, toolLibrary);
return depsJsonPath; return depsJsonPath;
} }
private void EnsureToolJsonDepsFileExists( private void EnsureToolJsonDepsFileExists(
LockFile toolLockFile, LockFile toolLockFile,
string depsPath) string depsPath,
SingleProjectInfo toolLibrary)
{ {
if (!File.Exists(depsPath)) if (!File.Exists(depsPath))
{ {
GenerateDepsJsonFile(toolLockFile, depsPath); GenerateDepsJsonFile(toolLockFile, depsPath, toolLibrary);
} }
} }
// Need to unit test this, so public // Need to unit test this, so public
public void GenerateDepsJsonFile( internal void GenerateDepsJsonFile(
LockFile toolLockFile, LockFile toolLockFile,
string depsPath) string depsPath,
SingleProjectInfo toolLibrary)
{ {
Reporter.Verbose.WriteLine($"Generating deps.json at: {depsPath}"); Reporter.Verbose.WriteLine($"Generating deps.json at: {depsPath}");
var projectContext = new ProjectContextBuilder() var dependencyContext = new DepsJsonBuilder()
.WithLockFile(toolLockFile) .Build(toolLibrary, null, toolLockFile, s_toolPackageFramework, null);
.WithTargetFramework(s_toolPackageFramework.ToString())
.Build();
var exporter = projectContext.CreateExporter(Constants.DefaultConfiguration);
var dependencyContext = new DependencyContextBuilder()
.Build(null,
null,
exporter.GetAllExports(),
true,
s_toolPackageFramework,
string.Empty);
var tempDepsFile = Path.GetTempFileName(); var tempDepsFile = Path.GetTempFileName();
using (var fileStream = File.Open(tempDepsFile, FileMode.Open, FileAccess.Write)) using (var fileStream = File.Open(tempDepsFile, FileMode.Open, FileAccess.Write))

View file

@ -0,0 +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 Microsoft.DotNet.Cli.Utils;
namespace Microsoft.DotNet.Cli.CommandResolution
{
public class ProjectToolsCommandResolverPolicy : ICommandResolverPolicy
{
public CompositeCommandResolver CreateCommandResolver()
{
var defaultCommandResolverPolicy = new DefaultCommandResolverPolicy();
var compositeCommandResolver = defaultCommandResolverPolicy.CreateCommandResolver();
var packagedCommandSpecFactory = new PackagedCommandSpecFactory();
compositeCommandResolver.AddCommandResolver(new ProjectToolsCommandResolver(packagedCommandSpecFactory));
return compositeCommandResolver;
}
}
}

View file

@ -0,0 +1,17 @@
// 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.Cli.CommandResolution
{
internal class ResourceAssemblyInfo
{
public string Culture { get; }
public string RelativePath { get; }
public ResourceAssemblyInfo(string culture, string relativePath)
{
Culture = culture;
RelativePath = relativePath;
}
}
}

View file

@ -0,0 +1,27 @@
// 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;
namespace Microsoft.DotNet.Cli.CommandResolution
{
internal class SingleProjectInfo
{
public string Name { get; }
public string Version { get; }
public IEnumerable<ResourceAssemblyInfo> ResourceAssemblies { get; }
public SingleProjectInfo(string name, string version, IEnumerable<ResourceAssemblyInfo> resourceAssemblies)
{
Name = name;
Version = version;
ResourceAssemblies = resourceAssemblies;
}
public string GetOutputName()
{
return $"{Name}.dll";
}
}
}

View file

@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using Microsoft.DotNet.Cli.CommandResolution;
using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.Configurer; using Microsoft.DotNet.Configurer;
using Microsoft.DotNet.PlatformAbstractions; using Microsoft.DotNet.PlatformAbstractions;
@ -190,7 +191,12 @@ namespace Microsoft.DotNet.Cli
} }
else else
{ {
CommandResult result = Command.Create("dotnet-" + command, appArgs, FrameworkConstants.CommonFrameworks.NetStandardApp15) var projectToolsCommandResolver = new ProjectToolsCommandResolverPolicy();
CommandResult result = Command.Create(
projectToolsCommandResolver,
"dotnet-" + command,
appArgs,
FrameworkConstants.CommonFrameworks.NetStandardApp15)
.Execute(); .Execute();
exitCode = result.ExitCode; exitCode = result.ExitCode;
} }
@ -240,7 +246,8 @@ namespace Microsoft.DotNet.Cli
{ {
HelpCommand.PrintVersionHeader(); HelpCommand.PrintVersionHeader();
var commitSha = GetCommitSha() ?? "N/A"; DotnetVersionFile versionFile = DotnetFiles.VersionFileObject;
var commitSha = versionFile.CommitSha ?? "N/A";
Reporter.Output.WriteLine(); Reporter.Output.WriteLine();
Reporter.Output.WriteLine("Product Information:"); Reporter.Output.WriteLine("Product Information:");
Reporter.Output.WriteLine($" Version: {Product.Version}"); Reporter.Output.WriteLine($" Version: {Product.Version}");
@ -250,7 +257,7 @@ namespace Microsoft.DotNet.Cli
Reporter.Output.WriteLine($" OS Name: {RuntimeEnvironment.OperatingSystem}"); Reporter.Output.WriteLine($" OS Name: {RuntimeEnvironment.OperatingSystem}");
Reporter.Output.WriteLine($" OS Version: {RuntimeEnvironment.OperatingSystemVersion}"); Reporter.Output.WriteLine($" OS Version: {RuntimeEnvironment.OperatingSystemVersion}");
Reporter.Output.WriteLine($" OS Platform: {RuntimeEnvironment.OperatingSystemPlatform}"); Reporter.Output.WriteLine($" OS Platform: {RuntimeEnvironment.OperatingSystemPlatform}");
Reporter.Output.WriteLine($" RID: {RuntimeEnvironment.GetRuntimeIdentifier()}"); Reporter.Output.WriteLine($" RID: {GetDisplayRid(versionFile)}");
} }
private static bool IsArg(string candidate, string longName) private static bool IsArg(string candidate, string longName)
@ -263,16 +270,17 @@ namespace Microsoft.DotNet.Cli
return (shortName != null && candidate.Equals("-" + shortName)) || (longName != null && candidate.Equals("--" + longName)); return (shortName != null && candidate.Equals("-" + shortName)) || (longName != null && candidate.Equals("--" + longName));
} }
private static string GetCommitSha() private static string GetDisplayRid(DotnetVersionFile versionFile)
{ {
var versionFile = DotnetFiles.VersionFile; FrameworkDependencyFile fxDepsFile = new FrameworkDependencyFile();
if (File.Exists(versionFile)) string currentRid = RuntimeEnvironment.GetRuntimeIdentifier();
{
return File.ReadLines(versionFile).FirstOrDefault()?.Substring(0, 10);
}
return null; // if the current RID isn't supported by the shared framework, display the RID the CLI was
// built with instead, so the user knows which RID they should put in their "runtimes" section.
return fxDepsFile.IsRuntimeSupported(currentRid) ?
currentRid :
versionFile.BuildRid;
} }
} }
} }

View file

@ -2,4 +2,4 @@ using System.Reflection;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
[assembly: AssemblyMetadataAttribute("Serviceable", "True")] [assembly: AssemblyMetadataAttribute("Serviceable", "True")]
[assembly: InternalsVisibleTo("dotnet.Tests")] [assembly: InternalsVisibleTo("dotnet.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]

View file

@ -131,7 +131,7 @@ namespace Microsoft.DotNet.Tools.Compiler
var rids = new List<string>(); var rids = new List<string>();
if (string.IsNullOrEmpty(RuntimeValue)) if (string.IsNullOrEmpty(RuntimeValue))
{ {
return RuntimeEnvironmentRidExtensions.GetAllCandidateRuntimeIdentifiers(); return DotnetRuntimeIdentifiers.InferCurrentRuntimeIdentifiers();
} }
else else
{ {

View file

@ -4,6 +4,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using Microsoft.Build.Construction; using Microsoft.Build.Construction;
using Microsoft.DotNet.ProjectJsonMigration; using Microsoft.DotNet.ProjectJsonMigration;
using Microsoft.DotNet.ProjectModel; using Microsoft.DotNet.ProjectModel;
@ -55,22 +56,33 @@ namespace Microsoft.DotNet.Tools.Migrate
private IEnumerable<string> GetProjectsToMigrate(string projectArg) private IEnumerable<string> GetProjectsToMigrate(string projectArg)
{ {
if (projectArg.EndsWith(Project.FileName)) IEnumerable<string> projects = null;
if (projectArg.EndsWith(Project.FileName, StringComparison.OrdinalIgnoreCase))
{ {
yield return GetProjectJsonPath(projectArg); projects = Enumerable.Repeat(projectArg, 1);
}
else if (projectArg.EndsWith(GlobalSettings.FileName, StringComparison.OrdinalIgnoreCase))
{
projects = GetProjectsFromGlobalJson(projectArg);
} }
else if (Directory.Exists(projectArg)) else if (Directory.Exists(projectArg))
{ {
var projects = Directory.EnumerateFiles(projectArg, Project.FileName, SearchOption.AllDirectories); projects = Directory.EnumerateFiles(projectArg, Project.FileName, SearchOption.AllDirectories);
foreach(var project in projects)
{
yield return GetProjectJsonPath(project);
}
} }
else else
{ {
throw new Exception($"Invalid project argument - '{projectArg}' is not a project.json file and a directory named '{projectArg}' doesn't exist."); throw new Exception($"Invalid project argument - '{projectArg}' is not a project.json or a global.json file and a directory named '{projectArg}' doesn't exist.");
}
if (!projects.Any())
{
throw new Exception($"Invalid project argument - Unable to find any projects in global.json or directory '{projectArg}'");
}
foreach(var project in projects)
{
yield return GetProjectJsonPath(project);
} }
} }
@ -93,5 +105,35 @@ namespace Microsoft.DotNet.Tools.Migrate
throw new Exception($"Unable to find project file at {projectJson}"); throw new Exception($"Unable to find project file at {projectJson}");
} }
private IEnumerable<string> GetProjectsFromGlobalJson(string globalJson)
{
if (!File.Exists(globalJson))
{
throw new Exception($"Unable to find global settings file at {globalJson}");
}
var searchPaths = ProjectDependencyFinder.GetGlobalPaths(Path.GetDirectoryName(globalJson));
foreach (var searchPath in searchPaths)
{
var directory = new DirectoryInfo(searchPath);
if (!directory.Exists)
{
continue;
}
foreach (var projectDirectory in directory.EnumerateDirectories())
{
var projectFilePath = Path.Combine(projectDirectory.FullName, "project.json");
if (File.Exists(projectFilePath))
{
yield return projectFilePath;
}
}
}
}
} }
} }

View file

@ -11,6 +11,12 @@ namespace Microsoft.DotNet.Tools.Migrate
{ {
public static int Run(string[] args) public static int Run(string[] args)
{ {
// IMPORTANT:
// When updating the command line args for dotnet-migrate, we need to update the in-VS caller of dotnet migrate as well.
// It is located at dotnet/roslyn-project-system:
// src/Microsoft.VisualStudio.ProjectSystem.CSharp.VS/ProjectSystem/VS/Xproj/MigrateXprojFactory.cs
DebugHelper.HandleDebugSwitch(ref args); DebugHelper.HandleDebugSwitch(ref args);
CommandLineApplication app = new CommandLineApplication(); CommandLineApplication app = new CommandLineApplication();
@ -20,10 +26,15 @@ namespace Microsoft.DotNet.Tools.Migrate
app.HandleResponseFiles = true; app.HandleResponseFiles = true;
app.HelpOption("-h|--help"); app.HelpOption("-h|--help");
CommandArgument projectArgument = app.Argument("<PROJECT_JSON/PROJECT_DIR>", CommandArgument projectArgument = app.Argument("<PROJECT_JSON/GLOBAL_JSON/PROJECT_DIR>",
"The path to project.json file or a directory to migrate." + string.Join(Environment.NewLine,
" If a directory is specified, then it will recursively search for project.json files to migrate." + "The path to ",
" Defaults to current directory if nothing is specified."); " - a project.json file to migrate.",
"or",
" - a global.json file, it will migrate the folders specified in global.json.",
"or",
" - a directory to migrate, it will recursively search for project.json files to migrate.",
"Defaults to current directory if nothing is specified."));
CommandOption template = app.Option("-t|--template-file", "Base MSBuild template to use for migrated app. The default is the project included in dotnet new -t msbuild", CommandOptionType.SingleValue); CommandOption template = app.Option("-t|--template-file", "Base MSBuild template to use for migrated app. The default is the project included in dotnet new -t msbuild", CommandOptionType.SingleValue);
CommandOption sdkVersion = app.Option("-v|--sdk-package-version", "The version of the sdk package that will be referenced in the migrated app. The default is the version of the sdk in dotnet new -t msbuild", CommandOptionType.SingleValue); CommandOption sdkVersion = app.Option("-v|--sdk-package-version", "The version of the sdk package that will be referenced in the migrated app. The default is the version of the sdk in dotnet new -t msbuild", CommandOptionType.SingleValue);

View file

@ -8,14 +8,11 @@ namespace Microsoft.DotNet.Tools.Migrate
{ {
public static string GetSdkVersion(this ProjectRootElement projectRootElement) public static string GetSdkVersion(this ProjectRootElement projectRootElement)
{ {
//TODO: Temporarily pinning the SDK version for Migration. Once we have packageref migration we can remove this. return projectRootElement
return "1.0.0-alpha-20160929-1"; .Items
.Where(i => i.ItemType == "PackageReference")
// return projectRootElement .First(i => i.Include == ConstantPackageNames.CSdkPackageName)
// .Items .GetMetadataWithName("version").Value;
// .Where(i => i.ItemType == "PackageReference")
// .First(i => i.Include == ConstantPackageNames.CSdkPackageName)
// .GetMetadataWithName("version").Value;
} }
} }
} }

View file

@ -414,7 +414,7 @@ namespace Microsoft.DotNet.Tools.Publish
contexts.Where(c => Equals(c.TargetFramework, framework)); contexts.Where(c => Equals(c.TargetFramework, framework));
var rids = string.IsNullOrEmpty(runtime) ? var rids = string.IsNullOrEmpty(runtime) ?
RuntimeEnvironmentRidExtensions.GetAllCandidateRuntimeIdentifiers() : DotnetRuntimeIdentifiers.InferCurrentRuntimeIdentifiers() :
new[] { runtime }; new[] { runtime };
return contexts.Select(c => Workspace.GetRuntimeContext(c, rids)); return contexts.Select(c => Workspace.GetRuntimeContext(c, rids));

View file

@ -1,14 +1,12 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved. // 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. // Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System.Collections.Generic;
using Microsoft.DotNet.Cli.CommandLine; using Microsoft.DotNet.Cli.CommandLine;
using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.Tools.MSBuild;
namespace Microsoft.DotNet.Tools.Publish3 namespace Microsoft.DotNet.Tools.Publish3
{ {
public class Publish3Command public partial class Publish3Command
{ {
public static int Run(string[] args) public static int Run(string[] args)
{ {
@ -47,43 +45,17 @@ namespace Microsoft.DotNet.Tools.Publish3
app.OnExecute(() => app.OnExecute(() =>
{ {
List<string> msbuildArgs = new List<string>(); Publish3Command publish = new Publish3Command();
if (!string.IsNullOrEmpty(projectArgument.Value)) publish.ProjectPath = projectArgument.Value;
{ publish.Framework = frameworkOption.Value();
msbuildArgs.Add(projectArgument.Value); publish.Runtime = runtimeOption.Value();
} publish.OutputPath = outputOption.Value();
publish.Configuration = configurationOption.Value();
publish.VersionSuffix = versionSuffixOption.Value();
publish.ExtraMSBuildArguments = app.RemainingArguments;
msbuildArgs.Add("/t:Publish"); return publish.Execute();
if (frameworkOption.HasValue())
{
msbuildArgs.Add($"/p:TargetFramework={frameworkOption.Value()}");
}
if (runtimeOption.HasValue())
{
msbuildArgs.Add($"/p:RuntimeIdentifier={runtimeOption.Value()}");
}
if (outputOption.HasValue())
{
msbuildArgs.Add($"/p:PublishDir={outputOption.Value()}");
}
if (configurationOption.HasValue())
{
msbuildArgs.Add($"/p:Configuration={configurationOption.Value()}");
}
if (versionSuffixOption.HasValue())
{
msbuildArgs.Add($"/p:VersionSuffix={versionSuffixOption.Value()}");
}
msbuildArgs.AddRange(app.RemainingArguments);
return new MSBuildForwardingApp(msbuildArgs).Execute();
}); });
return app.Execute(args); return app.Execute(args);

View file

@ -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.Collections.Generic;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.DotNet.Tools.MSBuild;
using Microsoft.DotNet.Tools.Restore3;
namespace Microsoft.DotNet.Tools.Publish3
{
public partial class Publish3Command
{
public string ProjectPath { get; set; }
public string Framework { get; set; }
public string Runtime { get; set; }
public string OutputPath { get; set; }
public string Configuration { get; set; }
public string VersionSuffix { get; set; }
public List<string> ExtraMSBuildArguments { get; set; }
private Publish3Command()
{
}
public int Execute()
{
int restoreResult = EnsureRestored();
if (restoreResult != 0)
{
throw new GracefulException("Restore failed. Please fix the errors and try publishing again.");
}
List<string> msbuildArgs = new List<string>();
if (!string.IsNullOrEmpty(ProjectPath))
{
msbuildArgs.Add(ProjectPath);
}
msbuildArgs.Add("/t:Publish");
if (!string.IsNullOrEmpty(Framework))
{
msbuildArgs.Add($"/p:TargetFramework={Framework}");
}
if (!string.IsNullOrEmpty(Runtime))
{
msbuildArgs.Add($"/p:RuntimeIdentifier={Runtime}");
}
if (!string.IsNullOrEmpty(OutputPath))
{
msbuildArgs.Add($"/p:PublishDir={OutputPath}");
}
if (!string.IsNullOrEmpty(Configuration))
{
msbuildArgs.Add($"/p:Configuration={Configuration}");
}
if (!string.IsNullOrEmpty(VersionSuffix))
{
msbuildArgs.Add($"/p:VersionSuffix={VersionSuffix}");
}
msbuildArgs.AddRange(ExtraMSBuildArguments);
return new MSBuildForwardingApp(msbuildArgs).Execute();
}
/// <summary>
/// Ensures that the project has been restored for the specified runtime.
/// </summary>
private int EnsureRestored()
{
int result = 0;
if (!string.IsNullOrEmpty(Runtime))
{
result = Restore3Command.Run(new[] { $"/p:RuntimeIdentifiers={Runtime}" });
}
return result;
}
}
}

View file

@ -83,7 +83,7 @@ namespace Microsoft.DotNet.Tools.Run
.EnsureValid(Project) .EnsureValid(Project)
.FrameworkOnlyContexts; .FrameworkOnlyContexts;
var rids = RuntimeEnvironmentRidExtensions.GetAllCandidateRuntimeIdentifiers(); var rids = DotnetRuntimeIdentifiers.InferCurrentRuntimeIdentifiers();
ProjectContext frameworkContext; ProjectContext frameworkContext;
if (Framework == null) if (Framework == null)

View file

@ -2,6 +2,7 @@
"version": "1.0.0-preview3-*", "version": "1.0.0-preview3-*",
"buildOptions": { "buildOptions": {
"emitEntryPoint": true, "emitEntryPoint": true,
"keyFile": "../../tools/Key.snk",
"embed": { "embed": {
"include": [ "include": [
"commands/dotnet-new/CSharp_Console.zip", "commands/dotnet-new/CSharp_Console.zip",

Some files were not shown because too many files have changed in this diff Show more