Skip to content

Commit a3e3dcd

Browse files
authored
Merge pull request #3974 from mavasani/TurnOffEnableNETAnalyzers
Turn off built-in .NET SDK analyzers if user installs analyzer FxCopAnalyzers or NetAnalyzers NuGet package
2 parents d802917 + 5f20966 commit a3e3dcd

File tree

4 files changed

+80
-33
lines changed

4 files changed

+80
-33
lines changed

eng/GenerateAnalyzerNuspec.targets

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
<_GeneratedGlobalAnalyzerConfigsDir>$(IntermediateOutputPath)GlobalAnalyzerConfigs</_GeneratedGlobalAnalyzerConfigsDir>
3333
<ContainsPortedFxCopRules Condition="'$(ContainsPortedFxCopRules)' == ''">false</ContainsPortedFxCopRules>
3434
<GeneratePackagePropsFile Condition="'$(GeneratePackagePropsFile)' == ''">true</GeneratePackagePropsFile>
35+
<GenerateDisableNETAnalyzersPackagePropsFile Condition=" '$(GenerateDisableNETAnalyzersPackagePropsFile)' == '' and '$(ContainsPortedFxCopRules)' == 'true'">true</GenerateDisableNETAnalyzersPackagePropsFile>
3536
<DevelopmentDependency Condition="'@(AnalyzerNupkgAssembly)' != '' or '@(AnalyzerNupkgDependency)' != ''">true</DevelopmentDependency>
3637
<GenerateAnalyzerMdFile Condition="'$(GenerateAnalyzerMdFile)' == ''">true</GenerateAnalyzerMdFile>
3738
<GenerateAnalyzerSarifFile Condition="'$(GenerateAnalyzerSarifFile)' == ''">true</GenerateAnalyzerSarifFile>
@@ -47,6 +48,13 @@
4748
<AnalyzerNupkgFile Include="$(PackagePropsFileDir)\$(PackagePropsFileName)"/>
4849
</ItemGroup>
4950

51+
<PropertyGroup Condition="'$(GenerateDisableNETAnalyzersPackagePropsFile)' == 'true'">
52+
<DisableNETAnalyzersPackagePropsFileName>DisableNETAnalyzersForNuGetPackage.props</DisableNETAnalyzersPackagePropsFileName>
53+
</PropertyGroup>
54+
<ItemGroup Condition="'$(GenerateDisableNETAnalyzersPackagePropsFile)' == 'true'" >
55+
<AnalyzerNupkgFile Include="$(PackagePropsFileDir)\$(DisableNETAnalyzersPackagePropsFileName)"/>
56+
</ItemGroup>
57+
5058
<PropertyGroup>
5159
<PackageTargetsFileDir>$(IntermediateOutputPath)Build</PackageTargetsFileDir>
5260
<PackageTargetsFileName>$(NuspecPackageId).targets</PackageTargetsFileName>
@@ -75,7 +83,7 @@
7583
<AnalyzerRulesetAssembly Condition="'@(AnalyzerNupkgAssembly)' != '' and '@(AnalyzerRulesetAssembly)' == ''" Include="@(AnalyzerNupkgAssembly)"/>
7684
<AnalyzerRulesetAssembly Update="@(AnalyzerRulesetAssembly)" Condition="'%(AnalyzerRulesetAssembly.TargetFramework)' == ''" TargetFramework="$(TargetFramework)" />
7785
</ItemGroup>
78-
<Exec Command='"$(DotNetRoot)dotnet.exe" "$(_GenerateDocumentationAndConfigFilesPath)" "$(_GeneratedRulesetsDir)" "$(_GeneratedEditorconfigsDir)" "$(ArtifactsBinDir)\" "$(Configuration)" "%(AnalyzerRulesetAssembly.TargetFramework)" "@(AnalyzerRulesetAssembly)" "$(PackagePropsFileDir)" "$(PackagePropsFileName)" "$(AnalyzerSarifFileDir)" "$(AnalyzerDocumentationFileName)" "$(AnalyzerSarifFileDir)" "$(AnalyzerSarifFileName)" "$(VersionPrefix)" $(NuspecPackageId) $(ContainsPortedFxCopRules) $(GenerateAnalyzerRulesMissingDocumentationFile)' />
86+
<Exec Command='"$(DotNetRoot)dotnet.exe" "$(_GenerateDocumentationAndConfigFilesPath)" "$(_GeneratedRulesetsDir)" "$(_GeneratedEditorconfigsDir)" "$(ArtifactsBinDir)\" "$(Configuration)" "%(AnalyzerRulesetAssembly.TargetFramework)" "@(AnalyzerRulesetAssembly)" "$(PackagePropsFileDir)" "$(PackagePropsFileName)" "$(DisableNETAnalyzersPackagePropsFileName)" "$(AnalyzerSarifFileDir)" "$(AnalyzerDocumentationFileName)" "$(AnalyzerSarifFileDir)" "$(AnalyzerSarifFileName)" "$(VersionPrefix)" $(NuspecPackageId) $(ContainsPortedFxCopRules) $(GenerateAnalyzerRulesMissingDocumentationFile)' />
7987

