Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,7 @@ dotnet_diagnostic.IDE0290.severity = sugges

# IDE0060: Remove unused parameter
dotnet_diagnostic.IDE0060.severity = warning
dotnet_diagnostic.RCS1163.severity = none
dotnet_code_quality_unused_parameters = all

# [CSharpier] Incompatible rules deactivated
Expand Down
9 changes: 7 additions & 2 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,17 @@
</PropertyGroup>
<ItemGroup>
<GlobalPackageReference Include="CSharpier.MSBuild" Version="1.2.6" />
<GlobalPackageReference Include="Microsoft.CodeAnalysis.BannedApiAnalyzers" Version="3.3.4" />
<GlobalPackageReference Include="Meziantou.Analyzer" Version="3.0.48" />
<GlobalPackageReference Include="Microsoft.CodeAnalysis.BannedApiAnalyzers" Version="4.14.0" />
<GlobalPackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="10.0.201" />
<GlobalPackageReference Include="Microsoft.SourceLink.GitHub" Version="10.0.201" />
<GlobalPackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.14.15" />
<GlobalPackageReference Include="Roslynator.Analyzers" Version="4.15.0" />
<GlobalPackageReference Include="SonarAnalyzer.CSharp" Version="10.23.0.137933" />
<GlobalPackageReference Include="Roslynator.Formatting.Analyzers" Version="4.15.0" />
<GlobalPackageReference Include="Roslynator.CodeAnalysis.Analyzers" Version="4.15.0" />
<GlobalPackageReference Include="Roslynator.CodeFixes" Version="4.15.0" />
<GlobalPackageReference Include="Roslynator.Refactorings" Version="4.15.0" />
<GlobalPackageReference Include="SonarAnalyzer.CSharp" Version="10.22.0.136894" />
</ItemGroup>
<ItemGroup>
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="5.3.0" />
Expand Down
15 changes: 9 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ The `PrivateAssets="all"` attribute ensures that these build utilities are only

## Repository Structure

```
```txt
defaults/
├── src/
│ ├── NetEvolve.Defaults/ # Core build configuration package
Expand All @@ -73,7 +73,7 @@ defaults/

## Included Packages

### NetEvolve.Defaults
### NetEvolve.Defaults (Core Build Configuration)

The foundational package providing standardized build settings:

Expand All @@ -85,23 +85,23 @@ The foundational package providing standardized build settings:

