Skip to content
This repository was archived by the owner on Apr 20, 2023. It is now read-only.

Commit 08f050c

Browse files
author
William Lee
authored
bundled DotnetTool (#8606)
Extract packages to DotnetTools folder under sdk/{version} Add new resolver to discover it Add test to enforce package structure. It will fail when the structure changed
1 parent f86ea50 commit 08f050c

16 files changed

+393
-12
lines changed

Directory.Build.props

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ tools\TestAssetsDependencies\TestAssetsDependencies.csproj
5757
<Import Project="build/BundledTools.props" />
5858
<Import Project="build/BundledSdks.props" />
5959
<Import Project="build/BundledTemplates.props" />
60+
<Import Project="build/BundledDotnetTools.props" />
6061

6162
<Import Project="build/BuildDefaults.props" />
6263
<Import Project="build/BundledRuntimes.props" />

build/BundledDotnetTools.proj

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<Project ToolsVersion="15.0" DefaultTargets="ExtractDotnetToolsToOutput">
2+
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
3+
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.tasks))\dir.tasks" />
4+
5+
<Target Name="ExtractDotnetToolsToOutput"
6+
DependsOnTargets="EnsureDotnetToolsRestored">
7+
8+
<Message Text="Restore DotnetTools $(TemplateFillInPackageName) from $(DotnetToolsNuPkgPath) to $(DotnetToolsLayoutDirectory)."
9+
Importance="High" />
10+
</Target>
11+
12+
<Target Name="EnsureDotnetToolsRestored"
13+
Condition="!Exists('$(DotnetToolsNuPkgPath)/$(TemplateFillInPackageName.ToLower())')">
14+
15+
<PropertyGroup>
16+
<DotnetToolsRestoreAdditionalParameters>/p:TargetFramework=$(CliTargetFramework)</DotnetToolsRestoreAdditionalParameters>
17+
<DotnetToolsRestoreAdditionalParameters>$(DotnetToolsRestoreAdditionalParameters) /p:TemplateFillInPackageName=$(TemplateFillInPackageName)</DotnetToolsRestoreAdditionalParameters>
18+
<DotnetToolsRestoreAdditionalParameters>$(DotnetToolsRestoreAdditionalParameters) /p:TemplateFillInPackageVersion=$(TemplateFillInPackageVersion)</DotnetToolsRestoreAdditionalParameters>
19+
<DotnetToolsRestoreAdditionalParameters>$(DotnetToolsRestoreAdditionalParameters) /p:RestorePackagesPath=$(DotnetToolsLayoutDirectory)</DotnetToolsRestoreAdditionalParameters>
20+
<DotnetToolsRestoreAdditionalParameters Condition=" $(DotnetToolsRestoreProjectStyle) != '' " >$(DotnetToolsRestoreAdditionalParameters) /p:RestoreProjectStyle=$(DotnetToolsRestoreProjectStyle)</DotnetToolsRestoreAdditionalParameters>
21+
</PropertyGroup>
22+
23+
<DotNetRestore ToolPath="$(PreviousStageDirectory)"
24+
ProjectPath="$(MSBuildThisFileDirectory)/templates/templates.csproj"
25+
AdditionalParameters="$(DotnetToolsRestoreAdditionalParameters)" />
26+
</Target>
27+
</Project>

build/BundledDotnetTools.props

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
2+
<ItemGroup>
3+
<BundledDotnetTools Include="dotnet-watch" Version="$(AspNetCoreVersion)" />
4+
<BundledDotnetTools Include="dotnet-dev-certs" Version="$(AspNetCoreVersion)" />
5+
</ItemGroup>
6+
</Project>

build/BundledTemplates.proj

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,26 +11,26 @@
1111
<Copy SourceFiles="@(TemplateContent)"
1212
DestinationFiles="@(TemplateContent->'$(TemplateLayoutDirectory)/%(RecursiveDir)%(FileName)%(Extension)')" />
1313

14-
<Message Text="Copied template $(TemplatePackageName) from $(TemplateNuPkgPath) to $(TemplateLayoutDirectory)."
14+
<Message Text="Copied template $(TemplateFillInPackageName) from $(TemplateNuPkgPath) to $(TemplateLayoutDirectory)."
1515
Importance="High" />
1616
</Target>
1717