8088
<MSBuild Projects="$(RepoRoot)src\Tools\GenerateGlobalAnalyzerConfigs\GenerateGlobalAnalyzerConfigs.csproj" Targets="Build">
8189
<Output TaskParameter="TargetOutputs" PropertyName="_GenerateGlobalAnalyzerConfigsPath"/>

src/Microsoft.NetCore.Analyzers/RulesMissingDocumentation.md

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,12 @@
22

33
Rule ID | Missing Help Link | Title |
44
--------|-------------------|-------|
5-
CA1830 | https://docs.microsoft.com/visualstudio/code-quality/ca1830 | Prefer strongly-typed Append and Insert method overloads on StringBuilder. |
6-
CA1831 | https://docs.microsoft.com/visualstudio/code-quality/ca1831 | Use AsSpan or AsMemory instead of Range-based indexers when appropriate |
7-
CA1832 | https://docs.microsoft.com/visualstudio/code-quality/ca1832 | Use AsSpan or AsMemory instead of Range-based indexers when appropriate |
8-
CA1833 | https://docs.microsoft.com/visualstudio/code-quality/ca1833 | Use AsSpan or AsMemory instead of Range-based indexers when appropriate |
9-
CA1834 | https://docs.microsoft.com/visualstudio/code-quality/ca1834 | Consider using 'StringBuilder.Append(char)' when applicable. |
10-
CA1835 | https://docs.microsoft.com/visualstudio/code-quality/ca1835 | Prefer the 'Memory'-based overloads for 'ReadAsync' and 'WriteAsync'. |
11-
CA1836 | https://docs.microsoft.com/visualstudio/code-quality/ca1836 | Prefer IsEmpty over Count |
5+
CA1834 | https://docs.microsoft.com/visualstudio/code-quality/ca1834 | Consider using 'StringBuilder.Append(char)' when applicable |
6+
CA1837 | https://docs.microsoft.com/visualstudio/code-quality/ca1837 | Use 'Environment.ProcessId' |
7+
CA1838 | https://docs.microsoft.com/visualstudio/code-quality/ca1838 | Avoid 'StringBuilder' parameters for P/Invokes |
128
CA2008 | https://docs.microsoft.com/visualstudio/code-quality/ca2008 | Do not create tasks without passing a TaskScheduler |
13-
CA2012 | https://docs.microsoft.com/visualstudio/code-quality/ca2012 | Use ValueTasks correctly |
14-
CA2014 | https://docs.microsoft.com/visualstudio/code-quality/ca2014 | Do not use stackalloc in loops. |
15-
CA2247 | https://docs.microsoft.com/visualstudio/code-quality/ca2247 | Argument passed to TaskCompletionSource constructor should be TaskCreationOptions enum instead of TaskContinuationOptions enum. |
169
CA2249 | https://docs.microsoft.com/visualstudio/code-quality/ca2249 | Consider using 'string.Contains' instead of 'string.IndexOf' |
10+
CA2361 | https://docs.microsoft.com/visualstudio/code-quality/ca2361 | Ensure autogenerated class containing DataSet.ReadXml() is not used with untrusted data |
11+
CA2362 | https://docs.microsoft.com/visualstudio/code-quality/ca2362 | Unsafe DataSet or DataTable in autogenerated serializable type can be vulnerable to remote code execution attacks |
12+
IL3000 | https://docs.microsoft.com/visualstudio/code-quality/il3000 | Avoid using accessing Assembly file path when publishing as a single-file |
13+
IL3001 | https://docs.microsoft.com/visualstudio/code-quality/il3001 | Avoid using accessing Assembly file path when publishing as a single-file |

