From 30da0f2cbddc5515d9bbddb71839a76927352117 Mon Sep 17 00:00:00 2001 From: Qi Wang Date: Thu, 4 Aug 2022 22:40:45 +0000 Subject: [PATCH] Merged PR 671684: Add roslynanalyzers recommend and required ruleset Add ruleset Add Copy To Directory for Roslynanalyzers Add suppression files Disable CA5350 CA5351 CA2301 warning in some files, this is moved to another PR https://dev.azure.com/mseng/Domino/_git/BuildXL.Internal/pullrequest/671797 Related work items: #1941023 --- .../buildxl/compliance/buildxl.gdnsuppress | 144 +++++++ .gdn/README.md | 1 + .../Tool.Guardian.RoslynAnalyzers.dsc | 55 ++- .../Tool.Guardian.ComplianceBuild.dsc | 2 +- .../Public/Tools/Guardian/Tool.Guardian.dsc | 1 + .../BuildXL.Recommend.Required.Error.ruleset | 405 ++++++++++++++++++ Public/Sdk/SelfHost/BuildXL/BuildXLSdk.dsc | 25 +- 7 files changed, 603 insertions(+), 30 deletions(-) create mode 100644 .gdn/README.md create mode 100644 Public/Sdk/SelfHost/BuildXL/BuildXL.Recommend.Required.Error.ruleset diff --git a/.config/buildxl/compliance/buildxl.gdnsuppress b/.config/buildxl/compliance/buildxl.gdnsuppress index f75cedea2..deb4f7bcc 100644 --- a/.config/buildxl/compliance/buildxl.gdnsuppress +++ b/.config/buildxl/compliance/buildxl.gdnsuppress @@ -399,6 +399,150 @@ "createdDate": "2022-05-12 20:19:18Z", "expirationDate": null, "type": null + }, + "4ea9bfe9e5da299112880357be33900959617c18232f6f58995592380b20af37": { + "signature": "4ea9bfe9e5da299112880357be33900959617c18232f6f58995592380b20af37", + "alternativeSignatures": [ + "25dd38c1ca5e0acd97440cb6eb388d4c804c62be2daea6a7dbf9c391c93eb70e" + ], + "target": "Public/Src/Cache/MemoizationStore/VstsApp/Application.cs", + "memberOf": [ + "default" + ], + "tool": "roslynanalyzers", + "ruleId": "RA004", + "justification": null, + "createdDate": "2022-07-23 17:31:56Z", + "expirationDate": null, + "type": null + }, + "2b691fc8d76f8aba6ad447a48eb10e76868176535911a2c27712bd487455fdef": { + "signature": "2b691fc8d76f8aba6ad447a48eb10e76868176535911a2c27712bd487455fdef", + "alternativeSignatures": [ + "225c4fda9e70dad045c11c9b114652e09998497b421c7fb3ee76fc1466257fea" + ], + "target": "Public/Src/Cache/MemoizationStore/VstsApp/Application.cs", + "memberOf": [ + "default" + ], + "tool": "roslynanalyzers", + "ruleId": "RA006", + "justification": null, + "createdDate": "2022-07-23 17:31:56Z", + "expirationDate": null, + "type": null + }, + "cad030ee53af08b694a9bf4f989a79bfe8b1310178fb478735ea0e1e69fff14f": { + "signature": "cad030ee53af08b694a9bf4f989a79bfe8b1310178fb478735ea0e1e69fff14f", + "alternativeSignatures": [ + "cff36e110e0a70c700f5856578957d332b0147cb65dfce1c1d22e3dd8c1505f0" + ], + "target": "Public/Src/Cache/MemoizationStore/VstsApp/Application.cs", + "memberOf": [ + "default" + ], + "tool": "roslynanalyzers", + "ruleId": "RA004", + "justification": null, + "createdDate": "2022-07-23 17:31:56Z", + "expirationDate": null, + "type": null + }, + "3d73e68cd176ab27ab1b4120f71939ad6c10d5f708b0b4f478a6f46690a8402e": { + "signature": "3d73e68cd176ab27ab1b4120f71939ad6c10d5f708b0b4f478a6f46690a8402e", + "alternativeSignatures": [ + "1a42a451eeffcbccc95439ceb768a6ea24429da45bcba8f039f4832a2675dd00" + ], + "target": "Public/Src/Cache/MemoizationStore/VstsApp/Application.cs", + "memberOf": [ + "default" + ], + "tool": "roslynanalyzers", + "ruleId": "RA006", + "justification": null, + "createdDate": "2022-07-23 17:31:56Z", + "expirationDate": null, + "type": null + }, + "680fe1e5ef990106e78fae0232bff03b7fae096179919e208810e899ef4357b9": { + "signature": "680fe1e5ef990106e78fae0232bff03b7fae096179919e208810e899ef4357b9", + "alternativeSignatures": [ + "7cc7065d83e4dfa28c3b4976c837b7f72e5fe1d5641421f99b4d6c537001269b" + ], + "target": "Public/Src/Cache/MemoizationStore/VstsApp/Application.cs", + "memberOf": [ + "default" + ], + "tool": "roslynanalyzers", + "ruleId": "CA1822", + "justification": null, + "createdDate": "2022-07-23 17:31:56Z", + "expirationDate": null, + "type": null + }, + "0179541aae15474f41e7e747ad56255c8c1904a8dab8492cbb6d7bfbb47a964f": { + "signature": "0179541aae15474f41e7e747ad56255c8c1904a8dab8492cbb6d7bfbb47a964f", + "alternativeSignatures": [ + "1c395131d32ad61eedb6d27c77f322ba379ca88c4eb78663d5fd2d8ba4400d18" + ], + "target": "Public/Src/Cache/MemoizationStore/VstsApp/ScrapeFingerprints.cs", + "memberOf": [ + "default" + ], + "tool": "roslynanalyzers", + "ruleId": "CA1822", + "justification": null, + "createdDate": "2022-07-23 17:31:56Z", + "expirationDate": null, + "type": null + }, + "5b2440596e68cf2840520b72f9aaaa9eaf603854e02b7b4222f9e5fc3ae96088": { + "signature": "5b2440596e68cf2840520b72f9aaaa9eaf603854e02b7b4222f9e5fc3ae96088", + "alternativeSignatures": [ + "af03388d6916cb51a65726dd2eeb88da177226008d690893ceb9c2a4e143073b" + ], + "target": "Public/Src/App/Bxl/Program.cs", + "memberOf": [ + "default" + ], + "tool": "roslynanalyzers", + "ruleId": "CA5386", + "justification": null, + "createdDate": "2022-07-23 17:43:50Z", + "expirationDate": null, + "type": null + }, + "e1157671337aa870eb78013fcd438e19b7c287120974f603554551be7593222f": { + "signature": "e1157671337aa870eb78013fcd438e19b7c287120974f603554551be7593222f", + "alternativeSignatures": [ + "dd5f9ac9ac571f107671cfe66319fead57857b9aa4fe5cbf58cba1da0eb89157" + ], + "target": "Public/Src/Tools/SymbolDaemon/Program.cs", + "memberOf": [ + "default" + ], + "tool": "roslynanalyzers", + "ruleId": "CA5386", + "justification": null, + "createdDate": "2022-07-23 17:29:46Z", + "expirationDate": null, + "type": null + }, + "4b8d75fe3345a8ff6619ba5695319afcec1bab1937b2f6cda65813a2d5473a99": { + "signature": "4b8d75fe3345a8ff6619ba5695319afcec1bab1937b2f6cda65813a2d5473a99", + "alternativeSignatures": [ + "b998f1b73a08d14c0f01b26c1c2210b16bc03c0ddef2efe8b07ee02386388f6e" + ], + "target": "Public/Src/Tools/DropDaemon/Program.cs", + "memberOf": [ + "default" + ], + "tool": "roslynanalyzers", + "ruleId": "CA5386", + "justification": null, + "createdDate": "2022-07-23 17:39:13Z", + "expirationDate": null, + "type": null } } } \ No newline at end of file diff --git a/.gdn/README.md b/.gdn/README.md new file mode 100644 index 000000000..62fc294e1 --- /dev/null +++ b/.gdn/README.md @@ -0,0 +1 @@ +This empty directory is required for Roslynanalyzers to run on a repo that does not have Guardian initialized. \ No newline at end of file diff --git a/Public/Sdk/Public/Managed/Tools/RoslynAnalyzers/Tool.Guardian.RoslynAnalyzers.dsc b/Public/Sdk/Public/Managed/Tools/RoslynAnalyzers/Tool.Guardian.RoslynAnalyzers.dsc index 3297bf141..70acf2027 100644 --- a/Public/Sdk/Public/Managed/Tools/RoslynAnalyzers/Tool.Guardian.RoslynAnalyzers.dsc +++ b/Public/Sdk/Public/Managed/Tools/RoslynAnalyzers/Tool.Guardian.RoslynAnalyzers.dsc @@ -6,6 +6,10 @@ import * as Guardian from "Sdk.Guardian"; const guardianRoslynAnalyzersConfigFile = Guardian.createConfigurationFile(roslynAnalyzersConfiguration(), p`${Guardian.guardianConfigFileDirectory.path}/roslynAnalyzersConfiguration.gdnconfig`); +const complianceBaselineSuppressionLocation = d`${Context.getMount("SourceRoot").path}/.config/buildxl/compliance`; +const baselines = glob(complianceBaselineSuppressionLocation, "*.gdnbaselines"); +const suppressions = glob(complianceBaselineSuppressionLocation, "*.gdnsuppress"); + /** * Create RoslynAnalyzers Guardian calls with copylogs=true * With RoslynAnalyzers enabled, roslynanalyzers run with Csc.exe and produce outputfiles @@ -34,28 +38,34 @@ export function createRoslynCalls(logRootDirectory: Directory, files: File[], un function addRoslynAnalyzersCalls(guardianToolRoot : StaticDirectory, packageDirectory : StaticDirectory, guardianDrop : Directory, files : File[], logRootDirectory: Directory, uniquePath: RelativePath) : Transformer.ExecuteResult { const roslynAnalyzersWorkDir = Context.getNewOutputDirectory("roslynAnalyzers"); - const environmentVariables : Transformer.EnvironmentVariable[] = [ - {name: "RoslynAnalyzers.LogRootDirectory", value: logRootDirectory} - ]; + const roslynAnalyzersCopyLogDirectory = Context.getNewOutputDirectory("CopyTo"); - return Guardian.createGuardianCall( - guardianToolRoot, - packageDirectory, - guardianDrop, - files, - `roslynanalyzer`, - roslynAnalyzersWorkDir, - r`${uniquePath}/roslynanalyzer.sarif`, - [guardianRoslynAnalyzersConfigFile], - environmentVariables, - /*retryExitCodes*/undefined, - /*processRetries*/undefined, - /*pathDirectories*/undefined, - /*additionalOutputs*/undefined, - /*untrackedPaths*/[d`${guardianToolRoot.path}/.gdn`], - /*untrackedScopes*/undefined, - /*allowUndeclaredSourceReads*/false, - /*passThroughEnvironmentVariables*/undefined); + const environmentVariables : Transformer.EnvironmentVariable[] = [ + {name: "RoslynAnalyzers.LogRootDirectory", value: logRootDirectory}, + {name: "RoslynAnalyzers.OutputDirectory", value: roslynAnalyzersCopyLogDirectory} + ]; + + const guardianArgs : Guardian.GuardianArguments = { + guardianCommand: "Run", + guardianToolRootDirectory: guardianToolRoot, + guardianConfigFiles: [guardianRoslynAnalyzersConfigFile], + guardianResultFile: f`${Context.getMount("LogsDirectory").path}/Guardian/${uniquePath}/roslynanalyzer.sarif`, + guardianPackageDirectory: packageDirectory, + guardianToolWorkingDirectory: roslynAnalyzersWorkDir, // Set this to pick up the newly generated tsv file automatically + dependencies: files, + logLevel: "Warning", // Display only warnings and errors only to simplify debugging and reduce log file size + baselineFiles: baselines.length > 0 ? baselines : undefined, + suppressionFiles: suppressions.length > 0 ? suppressions : undefined, + autoGeneratedBaselineSuppressionLocation: d`${Context.getMount("LogsDirectory").path}/Guardian/${uniquePath}`, + suppressionFileName: a`roslynanalyzers.gdnsuppressions`, + environmentVariables: environmentVariables, + untrackedPaths: [d`${Context.getMount("SourceRoot").path}/.gdn`], + policy: "microsoft", + severity: "Warning", + additionalOutputs: [{directory: roslynAnalyzersCopyLogDirectory, kind: "shared"}] + }; + + return Guardian.runGuardian(guardianArgs); } function roslynAnalyzersConfiguration() : Object { @@ -74,7 +84,8 @@ function roslynAnalyzersConfiguration() : Object { "CSharpCodeStyleAnalyzersRootDirectory": "", "ForceSuccess": false, "TreatWarningsAsErrors": false, - "LogRootDirectory": "$(RoslynAnalyzers.LogRootDirectory)" + "LogRootDirectory": "$(RoslynAnalyzers.LogRootDirectory)", + "OutputDirectory": "$(RoslynAnalyzers.OutputDirectory)" }, "outputExtension": "sarif", "successfulExitCodes": [ diff --git a/Public/Sdk/Public/Tools/Guardian/Tool.Guardian.ComplianceBuild.dsc b/Public/Sdk/Public/Tools/Guardian/Tool.Guardian.ComplianceBuild.dsc index 365c7b082..9bc4b3c7d 100644 --- a/Public/Sdk/Public/Tools/Guardian/Tool.Guardian.ComplianceBuild.dsc +++ b/Public/Sdk/Public/Tools/Guardian/Tool.Guardian.ComplianceBuild.dsc @@ -193,7 +193,7 @@ export function createGuardianCall( untrackedPaths: untrackedPaths, untrackedScopes: untrackedScopes, allowUndeclaredSourceReads: allowUndeclaredSourceReads, - passThroughEnvironmentVariables + passThroughEnvironmentVariables: passThroughEnvironmentVariables }; const guardianResult = runGuardian(guardianArgs); diff --git a/Public/Sdk/Public/Tools/Guardian/Tool.Guardian.dsc b/Public/Sdk/Public/Tools/Guardian/Tool.Guardian.dsc index e684319a5..0605163e7 100644 --- a/Public/Sdk/Public/Tools/Guardian/Tool.Guardian.dsc +++ b/Public/Sdk/Public/Tools/Guardian/Tool.Guardian.dsc @@ -378,6 +378,7 @@ function runGuardianInternal(args : GuardianArguments, guardianTool : Transforme Cmd.flag("no-policy", args.noPolicy), Cmd.option("--policy ", args.policy), Cmd.option("--logger-level ", args.logLevel !== undefined ? args.logLevel.toString() : undefined), + Cmd.option("--min-severity ", args.severity), ...getBaselineOrSuppressOptions(args), ]; diff --git a/Public/Sdk/SelfHost/BuildXL/BuildXL.Recommend.Required.Error.ruleset b/Public/Sdk/SelfHost/BuildXL/BuildXL.Recommend.Required.Error.ruleset new file mode 100644 index 000000000..ffd2b0f05 --- /dev/null +++ b/Public/Sdk/SelfHost/BuildXL/BuildXL.Recommend.Required.Error.ruleset @@ -0,0 +1,405 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Public/Sdk/SelfHost/BuildXL/BuildXLSdk.dsc b/Public/Sdk/SelfHost/BuildXL/BuildXLSdk.dsc index 1acdc861b..0700d248a 100644 --- a/Public/Sdk/SelfHost/BuildXL/BuildXLSdk.dsc +++ b/Public/Sdk/SelfHost/BuildXL/BuildXLSdk.dsc @@ -42,6 +42,8 @@ const brandingDefines = [ { key: "MainExecutableName", value: Branding.mainExecutableName}, ]; +const buildXLRuleset = f`BuildXL.ruleset`; + @@public export interface Arguments extends Managed.Arguments { /** Provide switch to turn skip tool that adds GetTypeInfo() calls to generated resource code, so the tool can be compiled */ @@ -284,7 +286,7 @@ namespace Flags { * We only want to enable it for PR builds not for local dev builds */ @@public - export const enableRoslynAnalyzers = Environment.getFlag("[Sdk.BuildXL]enableRoslynAnalyzers"); + export const enableRoslynAnalyzers = Environment.getFlag("[Sdk.BuildXL]enableRoslynAnalyzers") && isMicrosoftInternal; /** * Enable ESRP Signing @@ -669,8 +671,14 @@ function processArguments(args: Arguments, targetType: Csc.TargetType) : Argumen analyzers = [...analyzers, ...getInProcLogGenerators()]; } + let ruleset : File = undefined; + + if (args.enableStyleCopAnalyzers) { + ruleset = buildXLRuleset; + } + // Only add roslynanalyzers for microsoft internal build since Microsoft.Internal.Analyzers is for internal use - if (Flags.isMicrosoftInternal && Flags.enableRoslynAnalyzers) { + if (Flags.enableRoslynAnalyzers) { analyzers = [ ...analyzers, ...getAnalyzerDlls(importFrom("Microsoft.CodeAnalysis.NetAnalyzers").Contents.all), @@ -680,8 +688,11 @@ function processArguments(args: Arguments, targetType: Csc.TargetType) : Argumen // Required for v2.x Roslyn compilers // Flow analysis is used to infer the nullability of variables within executable code. The inferred nullability of a variable is independent of the variable's declared nullability. // Method calls are analyzed even when they are conditionally omitted. For instance, `Debug.Assert` in release mode. - features.push("flow-analysis"); - } + features = features.push("flow-analysis"); + + ruleset = f`BuildXL.Recommend.Required.Error.ruleset`; + args = args.merge({implicitSources: [buildXLRuleset]}); + } args = Object.merge( { @@ -725,11 +736,11 @@ function processArguments(args: Arguments, targetType: Csc.TargetType) : Argumen // TODO: Make analyzers supported in regular references by undestanding the structure in nuget packages analyzers: analyzers, - errorlog: Flags.isMicrosoftInternal && Flags.enableRoslynAnalyzers ? r`${assemblyName}/roslyn.csproj.diagnostics.sarif` : undefined, - enableRoslynAnalyzers: Flags.isMicrosoftInternal && Flags.enableRoslynAnalyzers, + errorlog: Flags.enableRoslynAnalyzers ? r`${assemblyName}/roslyn.csproj.diagnostics.sarif` : undefined, + enableRoslynAnalyzers: Flags.enableRoslynAnalyzers, features: features, - codeAnalysisRuleset: args.enableStyleCopAnalyzers ? f`BuildXL.ruleset` : undefined, + codeAnalysisRuleset: ruleset, additionalFiles: args.enableStyleCopAnalyzers ? [f`stylecop.json`] : [], keyFile: args.skipAssemblySigning ? undefined : devKey, shared: Flags.useManagedSharedCompilation,