1818
<Target Name="GetTemplateItemsToCopy">
1919
<ItemGroup>
20-
<TemplateContent Include="$(TemplateNuPkgPath)/$(TemplatePackageName.ToLower()).$(TemplatePackageVersion.ToLower()).nupkg" />
20+
<TemplateContent Include="$(TemplateNuPkgPath)/$(TemplateFillInPackageName.ToLower()).$(TemplateFillInPackageVersion.ToLower()).nupkg" />
2121
</ItemGroup>
2222
</Target>
2323

2424
<Target Name="EnsureTemplateRestored"
25-
Condition="!Exists('$(TemplateNuPkgPath)/$(TemplatePackageName.ToLower()).nuspec')">
25+
Condition="!Exists('$(TemplateNuPkgPath)/$(TemplateFillInPackageName.ToLower()).nuspec')">
2626
<DotNetRestore ToolPath="$(PreviousStageDirectory)"
2727
ProjectPath="$(MSBuildThisFileDirectory)/templates/templates.csproj"
28-
AdditionalParameters="/p:TemplatePackageName=$(TemplatePackageName) /p:TemplatePackageVersion=$(TemplatePackageVersion)" />
28+
AdditionalParameters="/p:TargetFramework=netcoreapp1.0 /p:TemplateFillInPackageName=$(TemplateFillInPackageName) /p:TemplateFillInPackageVersion=$(TemplateFillInPackageVersion)" />
2929
</Target>
3030

3131
<Target Name="PrepareBundledTemplateProps">
3232
<PropertyGroup>
33-
<TemplateNuPkgPath>$(NuGetPackagesDir)/$(TemplatePackageName.ToLower())/$(TemplatePackageVersion.ToLower())</TemplateNuPkgPath>
33+
<TemplateNuPkgPath>$(NuGetPackagesDir)/$(TemplateFillInPackageName.ToLower())/$(TemplateFillInPackageVersion.ToLower())</TemplateNuPkgPath>
3434
</PropertyGroup>
3535
</Target>
3636
</Project>

build/templates/templates.csproj

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,11 @@
33

44
<PropertyGroup>
55
<OutputType>Library</OutputType>
6-
<TargetFramework>netcoreapp1.0</TargetFramework>
76
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
87
</PropertyGroup>
98

109
<ItemGroup>
11-
<PackageReference Include="$(TemplatePackageName)" Version="$(TemplatePackageVersion)" />
10+
<PackageReference Include="$(TemplateFillInPackageName)" Version="$(TemplateFillInPackageVersion)" />
1211
</ItemGroup>
1312

1413
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

src/Microsoft.DotNet.Cli.Utils/CommandResolution/CommandResolutionStrategy.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ public enum CommandResolutionStrategy
1414
// command loaded from project tools nuget package
1515
ProjectToolsPackage,
1616

17+
// command loaded from bundled DotnetTools nuget package
18+
DotnetToolsPackage,
19+
1720
// command loaded from the same directory as the executing assembly
1821
BaseDirectory,
1922