src/NetAnalyzers/RulesMissingDocumentation.md

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,12 @@
22

33
Rule ID | Missing Help Link | Title |
44
--------|-------------------|-------|
5-
CA1830 | https://docs.microsoft.com/visualstudio/code-quality/ca1830 | Prefer strongly-typed Append and Insert method overloads on StringBuilder. |
6-
CA1831 | https://docs.microsoft.com/visualstudio/code-quality/ca1831 | Use AsSpan or AsMemory instead of Range-based indexers when appropriate |
7-
CA1832 | https://docs.microsoft.com/visualstudio/code-quality/ca1832 | Use AsSpan or AsMemory instead of Range-based indexers when appropriate |
8-
CA1833 | https://docs.microsoft.com/visualstudio/code-quality/ca1833 | Use AsSpan or AsMemory instead of Range-based indexers when appropriate |
9-
CA1834 | https://docs.microsoft.com/visualstudio/code-quality/ca1834 | Consider using 'StringBuilder.Append(char)' when applicable. |
10-
CA1835 | https://docs.microsoft.com/visualstudio/code-quality/ca1835 | Prefer the 'Memory'-based overloads for 'ReadAsync' and 'WriteAsync'. |
11-
CA1836 | https://docs.microsoft.com/visualstudio/code-quality/ca1836 | Prefer IsEmpty over Count |
5+
CA1834 | https://docs.microsoft.com/visualstudio/code-quality/ca1834 | Consider using 'StringBuilder.Append(char)' when applicable |
6+
CA1837 | https://docs.microsoft.com/visualstudio/code-quality/ca1837 | Use 'Environment.ProcessId' |
7+
CA1838 | https://docs.microsoft.com/visualstudio/code-quality/ca1838 | Avoid 'StringBuilder' parameters for P/Invokes |
128
CA2008 | https://docs.microsoft.com/visualstudio/code-quality/ca2008 | Do not create tasks without passing a TaskScheduler |
13-
CA2012 | https://docs.microsoft.com/visualstudio/code-quality/ca2012 | Use ValueTasks correctly |
14-
CA2014 | https://docs.microsoft.com/visualstudio/code-quality/ca2014 | Do not use stackalloc in loops. |
15-
CA2247 | https://docs.microsoft.com/visualstudio/code-quality/ca2247 | Argument passed to TaskCompletionSource constructor should be TaskCreationOptions enum instead of TaskContinuationOptions enum. |
169
CA2249 | https://docs.microsoft.com/visualstudio/code-quality/ca2249 | Consider using 'string.Contains' instead of 'string.IndexOf' |
10+
CA2361 | https://docs.microsoft.com/visualstudio/code-quality/ca2361 | Ensure autogenerated class containing DataSet.ReadXml() is not used with untrusted data |
11+
CA2362 | https://docs.microsoft.com/visualstudio/code-quality/ca2362 | Unsafe DataSet or DataTable in autogenerated serializable type can be vulnerable to remote code execution attacks |
12+
IL3000 | https://docs.microsoft.com/visualstudio/code-quality/il3000 | Avoid using accessing Assembly file path when publishing as a single-file |
13+
IL3001 | https://docs.microsoft.com/visualstudio/code-quality/il3001 | Avoid using accessing Assembly file path when publishing as a single-file |

src/Tools/GenerateDocumentationAndConfigFiles/Program.cs

