Skip to content

Instantly share code, notes, and snippets.

@devlead
Last active March 9, 2021 18:49
Show Gist options
  • Save devlead/559d9b082c9cd81c5c5d52f94d68380c to your computer and use it in GitHub Desktop.
Save devlead/559d9b082c9cd81c5c5d52f94d68380c to your computer and use it in GitHub Desktop.
NuGet .NET Tool Path PoC

Get Tool paths PoC

Example Output

ToolFolder exists (cake.tool)
	Version: cake.tool/0.37.0
		Tool: cake.tool/0.37.0/tools/netcoreapp2.1/any/DotnetToolSettings.xml
			Runner: dotnet
			Name: dotnet-cake
			EntryPoint: cake.tool/0.37.0/tools/netcoreapp2.1/any/Cake.dll
				ExitCode: 0
				Version: 0.37.0
		Tool: cake.tool/0.37.0/tools/netcoreapp3.0/any/DotnetToolSettings.xml
			Runner: dotnet
			Name: dotnet-cake
			EntryPoint: cake.tool/0.37.0/tools/netcoreapp3.0/any/Cake.dll
				ExitCode: 0
				Version: 0.37.0
	Version: cake.tool/1.1.0
		Tool: cake.tool/1.1.0/tools/net5.0/any/DotnetToolSettings.xml
			Runner: dotnet
			Name: dotnet-cake
			EntryPoint: cake.tool/1.1.0/tools/net5.0/any/Cake.dll
				ExitCode: 0
				Version: 1.1.0
		Tool: cake.tool/1.1.0/tools/netcoreapp2.1/any/DotnetToolSettings.xml
			Runner: dotnet
			Name: dotnet-cake
			EntryPoint: cake.tool/1.1.0/tools/netcoreapp2.1/any/Cake.dll
				ExitCode: 0
				Version: 1.1.0
		Tool: cake.tool/1.1.0/tools/netcoreapp3.0/any/DotnetToolSettings.xml
			Runner: dotnet
			Name: dotnet-cake
			EntryPoint: cake.tool/1.1.0/tools/netcoreapp3.0/any/Cake.dll
				ExitCode: 0
				Version: 1.1.0
		Tool: cake.tool/1.1.0/tools/netcoreapp3.1/any/DotnetToolSettings.xml
			Runner: dotnet
			Name: dotnet-cake
			EntryPoint: cake.tool/1.1.0/tools/netcoreapp3.1/any/Cake.dll
				ExitCode: 0
				Version: 1.1.0
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Cake.Bridge.DependencyInjection" Version="0.4.0" />
<PackageReference Include="NuGet.Configuration" Version="5.9.0" />
</ItemGroup>
</Project>
using Cake.Core.IO;
using Cake.Core.Diagnostics;
using Cake.Bridge.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
using System.Xml.Linq;
using System.Threading;
using System.Xml.XPath;
using System.Linq;
using Cake.Core;
var serviceCollection = new ServiceCollection()
.AddCakeCore();
var serviceProvider = serviceCollection.BuildServiceProvider();
var fileSystem = serviceProvider.GetRequiredService<IFileSystem>();
var log = serviceProvider.GetRequiredService<ICakeLog>();
var runner = serviceProvider.GetRequiredService<IProcessRunner>();
var settings = NuGet.Configuration.Settings.LoadDefaultSettings(null);
var globalPackagesFolder = DirectoryPath.FromString(
NuGet.Configuration.SettingsUtility.GetGlobalPackagesFolder(settings)
);
var toolFolder = globalPackagesFolder.Combine((args.FirstOrDefault() ?? "Cake.Tool").ToLowerInvariant());
if (fileSystem.Exist(toolFolder))
{
log.Information("ToolFolder exists ({0})", globalPackagesFolder.GetRelativePath(toolFolder));
foreach(var versionDir in fileSystem.GetDirectory(toolFolder).GetDirectories("*", SearchScope.Current))
{
log.Information("\tVersion: {0}", globalPackagesFolder.GetRelativePath(versionDir.Path));
foreach(var file in versionDir.GetFiles("DotnetToolSettings.xml", SearchScope.Recursive))
{
log.Information("\t\tTool: {0}", globalPackagesFolder.GetRelativePath(file.Path));
await using var stream = file.OpenRead();
var xml = await XDocument.LoadAsync(stream, LoadOptions.None, CancellationToken.None);
foreach (var command in xml.XPathSelectElements("/DotNetCliTool/Commands/Command")
.Select(commandElement => new {
Name = commandElement.Attribute("Name")?.Value,
EntryPoint = commandElement.Attribute("EntryPoint")?.Value switch {
{} entryPoint => file
.Path
.GetDirectory()
.CombineWithFilePath(entryPoint),
_ => null
},
Runner = commandElement.Attribute("Runner")?.Value
})
.Where(command => command.EntryPoint is {} entryPoint && fileSystem.Exist(entryPoint))
)
{
log.Information("\t\t\tRunner: {0}", command.Runner);
log.Information("\t\t\tName: {0}", command.Name);
log.Information("\t\t\tEntryPoint: {0}", globalPackagesFolder.GetRelativePath(command.EntryPoint));
using var process = runner.Start(
command.Runner,
new ProcessSettings {
Arguments = new ProcessArgumentBuilder()
.AppendQuoted(command.EntryPoint.FullPath)
.Append("--version"),
RedirectStandardOutput = true
}
);
process.WaitForExit();
log.Information("\t\t\t\tExitCode: {0}", string.Concat(process.GetExitCode()));
log.Information("\t\t\t\tVersion: {0}", string.Concat(process.GetStandardOutput()));
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment