├── .config
└── dotnet-tools.json
├── .editorconfig
├── .gitattributes
├── .github
├── CODEOWNERS
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ ├── config.yml
│ └── feature_request.md
├── PULL_REQUEST_TEMPLATE.md
└── workflows
│ ├── ci.yml
│ ├── create-stable-release.yml
│ ├── jira.yml
│ ├── publish.yml
│ └── semgrep.yml
├── .gitignore
├── Build.ps1
├── CODEOWNERS
├── CONTRIBUTING.md
├── Directory.Build.props
├── GitVersion.yml
├── LICENSE
├── README.md
├── SECURITY.md
├── Workleap.DotNet.CodingStandards.nuspec
├── global.json
├── renovate.json
├── src
├── build
│ ├── Workleap.DotNet.CodingStandards.props
│ └── Workleap.DotNet.CodingStandards.targets
├── buildMultiTargeting
│ ├── Workleap.DotNet.CodingStandards.props
│ └── Workleap.DotNet.CodingStandards.targets
├── buildTransitive
│ ├── Workleap.DotNet.CodingStandards.props
│ └── Workleap.DotNet.CodingStandards.targets
└── files
│ ├── 1_FileDefaults.editorconfig
│ ├── 2_CodeStyle.editorconfig
│ ├── 3_ReSharperAnalyzers.editorconfig
│ ├── 4_TestProjectsAnalyzers.editorconfig
│ ├── BannedSymbols.txt
│ └── analyzers
│ ├── Analyzer.Meziantou.Analyzer.editorconfig
│ ├── Analyzer.Microsoft.CodeAnalysis.BannedApiAnalyzers.editorconfig
│ ├── Analyzer.Microsoft.CodeAnalysis.CSharp.CodeStyle.editorconfig
│ ├── Analyzer.Microsoft.CodeAnalysis.NetAnalyzers.editorconfig
│ ├── Analyzer.StyleCop.Analyzers.Unstable.editorconfig
│ └── manual_rules.editorconfig
├── tests
└── Workleap.DotNet.CodingStandards.Tests
│ ├── CodingStandardTests.cs
│ ├── Helpers
│ ├── PathHelpers.cs
│ ├── ProjectBuilder.cs
│ ├── SarifFile.cs
│ ├── SarifFileRun.cs
│ ├── SarifFileRunResult.cs
│ ├── SarifFileRunResultMessage.cs
│ ├── SharedHttpClient.cs
│ └── TemporaryDirectory.cs
│ ├── PackageFixture.cs
│ └── Workleap.DotNet.CodingStandards.Tests.csproj
├── tools
└── ConfigurationFilesGenerator
│ ├── ConfigurationFilesGenerator.csproj
│ └── Program.cs
└── wl-dotnet-codingstandards.sln
/.config/dotnet-tools.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 1,
3 | "isRoot": true,
4 | "tools": {
5 | "gitversion.tool": {
6 | "version": "5.12.0",
7 | "commands": [
8 | "dotnet-gitversion"
9 | ]
10 | }
11 | }
12 | }
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | # Default settings
4 | [*]
5 | charset = utf-8
6 | indent_style = space
7 | indent_size = 4
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
11 | # Xml project files
12 | [*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,nativeproj,locproj}]
13 | indent_size = 2
14 | ij_xml_space_inside_empty_tag = true
15 |
16 | # Xml files
17 | [*.{xml,stylecop,resx,ruleset}]
18 | indent_size = 2
19 | ij_xml_space_inside_empty_tag = true
20 |
21 | # Xml config files
22 | [*.{props,targets,config,nuspec,conf}]
23 | indent_size = 2
24 | ij_xml_space_inside_empty_tag = true
25 |
26 | # YAML config files
27 | [*.{yml,yaml}]
28 | indent_size = 2
29 |
30 | # Shell scripts
31 | [*.{sh,ps1}]
32 | end_of_line = lf
33 | indent_size = 2
34 |
35 | [*.{cmd,bat}]
36 | end_of_line = crlf
37 | indent_size = 2
38 |
39 | # JSON
40 | [*.{json,json5,jsonc}]
41 | indent_size = 2
42 |
43 | # CSharp
44 | [*.cs]
45 | max_line_length = off
46 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Copied from the .NET runtime repository
2 | # https://github.com/dotnet/runtime/blob/v8.0.0/.gitattributes
3 |
4 | # Set default behavior to automatically normalize line endings.
5 | * text=auto
6 |
7 | *.doc diff=astextplain
8 | *.DOC diff=astextplain
9 | *.docx diff=astextplain
10 | *.DOCX diff=astextplain
11 | *.dot diff=astextplain
12 | *.DOT diff=astextplain
13 | *.pdf diff=astextplain
14 | *.PDF diff=astextplain
15 | *.rtf diff=astextplain
16 | *.RTF diff=astextplain
17 |
18 | *.jpg binary
19 | *.png binary
20 | *.gif binary
21 |
22 | *.lss text
23 |
24 | # Force bash scripts to always use lf line endings so that if a repo is accessed
25 | # in Unix via a file share from Windows, the scripts will work.
26 | *.in text eol=lf
27 | *.sh text eol=lf
28 |
29 | # Likewise, force cmd and batch scripts to always use crlf
30 | *.cmd text eol=crlf
31 | *.bat text eol=crlf
32 |
33 | *.cs text=auto diff=csharp
34 | *.vb text=auto
35 | *.resx text=auto
36 | *.c text=auto
37 | *.cpp text=auto
38 | *.cxx text=auto
39 | *.h text=auto
40 | *.hxx text=auto
41 | *.py text=auto
42 | *.rb text=auto
43 | *.java text=auto
44 | *.html text=auto
45 | *.htm text=auto
46 | *.css text=auto
47 | *.scss text=auto
48 | *.sass text=auto
49 | *.less text=auto
50 | *.js text=auto
51 | *.lisp text=auto
52 | *.clj text=auto
53 | *.sql text=auto
54 | *.php text=auto
55 | *.lua text=auto
56 | *.m text=auto
57 | *.asm text=auto
58 | *.erl text=auto
59 | *.fs text=auto
60 | *.fsx text=auto
61 | *.hs text=auto
62 |
63 | *.csproj text=auto
64 | *.vbproj text=auto
65 | *.fsproj text=auto
66 | *.dbproj text=auto
67 | *.sln text=auto eol=crlf
68 |
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | * @workleap/internal-developer-platform
2 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. See error
18 |
19 | **Expected behavior**
20 | A clear and concise description of what you expected to happen.
21 |
22 | **Screenshots**
23 | If applicable, add screenshots to help explain your problem.
24 |
25 | **Environment (please complete the following information):**
26 | - OS: [e.g. Windows]
27 | - Version: [e.g. 1.2.3]
28 | - IDE: [e.g. Rider]
29 | - etc.
30 |
31 | **Additional context**
32 | Add any other context about the problem here.
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: false
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## Description of changes
4 |
5 |
6 | ## Breaking changes
7 |
8 |
9 | ## Additional checks
10 |
11 |
12 | - [ ] Updated the documentation of the project to reflect the changes
13 | - [ ] Added new tests that cover the code changes
14 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 |
3 | on:
4 | pull_request:
5 | branches: [main]
6 | paths-ignore: ["*.md"]
7 |
8 | push:
9 | branches:
10 | - "renovate/**"
11 |
12 | # Prevent duplicate runs if Renovate falls back to creating a PR
13 | concurrency:
14 | group: ${{ github.workflow }}-${{ github.head_ref || github.ref_name }}
15 | cancel-in-progress: true
16 |
17 | # We are using OpenID Connect to authenticate with Azure with secret.
18 | # https://docs.github.com/en/actions/security-for-github-actions/security-hardening-your-deployments/configuring-openid-connect-in-azure
19 | permissions:
20 | id-token: write
21 | contents: read
22 |
23 | jobs:
24 | main:
25 | # We need windows to use nuget
26 | runs-on: [self-hosted, idp]
27 | environment: ci
28 | steps:
29 | - uses: actions/checkout@v4
30 | with:
31 | fetch-depth: 0
32 |
33 | - name: Get gsoft-nuget-feed secret
34 | id: get_gsoft_nuget_feed_secret
35 | uses: workleap/wl-reusable-workflows/retrieve-managed-secret@main
36 | with:
37 | azure-client-id: ${{ vars.AZURE_CLIENT_ID }}
38 | azure-tenant-id: ${{ vars.AZURE_TENANT_ID }}
39 | azure-subscription-id: ${{ vars.AZURE_SUBSCRIPTION_ID }}
40 | keyvault-name: ${{ vars.IDP_CICD_KEYVAULT_NAME }}
41 | secret-name: "gsoft-nuget-feed-ado-pat"
42 |
43 | - uses: actions/setup-dotnet@v4
44 | with:
45 | source-url: ${{ vars.GSOFTDEV_NUGET_SOURCE }}
46 | env:
47 | NUGET_AUTH_TOKEN: ${{ steps.get_gsoft_nuget_feed_secret.outputs.secret }}
48 |
49 | - name: Install Mono
50 | shell: bash
51 | run: |
52 | apt-get update
53 | apt-get install -y mono-complete
54 |
55 | - uses: NuGet/setup-nuget@v2
56 |
57 | - run: ./Build.ps1
58 | shell: pwsh
59 | env:
60 | NUGET_SOURCE: ${{ vars.GSOFTDEV_NUGET_SOURCE }}
61 | NUGET_API_KEY: ${{ steps.get_gsoft_nuget_feed_secret.outputs.secret }}
62 |
63 | linearb:
64 | needs: [main]
65 | uses: workleap/wl-reusable-workflows/.github/workflows/linearb-deployment.yml@main
66 | with:
67 | environment: development
68 | permissions:
69 | id-token: write
70 | contents: read
71 |
--------------------------------------------------------------------------------
/.github/workflows/create-stable-release.yml:
--------------------------------------------------------------------------------
1 | name: Create stable release
2 |
3 | on:
4 | schedule:
5 | - cron: "0 3 * * 0" # At 03:00 on Sunday
6 | workflow_dispatch:
7 |
8 | jobs:
9 | create-release:
10 | permissions:
11 | contents: write
12 | id-token: write
13 | uses: workleap/wl-reusable-workflows/.github/workflows/create-stable-release.yml@main
14 |
--------------------------------------------------------------------------------
/.github/workflows/jira.yml:
--------------------------------------------------------------------------------
1 | name: Jira
2 |
3 | on:
4 | pull_request:
5 | branches: [main]
6 | paths-ignore: ["*.md"]
7 |
8 | jobs:
9 | call-workflow-jira:
10 | uses: workleap/wl-reusable-workflows/.github/workflows/reusable-jira-workflow.yml@main
11 | with:
12 | branch_name: ${{ github.head_ref }}
13 | permissions:
14 | contents: read
15 | id-token: write
16 |
--------------------------------------------------------------------------------
/.github/workflows/publish.yml:
--------------------------------------------------------------------------------
1 | name: Publish
2 |
3 | on:
4 | push:
5 | branches: [main]
6 | tags: ["*.*.*"]
7 | paths-ignore: ["*.md"]
8 |
9 | # We are using OpenID Connect to authenticate with Azure with secret.
10 | # https://docs.github.com/en/actions/security-for-github-actions/security-hardening-your-deployments/configuring-openid-connect-in-azure
11 | permissions:
12 | id-token: write
13 | contents: read
14 |
15 | jobs:
16 | main:
17 | # We need windows to use nuget
18 | runs-on: [self-hosted, idp]
19 | environment: ci
20 |
21 | steps:
22 | - uses: actions/checkout@v4
23 | with:
24 | fetch-depth: 0
25 |
26 | - name: Get nuget-org-workleap-api-key
27 | id: get_nuget_org_workleap_api_key_secret
28 | uses: workleap/wl-reusable-workflows/retrieve-managed-secret@main
29 | with:
30 | azure-client-id: ${{ vars.AZURE_CLIENT_ID }}
31 | azure-tenant-id: ${{ vars.AZURE_TENANT_ID }}
32 | azure-subscription-id: ${{ vars.AZURE_SUBSCRIPTION_ID }}
33 | keyvault-name: ${{ vars.IDP_CICD_KEYVAULT_NAME }}
34 | secret-name: "nuget-org-workleap-api-key"
35 |
36 | - uses: actions/setup-dotnet@v4
37 |
38 | - name: Install Mono
39 | shell: bash
40 | run: |
41 | apt-get update
42 | apt-get install -y mono-complete
43 |
44 | - uses: NuGet/setup-nuget@v2
45 |
46 | - run: ./Build.ps1
47 | shell: pwsh
48 | env:
49 | NUGET_SOURCE: ${{ vars.NUGET_SOURCE }}
50 | NUGET_API_KEY: ${{ steps.get_nuget_org_workleap_api_key_secret.outputs.secret }}
51 |
52 | linearb:
53 | needs: [main]
54 | uses: workleap/wl-reusable-workflows/.github/workflows/linearb-deployment.yml@main
55 | with:
56 | environment: 'release'
57 | permissions:
58 | id-token: write
59 | contents: read
60 |
--------------------------------------------------------------------------------
/.github/workflows/semgrep.yml:
--------------------------------------------------------------------------------
1 | name: Semgrep scan
2 |
3 | on:
4 | pull_request:
5 | branches: ["main"]
6 | workflow_dispatch: {}
7 | schedule:
8 | - cron: "52 2 * * 6"
9 |
10 | jobs:
11 | call-workflow-semgrep:
12 | permissions:
13 | contents: read
14 | security-events: write
15 | uses: workleap/wl-reusable-workflows/.github/workflows/reusable-semgrep-workflow.yml@main
16 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 | ##
4 | ## Get latest from `dotnet new gitignore`
5 |
6 | # dotenv files
7 | .env
8 |
9 | # User-specific files
10 | *.rsuser
11 | *.suo
12 | *.user
13 | *.userosscache
14 | *.sln.docstates
15 |
16 | # User-specific files (MonoDevelop/Xamarin Studio)
17 | *.userprefs
18 |
19 | # Mono auto generated files
20 | mono_crash.*
21 |
22 | # Build results
23 | [Dd]ebug/
24 | [Dd]ebugPublic/
25 | [Rr]elease/
26 | [Rr]eleases/
27 | x64/
28 | x86/
29 | [Ww][Ii][Nn]32/
30 | [Aa][Rr][Mm]/
31 | [Aa][Rr][Mm]64/
32 | bld/
33 | [Bb]in/
34 | [Oo]bj/
35 | [Ll]og/
36 | [Ll]ogs/
37 |
38 | # Visual Studio 2015/2017 cache/options directory
39 | .vs/
40 | # Uncomment if you have tasks that create the project's static files in wwwroot
41 | #wwwroot/
42 |
43 | # Visual Studio 2017 auto generated files
44 | Generated\ Files/
45 |
46 | # MSTest test Results
47 | [Tt]est[Rr]esult*/
48 | [Bb]uild[Ll]og.*
49 |
50 | # NUnit
51 | *.VisualState.xml
52 | TestResult.xml
53 | nunit-*.xml
54 |
55 | # Build Results of an ATL Project
56 | [Dd]ebugPS/
57 | [Rr]eleasePS/
58 | dlldata.c
59 |
60 | # Benchmark Results
61 | BenchmarkDotNet.Artifacts/
62 |
63 | # .NET
64 | project.lock.json
65 | project.fragment.lock.json
66 | artifacts/
67 |
68 | # Tye
69 | .tye/
70 |
71 | # ASP.NET Scaffolding
72 | ScaffoldingReadMe.txt
73 |
74 | # StyleCop
75 | StyleCopReport.xml
76 |
77 | # Files built by Visual Studio
78 | *_i.c
79 | *_p.c
80 | *_h.h
81 | *.ilk
82 | *.meta
83 | *.obj
84 | *.iobj
85 | *.pch
86 | *.pdb
87 | *.ipdb
88 | *.pgc
89 | *.pgd
90 | *.rsp
91 | *.sbr
92 | *.tlb
93 | *.tli
94 | *.tlh
95 | *.tmp
96 | *.tmp_proj
97 | *_wpftmp.csproj
98 | *.log
99 | *.tlog
100 | *.vspscc
101 | *.vssscc
102 | .builds
103 | *.pidb
104 | *.svclog
105 | *.scc
106 |
107 | # Chutzpah Test files
108 | _Chutzpah*
109 |
110 | # Visual C++ cache files
111 | ipch/
112 | *.aps
113 | *.ncb
114 | *.opendb
115 | *.opensdf
116 | *.sdf
117 | *.cachefile
118 | *.VC.db
119 | *.VC.VC.opendb
120 |
121 | # Visual Studio profiler
122 | *.psess
123 | *.vsp
124 | *.vspx
125 | *.sap
126 |
127 | # Visual Studio Trace Files
128 | *.e2e
129 |
130 | # TFS 2012 Local Workspace
131 | $tf/
132 |
133 | # Guidance Automation Toolkit
134 | *.gpState
135 |
136 | # ReSharper is a .NET coding add-in
137 | _ReSharper*/
138 | *.[Rr]e[Ss]harper
139 | *.DotSettings.user
140 |
141 | # TeamCity is a build add-in
142 | _TeamCity*
143 |
144 | # DotCover is a Code Coverage Tool
145 | *.dotCover
146 |
147 | # AxoCover is a Code Coverage Tool
148 | .axoCover/*
149 | !.axoCover/settings.json
150 |
151 | # Coverlet is a free, cross platform Code Coverage Tool
152 | coverage*.json
153 | coverage*.xml
154 | coverage*.info
155 |
156 | # Visual Studio code coverage results
157 | *.coverage
158 | *.coveragexml
159 |
160 | # NCrunch
161 | _NCrunch_*
162 | .*crunch*.local.xml
163 | nCrunchTemp_*
164 |
165 | # MightyMoose
166 | *.mm.*
167 | AutoTest.Net/
168 |
169 | # Web workbench (sass)
170 | .sass-cache/
171 |
172 | # Installshield output folder
173 | [Ee]xpress/
174 |
175 | # DocProject is a documentation generator add-in
176 | DocProject/buildhelp/
177 | DocProject/Help/*.HxT
178 | DocProject/Help/*.HxC
179 | DocProject/Help/*.hhc
180 | DocProject/Help/*.hhk
181 | DocProject/Help/*.hhp
182 | DocProject/Help/Html2
183 | DocProject/Help/html
184 |
185 | # Click-Once directory
186 | publish/
187 |
188 | # Publish Web Output
189 | *.[Pp]ublish.xml
190 | *.azurePubxml
191 | # Note: Comment the next line if you want to checkin your web deploy settings,
192 | # but database connection strings (with potential passwords) will be unencrypted
193 | *.pubxml
194 | *.publishproj
195 |
196 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
197 | # checkin your Azure Web App publish settings, but sensitive information contained
198 | # in these scripts will be unencrypted
199 | PublishScripts/
200 |
201 | # NuGet Packages
202 | *.nupkg
203 | # NuGet Symbol Packages
204 | *.snupkg
205 | # The packages folder can be ignored because of Package Restore
206 | **/[Pp]ackages/*
207 | # except build/, which is used as an MSBuild target.
208 | !**/[Pp]ackages/build/
209 | # Uncomment if necessary however generally it will be regenerated when needed
210 | #!**/[Pp]ackages/repositories.config
211 | # NuGet v3's project.json files produces more ignorable files
212 | *.nuget.props
213 | *.nuget.targets
214 |
215 | # Microsoft Azure Build Output
216 | csx/
217 | *.build.csdef
218 |
219 | # Microsoft Azure Emulator
220 | ecf/
221 | rcf/
222 |
223 | # Windows Store app package directories and files
224 | AppPackages/
225 | BundleArtifacts/
226 | Package.StoreAssociation.xml
227 | _pkginfo.txt
228 | *.appx
229 | *.appxbundle
230 | *.appxupload
231 |
232 | # Visual Studio cache files
233 | # files ending in .cache can be ignored
234 | *.[Cc]ache
235 | # but keep track of directories ending in .cache
236 | !?*.[Cc]ache/
237 |
238 | # Others
239 | ClientBin/
240 | ~$*
241 | *~
242 | *.dbmdl
243 | *.dbproj.schemaview
244 | *.jfm
245 | *.pfx
246 | *.publishsettings
247 | orleans.codegen.cs
248 |
249 | # Including strong name files can present a security risk
250 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
251 | #*.snk
252 |
253 | # Since there are multiple workflows, uncomment next line to ignore bower_components
254 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
255 | #bower_components/
256 |
257 | # RIA/Silverlight projects
258 | Generated_Code/
259 |
260 | # Backup & report files from converting an old project file
261 | # to a newer Visual Studio version. Backup files are not needed,
262 | # because we have git ;-)
263 | _UpgradeReport_Files/
264 | Backup*/
265 | UpgradeLog*.XML
266 | UpgradeLog*.htm
267 | ServiceFabricBackup/
268 | *.rptproj.bak
269 |
270 | # SQL Server files
271 | *.mdf
272 | *.ldf
273 | *.ndf
274 |
275 | # Business Intelligence projects
276 | *.rdl.data
277 | *.bim.layout
278 | *.bim_*.settings
279 | *.rptproj.rsuser
280 | *- [Bb]ackup.rdl
281 | *- [Bb]ackup ([0-9]).rdl
282 | *- [Bb]ackup ([0-9][0-9]).rdl
283 |
284 | # Microsoft Fakes
285 | FakesAssemblies/
286 |
287 | # GhostDoc plugin setting file
288 | *.GhostDoc.xml
289 |
290 | # Node.js Tools for Visual Studio
291 | .ntvs_analysis.dat
292 | node_modules/
293 |
294 | # Visual Studio 6 build log
295 | *.plg
296 |
297 | # Visual Studio 6 workspace options file
298 | *.opt
299 |
300 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
301 | *.vbw
302 |
303 | # Visual Studio 6 auto-generated project file (contains which files were open etc.)
304 | *.vbp
305 |
306 | # Visual Studio 6 workspace and project file (working project files containing files to include in project)
307 | *.dsw
308 | *.dsp
309 |
310 | # Visual Studio 6 technical files
311 | *.ncb
312 | *.aps
313 |
314 | # Visual Studio LightSwitch build output
315 | **/*.HTMLClient/GeneratedArtifacts
316 | **/*.DesktopClient/GeneratedArtifacts
317 | **/*.DesktopClient/ModelManifest.xml
318 | **/*.Server/GeneratedArtifacts
319 | **/*.Server/ModelManifest.xml
320 | _Pvt_Extensions
321 |
322 | # Paket dependency manager
323 | .paket/paket.exe
324 | paket-files/
325 |
326 | # FAKE - F# Make
327 | .fake/
328 |
329 | # CodeRush personal settings
330 | .cr/personal
331 |
332 | # Python Tools for Visual Studio (PTVS)
333 | __pycache__/
334 | *.pyc
335 |
336 | # Cake - Uncomment if you are using it
337 | # tools/**
338 | # !tools/packages.config
339 |
340 | # Tabs Studio
341 | *.tss
342 |
343 | # Telerik's JustMock configuration file
344 | *.jmconfig
345 |
346 | # BizTalk build output
347 | *.btp.cs
348 | *.btm.cs
349 | *.odx.cs
350 | *.xsd.cs
351 |
352 | # OpenCover UI analysis results
353 | OpenCover/
354 |
355 | # Azure Stream Analytics local run output
356 | ASALocalRun/
357 |
358 | # MSBuild Binary and Structured Log
359 | *.binlog
360 |
361 | # NVidia Nsight GPU debugger configuration file
362 | *.nvuser
363 |
364 | # MFractors (Xamarin productivity tool) working folder
365 | .mfractor/
366 |
367 | # Local History for Visual Studio
368 | .localhistory/
369 |
370 | # Visual Studio History (VSHistory) files
371 | .vshistory/
372 |
373 | # BeatPulse healthcheck temp database
374 | healthchecksdb
375 |
376 | # Backup folder for Package Reference Convert tool in Visual Studio 2017
377 | MigrationBackup/
378 |
379 | # Ionide (cross platform F# VS Code tools) working folder
380 | .ionide/
381 |
382 | # Fody - auto-generated XML schema
383 | FodyWeavers.xsd
384 |
385 | # VS Code files for those working on multiple tools
386 | .vscode/*
387 | !.vscode/settings.json
388 | !.vscode/tasks.json
389 | !.vscode/launch.json
390 | !.vscode/extensions.json
391 | *.code-workspace
392 |
393 | # Local History for Visual Studio Code
394 | .history/
395 |
396 | # Windows Installer files from build outputs
397 | *.cab
398 | *.msi
399 | *.msix
400 | *.msm
401 | *.msp
402 |
403 | # JetBrains Rider
404 | *.sln.iml
405 | .idea
406 |
407 | ##
408 | ## Visual studio for Mac
409 | ##
410 |
411 |
412 | # globs
413 | Makefile.in
414 | *.userprefs
415 | *.usertasks
416 | config.make
417 | config.status
418 | aclocal.m4
419 | install-sh
420 | autom4te.cache/
421 | *.tar.gz
422 | tarballs/
423 | test-results/
424 |
425 | # Mac bundle stuff
426 | *.dmg
427 | *.app
428 |
429 | # content below from: https://github.com/github/gitignore/blob/master/Global/macOS.gitignore
430 | # General
431 | .DS_Store
432 | .AppleDouble
433 | .LSOverride
434 |
435 | # Icon must end with two \r
436 | Icon
437 |
438 |
439 | # Thumbnails
440 | ._*
441 |
442 | # Files that might appear in the root of a volume
443 | .DocumentRevisions-V100
444 | .fseventsd
445 | .Spotlight-V100
446 | .TemporaryItems
447 | .Trashes
448 | .VolumeIcon.icns
449 | .com.apple.timemachine.donotpresent
450 |
451 | # Directories potentially created on remote AFP share
452 | .AppleDB
453 | .AppleDesktop
454 | Network Trash Folder
455 | Temporary Items
456 | .apdisk
457 |
458 | # content below from: https://github.com/github/gitignore/blob/master/Global/Windows.gitignore
459 | # Windows thumbnail cache files
460 | Thumbs.db
461 | ehthumbs.db
462 | ehthumbs_vista.db
463 |
464 | # Dump file
465 | *.stackdump
466 |
467 | # Folder config file
468 | [Dd]esktop.ini
469 |
470 | # Recycle Bin used on file shares
471 | $RECYCLE.BIN/
472 |
473 | # Windows Installer files
474 | *.cab
475 | *.msi
476 | *.msix
477 | *.msm
478 | *.msp
479 |
480 | # Windows shortcuts
481 | *.lnk
482 |
483 | # Vim temporary swap files
484 | *.swp
485 |
486 | # Build output
487 | .output/
488 |
--------------------------------------------------------------------------------
/Build.ps1:
--------------------------------------------------------------------------------
1 | #Requires -Version 5.0
2 |
3 | Begin {
4 | $ErrorActionPreference = "stop"
5 | }
6 |
7 | Process {
8 | function Exec([scriptblock]$Command) {
9 | & $Command
10 | if ($LASTEXITCODE -ne 0) {
11 | throw ("An error occurred while executing command: {0}" -f $Command)
12 | }
13 | }
14 |
15 | $workingDir = $PSScriptRoot
16 | $outputDir = Join-Path $PSScriptRoot ".output"
17 | $nupkgsPath = Join-Path $outputDir "*.nupkg"
18 |
19 | try {
20 | Push-Location $workingDir
21 | Remove-Item $outputDir -Force -Recurse -ErrorAction SilentlyContinue
22 |
23 | # Install GitVersion which is specified in the .config/dotnet-tools.json
24 | # https://learn.microsoft.com/en-us/dotnet/core/tools/local-tools-how-to-use
25 | Exec { & dotnet tool restore }
26 |
27 | # Let GitVersion compute the NuGet package version
28 | $version = Exec { & dotnet dotnet-gitversion /output json /showvariable SemVer }
29 |
30 | # Generate .editorconfig files for analyzers
31 | Exec { & dotnet run --project=tools/ConfigurationFilesGenerator/ConfigurationFilesGenerator.csproj --configuration Release }
32 |
33 | # Pack using NuGet.exe
34 | Exec { & nuget pack Workleap.DotNet.CodingStandards.nuspec -OutputDirectory $outputDir -Version $version -ForceEnglishOutput }
35 |
36 | # Run tests
37 | Exec { & dotnet test --configuration Release --logger "console;verbosity=detailed" }
38 |
39 | # Push to a NuGet feed if the environment variables are set
40 | if (($null -ne $env:NUGET_SOURCE) -and ($null -ne $env:NUGET_API_KEY)) {
41 | Exec { & dotnet nuget push "$nupkgsPath" -s $env:NUGET_SOURCE -k $env:NUGET_API_KEY --skip-duplicate }
42 | }
43 | }
44 | finally {
45 | Pop-Location
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/CODEOWNERS:
--------------------------------------------------------------------------------
1 | * @workleap/internal-developer-platform
2 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | We do not accept external pull requests yet.
--------------------------------------------------------------------------------
/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 | enable
4 | enable
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/GitVersion.yml:
--------------------------------------------------------------------------------
1 | assembly-versioning-scheme: MajorMinorPatch
2 | assembly-file-versioning-scheme: MajorMinorPatch
3 | assembly-informational-format: "{NugetVersion}"
4 | mode: ContinuousDelivery
5 | increment: Inherit
6 | continuous-delivery-fallback-tag: ci
7 | tag-prefix: "[vV]"
8 | major-version-bump-message: '\+semver:\s?(breaking|major)'
9 | minor-version-bump-message: '\+semver:\s?(feature|minor)'
10 | patch-version-bump-message: '\+semver:\s?(fix|patch)'
11 | no-bump-message: '\+semver:\s?(none|skip)'
12 | legacy-semver-padding: 4
13 | build-metadata-padding: 4
14 | commits-since-version-source-padding: 4
15 | tag-pre-release-weight: 60000
16 | commit-message-incrementing: Enabled
17 | update-build-number: true
18 |
19 | branches:
20 | main:
21 | regex: ^(master|main)$
22 | mode: ContinuousDeployment
23 | tag: preview
24 | increment: Patch
25 | prevent-increment-of-merged-branch-version: true
26 | track-merge-target: false
27 | source-branches: ["develop", "release"]
28 | tracks-release-branches: false
29 | is-release-branch: false
30 | is-mainline: true
31 | pre-release-weight: 55000
32 | develop:
33 | regex: ^dev(elop)?(ment)?$
34 | mode: ContinuousDeployment
35 | tag: alpha
36 | increment: Minor
37 | prevent-increment-of-merged-branch-version: false
38 | track-merge-target: true
39 | source-branches: []
40 | tracks-release-branches: true
41 | is-release-branch: false
42 | is-mainline: false
43 | pre-release-weight: 0
44 | release:
45 | regex: ^releases?[/-]
46 | mode: ContinuousDelivery
47 | tag: beta
48 | increment: None
49 | prevent-increment-of-merged-branch-version: true
50 | track-merge-target: false
51 | source-branches: ["develop", "main", "support", "release"]
52 | tracks-release-branches: false
53 | is-release-branch: true
54 | is-mainline: false
55 | pre-release-weight: 30000
56 | feature:
57 | regex: ^features?[/-]
58 | mode: ContinuousDelivery
59 | tag: useBranchName
60 | increment: Inherit
61 | prevent-increment-of-merged-branch-version: false
62 | track-merge-target: false
63 | source-branches:
64 | ["develop", "main", "release", "feature", "support", "hotfix"]
65 | tracks-release-branches: false
66 | is-release-branch: false
67 | is-mainline: false
68 | pre-release-weight: 30000
69 | pull-request:
70 | regex: ^(pull|pull\-requests|pr)[/-]
71 | mode: ContinuousDelivery
72 | tag: PullRequest
73 | increment: Inherit
74 | prevent-increment-of-merged-branch-version: false
75 | tag-number-pattern: '[/-](?\d+)[-/]'
76 | track-merge-target: false
77 | source-branches:
78 | ["develop", "main", "release", "feature", "support", "hotfix"]
79 | tracks-release-branches: false
80 | is-release-branch: false
81 | is-mainline: false
82 | pre-release-weight: 30000
83 | hotfix:
84 | regex: ^hotfix(es)?[/-]
85 | mode: ContinuousDelivery
86 | tag: beta
87 | increment: Patch
88 | prevent-increment-of-merged-branch-version: false
89 | track-merge-target: false
90 | source-branches: ["develop", "main", "support"]
91 | tracks-release-branches: false
92 | is-release-branch: false
93 | is-mainline: false
94 | pre-release-weight: 30000
95 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Workleap.DotNet.CodingStandards
2 |
3 | [](https://www.nuget.org/packages/Workleap.DotNet.CodingStandards/)
4 | [](https://github.com/workleap/wl-dotnet-codingstandards/actions/workflows/publish.yml)
5 |
6 | This package provides a set of **programming standards for .NET projects**, including rules for **style**, **quality**, **security**, and **performance**. It relies on [built-in .NET analyzers](https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/overview) that are shipped with the .NET SDK.
7 |
8 | During development, the package will provide warnings :warning: when standards are not met. For a production build (`Release` configuration), these warnings will be treated as errors :x: and will make the build fail.
9 |
10 | > [!WARNING]
11 | > This package only works with [SDK-style projects](https://learn.microsoft.com/en-us/dotnet/core/project-sdk/overview). Older ASP.NET projects (non-Core) are not supported. The same applies to older desktop applications unless they have migrated to the new `Microsoft.NET.Sdk.WindowsDesktop` SDK.
12 |
13 | ## Usage
14 |
15 | Install the NuGet package in your project:
16 |
17 | ```
18 | dotnet add package Workleap.DotNet.CodingStandards
19 | ```
20 |
21 | If you are using [StyleCop.Analyzers](https://www.nuget.org/packages/StyleCop.Analyzers), you can safely remove it from your project. You can also remove the relevant parts of your `.editorconfig` files which contain analysis rules configuration.
22 |
23 | If you also have a `Directory.Build.props` file in your solution, you can remove properties that are [already set by this package](src/buildTransitive/Workleap.DotNet.CodingStandards.props).
24 |
25 | ## What's included
26 |
27 | - Code style and formatting options, including indentation, line wrapping, encoding, new lines preferences, and more.
28 | - .NET and C# coding conventions, including naming, preferences for types, modifiers, code blocks, expressions, pattern matching, using directives, parentheses, and much more.
29 | - Project properties, including deterministic build, strict mode, continuous integration build detection, [faster package restoration](https://learn.microsoft.com/en-us/nuget/reference/msbuild-targets#restoring-with-msbuild-static-graph-evaluation), and [faster builds on Visual Studio](https://devblogs.microsoft.com/visualstudio/vs-toolbox-accelerate-your-builds-of-sdk-style-net-projects/), and more.
30 | - .NET analysis rules configuration, including style rules (`IDExxxx`) and code analysis rules (`CAxxxx`). These rules have been manually configured to provide a good balance between quality, performance, security, and build time.
31 | - Banned APIs, such as `DateTime.Now` and `DateTimeOffset.Now` (use their UTC counterparts instead).
32 |
33 | ## What's NOT included
34 |
35 | - Enabling a specific or latest C# language version.
36 | - Enabling nullable reference types by default.
37 | - Enabling implicit using directives by default.
38 | - Enforcing a specific target framework.
39 | - Code styles for files that are not C# source files (e.g. `.csproj`, `.json`, etc.).
40 |
41 | We believe that most of these settings should be set on a per-project basis, and decided by the project's maintainers.
42 |
43 | For files other than C# source files, it is technically impossible for this package to enforce code styles, so you will have to configure their style using your own `.editorconfig` files.
44 |
45 | ## How it works
46 |
47 | This package comes with a set of `.props` and `.targets` files that are automatically imported into your project when you install the package. These files contain MSBuild properties and targets that configure the build process and the code analysis rules.
48 |
49 | It also includes multiple `.editorconfig` files that are automatically imported by Roslyn during the build process.
50 |
51 | ## Facilitating package adoption
52 |
53 | From experience, installing the package will result in numerous warnings, the majority of which are related to code formatting. We recommend addressing these in several steps to minimize the impact on code review, using the [dotnet format](https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-format) utility, which is included in the .NET SDK.
54 |
55 | Firstly, warnings related to code formatting **can be automatically corrected**. This includes: indentation, unnecessary spaces, empty lines, braces, file-scoped namespaces, unnecessary using directives, etc. Here is the command to execute:
56 |
57 | ```
58 | dotnet format --diagnostics IDE0001 IDE0004 IDE0005 IDE0007 IDE0009 IDE0011 IDE0055 IDE0161 IDE2000 IDE2001 IDE2002 IDE2003 IDE2004 IDE2005 IDE2006 --verbosity diagnostic
59 | ```
60 |
61 | Once the pull request is merged, one can then attempt to automatically correct the remaining warnings. Without the noise of formatting warnings, it will be easier to focus on them:
62 |
63 | ```
64 | dotnet format --severity warn --verbosity diagnostic
65 | ```
66 |
67 | You can also modify the command to specify the IDs of the analysis rules you wish to automatically correct (if a fix is available). In this way, you avoid manual work, and breaking the correction into several pull requests will increase developers' confidence in the process of adopting new standards.
68 |
69 | All rules included in this package **can be disabled or modified** in an `.editorconfig` file that you can add to your project. You can also **disable a rule for a specific line or block of code** using `#pragma` directives or `[SuppressMessage]` attributes. Learn more about [configuring code analysis rules](https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/suppress-warnings). Remember to always justify why a rule is disabled or modified. Here're some examples:
70 |
71 | - Disable specific diagnostics in the code
72 |
73 | ````c#
74 | #pragma warning disable CA2200 // Rethrow to preserve stack details
75 | throw e;
76 | #pragma warning restore CA2200
77 | ````
78 |
79 | - Disable specific diagnostics for a method
80 |
81 | ````c#
82 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2200:Rethrow to preserve stack details", Justification = "Not production code.")]
83 | void Sample()
84 | {
85 | }
86 | ````
87 |
88 | - Disable a rule using an .editorconfig
89 |
90 | ````editorconfig
91 | # Disable CA2200 globally
92 | [*.cs]
93 | dotnet_diagnostic.CA2200.severity = none
94 |
95 | # Disable CA2200 for specific files
96 | [tests/**/*.cs]
97 | dotnet_diagnostic.CA2200.severity = none
98 | ````
99 |
100 | - Disable [NuGet auditing](https://learn.microsoft.com/en-us/nuget/concepts/auditing-packages?WT.mc_id=DT-MVP-5003978) for a specific package
101 |
102 | ````xml
103 |
104 | ````
105 |
106 | > [!WARNING]
107 | > Remember that this should be a temporary solution to help adopting the package
108 |
109 | Finally, the warnings breaks the CI because they are treated as errors when building the `Release` configuration. You can disable this behavior by setting the following MSBuild property in the `.csproj` file or in the `Directory.Build.props` file
110 |
111 | ````xml
112 |
113 |
114 | false
115 | false
116 |
117 |
118 | ````
119 |
120 | ## References
121 |
122 | - [Configuration files for code analysis rules: Global analyzer options](https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/configuration-files#global-analyzerconfig) (Microsoft documentation).
123 | - [Sharing coding style and Roslyn analyzers across projects](https://www.meziantou.net/sharing-coding-style-and-roslyn-analyzers-across-projects.htm) (blog post written by [Gérald Barré](https://github.com/meziantou)).
124 | - [Microsoft.CodeAnalysis.NetAnalyzers package content](https://nuget.info/packages/Microsoft.CodeAnalysis.NetAnalyzers/8.0.0) (NuGet.info).
125 |
126 | ## Build and release process
127 |
128 | This project uses [GitVersion](https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/overview) as a .NET tool during the build process to automatically compute the version number for preview packages that are automatically published on the main branch and pull requests.
129 |
130 | To publish a new public (non-preview) version, simply create a new release on GitHub with a `x.y.z` tag.
131 |
132 | ## License
133 |
134 | Copyright © 2024, Workleap. This code is licensed under the Apache License, Version 2.0. You may obtain a copy of this license at https://github.com/workleap/gsoft-license/blob/master/LICENSE.
135 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Security Policy
2 |
3 | If you'd like to report a vulnerability, please open a GitHub issue.
4 |
--------------------------------------------------------------------------------
/Workleap.DotNet.CodingStandards.nuspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Workleap.DotNet.CodingStandards
5 | $version$
6 | Workleap
7 | Workleap
8 | true
9 | Apache-2.0
10 | README.md
11 | https://github.com/workleap/wl-dotnet-codingstandards
12 | Workleap recommended coding standards for .NET.
13 | Copyright © Workleap
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/global.json:
--------------------------------------------------------------------------------
1 | {
2 | "sdk": {
3 | "version": "9.0.300",
4 | "rollForward": "latestMinor",
5 | "allowPrerelease": false
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3 | "extends": [
4 | "github>workleap/renovate-config",
5 | "github>workleap/renovate-config:all-automerge.json"
6 | ]
7 | }
--------------------------------------------------------------------------------
/src/build/Workleap.DotNet.CodingStandards.props:
--------------------------------------------------------------------------------
1 |
2 |
3 | true
4 | strict
5 | true
6 | true
7 | latest-all
8 | true
9 |
10 | true
11 | embedded
12 |
13 |
14 | <_SkipUpgradeNetAnalyzersNuGetWarning>true
15 |
16 |
17 | true
18 |
19 |
20 | true
21 | true
22 | true
23 | true
24 | true
25 |
26 |
27 | true
28 | true
29 |
30 |
31 | true
32 |
33 |
34 | true
35 |
36 |
37 |
38 |
39 |
40 | true
41 |
42 |
43 | all
44 |
45 |
46 | low
47 |
48 | true
49 |
50 |
51 |
52 | (WarningsAsErrors);NU1900;NU1901;NU1902;NU1903;NU1904
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/src/build/Workleap.DotNet.CodingStandards.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | true
24 |
25 |
26 |
27 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/src/buildMultiTargeting/Workleap.DotNet.CodingStandards.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/src/buildMultiTargeting/Workleap.DotNet.CodingStandards.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/src/buildTransitive/Workleap.DotNet.CodingStandards.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/src/buildTransitive/Workleap.DotNet.CodingStandards.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/src/files/1_FileDefaults.editorconfig:
--------------------------------------------------------------------------------
1 | is_global = true
2 | global_level = -1
3 |
4 | # Default settings for C# and Visual Basic
5 | charset = utf-8
6 | indent_style = space
7 | indent_size = 4
8 | insert_final_newline = false
9 | trim_trailing_whitespace = true
10 | max_line_length = off
11 |
--------------------------------------------------------------------------------
/src/files/2_CodeStyle.editorconfig:
--------------------------------------------------------------------------------
1 | is_global = true
2 | global_level = -1
3 |
4 | #### BEGIN GENERATED CONTENT FROM VISUAL STUDIO CODE STYLE EDITOR ####
5 |
6 | # These options were hand-picked in VS Options > Text Editor > C# > Code Style
7 | # then exported to .editorconfig using the "Generate .editorconfig file from settings" feature
8 |
9 | #### .NET Coding Conventions ####
10 |
11 | # Organize usings
12 | dotnet_separate_import_directive_groups = false
13 | dotnet_sort_system_directives_first = true
14 | file_header_template = unset
15 |
16 | # this. and Me. preferences
17 | dotnet_style_qualification_for_event = true
18 | dotnet_style_qualification_for_field = true
19 | dotnet_style_qualification_for_method = true
20 | dotnet_style_qualification_for_property = true
21 |
22 | # Language keywords vs BCL types preferences
23 | dotnet_style_predefined_type_for_locals_parameters_members = true
24 | dotnet_style_predefined_type_for_member_access = true
25 |
26 | # Parentheses preferences
27 | dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity
28 | dotnet_style_parentheses_in_other_binary_operators = always_for_clarity
29 | dotnet_style_parentheses_in_other_operators = never_if_unnecessary
30 | dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity
31 |
32 | # Modifier preferences
33 | dotnet_style_require_accessibility_modifiers = for_non_interface_members
34 |
35 | # Expression-level preferences
36 | dotnet_style_coalesce_expression = true
37 | dotnet_style_collection_initializer = true
38 | dotnet_style_explicit_tuple_names = true
39 | dotnet_style_namespace_match_folder = true
40 | dotnet_style_null_propagation = true
41 | dotnet_style_object_initializer = true
42 | dotnet_style_operator_placement_when_wrapping = beginning_of_line
43 | dotnet_style_prefer_auto_properties = true
44 | dotnet_style_prefer_collection_expression = true
45 | dotnet_style_prefer_compound_assignment = true
46 | dotnet_style_prefer_conditional_expression_over_assignment = true
47 | dotnet_style_prefer_conditional_expression_over_return = true
48 | dotnet_style_prefer_foreach_explicit_cast_in_source = when_strongly_typed
49 | dotnet_style_prefer_inferred_anonymous_type_member_names = true
50 | dotnet_style_prefer_inferred_tuple_names = true
51 | dotnet_style_prefer_is_null_check_over_reference_equality_method = true
52 | dotnet_style_prefer_simplified_boolean_expressions = true
53 | dotnet_style_prefer_simplified_interpolation = true
54 |
55 | # Field preferences
56 | dotnet_style_readonly_field = true
57 |
58 | # Parameter preferences
59 | dotnet_code_quality_unused_parameters = all
60 |
61 | # Suppression preferences
62 | dotnet_remove_unnecessary_suppression_exclusions = none
63 |
64 | # New line preferences
65 | dotnet_style_allow_multiple_blank_lines_experimental = false
66 | dotnet_style_allow_statement_immediately_after_block_experimental = false
67 |
68 | #### C# Coding Conventions ####
69 |
70 | # var preferences
71 | csharp_style_var_elsewhere = true
72 | csharp_style_var_for_built_in_types = true
73 | csharp_style_var_when_type_is_apparent = true
74 |
75 | # Expression-bodied members
76 | csharp_style_expression_bodied_accessors = true
77 | csharp_style_expression_bodied_constructors = false
78 | csharp_style_expression_bodied_indexers = true
79 | csharp_style_expression_bodied_lambdas = true
80 | csharp_style_expression_bodied_local_functions = false
81 | csharp_style_expression_bodied_methods = false
82 | csharp_style_expression_bodied_operators = false
83 | csharp_style_expression_bodied_properties = true
84 |
85 | # Pattern matching preferences
86 | csharp_style_pattern_matching_over_as_with_null_check = true
87 | csharp_style_pattern_matching_over_is_with_cast_check = true
88 | csharp_style_prefer_extended_property_pattern = true
89 | csharp_style_prefer_not_pattern = true
90 | csharp_style_prefer_pattern_matching = true
91 | csharp_style_prefer_switch_expression = true
92 |
93 | # Null-checking preferences
94 | csharp_style_conditional_delegate_call = true
95 |
96 | # Modifier preferences
97 | csharp_prefer_static_local_function = true
98 | csharp_preferred_modifier_order = public,private,protected,internal,file,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,required,volatile,async
99 | csharp_style_prefer_readonly_struct = true
100 | csharp_style_prefer_readonly_struct_member = true
101 |
102 | # Code-block preferences
103 | csharp_prefer_braces = true
104 | csharp_prefer_simple_using_statement = true
105 | csharp_style_namespace_declarations = file_scoped
106 | csharp_style_prefer_method_group_conversion = true
107 | csharp_style_prefer_primary_constructors = true
108 | csharp_style_prefer_top_level_statements = true
109 |
110 | # Expression-level preferences
111 | csharp_prefer_simple_default_expression = true
112 | csharp_style_deconstructed_variable_declaration = true
113 | csharp_style_implicit_object_creation_when_type_is_apparent = true
114 | csharp_style_inlined_variable_declaration = true
115 | csharp_style_prefer_index_operator = true
116 | csharp_style_prefer_local_over_anonymous_function = true
117 | csharp_style_prefer_null_check_over_type_check = true
118 | csharp_style_prefer_range_operator = true
119 | csharp_style_prefer_tuple_swap = true
120 | csharp_style_prefer_utf8_string_literals = true
121 | csharp_style_throw_expression = true
122 | csharp_style_unused_value_assignment_preference = discard_variable
123 | csharp_style_unused_value_expression_statement_preference = discard_variable
124 |
125 | # 'using' directive preferences
126 | csharp_using_directive_placement = outside_namespace
127 |
128 | # New line preferences
129 | csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = false
130 | csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental = true
131 | csharp_style_allow_blank_line_after_token_in_conditional_expression_experimental = false
132 | csharp_style_allow_blank_lines_between_consecutive_braces_experimental = false
133 | csharp_style_allow_embedded_statements_on_same_line_experimental = false
134 |
135 | #### C# Formatting Rules ####
136 |
137 | # New line preferences
138 | csharp_new_line_before_catch = true
139 | csharp_new_line_before_else = true
140 | csharp_new_line_before_finally = true
141 | csharp_new_line_before_members_in_anonymous_types = true
142 | csharp_new_line_before_members_in_object_initializers = true
143 | csharp_new_line_before_open_brace = all
144 | csharp_new_line_between_query_expression_clauses = true
145 |
146 | # Indentation preferences
147 | csharp_indent_block_contents = true
148 | csharp_indent_braces = false
149 | csharp_indent_case_contents = true
150 | csharp_indent_case_contents_when_block = false
151 | csharp_indent_labels = one_less_than_current
152 | csharp_indent_switch_labels = true
153 |
154 | # Space preferences
155 | csharp_space_after_cast = false
156 | csharp_space_after_colon_in_inheritance_clause = true
157 | csharp_space_after_comma = true
158 | csharp_space_after_dot = false
159 | csharp_space_after_keywords_in_control_flow_statements = true
160 | csharp_space_after_semicolon_in_for_statement = true
161 | csharp_space_around_binary_operators = before_and_after
162 | csharp_space_around_declaration_statements = false
163 | csharp_space_before_colon_in_inheritance_clause = true
164 | csharp_space_before_comma = false
165 | csharp_space_before_dot = false
166 | csharp_space_before_open_square_brackets = false
167 | csharp_space_before_semicolon_in_for_statement = false
168 | csharp_space_between_empty_square_brackets = false
169 | csharp_space_between_method_call_empty_parameter_list_parentheses = false
170 | csharp_space_between_method_call_name_and_opening_parenthesis = false
171 | csharp_space_between_method_call_parameter_list_parentheses = false
172 | csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
173 | csharp_space_between_method_declaration_name_and_open_parenthesis = false
174 | csharp_space_between_method_declaration_parameter_list_parentheses = false
175 | csharp_space_between_parentheses = false
176 | csharp_space_between_square_brackets = false
177 |
178 | # Wrapping preferences
179 | csharp_preserve_single_line_blocks = true
180 | csharp_preserve_single_line_statements = false
181 |
182 | #### Naming styles ####
183 |
184 | # Naming rules
185 |
186 | dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion
187 | dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
188 | dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
189 |
190 | dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
191 | dotnet_naming_rule.types_should_be_pascal_case.symbols = types
192 | dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
193 |
194 | dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion
195 | dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
196 | dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
197 |
198 | dotnet_naming_rule.private_fields_should_be_camel_case_underscore_prefix.severity = suggestion
199 | dotnet_naming_rule.private_fields_should_be_camel_case_underscore_prefix.symbols = private_fields
200 | dotnet_naming_rule.private_fields_should_be_camel_case_underscore_prefix.style = camel_case_underscore_prefix
201 |
202 | dotnet_naming_rule.static_readonly_fields_should_be_pascal_case.severity = suggestion
203 | dotnet_naming_rule.static_readonly_fields_should_be_pascal_case.symbols = static_readonly_fields
204 | dotnet_naming_rule.static_readonly_fields_should_be_pascal_case.style = pascal_case
205 |
206 | dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion
207 | dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields
208 | dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case
209 |
210 | dotnet_naming_rule.local_variables_should_be_camel_case.severity = suggestion
211 | dotnet_naming_rule.local_variables_should_be_camel_case.symbols = local_variables
212 | dotnet_naming_rule.local_variables_should_be_camel_case.style = camel_case
213 |
214 | # Symbol specifications
215 |
216 | dotnet_naming_symbols.interface.applicable_kinds = interface
217 | dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
218 | dotnet_naming_symbols.interface.required_modifiers =
219 |
220 | dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
221 | dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
222 | dotnet_naming_symbols.types.required_modifiers =
223 |
224 | dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
225 | dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
226 | dotnet_naming_symbols.non_field_members.required_modifiers =
227 |
228 | dotnet_naming_symbols.private_fields.applicable_kinds = field
229 | dotnet_naming_symbols.private_fields.applicable_accessibilities = private, private_protected
230 | dotnet_naming_symbols.private_fields.required_modifiers =
231 |
232 | dotnet_naming_symbols.static_readonly_fields.applicable_kinds = field
233 | dotnet_naming_symbols.static_readonly_fields.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
234 | dotnet_naming_symbols.static_readonly_fields.required_modifiers = static, readonly
235 |
236 | dotnet_naming_symbols.constant_fields.applicable_kinds = field
237 | dotnet_naming_symbols.constant_fields.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
238 | dotnet_naming_symbols.constant_fields.required_modifiers = const
239 |
240 | dotnet_naming_symbols.local_variables.applicable_kinds = parameter, local
241 | dotnet_naming_symbols.local_variables.applicable_accessibilities = local
242 | dotnet_naming_symbols.local_variables.required_modifiers =
243 |
244 | # Naming styles
245 |
246 | dotnet_naming_style.pascal_case.required_prefix =
247 | dotnet_naming_style.pascal_case.required_suffix =
248 | dotnet_naming_style.pascal_case.word_separator =
249 | dotnet_naming_style.pascal_case.capitalization = pascal_case
250 |
251 | dotnet_naming_style.camel_case.required_prefix =
252 | dotnet_naming_style.camel_case.required_suffix =
253 | dotnet_naming_style.camel_case.word_separator =
254 | dotnet_naming_style.camel_case.capitalization = camel_case
255 |
256 | dotnet_naming_style.begins_with_i.required_prefix = I
257 | dotnet_naming_style.begins_with_i.required_suffix =
258 | dotnet_naming_style.begins_with_i.word_separator =
259 | dotnet_naming_style.begins_with_i.capitalization = pascal_case
260 |
261 | dotnet_naming_style.camel_case_underscore_prefix.required_prefix = _
262 | dotnet_naming_style.camel_case_underscore_prefix.required_suffix =
263 | dotnet_naming_style.camel_case_underscore_prefix.word_separator =
264 | dotnet_naming_style.camel_case_underscore_prefix.capitalization = camel_case
265 |
--------------------------------------------------------------------------------
/src/files/3_ReSharperAnalyzers.editorconfig:
--------------------------------------------------------------------------------
1 | is_global = true
2 | global_level = -1
3 |
4 | # Disable some ReSharper / Rider inspections already covered by .NET analyzers
5 |
6 | # Already covered by IDE0130
7 | resharper_check_namespace_highlighting = none
8 |
9 | # Already covered by file defaults "insert_final_newline"
10 | csharp_insert_final_newline = false
11 |
12 | # Fix to address https://youtrack.jetbrains.com/issue/RSRP-486359
13 | # where csharp_new_line_before_members_in_object_initializers would still inline object initializers
14 | resharper_wrap_object_and_collection_initializer_style = chop_always
--------------------------------------------------------------------------------
/src/files/4_TestProjectsAnalyzers.editorconfig:
--------------------------------------------------------------------------------
1 | # global_level must be higher than the .NET Analyzer files
2 | is_global = true
3 | global_level = 0
4 |
5 | # GMNG01: Add 'IndexBy' or 'NoIndexNeeded' attributes on the containing type
6 | # Disabled because specifying MongoDB indexes is only required for production code, not for test projects
7 | dotnet_diagnostic.GMNG01.severity = none
8 |
9 | # GMDTR12: Use method ending with 'Async' instead
10 | # Disabled because our MediatR static extension method that ends with "Async" cannot be mocked in unit tests so developers have to use the "Send" method instead
11 | dotnet_diagnostic.GMDTR12.severity = none
12 |
--------------------------------------------------------------------------------
/src/files/BannedSymbols.txt:
--------------------------------------------------------------------------------
1 | P:System.DateTime.Now;Use System.DateTime.UtcNow instead.
2 | P:System.DateTimeOffset.Now;Use System.DateTimeOffset.UtcNow instead.
3 | P:System.DateTimeOffset.DateTime;Use System.DateTimeOffset.UtcDateTime instead.
4 |
5 | F:System.StringComparison.InvariantCulture;InvariantCulture performs a linguistic comparison. Most of the time Ordinal is the correct one.
6 | F:System.StringComparison.InvariantCultureIgnoreCase;InvariantCultureIgnoreCase performs a linguistic comparison. Most of the time OrdinalIgnoreCase is the correct one.
7 | P:System.StringComparer.InvariantCulture;InvariantCulture performs a linguistic comparison. Most of the time Ordinal is the correct one.
8 | P:System.StringComparer.InvariantCultureIgnoreCase;InvariantCultureIgnoreCase performs a linguistic comparison. Most of the time OrdinalIgnoreCase is the correct one.
9 |
--------------------------------------------------------------------------------
/src/files/analyzers/Analyzer.Meziantou.Analyzer.editorconfig:
--------------------------------------------------------------------------------
1 | # global_level must be higher than the NET Analyzer files
2 | is_global = true
3 | global_level = 0
4 |
5 | # MA0001: StringComparison is missing
6 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0001.md
7 | # Enabled: True, Severity: suggestion
8 | dotnet_diagnostic.MA0001.severity = none
9 |
10 | # MA0002: IEqualityComparer or IComparer is missing
11 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0002.md
12 | # Enabled: True, Severity: warning
13 | dotnet_diagnostic.MA0002.severity = none
14 |
15 | # MA0003: Add parameter name to improve readability
16 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0003.md
17 | # Enabled: True, Severity: suggestion
18 | dotnet_diagnostic.MA0003.severity = none
19 |
20 | # MA0004: Use Task.ConfigureAwait
21 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0004.md
22 | # Enabled: True, Severity: warning
23 | dotnet_diagnostic.MA0004.severity = none
24 |
25 | # MA0005: Use Array.Empty()
26 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0005.md
27 | # Enabled: True, Severity: warning
28 | dotnet_diagnostic.MA0005.severity = none
29 |
30 | # MA0006: Use String.Equals instead of equality operator
31 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0006.md
32 | # Enabled: True, Severity: warning
33 | dotnet_diagnostic.MA0006.severity = none
34 |
35 | # MA0007: Add a comma after the last value
36 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0007.md
37 | # Enabled: True, Severity: suggestion
38 | dotnet_diagnostic.MA0007.severity = none
39 |
40 | # MA0008: Add StructLayoutAttribute
41 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0008.md
42 | # Enabled: True, Severity: warning
43 | dotnet_diagnostic.MA0008.severity = none
44 |
45 | # MA0009: Add regex evaluation timeout
46 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0009.md
47 | # Enabled: True, Severity: warning
48 | dotnet_diagnostic.MA0009.severity = none
49 |
50 | # MA0010: Mark attributes with AttributeUsageAttribute
51 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0010.md
52 | # Enabled: True, Severity: warning
53 | dotnet_diagnostic.MA0010.severity = none
54 |
55 | # MA0011: IFormatProvider is missing
56 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0011.md
57 | # Enabled: True, Severity: warning
58 | dotnet_diagnostic.MA0011.severity = none
59 |
60 | # MA0012: Do not raise reserved exception type
61 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0012.md
62 | # Enabled: True, Severity: warning
63 | dotnet_diagnostic.MA0012.severity = none
64 |
65 | # MA0013: Types should not extend System.ApplicationException
66 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0013.md
67 | # Enabled: True, Severity: warning
68 | dotnet_diagnostic.MA0013.severity = none
69 |
70 | # MA0014: Do not raise System.ApplicationException type
71 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0014.md
72 | # Enabled: True, Severity: warning
73 | dotnet_diagnostic.MA0014.severity = none
74 |
75 | # MA0015: Specify the parameter name in ArgumentException
76 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0015.md
77 | # Enabled: True, Severity: warning
78 | dotnet_diagnostic.MA0015.severity = suggestion
79 |
80 | # MA0016: Prefer using collection abstraction instead of implementation
81 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0016.md
82 | # Enabled: True, Severity: warning
83 | dotnet_diagnostic.MA0016.severity = none
84 |
85 | # MA0017: Abstract types should not have public or internal constructors
86 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0017.md
87 | # Enabled: True, Severity: warning
88 | dotnet_diagnostic.MA0017.severity = suggestion
89 |
90 | # MA0018: Do not declare static members on generic types (deprecated; use CA1000 instead)
91 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0018.md
92 | # Enabled: True, Severity: suggestion
93 | dotnet_diagnostic.MA0018.severity = none
94 |
95 | # MA0019: Use EventArgs.Empty
96 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0019.md
97 | # Enabled: True, Severity: warning
98 | dotnet_diagnostic.MA0019.severity = suggestion
99 |
100 | # MA0020: Use direct methods instead of LINQ methods
101 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0020.md
102 | # Enabled: True, Severity: suggestion
103 | dotnet_diagnostic.MA0020.severity = none
104 |
105 | # MA0021: Use StringComparer.GetHashCode instead of string.GetHashCode
106 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0021.md
107 | # Enabled: True, Severity: warning
108 | dotnet_diagnostic.MA0021.severity = none
109 |
110 | # MA0022: Return Task.FromResult instead of returning null
111 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0022.md
112 | # Enabled: True, Severity: warning
113 | dotnet_diagnostic.MA0022.severity = warning
114 |
115 | # MA0023: Add RegexOptions.ExplicitCapture
116 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0023.md
117 | # Enabled: True, Severity: warning
118 | dotnet_diagnostic.MA0023.severity = suggestion
119 |
120 | # MA0024: Use an explicit StringComparer when possible
121 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0024.md
122 | # Enabled: True, Severity: warning
123 | dotnet_diagnostic.MA0024.severity = none
124 |
125 | # MA0025: Implement the functionality instead of throwing NotImplementedException
126 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0025.md
127 | # Enabled: True, Severity: warning
128 | dotnet_diagnostic.MA0025.severity = none
129 |
130 | # MA0026: Fix TODO comment
131 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0026.md
132 | # Enabled: True, Severity: warning
133 | dotnet_diagnostic.MA0026.severity = none
134 |
135 | # MA0027: Prefer rethrowing an exception implicitly
136 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0027.md
137 | # Enabled: True, Severity: warning
138 | dotnet_diagnostic.MA0027.severity = warning
139 |
140 | # MA0028: Optimize StringBuilder usage
141 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0028.md
142 | # Enabled: True, Severity: suggestion
143 | dotnet_diagnostic.MA0028.severity = none
144 |
145 | # MA0029: Combine LINQ methods
146 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0029.md
147 | # Enabled: True, Severity: suggestion
148 | dotnet_diagnostic.MA0029.severity = suggestion
149 |
150 | # MA0030: Remove useless OrderBy call
151 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0030.md
152 | # Enabled: True, Severity: warning
153 | dotnet_diagnostic.MA0030.severity = suggestion
154 |
155 | # MA0031: Optimize Enumerable.Count() usage
156 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0031.md
157 | # Enabled: True, Severity: suggestion
158 | dotnet_diagnostic.MA0031.severity = none
159 |
160 | # MA0032: Use an overload with a CancellationToken argument
161 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0032.md
162 | # Enabled: False, Severity: suggestion
163 | dotnet_diagnostic.MA0032.severity = none
164 |
165 | # MA0033: Do not tag instance fields with ThreadStaticAttribute
166 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0033.md
167 | # Enabled: True, Severity: warning
168 | dotnet_diagnostic.MA0033.severity = none
169 |
170 | # MA0035: Do not use dangerous threading methods
171 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0035.md
172 | # Enabled: True, Severity: warning
173 | dotnet_diagnostic.MA0035.severity = warning
174 |
175 | # MA0036: Make class static
176 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0036.md
177 | # Enabled: True, Severity: suggestion
178 | dotnet_diagnostic.MA0036.severity = none
179 |
180 | # MA0037: Remove empty statement
181 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0037.md
182 | # Enabled: True, Severity: error
183 | dotnet_diagnostic.MA0037.severity = warning
184 |
185 | # MA0038: Make method static (deprecated, use CA1822 instead)
186 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0038.md
187 | # Enabled: True, Severity: suggestion
188 | dotnet_diagnostic.MA0038.severity = none
189 |
190 | # MA0039: Do not write your own certificate validation method
191 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0039.md
192 | # Enabled: True, Severity: error
193 | dotnet_diagnostic.MA0039.severity = none
194 |
195 | # MA0040: Forward the CancellationToken parameter to methods that take one
196 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0040.md
197 | # Enabled: True, Severity: suggestion
198 | dotnet_diagnostic.MA0040.severity = suggestion
199 |
200 | # MA0041: Make property static (deprecated, use CA1822 instead)
201 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0041.md
202 | # Enabled: True, Severity: suggestion
203 | dotnet_diagnostic.MA0041.severity = none
204 |
205 | # MA0042: Do not use blocking calls in an async method
206 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0042.md
207 | # Enabled: True, Severity: suggestion
208 | dotnet_diagnostic.MA0042.severity = suggestion
209 |
210 | # MA0043: Use nameof operator in ArgumentException
211 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0043.md
212 | # Enabled: True, Severity: suggestion
213 | dotnet_diagnostic.MA0043.severity = none
214 |
215 | # MA0044: Remove useless ToString call
216 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0044.md
217 | # Enabled: True, Severity: suggestion
218 | dotnet_diagnostic.MA0044.severity = suggestion
219 |
220 | # MA0045: Do not use blocking calls in a sync method (need to make calling method async)
221 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0045.md
222 | # Enabled: False, Severity: suggestion
223 | dotnet_diagnostic.MA0045.severity = none
224 |
225 | # MA0046: Use EventHandler to declare events
226 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0046.md
227 | # Enabled: True, Severity: warning
228 | dotnet_diagnostic.MA0046.severity = none
229 |
230 | # MA0047: Declare types in namespaces
231 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0047.md
232 | # Enabled: True, Severity: warning
233 | dotnet_diagnostic.MA0047.severity = none
234 |
235 | # MA0048: File name must match type name
236 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0048.md
237 | # Enabled: True, Severity: warning
238 | dotnet_diagnostic.MA0048.severity = none
239 |
240 | # MA0049: Type name should not match containing namespace
241 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0049.md
242 | # Enabled: True, Severity: error
243 | dotnet_diagnostic.MA0049.severity = none
244 |
245 | # MA0050: Validate arguments correctly in iterator methods
246 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0050.md
247 | # Enabled: True, Severity: suggestion
248 | dotnet_diagnostic.MA0050.severity = none
249 |
250 | # MA0051: Method is too long
251 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0051.md
252 | # Enabled: True, Severity: warning
253 | dotnet_diagnostic.MA0051.severity = none
254 |
255 | # MA0052: Replace constant Enum.ToString with nameof
256 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0052.md
257 | # Enabled: True, Severity: suggestion
258 | dotnet_diagnostic.MA0052.severity = suggestion
259 |
260 | # MA0053: Make class sealed
261 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0053.md
262 | # Enabled: True, Severity: suggestion
263 | dotnet_diagnostic.MA0053.severity = none
264 |
265 | # MA0054: Embed the caught exception as innerException
266 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0054.md
267 | # Enabled: True, Severity: warning
268 | dotnet_diagnostic.MA0054.severity = warning
269 |
270 | # MA0055: Do not use finalizer
271 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0055.md
272 | # Enabled: True, Severity: warning
273 | dotnet_diagnostic.MA0055.severity = warning
274 |
275 | # MA0056: Do not call overridable members in constructor
276 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0056.md
277 | # Enabled: True, Severity: warning
278 | dotnet_diagnostic.MA0056.severity = suggestion
279 |
280 | # MA0057: Class name should end with 'Attribute'
281 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0057.md
282 | # Enabled: True, Severity: suggestion
283 | dotnet_diagnostic.MA0057.severity = none
284 |
285 | # MA0058: Class name should end with 'Exception'
286 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0058.md
287 | # Enabled: True, Severity: suggestion
288 | dotnet_diagnostic.MA0058.severity = none
289 |
290 | # MA0059: Class name should end with 'EventArgs'
291 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0059.md
292 | # Enabled: True, Severity: suggestion
293 | dotnet_diagnostic.MA0059.severity = none
294 |
295 | # MA0060: The value returned by Stream.Read/Stream.ReadAsync is not used
296 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0060.md
297 | # Enabled: True, Severity: warning
298 | dotnet_diagnostic.MA0060.severity = warning
299 |
300 | # MA0061: Method overrides should not change default values
301 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0061.md
302 | # Enabled: True, Severity: warning
303 | dotnet_diagnostic.MA0061.severity = none
304 |
305 | # MA0062: Non-flags enums should not be marked with "FlagsAttribute"
306 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0062.md
307 | # Enabled: True, Severity: warning
308 | dotnet_diagnostic.MA0062.severity = none
309 |
310 | # MA0063: Use Where before OrderBy
311 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0063.md
312 | # Enabled: True, Severity: suggestion
313 | dotnet_diagnostic.MA0063.severity = suggestion
314 |
315 | # MA0064: Avoid locking on publicly accessible instance
316 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0064.md
317 | # Enabled: True, Severity: warning
318 | dotnet_diagnostic.MA0064.severity = none
319 |
320 | # MA0065: Default ValueType.Equals or HashCode is used for struct equality
321 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0065.md
322 | # Enabled: True, Severity: warning
323 | dotnet_diagnostic.MA0065.severity = none
324 |
325 | # MA0066: Hash table unfriendly type is used in a hash table
326 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0066.md
327 | # Enabled: True, Severity: warning
328 | dotnet_diagnostic.MA0066.severity = none
329 |
330 | # MA0067: Use Guid.Empty
331 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0067.md
332 | # Enabled: True, Severity: suggestion
333 | dotnet_diagnostic.MA0067.severity = suggestion
334 |
335 | # MA0068: Invalid parameter name for nullable attribute
336 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0068.md
337 | # Enabled: True, Severity: warning
338 | dotnet_diagnostic.MA0068.severity = warning
339 |
340 | # MA0069: Non-constant static fields should not be visible
341 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0069.md
342 | # Enabled: True, Severity: warning
343 | dotnet_diagnostic.MA0069.severity = none
344 |
345 | # MA0070: Obsolete attributes should include explanations
346 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0070.md
347 | # Enabled: True, Severity: warning
348 | dotnet_diagnostic.MA0070.severity = suggestion
349 |
350 | # MA0071: Avoid using redundant else
351 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0071.md
352 | # Enabled: True, Severity: suggestion
353 | dotnet_diagnostic.MA0071.severity = none
354 |
355 | # MA0072: Do not throw from a finally block
356 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0072.md
357 | # Enabled: True, Severity: warning
358 | dotnet_diagnostic.MA0072.severity = warning
359 |
360 | # MA0073: Avoid comparison with bool constant
361 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0073.md
362 | # Enabled: True, Severity: suggestion
363 | dotnet_diagnostic.MA0073.severity = suggestion
364 |
365 | # MA0074: Avoid implicit culture-sensitive methods
366 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0074.md
367 | # Enabled: True, Severity: warning
368 | dotnet_diagnostic.MA0074.severity = none
369 |
370 | # MA0075: Do not use implicit culture-sensitive ToString
371 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0075.md
372 | # Enabled: True, Severity: suggestion
373 | dotnet_diagnostic.MA0075.severity = none
374 |
375 | # MA0076: Do not use implicit culture-sensitive ToString in interpolated strings
376 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0076.md
377 | # Enabled: True, Severity: suggestion
378 | dotnet_diagnostic.MA0076.severity = none
379 |
380 | # MA0077: A class that provides Equals(T) should implement IEquatable
381 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0077.md
382 | # Enabled: True, Severity: warning
383 | dotnet_diagnostic.MA0077.severity = none
384 |
385 | # MA0078: Use 'Cast' instead of 'Select' to cast
386 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0078.md
387 | # Enabled: True, Severity: suggestion
388 | dotnet_diagnostic.MA0078.severity = none
389 |
390 | # MA0079: Forward the CancellationToken using .WithCancellation()
391 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0079.md
392 | # Enabled: True, Severity: suggestion
393 | dotnet_diagnostic.MA0079.severity = suggestion
394 |
395 | # MA0080: Use a cancellation token using .WithCancellation()
396 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0080.md
397 | # Enabled: False, Severity: suggestion
398 | dotnet_diagnostic.MA0080.severity = none
399 |
400 | # MA0081: Method overrides should not omit params keyword
401 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0081.md
402 | # Enabled: True, Severity: warning
403 | dotnet_diagnostic.MA0081.severity = none
404 |
405 | # MA0082: NaN should not be used in comparisons
406 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0082.md
407 | # Enabled: True, Severity: warning
408 | dotnet_diagnostic.MA0082.severity = warning
409 |
410 | # MA0083: ConstructorArgument parameters should exist in constructors
411 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0083.md
412 | # Enabled: True, Severity: warning
413 | dotnet_diagnostic.MA0083.severity = none
414 |
415 | # MA0084: Local variables should not hide other symbols
416 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0084.md
417 | # Enabled: True, Severity: warning
418 | dotnet_diagnostic.MA0084.severity = none
419 |
420 | # MA0085: Anonymous delegates should not be used to unsubscribe from Events
421 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0085.md
422 | # Enabled: True, Severity: warning
423 | dotnet_diagnostic.MA0085.severity = warning
424 |
425 | # MA0086: Do not throw from a finalizer
426 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0086.md
427 | # Enabled: True, Severity: warning
428 | dotnet_diagnostic.MA0086.severity = warning
429 |
430 | # MA0087: Parameters with [DefaultParameterValue] attributes should also be marked [Optional]
431 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0087.md
432 | # Enabled: True, Severity: warning
433 | dotnet_diagnostic.MA0087.severity = suggestion
434 |
435 | # MA0088: Use [DefaultParameterValue] instead of [DefaultValue]
436 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0088.md
437 | # Enabled: True, Severity: warning
438 | dotnet_diagnostic.MA0088.severity = suggestion
439 |
440 | # MA0089: Optimize string method usage
441 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0089.md
442 | # Enabled: True, Severity: suggestion
443 | dotnet_diagnostic.MA0089.severity = none
444 |
445 | # MA0090: Remove empty else/finally block
446 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0090.md
447 | # Enabled: True, Severity: suggestion
448 | dotnet_diagnostic.MA0090.severity = suggestion
449 |
450 | # MA0091: Sender should be 'this' for instance events
451 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0091.md
452 | # Enabled: True, Severity: warning
453 | dotnet_diagnostic.MA0091.severity = none
454 |
455 | # MA0092: Sender should be 'null' for static events
456 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0092.md
457 | # Enabled: True, Severity: warning
458 | dotnet_diagnostic.MA0092.severity = none
459 |
460 | # MA0093: EventArgs should not be null
461 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0093.md
462 | # Enabled: True, Severity: warning
463 | dotnet_diagnostic.MA0093.severity = suggestion
464 |
465 | # MA0094: A class that provides CompareTo(T) should implement IComparable
466 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0094.md
467 | # Enabled: True, Severity: warning
468 | dotnet_diagnostic.MA0094.severity = none
469 |
470 | # MA0095: A class that implements IEquatable should override Equals(object)
471 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0095.md
472 | # Enabled: True, Severity: warning
473 | dotnet_diagnostic.MA0095.severity = none
474 |
475 | # MA0096: A class that implements IComparable should also implement IEquatable
476 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0096.md
477 | # Enabled: True, Severity: warning
478 | dotnet_diagnostic.MA0096.severity = none
479 |
480 | # MA0097: A class that implements IComparable or IComparable should override comparison operators
481 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0097.md
482 | # Enabled: True, Severity: warning
483 | dotnet_diagnostic.MA0097.severity = none
484 |
485 | # MA0098: Use indexer instead of LINQ methods
486 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0098.md
487 | # Enabled: True, Severity: suggestion
488 | dotnet_diagnostic.MA0098.severity = none
489 |
490 | # MA0099: Use Explicit enum value instead of 0
491 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0099.md
492 | # Enabled: True, Severity: warning
493 | dotnet_diagnostic.MA0099.severity = suggestion
494 |
495 | # MA0100: Await task before disposing of resources
496 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0100.md
497 | # Enabled: True, Severity: warning
498 | dotnet_diagnostic.MA0100.severity = warning
499 |
500 | # MA0101: String contains an implicit end of line character
501 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0101.md
502 | # Enabled: True, Severity: silent
503 | dotnet_diagnostic.MA0101.severity = none
504 |
505 | # MA0102: Make member readonly
506 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0102.md
507 | # Enabled: True, Severity: suggestion
508 | dotnet_diagnostic.MA0102.severity = none
509 |
510 | # MA0103: Use SequenceEqual instead of equality operator
511 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0103.md
512 | # Enabled: True, Severity: warning
513 | dotnet_diagnostic.MA0103.severity = suggestion
514 |
515 | # MA0104: Do not create a type with a name from the BCL
516 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0104.md
517 | # Enabled: False, Severity: warning
518 | dotnet_diagnostic.MA0104.severity = none
519 |
520 | # MA0105: Use the lambda parameters instead of using a closure
521 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0105.md
522 | # Enabled: True, Severity: suggestion
523 | dotnet_diagnostic.MA0105.severity = none
524 |
525 | # MA0106: Avoid closure by using an overload with the 'factoryArgument' parameter
526 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0106.md
527 | # Enabled: True, Severity: suggestion
528 | dotnet_diagnostic.MA0106.severity = none
529 |
530 | # MA0107: Do not use culture-sensitive object.ToString
531 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0107.md
532 | # Enabled: False, Severity: suggestion
533 | dotnet_diagnostic.MA0107.severity = none
534 |
535 | # MA0108: Remove redundant argument value
536 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0108.md
537 | # Enabled: True, Severity: suggestion
538 | dotnet_diagnostic.MA0108.severity = suggestion
539 |
540 | # MA0109: Consider adding an overload with a Span or Memory
541 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0109.md
542 | # Enabled: False, Severity: suggestion
543 | dotnet_diagnostic.MA0109.severity = none
544 |
545 | # MA0110: Use the Regex source generator
546 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0110.md
547 | # Enabled: True, Severity: suggestion
548 | dotnet_diagnostic.MA0110.severity = none
549 |
550 | # MA0111: Use string.Create instead of FormattableString
551 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0111.md
552 | # Enabled: True, Severity: suggestion
553 | dotnet_diagnostic.MA0111.severity = none
554 |
555 | # MA0112: Use 'Count > 0' instead of 'Any()'
556 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0112.md
557 | # Enabled: False, Severity: suggestion
558 | dotnet_diagnostic.MA0112.severity = none
559 |
560 | # MA0113: Use DateTime.UnixEpoch
561 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0113.md
562 | # Enabled: True, Severity: suggestion
563 | dotnet_diagnostic.MA0113.severity = suggestion
564 |
565 | # MA0114: Use DateTimeOffset.UnixEpoch
566 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0114.md
567 | # Enabled: True, Severity: suggestion
568 | dotnet_diagnostic.MA0114.severity = suggestion
569 |
570 | # MA0115: Unknown component parameter
571 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0115.md
572 | # Enabled: True, Severity: warning
573 | dotnet_diagnostic.MA0115.severity = none
574 |
575 | # MA0116: Parameters with [SupplyParameterFromQuery] attributes should also be marked as [Parameter]
576 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0116.md
577 | # Enabled: True, Severity: warning
578 | dotnet_diagnostic.MA0116.severity = none
579 |
580 | # MA0117: Parameters with [EditorRequired] attributes should also be marked as [Parameter]
581 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0117.md
582 | # Enabled: True, Severity: warning
583 | dotnet_diagnostic.MA0117.severity = none
584 |
585 | # MA0118: [JSInvokable] methods must be public
586 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0118.md
587 | # Enabled: True, Severity: warning
588 | dotnet_diagnostic.MA0118.severity = none
589 |
590 | # MA0119: JSRuntime must not be used in OnInitialized or OnInitializedAsync
591 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0119.md
592 | # Enabled: True, Severity: warning
593 | dotnet_diagnostic.MA0119.severity = none
594 |
595 | # MA0120: Use InvokeVoidAsync when the returned value is not used
596 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0120.md
597 | # Enabled: True, Severity: suggestion
598 | dotnet_diagnostic.MA0120.severity = none
599 |
600 | # MA0121: Do not overwrite parameter value
601 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0121.md
602 | # Enabled: False, Severity: suggestion
603 | dotnet_diagnostic.MA0121.severity = none
604 |
605 | # MA0122: Parameters with [SupplyParameterFromQuery] attributes are only valid in routable components (@page)
606 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0122.md
607 | # Enabled: True, Severity: suggestion
608 | dotnet_diagnostic.MA0122.severity = none
609 |
610 | # MA0123: Sequence number must be a constant
611 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0123.md
612 | # Enabled: True, Severity: warning
613 | dotnet_diagnostic.MA0123.severity = none
614 |
615 | # MA0124: Log parameter type is not valid
616 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0124.md
617 | # Enabled: True, Severity: warning
618 | dotnet_diagnostic.MA0124.severity = none
619 |
620 | # MA0125: The list of log parameter types contains an invalid type
621 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0125.md
622 | # Enabled: True, Severity: warning
623 | dotnet_diagnostic.MA0125.severity = none
624 |
625 | # MA0126: The list of log parameter types contains a duplicate
626 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0126.md
627 | # Enabled: True, Severity: warning
628 | dotnet_diagnostic.MA0126.severity = none
629 |
630 | # MA0127: Use String.Equals instead of is pattern
631 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0127.md
632 | # Enabled: False, Severity: warning
633 | dotnet_diagnostic.MA0127.severity = none
634 |
635 | # MA0128: Use 'is' operator instead of SequenceEqual
636 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0128.md
637 | # Enabled: True, Severity: suggestion
638 | dotnet_diagnostic.MA0128.severity = suggestion
639 |
640 | # MA0129: Await task in using statement
641 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0129.md
642 | # Enabled: True, Severity: warning
643 | dotnet_diagnostic.MA0129.severity = warning
644 |
645 | # MA0130: GetType() should not be used on System.Type instances
646 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0130.md
647 | # Enabled: True, Severity: warning
648 | dotnet_diagnostic.MA0130.severity = warning
649 |
650 | # MA0131: ArgumentNullException.ThrowIfNull should not be used with non-nullable types
651 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0131.md
652 | # Enabled: True, Severity: warning
653 | dotnet_diagnostic.MA0131.severity = none
654 |
655 | # MA0132: Do not convert implicitly to DateTimeOffset
656 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0132.md
657 | # Enabled: True, Severity: warning
658 | dotnet_diagnostic.MA0132.severity = none
659 |
660 | # MA0133: Use DateTimeOffset instead of relying on the implicit conversion
661 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0133.md
662 | # Enabled: True, Severity: suggestion
663 | dotnet_diagnostic.MA0133.severity = none
664 |
665 | # MA0134: Observe result of async calls
666 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0134.md
667 | # Enabled: True, Severity: warning
668 | dotnet_diagnostic.MA0134.severity = warning
669 |
670 | # MA0135: The log parameter has no configured type
671 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0135.md
672 | # Enabled: False, Severity: warning
673 | dotnet_diagnostic.MA0135.severity = none
674 |
675 | # MA0136: Raw String contains an implicit end of line character
676 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0136.md
677 | # Enabled: True, Severity: silent
678 | dotnet_diagnostic.MA0136.severity = none
679 |
680 | # MA0137: Use 'Async' suffix when a method returns an awaitable type
681 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0137.md
682 | # Enabled: False, Severity: warning
683 | dotnet_diagnostic.MA0137.severity = none
684 |
685 | # MA0138: Do not use 'Async' suffix when a method does not return an awaitable type
686 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0138.md
687 | # Enabled: False, Severity: warning
688 | dotnet_diagnostic.MA0138.severity = none
689 |
690 | # MA0139: Log parameter type is not valid
691 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0139.md
692 | # Enabled: True, Severity: warning
693 | dotnet_diagnostic.MA0139.severity = none
694 |
695 | # MA0140: Both if and else branch have identical code
696 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0140.md
697 | # Enabled: True, Severity: warning
698 | dotnet_diagnostic.MA0140.severity = warning
699 |
700 | # MA0141: Use pattern matching instead of inequality operators for null check
701 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0141.md
702 | # Enabled: False, Severity: suggestion
703 | dotnet_diagnostic.MA0141.severity = none
704 |
705 | # MA0142: Use pattern matching instead of equality operators for null check
706 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0142.md
707 | # Enabled: False, Severity: suggestion
708 | dotnet_diagnostic.MA0142.severity = none
709 |
710 | # MA0143: Primary constructor parameters should be readonly
711 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0143.md
712 | # Enabled: True, Severity: warning
713 | dotnet_diagnostic.MA0143.severity = suggestion
714 |
715 | # MA0144: Use System.OperatingSystem to check the current OS
716 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0144.md
717 | # Enabled: True, Severity: warning
718 | dotnet_diagnostic.MA0144.severity = suggestion
719 |
720 | # MA0145: Signature for [UnsafeAccessorAttribute] method is not valid
721 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0145.md
722 | # Enabled: True, Severity: warning
723 | dotnet_diagnostic.MA0145.severity = warning
724 |
725 | # MA0146: Name must be set explicitly on local functions
726 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0146.md
727 | # Enabled: True, Severity: warning
728 | dotnet_diagnostic.MA0146.severity = warning
729 |
730 | # MA0147: Avoid async void method for delegate
731 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0147.md
732 | # Enabled: True, Severity: warning
733 | dotnet_diagnostic.MA0147.severity = none
734 |
735 | # MA0148: Use pattern matching instead of equality operators for discrete value
736 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0148.md
737 | # Enabled: False, Severity: suggestion
738 | dotnet_diagnostic.MA0148.severity = none
739 |
740 | # MA0149: Use pattern matching instead of inequality operators for discrete value
741 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0149.md
742 | # Enabled: False, Severity: suggestion
743 | dotnet_diagnostic.MA0149.severity = none
744 |
745 | # MA0150: Do not call the default object.ToString explicitly
746 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0150.md
747 | # Enabled: True, Severity: warning
748 | dotnet_diagnostic.MA0150.severity = none
749 |
750 | # MA0151: DebuggerDisplay must contain valid members
751 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0151.md
752 | # Enabled: True, Severity: warning
753 | dotnet_diagnostic.MA0151.severity = suggestion
754 |
755 | # MA0152: Use Unwrap instead of using await twice
756 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0152.md
757 | # Enabled: True, Severity: suggestion
758 | dotnet_diagnostic.MA0152.severity = suggestion
759 |
760 | # MA0153: Do not log symbols decorated with DataClassificationAttribute directly
761 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0153.md
762 | # Enabled: True, Severity: warning
763 | dotnet_diagnostic.MA0153.severity = none
764 |
765 | # MA0154: Use langword in XML comment
766 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0154.md
767 | # Enabled: True, Severity: suggestion
768 | dotnet_diagnostic.MA0154.severity = none
769 |
770 | # MA0155: Do not use async void methods
771 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0155.md
772 | # Enabled: False, Severity: warning
773 | dotnet_diagnostic.MA0155.severity = none
774 |
775 | # MA0156: Use 'Async' suffix when a method returns IAsyncEnumerable
776 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0156.md
777 | # Enabled: False, Severity: warning
778 | dotnet_diagnostic.MA0156.severity = none
779 |
780 | # MA0157: Do not use 'Async' suffix when a method returns IAsyncEnumerable
781 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0157.md
782 | # Enabled: False, Severity: warning
783 | dotnet_diagnostic.MA0157.severity = none
784 |
785 | # MA0158: Use System.Threading.Lock
786 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0158.md
787 | # Enabled: True, Severity: warning
788 | dotnet_diagnostic.MA0158.severity = suggestion
789 |
790 | # MA0159: Use 'Order' instead of 'OrderBy'
791 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0159.md
792 | # Enabled: True, Severity: suggestion
793 | dotnet_diagnostic.MA0159.severity = suggestion
794 |
795 | # MA0160: Use ContainsKey instead of TryGetValue
796 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0160.md
797 | # Enabled: True, Severity: suggestion
798 | dotnet_diagnostic.MA0160.severity = suggestion
799 |
800 | # MA0161: UseShellExecute must be explicitly set
801 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0161.md
802 | # Enabled: False, Severity: suggestion
803 | dotnet_diagnostic.MA0161.severity = none
804 |
805 | # MA0162: Use Process.Start overload with ProcessStartInfo
806 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0162.md
807 | # Enabled: False, Severity: suggestion
808 | dotnet_diagnostic.MA0162.severity = none
809 |
810 | # MA0163: UseShellExecute must be false when redirecting standard input or output
811 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0163.md
812 | # Enabled: True, Severity: warning
813 | dotnet_diagnostic.MA0163.severity = none
814 |
815 | # MA0164: Use parentheses to make not pattern clearer
816 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0164.md
817 | # Enabled: True, Severity: warning
818 | dotnet_diagnostic.MA0164.severity = none
819 |
820 | # MA0165: Make interpolated string
821 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0165.md
822 | # Enabled: True, Severity: silent
823 | dotnet_diagnostic.MA0165.severity = none
824 |
825 | # MA0166: Forward the TimeProvider to methods that take one
826 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0166.md
827 | # Enabled: True, Severity: suggestion
828 | dotnet_diagnostic.MA0166.severity = suggestion
829 |
830 | # MA0167: Use an overload with a TimeProvider argument
831 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0167.md
832 | # Enabled: False, Severity: suggestion
833 | dotnet_diagnostic.MA0167.severity = none
834 |
835 | # MA0168: Use readonly struct for in or ref readonly parameter
836 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0168.md
837 | # Enabled: False, Severity: suggestion
838 | dotnet_diagnostic.MA0168.severity = none
839 |
840 | # MA0169: Use Equals method instead of operator
841 | # Help link: https://github.com/meziantou/Meziantou.Analyzer/blob/main/docs/Rules/MA0169.md
842 | # Enabled: True, Severity: warning
843 | dotnet_diagnostic.MA0169.severity = none
844 |
845 |
--------------------------------------------------------------------------------
/src/files/analyzers/Analyzer.Microsoft.CodeAnalysis.BannedApiAnalyzers.editorconfig:
--------------------------------------------------------------------------------
1 | # global_level must be higher than the NET Analyzer files
2 | is_global = true
3 | global_level = 0
4 |
5 | # RS0030: Do not use banned APIs
6 | # Help link: https://github.com/dotnet/roslyn-analyzers/blob/main/src/Microsoft.CodeAnalysis.BannedApiAnalyzers/BannedApiAnalyzers.Help.md
7 | # Enabled: True, Severity: warning
8 | dotnet_diagnostic.RS0030.severity = warning
9 |
10 | # RS0031: The list of banned symbols contains a duplicate
11 | # Help link: https://github.com/dotnet/roslyn-analyzers/blob/main/src/Microsoft.CodeAnalysis.BannedApiAnalyzers/BannedApiAnalyzers.Help.md
12 | # Enabled: True, Severity: warning
13 | dotnet_diagnostic.RS0031.severity = warning
14 |
15 | # RS0035: External access to internal symbols outside the restricted namespace(s) is prohibited
16 | # Enabled: True, Severity: error
17 | dotnet_diagnostic.RS0035.severity = error
18 |
19 |
--------------------------------------------------------------------------------
/src/files/analyzers/Analyzer.Microsoft.CodeAnalysis.CSharp.CodeStyle.editorconfig:
--------------------------------------------------------------------------------
1 | # global_level must be higher than the NET Analyzer files
2 | is_global = true
3 | global_level = 0
4 |
5 | # EnableGenerateDocumentationFile: Set MSBuild property 'GenerateDocumentationFile' to 'true'
6 | # Help link: https://github.com/dotnet/roslyn/issues/41640
7 | # Enabled: True, Severity: warning
8 | dotnet_diagnostic.EnableGenerateDocumentationFile.severity = warning
9 |
10 | # IDE0004: Remove Unnecessary Cast
11 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0004
12 | # Enabled: True, Severity: silent
13 | dotnet_diagnostic.IDE0004.severity = warning
14 |
15 | # IDE0005: Using directive is unnecessary.
16 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0005
17 | # Enabled: True, Severity: silent
18 | dotnet_diagnostic.IDE0005.severity = warning
19 |
20 | # IDE0005_gen: Using directive is unnecessary.
21 | # Enabled: True, Severity: silent
22 | dotnet_diagnostic.IDE0005_gen.severity = silent
23 |
24 | # IDE0007: Use implicit type
25 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0007
26 | # Enabled: True, Severity: silent
27 | dotnet_diagnostic.IDE0007.severity = warning
28 |
29 | # IDE0008: Use explicit type
30 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0008
31 | # Enabled: True, Severity: silent
32 | dotnet_diagnostic.IDE0008.severity = silent
33 |
34 | # IDE0009: Member access should be qualified.
35 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0009
36 | # Enabled: True, Severity: silent
37 | dotnet_diagnostic.IDE0009.severity = warning
38 |
39 | # IDE0010: Add missing cases
40 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0010
41 | # Enabled: True, Severity: silent
42 | dotnet_diagnostic.IDE0010.severity = suggestion
43 |
44 | # IDE0011: Add braces
45 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0011
46 | # Enabled: True, Severity: silent
47 | dotnet_diagnostic.IDE0011.severity = warning
48 |
49 | # IDE0016: Use 'throw' expression
50 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0016
51 | # Enabled: True, Severity: silent
52 | dotnet_diagnostic.IDE0016.severity = silent
53 |
54 | # IDE0017: Simplify object initialization
55 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0017
56 | # Enabled: True, Severity: silent
57 | dotnet_diagnostic.IDE0017.severity = suggestion
58 |
59 | # IDE0018: Inline variable declaration
60 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0018
61 | # Enabled: True, Severity: silent
62 | dotnet_diagnostic.IDE0018.severity = suggestion
63 |
64 | # IDE0019: Use pattern matching
65 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0019
66 | # Enabled: True, Severity: silent
67 | dotnet_diagnostic.IDE0019.severity = suggestion
68 |
69 | # IDE0020: Use pattern matching
70 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0020
71 | # Enabled: True, Severity: silent
72 | dotnet_diagnostic.IDE0020.severity = warning
73 |
74 | # IDE0021: Use expression body for constructor
75 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0021
76 | # Enabled: True, Severity: silent
77 | dotnet_diagnostic.IDE0021.severity = silent
78 |
79 | # IDE0022: Use expression body for method
80 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0022
81 | # Enabled: True, Severity: silent
82 | dotnet_diagnostic.IDE0022.severity = silent
83 |
84 | # IDE0023: Use expression body for conversion operator
85 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0023
86 | # Enabled: True, Severity: silent
87 | dotnet_diagnostic.IDE0023.severity = silent
88 |
89 | # IDE0024: Use expression body for operator
90 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0024
91 | # Enabled: True, Severity: silent
92 | dotnet_diagnostic.IDE0024.severity = silent
93 |
94 | # IDE0025: Use expression body for property
95 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0025
96 | # Enabled: True, Severity: silent
97 | dotnet_diagnostic.IDE0025.severity = silent
98 |
99 | # IDE0026: Use expression body for indexer
100 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0026
101 | # Enabled: True, Severity: silent
102 | dotnet_diagnostic.IDE0026.severity = silent
103 |
104 | # IDE0027: Use expression body for accessor
105 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0027
106 | # Enabled: True, Severity: silent
107 | dotnet_diagnostic.IDE0027.severity = silent
108 |
109 | # IDE0028: Simplify collection initialization
110 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0028
111 | # Enabled: True, Severity: silent
112 | dotnet_diagnostic.IDE0028.severity = suggestion
113 |
114 | # IDE0029: Use coalesce expression
115 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0029
116 | # Enabled: True, Severity: silent
117 | dotnet_diagnostic.IDE0029.severity = warning
118 |
119 | # IDE0030: Use coalesce expression
120 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0030
121 | # Enabled: True, Severity: silent
122 | dotnet_diagnostic.IDE0030.severity = warning
123 |
124 | # IDE0031: Use null propagation
125 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0031
126 | # Enabled: True, Severity: silent
127 | dotnet_diagnostic.IDE0031.severity = warning
128 |
129 | # IDE0032: Use auto property
130 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0032
131 | # Enabled: True, Severity: silent
132 | dotnet_diagnostic.IDE0032.severity = silent
133 |
134 | # IDE0033: Use explicitly provided tuple name
135 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0033
136 | # Enabled: True, Severity: silent
137 | dotnet_diagnostic.IDE0033.severity = suggestion
138 |
139 | # IDE0034: Simplify 'default' expression
140 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0034
141 | # Enabled: True, Severity: silent
142 | dotnet_diagnostic.IDE0034.severity = suggestion
143 |
144 | # IDE0035: Unreachable code detected
145 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0035
146 | # Enabled: True, Severity: silent
147 | dotnet_diagnostic.IDE0035.severity = none
148 |
149 | # IDE0036: Order modifiers
150 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0036
151 | # Enabled: True, Severity: silent
152 | dotnet_diagnostic.IDE0036.severity = warning
153 |
154 | # IDE0037: Use inferred member name
155 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0037
156 | # Enabled: True, Severity: silent
157 | dotnet_diagnostic.IDE0037.severity = none
158 |
159 | # IDE0039: Use local function
160 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0039
161 | # Enabled: True, Severity: silent
162 | dotnet_diagnostic.IDE0039.severity = suggestion
163 |
164 | # IDE0040: Add accessibility modifiers
165 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0040
166 | # Enabled: True, Severity: silent
167 | dotnet_diagnostic.IDE0040.severity = warning
168 |
169 | # IDE0041: Use 'is null' check
170 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0041
171 | # Enabled: True, Severity: silent
172 | dotnet_diagnostic.IDE0041.severity = silent
173 |
174 | # IDE0042: Deconstruct variable declaration
175 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0042
176 | # Enabled: True, Severity: silent
177 | dotnet_diagnostic.IDE0042.severity = silent
178 |
179 | # IDE0043: Invalid format string
180 | # Enabled: True, Severity: suggestion
181 | dotnet_diagnostic.IDE0043.severity = warning
182 |
183 | # IDE0044: Add readonly modifier
184 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0044
185 | # Enabled: True, Severity: silent
186 | dotnet_diagnostic.IDE0044.severity = warning
187 |
188 | # IDE0045: Convert to conditional expression
189 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0045
190 | # Enabled: True, Severity: silent
191 | dotnet_diagnostic.IDE0045.severity = suggestion
192 |
193 | # IDE0046: Convert to conditional expression
194 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0046
195 | # Enabled: True, Severity: silent
196 | dotnet_diagnostic.IDE0046.severity = suggestion
197 |
198 | # IDE0047: Remove unnecessary parentheses
199 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0047
200 | # Enabled: True, Severity: silent
201 | dotnet_diagnostic.IDE0047.severity = silent
202 |
203 | # IDE0048: Add parentheses for clarity
204 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0048
205 | # Enabled: True, Severity: silent
206 | dotnet_diagnostic.IDE0048.severity = silent
207 |
208 | # IDE0051: Remove unused private members
209 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0051
210 | # Enabled: True, Severity: silent
211 | dotnet_diagnostic.IDE0051.severity = suggestion
212 |
213 | # IDE0052: Remove unread private members
214 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0052
215 | # Enabled: True, Severity: silent
216 | dotnet_diagnostic.IDE0052.severity = suggestion
217 |
218 | # IDE0053: Use block body for lambda expression
219 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0053
220 | # Enabled: True, Severity: silent
221 | dotnet_diagnostic.IDE0053.severity = silent
222 |
223 | # IDE0053: Use expression body for lambda expression
224 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0053
225 | # Enabled: True, Severity: silent
226 | dotnet_diagnostic.IDE0053.severity = silent
227 |
228 | # IDE0054: Use compound assignment
229 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0054
230 | # Enabled: True, Severity: silent
231 | dotnet_diagnostic.IDE0054.severity = warning
232 |
233 | # IDE0055: Fix formatting
234 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0055
235 | # Enabled: True, Severity: silent
236 | dotnet_diagnostic.IDE0055.severity = warning
237 |
238 | # IDE0056: Use index operator
239 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0056
240 | # Enabled: True, Severity: silent
241 | dotnet_diagnostic.IDE0056.severity = suggestion
242 |
243 | # IDE0057: Use range operator
244 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0057
245 | # Enabled: True, Severity: silent
246 | dotnet_diagnostic.IDE0057.severity = suggestion
247 |
248 | # IDE0058: Expression value is never used
249 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0058
250 | # Enabled: True, Severity: silent
251 | dotnet_diagnostic.IDE0058.severity = silent
252 |
253 | # IDE0059: Unnecessary assignment of a value
254 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0059
255 | # Enabled: True, Severity: silent
256 | dotnet_diagnostic.IDE0059.severity = warning
257 |
258 | # IDE0060: Remove unused parameter
259 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0060
260 | # Enabled: True, Severity: silent
261 | dotnet_diagnostic.IDE0060.severity = suggestion
262 |
263 | # IDE0061: Use expression body for local function
264 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0061
265 | # Enabled: True, Severity: silent
266 | dotnet_diagnostic.IDE0061.severity = silent
267 |
268 | # IDE0062: Make local function 'static'
269 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0062
270 | # Enabled: True, Severity: silent
271 | dotnet_diagnostic.IDE0062.severity = warning
272 |
273 | # IDE0063: Use simple 'using' statement
274 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0063
275 | # Enabled: True, Severity: silent
276 | dotnet_diagnostic.IDE0063.severity = silent
277 |
278 | # IDE0064: Make readonly fields writable
279 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0064
280 | # Enabled: True, Severity: suggestion
281 | dotnet_diagnostic.IDE0064.severity = suggestion
282 |
283 | # IDE0065: Misplaced using directive
284 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0065
285 | # Enabled: True, Severity: silent
286 | dotnet_diagnostic.IDE0065.severity = warning
287 |
288 | # IDE0066: Convert switch statement to expression
289 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0066
290 | # Enabled: True, Severity: silent
291 | dotnet_diagnostic.IDE0066.severity = suggestion
292 |
293 | # IDE0070: Use 'System.HashCode'
294 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0070
295 | # Enabled: True, Severity: silent
296 | dotnet_diagnostic.IDE0070.severity = suggestion
297 |
298 | # IDE0071: Simplify interpolation
299 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0071
300 | # Enabled: True, Severity: silent
301 | dotnet_diagnostic.IDE0071.severity = warning
302 |
303 | # IDE0072: Add missing cases
304 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0072
305 | # Enabled: True, Severity: silent
306 | dotnet_diagnostic.IDE0072.severity = silent
307 |
308 | # IDE0073: The file header does not match the required text
309 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0073
310 | # Enabled: True, Severity: silent
311 | dotnet_diagnostic.IDE0073.severity = silent
312 |
313 | # IDE0073: The file header is missing or not located at the top of the file
314 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0073
315 | # Enabled: True, Severity: silent
316 | dotnet_diagnostic.IDE0073.severity = silent
317 |
318 | # IDE0074: Use compound assignment
319 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0074
320 | # Enabled: True, Severity: silent
321 | dotnet_diagnostic.IDE0074.severity = warning
322 |
323 | # IDE0075: Simplify conditional expression
324 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0075
325 | # Enabled: True, Severity: silent
326 | dotnet_diagnostic.IDE0075.severity = silent
327 |
328 | # IDE0076: Invalid global 'SuppressMessageAttribute'
329 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0076
330 | # Enabled: True, Severity: suggestion
331 | dotnet_diagnostic.IDE0076.severity = warning
332 |
333 | # IDE0077: Avoid legacy format target in 'SuppressMessageAttribute'
334 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0077
335 | # Enabled: True, Severity: suggestion
336 | dotnet_diagnostic.IDE0077.severity = none
337 |
338 | # IDE0078: Use pattern matching
339 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0078
340 | # Enabled: True, Severity: silent
341 | dotnet_diagnostic.IDE0078.severity = suggestion
342 |
343 | # IDE0079: Remove unnecessary suppression
344 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0079
345 | # Enabled: True, Severity: suggestion
346 | dotnet_diagnostic.IDE0079.severity = suggestion
347 |
348 | # IDE0080: Remove unnecessary suppression operator
349 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0080
350 | # Enabled: True, Severity: silent
351 | dotnet_diagnostic.IDE0080.severity = warning
352 |
353 | # IDE0082: 'typeof' can be converted to 'nameof'
354 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0082
355 | # Enabled: True, Severity: silent
356 | dotnet_diagnostic.IDE0082.severity = warning
357 |
358 | # IDE0083: Use pattern matching
359 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0083
360 | # Enabled: True, Severity: silent
361 | dotnet_diagnostic.IDE0083.severity = suggestion
362 |
363 | # IDE0090: Use 'new(...)'
364 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0090
365 | # Enabled: True, Severity: silent
366 | dotnet_diagnostic.IDE0090.severity = silent
367 |
368 | # IDE0100: Remove redundant equality
369 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0100
370 | # Enabled: True, Severity: silent
371 | dotnet_diagnostic.IDE0100.severity = suggestion
372 |
373 | # IDE0110: Remove unnecessary discard
374 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0110
375 | # Enabled: True, Severity: silent
376 | dotnet_diagnostic.IDE0110.severity = warning
377 |
378 | # IDE0120: Simplify LINQ expression
379 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0120
380 | # Enabled: True, Severity: silent
381 | dotnet_diagnostic.IDE0120.severity = silent
382 |
383 | # IDE0121: Simplify LINQ expression
384 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0121
385 | # Enabled: True, Severity: silent
386 | dotnet_diagnostic.IDE0121.severity = silent
387 |
388 | # IDE0130: Namespace does not match folder structure
389 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0130
390 | # Enabled: True, Severity: silent
391 | dotnet_diagnostic.IDE0130.severity = warning
392 |
393 | # IDE0150: Prefer 'null' check over type check
394 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0150
395 | # Enabled: True, Severity: silent
396 | dotnet_diagnostic.IDE0150.severity = silent
397 |
398 | # IDE0160: Convert to block scoped namespace
399 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0160
400 | # Enabled: True, Severity: silent
401 | dotnet_diagnostic.IDE0160.severity = none
402 |
403 | # IDE0161: Convert to file-scoped namespace
404 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0161
405 | # Enabled: True, Severity: silent
406 | dotnet_diagnostic.IDE0161.severity = warning
407 |
408 | # IDE0170: Property pattern can be simplified
409 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0170
410 | # Enabled: True, Severity: silent
411 | dotnet_diagnostic.IDE0170.severity = warning
412 |
413 | # IDE0180: Use tuple to swap values
414 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0180
415 | # Enabled: True, Severity: silent
416 | dotnet_diagnostic.IDE0180.severity = suggestion
417 |
418 | # IDE0200: Remove unnecessary lambda expression
419 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0200
420 | # Enabled: True, Severity: silent
421 | dotnet_diagnostic.IDE0200.severity = suggestion
422 |
423 | # IDE0210: Convert to top-level statements
424 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0210
425 | # Enabled: True, Severity: silent
426 | dotnet_diagnostic.IDE0210.severity = silent
427 |
428 | # IDE0211: Convert to 'Program.Main' style program
429 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0211
430 | # Enabled: True, Severity: silent
431 | dotnet_diagnostic.IDE0211.severity = silent
432 |
433 | # IDE0220: Add explicit cast
434 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0220
435 | # Enabled: True, Severity: silent
436 | dotnet_diagnostic.IDE0220.severity = silent
437 |
438 | # IDE0230: Use UTF-8 string literal
439 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0230
440 | # Enabled: True, Severity: silent
441 | dotnet_diagnostic.IDE0230.severity = suggestion
442 |
443 | # IDE0240: Remove redundant nullable directive
444 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0240
445 | # Enabled: True, Severity: silent
446 | dotnet_diagnostic.IDE0240.severity = suggestion
447 |
448 | # IDE0241: Remove unnecessary nullable directive
449 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0241
450 | # Enabled: True, Severity: silent
451 | dotnet_diagnostic.IDE0241.severity = suggestion
452 |
453 | # IDE0250: Make struct 'readonly'
454 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0250
455 | # Enabled: True, Severity: silent
456 | dotnet_diagnostic.IDE0250.severity = suggestion
457 |
458 | # IDE0251: Make member 'readonly'
459 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0251
460 | # Enabled: True, Severity: silent
461 | dotnet_diagnostic.IDE0251.severity = silent
462 |
463 | # IDE0260: Use pattern matching
464 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0260
465 | # Enabled: True, Severity: silent
466 | dotnet_diagnostic.IDE0260.severity = suggestion
467 |
468 | # IDE0270: Use coalesce expression
469 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0270
470 | # Enabled: True, Severity: silent
471 | dotnet_diagnostic.IDE0270.severity = suggestion
472 |
473 | # IDE0280: Use 'nameof'
474 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0280
475 | # Enabled: True, Severity: silent
476 | dotnet_diagnostic.IDE0280.severity = warning
477 |
478 | # IDE0290: Use primary constructor
479 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0290
480 | # Enabled: True, Severity: silent
481 | dotnet_diagnostic.IDE0290.severity = silent
482 |
483 | # IDE0300: Simplify collection initialization
484 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0300
485 | # Enabled: True, Severity: silent
486 | dotnet_diagnostic.IDE0300.severity = suggestion
487 |
488 | # IDE0301: Simplify collection initialization
489 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0301
490 | # Enabled: True, Severity: silent
491 | dotnet_diagnostic.IDE0301.severity = suggestion
492 |
493 | # IDE0302: Simplify collection initialization
494 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0302
495 | # Enabled: True, Severity: silent
496 | dotnet_diagnostic.IDE0302.severity = suggestion
497 |
498 | # IDE0303: Simplify collection initialization
499 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0303
500 | # Enabled: True, Severity: silent
501 | dotnet_diagnostic.IDE0303.severity = suggestion
502 |
503 | # IDE0304: Simplify collection initialization
504 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0304
505 | # Enabled: True, Severity: silent
506 | dotnet_diagnostic.IDE0304.severity = suggestion
507 |
508 | # IDE0305: Simplify collection initialization
509 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0305
510 | # Enabled: True, Severity: silent
511 | dotnet_diagnostic.IDE0305.severity = suggestion
512 |
513 | # IDE0306: Simplify collection initialization
514 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0306
515 | # Enabled: True, Severity: silent
516 | dotnet_diagnostic.IDE0306.severity = silent
517 |
518 | # IDE0320: Make anonymous function static
519 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0320
520 | # Enabled: True, Severity: silent
521 | dotnet_diagnostic.IDE0320.severity = silent
522 |
523 | # IDE0330: Use 'System.Threading.Lock'
524 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0330
525 | # Enabled: True, Severity: silent
526 | dotnet_diagnostic.IDE0330.severity = suggestion
527 |
528 | # IDE0340: Use unbound generic type
529 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0340
530 | # Enabled: True, Severity: silent
531 | dotnet_diagnostic.IDE0340.severity = silent
532 |
533 | # IDE0350: Use implicitly typed lambda
534 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0350
535 | # Enabled: True, Severity: silent
536 | dotnet_diagnostic.IDE0350.severity = silent
537 |
538 | # IDE1005: Delegate invocation can be simplified.
539 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide1005
540 | # Enabled: True, Severity: silent
541 | dotnet_diagnostic.IDE1005.severity = warning
542 |
543 | # IDE1006: Naming Styles
544 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide1006
545 | # Enabled: True, Severity: silent
546 | dotnet_diagnostic.IDE1006.severity = warning
547 |
548 | # IDE2000: Avoid multiple blank lines
549 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide2000
550 | # Enabled: True, Severity: silent
551 | dotnet_diagnostic.IDE2000.severity = warning
552 |
553 | # IDE2001: Embedded statements must be on their own line
554 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide2001
555 | # Enabled: True, Severity: silent
556 | dotnet_diagnostic.IDE2001.severity = warning
557 |
558 | # IDE2002: Consecutive braces must not have blank line between them
559 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide2002
560 | # Enabled: True, Severity: silent
561 | dotnet_diagnostic.IDE2002.severity = warning
562 |
563 | # IDE2003: Blank line required between block and subsequent statement
564 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide2003
565 | # Enabled: True, Severity: silent
566 | dotnet_diagnostic.IDE2003.severity = warning
567 |
568 | # IDE2004: Blank line not allowed after constructor initializer colon
569 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide2004
570 | # Enabled: True, Severity: silent
571 | dotnet_diagnostic.IDE2004.severity = warning
572 |
573 | # IDE2005: Blank line not allowed after conditional expression token
574 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide2005
575 | # Enabled: True, Severity: silent
576 | dotnet_diagnostic.IDE2005.severity = warning
577 |
578 | # IDE2006: Blank line not allowed after arrow expression clause token
579 | # Help link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide2006
580 | # Enabled: True, Severity: silent
581 | dotnet_diagnostic.IDE2006.severity = warning
582 |
583 | # RemoveUnnecessaryImportsFixable:
584 | # Enabled: True, Severity: silent
585 | dotnet_diagnostic.RemoveUnnecessaryImportsFixable.severity = silent
586 |
587 |
--------------------------------------------------------------------------------
/src/files/analyzers/manual_rules.editorconfig:
--------------------------------------------------------------------------------
1 | # These rules are not part of the generated rules.
2 | # The IDE rules in this file are only available in IDE, not in the build.
3 |
4 | # global_level must be higher than the NET Analyzer files
5 | is_global = true
6 | global_level = 0
7 |
8 | # CS1591: Missing XML comment for publicly visible type or member
9 | # Disabled because although XML documentation is enabled on the project, documenting everything is not always necessary
10 | dotnet_diagnostic.CS1591.severity = none
11 |
12 | # IDE0001: Simplify name (specifying a full type name is sometimes unnecessary)
13 | dotnet_diagnostic.IDE0001.severity = warning
14 |
15 | # IDE0002: Simplify member access (specifying a type name in a static invocation is sometimes unnecessary)
16 | dotnet_diagnostic.IDE0002.severity = suggestion
17 |
18 | # IDE0003: Remove this or Me qualification (enforce the use of 'this.')
19 | dotnet_diagnostic.IDE0003.severity = none
20 |
21 | # IDE0038: Use pattern matching to avoid is check followed by a cast (without variable)
22 | dotnet_diagnostic.IDE0038.severity = suggestion
23 |
24 | # IDE0049: Use language keywords instead of framework type names for type references
25 | dotnet_diagnostic.IDE0049.severity = warning
26 |
27 | # IDE0081: Remove unnecessary suppression operator
28 | dotnet_diagnostic.IDE0081.severity = none
29 |
30 | # IDE0084: Use pattern matching (IsNot operator)
31 | dotnet_diagnostic.IDE0084.severity = suggestion
32 |
33 | # IDE0140: Simplify object creation
34 | dotnet_diagnostic.IDE0140.severity = none
35 |
--------------------------------------------------------------------------------
/tests/Workleap.DotNet.CodingStandards.Tests/CodingStandardTests.cs:
--------------------------------------------------------------------------------
1 | using System.IO.Compression;
2 | using System.Reflection.PortableExecutable;
3 | using Workleap.DotNet.CodingStandards.Tests.Helpers;
4 | using Xunit.Abstractions;
5 |
6 | namespace Workleap.DotNet.CodingStandards.Tests;
7 |
8 | public sealed class CodingStandardTests(PackageFixture fixture, ITestOutputHelper testOutputHelper) : IClassFixture
9 | {
10 | [Fact]
11 | public async Task BannedSymbolsAreReported()
12 | {
13 | using var project = new ProjectBuilder(fixture, testOutputHelper);
14 | project.AddCsprojFile();
15 | project.AddFile("sample.cs", "_ = System.DateTime.Now;");
16 | var data = await project.BuildAndGetOutput();
17 | Assert.True(data.HasWarning("RS0030"));
18 | }
19 |
20 | [Fact]
21 | public async Task WarningsAsErrorOnGitHubActions()
22 | {
23 | using var project = new ProjectBuilder(fixture, testOutputHelper);
24 | project.AddCsprojFile();
25 | project.AddFile("sample.cs", "_ = System.DateTime.Now;");
26 | var data = await project.BuildAndGetOutput(["/p:GITHUB_ACTIONS=true"]);
27 | Assert.True(data.HasError("RS0030"));
28 | }
29 |
30 | [Fact]
31 | public async Task MSBuildWarningsAsErrorOnDefaultConfiguration()
32 | {
33 | using var project = new ProjectBuilder(fixture, testOutputHelper);
34 | project.AddCsprojFile(packageReferences: new Dictionary { { "Azure.Identity", "1.10.4" } });
35 | project.AddFile("sample.cs", """
36 | namespace sample;
37 | public static class Sample
38 | {
39 | public static void Main(string[] args)
40 | {
41 | }
42 | }
43 | """);
44 | var data = await project.BuildAndGetOutput();
45 | Assert.True(data.HasWarning("NU1902"));
46 | }
47 |
48 | [Fact]
49 | public async Task MSBuildWarningsAsErrorOnDebugConfiguration()
50 | {
51 | using var project = new ProjectBuilder(fixture, testOutputHelper);
52 | project.AddCsprojFile(packageReferences: new Dictionary { { "Azure.Identity", "1.10.4" } });
53 | project.AddFile("sample.cs", """
54 | namespace sample;
55 | public static class Sample
56 | {
57 | public static void Main(string[] args)
58 | {
59 | }
60 | }
61 | """);
62 | var data = await project.BuildAndGetOutput(["--configuration", "Debug"]);
63 | Assert.True(data.HasWarning("NU1902"));
64 | }
65 |
66 | [Fact]
67 | public async Task MSBuildWarningsAsErrorOnReleaseConfiguration()
68 | {
69 | using var project = new ProjectBuilder(fixture, testOutputHelper);
70 | project.AddCsprojFile(packageReferences: new Dictionary { { "Azure.Identity", "1.10.4" } });
71 | project.AddFile("sample.cs", """
72 | namespace sample;
73 | public static class Sample
74 | {
75 | public static void Main(string[] args)
76 | {
77 | }
78 | }
79 | """);
80 | var data = await project.BuildAndGetOutput(["--configuration", "Release"]);
81 | Assert.True(data.HasError("NU1902"));
82 | }
83 |
84 | [Fact]
85 | public async Task NamingConvention_Invalid()
86 | {
87 | using var project = new ProjectBuilder(fixture, testOutputHelper);
88 | project.AddCsprojFile();
89 | project.AddFile("sample.cs", """
90 | _ = "";
91 |
92 | class Sample
93 | {
94 | private readonly int field;
95 |
96 | public Sample(int a) => field = a;
97 |
98 | public int A() => field;
99 | }
100 | """);
101 | var data = await project.BuildAndGetOutput(["--configuration", "Release"]);
102 | Assert.True(data.HasError("IDE1006"));
103 | }
104 |
105 | [Fact]
106 | public async Task NamingConvention_Valid()
107 | {
108 | using var project = new ProjectBuilder(fixture, testOutputHelper);
109 | project.AddCsprojFile();
110 | project.AddFile("sample.cs", """
111 | _ = "";
112 |
113 | class Sample
114 | {
115 | private int _field;
116 | }
117 | """);
118 | var data = await project.BuildAndGetOutput(["--configuration", "Release"]);
119 | Assert.False(data.HasError("IDE1006"));
120 | Assert.False(data.HasWarning("IDE1006"));
121 | }
122 |
123 | [Fact]
124 | public async Task ReportVulnerablePackage_Release_ShouldReportError()
125 | {
126 | using var project = new ProjectBuilder(fixture, testOutputHelper);
127 | project.AddCsprojFile(packageReferences: new Dictionary { { "System.Text.Json", "8.0.1" } });
128 | project.AddFile("sample.cs", """
129 | Console.WriteLine();
130 | """);
131 | var data = await project.BuildAndGetOutput(["--configuration", "Release"]);
132 | Assert.True(data.HasError("NU1903"));
133 | }
134 |
135 | [Fact]
136 | public async Task ReportVulnerablePackage_Debug_ShouldReportWarning()
137 | {
138 | using var project = new ProjectBuilder(fixture, testOutputHelper);
139 | project.AddCsprojFile(packageReferences: new Dictionary { { "System.Text.Json", "8.0.1" } });
140 | project.AddFile("sample.cs", """
141 | Console.WriteLine();
142 | """);
143 | var data = await project.BuildAndGetOutput(["--configuration", "Debug"]);
144 | Assert.False(data.HasError("NU1903"));
145 | Assert.True(data.HasWarning("NU1903"));
146 | }
147 |
148 | [Fact]
149 | public async Task ReportVulnerablePackage_DisabledWarningOnPackage()
150 | {
151 | using var project = new ProjectBuilder(fixture, testOutputHelper);
152 | project.AddFile("test.csproj", $"""
153 |
154 |
155 | exe
156 | net$(NETCoreAppMaximumVersion)
157 | enable
158 | enable
159 | {ProjectBuilder.SarifFileName},version=2.1
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 | """);
168 |
169 | project.AddFile("sample.cs", """
170 | Console.WriteLine();
171 | """);
172 | var data = await project.BuildAndGetOutput(["--configuration", "Release"]);
173 | Assert.False(data.HasError("NU1903"));
174 | Assert.False(data.HasWarning("NU1903"));
175 | }
176 |
177 | [Fact]
178 | public async Task PdbShouldBeEmbedded_Dotnet_Build()
179 | {
180 | using var project = new ProjectBuilder(fixture, testOutputHelper);
181 | project.AddFile("test.csproj", $"""
182 |
183 |
184 | net8.0
185 | enable
186 | enable
187 | {ProjectBuilder.SarifFileName},version=2.1
188 | Foo
189 |
190 |
191 |
192 |
193 |
194 |
195 | """);
196 |
197 | project.AddFile("Sample.cs", """
198 | namespace Foo;
199 | public static class Sample { }
200 | """);
201 | var data = await project.BuildAndGetOutput(["--configuration", "Release"]);
202 |
203 | var outputFiles = Directory.GetFiles(Path.Combine(project.RootFolder, "bin", "Release", "net8.0"));
204 | await AssertPdbIsEmbedded(outputFiles);
205 | }
206 |
207 | [Fact]
208 | public async Task PdbShouldBeEmbedded_Dotnet_Pack()
209 | {
210 | using var project = new ProjectBuilder(fixture, testOutputHelper);
211 | project.AddFile("test.csproj", $"""
212 |
213 |
214 | net8.0
215 | enable
216 | enable
217 | {ProjectBuilder.SarifFileName},version=2.1
218 | Foo
219 |
220 |
221 |
222 |
223 |
224 |
225 | """);
226 |
227 | project.AddFile("Sample.cs", """
228 | namespace Foo;
229 | public static class Sample { }
230 | """);
231 | var data = await project.PackAndGetOutput(["--configuration", "Release"]);
232 |
233 | var extractedPath = Path.Combine(project.RootFolder, "extracted");
234 | var files = Directory.GetFiles(Path.Combine(project.RootFolder, "bin", "Release"));
235 | Assert.Single(files); // Only the .nupkg should be generated
236 | var nupkg = files.Single(f => f.EndsWith(".nupkg", StringComparison.OrdinalIgnoreCase));
237 | ZipFile.ExtractToDirectory(nupkg, extractedPath);
238 |
239 | var outputFiles = Directory.GetFiles(extractedPath, "*", SearchOption.AllDirectories);
240 | await AssertPdbIsEmbedded(outputFiles);
241 | }
242 |
243 | private static async Task AssertPdbIsEmbedded(string[] outputFiles)
244 | {
245 | Assert.DoesNotContain(outputFiles, f => f.EndsWith(".pdb", StringComparison.OrdinalIgnoreCase));
246 | var dllPath = outputFiles.Single(f => f.EndsWith(".dll", StringComparison.OrdinalIgnoreCase));
247 | await using var stream = File.OpenRead(dllPath);
248 | var peReader = new PEReader(stream);
249 | var debug = peReader.ReadDebugDirectory();
250 | Assert.Contains(debug, entry => entry.Type == DebugDirectoryEntryType.EmbeddedPortablePdb);
251 | }
252 | }
253 |
--------------------------------------------------------------------------------
/tests/Workleap.DotNet.CodingStandards.Tests/Helpers/PathHelpers.cs:
--------------------------------------------------------------------------------
1 | namespace Workleap.DotNet.CodingStandards.Tests.Helpers;
2 |
3 | internal static class PathHelpers
4 | {
5 | public static string GetRootDirectory()
6 | {
7 | var directory = Environment.CurrentDirectory;
8 | while (directory != null && !Directory.Exists(Path.Combine(directory, ".git")))
9 | {
10 | directory = Path.GetDirectoryName(directory);
11 | }
12 |
13 | return directory ?? throw new InvalidOperationException("Cannot find the root of the git repository");
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/tests/Workleap.DotNet.CodingStandards.Tests/Helpers/ProjectBuilder.cs:
--------------------------------------------------------------------------------
1 | using System.Xml.Linq;
2 | using Xunit.Abstractions;
3 | using System.Text.Json;
4 | using CliWrap;
5 | using Xunit.Sdk;
6 |
7 | namespace Workleap.DotNet.CodingStandards.Tests.Helpers;
8 |
9 | internal sealed class ProjectBuilder : IDisposable
10 | {
11 | public const string SarifFileName = "BuildOutput.sarif";
12 |
13 | private readonly TemporaryDirectory _directory;
14 | private readonly ITestOutputHelper _testOutputHelper;
15 |
16 | public string RootFolder => this._directory.FullPath;
17 |
18 | public ProjectBuilder(PackageFixture fixture, ITestOutputHelper testOutputHelper)
19 | {
20 | this._testOutputHelper = testOutputHelper;
21 |
22 | this._directory = TemporaryDirectory.Create();
23 | this._directory.CreateTextFile("NuGet.config", $"""
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 | """);
43 |
44 | File.Copy(Path.Combine(PathHelpers.GetRootDirectory(), "global.json"), this._directory.GetPath("global.json"));
45 | }
46 |
47 | public void AddFile(string relativePath, string content)
48 | {
49 | File.WriteAllText(this._directory.GetPath(relativePath), content);
50 | }
51 |
52 | public void AddCsprojFile(Dictionary? properties = null, Dictionary? packageReferences = null)
53 | {
54 | var propertyElement = new XElement("PropertyGroup");
55 | if (properties != null)
56 | {
57 | foreach (var prop in properties)
58 | {
59 | propertyElement.Add(new XElement(prop.Key), prop.Value);
60 | }
61 | }
62 |
63 | var referencesElement = new XElement("ItemGroup");
64 | if (packageReferences != null)
65 | {
66 | foreach (var reference in packageReferences)
67 | {
68 | var packageReference = new XElement("PackageReference");
69 | packageReference.SetAttributeValue("Include", reference.Key);
70 | packageReference.SetAttributeValue("Version", reference.Value);
71 |
72 | referencesElement.Add(packageReference);
73 | }
74 | }
75 |
76 | var content = $"""
77 |
78 |
79 | exe
80 | net$(NETCoreAppMaximumVersion)
81 | enable
82 | enable
83 | {SarifFileName},version=2.1
84 |
85 | {propertyElement}
86 |
87 |
88 |
89 |
90 | {referencesElement}
91 |
92 | """;
93 |
94 | File.WriteAllText(this._directory.GetPath("test.csproj"), content);
95 | }
96 |
97 | public Task BuildAndGetOutput(string[]? buildArguments = null)
98 | {
99 | return this.ExecuteDotnetCommandAndGetOutput("build", buildArguments);
100 | }
101 |
102 | public Task PackAndGetOutput(string[]? buildArguments = null)
103 | {
104 | return this.ExecuteDotnetCommandAndGetOutput("pack", buildArguments);
105 | }
106 |
107 | private async Task ExecuteDotnetCommandAndGetOutput(string command, string[]? buildArguments = null)
108 | {
109 | var result = await Cli.Wrap("dotnet")
110 | .WithWorkingDirectory(this._directory.FullPath)
111 | .WithArguments([command, .. (buildArguments ?? [])])
112 | .WithEnvironmentVariables(env => env.Set("CI", null).Set("GITHUB_ACTIONS", null))
113 | .WithStandardOutputPipe(PipeTarget.ToDelegate(this._testOutputHelper.WriteLine))
114 | .WithStandardErrorPipe(PipeTarget.ToDelegate(this._testOutputHelper.WriteLine))
115 | .WithValidation(CommandResultValidation.None)
116 | .ExecuteAsync();
117 |
118 | this._testOutputHelper.WriteLine("Process exit code: " + result.ExitCode);
119 |
120 | var bytes = await File.ReadAllBytesAsync(this._directory.GetPath(SarifFileName));
121 | var sarif = JsonSerializer.Deserialize(bytes) ?? throw new InvalidOperationException("The sarif file is invalid");
122 |
123 | this.AppendAdditionalResult(sarif);
124 |
125 | this._testOutputHelper.WriteLine("Sarif result:\n" + string.Join("\n", sarif.AllResults().Select(r => r.ToString())));
126 | return sarif;
127 | }
128 |
129 | public void Dispose() => this._directory.Dispose();
130 |
131 | private void AppendAdditionalResult(SarifFile sarifFile)
132 | {
133 | if (this._testOutputHelper is not TestOutputHelper testOutputHelper || sarifFile.Runs == null)
134 | {
135 | return;
136 | }
137 |
138 | var outputLines = testOutputHelper.Output.Split(Environment.NewLine);
139 | var customRunResults = new List();
140 |
141 | // These rules (for nuget package vulnerability) are not parsed in the sarif file automatically
142 | // See https://learn.microsoft.com/en-us/nuget/reference/errors-and-warnings/nu1901-nu1904
143 | var scannedRules = new List { "NU1901", "NU1902", "NU1903", "NU1904" }
144 | .ToDictionary(x => x, x => $"{x}:");
145 |
146 | foreach (var outputLine in outputLines)
147 | {
148 | foreach (var scannedRule in scannedRules)
149 | {
150 | var scannedRuleIndex = outputLine.IndexOf(scannedRule.Value, StringComparison.OrdinalIgnoreCase);
151 | if (scannedRuleIndex == -1)
152 | {
153 | continue;
154 | }
155 |
156 | var previousColonIndex = outputLine.LastIndexOf(':', scannedRuleIndex);
157 | var ruleLevel = outputLine.Substring(previousColonIndex + 1, scannedRuleIndex - previousColonIndex - 1).Trim();
158 |
159 | var message = outputLine[(scannedRuleIndex + scannedRule.Value.Length + 1)..];
160 | customRunResults.Add(new SarifFileRunResult { Level = ruleLevel, RuleId = scannedRule.Key, Message = new SarifFileRunResultMessage { Text = message } });
161 | }
162 | }
163 |
164 | var distinctRules = customRunResults
165 | .DistinctBy(x => new { x.RuleId, x.Level })
166 | .ToArray();
167 |
168 | sarifFile.Runs = sarifFile.Runs.Append(new SarifFileRun { Results = distinctRules }).ToArray();
169 | }
170 | }
171 |
--------------------------------------------------------------------------------
/tests/Workleap.DotNet.CodingStandards.Tests/Helpers/SarifFile.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json.Serialization;
2 |
3 | namespace Workleap.DotNet.CodingStandards.Tests.Helpers;
4 |
5 | internal sealed class SarifFile
6 | {
7 | [JsonPropertyName("runs")]
8 | public SarifFileRun[]? Runs { get; set; }
9 |
10 | public IEnumerable AllResults() => this.Runs?.SelectMany(r => r.Results ?? []) ?? [];
11 |
12 | public bool HasError() => this.AllResults().Any(r => r.Level == "error");
13 | public bool HasError(string ruleId) => this.AllResults().Any(r => r.Level == "error" && r.RuleId == ruleId);
14 | public bool HasWarning(string ruleId) => this.AllResults().Any(r => r.Level == "warning" && r.RuleId == ruleId);
15 | public bool HasNote(string ruleId) => this.AllResults().Any(r => r.Level == "note" && r.RuleId == ruleId);
16 | }
17 |
--------------------------------------------------------------------------------
/tests/Workleap.DotNet.CodingStandards.Tests/Helpers/SarifFileRun.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json.Serialization;
2 |
3 | namespace Workleap.DotNet.CodingStandards.Tests.Helpers;
4 |
5 | internal sealed class SarifFileRun
6 | {
7 | [JsonPropertyName("results")]
8 | public SarifFileRunResult[]? Results { get; set; }
9 | }
10 |
--------------------------------------------------------------------------------
/tests/Workleap.DotNet.CodingStandards.Tests/Helpers/SarifFileRunResult.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json.Serialization;
2 |
3 | namespace Workleap.DotNet.CodingStandards.Tests.Helpers;
4 |
5 | internal sealed class SarifFileRunResult
6 | {
7 | [JsonPropertyName("ruleId")]
8 | public string? RuleId { get; set; }
9 |
10 | [JsonPropertyName("level")]
11 | public string? Level { get; set; }
12 |
13 | [JsonPropertyName("message")]
14 | public SarifFileRunResultMessage? Message { get; set; }
15 |
16 | public override string ToString()
17 | {
18 | return $"{this.Level}:{this.RuleId} {this.Message}";
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/tests/Workleap.DotNet.CodingStandards.Tests/Helpers/SarifFileRunResultMessage.cs:
--------------------------------------------------------------------------------
1 | using System.Text.Json.Serialization;
2 |
3 | namespace Workleap.DotNet.CodingStandards.Tests.Helpers;
4 |
5 | internal sealed class SarifFileRunResultMessage
6 | {
7 | [JsonPropertyName("text")]
8 | public string? Text { get; set; }
9 |
10 | public override string ToString()
11 | {
12 | return this.Text ?? "";
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/tests/Workleap.DotNet.CodingStandards.Tests/Helpers/SharedHttpClient.cs:
--------------------------------------------------------------------------------
1 | namespace Workleap.DotNet.CodingStandards.Tests.Helpers;
2 | internal static class SharedHttpClient
3 | {
4 | public static HttpClient Instance { get; } = CreateHttpClient();
5 |
6 | private static HttpClient CreateHttpClient()
7 | {
8 | var socketHandler = new SocketsHttpHandler()
9 | {
10 | PooledConnectionIdleTimeout = TimeSpan.FromMinutes(1),
11 | PooledConnectionLifetime = TimeSpan.FromMinutes(1),
12 | };
13 |
14 | return new HttpClient(new HttpRetryMessageHandler(socketHandler), disposeHandler: true);
15 | }
16 | private sealed class HttpRetryMessageHandler(HttpMessageHandler handler) : DelegatingHandler(handler)
17 | {
18 | protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
19 | {
20 | const int maxRetries = 5;
21 | var defaultDelay = TimeSpan.FromMilliseconds(200);
22 | for (var i = 1; ; i++, defaultDelay *= 2)
23 | {
24 | TimeSpan? delayHint = null;
25 | HttpResponseMessage? result = null;
26 |
27 | try
28 | {
29 | result = await base.SendAsync(request, cancellationToken).ConfigureAwait(false);
30 | if (!IsLastAttempt(i) && ((int)result.StatusCode >= 500 || result.StatusCode is System.Net.HttpStatusCode.RequestTimeout or System.Net.HttpStatusCode.TooManyRequests))
31 | {
32 | // Use "Retry-After" value, if available. Typically, this is sent with
33 | // either a 503 (Service Unavailable) or 429 (Too Many Requests):
34 | // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After
35 |
36 | delayHint = result.Headers.RetryAfter switch
37 | {
38 | { Date: { } date } => date - DateTimeOffset.UtcNow,
39 | { Delta: { } delta } => delta,
40 | _ => null,
41 | };
42 |
43 | result.Dispose();
44 | }
45 | else
46 | {
47 | return result;
48 | }
49 | }
50 | catch (HttpRequestException)
51 | {
52 | result?.Dispose();
53 | if (IsLastAttempt(i))
54 | {
55 | throw;
56 | }
57 | }
58 | catch (TaskCanceledException ex) when (ex.CancellationToken != cancellationToken) // catch "The request was canceled due to the configured HttpClient.Timeout of 100 seconds elapsing"
59 | {
60 | result?.Dispose();
61 | if (IsLastAttempt(i))
62 | {
63 | throw;
64 | }
65 | }
66 |
67 | await Task.Delay(delayHint is { } someDelay && someDelay > TimeSpan.Zero ? someDelay : defaultDelay, cancellationToken).ConfigureAwait(false);
68 |
69 | static bool IsLastAttempt(int i) => i >= maxRetries;
70 | }
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/tests/Workleap.DotNet.CodingStandards.Tests/Helpers/TemporaryDirectory.cs:
--------------------------------------------------------------------------------
1 | namespace Workleap.DotNet.CodingStandards.Tests.Helpers;
2 |
3 | internal sealed class TemporaryDirectory : IDisposable
4 | {
5 | private TemporaryDirectory(string fullPath) => this.FullPath = fullPath;
6 |
7 | public string FullPath { get; }
8 |
9 | public static TemporaryDirectory Create()
10 | {
11 | var path = Path.GetFullPath(Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N")));
12 | _ = Directory.CreateDirectory(path);
13 | return new TemporaryDirectory(path);
14 | }
15 |
16 | public string GetPath(string relativePath)
17 | {
18 | return Path.Combine(this.FullPath, relativePath);
19 | }
20 |
21 | public void CreateTextFile(string relativePath, string content)
22 | {
23 | var path = this.GetPath(relativePath);
24 | _ = Directory.CreateDirectory(Path.GetDirectoryName(path)!);
25 | File.WriteAllText(path, content);
26 | }
27 |
28 | public void Dispose()
29 | {
30 | try
31 | {
32 | Directory.Delete(this.FullPath, recursive: true);
33 | }
34 | catch
35 | {
36 | // We use this code in tests, so it's not important if a folder cannot be deleted
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/tests/Workleap.DotNet.CodingStandards.Tests/PackageFixture.cs:
--------------------------------------------------------------------------------
1 | using CliWrap;
2 | using CliWrap.Buffered;
3 | using Workleap.DotNet.CodingStandards.Tests.Helpers;
4 |
5 | namespace Workleap.DotNet.CodingStandards.Tests;
6 |
7 | public sealed class PackageFixture : IAsyncLifetime
8 | {
9 | private readonly TemporaryDirectory _packageDirectory = TemporaryDirectory.Create();
10 |
11 | public string PackageDirectory => this._packageDirectory.FullPath;
12 |
13 | public async Task InitializeAsync()
14 | {
15 | var nuspecPath = Path.Combine(PathHelpers.GetRootDirectory(), "Workleap.DotNet.CodingStandards.nuspec");
16 | string[] args = ["pack", nuspecPath, "-ForceEnglishOutput", "-Version", "999.9.9", "-OutputDirectory", this._packageDirectory.FullPath];
17 |
18 | if (OperatingSystem.IsWindows())
19 | {
20 | var exe = Path.Combine(Path.GetTempPath(), $"nuget-{Guid.NewGuid()}.exe");
21 | await DownloadFileAsync("https://dist.nuget.org/win-x86-commandline/latest/nuget.exe", exe);
22 |
23 | _ = await Cli.Wrap(exe)
24 | .WithArguments(args)
25 | .ExecuteAsync();
26 | }
27 | else
28 | {
29 | _ = await Cli.Wrap("nuget")
30 | .WithArguments(args)
31 | .ExecuteBufferedAsync();
32 | }
33 | }
34 |
35 | public Task DisposeAsync()
36 | {
37 | this._packageDirectory.Dispose();
38 | return Task.CompletedTask;
39 | }
40 |
41 | private static async Task DownloadFileAsync(string url, string path)
42 | {
43 | _ = Directory.CreateDirectory(Path.GetDirectoryName(path)!);
44 | await using var nugetStream = await SharedHttpClient.Instance.GetStreamAsync(url);
45 | await using var fileStream = File.Create(path);
46 | await nugetStream.CopyToAsync(fileStream);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/tests/Workleap.DotNet.CodingStandards.Tests/Workleap.DotNet.CodingStandards.Tests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net8.0
5 | false
6 | true
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | all
15 | runtime; build; native; contentfiles; analyzers; buildtransitive
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/tools/ConfigurationFilesGenerator/ConfigurationFilesGenerator.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net9.0
6 | enable
7 | enable
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/tools/ConfigurationFilesGenerator/Program.cs:
--------------------------------------------------------------------------------
1 | #pragma warning disable IDE0058 // Expression value is never used
2 | #pragma warning disable SA1649 // File name should match first type name
3 | using System.Globalization;
4 | using System.Runtime.Loader;
5 | using System.Xml.Linq;
6 | using Meziantou.Framework;
7 | using Microsoft.CodeAnalysis;
8 | using Microsoft.CodeAnalysis.Diagnostics;
9 | using NuGet.Common;
10 | using NuGet.Configuration;
11 | using NuGet.Packaging.Core;
12 | using NuGet.Packaging.Signing;
13 | using NuGet.Protocol.Core.Types;
14 | using NuGet.Protocol;
15 | using NuGet.Versioning;
16 | using System.Reflection;
17 | using System.Text;
18 | using System.Text.RegularExpressions;
19 | using NuGet.Frameworks;
20 |
21 | var rootFolder = GetRootFolderPath();
22 |
23 | var writtenFiles = 0;
24 | var packages = await GetAllReferencedNuGetPackages();
25 | await Parallel.ForEachAsync(packages, async (item, cancellationToken) =>
26 | {
27 | var (packageId, packageVersion) = item;
28 |
29 | Console.WriteLine(packageId + "@" + packageVersion);
30 | var configurationFilePath = rootFolder / "src" / "files" / "analyzers" / ("Analyzer." + packageId + ".editorconfig");
31 |
32 | var rules = new HashSet();
33 | foreach (var assembly in await GetAnalyzerReferences(packageId, packageVersion))
34 | {
35 | foreach (var type in assembly.GetTypes())
36 | {
37 | if (type.IsAbstract || type.IsInterface || !typeof(DiagnosticAnalyzer).IsAssignableFrom(type))
38 | {
39 | continue;
40 | }
41 |
42 | var analyzer = (DiagnosticAnalyzer)Activator.CreateInstance(type)!;
43 | foreach (var diagnostic in analyzer.SupportedDiagnostics)
44 | {
45 | rules.Add(new AnalyzerRule(diagnostic.Id, diagnostic.Title.ToString(CultureInfo.InvariantCulture), diagnostic.HelpLinkUri, diagnostic.IsEnabledByDefault, diagnostic.DefaultSeverity, diagnostic.IsEnabledByDefault ? diagnostic.DefaultSeverity : null));
46 | }
47 | }
48 | }
49 |
50 | if (rules.Count > 0)
51 | {
52 | var sb = new StringBuilder();
53 | sb.AppendLine("# global_level must be higher than the NET Analyzer files");
54 | sb.AppendLine("is_global = true");
55 | sb.AppendLine("global_level = 0");
56 |
57 | var currentConfiguration = GetConfiguration(configurationFilePath);
58 |
59 | if (currentConfiguration.Unknowns.Length > 0)
60 | {
61 | foreach (var unknown in currentConfiguration.Unknowns)
62 | {
63 | sb.AppendLine(unknown);
64 | }
65 | }
66 | else
67 | {
68 | sb.AppendLine();
69 | }
70 |
71 | foreach (var rule in rules.OrderBy(rule => rule.Id).ThenBy(rule => rule.Title))
72 | {
73 | var currentRuleConfiguration = currentConfiguration.Rules.FirstOrDefault(r => r.Id == rule.Id);
74 | var severity = currentRuleConfiguration != null ? currentRuleConfiguration.Severity : rule.DefaultEffectiveSeverity;
75 |
76 | sb.AppendLine($"# {rule.Id}: {rule.Title?.TrimEnd()}".TrimEnd());
77 | if (!string.IsNullOrEmpty(rule.Url))
78 | {
79 | sb.AppendLine($"# Help link: {rule.Url?.TrimEnd()}");
80 | }
81 |
82 | sb.AppendLine($"# Enabled: {rule.Enabled}, Severity: {GetSeverity(rule.DefaultSeverity)}");
83 |
84 | if (currentRuleConfiguration?.Comments.Length > 0)
85 | {
86 | foreach (var comment in currentRuleConfiguration.Comments)
87 | {
88 | sb.AppendLine(comment);
89 | }
90 | }
91 |
92 | sb.AppendLine($"dotnet_diagnostic.{rule.Id}.severity = {GetSeverity(severity)}");
93 | sb.AppendLine();
94 | }
95 |
96 | var text = sb.ToString().ReplaceLineEndings("\n");
97 |
98 | if (File.Exists(configurationFilePath))
99 | {
100 | if ((await File.ReadAllTextAsync(configurationFilePath, cancellationToken)).ReplaceLineEndings("\n") == text)
101 | {
102 | return;
103 | }
104 | }
105 |
106 | configurationFilePath.CreateParentDirectory();
107 | await File.WriteAllTextAsync(configurationFilePath, text, cancellationToken);
108 | _ = Interlocked.Increment(ref writtenFiles);
109 |
110 | static string GetSeverity(DiagnosticSeverity? severity)
111 | {
112 | return severity switch
113 | {
114 | null => "none",
115 | DiagnosticSeverity.Hidden => "silent",
116 | DiagnosticSeverity.Info => "suggestion",
117 | DiagnosticSeverity.Warning => "warning",
118 | DiagnosticSeverity.Error => "error",
119 | _ => throw new Exception($"Severity '{severity}' is not supported"),
120 | };
121 | }
122 | }
123 | });
124 |
125 | if (writtenFiles > 0)
126 | {
127 | await Console.Error.WriteLineAsync("The content of the .editorconfig files is out of date. If this occurs on CI, you need to run the Build.ps1 command on your machine and commit the new .editorconfig files.");
128 | }
129 |
130 | return writtenFiles;
131 |
132 | async Task<(string Id, NuGetVersion Version)[]> GetAllReferencedNuGetPackages()
133 | {
134 | var foundPackages = new HashSet();
135 |
136 | var cache = new SourceCacheContext();
137 | var repository = Repository.Factory.GetCoreV3("https://api.nuget.org/v3/index.json");
138 | var resource = await repository.GetResourceAsync();
139 |
140 | foreach (var package in GetReferencedNuGetPackages())
141 | {
142 | // Find the latest version if no version is specified
143 | var version = package.Version is null ? null : NuGetVersion.Parse(package.Version);
144 | if (version is null)
145 | {
146 | var metadata = await resource.GetMetadataAsync(package.Id, includePrerelease: false, includeUnlisted: false, cache, NullLogger.Instance, CancellationToken.None);
147 | version = metadata.MaxBy(metadata => metadata.Identity.Version)!.Identity.Version;
148 | }
149 |
150 | var packageIdentity = new PackageIdentity(package.Id, version);
151 | await ListAllPackageDependencies(packageIdentity, [repository], NuGetFramework.AnyFramework, cache, NullLogger.Instance, foundPackages, CancellationToken.None);
152 | }
153 |
154 | return foundPackages.Select(p => (p.Id, p.Version)).ToArray();
155 |
156 | static async Task ListAllPackageDependencies(
157 | PackageIdentity package,
158 | IEnumerable repositories,
159 | NuGetFramework framework,
160 | SourceCacheContext cache,
161 | ILogger logger,
162 | HashSet dependencies,
163 | CancellationToken cancellationToken)
164 | {
165 | if (dependencies.Contains(package))
166 | {
167 | return;
168 | }
169 |
170 | foreach (var repository in repositories)
171 | {
172 | var dependencyInfoResource = await repository.GetResourceAsync();
173 | var dependencyInfo = await dependencyInfoResource.ResolvePackage(package, framework, cache, logger, cancellationToken);
174 |
175 | if (dependencyInfo == null)
176 | {
177 | continue;
178 | }
179 |
180 | if (dependencies.Add(dependencyInfo))
181 | {
182 | foreach (var dependency in dependencyInfo.Dependencies)
183 | {
184 | await ListAllPackageDependencies(
185 | new PackageIdentity(dependency.Id, dependency.VersionRange.MinVersion),
186 | repositories,
187 | framework,
188 | cache,
189 | logger,
190 | dependencies,
191 | cancellationToken);
192 | }
193 | }
194 | }
195 | }
196 | }
197 |
198 | IEnumerable<(string Id, string? Version)> GetReferencedNuGetPackages()
199 | {
200 | foreach (var nuspecPath in Directory.GetFiles(rootFolder, "*.nuspec"))
201 | {
202 | var document = XDocument.Load(nuspecPath);
203 | var ns = document.Root!.Name.Namespace;
204 | foreach (var value in document.Descendants(ns + "dependency").Select(node => (node.Attribute("id")!.Value, node.Attribute("version")!.Value)))
205 | {
206 | yield return value;
207 | }
208 | }
209 |
210 | // Add analyzers from the .NET SDK
211 | foreach (var package in new[] { "Microsoft.CodeAnalysis.NetAnalyzers", "Microsoft.CodeAnalysis.CSharp.CodeStyle" })
212 | {
213 | yield return (package, null);
214 | }
215 | }
216 |
217 | static FullPath GetRootFolderPath()
218 | {
219 | var path = FullPath.CurrentDirectory();
220 | while (!path.IsEmpty)
221 | {
222 | if (Directory.Exists(path / ".git"))
223 | {
224 | return path;
225 | }
226 |
227 | path = path.Parent;
228 | }
229 |
230 | return !path.IsEmpty ? path : throw new InvalidOperationException("Cannot find the root folder");
231 | }
232 |
233 | static async Task GetAnalyzerReferences(string packageId, NuGetVersion version)
234 | {
235 | var logger = NullLogger.Instance;
236 | var cancellationToken = CancellationToken.None;
237 |
238 | var settings = Settings.LoadDefaultSettings(null);
239 | var globalPackagesFolder = SettingsUtility.GetGlobalPackagesFolder(settings);
240 | var source = "https://api.nuget.org/v3/index.json";
241 |
242 | var cache = new SourceCacheContext();
243 | var repository = Repository.Factory.GetCoreV3(source);
244 | var resource = await repository.GetResourceAsync();
245 |
246 | // Get the package from the global cache or download it
247 | var package = GlobalPackagesFolderUtility.GetPackage(new PackageIdentity(packageId, version), globalPackagesFolder);
248 | if (package is null || package.Status is DownloadResourceResultStatus.NotFound)
249 | {
250 | // Download the package
251 | using var packageStream = new MemoryStream();
252 | _ = await resource.CopyNupkgToStreamAsync(
253 | packageId,
254 | version,
255 | packageStream,
256 | cache,
257 | logger,
258 | cancellationToken);
259 |
260 | _ = packageStream.Seek(0, SeekOrigin.Begin);
261 |
262 | // Add it to the global package folder
263 | package = await GlobalPackagesFolderUtility.AddPackageAsync(
264 | source,
265 | new PackageIdentity(packageId, version),
266 | packageStream,
267 | globalPackagesFolder,
268 | parentId: Guid.Empty,
269 | ClientPolicyContext.GetClientPolicy(settings, logger),
270 | logger,
271 | cancellationToken);
272 | }
273 |
274 | // Load all analyzers DLLs from the NuGet packages
275 | var result = new List();
276 | var groups = package.PackageReader.GetFiles("analyzers").GroupBy(Path.GetDirectoryName).ToArray();
277 | foreach (var group in groups)
278 | {
279 | var context = new AssemblyLoadContext(null);
280 | foreach (var file in group)
281 | {
282 | try
283 | {
284 | using var stream = package.PackageReader.GetStream(file);
285 | result.Add(context.LoadFromStream(stream));
286 | }
287 | catch (Exception ex)
288 | {
289 | Console.WriteLine(ex);
290 | }
291 | }
292 | }
293 |
294 | return [.. result];
295 | }
296 |
297 | static (AnalyzerConfiguration[] Rules, string[] Unknowns) GetConfiguration(FullPath editorconfig)
298 | {
299 | var rules = new List();
300 | var unknowns = new List();
301 |
302 | var currentComment = new List();
303 | try
304 | {
305 | var lines = File.ReadAllLines(editorconfig);
306 |
307 | foreach (var line in lines)
308 | {
309 | try
310 | {
311 | if (line.StartsWith('#'))
312 | {
313 | if (line.StartsWith("# Enabled: ", StringComparison.Ordinal))
314 | {
315 | continue;
316 | }
317 |
318 | if (line.StartsWith("# Default severity: ", StringComparison.Ordinal))
319 | {
320 | continue;
321 | }
322 |
323 | if (line.StartsWith("# Help link: ", StringComparison.Ordinal))
324 | {
325 | continue;
326 | }
327 |
328 | currentComment.Add(line);
329 | continue;
330 | }
331 |
332 | if (line.StartsWith("is_global", StringComparison.Ordinal))
333 | {
334 | continue;
335 | }
336 |
337 | if (line.StartsWith("global_level", StringComparison.Ordinal))
338 | {
339 | continue;
340 | }
341 |
342 | var match = Regex.Match(line, @"^dotnet_diagnostic\.(?.+?).severity\s*=\s*(?[a-z]+)");
343 | if (match.Success)
344 | {
345 | DiagnosticSeverity? diagnosticSeverity = null;
346 | var severityValue = match.Groups["Severity"].Value;
347 | if (severityValue == "silent")
348 | {
349 | diagnosticSeverity = DiagnosticSeverity.Hidden;
350 | }
351 | else if (severityValue == "suggestion")
352 | {
353 | diagnosticSeverity = DiagnosticSeverity.Info;
354 | }
355 | else if (Enum.TryParse(severityValue, ignoreCase: true, out var severity))
356 | {
357 | diagnosticSeverity = severity;
358 | }
359 |
360 | rules.Add(new AnalyzerConfiguration(match.Groups["RuleId"].Value, currentComment.Skip(1).ToArray(), diagnosticSeverity));
361 | }
362 | else
363 | {
364 | foreach (var comment in currentComment)
365 | {
366 | unknowns.Add(comment);
367 | }
368 |
369 | if (rules.Count == 0 || !string.IsNullOrEmpty(line))
370 | {
371 | unknowns.Add(line);
372 | }
373 | }
374 | }
375 | finally
376 | {
377 | if (!line.StartsWith('#'))
378 | {
379 | currentComment.Clear();
380 | }
381 | }
382 | }
383 | }
384 | catch
385 | {
386 | }
387 |
388 | return (rules.ToArray(), unknowns.ToArray());
389 | }
390 |
391 | internal sealed record AnalyzerConfiguration(string Id, string[] Comments, DiagnosticSeverity? Severity);
392 |
393 | internal sealed record AnalyzerRule(string Id, string Title, string? Url, bool Enabled, DiagnosticSeverity DefaultSeverity, DiagnosticSeverity? DefaultEffectiveSeverity);
394 |
--------------------------------------------------------------------------------
/wl-dotnet-codingstandards.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.5.002.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{C1F5A879-3A26-4621-ADB7-3B1C59CBC8B3}"
7 | EndProject
8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Workleap.DotNet.CodingStandards.Tests", "tests\Workleap.DotNet.CodingStandards.Tests\Workleap.DotNet.CodingStandards.Tests.csproj", "{640037BA-49DF-4BBD-9858-3DC89E2739FD}"
9 | EndProject
10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConfigurationFilesGenerator", "tools\ConfigurationFilesGenerator\ConfigurationFilesGenerator.csproj", "{2A95B554-DB07-434B-82C3-8D056819DED4}"
11 | EndProject
12 | Global
13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
14 | Debug|Any CPU = Debug|Any CPU
15 | Release|Any CPU = Release|Any CPU
16 | EndGlobalSection
17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
18 | {640037BA-49DF-4BBD-9858-3DC89E2739FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
19 | {640037BA-49DF-4BBD-9858-3DC89E2739FD}.Debug|Any CPU.Build.0 = Debug|Any CPU
20 | {640037BA-49DF-4BBD-9858-3DC89E2739FD}.Release|Any CPU.ActiveCfg = Release|Any CPU
21 | {640037BA-49DF-4BBD-9858-3DC89E2739FD}.Release|Any CPU.Build.0 = Release|Any CPU
22 | {2A95B554-DB07-434B-82C3-8D056819DED4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
23 | {2A95B554-DB07-434B-82C3-8D056819DED4}.Debug|Any CPU.Build.0 = Debug|Any CPU
24 | {2A95B554-DB07-434B-82C3-8D056819DED4}.Release|Any CPU.ActiveCfg = Release|Any CPU
25 | {2A95B554-DB07-434B-82C3-8D056819DED4}.Release|Any CPU.Build.0 = Release|Any CPU
26 | EndGlobalSection
27 | GlobalSection(SolutionProperties) = preSolution
28 | HideSolutionNode = FALSE
29 | EndGlobalSection
30 | GlobalSection(NestedProjects) = preSolution
31 | {640037BA-49DF-4BBD-9858-3DC89E2739FD} = {C1F5A879-3A26-4621-ADB7-3B1C59CBC8B3}
32 | EndGlobalSection
33 | GlobalSection(ExtensibilityGlobals) = postSolution
34 | SolutionGuid = {18E64023-58E9-4BA2-BCE7-4BD5E1A023C1}
35 | EndGlobalSection
36 | EndGlobal
37 |
--------------------------------------------------------------------------------