Lines changed: 57 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public static class Program
2020
{
2121
public static int Main(string[] args)
2222
{
23-
const int expectedArguments = 16;
23+
const int expectedArguments = 17;
2424

2525
if (args.Length != expectedArguments)
2626
{
@@ -36,13 +36,14 @@ public static int Main(string[] args)
3636
var assemblyList = args[5].Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries).ToList();
3737
string propsFileDir = args[6];
3838
string propsFileName = args[7];
39-
string analyzerDocumentationFileDir = args[8];
40-
string analyzerDocumentationFileName = args[9];
41-
string analyzerSarifFileDir = args[10];
42-
string analyzerSarifFileName = args[11];
43-
var analyzerVersion = args[12];
44-
var analyzerPackageName = args[13];
45-
if (!bool.TryParse(args[14], out var containsPortedFxCopRules))
39+
string propsFileToDisableNetAnalyzersInNuGetPackageName = args[8];
40+
string analyzerDocumentationFileDir = args[9];
41+
string analyzerDocumentationFileName = args[10];
42+
string analyzerSarifFileDir = args[11];
43+
string analyzerSarifFileName = args[12];
44+
var analyzerVersion = args[13];
45+
var analyzerPackageName = args[14];
46+
if (!bool.TryParse(args[15], out var containsPortedFxCopRules))
4647
{
4748
containsPortedFxCopRules = false;
4849
}
@@ -149,7 +150,7 @@ public static int Main(string[] args)
149150
customTag: customTag);
150151
}
151152

152-
createPropsFile();
153+
createPropsFiles();
153154

154155
createAnalyzerDocumentationFile();
155156

@@ -179,21 +180,65 @@ void createRulesetAndEditorconfig(
179180
return;
180181
}
181182

182-
void createPropsFile()
183+
void createPropsFiles()
183184
{
184185
if (string.IsNullOrEmpty(propsFileDir) || string.IsNullOrEmpty(propsFileName))
185186
{
186187
Debug.Assert(!containsPortedFxCopRules);
188+
Debug.Assert(string.IsNullOrEmpty(propsFileToDisableNetAnalyzersInNuGetPackageName));
187189
return;
188190
}
189191

192+
var disableNetAnalyzersImport = getDisableNetAnalyzersImport();
193+
190194
var fileContents =
191-
$@"<Project DefaultTargets=""Build"" xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
192-
{getCodeAnalysisTreatWarningsNotAsErrors()}
195+
$@"<Project>
196+
{disableNetAnalyzersImport}{getCodeAnalysisTreatWarningsNotAsErrors()}
193197
</Project>";
194198
var directory = Directory.CreateDirectory(propsFileDir);
195199
var fileWithPath = Path.Combine(directory.FullName, propsFileName);
196200
File.WriteAllText(fileWithPath, fileContents);
201+
202+
if (!string.IsNullOrEmpty(disableNetAnalyzersImport))
203+
{
204+
fileWithPath = Path.Combine(directory.FullName, propsFileToDisableNetAnalyzersInNuGetPackageName);
205+
fileContents =
206+
$@"<Project>
207+
<!--
208+
PropertyGroup to disable built-in analyzers from .NET SDK that have the identical CA rules to those implemented in this package.
209+
This props file should only be present in the analyzer NuGet package, it should **not** be inserted into the .NET SDK.
210+
-->
211+
<PropertyGroup>
212+
<EnableNETAnalyzers>false</EnableNETAnalyzers>
213+
</PropertyGroup>
214+
</Project>";
215+
File.WriteAllText(fileWithPath, fileContents);
216+
}
217+
218+
return;
219+
220+
string getDisableNetAnalyzersImport()
221+
{
222+
if (!string.IsNullOrEmpty(propsFileToDisableNetAnalyzersInNuGetPackageName))
223+
{
224+
Debug.Assert(analyzerPackageName == "Microsoft.CodeAnalysis.NetAnalyzers" ||
225+
analyzerPackageName == "Microsoft.CodeAnalysis.FxCopAnalyzers" ||
226+
analyzerPackageName == "Microsoft.NetCore.Analyzers" ||
227+
analyzerPackageName == "Microsoft.NetFramework.Analyzers" ||
228+
analyzerPackageName == "Microsoft.CodeQuality.Analyzers");
229+
230+
return $@"
231+
<!--
232+
This import includes an additional props file that disables built-in analyzers from .NET SDK that have the identical CA rules to those implemented in this package.
233+
This additional props file should only be present in the analyzer NuGet package, it should **not** be inserted into the .NET SDK.
234+
-->
235+
<Import Project=""{propsFileToDisableNetAnalyzersInNuGetPackageName}"" Condition=""Exists('{propsFileToDisableNetAnalyzersInNuGetPackageName}')"" />
236+
";
237+
}
238+
239+
Debug.Assert(!containsPortedFxCopRules);
240+
return string.Empty;
241+
}
197242
}
198243

199244
string getCodeAnalysisTreatWarningsNotAsErrors()

0 commit comments

Comments
 (0)