Skip to content

Implement dotnet nuget trust command#3989

Merged
erdembayar merged 23 commits intodevfrom
dev-eryondon-8053DotnetTrustedSignersCommand
Apr 24, 2021
Merged

Implement dotnet nuget trust command#3989
erdembayar merged 23 commits intodevfrom
dev-eryondon-8053DotnetTrustedSignersCommand

Conversation

@erdembayar
Copy link
Copy Markdown
Contributor

@erdembayar erdembayar commented Apr 9, 2021

Bug

Fixes: NuGet/Home#8053

Regression? Last working version: No

Description

  1. Implement "dotnet nuget trust" command according to Nuget.exe command "nuget trusted-signers". Spec is here.
  2. Add tests in \test\NuGet.Core.FuncTests\Dotnet.Integration.Test\DotnetTrustTests.cs
  3. Add tests in \test\NuGet.Core.FuncTests\NuGet.XPlat.FuncTest\XPlatTrustTests.cs

PR Checklist

@erdembayar erdembayar marked this pull request as ready for review April 10, 2021 03:59
@erdembayar erdembayar requested a review from a team as a code owner April 10, 2021 03:59
@erdembayar erdembayar force-pushed the dev-eryondon-8053DotnetTrustedSignersCommand branch from c26bd42 to 3eb5aba Compare April 10, 2021 17:12
@erdembayar erdembayar force-pushed the dev-eryondon-8053DotnetTrustedSignersCommand branch from 9f5ce09 to 4439901 Compare April 12, 2021 20:10
Copy link
Copy Markdown
Contributor

@kartheekp-ms kartheekp-ms left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left few comments to start with.

Copy link
Copy Markdown
Contributor Author

@erdembayar erdembayar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kartheekp-ms
Thank you for your review. I addressed your comments, please check.