[Learn more about NetEvolve.Defaults →](https://www.nuget.org/packages/NetEvolve.Defaults)

### NetEvolve.Defaults.Analyzer
### NetEvolve.Defaults.Analyzer (NuGet Package Quality Analyzer)

Comprehensive diagnostic analyzer for NuGet package quality:

- **Package Metadata Validation**: Ensures complete and professional package information
- **Repository Configuration**: Validates repository URLs, issue trackers, and licensing
- **Build Standards Enforcement**: Verifies compliance with modern build patterns
- **Real-Time Diagnostics**: Immediate feedback during development with actionable fixes
- **9+ Diagnostic Rules**: Covering critical package configuration aspects
- **10+ Diagnostic Rules**: Covering critical package configuration aspects

[Learn more about NetEvolve.Defaults.Analyzer →](https://www.nuget.org/packages/NetEvolve.Defaults.Analyzer)

## Diagnostic Rules

The analyzer package enforces standardized quality checks via diagnostic rules. For detailed documentation on all rules and remediation steps:

- [NED0001-NED0009 Rules Documentation](https://github.com/dailydevops/defaults/tree/main/docs/usage)
- [NED0001-NED0010 Rules Documentation](https://github.com/dailydevops/defaults/tree/main/docs/usage)
- [Diagnostic Configuration Guide](https://github.com/dailydevops/defaults/tree/main/src/NetEvolve.Defaults.Analyzer#diagnostic-rules)

## Configuration & Customization
Expand All @@ -116,20 +116,23 @@ All settings can be customized through:
### Common Customizations

**Enable Preview Language Features:**

```xml
<PropertyGroup>
<LangVersion>preview</LangVersion>
</PropertyGroup>
```

**Disable Nullable Reference Types (Not Recommended):**

```xml
<PropertyGroup>
<Nullable>disable</Nullable>
</PropertyGroup>
```

**Customize Target Frameworks:**

```xml
<PropertyGroup>
<TargetFrameworks>net8.0;net9.0</TargetFrameworks>
Expand Down Expand Up @@ -184,4 +187,4 @@ For issues, feature requests, or questions:

## License

This project is licensed under the [MIT License](https://github.com/dailydevops/defaults/blob/main/LICENSE).
This project is licensed under the [MIT License](https://github.com/dailydevops/defaults/blob/main/LICENSE).
144 changes: 144 additions & 0 deletions docs/usage/ned0010.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
# NED0010: Missing Recommended Analyzer Package

## Overview

**Severity**: Warning
**Category**: Build Configuration
**Applies To**: All Projects

## Description

The project is missing one or more recommended analyzer packages. NetEvolve.Defaults evaluates a curated list of analyzer packages at build time and emits one `NED0010` warning per missing package. These packages provide static analysis, code quality enforcement, formatting, and security diagnostics that complement the built-in .NET analyzers.

This diagnostic is emitted by the MSBuild target `ValidateRequiredAnalyzerPackages` defined in `SupportMissingAnalyzers.targets`, which runs before the `Build` target. It checks both direct `<PackageReference>` items and `<GlobalPackageReference>` items, so packages referenced at the solution level via `Directory.Packages.props` are also recognized.

## Recommended Packages

The following packages are evaluated:

| Package | Purpose |
| -------------------------------------------- | --------------------------------------------------------- |
| `Meziantou.Analyzer` | Additional code quality and best-practice diagnostics |
| `Microsoft.CodeAnalysis.BannedApiAnalyzers` | Enforces restrictions on banned APIs across the codebase |
| `Microsoft.CodeAnalysis.NetAnalyzers` | Built-in .NET platform analyzers for modern code patterns |
| `Microsoft.VisualStudio.Threading.Analyzers` | Detects threading and async/await anti-patterns |
| `NetEvolve.Defaults` | Standardized build configuration and compiler settings |
| `Roslynator.Analyzers` | Extensive Roslyn-based diagnostic rules |
| `Roslynator.CodeAnalysis.Analyzers` | Roslyn-specific code analysis diagnostics |
| `Roslynator.CodeFixes` | Automated code fixes for Roslynator diagnostics |
| `Roslynator.Formatting.Analyzers` | Code formatting diagnostics via Roslynator |
| `Roslynator.Refactorings` | Roslyn-based refactoring suggestions |
| `SonarAnalyzer.CSharp` | SonarQube static analysis rules for C# |

## Impact

- Reduced static analysis coverage, increasing the risk of undetected code quality issues
- Missing security, threading, or formatting diagnostics that would otherwise surface during development
- Inconsistent analysis across projects in the same solution
- Potential for issues to reach review or production that would have been caught earlier

## Resolution

### Option 1: Add the Missing Package Reference

Install the missing package into your project:

```bash
dotnet add package <PackageName>
```

Or add it manually to your project file (`.csproj`, `.fsproj`, or `.vbproj`):

```xml
<ItemGroup>
<PackageReference Include="Meziantou.Analyzer" PrivateAssets="all" />
<PackageReference Include="Roslynator.Analyzers" PrivateAssets="all" />
</ItemGroup>
```

Use `PrivateAssets="all"` to ensure analyzer packages are not propagated to consumers of your package.

### Option 2: Reference Packages at the Solution Level

To apply recommended packages across all projects in a solution, add them as `<GlobalPackageReference>` items in `Directory.Packages.props` or `Directory.Build.props`:

```xml
<ItemGroup>
<GlobalPackageReference Include="Meziantou.Analyzer" Version="x.x.x" />
<GlobalPackageReference Include="Roslynator.Analyzers" Version="x.x.x" />
</ItemGroup>
```

### Option 3: Suppress the Warning for Specific Packages

If a particular recommended package is intentionally excluded (for example, because an equivalent alternative is already referenced), suppress the warning for that package using the `DisableRecommendedPackage` MSBuild property:

```xml
<PropertyGroup>
<DisableRecommendedPackage>SonarAnalyzer.CSharp</DisableRecommendedPackage>
</PropertyGroup>
```

To suppress multiple packages, separate their names with semicolons:

```xml
<PropertyGroup>
<DisableRecommendedPackage>SonarAnalyzer.CSharp;Microsoft.VisualStudio.Threading.Analyzers</DisableRecommendedPackage>
</PropertyGroup>
```

### Option 4: Suppress the Warning Entirely

To suppress all `NED0010` warnings for a project, add the warning code to `NoWarn`:

```xml
<PropertyGroup>
<NoWarn>$(NoWarn);NED0010</NoWarn>
</PropertyGroup>
```

To suppress it solution-wide, add this to `Directory.Build.props`.

## Best Practices

- Reference analyzer packages with `PrivateAssets="all"` to prevent leaking them into consumers of your package
- Prefer managing recommended analyzer packages in `Directory.Build.props` or `Directory.Packages.props` so all projects in a solution benefit consistently
- Use `DisableRecommendedPackage` instead of `NoWarn` when suppressing for specific packages, as it provides finer-grained control and remains self-documenting
- Avoid suppressing `NED0010` entirely unless all recommended packages are intentionally excluded and alternatives are in place

## Example

A project referencing all recommended packages at the solution level via `Directory.Build.props`:

```xml
<ItemGroup>
<GlobalPackageReference Include="Meziantou.Analyzer" Version="x.x.x" />
<GlobalPackageReference Include="Microsoft.CodeAnalysis.BannedApiAnalyzers" Version="x.x.x" />
<GlobalPackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="x.x.x" />
<GlobalPackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="x.x.x" />
<GlobalPackageReference Include="NetEvolve.Defaults" Version="x.x.x" />
<GlobalPackageReference Include="Roslynator.Analyzers" Version="x.x.x" />
<GlobalPackageReference Include="Roslynator.CodeAnalysis.Analyzers" Version="x.x.x" />
<GlobalPackageReference Include="Roslynator.CodeFixes" Version="x.x.x" />
<GlobalPackageReference Include="Roslynator.Formatting.Analyzers" Version="x.x.x" />
<GlobalPackageReference Include="Roslynator.Refactorings" Version="x.x.x" />
<GlobalPackageReference Include="SonarAnalyzer.CSharp" Version="x.x.x" />
</ItemGroup>
```

A project that intentionally excludes one package and suppresses only that warning:

```xml
<PropertyGroup>
<!-- SonarAnalyzer.CSharp is excluded: Meziantou.Analyzer covers equivalent rules -->
<DisableRecommendedPackage>SonarAnalyzer.CSharp</DisableRecommendedPackage>
</PropertyGroup>
```

## See Also

- [NuGet Package References](https://learn.microsoft.com/en-us/nuget/consume-packages/package-references-in-project-files)
- [GlobalPackageReference in MSBuild](https://learn.microsoft.com/en-us/nuget/consume-packages/central-packages-management)
- [Roslynator Documentation](https://github.com/dotnet/roslynator)
- [Meziantou.Analyzer Documentation](https://github.com/meziantou/Meziantou.Analyzer)
- [SonarAnalyzer for C#](https://github.com/SonarSource/sonar-dotnet)
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Collections.Immutable;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;

Expand Down Expand Up @@ -100,7 +101,10 @@ public override void Initialize(AnalysisContext context)
options,
_ruleNED0009,
"build_property.copyrightyearstart",
propertyValue => int.TryParse(propertyValue, out var year) && year >= 1900 && year <= 9999
propertyValue =>
int.TryParse(propertyValue, NumberStyles.Integer, CultureInfo.InvariantCulture, out var year)
&& year >= 1900
&& year <= 9999
);
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
<IncludeSymbols>false</IncludeSymbols>
<NoWarn>$(NoWarn);RS1036</NoWarn>
<TargetsForTfmSpecificContentInPackage>$(TargetsForTfmSpecificContentInPackage);_AddAnalyzersToOutput</TargetsForTfmSpecificContentInPackage>
<DisableRecommendedPackage>NetEvolve.Defaults</DisableRecommendedPackage>
</PropertyGroup>
<ItemGroup>
<None Include="build\**" Pack="true" PackagePath="build\" />
Expand Down
Loading
Loading