-
Notifications
You must be signed in to change notification settings - Fork 467
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Generate and package ruleset files for each analyzer package. (#1718)
We now generate the following set of ruleset files for each analyzer package: 1. AllRulesEnabled.ruleset 2. AllRulesDefault.ruleset 3. AllRulesDisabled.ruleset For every unique rule category within the pacakge, say security, performance, design, etc., we generate 2 ruleset files per category. For example, for Security, we generate: 1. SecurityRulesEnabled.ruleset (all security rules enabled, including the ones with IsEnabledByDefault = false. All rules from other categories are disabled) 2. SecurityRulesDefault.ruleset (all security rules have default severity and IsEnabledByDefault is honored. All rules from other categories are disabled) For the core FxCopAnalyzers package, we also package all the legacy FxCop rulesets, which have been edited to include AllRulesDisabled.ruleset upfront to match legacy FxCop configuration. Fixes #943
- Loading branch information
Showing
16 changed files
with
710 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
16 changes: 16 additions & 0 deletions
16
eng/GenerateAnalyzerRulesets/GenerateAnalyzerRulesets.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
<PropertyGroup> | ||
<ImportNetSdkFromRepoToolset>false</ImportNetSdkFromRepoToolset> | ||
</PropertyGroup> | ||
|
||
<Import Project="Sdk.props" Sdk="RoslynTools.RepoToolset" /> | ||
|
||
<PropertyGroup> | ||
<OutputType>Exe</OutputType> | ||
<TargetFramework>netcoreapp2.0</TargetFramework> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.CodeAnalysis" Version="$(MicrosoftCodeAnalysisVersion)" /> | ||
</ItemGroup> | ||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,259 @@ | ||
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
using System.Diagnostics; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Reflection; | ||
using System.Text; | ||
using Microsoft.CodeAnalysis; | ||
using Microsoft.CodeAnalysis.Diagnostics; | ||
|
||
namespace GenerateAnalyzerRulesets | ||
{ | ||
class Program | ||
{ | ||
public static void Main(string[] args) | ||
{ | ||
if (args.Length != 4) | ||
{ | ||
throw new ArgumentException($"Excepted 4 arguments, found {args.Length}: {string.Join(';', args)}"); | ||
} | ||
|
||
string analyzerRulesetsDir = args[0]; | ||
string analyzerPackageName = args[1]; | ||
string tfm = args[2]; | ||
var assemblyList = args[3].Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries).ToList(); | ||
|
||
var allRulesByAssembly = new SortedList<string, SortedList<string, DiagnosticDescriptor>>(); | ||
var categories = new HashSet<string>(); | ||
foreach (string assembly in assemblyList) | ||
{ | ||
var assemblyName = Path.GetFileNameWithoutExtension(assembly); | ||
string path = Path.Combine(analyzerRulesetsDir, @"..\..", assemblyName, tfm, assembly); | ||
if (!File.Exists(path)) | ||
{ | ||
throw new ArgumentException($"{path} does not exist", "assemblyList"); | ||
} | ||
|
||
var analyzerFileReference = new AnalyzerFileReference(path, AnalyzerAssemblyLoader.Instance); | ||
var analyzers = analyzerFileReference.GetAnalyzersForAllLanguages(); | ||
var rules = analyzers.SelectMany(a => a.SupportedDiagnostics); | ||
if (rules.Any()) | ||
{ | ||
var rulesById = new SortedList<string, DiagnosticDescriptor>(); | ||
foreach (DiagnosticDescriptor rule in rules) | ||
{ | ||
rulesById[rule.Id] = rule; | ||
categories.Add(rule.Category); | ||
} | ||
|
||
allRulesByAssembly.Add(assemblyName, rulesById); | ||
} | ||
} | ||
|
||
createRuleset( | ||
"AllRulesDefault.ruleset", | ||
"All Rules with default action", | ||
@"All Rules with default action. Rules with IsEnabledByDefault = false are disabled.", | ||
RulesetKind.AllDefault, | ||
categoryOpt: null); | ||
|
||
createRuleset( | ||
"AllRulesEnabled.ruleset", | ||
"All Rules Enabled with default action", | ||
"All Rules are enabled with default action. Rules with IsEnabledByDefault = false are force enabled with default action.", | ||
RulesetKind.AllEnabled, | ||
categoryOpt: null); | ||
|
||
createRuleset( | ||
"AllRulesDisabled.ruleset", | ||
"All Rules Disabled", | ||
@"All Rules are disabled.", | ||
RulesetKind.AllDisabled, | ||
categoryOpt: null); | ||
|
||
foreach (var category in categories) | ||
{ | ||
createRuleset( | ||
$"{category}RulesDefault.ruleset", | ||
$"{category} Rules with default action", | ||
$@"All {category} Rules with default action. Rules with IsEnabledByDefault = false or from a different category are disabled.", | ||
RulesetKind.CategoryDefault, | ||
categoryOpt: category); | ||
|
||
createRuleset( | ||
$"{category}RulesEnabled.ruleset", | ||
$"{category} Rules Enabled with default action", | ||
$@"All {category} Rules are enabled with default action. {category} Rules with IsEnabledByDefault = false are force enabled with default action. Rules from a different category are disabled.", | ||
RulesetKind.CategoryEnabled, | ||
categoryOpt: category); | ||
} | ||
|
||
void createRuleset( | ||
string rulesetFileName, | ||
string rulesetName, | ||
string rulesetDescription, | ||
RulesetKind rulesetKind, | ||
string categoryOpt) | ||
{ | ||
Debug.Assert((categoryOpt != null) == (rulesetKind == RulesetKind.CategoryDefault || rulesetKind == RulesetKind.CategoryEnabled)); | ||
|
||
var result = new StringBuilder(); | ||
startRuleset(); | ||
if (categoryOpt == null) | ||
{ | ||
addRules(categoryPass: false); | ||
} | ||
else | ||
{ | ||
result.AppendLine($@" <!-- {categoryOpt} Rules -->"); | ||
addRules(categoryPass: true); | ||
result.AppendLine(); | ||
result.AppendLine($@" <!-- Other Rules -->"); | ||
addRules(categoryPass: false); | ||
} | ||
|
||
endRuleset(); | ||
var directory = Directory.CreateDirectory(analyzerRulesetsDir); | ||
var rulesetFilePath = Path.Combine(directory.FullName, rulesetFileName); | ||
File.WriteAllText(rulesetFilePath, result.ToString()); | ||
return; | ||
|
||
void startRuleset() | ||
{ | ||
result.AppendLine(@"<?xml version=""1.0""?>"); | ||
result.AppendLine($@"<RuleSet Name=""{rulesetName}"" Description=""{rulesetDescription}"" ToolsVersion=""15.0"">"); | ||
} | ||
|
||
void endRuleset() | ||
{ | ||
result.AppendLine("</RuleSet>"); | ||
} | ||
|
||
void addRules(bool categoryPass) | ||
{ | ||
foreach (var rulesByAssembly in allRulesByAssembly) | ||
{ | ||
string assemblyName = rulesByAssembly.Key; | ||
SortedList<string, DiagnosticDescriptor> sortedRulesById = rulesByAssembly.Value; | ||
|
||
startRules(assemblyName); | ||
|
||
foreach (var rule in sortedRulesById) | ||
{ | ||
addRule(rule.Value); | ||
} | ||
|
||
endRules(); | ||
} | ||
|
||
return; | ||
|
||
void startRules(string assemblyName) | ||
{ | ||
result.AppendLine($@" <Rules AnalyzerId=""{assemblyName}"" RuleNamespace=""{assemblyName}"">"); | ||
} | ||
|
||
void endRules() | ||
{ | ||
result.AppendLine(" </Rules>"); | ||
} | ||
|
||
void addRule(DiagnosticDescriptor rule) | ||
{ | ||
if (shouldSkipRule(rule)) | ||
{ | ||
return; | ||
} | ||
|
||
string ruleAction = getRuleAction(rule); | ||
var spacing = new string(' ', count: 15 - ruleAction.Length); | ||
result.AppendLine($@" <Rule Id=""{rule.Id}"" Action=""{ruleAction}"" /> {spacing} <!-- {rule.Title} -->"); | ||
} | ||
|
||
bool shouldSkipRule(DiagnosticDescriptor rule) | ||
{ | ||
switch (rulesetKind) | ||
{ | ||
case RulesetKind.CategoryDefault: | ||
case RulesetKind.CategoryEnabled: | ||
if (categoryPass) | ||
{ | ||
return rule.Category != categoryOpt; | ||
} | ||
else | ||
{ | ||
return rule.Category == categoryOpt; | ||
} | ||
|
||
default: | ||
return false; | ||
} | ||
} | ||
|
||
string getRuleAction(DiagnosticDescriptor rule) | ||
{ | ||
switch (rulesetKind) | ||
{ | ||
case RulesetKind.CategoryDefault: | ||
return getRuleActionCore(enable: categoryPass && rule.IsEnabledByDefault); | ||
|
||
case RulesetKind.CategoryEnabled: | ||
return getRuleActionCore(enable: categoryPass); | ||
|
||
case RulesetKind.AllDefault: | ||
return getRuleActionCore(enable: rule.IsEnabledByDefault); | ||
|
||
case RulesetKind.AllEnabled: | ||
return getRuleActionCore(enable: true); | ||
|
||
case RulesetKind.AllDisabled: | ||
return getRuleActionCore(enable: false); | ||
|
||
default: | ||
throw new InvalidProgramException(); | ||
} | ||
|
||
string getRuleActionCore(bool enable) | ||
{ | ||
if (enable) | ||
{ | ||
return rule.DefaultSeverity.ToString(); | ||
} | ||
else | ||
{ | ||
return "None"; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
private enum RulesetKind | ||
{ | ||
AllDefault, | ||
CategoryDefault, | ||
AllEnabled, | ||
CategoryEnabled, | ||
AllDisabled, | ||
} | ||
|
||
private sealed class AnalyzerAssemblyLoader : IAnalyzerAssemblyLoader | ||
{ | ||
public static IAnalyzerAssemblyLoader Instance = new AnalyzerAssemblyLoader(); | ||
|
||
private AnalyzerAssemblyLoader() { } | ||
public void AddDependencyLocation(string fullPath) | ||
{ | ||
} | ||
|
||
public Assembly LoadFromPath(string fullPath) | ||
{ | ||
return Assembly.LoadFrom(fullPath); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
@echo off | ||
powershell -ExecutionPolicy ByPass -command "& """%~dp0Build.ps1""" -restore -build -projects """%~dp0..\GenerateAnalyzerRulesets\GenerateAnalyzerRulesets.csproj""" %*" | ||
powershell -ExecutionPolicy ByPass -command "& """%~dp0Build.ps1""" -restore -build -test -sign -pack -ci %*" | ||
exit /b %ErrorLevel% |
4 changes: 4 additions & 0 deletions
4
nuget/Microsoft.CodeAnalysis.FxCopAnalyzers/LegacyRulesets/AllRules.ruleset
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
<?xml version="1.0"?> | ||
<RuleSet Name="Microsoft All Rules" Description="This rule set contains all rules. Running this rule set may result in a large number of warnings being reported. Use this rule set to get a comprehensive picture of all issues in your code. This can help you decide which of the more focused rule sets are most appropriate to run for your projects." ToolsVersion="10.0"> | ||
<Include Path="..\AllRulesEnabled.ruleset" Action="Default" /> | ||
</RuleSet> |
36 changes: 36 additions & 0 deletions
36
nuget/Microsoft.CodeAnalysis.FxCopAnalyzers/LegacyRulesets/BasicCorrectnessRules.ruleset
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
<?xml version="1.0"?> | ||
<RuleSet Name="Microsoft Basic Correctness Rules" Description="These rules focus on logic errors and common mistakes made in the usage of framework APIs. Include this rule set to expand on the list of warnings reported by the minimum recommended rules." ToolsVersion="10.0"> | ||
<Include Path="minimumrecommendedrules.ruleset" Action="Default" /> | ||
<Rules AnalyzerId="Microsoft.Analyzers.ManagedCodeAnalysis" RuleNamespace="Microsoft.Rules.Managed"> | ||
<Rule Id="CA1008" Action="Warning" /> | ||
<Rule Id="CA1013" Action="Warning" /> | ||
<Rule Id="CA1303" Action="Warning" /> | ||
<Rule Id="CA1308" Action="Warning" /> | ||
<Rule Id="CA1806" Action="Warning" /> | ||
<Rule Id="CA1816" Action="Warning" /> | ||
<Rule Id="CA1819" Action="Warning" /> | ||
<Rule Id="CA1820" Action="Warning" /> | ||
<Rule Id="CA1903" Action="Warning" /> | ||
<Rule Id="CA2004" Action="Warning" /> | ||
<Rule Id="CA2006" Action="Warning" /> | ||
<Rule Id="CA2102" Action="Warning" /> | ||
<Rule Id="CA2104" Action="Warning" /> | ||
<Rule Id="CA2105" Action="Warning" /> | ||
<Rule Id="CA2106" Action="Warning" /> | ||
<Rule Id="CA2115" Action="Warning" /> | ||
<Rule Id="CA2119" Action="Warning" /> | ||
<Rule Id="CA2120" Action="Warning" /> | ||
<Rule Id="CA2121" Action="Warning" /> | ||
<Rule Id="CA2130" Action="Warning" /> | ||
<Rule Id="CA2205" Action="Warning" /> | ||
<Rule Id="CA2215" Action="Warning" /> | ||
<Rule Id="CA2221" Action="Warning" /> | ||
<Rule Id="CA2222" Action="Warning" /> | ||
<Rule Id="CA2223" Action="Warning" /> | ||
<Rule Id="CA2224" Action="Warning" /> | ||
<Rule Id="CA2226" Action="Warning" /> | ||
<Rule Id="CA2227" Action="Warning" /> | ||
<Rule Id="CA2231" Action="Warning" /> | ||
<Rule Id="CA2239" Action="Warning" /> | ||
</Rules> | ||
</RuleSet> |
Oops, something went wrong.