src/Microsoft.DotNet.Cli.Utils/CommandResolution/DefaultCommandResolverPolicy.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ public static CompositeCommandResolver CreateDefaultCommandResolver(
4444
var compositeCommandResolver = new CompositeCommandResolver();
4545

4646
compositeCommandResolver.AddCommandResolver(new MuxerCommandResolver());
47+
compositeCommandResolver.AddCommandResolver(new DotnetToolsCommandResolver());
4748
compositeCommandResolver.AddCommandResolver(new RootedCommandResolver());
4849
compositeCommandResolver.AddCommandResolver(
4950
new ProjectToolsCommandResolver(packagedCommandSpecFactory, environment));
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
// Copyright (c) .NET Foundation and contributors. All rights reserved.
2+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3+
4+
using System;
5+
using System.IO;
6+
using System.Reflection;
7+
using System.Collections.Generic;
8+
using Microsoft.DotNet.PlatformAbstractions;
9+
10+
namespace Microsoft.DotNet.Cli.Utils
11+
{
12+
public class DotnetToolsCommandResolver : ICommandResolver
13+
{
14+
private string _dotnetToolPath;
15+
16+
public DotnetToolsCommandResolver(string dotnetToolPath = null)
17+
{
18+
if (dotnetToolPath == null)
19+
{
20+
_dotnetToolPath = Path.Combine(ApplicationEnvironment.ApplicationBasePath,
21+
"DotnetTools");
22+
}
23+
else
24+
{
25+
_dotnetToolPath = dotnetToolPath;
26+
}
27+
}
28+
29+
public CommandSpec Resolve(CommandResolverArguments arguments)
30+
{
31+
if (string.IsNullOrEmpty(arguments.CommandName))
32+
{
33+
return null;
34+
}
35+
36+
var packageId = new DirectoryInfo(Path.Combine(_dotnetToolPath, arguments.CommandName));
37+
if (!packageId.Exists)
38+
{
39+
return null;
40+
}
41+
42+
var version = packageId.GetDirectories()[0];
43+
var dll = version.GetDirectories("tools")[0]
44+
.GetDirectories()[0] // TFM
45+
.GetDirectories()[0] // RID
46+
.GetFiles($"{arguments.CommandName}.dll")[0];
47+
48+
return CreatePackageCommandSpecUsingMuxer(
49+
dll.FullName,
50+
arguments.CommandArguments,
51+
CommandResolutionStrategy.DotnetToolsPackage);
52+
}
53+
54+
private CommandSpec CreatePackageCommandSpecUsingMuxer(
55+
string commandPath,
56+
IEnumerable<string> commandArguments,
57+
CommandResolutionStrategy commandResolutionStrategy)
58+
{
59+
var arguments = new List<string>();
60+
61+
var muxer = new Muxer();
62+
63+
var host = muxer.MuxerPath;
64+
if (host == null)
65+
{
66+
throw new Exception(LocalizableStrings.UnableToLocateDotnetMultiplexer);
67+
}
68+
69+
arguments.Add(commandPath);
70+
71+
if (commandArguments != null)
72+
{
73+
arguments.AddRange(commandArguments);
74+
}
75+
76+
return CreateCommandSpec(host, arguments, commandResolutionStrategy);
77+
}
78+
79+
private CommandSpec CreateCommandSpec(
80+
string commandPath,
81+
IEnumerable<string> commandArguments,
82+
CommandResolutionStrategy commandResolutionStrategy)
83+
{
84+
var escapedArgs = ArgumentEscaper.EscapeAndConcatenateArgArrayForProcessStart(commandArguments);
85+
86+
return new CommandSpec(commandPath, escapedArgs, commandResolutionStrategy);
87+
}
88+
}
89+
}

src/redist/redist.csproj

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,8 +179,8 @@
179179
<TemplatesToBundle Include="$(RepoRoot)/build/BundledTemplates.proj">
180180
<Properties>
181181
TemplateLayoutDirectory=$(SdkOutputDirectory)/Templates;
182-
TemplatePackageName=%(BundledTemplate.Identity);
183-
TemplatePackageVersion=%(BundledTemplate.Version);
182+
TemplateFillInPackageName=%(BundledTemplate.Identity);
183+
TemplateFillInPackageVersion=%(BundledTemplate.Version);
184184
PreviousStageDirectory=$(PreviousStageDirectory)
185185
</Properties>
186186
</TemplatesToBundle>
@@ -192,6 +192,25 @@
192192
</MSBuild>
193193
</Target>
194194

195+
<Target Name="PublishDotnetTools"
196+
AfterTargets="Publish">
197+
<ItemGroup>
198+
<DotnetToolsToBundle Include="$(RepoRoot)/build/BundledDotnetTools.proj">
199+
<Properties>
200+
DotnetToolsLayoutDirectory=$(SdkOutputDirectory)/DotnetTools;
201+
TemplateFillInPackageName=%(BundledDotnetTools.Identity);
202+
TemplateFillInPackageVersion=%(BundledDotnetTools.Version);
203+
PreviousStageDirectory=$(PreviousStageDirectory)
204+
</Properties>
205+
</DotnetToolsToBundle>
206+
</ItemGroup>
207+
208+
<MSBuild
209+
BuildInParallel="False"
210+
Projects="@(DotnetToolsToBundle)">
211+
</MSBuild>
212+
</Target>
213+
195214
<Target Name="PublishLzmaArchive"
196215
Condition="'$(CLIBUILD_SKIP_LZMA)' != 'true'"
197216
DependsOnTargets="GetNuGetPackagesArchive"
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using FluentAssertions;
2+
using Microsoft.DotNet.Tools.Test.Utilities;
3+
using Xunit;
4+
5+
namespace EndToEnd
6+
{
7+
public class GivenDotnetUsesDotnetTools : TestBase
8+
{
9+
[Fact]
10+
public void ThenOneDotnetToolsCanBeCalled()
11+
{
12+
new DotnetCommand()
13+
.ExecuteWithCapturedOutput("dev-certs --help")
14+
.Should().Pass();
15+
}
16+
}
17+
}

0 commit comments

Comments
 (0)