Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
380 changes: 380 additions & 0 deletions src/SourceBuild/patches/sourcelink/0001-New-command-line-APIs.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,380 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Nikola Milosavljevic <[email protected]>
Date: Mon, 17 Jul 2023 18:27:44 +0000
Subject: [PATCH] New command-line APIs

Backport: https://github.com/dotnet/sourcelink/pull/1068
---
NuGet.config | 2 +
eng/Version.Details.xml | 16 +-
eng/Versions.props | 6 +-
src/dotnet-sourcelink/Program.cs | 160 +++++++++++-------
.../dotnet-sourcelink.csproj | 4 +-
5 files changed, 114 insertions(+), 74 deletions(-)

diff --git a/NuGet.config b/NuGet.config
index ed5441c..1873d27 100644
--- a/NuGet.config
+++ b/NuGet.config
@@ -7,6 +7,8 @@
<add key="dotnet-tools" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json" />
<add key="dotnet8" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet8/nuget/v3/index.json" />
<add key="dotnet8-transport" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet8-transport/nuget/v3/index.json" />
+ <!-- Feeds for command-line-api -->
+ <add key="dotnet-libraries" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-libraries/nuget/v3/index.json" />
<!-- Feeds for source-build command-line-api intermediate -->
<add key="dotnet-libraries-transport" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-libraries-transport/nuget/v3/index.json" />
</packageSources>
diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml
index 0c3e675..fad95bd 100644
--- a/eng/Version.Details.xml
+++ b/eng/Version.Details.xml
@@ -1,21 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<Dependencies>
<ProductDependencies>
- <Dependency Name="System.CommandLine" Version="2.0.0-beta4.22272.1">
+ <Dependency Name="System.CommandLine" Version="2.0.0-beta4.23307.1">
<Uri>https://github.com/dotnet/command-line-api</Uri>
- <Sha>209b724a3c843253d3071e8348c353b297b0b8b5</Sha>
+ <Sha>02fe27cd6a9b001c8feb7938e6ef4b3799745759</Sha>
</Dependency>
- <Dependency Name="System.CommandLine.NamingConventionBinder" Version="2.0.0-beta4.22272.1">
+ <Dependency Name="System.CommandLine.NamingConventionBinder" Version="2.0.0-beta4.23307.1">
<Uri>https://github.com/dotnet/command-line-api</Uri>
- <Sha>209b724a3c843253d3071e8348c353b297b0b8b5</Sha>
+ <Sha>02fe27cd6a9b001c8feb7938e6ef4b3799745759</Sha>
</Dependency>
- <Dependency Name="System.CommandLine.Rendering" Version="0.4.0-alpha.22272.1">
+ <Dependency Name="System.CommandLine.Rendering" Version="0.4.0-alpha.23307.1">
<Uri>https://github.com/dotnet/command-line-api</Uri>
- <Sha>209b724a3c843253d3071e8348c353b297b0b8b5</Sha>
+ <Sha>02fe27cd6a9b001c8feb7938e6ef4b3799745759</Sha>
</Dependency>
- <Dependency Name="Microsoft.SourceBuild.Intermediate.command-line-api" Version="0.1.327201">
+ <Dependency Name="Microsoft.SourceBuild.Intermediate.command-line-api" Version="0.1.430701">
<Uri>https://github.com/dotnet/command-line-api</Uri>
- <Sha>209b724a3c843253d3071e8348c353b297b0b8b5</Sha>
+ <Sha>02fe27cd6a9b001c8feb7938e6ef4b3799745759</Sha>
<SourceBuild RepoName="command-line-api" ManagedOnly="true" />
</Dependency>
<Dependency Name="Microsoft.SourceBuild.Intermediate.source-build-reference-packages" Version="8.0.0-alpha.1.23356.4">
diff --git a/eng/Versions.props b/eng/Versions.props
index 994e10a..65ed6ee 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -10,9 +10,9 @@
</PropertyGroup>
<PropertyGroup>
<!-- commandline -->
- <SystemCommandLineVersion>2.0.0-beta4.22272.1</SystemCommandLineVersion>
- <SystemCommandLineNamingConventionBinderVersion>2.0.0-beta4.22272.1</SystemCommandLineNamingConventionBinderVersion>
- <SystemCommandLineRenderingVersion>0.4.0-alpha.22272.1</SystemCommandLineRenderingVersion>
+ <SystemCommandLineVersion>2.0.0-beta4.23307.1</SystemCommandLineVersion>
+ <SystemCommandLineNamingConventionBinderVersion>2.0.0-beta4.23307.1</SystemCommandLineNamingConventionBinderVersion>
+ <SystemCommandLineRenderingVersion>0.4.0-alpha.23307.1</SystemCommandLineRenderingVersion>
<!-- msbuild -->
<MicrosoftBuildVersion>17.3.2</MicrosoftBuildVersion>
<MicrosoftBuildTasksCoreVersion>17.3.2</MicrosoftBuildTasksCoreVersion>
diff --git a/src/dotnet-sourcelink/Program.cs b/src/dotnet-sourcelink/Program.cs
index 0803734..eba8e56 100644
--- a/src/dotnet-sourcelink/Program.cs
+++ b/src/dotnet-sourcelink/Program.cs
@@ -42,18 +42,18 @@ private record DocumentInfo(
ImmutableArray<byte> Hash,
Guid HashAlgorithm);