{
var baseException = e.GetBaseException();

if (baseException is TrustedSignerAlreadyExistsException
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reason I added this part is to make experience same as nuget.exe.
For example if same trusted signed already exist then it just show A trusted signer 'NewtonAuthor333' already exists.

image

Without this check dotnet nuget trust 'll show red marked part assuming it's unhandled.

image

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really wish we weren't doing this in the first place. Printing out help doesn't help at all unless the error itself has to do with a command, argument, or option being invalid.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Anyway, I don't think we should do this, and we should start a separate conversation for not calling ShowBestHelp() in every case, and narrowing it down, instead of creating an allowlist like this that definitely does not consistently cover other errors in dotnet.exe nuget commands.

So tl;dr: I see where you're coming from, and it's good that you're aiming to maintain nuget.exe similarity here, but I think "fit in to dotnet.exe" should be higher priority, and also I just don't like this specific approach to it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. Yes, I agree it needs to be addressed separately.
I removed this part and created NuGet/Home#10788 issue to track it.

Copy link
Copy Markdown
Contributor

@zkat zkat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So far so good! A few questions, and some comments on stuff I think should be changed. Great work!

{
var baseException = e.GetBaseException();

if (baseException is TrustedSignerAlreadyExistsException
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really wish we weren't doing this in the first place. Printing out help doesn't help at all unless the error itself has to do with a command, argument, or option being invalid.

{
var baseException = e.GetBaseException();

if (baseException is TrustedSignerAlreadyExistsException
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Anyway, I don't think we should do this, and we should start a separate conversation for not calling ShowBestHelp() in every case, and narrowing it down, instead of creating an allowlist like this that definitely does not consistently cover other errors in dotnet.exe nuget commands.

So tl;dr: I see where you're coming from, and it's good that you're aiming to maintain nuget.exe similarity here, but I think "fit in to dotnet.exe" should be higher priority, and also I just don't like this specific approach to it.

Copy link
Copy Markdown
Contributor Author

@erdembayar erdembayar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zkat
Thank you for your review.
I addressed your PR comment concerns. Please review again.

{
var baseException = e.GetBaseException();

if (baseException is TrustedSignerAlreadyExistsException
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. Yes, I agree it needs to be addressed separately.
I removed this part and created NuGet/Home#10788 issue to track it.

@erdembayar erdembayar force-pushed the dev-eryondon-8053DotnetTrustedSignersCommand branch from 3800278 to b408441 Compare April 21, 2021 18:23
@erdembayar erdembayar requested a review from kartheekp-ms April 21, 2021 19:05
Copy link
Copy Markdown
Contributor

@heng-liu heng-liu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for implementing the trusted-signers command!

Copy link
Copy Markdown
Contributor Author

@erdembayar erdembayar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@heng-liu
Thank you for your review. I addressed your comments, please check.

_trustedSignersProvider.AddOrUpdateTrustedSigner(existingRepository);

await _logger.LogAsync(LogLevel.Information, string.Format(CultureInfo.CurrentCulture, Strings.SuccessfullySynchronizedTrustedRepository, name));
await _logger.LogAsync(LogLevel.Minimal, string.Format(CultureInfo.CurrentCulture, Strings.SuccessfullySynchronizedTrustedRepository, name));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you elaborate on the before and after results of logging level changes in this and other files? What's the impact in NuGet.exe too?

Copy link
Copy Markdown
Contributor Author

@erdembayar erdembayar Apr 22, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I get this idea from @kartheekp-ms 's recent PR#3992
Without this change dotnet nuget trust command show nothing on cli with successful action. Only show something if there is error/warning. Technically it's too quite due to differences in msbuild and nuget.exe loge levels.
With this change we can see result exactly same as NuGet.exe for successful action. I believe there is no impact on NuGet.exe.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kartheekp-ms Also can comment on this.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe there is no impact on NuGet.exe.

Isn't it the same code path for both dotnet and NuGet.exe? How could the change affect only dotnet and not NuGet.exe? I'm trying to understand.

Copy link
Copy Markdown
Contributor Author

@erdembayar erdembayar Apr 23, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dtivel @kartheekp-ms
If no verbosity is passed then verbosity default to LogLevel.Minimal:

default:
return LogLevel.Minimal;

But this log is logged with LogLevel.Information wouldn't displayed due to below level check:

protected virtual bool DisplayMessage(LogLevel messageLevel)
{
return (messageLevel >= VerbosityLevel);
}

After thinking instead of making change here in TrustedSignerActionsProvider.cs, how about I change below?

setLogLevel(XPlatUtility.MSBuildVerbosityToNuGetLogLevel(verbosity.Value()));

To:

                    // If not verbosity passed then it defaults LogLevel.Minimal which result no message displayed because successfull message are logged at Loglevel.Information.
                    // Since NuGet LogLevel.Information is equal to MSBuild normal, we need to defaults "N"
                    setLogLevel(XPlatUtility.MSBuildVerbosityToNuGetLogLevel(verbosity.Value() ?? "N"));

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kartheekp-ms
I just synched offline with @dtivel.
I'll leave code as it's for now, but I'll post table shows if there is any change of user experience in output.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that a table showing what is displayed for each verbosity level is helpful. For e.g., https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-nuget-verify#options

Copy link
Copy Markdown
Contributor Author

@erdembayar erdembayar Apr 23, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dtivel @kartheekp-ms
I created comparison table between latest nuget(v5.9) and nugetcandidate(compiled from my code), dotnet nuget trust(compiled from my code). So far I don't see any regression on nuget.exe usage experience. Please note dotnet nuget trust is bit different in handling error cases than nuget.exe, in this table I still assumed as same, but dotnet nuget trust it's not objective of this table, it's created to make sure nuget(v5.9) and nugetcandidate experience are still same. You can ignore dotnet column. Also you can press on ✔️ links to see actual output behind it, some outputs are combined for all 3, for example for q mode since there is no output.

Action nuget59 nugetCandidate dotnet  
nuget59 trusted-signer list ✔️ ✔️ ✔️  
nuget59 trusted-signer list -verbosity q  ✔️ ✔️  ✔️    
nuget59 trusted-signer list -verbosity n ✔️  ✔️   ✔️  
nuget59 trusted-signer list -verbosity d  ✔️   ✔️ ✔️   
nuget59 trusted-signers Add -Name NuGet -config ..\nuget.config   ✔️ ✔️  ✔️  
nuget59 trusted-signers add .\newtonsoft.json.13.0.1-beta1.nupkg -Name NugetOrg -Repository -config ..\nuget.config   ✔️ ✔️  ✔️   
nuget59 trusted-signers Add -Name MyCompanyCert -CertificateFingerprint CE40881FF5F0AD3E58965DA20A9F571EF1651A56933748E1BF1C99E537C4E039 -FingerprintAlgorithm SHA256 -config ..\nuget.config  ✔️  ✔️  ✔️   
nuget59 trusted-signers Add -Name NuGetTrust -ServiceIndex https://api.nuget.org/v3/index.json -config ..\nuget.config -Owners "NugetTestOrg;MSTestOrg;TrustedTesOwners" -config ..\nuget.config   ✔️ ✔️  ✔️   
nuget59 trusted-signers sync -Name NuGetTrust -config ..\nuget.config   ✔️ ✔️  ✔️   
nuget59 trusted-signers Remove -Name NugetTrust -config ..\nuget.config   ✔️  ✔️ ✔️  

{
if (action == TrustCommand.Author || action == TrustCommand.Repository)
{
packagePath = command.Values[2];
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As per spec, For trust author and trust repository, <package> may be a glob/wildcard. This must be consistent across platforms, so the Windows version must expand these wildcards when it receives them as arguments.. The way I am reading this is the command should accept multiple packagePaths. If I understand the current logic correctly, only one value is accepted for package path. The following command should be supported.

dotnet nuget trust author Contoso ./contoso.library1.nupkg ./contoso.library2.nupkg

When I implemented dotnet nuget verify command, I changed VerifyArgs as shown below to accept multiple packagePaths.

/// <summary>
/// Path to the package that has to be verified.
/// </summary>
[Obsolete("Use PackagePaths instead")]
public string PackagePath
{
get
{
switch (PackagePaths.Count)
{
case 0:
return null;
case 1:
return PackagePaths[0];
default:
throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture,
Strings.Error_MultiplePackagePaths,
nameof(PackagePaths)));
}
}
set => PackagePaths = new[] { value };
}
/// <summary>
/// Paths to the packages that has to be verified.
/// </summary>
public IReadOnlyList<string> PackagePaths { get; set; }

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I recently created this PR#3993 for nuget.exe, as you can see based on other trust related commands doesn't accept multiple files we decided to accept only 1 file at the time. So I believe it applies here too. Please note that experience didn't work for nuget.exe even before my change, so there is no backward compat issue nor breaking experience.

But dotnet nuget verify case is different since it's just outputting result on cli and not mutating state of machine config, so it's ok.

_trustedSignersProvider.AddOrUpdateTrustedSigner(existingRepository);

await _logger.LogAsync(LogLevel.Information, string.Format(CultureInfo.CurrentCulture, Strings.SuccessfullySynchronizedTrustedRepository, name));
await _logger.LogAsync(LogLevel.Minimal, string.Format(CultureInfo.CurrentCulture, Strings.SuccessfullySynchronizedTrustedRepository, name));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that a table showing what is displayed for each verbosity level is helpful. For e.g., https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-nuget-verify#options

[CIOnlyTheory]
[InlineData(true)]
[InlineData(false)]
public async Task DotnetTrust_AuthorAction_RelativePathConfileFile_Succeeds(bool allowUntrustedRoot)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit : test case name DotnetTrust_AuthorAction_RelativePathConfigFile_Succeeds

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. I'll address later in another PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Signing: implement dotnet trusted-signers command

6 participants