Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for suppressing warning messages #1393

Closed
wants to merge 1 commit into from

Conversation

JohnTortugo
Copy link
Contributor

Closes: #1295

With this change SignTool will support the user to specify warning messages that should be disabled in the scope of a specific file or the whole signing process. For instance, first candidate for this is the SIGN001 warning.

Changes:

  • SignToolTests.cs : Two new test cases added
  • SignToolConstants.cs : Moved definition of error messages here
  • Configuration.cs : Receive the new parameters and check the suppress condition.
  • SignToolTask.cs : Receive & parse the new parameter / attribute.

@JohnTortugo
Copy link
Contributor Author

Can someone take peek?

@@ -191,7 +193,7 @@ public void Dispose()
var signToolArgs = new SignToolArgs(_tmpDir, microBuildCorePath: "MicroBuildCorePath", testSign: true, msBuildPath: null, _tmpDir, enclosingDir: "", "");

var signTool = new FakeSignTool(signToolArgs, task.Log);
var signingInput = new Configuration(signToolArgs.TempDir, itemsToSign, strongNameSignInfo, fileSignInfo, extensionsSignInfo, dualCertificates, task.Log).GenerateListOfFiles();
var signingInput = new Configuration(signToolArgs.TempDir, itemsToSign, strongNameSignInfo, fileSignInfo, globallySupressedMessageCodes, supressedMessageCodes, extensionsSignInfo, dualCertificates, task.Log).GenerateListOfFiles();
Copy link
Contributor

Choose a reason for hiding this comment

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

signToolArgs.Te [](start = 49, length = 15)

Nit: move each parameter to its own line.

{
var engine = new FakeBuildEngine();
var task = new SignToolTask { BuildEngine = engine };
var signingInput = new Configuration(_tmpDir, itemsToSign, strongNameSignInfo, fileSignInfo, extensionsSignInfo, dualCertificates, task.Log).GenerateListOfFiles();
var signingInput = new Configuration(_tmpDir, itemsToSign, strongNameSignInfo, fileSignInfo, globallySupressedMessageCodes, supressedMessageCodes, extensionsSignInfo, dualCertificates, task.Log).GenerateListOfFiles();
Copy link
Contributor

Choose a reason for hiding this comment

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

var signingInput [](start = 12, length = 16)

Nit: same as above

$@"SIGN001: Signing 3rd party library '{Path.Combine(_tmpDir, "ContainerSigning", "B306A318B3A11BF342995F6A1FC5AADF5DB4DD49F4EFF7E013D31208DD58EBDC", "lib/net461/ProjectOne.dll")}' with Microsoft certificate 'Microsoft400'. The library is considered 3rd party library due to its copyright: ''.",
$@"SIGN001: Signing 3rd party library '{Path.Combine(_tmpDir, "ContainerSigning", "9F8CCEE4CECF286C80916F13EAB8DF1FC6C9BED5F81E3AFF26747C008D265E5C", "lib/netcoreapp2.0/ContainerOne.dll")}' with Microsoft certificate 'Microsoft400'. The library is considered 3rd party library due to its copyright: ''.",
$@"SIGN001: Signing 3rd party library '{Path.Combine(_tmpDir, "ContainerSigning", "CC1D99EE8C2F627E77D019E94B06EBB6D87A4D19E65DDAEF62B6137E49167BAF", "lib/netcoreapp2.1/ProjectOne.dll")}' with Microsoft certificate 'Microsoft400'. The library is considered 3rd party library due to its copyright: ''.",
$@"SIGN001: Signing 3rd party library '{Path.Combine(_tmpDir, "ContainerSigning", "47F202CA51AD708535A01E96B95027042F8448333D86FA7D5F8D66B67644ACEC", "lib/netstandard2.0/ProjectOne.dll")}' with Microsoft certificate 'Microsoft400'. The library is considered 3rd party library due to its copyright: ''."
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: Split these in more lines so there is no need to scroll right/left in CodeFlow as in GitHub

Copy link
Member

Choose a reason for hiding this comment

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

I wouldn't do that here. The actual message is not that interesting to review.


In reply to: 236888896 [](ancestors = 236888896)


private readonly Dictionary<ExplicitCertificateKey, HashSet<SignToolConstants.SigningToolMSGCodes>> _suppressedMessageCodes;

private readonly HashSet<SignToolConstants.SigningToolMSGCodes> _globallySupressedMessageCodes;
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: Most others have summaries please add them to these as well

string[] dualCertificates, TaskLoggingHelper log)
Dictionary<ExplicitCertificateKey, string> fileSignInfo, HashSet<SignToolConstants.SigningToolMSGCodes> globallySupressedMessageCodes,
Dictionary<ExplicitCertificateKey, HashSet<SignToolConstants.SigningToolMSGCodes>> suppressedMessageCodes,
Dictionary<string, SignInfo> extensionSignInfo, string[] dualCertificates, TaskLoggingHelper log)
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: move to one parameter per line