- private readonly IConsole _console;
+ private readonly ParseResult _parseResult;
private bool _errorReported;

- public Program(IConsole console)
+ public Program(ParseResult parseResult)
{
- _console = console;
+ _parseResult = parseResult;
}

public static async Task<int> Main(string[] args)
{
var rootCommand = GetRootCommand();
- return await rootCommand.InvokeAsync(args);
+ return await rootCommand.Parse(args).InvokeAsync();
}

private static string GetSourceLinkVersion()
@@ -62,41 +62,77 @@ private static string GetSourceLinkVersion()
return attribute.InformationalVersion.Split('+').First();
}

- private static RootCommand GetRootCommand()
+ private static CliRootCommand GetRootCommand()
{
- var authArg = new Option<string>(new[] { "--auth", "-a" }, "Authentication method").FromAmong(AuthenticationMethod.Basic);
- var userArg = new Option<string>(new[] { "--user", "-u" }, "Username to use to authenticate") { Arity = ArgumentArity.ExactlyOne };
- var passwordArg = new Option<string>(new[] { "--password", "-p" }, "Password to use to authenticate") { Arity = ArgumentArity.ExactlyOne };
+ var authArg = new CliOption<string>("--auth", "-a")
+ {
+ Description = "Authentication method"
+ };
+ authArg.AcceptOnlyFromAmong(AuthenticationMethod.Basic);
+
+ var userArg = new CliOption<string>("--user", "-u")
+ {
+ Description = "Username to use to authenticate",
+ Arity = ArgumentArity.ExactlyOne
+ };
+
+ var passwordArg = new CliOption<string>("--password", "-p")
+ {
+ Description = "Password to use to authenticate",
+ Arity = ArgumentArity.ExactlyOne
+ };

- var test = new Command("test", "TODO")
+ var offlineArg = new CliOption<bool>("--offline")
{
- new Argument<string>("path", "Path to an assembly or .pdb"),
+ Description = "Offline mode - skip validation of sourcelink URL targets"
+ };
+
+ var test = new CliCommand("test", "TODO")
+ {
+ new CliArgument<string>("path")
+ {
+ Description = "Path to an assembly or .pdb"
+ },
authArg,
- new Option<Encoding>(new[] { "--auth-encoding", "-e" }, (arg) => Encoding.GetEncoding(arg.Tokens.Single().Value), false, "Encoding to use for authentication value"),
+ new CliOption<Encoding>("--auth-encoding", "-e")
+ {
+ CustomParser = arg => Encoding.GetEncoding(arg.Tokens.Single().Value),
+ Description = "Encoding to use for authentication value"
+ },
userArg,
passwordArg,
+ offlineArg,
};
- test.Handler = CommandHandler.Create<string, string?, Encoding?, string?, string?, IConsole>(TestAsync);
+ test.Action = CommandHandler.Create<string, string?, Encoding?, string?, string?, bool, ParseResult>(TestAsync);

- var printJson = new Command("print-json", "Print Source Link JSON stored in the PDB")
+ var printJson = new CliCommand("print-json", "Print Source Link JSON stored in the PDB")
{
- new Argument<string>("path", "Path to an assembly or .pdb"),
+ new CliArgument<string>("path")
+ {
+ Description = "Path to an assembly or .pdb"
+ }
};
- printJson.Handler = CommandHandler.Create<string, IConsole>(PrintJsonAsync);
+ printJson.Action = CommandHandler.Create<string, ParseResult>(PrintJsonAsync);

- var printDocuments = new Command("print-documents", "TODO")
+ var printDocuments = new CliCommand("print-documents", "TODO")
{
- new Argument<string>("path", "Path to an assembly or .pdb"),
+ new CliArgument<string>("path")
+ {
+ Description = "Path to an assembly or .pdb"
+ }
};
- printDocuments.Handler = CommandHandler.Create<string, IConsole>(PrintDocumentsAsync);
+ printDocuments.Action = CommandHandler.Create<string, ParseResult>(PrintDocumentsAsync);

- var printUrls = new Command("print-urls", "TODO")
+ var printUrls = new CliCommand("print-urls", "TODO")
{
- new Argument<string>("path", "Path to an assembly or .pdb"),
+ new CliArgument<string>("path")
+ {
+ Description = "Path to an assembly or .pdb"
+ }
};
- printUrls.Handler = CommandHandler.Create<string, IConsole>(PrintUrlsAsync);
+ printUrls.Action = CommandHandler.Create<string, ParseResult>(PrintUrlsAsync);

- var root = new RootCommand()
+ var root = new CliRootCommand()
{
test,
printJson,
@@ -106,13 +142,13 @@ private static RootCommand GetRootCommand()

root.Description = "dotnet-sourcelink";

- root.AddValidator(commandResult =>
+ root.Validators.Add(commandResult =>
{
- if (commandResult.FindResultFor(authArg) != null)
+ if (commandResult.GetResult(authArg) != null)
{
- if (commandResult.FindResultFor(userArg) == null || commandResult.FindResultFor(passwordArg) == null)
+ if (commandResult.GetResult(userArg) == null || commandResult.GetResult(passwordArg) == null)
{
- commandResult.ErrorMessage = "Specify --user and --password options";
+ commandResult.AddError("Specify --user and --password options");
}
}
});
@@ -122,15 +158,15 @@ private static RootCommand GetRootCommand()

private void ReportError(string message)
{
- _console.Error.Write(message);
- _console.Error.Write(Environment.NewLine);
+ _parseResult.Configuration.Error.Write(message);
+ _parseResult.Configuration.Error.Write(Environment.NewLine);
_errorReported = true;
}

private void WriteOutputLine(string message)
{
- _console.Out.Write(message);
- _console.Out.Write(Environment.NewLine);
+ _parseResult.Configuration.Output.Write(message);
+ _parseResult.Configuration.Output.Write(Environment.NewLine);
}

private static async Task<int> TestAsync(
@@ -139,7 +175,8 @@ private void WriteOutputLine(string message)
Encoding? authEncoding,
string? user,
string? password,
- IConsole console)
+ bool offline,
+ ParseResult parseResult)
{
var authenticationHeader = (authMethod != null) ? GetAuthenticationHeader(authMethod, authEncoding ?? Encoding.ASCII, user!, password!) : null;

@@ -152,17 +189,17 @@ private void WriteOutputLine(string message)

try
{
- return await new Program(console).TestAsync(path, authenticationHeader, cancellationSource.Token).ConfigureAwait(false);
+ return await new Program(parseResult).TestAsync(path, authenticationHeader, offline, cancellationSource.Token).ConfigureAwait(false);
}
catch (OperationCanceledException)
{
- console.Error.Write("Operation canceled.");
- console.Error.Write(Environment.NewLine);
+ parseResult.Configuration.Error.Write("Operation canceled.");
+ parseResult.Configuration.Error.Write(Environment.NewLine);
return -1;
}
}

- private async Task<int> TestAsync(string path, AuthenticationHeaderValue? authenticationHeader, CancellationToken cancellationToken)
+ private async Task<int> TestAsync(string path, AuthenticationHeaderValue? authenticationHeader, bool offline, CancellationToken cancellationToken)
{
var documents = new List<DocumentInfo>();
ReadAndResolveDocuments(path, documents);
@@ -172,31 +209,34 @@ private async Task<int> TestAsync(string path, AuthenticationHeaderValue? authen
return _errorReported ? 1 : 0;
}

- var handler = new HttpClientHandler();
- if (handler.SupportsAutomaticDecompression)
- handler.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
+ if (!offline)
+ {
+ var handler = new HttpClientHandler();
+ if (handler.SupportsAutomaticDecompression)
+ handler.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;

- using var client = new HttpClient(handler);
- client.DefaultRequestHeaders.UserAgent.Add(s_sourceLinkProductHeaderValue);
- client.DefaultRequestHeaders.Authorization = authenticationHeader;
+ using var client = new HttpClient(handler);
+ client.DefaultRequestHeaders.UserAgent.Add(s_sourceLinkProductHeaderValue);
+ client.DefaultRequestHeaders.Authorization = authenticationHeader;

- var outputLock = new object();
+ var outputLock = new object();

- var errorReporter = new Action<string>(message =>
- {
- lock (outputLock)
+ var errorReporter = new Action<string>(message =>
{
- ReportError(message);
- }
- });
+ lock (outputLock)
+ {
+ ReportError(message);
+ }
+ });

- var tasks = documents.Where(document => document.Uri != null).Select(document => DownloadAndValidateDocumentAsync(client, document, errorReporter, cancellationToken));
-
- _ = await Task.WhenAll(tasks).ConfigureAwait(false);
+ var tasks = documents.Where(document => document.Uri != null).Select(document => DownloadAndValidateDocumentAsync(client, document, errorReporter, cancellationToken));

- if (_errorReported)
- {
- return 1;
+ _ = await Task.WhenAll(tasks).ConfigureAwait(false);
+
+ if (_errorReported)
+ {
+ return 1;
+ }
}

WriteOutputLine($"File '{path}' validated.");
@@ -277,8 +317,8 @@ private static async Task<bool> DownloadAndValidateDocumentAsync(HttpClient clie
}
}

- private static Task<int> PrintJsonAsync(string path, IConsole console)
- => Task.FromResult(new Program(console).PrintJson(path));
+ private static Task<int> PrintJsonAsync(string path, ParseResult parseResult)
+ => Task.FromResult(new Program(parseResult).PrintJson(path));

private int PrintJson(string path)
{
@@ -299,8 +339,8 @@ private int PrintJson(string path)
return _errorReported ? 1 : 0;
}

- private static Task<int> PrintDocumentsAsync(string path, IConsole console)
- => Task.FromResult(new Program(console).PrintDocuments(path));
+ private static Task<int> PrintDocumentsAsync(string path, ParseResult parseResult)
+ => Task.FromResult(new Program(parseResult).PrintDocuments(path));

public static string ToHex(byte[] bytes)
=> BitConverter.ToString(bytes).Replace("-", "").ToLowerInvariant();
@@ -324,8 +364,8 @@ private int PrintDocuments(string path)
return _errorReported ? 1 : 0;
}

- private static Task<int> PrintUrlsAsync(string path,IConsole console)
- => Task.FromResult(new Program(console).PrintUrls(path));
+ private static Task<int> PrintUrlsAsync(string path, ParseResult parseResult)
+ => Task.FromResult(new Program(parseResult).PrintUrls(path));

private int PrintUrls(string path)
{
diff --git a/src/dotnet-sourcelink/dotnet-sourcelink.csproj b/src/dotnet-sourcelink/dotnet-sourcelink.csproj
index 6e0bd5f..ac179f1 100644
--- a/src/dotnet-sourcelink/dotnet-sourcelink.csproj
+++ b/src/dotnet-sourcelink/dotnet-sourcelink.csproj
@@ -4,8 +4,6 @@
<TargetFrameworks>$(NetCurrent)</TargetFrameworks>
<!-- Allow tool to roll forward to a newer major version. -->
<RollForward>Major</RollForward>
- <!-- Will be removed by https://github.com/dotnet/sourcelink/issues/1028 -->
- <ExcludeFromSourceBuild>true</ExcludeFromSourceBuild>

<!-- NuGet -->
<IsPackable>true</IsPackable>
@@ -13,7 +11,7 @@
<ToolCommandName>sourcelink</ToolCommandName>
<Description>Command line tool for SourceLink testing.</Description>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
- <PackAsToolShimRuntimeIdentifiers>win-x64;win-x86;osx-x64</PackAsToolShimRuntimeIdentifiers>
+ <PackAsToolShimRuntimeIdentifiers Condition="'$(DotNetBuildFromSource)' != 'true'">win-x64;win-x86;osx-x64</PackAsToolShimRuntimeIdentifiers>
</PropertyGroup>

<ItemGroup>