@jcagme
Copy link
Contributor

jcagme commented Nov 27, 2018

            GetPEInfo(fullPath, out isManagedPE, out var publicKeyToken, out targetFramework, out copyright);

You could inline this here, just do out string copyright and remove line 214


Refers to: src/Microsoft.DotNet.SignTool/src/Configuration.cs:224 in 4081535. [](commit_id = 4081535, deletion_comment = False)

// Check if there is any configuration to disable messages for this specific file
if (!_suppressedMessageCodes.TryGetValue(new ExplicitCertificateKey(fileName, publicKeyToken, targetFramework), out suppressedMessages))
{
_suppressedMessageCodes.TryGetValue(new ExplicitCertificateKey(fileName, publicKeyToken), out suppressedMessages);
Copy link
Contributor

Choose a reason for hiding this comment

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

Same inline comment for supressedMessages

// Check if there is any configuration to disable messages for this specific file
if (!_suppressedMessageCodes.TryGetValue(new ExplicitCertificateKey(fileName, publicKeyToken, targetFramework), out suppressedMessages))
{
_suppressedMessageCodes.TryGetValue(new ExplicitCertificateKey(fileName, publicKeyToken), out suppressedMessages);
Copy link
Contributor

Choose a reason for hiding this comment

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

_suppressedMessageCodes.TryGetValue [](start = 20, length = 35)

What if this also returns false?

// at least not by checking with PKT + TargetFramework.
if (suppressedMessages == null)
{
_suppressedMessageCodes.TryGetValue(new ExplicitCertificateKey(fileName), out suppressedMessages);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd check the returned value in 243 and if its false I'd execute this code to try to keep related code close together

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I can do that. I did this way to follow the pattern of the existing code.

@jcagme
Copy link
Contributor

jcagme commented Nov 27, 2018

        if (SignToolConstants.IgnoreFileCertificateSentinel.Equals(explicitCertificateName, StringComparison.OrdinalIgnoreCase))

There is a chance this is null and I assume SignToolConstants.IgnoreFileCertificateSentinel is none, should we move this if inside the if in line 268?


Refers to: src/Microsoft.DotNet.SignTool/src/Configuration.cs:261 in 4081535. [](commit_id = 4081535, deletion_comment = False)

bool isMicrosoftLibrary = IsMicrosoftLibrary(copyright);
bool isMicrosoftCertificate = !IsThirdPartyCertificate(signInfo.Certificate);
if (isMicrosoftLibrary != isMicrosoftCertificate)
if (!_globallySupressedMessageCodes.Contains(SigningToolMSGCodes.SIGN001) && (suppressedMessages == null || !suppressedMessages.Contains(SigningToolMSGCodes.SIGN001)))
Copy link
Contributor

Choose a reason for hiding this comment

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

if (!_g [](start = 20, length = 7)

NIt: Move each condition to its own line

LogWarning("SIGN001", $"Signing 3rd party library '{fullPath}' with Microsoft certificate '{signInfo.Certificate}'. The library is considered 3rd party library due to its copyright: '{copyright}'.");
if (isMicrosoftLibrary)
{
LogWarning(SigningToolMSGCodes.SIGN001, $"Signing Microsoft library '{fullPath}' with 3rd party certificate '{signInfo.Certificate}'. The library is considered Microsoft library due to its copyright: '{copyright}'.");
Copy link
Contributor

Choose a reason for hiding this comment

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

LogWarning(Si [](start = 32, length = 13)

Nit: Break these warnings down in different lines

@@ -11,6 +11,9 @@ internal static class SignToolConstants
{
public const string IgnoreFileCertificateSentinel = "None";

public enum SigningToolMSGCodes { SIGN001, SIGN002 };


Copy link
Contributor

Choose a reason for hiding this comment

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

Remove blank line

@@ -163,16 +167,18 @@ public void ExecuteImpl()

if (Log.HasLoggedErrors) return;

ParseFileSignInfo(out var fileSignInfo, out var supressedMessageCodes);
Copy link
Contributor

Choose a reason for hiding this comment

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

out var fileSignInfo, out var supressedMessageCodes [](start = 30, length = 51)

In cases like this I rather use types to understand what these objects are.


if (Log.HasLoggedErrors) return;

var signToolArgs = new SignToolArgs(TempDir, MicroBuildCorePath, TestSign, MSBuildPath, LogDir, enclosingDir, SNBinaryPath);
var signTool = DryRun ? new ValidationOnlySignTool(signToolArgs, Log) : (SignTool)new RealSignTool(signToolArgs, Log);
var signingInput = new Configuration(TempDir, ItemsToSign, strongNameInfo, fileSignInfo, extensionSignInfo, dualCertificates, Log).GenerateListOfFiles();
var signingInput = new Configuration(TempDir, ItemsToSign, strongNameInfo, fileSignInfo, globallySuppWarnings, supressedMessageCodes, extensionSignInfo, dualCertificates, Log).GenerateListOfFiles();
Copy link
Contributor

Choose a reason for hiding this comment

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

var signi [](start = 12, length = 9)

Nit: split

@@ -335,9 +362,10 @@ int getCommonPrefixLength(string[] dir1, string[] dir2)
return map;
}

private Dictionary<ExplicitCertificateKey, string> ParseFileSignInfo()
private void ParseFileSignInfo(out Dictionary<ExplicitCertificateKey, string> explicitCertificateNames, out Dictionary<ExplicitCertificateKey, HashSet<SignToolConstants.SigningToolMSGCodes>> suppressedMessageCodes)
Copy link
Contributor

Choose a reason for hiding this comment

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

private void P [](start = 8, length = 14)

Nit: split

{
if (explicitCertificateNames.TryGetValue(key, out var existingCert))
{
Log.LogError($"Duplicate entries in {nameof(FileSignInfo)} with the same key ('{fileName}', '{publicKeyToken}', '{targetFramework}') for CertificateName attribute: '{existingCert}', '{certificateName}'. Keeping the previous one.");
Copy link
Contributor

Choose a reason for hiding this comment

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

Log.LogError($"Dupli [](start = 28, length = 20)

No need to continue here? Also, split

map.Add(key, certificateName);
if (!string.IsNullOrWhiteSpace(certificateName))
{
if (explicitCertificateNames.TryGetValue(key, out var existingCert))
Copy link
Contributor

Choose a reason for hiding this comment

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

explicitCertificateNames.TryGetValue [](start = 28, length = 36)

Are you just trying to determine whether this Dictionary contains a key? If so, you could use the ContainsKey method so you don't keep an extra variable around

}
}

if (suppressedMessageCodes.TryGetValue(key, out var existingCert))
Copy link
Contributor

Choose a reason for hiding this comment

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

suppressedMessageCodes [](start = 28, length = 22)

Use ContainsKey


if (suppressedMessageCodes.TryGetValue(key, out var existingCert))
{
Log.LogError($"Duplicate entries in {nameof(FileSignInfo)} with the same key ('{fileName}', '{publicKeyToken}', '{targetFramework}') for NoWarn attribute. Keeping the previous one.");
Copy link
Contributor

Choose a reason for hiding this comment

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

LogError [](start = 32, length = 8)

Also, is this truly an error? I feel is more of information or warning

Copy link
Contributor

@jcagme jcagme left a comment

Choose a reason for hiding this comment

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

🕐

@@ -11,6 +11,9 @@ internal static class SignToolConstants
{
public const string IgnoreFileCertificateSentinel = "None";

public enum SigningToolMSGCodes { SIGN001, SIGN002 };
Copy link
Member

@tmat tmat Nov 29, 2018

Choose a reason for hiding this comment

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

public enum SigningToolMSGCodes { SIGN001, SIGN002 }; [](start = 8, length = 53)

I'd move this enum outside of the class and rename it to DiagnosticId.

{
if (!Enum.TryParse<SignToolConstants.SigningToolMSGCodes>(warningCode.ItemSpec, true, out var value))
{
Log.LogError($"Unrecognized message code was informed in {nameof(NoWarn)} -> {warningCode}");
Copy link
Member

Choose a reason for hiding this comment

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

nrecognized message code was informed in [](start = 40, length = 41)

This doesn't make sense in English. Instead use something like "Unrecognized warning id specified in {nameof(NoWarn)}: '{warningCode}'"

if (!_suppressedMessageCodes.TryGetValue(new ExplicitCertificateKey(fileName, publicKeyToken, targetFramework), out suppressedMessages))
{
_suppressedMessageCodes.TryGetValue(new ExplicitCertificateKey(fileName, publicKeyToken), out suppressedMessages);
}
Copy link
Member

@tmat tmat Nov 29, 2018

Choose a reason for hiding this comment

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

This seems pretty complicated. Why not make the NoWarn part of the fileSignInfo map? That is Dictionary<ExplicitCertificateKey, CertificateInfo> where CertificateInfo is struct { Name; ImmutableArray<DiagnosticId> SuppressedWarnings; } .
Then when we look up a file in the map and get the certificate name we immediately see if we have any warning suppressions.

Copy link
Member

@tmat tmat left a comment

Choose a reason for hiding this comment

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

🕐

@JohnTortugo
Copy link
Contributor Author

Thank you all for reviewing. I'm going to close this PR until we get further evidence that we indeed need this.

@JohnTortugo JohnTortugo deleted the SupressWarnings branch January 18, 2019 20:36
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.

3 participants