commit 32c088f1e72d10cdf3087ae6cd4856327e3d8a00 Author: Louis Seubert Date: Fri Oct 23 23:23:08 2026 +0200 chore: squash repository history into a single commit diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..50baf47 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,20 @@ +root = true + +[*] +max_line_length = 120 +indent_style = tab +indent_size = 2 +tab_width = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true +file_header_template = Copyright (c) The Geekeey Authors\nSPDX-License-Identifier: EUPL-1.2 + +[*.md] +indent_style = space +trim_trailing_whitespace = false + +[*.yml] +indent_style = space +trim_trailing_whitespace = false diff --git a/.forgejo/workflows/ci.yml b/.forgejo/workflows/ci.yml new file mode 100644 index 0000000..056ec35 --- /dev/null +++ b/.forgejo/workflows/ci.yml @@ -0,0 +1,79 @@ +name: CI + +on: + push: + branches: [main] + tags: ['*'] + pull_request: + branches: [main] + +enable-openid-connect: true + +jobs: + build: + name: build + runs-on: debian-latest + container: mcr.microsoft.com/dotnet/sdk:10.0@sha256:0d99ebf1ccad15037b5c98c9fe8979d6b8dbac23812feae2277a0b277b5c5ffa + steps: + - name: checkout + uses: https://code.geekeey.de/actions/checkout@54953ce9d6c7d0a9cbd89d185c5b2c7515358c5f # 1 + + - name: dotnet pack + shell: bash + env: + TAG: ${{ forgejo.ref }} + TAG_NAME: ${{ forgejo.ref_name }} + run: | + set -euo pipefail + + if [[ "$TAG" == refs/tags/* ]]; then + version="${TAG_NAME#v}" + if ! printf '%s' "$version" | grep -Eq '^[0-9]+\.[0-9]+\.[0-9]+$'; then + echo "::error::Tag '$TAG_NAME' is not a valid release version (expected MAJOR.MINOR.PATCH)" + exit 1 + fi + export version + fi + + dotnet pack arcade.slnx + + - name: upload packages + uses: https://code.geekeey.de/actions/artifacts/push@ae8d20e174a8706675e6d54ebd3719a2802ea9dd # 1 + with: + name: nuget-packages + path: artifacts/package/release + pattern: | + *.nupkg + *.snupkg + + - name: dotnet test + run: dotnet test src/sdk.tests/Geekeey.Arcade.NET.Tests.csproj + + - name: publish to nuget + if: startsWith(forgejo.ref, 'refs/tags/') + shell: bash + env: + AUDIENCE: "u:1:00000000-0000-0000-0000-000000000000" + run: | + set -euo pipefail + + if [[ -z "${ACTIONS_ID_TOKEN_REQUEST_URL:-}" || -z "${ACTIONS_ID_TOKEN_REQUEST_TOKEN:-}" ]]; then + echo "::error::OpenID Connect is not enabled. Set enable-openid-connect: true on the workflow or job." + exit 1 + fi + + response=$(curl --fail --silent --show-error \ + --header "Authorization: bearer ${ACTIONS_ID_TOKEN_REQUEST_TOKEN}" "${ACTIONS_ID_TOKEN_REQUEST_URL}&audience=${AUDIENCE}") + token=$(printf '%s' "${response}" | grep --only-matching '"value":"[^"]*"' | cut --delimiter '"' --fields 4) + + if [[ -z "${token}" ]]; then + echo "::error::Failed to obtain an OpenID Connect token from Forgejo." + exit 1 + fi + + echo "::add-mask::${token}" + + feed="${{ forgejo.server_url }}/api/packages/${{ forgejo.repository_owner }}/nuget/index.json" + + dotnet nuget add source --name forgejo --username forgejo-publish --password "$token" --store-password-in-clear-text "$feed" + dotnet nuget push "artifacts/package/release/*.nupkg" "artifacts/package/release/*.snupkg" --source forgejo --skip-duplicate diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0ab95b3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +artifacts/ +TestResults/ +node_modules/ +*.DotSettings.user diff --git a/Directory.Build.props b/Directory.Build.props new file mode 100644 index 0000000..5d86ec8 --- /dev/null +++ b/Directory.Build.props @@ -0,0 +1,7 @@ + + + + + $(MSBuildThisFileDirectory)artifacts + + diff --git a/Directory.Build.targets b/Directory.Build.targets new file mode 100644 index 0000000..8913fe1 --- /dev/null +++ b/Directory.Build.targets @@ -0,0 +1,3 @@ + + + diff --git a/Directory.Packages.props b/Directory.Packages.props new file mode 100644 index 0000000..649f17a --- /dev/null +++ b/Directory.Packages.props @@ -0,0 +1,8 @@ + + + true + + + + + diff --git a/README.md b/README.md new file mode 100644 index 0000000..6c5da8c --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# arcade diff --git a/arcade.slnx b/arcade.slnx new file mode 100644 index 0000000..8850128 --- /dev/null +++ b/arcade.slnx @@ -0,0 +1,7 @@ + + + + + + + diff --git a/global.json b/global.json new file mode 100644 index 0000000..76286dc --- /dev/null +++ b/global.json @@ -0,0 +1,11 @@ +{ + "$schema": "https://www.schemastore.org/global.json", + "sdk": { + "version": "10.0.0", + "rollForward": "latestMinor" + }, + "msbuild-sdks": {}, + "test": { + "runner": "Microsoft.Testing.Platform" + } +} diff --git a/src/sdk.tests/DirectoryExtensions.cs b/src/sdk.tests/DirectoryExtensions.cs new file mode 100644 index 0000000..1b73e4d --- /dev/null +++ b/src/sdk.tests/DirectoryExtensions.cs @@ -0,0 +1,23 @@ +// Copyright (c) The Geekeey Authors +// SPDX-License-Identifier: EUPL-1.2 + +namespace Geekeey.Arcade.NET.Tests; + +public static class DirectoryExtensions +{ + extension(Directory) + { + public static void Copy(string sourceDirectory, string destinationDirectory) + { + foreach (var directory in Directory.EnumerateDirectories(sourceDirectory, "*", SearchOption.AllDirectories)) + { + Directory.CreateDirectory(Path.Combine(destinationDirectory, Path.GetRelativePath(sourceDirectory, directory))); + } + + foreach (var file in Directory.EnumerateFiles(sourceDirectory, "*", SearchOption.AllDirectories)) + { + File.Copy(file, Path.Combine(destinationDirectory, Path.GetRelativePath(sourceDirectory, file))); + } + } + } +} diff --git a/src/sdk.tests/Geekeey.Arcade.NET.Tests.csproj b/src/sdk.tests/Geekeey.Arcade.NET.Tests.csproj new file mode 100644 index 0000000..ae672d9 --- /dev/null +++ b/src/sdk.tests/Geekeey.Arcade.NET.Tests.csproj @@ -0,0 +1,15 @@ + + + net10.0 + false + true + Exe + + + + + + + + + diff --git a/src/sdk.tests/SdkPackageIntegrationTests.cs b/src/sdk.tests/SdkPackageIntegrationTests.cs new file mode 100644 index 0000000..1832e08 --- /dev/null +++ b/src/sdk.tests/SdkPackageIntegrationTests.cs @@ -0,0 +1,163 @@ +// Copyright (c) The Geekeey Authors +// SPDX-License-Identifier: EUPL-1.2 + +using System.Diagnostics; +using System.Text.RegularExpressions; + +namespace Geekeey.Arcade.NET.Tests; + +public sealed class SdkPackageIntegrationTests +{ + + private static string RepositoryPath + { + get + { + for (var directory = new DirectoryInfo(AppContext.BaseDirectory); directory is not null; directory = directory.Parent) + { + if (File.Exists(Path.Combine(directory.FullName, "global.json"))) + { + return directory.FullName; + } + } + + throw new InvalidOperationException("Could not locate the repository root containing global.json."); + } + } + + private static string NuGetFeedPath { get; } = Path.Combine(RepositoryPath, "artifacts", "package", "release"); + + [Test] + [Arguments("Geekeey.Arcade.NET.Sdk", "base")] + [Arguments("Geekeey.Arcade.NET.Sdk.Razor", "razor")] + [Arguments("Geekeey.Arcade.NET.Sdk.Web", "web")] + public async Task SdkPackageCanBeConsumedFromAFeed(string packageId, string name) + { + // Arrange + var version = FindPackageVersion(packageId); + using var sut = await SdkTestProject.CreateAsync(name, version); + + // Act + await sut.RunDotnetAsync($"restore --configfile \"{sut.NuGetConfigPath}\" --packages \"{sut.PackagesPath}\" --nologo"); + await sut.RunDotnetAsync("build --no-restore --nologo"); + await sut.RunDotnetAsync($"pack --no-restore --configuration Debug --output \"{sut.PackedPath}\" --nologo"); + + // Assert + await Assert.That(File.Exists(Path.Combine(sut.ProjectPath, "bin", "Debug", "net10.0", $"{sut.ProjectName}.dll"))).IsTrue(); + await Assert.That(Directory.Exists(sut.PackedPath)).IsTrue(); + await Assert.That(Directory.EnumerateFiles(sut.PackedPath, $"{sut.ProjectName}.*.nupkg").Any()).IsTrue(); + } + + [Test] + public async Task TestSdkPackageStoresTestOutputInArtifacts() + { + // Arrange + var version = FindPackageVersion("Geekeey.Arcade.NET.Sdk.Test"); + using var sut = await SdkTestProject.CreateAsync("test", version); + await sut.RunDotnetAsync($"restore --configfile \"{sut.NuGetConfigPath}\" --packages \"{sut.PackagesPath}\" --nologo"); + await sut.RunDotnetAsync("build --no-restore --nologo"); + + var outputDirectory = Path.Combine(sut.ProjectPath, "artifacts", "bin", sut.ProjectName, "debug"); + await Assert.That(File.Exists(Path.Combine(outputDirectory, $"{sut.ProjectName}.dll"))).IsTrue(); + + // Act + var stdout = await sut.RunDotnetAsync("run --no-build --no-restore"); + + // Assert + await Assert.That(stdout.Contains("succeeded: 1", StringComparison.Ordinal)).IsTrue(); + } + + private static string FindPackageVersion(string packageId) + { + var pattern = $"""^{Regex.Escape(packageId)}\.(?\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?)\.nupkg$"""; + foreach (var package in Directory.EnumerateFiles(NuGetFeedPath, "*.nupkg")) + { + var match = Regex.Match(Path.GetFileName(package), pattern, RegexOptions.CultureInvariant); + if (match.Success) + { + return match.Groups["version"].Value; + } + } + + throw new InvalidOperationException($"No current package found for {packageId}. Run dotnet pack first."); + } + + private sealed class SdkTestProject : IDisposable + { + private SdkTestProject(string root) + { + RootPath = root; + ProjectPath = Path.Combine(RootPath, "Project"); + PackagesPath = Path.Combine(RootPath, "packages"); + PackedPath = Path.Combine(RootPath, "packed"); + NuGetConfigPath = Path.Combine(RootPath, "NuGet.config"); + } + + public static async Task CreateAsync(string name, string version) + { + var sut = new SdkTestProject(Path.Combine(Path.GetTempPath(), $"arcade-sdk-test-{Guid.NewGuid():N}")); + try + { + Directory.CreateDirectory(sut.ProjectPath); + Directory.Copy(Path.Combine(AppContext.BaseDirectory, "fixtures", name), sut.ProjectPath); + sut.ProjectFilePath = Directory.EnumerateFiles(sut.ProjectPath, "*.csproj").Single(); + sut.ProjectName = Path.GetFileNameWithoutExtension(sut.ProjectFilePath); + var project = await File.ReadAllTextAsync(sut.ProjectFilePath); + await File.WriteAllTextAsync(sut.ProjectFilePath, project.Replace("{0}", version, StringComparison.Ordinal)); + var contents = $""" + + + + + + + + """; + await File.WriteAllTextAsync(sut.NuGetConfigPath, contents); + return sut; + } + catch + { + sut.Dispose(); + throw; + } + } + + public string RootPath { get; } + + public string ProjectPath { get; } + + public string ProjectFilePath { get; private set; } = ""; + + public string ProjectName { get; private set; } = ""; + + public string PackagesPath { get; } + + public string PackedPath { get; } + + public string NuGetConfigPath { get; } + + public async Task RunDotnetAsync(string arguments) + { + var startInfo = new ProcessStartInfo("dotnet", arguments) + { + WorkingDirectory = ProjectPath, + RedirectStandardOutput = true, + RedirectStandardError = true, + UseShellExecute = false, + CreateNoWindow = true, + Environment = { ["NUGET_PACKAGES"] = PackagesPath, ["DOTNET_CLI_DO_NOT_USE_MSBUILD_SERVER"] = "1" } + }; + var process = Process.Start(startInfo) ?? throw new InvalidOperationException("Could not start dotnet."); + var output = await process.StandardOutput.ReadToEndAsync(); + var error = await process.StandardError.ReadToEndAsync(); + await process.WaitForExitAsync(); + return process.ExitCode is 0 ? output : throw new InvalidOperationException($"dotnet {arguments} failed with exit code {process.ExitCode}.\n{output}\n{error}"); + } + + public void Dispose() + { + Directory.Delete(RootPath, recursive: true); + } + } +} diff --git a/src/sdk.tests/fixtures/base/BaseConsumer.csproj b/src/sdk.tests/fixtures/base/BaseConsumer.csproj new file mode 100644 index 0000000..65f8f3f --- /dev/null +++ b/src/sdk.tests/fixtures/base/BaseConsumer.csproj @@ -0,0 +1,9 @@ + + + net10.0 + true + false + BaseConsumer + IDE0055 + + diff --git a/src/sdk.tests/fixtures/base/Program.cs b/src/sdk.tests/fixtures/base/Program.cs new file mode 100644 index 0000000..3fd5015 --- /dev/null +++ b/src/sdk.tests/fixtures/base/Program.cs @@ -0,0 +1,4 @@ +public static class EntryPoint +{ + public static string Value { get; } = "ok"; +} diff --git a/src/sdk.tests/fixtures/razor/Program.cs b/src/sdk.tests/fixtures/razor/Program.cs new file mode 100644 index 0000000..2e29697 --- /dev/null +++ b/src/sdk.tests/fixtures/razor/Program.cs @@ -0,0 +1,4 @@ +public sealed class ComponentModel +{ + public static string Value { get; } = "ok"; +} diff --git a/src/sdk.tests/fixtures/razor/RazorConsumer.csproj b/src/sdk.tests/fixtures/razor/RazorConsumer.csproj new file mode 100644 index 0000000..b3de58d --- /dev/null +++ b/src/sdk.tests/fixtures/razor/RazorConsumer.csproj @@ -0,0 +1,8 @@ + + + net10.0 + RazorConsumer + false + IDE0055 + + diff --git a/src/sdk.tests/fixtures/test/Directory.Build.props b/src/sdk.tests/fixtures/test/Directory.Build.props new file mode 100644 index 0000000..1b15241 --- /dev/null +++ b/src/sdk.tests/fixtures/test/Directory.Build.props @@ -0,0 +1,5 @@ + + + $(MSBuildProjectDirectory)/artifacts/ + + diff --git a/src/sdk.tests/fixtures/test/Program.cs b/src/sdk.tests/fixtures/test/Program.cs new file mode 100644 index 0000000..be2f92a --- /dev/null +++ b/src/sdk.tests/fixtures/test/Program.cs @@ -0,0 +1,7 @@ +using TUnit.Core; + +public class ConsumerTests +{ + [Test] + public void TestPasses() { } +} diff --git a/src/sdk.tests/fixtures/test/TestConsumer.csproj b/src/sdk.tests/fixtures/test/TestConsumer.csproj new file mode 100644 index 0000000..6f86a2d --- /dev/null +++ b/src/sdk.tests/fixtures/test/TestConsumer.csproj @@ -0,0 +1,14 @@ + + + net10.0 + true + false + TestConsumer + true + Exe + IDE0055 + + + + + diff --git a/src/sdk.tests/fixtures/web/Program.cs b/src/sdk.tests/fixtures/web/Program.cs new file mode 100644 index 0000000..971a50d --- /dev/null +++ b/src/sdk.tests/fixtures/web/Program.cs @@ -0,0 +1,3 @@ +var builder = WebApplication.CreateBuilder(args); +var app = builder.Build(); +app.MapGet("/", () => "ok"); diff --git a/src/sdk.tests/fixtures/web/WebConsumer.csproj b/src/sdk.tests/fixtures/web/WebConsumer.csproj new file mode 100644 index 0000000..3d9e2d9 --- /dev/null +++ b/src/sdk.tests/fixtures/web/WebConsumer.csproj @@ -0,0 +1,10 @@ + + + net10.0 + true + false + WebConsumer + Exe + IDE0055 + + diff --git a/src/sdk/README.md b/src/sdk/README.md new file mode 100644 index 0000000..1f55011 --- /dev/null +++ b/src/sdk/README.md @@ -0,0 +1,25 @@ +# Geekeey.Arcade.NET.Sdk + +Opinionated MSBuild SDKs for .NET projects with standardized build, analyzer, and editor configuration defaults: + +- `Geekeey.Arcade.NET.Sdk` — base SDK +- `Geekeey.Arcade.NET.Sdk.Razor` — Razor class library and Blazor projects +- `Geekeey.Arcade.NET.Sdk.Web` — ASP.NET Core web projects +- `Geekeey.Arcade.NET.Sdk.Test` — test projects + +## Packaging metadata + +Set these properties in your project file or a directory-level props file. Unless stated otherwise, defaults apply only when the property is empty. + +| Property | Default | Description | +| --- | --- | --- | +| `Authors` | `The Geekeey Team` | Default authors when no value is set. | +| `Copyright` | `Copyright (c) The Geekeey Team` | Default copyright when no value is set. | +| `PublishRepositoryUrl` | `true` | Publishes the repository URL in packages. | +| `IncludeSymbols` | `true` | Packs a symbol package. | +| `SymbolPackageFormat` | `snupkg` | Format of the symbol package. | +| `PackageReadmeFile` | `PACKAGE.md` when found | Packs a `PACKAGE.md` file from the project directory as the package readme. Not packed: `README.md` is for repository visitors. | +| `SearchReadmeFileAbove` | `false` | When `true`, searches parent directories for a `PACKAGE.md` to pack. | +| `PackageLicenseFile` | Detected license file | Packs and declares a `LICENSE.txt`, `LICENSE.md` or `LICENSE` file found in the project directory or a parent directory. Skipped when the project sets `PackageLicenseExpression` or `PackageLicenseFile`. | + +Within this repository, each SDK project lives alongside its package contents in `Sdk//`, so its `PACKAGE.md` is discovered automatically. diff --git a/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk.Razor/Geekeey.Arcade.NET.Sdk.Razor.csproj b/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk.Razor/Geekeey.Arcade.NET.Sdk.Razor.csproj new file mode 100644 index 0000000..3af8be6 --- /dev/null +++ b/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk.Razor/Geekeey.Arcade.NET.Sdk.Razor.csproj @@ -0,0 +1,19 @@ + + + netstandard2.0 + true + false + true + false + MSBuild SDK for Razor class library and Blazor projects with standardized build, analyzer, and editor configuration defaults. + + + + + + + + + + + diff --git a/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk.Razor/Geekeey.Arcade.NET.Sdk.Razor.editorconfig b/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk.Razor/Geekeey.Arcade.NET.Sdk.Razor.editorconfig new file mode 100644 index 0000000..6847850 --- /dev/null +++ b/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk.Razor/Geekeey.Arcade.NET.Sdk.Razor.editorconfig @@ -0,0 +1,3 @@ +# global_level must be higher than the base editorconfig files +is_global = true +global_level = 1 diff --git a/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk.Razor/PACKAGE.md b/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk.Razor/PACKAGE.md new file mode 100644 index 0000000..f3d0cc5 --- /dev/null +++ b/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk.Razor/PACKAGE.md @@ -0,0 +1,29 @@ +# Geekeey.Arcade.NET.Sdk.Razor + +Opinionated MSBuild SDK for Razor class library and Blazor projects with standardized build, analyzer, and editor configuration defaults. + +## Getting started + +```xml + + + net8.0 + + +``` + +## What it provides + +- Everything from the base `Geekeey.Arcade.NET.Sdk` (language, analyzer, editor, and packaging defaults), layered on top of the `Microsoft.NET.Sdk.Razor` SDK. +- Opinionated `.editorconfig` settings for Razor projects, applied automatically via `EditorConfigFiles` (including file-based programs when `FileBasedProgram=true`). + +## Opt-outs + +| Property | Effect | +| --- | --- | +| `EnableDefaultJsonSerializationOptions=false` | Skips the `System.Text.Json` nullable annotation defaults. | +| `IncludeDefaultBannedSymbols=false` | Skips the built-in `BannedSymbols.txt`. | +| `BannedNewtonsoftJsonSymbols=false` | Skips the built-in `BannedSymbols.NewtonsoftJson.txt`. | +| `SearchReadmeFileAbove=true` | Also searches parent directories for a `PACKAGE.md` to pack. | + +See the [repository](https://code.geekeey.de/geekeey/arcade) for the full configuration. diff --git a/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk.Razor/Sdk.props b/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk.Razor/Sdk.props new file mode 100644 index 0000000..72503c0 --- /dev/null +++ b/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk.Razor/Sdk.props @@ -0,0 +1,16 @@ + + + <_MustImportMicrosoftNETSdk Condition="'$(UsingMicrosoftNETSdk)' != 'true'">true + + $(CustomBeforeDirectoryBuildProps);$(MSBuildThisFileDirectory)../common/Common.props + $(BeforeMicrosoftNETSdkTargets);$(MSBuildThisFileDirectory)/../common/Common.targets + + + + + + + + + + diff --git a/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk.Razor/Sdk.targets b/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk.Razor/Sdk.targets new file mode 100644 index 0000000..169fe69 --- /dev/null +++ b/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk.Razor/Sdk.targets @@ -0,0 +1,3 @@ + + + diff --git a/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk.Test/Geekeey.Arcade.NET.Sdk.Test.csproj b/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk.Test/Geekeey.Arcade.NET.Sdk.Test.csproj new file mode 100644 index 0000000..e10ba66 --- /dev/null +++ b/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk.Test/Geekeey.Arcade.NET.Sdk.Test.csproj @@ -0,0 +1,23 @@ + + + netstandard2.0 + true + false + true + false + true + + false + MSBuild SDK for test projects with standardized build, analyzer, and editor configuration defaults. + + + + + + + + + + + diff --git a/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk.Test/Geekeey.Arcade.NET.Sdk.Test.editorconfig b/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk.Test/Geekeey.Arcade.NET.Sdk.Test.editorconfig new file mode 100644 index 0000000..6847850 --- /dev/null +++ b/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk.Test/Geekeey.Arcade.NET.Sdk.Test.editorconfig @@ -0,0 +1,3 @@ +# global_level must be higher than the base editorconfig files +is_global = true +global_level = 1 diff --git a/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk.Test/PACKAGE.md b/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk.Test/PACKAGE.md new file mode 100644 index 0000000..9324dd5 --- /dev/null +++ b/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk.Test/PACKAGE.md @@ -0,0 +1,31 @@ +# Geekeey.Arcade.NET.Sdk.Test + +Opinionated MSBuild SDK for test projects with standardized build, analyzer, and editor configuration defaults. + +## Getting started + +```xml + + + net8.0 + + +``` + +## What it provides + +- Everything from the base `Geekeey.Arcade.NET.Sdk` (language, analyzer, editor, and packaging defaults), layered on top of the `Microsoft.NET.Sdk` SDK. +- Marks consuming projects as test projects by setting `IsTestProject=true` automatically. +- `Microsoft.Testing.Platform.MSBuild` integration out of the box. +- Opinionated `.editorconfig` settings for test projects, applied automatically via `EditorConfigFiles` (including file-based programs when `FileBasedProgram=true`). + +## Opt-outs + +| Property | Effect | +| --- | --- | +| `EnableDefaultJsonSerializationOptions=false` | Skips the `System.Text.Json` nullable annotation defaults. | +| `IncludeDefaultBannedSymbols=false` | Skips the built-in `BannedSymbols.txt`. | +| `BannedNewtonsoftJsonSymbols=false` | Skips the built-in `BannedSymbols.NewtonsoftJson.txt`. | +| `SearchReadmeFileAbove=true` | Also searches parent directories for a `PACKAGE.md` to pack. | + +See the [repository](https://code.geekeey.de/geekeey/arcade) for the full configuration. diff --git a/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk.Test/Sdk.props b/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk.Test/Sdk.props new file mode 100644 index 0000000..7c6b9dd --- /dev/null +++ b/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk.Test/Sdk.props @@ -0,0 +1,17 @@ + + + true + <_MustImportMicrosoftNETSdk Condition="'$(UsingMicrosoftNETSdk)' != 'true'">true + + $(CustomBeforeDirectoryBuildProps);$(MSBuildThisFileDirectory)../common/Common.props + $(BeforeMicrosoftNETSdkTargets);$(MSBuildThisFileDirectory)/../common/Common.targets + + + + + + + + + + diff --git a/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk.Test/Sdk.targets b/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk.Test/Sdk.targets new file mode 100644 index 0000000..c34d867 --- /dev/null +++ b/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk.Test/Sdk.targets @@ -0,0 +1,3 @@ + + + diff --git a/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk.Web/Geekeey.Arcade.NET.Sdk.Web.csproj b/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk.Web/Geekeey.Arcade.NET.Sdk.Web.csproj new file mode 100644 index 0000000..48167a6 --- /dev/null +++ b/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk.Web/Geekeey.Arcade.NET.Sdk.Web.csproj @@ -0,0 +1,19 @@ + + + netstandard2.0 + true + false + true + false + MSBuild SDK for ASP.NET Core web projects with standardized build, analyzer, and editor configuration defaults. + + + + + + + + + + + diff --git a/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk.Web/Geekeey.Arcade.NET.Sdk.Web.editorconfig b/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk.Web/Geekeey.Arcade.NET.Sdk.Web.editorconfig new file mode 100644 index 0000000..6847850 --- /dev/null +++ b/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk.Web/Geekeey.Arcade.NET.Sdk.Web.editorconfig @@ -0,0 +1,3 @@ +# global_level must be higher than the base editorconfig files +is_global = true +global_level = 1 diff --git a/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk.Web/PACKAGE.md b/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk.Web/PACKAGE.md new file mode 100644 index 0000000..dae948b --- /dev/null +++ b/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk.Web/PACKAGE.md @@ -0,0 +1,29 @@ +# Geekeey.Arcade.NET.Sdk.Web + +Opinionated MSBuild SDK for ASP.NET Core web projects with standardized build, analyzer, and editor configuration defaults. + +## Getting started + +```xml + + + net8.0 + + +``` + +## What it provides + +- Everything from the base `Geekeey.Arcade.NET.Sdk` (language, analyzer, editor, and packaging defaults), layered on top of the `Microsoft.NET.Sdk.Web` SDK. +- Opinionated `.editorconfig` settings for web projects, applied automatically via `EditorConfigFiles` (including file-based programs when `FileBasedProgram=true`). + +## Opt-outs + +| Property | Effect | +| --- | --- | +| `EnableDefaultJsonSerializationOptions=false` | Skips the `System.Text.Json` nullable annotation defaults. | +| `IncludeDefaultBannedSymbols=false` | Skips the built-in `BannedSymbols.txt`. | +| `BannedNewtonsoftJsonSymbols=false` | Skips the built-in `BannedSymbols.NewtonsoftJson.txt`. | +| `SearchReadmeFileAbove=true` | Also searches parent directories for a `PACKAGE.md` to pack. | + +See the [repository](https://code.geekeey.de/geekeey/arcade) for the full configuration. diff --git a/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk.Web/Sdk.props b/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk.Web/Sdk.props new file mode 100644 index 0000000..1666365 --- /dev/null +++ b/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk.Web/Sdk.props @@ -0,0 +1,16 @@ + + + <_MustImportMicrosoftNETSdk Condition="'$(UsingMicrosoftNETSdk)' != 'true'">true + + $(CustomBeforeDirectoryBuildProps);$(MSBuildThisFileDirectory)../common/Common.props + $(BeforeMicrosoftNETSdkTargets);$(MSBuildThisFileDirectory)/../common/Common.targets + + + + + + + + + + diff --git a/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk.Web/Sdk.targets b/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk.Web/Sdk.targets new file mode 100644 index 0000000..2f7da47 --- /dev/null +++ b/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk.Web/Sdk.targets @@ -0,0 +1,3 @@ + + + diff --git a/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk/Geekeey.Arcade.NET.Sdk.csproj b/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk/Geekeey.Arcade.NET.Sdk.csproj new file mode 100644 index 0000000..4739f5b --- /dev/null +++ b/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk/Geekeey.Arcade.NET.Sdk.csproj @@ -0,0 +1,19 @@ + + + netstandard2.0 + true + false + true + false + MSBuild SDK for .NET projects with standardized build, analyzer, and editor configuration defaults. + + + + + + + + + + + diff --git a/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk/Geekeey.Arcade.NET.Sdk.editorconfig b/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk/Geekeey.Arcade.NET.Sdk.editorconfig new file mode 100644 index 0000000..6847850 --- /dev/null +++ b/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk/Geekeey.Arcade.NET.Sdk.editorconfig @@ -0,0 +1,3 @@ +# global_level must be higher than the base editorconfig files +is_global = true +global_level = 1 diff --git a/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk/PACKAGE.md b/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk/PACKAGE.md new file mode 100644 index 0000000..106afff --- /dev/null +++ b/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk/PACKAGE.md @@ -0,0 +1,33 @@ +# Geekeey.Arcade.NET.Sdk + +Opinionated MSBuild SDK for .NET projects with standardized build, analyzer, and editor configuration defaults. + +## Getting started + +```xml + + + net8.0 + + +``` + +## What it provides + +- Sensible language defaults: `ImplicitUsings` and `Nullable` enabled, extra global usings for `System.Diagnostics.CodeAnalysis`, `System.Globalization`, and `System.Text`. +- Code quality defaults: `AnalysisLevel=latest`, `AnalysisMode=Recommended`, `EnforceCodeStyleInBuild`, nullable warnings as errors, and all warnings as errors on CI (`ContinuousIntegrationBuild`). +- Opinionated `.editorconfig` settings, applied via `EditorConfigFiles` (including file-based programs when `FileBasedProgram=true`). +- Banned API analysis with `Microsoft.CodeAnalysis.BannedApiAnalyzers` (with a built-in `BannedSymbols.txt`), public API analysis with `Microsoft.CodeAnalysis.PublicApiAnalyzers`, and RESX source generation with `Microsoft.CodeAnalysis.ResxSourceGenerator`. +- `System.Text.Json` defaults that honor nullable annotations and `required` constructor parameters. Opt out with `EnableDefaultJsonSerializationOptions=false`. +- NuGet packaging metadata defaults: `Authors`, `Copyright`, `PublishRepositoryUrl`, symbol packages (`snupkg`), and automatic packaging of a `PACKAGE.md` readme, `THIRD-PARTY-NOTICES` file, and a detected license file. + +## Opt-outs + +| Property | Effect | +| --- | --- | +| `EnableDefaultJsonSerializationOptions=false` | Skips the `System.Text.Json` nullable annotation defaults. | +| `IncludeDefaultBannedSymbols=false` | Skips the built-in `BannedSymbols.txt`. | +| `BannedNewtonsoftJsonSymbols=false` | Skips the built-in `BannedSymbols.NewtonsoftJson.txt`. | +| `SearchReadmeFileAbove=true` | Also searches parent directories for a `PACKAGE.md` to pack. | + +See the [repository](https://code.geekeey.de/geekeey/arcade) for the full configuration. diff --git a/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk/Sdk.props b/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk/Sdk.props new file mode 100644 index 0000000..9937919 --- /dev/null +++ b/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk/Sdk.props @@ -0,0 +1,16 @@ + + + <_MustImportMicrosoftNETSdk Condition="'$(UsingMicrosoftNETSdk)' != 'true'">true + + $(CustomBeforeDirectoryBuildProps);$(MSBuildThisFileDirectory)../common/Common.props + $(BeforeMicrosoftNETSdkTargets);$(MSBuildThisFileDirectory)/../common/Common.targets + + + + + + + + + + diff --git a/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk/Sdk.targets b/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk/Sdk.targets new file mode 100644 index 0000000..c34d867 --- /dev/null +++ b/src/sdk/Sdk/Geekeey.Arcade.NET.Sdk/Sdk.targets @@ -0,0 +1,3 @@ + + + diff --git a/src/sdk/common/Common.props b/src/sdk/common/Common.props new file mode 100644 index 0000000..8a60993 --- /dev/null +++ b/src/sdk/common/Common.props @@ -0,0 +1,80 @@ + + + true + + + + true + + + + enable + enable + + + + + true + + + + The Geekeey Team + Copyright (c) The Geekeey Team + + true + + true + snupkg + + + + Recommended + latest + true + nullable + true + true + + + + + false + + + true + low + all + $(WarningsNotAsErrors);NU1900;NU1901;NU1902;NU1903;NU1904;NU1905 + + + + + true + true + + + + true + true + + + + + + + + + all + runtime; build; native; contentfiles; analyzers + + + all + runtime; build; native; contentfiles; analyzers + + + all + runtime; build; native; contentfiles; analyzers + + + + diff --git a/src/sdk/common/Common.targets b/src/sdk/common/Common.targets new file mode 100644 index 0000000..c94cbec --- /dev/null +++ b/src/sdk/common/Common.targets @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_PackageReadmeFilePath Condition="'$(_PackageReadmeFilePath)' == '' AND Exists('$(MSBuildProjectDirectory)/PACKAGE.md')">$(MSBuildProjectDirectory)/PACKAGE.md + <_PackageReadmeFilePath Condition="'$(_PackageReadmeFilePath)' == '' AND Exists('$(MSBuildProjectDirectory)/package.md')">$(MSBuildProjectDirectory)/package.md + <_PackageReadmeFilePath Condition="'$(_PackageReadmeFilePath)' == '' AND Exists('$(MSBuildProjectDirectory)/Package.md')">$(MSBuildProjectDirectory)/Package.md + <_PackageReadmeFilePath Condition="'$(_PackageReadmeFilePath)' == '' AND Exists('$(MSBuildProjectDirectory)/PackAge.md')">$(MSBuildProjectDirectory)/PackAge.md + + <_PackageReadmeFilePath Condition="'$(SearchReadmeFileAbove)' == 'true' AND '$(_PackageReadmeFilePath)' == '' AND Exists($([MSBuild]::GetPathOfFileAbove('PACKAGE.md', '$(MSBuildProjectDirectory)')))">$([MSBuild]::GetPathOfFileAbove('PACKAGE.md', '$(MSBuildProjectDirectory)')) + <_PackageReadmeFilePath Condition="'$(SearchReadmeFileAbove)' == 'true' AND '$(_PackageReadmeFilePath)' == '' AND Exists($([MSBuild]::GetPathOfFileAbove('package.md', '$(MSBuildProjectDirectory)')))">$([MSBuild]::GetPathOfFileAbove('package.md', '$(MSBuildProjectDirectory)')) + <_PackageReadmeFilePath Condition="'$(SearchReadmeFileAbove)' == 'true' AND '$(_PackageReadmeFilePath)' == '' AND Exists($([MSBuild]::GetPathOfFileAbove('Package.md', '$(MSBuildProjectDirectory)')))">$([MSBuild]::GetPathOfFileAbove('Package.md', '$(MSBuildProjectDirectory)')) + <_PackageReadmeFilePath Condition="'$(SearchReadmeFileAbove)' == 'true' AND '$(_PackageReadmeFilePath)' == '' AND Exists($([MSBuild]::GetPathOfFileAbove('PackAge.md', '$(MSBuildProjectDirectory)')))">$([MSBuild]::GetPathOfFileAbove('PackAge.md', '$(MSBuildProjectDirectory)')) + + <_PackageThirdPartyNoticesPath Condition="'$(_PackageThirdPartyNoticesPath)' == '' AND Exists('$(MSBuildProjectDirectory)/THIRD-PARTY-NOTICES.TXT')">$(MSBuildProjectDirectory)/THIRD-PARTY-NOTICES.TXT + <_PackageThirdPartyNoticesPath Condition="'$(_PackageThirdPartyNoticesPath)' == '' AND Exists('$(MSBuildProjectDirectory)/THIRD-PARTY-NOTICES.txt')">$(MSBuildProjectDirectory)/THIRD-PARTY-NOTICES.txt + <_PackageThirdPartyNoticesPath Condition="'$(_PackageThirdPartyNoticesPath)' == '' AND Exists('$(MSBuildProjectDirectory)/THIRD-PARTY-NOTICES.MD')">$(MSBuildProjectDirectory)/THIRD-PARTY-NOTICES.MD + <_PackageThirdPartyNoticesPath Condition="'$(_PackageThirdPartyNoticesPath)' == '' AND Exists('$(MSBuildProjectDirectory)/THIRD-PARTY-NOTICES.md')">$(MSBuildProjectDirectory)/THIRD-PARTY-NOTICES.md + + + <_LicensePath Condition="'$(_LicensePath)' == '' AND Exists($([MSBuild]::GetPathOfFileAbove('LICENSE.txt', '$(MSBuildProjectDirectory)')))">$([MSBuild]::GetPathOfFileAbove('LICENSE.txt', '$(MSBuildProjectDirectory)')) + <_LicensePath Condition="'$(_LicensePath)' == '' AND Exists($([MSBuild]::GetPathOfFileAbove('LICENSE.md', '$(MSBuildProjectDirectory)')))">$([MSBuild]::GetPathOfFileAbove('LICENSE.md', '$(MSBuildProjectDirectory)')) + <_LicensePath Condition="'$(_LicensePath)' == '' AND Exists($([MSBuild]::GetPathOfFileAbove('LICENSE', '$(MSBuildProjectDirectory)')))">$([MSBuild]::GetPathOfFileAbove('LICENSE', '$(MSBuildProjectDirectory)')) + + PACKAGE.md + + $([System.IO.Path]::GetFileName($(_LicensePath))) + + + + + + + + diff --git a/src/sdk/configuration/Analyzer.Microsoft.CodeAnalysis.BannedApiAnalyzers.editorconfig b/src/sdk/configuration/Analyzer.Microsoft.CodeAnalysis.BannedApiAnalyzers.editorconfig new file mode 100644 index 0000000..ad2f3d3 --- /dev/null +++ b/src/sdk/configuration/Analyzer.Microsoft.CodeAnalysis.BannedApiAnalyzers.editorconfig @@ -0,0 +1,19 @@ +# global_level must be higher than the NET Analyzer files +is_global = true +global_level = 0 + +dotnet_banned_api_analyzer.exclude_generated_code = true + +# RS0030: Do not use banned APIs +# Help link: https://github.com/dotnet/roslyn/blob/main/src/RoslynAnalyzers/Microsoft.CodeAnalysis.BannedApiAnalyzers/BannedApiAnalyzers.Help.md +# Enabled: True, Severity: warning +dotnet_diagnostic.RS0030.severity = warning + +# RS0031: The list of banned symbols contains a duplicate +# Help link: https://github.com/dotnet/roslyn/blob/main/src/RoslynAnalyzers/Microsoft.CodeAnalysis.BannedApiAnalyzers/BannedApiAnalyzers.Help.md +# Enabled: True, Severity: warning +dotnet_diagnostic.RS0031.severity = warning + +# RS0035: External access to internal symbols outside the restricted namespace(s) is prohibited +# Enabled: True, Severity: error +dotnet_diagnostic.RS0035.severity = error diff --git a/src/sdk/configuration/Analyzer.Microsoft.CodeAnalysis.NetAnalyzers.editorconfig b/src/sdk/configuration/Analyzer.Microsoft.CodeAnalysis.NetAnalyzers.editorconfig new file mode 100644 index 0000000..942853a --- /dev/null +++ b/src/sdk/configuration/Analyzer.Microsoft.CodeAnalysis.NetAnalyzers.editorconfig @@ -0,0 +1,3 @@ +# global_level must be higher than the NET Analyzer files +is_global = true +global_level = 0 diff --git a/src/sdk/configuration/Analyzer.Microsoft.CodeAnalysis.PublicApiAnalyzers.editorconfig b/src/sdk/configuration/Analyzer.Microsoft.CodeAnalysis.PublicApiAnalyzers.editorconfig new file mode 100644 index 0000000..1391c5a --- /dev/null +++ b/src/sdk/configuration/Analyzer.Microsoft.CodeAnalysis.PublicApiAnalyzers.editorconfig @@ -0,0 +1,113 @@ +# global_level must be higher than the NET Analyzer files +is_global = true +global_level = 0 + +# Bail out silently for projects that do not have public API files. Projects opt in to +# public API tracking by adding PublicAPI.Shipped.txt / PublicAPI.Unshipped.txt. +dotnet_public_api_analyzer.require_api_files = true + +# RS0016: Add public types and members to the declared API +# Help link: https://github.com/dotnet/roslyn/blob/main/src/RoslynAnalyzers/PublicApiAnalyzers/PublicApiAnalyzers.Help.md +# Enabled: True, Severity: warning +dotnet_diagnostic.RS0016.severity = warning + +# RS0017: Remove deleted types and members from the declared API +# Help link: https://github.com/dotnet/roslyn/blob/main/src/RoslynAnalyzers/PublicApiAnalyzers/PublicApiAnalyzers.Help.md +# Enabled: True, Severity: warning +dotnet_diagnostic.RS0017.severity = warning + +# RS0022: Constructor make noninheritable base class inheritable +# Help link: https://github.com/dotnet/roslyn/blob/main/src/RoslynAnalyzers/PublicApiAnalyzers/PublicApiAnalyzers.Help.md +# Enabled: True, Severity: warning +dotnet_diagnostic.RS0022.severity = warning + +# RS0024: The contents of the public API files are invalid +# Help link: https://github.com/dotnet/roslyn/blob/main/src/RoslynAnalyzers/PublicApiAnalyzers/PublicApiAnalyzers.Help.md +# Enabled: True, Severity: warning +dotnet_diagnostic.RS0024.severity = warning + +# RS0025: Do not duplicate symbols in public API files +# Help link: https://github.com/dotnet/roslyn/blob/main/src/RoslynAnalyzers/PublicApiAnalyzers/PublicApiAnalyzers.Help.md +# Enabled: True, Severity: warning +dotnet_diagnostic.RS0025.severity = warning + +# RS0026: Do not add multiple public overloads with optional parameters +# Help link: https://github.com/dotnet/roslyn/blob/main/docs/Adding%20Optional%20Parameters%20in%20Public%20API.md +# Enabled: True, Severity: warning +dotnet_diagnostic.RS0026.severity = warning + +# RS0027: API with optional parameter(s) should have the most parameters amongst its public overloads +# Help link: https://github.com/dotnet/roslyn/blob/main/docs/Adding%20Optional%20Parameters%20in%20Public%20API.md +# Enabled: True, Severity: warning +dotnet_diagnostic.RS0027.severity = warning + +# RS0036: Annotate nullability of public types and members in the declared API +# Help link: https://github.com/dotnet/roslyn/blob/main/src/RoslynAnalyzers/PublicApiAnalyzers/PublicApiAnalyzers.Help.md +# Enabled: True, Severity: warning +dotnet_diagnostic.RS0036.severity = warning + +# RS0037: Enable tracking of nullability of reference types in the declared API +# Help link: https://github.com/dotnet/roslyn/blob/main/src/RoslynAnalyzers/PublicApiAnalyzers/PublicApiAnalyzers.Help.md +# Enabled: True, Severity: warning +dotnet_diagnostic.RS0037.severity = warning + +# RS0041: Public members should not use oblivious types +# Help link: https://github.com/dotnet/roslyn/blob/main/src/RoslynAnalyzers/PublicApiAnalyzers/PublicApiAnalyzers.Help.md +# Enabled: True, Severity: warning +dotnet_diagnostic.RS0041.severity = warning + +# RS0048: Missing shipped or unshipped public API file +# Help link: https://github.com/dotnet/roslyn/blob/main/src/RoslynAnalyzers/PublicApiAnalyzers/PublicApiAnalyzers.Help.md +# Enabled: True, Severity: warning +dotnet_diagnostic.RS0048.severity = warning + +# RS0050: API is marked as removed but it exists in source code +# Help link: https://github.com/dotnet/roslyn/blob/main/src/RoslynAnalyzers/PublicApiAnalyzers/PublicApiAnalyzers.Help.md +# Enabled: True, Severity: warning +dotnet_diagnostic.RS0050.severity = warning + +# --------------------------------------------------------------------------- +# Internal API tracking (InternalAPI.Shipped.txt / InternalAPI.Unshipped.txt) +# These rules are disabled by default. Projects opt in to internal API tracking +# by adding the InternalAPI.*.txt files, so the defaults are kept here. +# --------------------------------------------------------------------------- + +# RS0051: Add internal types and members to the declared API +# Help link: https://github.com/dotnet/roslyn/blob/main/src/RoslynAnalyzers/PublicApiAnalyzers/PublicApiAnalyzers.Help.md +# Enabled: False, Severity: warning +dotnet_diagnostic.RS0051.severity = none + +# RS0052: Remove deleted types and members from the declared internal API +# Help link: https://github.com/dotnet/roslyn/blob/main/src/RoslynAnalyzers/PublicApiAnalyzers/PublicApiAnalyzers.Help.md +# Enabled: False, Severity: warning +dotnet_diagnostic.RS0052.severity = none + +# RS0053: The contents of the internal API files are invalid +# Help link: https://github.com/dotnet/roslyn/blob/main/src/RoslynAnalyzers/PublicApiAnalyzers/PublicApiAnalyzers.Help.md +# Enabled: False, Severity: warning +dotnet_diagnostic.RS0053.severity = none + +# RS0054: Do not duplicate symbols in internal API files +# Help link: https://github.com/dotnet/roslyn/blob/main/src/RoslynAnalyzers/PublicApiAnalyzers/PublicApiAnalyzers.Help.md +# Enabled: False, Severity: warning +dotnet_diagnostic.RS0054.severity = none + +# RS0055: Annotate nullability of internal types and members in the declared API +# Help link: https://github.com/dotnet/roslyn/blob/main/src/RoslynAnalyzers/PublicApiAnalyzers/PublicApiAnalyzers.Help.md +# Enabled: False, Severity: warning +dotnet_diagnostic.RS0055.severity = none + +# RS0056: Enable tracking of nullability of reference types in the declared API +# Help link: https://github.com/dotnet/roslyn/blob/main/src/RoslynAnalyzers/PublicApiAnalyzers/PublicApiAnalyzers.Help.md +# Enabled: False, Severity: warning +dotnet_diagnostic.RS0056.severity = none + +# RS0057: Internal members should not use oblivious types +# Help link: https://github.com/dotnet/roslyn/blob/main/src/RoslynAnalyzers/PublicApiAnalyzers/PublicApiAnalyzers.Help.md +# Enabled: False, Severity: warning +dotnet_diagnostic.RS0057.severity = none + +# RS0058: Missing shipped or unshipped internal API file +# Help link: https://github.com/dotnet/roslyn/blob/main/src/RoslynAnalyzers/PublicApiAnalyzers/PublicApiAnalyzers.Help.md +# Enabled: False, Severity: warning +dotnet_diagnostic.RS0058.severity = none diff --git a/src/sdk/configuration/BannedSymbols.NewtonsoftJson.txt b/src/sdk/configuration/BannedSymbols.NewtonsoftJson.txt new file mode 100644 index 0000000..2e12391 --- /dev/null +++ b/src/sdk/configuration/BannedSymbols.NewtonsoftJson.txt @@ -0,0 +1,9 @@ +N:Newtonsoft +N:Newtonsoft.Json +N:Newtonsoft.Json.Bson +N:Newtonsoft.Json.Converters +N:Newtonsoft.Json.Linq +N:Newtonsoft.Json.Linq.JsonPath +N:Newtonsoft.Json.Schema +N:Newtonsoft.Json.Serialization +N:Newtonsoft.Json.Utilities diff --git a/src/sdk/configuration/BannedSymbols.txt b/src/sdk/configuration/BannedSymbols.txt new file mode 100644 index 0000000..e85b6b1 --- /dev/null +++ b/src/sdk/configuration/BannedSymbols.txt @@ -0,0 +1,50 @@ +T:System.Collections.ArrayList;Use System.Collections.Generic.List instead +M:System.Reflection.Assembly.GetAssembly(System.Type);Use Type.Assembly instead + +P:System.DateTime.Now;Use System.DateTime.UtcNow instead +P:System.DateTimeOffset.Now;Use System.DateTimeOffset.UtcNow instead + +P:System.IO.FileSystemInfo.CreationTime;Use CreationTimeUtc instead +P:System.IO.FileSystemInfo.LastAccessTime;Use LastAccessTimeUtc instead +P:System.IO.FileSystemInfo.LastWriteTime;Use LastWriteTimeUtc instead + +M:System.IO.File.GetCreationTime(System.String);Use GetCreationTimeUtc instead +M:System.IO.File.GetCreationTime(Microsoft.Win32.SafeHandles.SafeFileHandle);Use GetCreationTimeUtc instead +M:System.IO.File.GetLastAccessTime(System.String);Use GetLastAccessTimeUtc instead +M:System.IO.File.GetLastAccessTime(Microsoft.Win32.SafeHandles.SafeFileHandle);Use GetLastAccessTimeUtc instead +M:System.IO.File.GetLastWriteTime(System.String);Use GetLastWriteTimeUtc instead +M:System.IO.File.GetLastWriteTime(Microsoft.Win32.SafeHandles.SafeFileHandle);Use GetLastWriteTimeUtc instead +M:System.IO.File.SetCreationTime(System.String,System.DateTime);Use SetCreationTimeUtc instead +M:System.IO.File.SetCreationTime(Microsoft.Win32.SafeHandles.SafeFileHandle,System.DateTime);Use SetCreationTimeUtc instead +M:System.IO.File.SetLastAccessTime(System.String,System.DateTime);Use SetLastAccessTimeUtc instead +M:System.IO.File.SetLastAccessTime(Microsoft.Win32.SafeHandles.SafeFileHandle,System.DateTime);Use SetLastAccessTimeUtc instead +M:System.IO.File.SetLastWriteTime(System.String,System.DateTime);Use SetLastWriteTimeUtc instead +M:System.IO.File.SetLastWriteTime(Microsoft.Win32.SafeHandles.SafeFileHandle,System.DateTime);Use SetLastWriteTimeUtc instead + +M:System.IO.Directory.GetCreationTime(System.String);Use GetCreationTimeUtc instead +M:System.IO.Directory.GetLastWriteTime(System.String);Use GetLastWriteTimeUtc instead +M:System.IO.Directory.GetLastAccessTime(System.String);Use GetLastAccessTimeUtc instead +M:System.IO.Directory.SetCreationTime(System.String,System.DateTime);Use SetCreationTimeUtc instead +M:System.IO.Directory.SetLastAccessTime(System.String,System.DateTime);Use SetLastAccessTimeUtc instead +M:System.IO.Directory.SetLastWriteTime(System.String,System.DateTime);Use SetLastWriteTimeUtc instead + +F:System.StringComparison.InvariantCulture;Do you mean Ordinal? +F:System.StringComparison.InvariantCultureIgnoreCase;Do you mean OrdinalIgnoreCase? +P:System.StringComparer.InvariantCulture;Do you mean Ordinal? +P:System.StringComparer.InvariantCultureIgnoreCase;Do you mean OrdinalIgnoreCase? + +M:System.Enum.TryParse(System.Type,System.String,System.Object);Use an overload with a ignoreCase argument +M:System.Enum.TryParse(System.Type,System.ReadOnlySpan{System.Char},System.Object);Use an overload with a ignoreCase argument +M:System.Enum.TryParse``1(System.String,``0@);Use an overload with a ignoreCase argument +M:System.Enum.TryParse``1(System.ReadOnlySpan{System.Char},``0@);Use an overload with a ignoreCase argument + +M:System.Globalization.CultureInfo.#ctor(System.String);Use CultureInfo.GetCultureInfo + +T:System.Tuple`1;Use System.ValueTuple`1 +T:System.Tuple`2;Use System.ValueTuple`2 +T:System.Tuple`3;Use System.ValueTuple`3 +T:System.Tuple`4;Use System.ValueTuple`4 +T:System.Tuple`5;Use System.ValueTuple`5 +T:System.Tuple`6;Use System.ValueTuple`6 +T:System.Tuple`7;Use System.ValueTuple`7 +T:System.Tuple`8;Use System.ValueTuple`8 diff --git a/src/sdk/configuration/Geekeey.Arcade.NET.FileBasedProgram.editorconfig b/src/sdk/configuration/Geekeey.Arcade.NET.FileBasedProgram.editorconfig new file mode 100644 index 0000000..71193b9 --- /dev/null +++ b/src/sdk/configuration/Geekeey.Arcade.NET.FileBasedProgram.editorconfig @@ -0,0 +1,6 @@ +# global_level must be higher than the base editorconfig files +is_global = true +global_level = 1 + +# CA1050: Declare types in namespaces +dotnet_diagnostic.CA1050.severity = none diff --git a/src/sdk/configuration/Geekeey.CodingStyle.editorconfig b/src/sdk/configuration/Geekeey.CodingStyle.editorconfig new file mode 100644 index 0000000..1722fef --- /dev/null +++ b/src/sdk/configuration/Geekeey.CodingStyle.editorconfig @@ -0,0 +1,598 @@ +# global_level must be higher than the NET Analyzer files +is_global = true +global_level = 0 + +# https://learn.microsoft.com/en-us/visualstudio/ide/reference/code-styles-refactoring-options +dotnet_style_operator_placement_when_wrapping = beginning_of_line + +# Require file header (IDE0073) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0073 +dotnet_diagnostic.IDE0073.severity = warning + +# Remove unnecessary using directives (IDE0005) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0005 +dotnet_diagnostic.IDE0005.severity = none + +# 'using' directive placement (IDE0065) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0065 +dotnet_diagnostic.IDE0065.severity = warning +csharp_using_directive_placement = outside_namespace + +# Add braces (IDE0011) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0011 +dotnet_diagnostic.IDE0011.severity = warning +csharp_prefer_braces = true + +# Use simple 'using' statement (IDE0063) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0063 +dotnet_diagnostic.IDE0063.severity = warning +csharp_prefer_simple_using_statement = true + +# Namespace declaration preferences (IDE0160 and IDE0161) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0160-ide0161 +dotnet_diagnostic.IDE0160.severity = warning +dotnet_diagnostic.IDE0161.severity = warning +csharp_style_namespace_declarations = file_scoped + +# Remove unnecessary lambda expression (IDE0200) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0200 +dotnet_diagnostic.IDE0200.severity = warning +csharp_style_prefer_method_group_conversion = true + +# Convert to top-level statements (IDE0210) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0210 +# Convert to 'Program.Main' style program (IDE0211) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0211 +dotnet_diagnostic.IDE0210.severity = none +dotnet_diagnostic.IDE0211.severity = none +csharp_style_prefer_top_level_statements = false + +# Use primary constructor (IDE0290) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0290 +dotnet_diagnostic.IDE0290.severity = none +csharp_style_prefer_primary_constructors = false + +# Prefer 'System.Threading.Lock' (IDE0330) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0330 +dotnet_diagnostic.IDE0330.severity = warning +csharp_prefer_system_threading_lock = true + +# Use labeled jump statement (IDE0410) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0410 +dotnet_diagnostic.IDE0410.severity = warning +csharp_style_prefer_labeled_jump_statements = true + +# Use expression body for constructors (IDE0021) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0021 +dotnet_diagnostic.IDE0021.severity = warning +csharp_style_expression_bodied_constructors = false + +# Use expression body for methods (IDE0022) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0022 +dotnet_diagnostic.IDE0022.severity = warning +csharp_style_expression_bodied_methods = false + +# Use expression body for operators (IDE0023, IDE0024) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0023-ide0024 +dotnet_diagnostic.IDE0023.severity = warning +dotnet_diagnostic.IDE0024.severity = warning +csharp_style_expression_bodied_operators = false + +# Use expression body for properties (IDE0025) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0025 +dotnet_diagnostic.IDE0025.severity = warning +csharp_style_expression_bodied_properties = false + +# Use expression body for indexers (IDE0026) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0026 +dotnet_diagnostic.IDE0026.severity = warning +csharp_style_expression_bodied_indexers = false + +# Use expression body for accessors (IDE0027) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0027 +dotnet_diagnostic.IDE0027.severity = warning +csharp_style_expression_bodied_accessors = when_on_single_line + +# Use expression body for lambdas (IDE0053) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0053 +dotnet_diagnostic.IDE0053.severity = warning +csharp_style_expression_bodied_lambdas = when_on_single_line + +# Use expression body for local functions (IDE0061) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0061 +dotnet_diagnostic.IDE0061.severity = warning +csharp_style_expression_bodied_local_functions = false + +# Simplify name (IDE0001) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0001 +dotnet_diagnostic.IDE0001.severity = warning + +# Simplify member access (IDE0002) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0002 +dotnet_diagnostic.IDE0002.severity = warning + +# Remove unnecessary cast (IDE0004) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0004 +dotnet_diagnostic.IDE0004.severity = warning + +# Add missing cases to switch statement (IDE0010) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0010 +dotnet_diagnostic.IDE0010.severity = warning + +# Use object initializers (IDE0017) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0017 +dotnet_diagnostic.IDE0017.severity = warning +dotnet_style_object_initializer = true + +# Use collection initializers or expressions (IDE0028) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0028 +# Use collection expression for array (IDE0300) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0300 +# Use collection expression for empty (IDE0301) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0301 +# Use collection expression for stackalloc (IDE0302) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0302 +# Use collection expression for Create() (IDE0303) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0303 +# Use collection expression for builder (IDE0304) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0304 +# Use collection expression for fluent (IDE0305) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0305 +# Use collection expression for new (IDE0306) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0306 +dotnet_diagnostic.IDE0028.severity = warning +dotnet_diagnostic.IDE0300.severity = warning +dotnet_diagnostic.IDE0301.severity = warning +dotnet_diagnostic.IDE0302.severity = warning +dotnet_diagnostic.IDE0303.severity = warning +dotnet_diagnostic.IDE0304.severity = warning +dotnet_diagnostic.IDE0305.severity = warning +dotnet_diagnostic.IDE0306.severity = warning +dotnet_style_collection_initializer = true +dotnet_style_prefer_collection_expression = when_types_loosely_match + +# Null check can be simplified (IDE0029, IDE0030, and IDE0270) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0029-ide0030-ide0270 +dotnet_diagnostic.IDE0029.severity = warning +dotnet_diagnostic.IDE0030.severity = warning +dotnet_diagnostic.IDE0270.severity = warning +dotnet_style_coalesce_expression = true + +# Use null propagation (IDE0031) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0031 +dotnet_diagnostic.IDE0031.severity = warning +dotnet_style_null_propagation = true + +# Use auto-implemented property (IDE0032) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0032 +dotnet_diagnostic.IDE0032.severity = warning +dotnet_style_prefer_auto_properties = true + +# Use explicitly provided tuple name (IDE0033) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0033 +dotnet_diagnostic.IDE0033.severity = warning +dotnet_style_explicit_tuple_names = true + +# Remove unreachable code (IDE0035) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0035 +dotnet_diagnostic.IDE0035.severity = warning + +# Use inferred member names (IDE0037) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0037 +dotnet_diagnostic.IDE0037.severity = warning +dotnet_style_prefer_inferred_tuple_names = true +dotnet_style_prefer_inferred_anonymous_type_member_names = true + +# Use 'is null' check (IDE0041) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0041 +dotnet_diagnostic.IDE0041.severity = warning +dotnet_style_prefer_is_null_check_over_reference_equality_method = true + +# Use conditional expression for assignment (IDE0045) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0045 +dotnet_diagnostic.IDE0045.severity = warning +dotnet_style_prefer_conditional_expression_over_assignment = true + +# Use conditional expression for return (IDE0046) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0046 +dotnet_diagnostic.IDE0046.severity = warning +dotnet_style_prefer_conditional_expression_over_return = true + +# Convert anonymous type to tuple (IDE0050) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0050 +dotnet_diagnostic.IDE0050.severity = warning + +# Remove unused private member (IDE0051) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0051 +dotnet_diagnostic.IDE0051.severity = warning + +# Remove unread private member (IDE0052) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0052 +dotnet_diagnostic.IDE0052.severity = warning + +# Use compound assignment (IDE0054 and IDE0074) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0054-ide0074 +dotnet_diagnostic.IDE0054.severity = warning +dotnet_diagnostic.IDE0074.severity = warning +dotnet_style_prefer_compound_assignment = true + +# Remove unnecessary expression value (IDE0058) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0058 +dotnet_diagnostic.IDE0058.severity = none +csharp_style_unused_value_expression_statement_preference = discard_variable + +# Remove unnecessary value assignment (IDE0059) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0059 +dotnet_diagnostic.IDE0059.severity = warning +csharp_style_unused_value_assignment_preference = discard_variable + +# Use 'System.HashCode.Combine' (IDE0070) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0070 +dotnet_diagnostic.IDE0070.severity = warning +dotnet_prefer_system_hash_code = true + +# Simplify interpolation (IDE0071) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0071 +dotnet_diagnostic.IDE0071.severity = warning +dotnet_style_prefer_simplified_interpolation = true + +# Simplify conditional expression (IDE0075) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0075 +dotnet_diagnostic.IDE0075.severity = warning +dotnet_style_prefer_simplified_boolean_expressions = true + +# Convert typeof to nameof (IDE0082) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0082 +dotnet_diagnostic.IDE0082.severity = warning + +# Remove unnecessary equality operator (IDE0100) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0100 +dotnet_diagnostic.IDE0100.severity = warning + +# Simplify LINQ expression (IDE0120) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0120 +dotnet_diagnostic.IDE0120.severity = warning + +# Simplify LINQ type check and cast (IDE0121) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0121 +dotnet_diagnostic.IDE0121.severity = warning + +# Namespace does not match folder structure (IDE0130) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0130 +dotnet_diagnostic.IDE0130.severity = warning +dotnet_style_namespace_match_folder = false + +# Use throw expression (IDE0016) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0016 +dotnet_diagnostic.IDE0016.severity = warning +csharp_style_throw_expression = true + +# Inline variable declaration (IDE0018) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0018 +dotnet_diagnostic.IDE0018.severity = warning +csharp_style_inlined_variable_declaration = true + +# Simplify 'default' expression (IDE0034) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0034 +dotnet_diagnostic.IDE0034.severity = warning +csharp_prefer_simple_default_expression = true + +# Use local function instead of lambda (IDE0039) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0039 +dotnet_diagnostic.IDE0039.severity = warning +csharp_style_prefer_local_over_anonymous_function = true + +# Deconstruct variable declaration (IDE0042) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0042 +dotnet_diagnostic.IDE0042.severity = warning +csharp_style_deconstructed_variable_declaration = true + +# Invalid format string (IDE0043) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0043 +dotnet_diagnostic.IDE0043.severity = warning + +# Use index operator (IDE0056) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0056 +dotnet_diagnostic.IDE0056.severity = warning +csharp_style_prefer_index_operator = true + +# Use range operator (IDE0057) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0057 +dotnet_diagnostic.IDE0057.severity = warning +csharp_style_prefer_range_operator = true + +# Add missing cases to switch expression (IDE0072) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0072 +dotnet_diagnostic.IDE0072.severity = warning + +# Remove unnecessary suppression operator (IDE0080) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0080 +dotnet_diagnostic.IDE0080.severity = warning + +# Simplify new expression (IDE0090) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0090 +dotnet_diagnostic.IDE0090.severity = warning +csharp_style_implicit_object_creation_when_type_is_apparent = true + +# Remove unnecessary discard (IDE0110) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0110 +dotnet_diagnostic.IDE0110.severity = warning + +# Prefer 'null' check over type check (IDE0150) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0150 +dotnet_diagnostic.IDE0150.severity = warning +csharp_style_prefer_null_check_over_type_check = true + +# Use tuple to swap values (IDE0180) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0180 +dotnet_diagnostic.IDE0180.severity = warning +csharp_style_prefer_tuple_swap = true + +# Add explicit cast in foreach loop (IDE0220) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0220 +dotnet_diagnostic.IDE0220.severity = warning +dotnet_style_prefer_foreach_explicit_cast_in_source = when_strongly_typed + +# Add explicit cast (IDE0221) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0221 +dotnet_diagnostic.IDE0221.severity = warning +dotnet_style_prefer_non_hidden_explicit_cast_in_source = true + +# Use UTF-8 string literal (IDE0230) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0230 +dotnet_diagnostic.IDE0230.severity = warning +csharp_style_prefer_utf8_string_literals = true + +# Nullable directive is redundant (IDE0240) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0240 +dotnet_diagnostic.IDE0240.severity = warning + +# Nullable directive is unnecessary (IDE0241) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0241 +dotnet_diagnostic.IDE0241.severity = warning + +# Use unbound generic type (IDE0340) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0340 +dotnet_diagnostic.IDE0340.severity = warning +csharp_style_prefer_unbound_generic_type_in_nameof = true + +# Use implicitly typed lambda (IDE0350) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0350 +dotnet_diagnostic.IDE0350.severity = warning +csharp_style_prefer_implicitly_typed_lambda_expression = true + +# Simplify property accessor (IDE0360) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0360 +dotnet_diagnostic.IDE0360.severity = warning +csharp_style_prefer_simple_property_accessors = true + +# The name does not exist in the current context (IDE1007) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide1007 +dotnet_diagnostic.IDE1007.severity = warning + +# Add readonly modifier (IDE0044) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0044 +dotnet_diagnostic.IDE0044.severity = warning +dotnet_style_readonly_field = true + +# Use language keywords instead of framework type names for type references (IDE0049) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0049 +dotnet_diagnostic.IDE0049.severity = warning +dotnet_style_predefined_type_for_locals_parameters_members = true +dotnet_style_predefined_type_for_member_access = true + +# Order modifiers (IDE0036) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0036 +dotnet_diagnostic.IDE0036.severity = warning +csharp_preferred_modifier_order = public,private,protected,internal,file,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,required,volatile,async + +# Add accessibility modifiers (IDE0040) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0040 +dotnet_diagnostic.IDE0040.severity = warning +dotnet_style_require_accessibility_modifiers = for_non_interface_members + +# Make local function static (IDE0062) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0062 +dotnet_diagnostic.IDE0062.severity = warning +csharp_prefer_static_local_function = true + +# Make struct fields writable (IDE0064) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0064 +dotnet_diagnostic.IDE0064.severity = warning + +# Struct can be made 'readonly' (IDE0250) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0250 +dotnet_diagnostic.IDE0250.severity = warning +csharp_style_prefer_readonly_struct = true + +# Member can be made 'readonly' (IDE0251) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0251 +dotnet_diagnostic.IDE0251.severity = warning +csharp_style_prefer_readonly_struct_member = true + +# Make anonymous function static (IDE0320) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0320 +dotnet_diagnostic.IDE0320.severity = warning +csharp_prefer_static_anonymous_function = true + +# Remove unnecessary unsafe modifier (IDE0380) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0380 +dotnet_diagnostic.IDE0380.severity = warning + +# Make method synchronous (IDE0390 and IDE0391) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0390-ide0391 +dotnet_diagnostic.IDE0390.severity = warning +dotnet_diagnostic.IDE0391.severity = warning + +# Avoid multiple blank lines (IDE2000) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide2000 +dotnet_diagnostic.IDE2000.severity = warning +dotnet_style_allow_multiple_blank_lines_experimental = false + +# Embedded statements must be on their own line (IDE2001) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide2001 +dotnet_diagnostic.IDE2001.severity = warning +csharp_style_allow_embedded_statements_on_same_line_experimental = false + +# Consecutive braces must not have blank line between them (IDE2002) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide2002 +dotnet_diagnostic.IDE2002.severity = warning +csharp_style_allow_blank_lines_between_consecutive_braces_experimental = false + +# Blank line required between block and subsequent statement (IDE2003) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide2003 +dotnet_diagnostic.IDE2003.severity = warning +dotnet_style_allow_statement_immediately_after_block_experimental = false + +# Blank line not allowed after constructor initializer colon (IDE2004) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide2004 +dotnet_diagnostic.IDE2004.severity = warning +csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = false + +# Blank line not allowed after conditional expression token (IDE2005) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide2005 +dotnet_diagnostic.IDE2005.severity = warning +csharp_style_allow_blank_line_after_token_in_conditional_expression_experimental = false + +# Blank line not allowed after arrow expression clause token (IDE2006) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide2006 +dotnet_diagnostic.IDE2006.severity = warning +csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental = false + +# Use conditional delegate call (IDE1005) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide1005 +dotnet_diagnostic.IDE1005.severity = warning +csharp_style_conditional_delegate_call = true + +# Remove unused parameter (IDE0060) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0060 +dotnet_diagnostic.IDE0060.severity = warning +dotnet_code_quality_unused_parameters = non_public + +# Use 'nameof' (IDE0280) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0280 +dotnet_diagnostic.IDE0280.severity = warning + +# Parentheses preferences (IDE0047 and IDE0048) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0047-ide0048 +dotnet_diagnostic.IDE0047.severity = warning +dotnet_diagnostic.IDE0048.severity = warning +dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity +dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity +dotnet_style_parentheses_in_other_binary_operators = always_for_clarity +dotnet_style_parentheses_in_other_operators = never_if_unnecessary + +# Use pattern matching to avoid 'is' check followed by a cast (IDE0020 and IDE0038) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0020-ide0038 +dotnet_diagnostic.IDE0020.severity = warning +dotnet_diagnostic.IDE0038.severity = warning +csharp_style_pattern_matching_over_is_with_cast_check = true + +# Use switch expression (IDE0066) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0066 +dotnet_diagnostic.IDE0066.severity = warning +csharp_style_prefer_switch_expression = true + +# Use pattern matching to avoid 'as' followed by a 'null' check (IDE0019) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0019 +# Use pattern matching (IDE0078 and IDE0260) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0078-ide0260 +dotnet_diagnostic.IDE0019.severity = warning +dotnet_diagnostic.IDE0078.severity = warning +dotnet_diagnostic.IDE0260.severity = warning +csharp_style_prefer_pattern_matching = true +csharp_style_pattern_matching_over_as_with_null_check = true + +# Use pattern matching (not operator) (IDE0083) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0083 +dotnet_diagnostic.IDE0083.severity = warning +csharp_style_prefer_not_pattern = true + +# Simplify property pattern (IDE0170) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0170 +dotnet_diagnostic.IDE0170.severity = warning +csharp_style_prefer_extended_property_pattern = true + +# Remove unnecessary suppression (IDE0079) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0079 +dotnet_diagnostic.IDE0079.severity = warning +dotnet_remove_unnecessary_suppression_exclusions = none + +# Remove unnecessary suppression (IDE0370) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0370 +dotnet_diagnostic.IDE0370.severity = warning + +# Member-access qualification preferences (IDE0003 and IDE0009) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0003-ide0009 +dotnet_diagnostic.IDE0003.severity = warning +dotnet_diagnostic.IDE0009.severity = warning +dotnet_style_qualification_for_field = false +dotnet_style_qualification_for_property = false +dotnet_style_qualification_for_method = false +dotnet_style_qualification_for_event = false + +# 'var' preferences (IDE0007 and IDE0008) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0007-ide0008 +dotnet_diagnostic.IDE0007.severity = warning +dotnet_diagnostic.IDE0008.severity = warning +csharp_style_var_for_built_in_types = true +csharp_style_var_when_type_is_apparent = true +csharp_style_var_elsewhere = true + +# Formatting rule (IDE0055) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0055 +dotnet_diagnostic.IDE0055.severity = warning + +## .NET formatting options +## https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/dotnet-formatting-options + +dotnet_sort_system_directives_first = true +dotnet_separate_import_directive_groups = false + +## C# formatting options +## https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/csharp-formatting-options + +### New-line options +csharp_new_line_before_open_brace = all +csharp_new_line_before_else = true +csharp_new_line_before_catch = true +csharp_new_line_before_finally = true +csharp_new_line_before_members_in_object_initializers = true +csharp_new_line_before_members_in_anonymous_types = true +csharp_new_line_between_query_expression_clauses = true + +### Indentation options +csharp_indent_case_contents = true +csharp_indent_switch_labels = true +csharp_indent_labels = one_less_than_current +csharp_indent_block_contents = true +csharp_indent_braces = false +csharp_indent_case_contents_when_block = false + +### Spacing options +csharp_space_after_cast = false +csharp_space_after_keywords_in_control_flow_statements = true +csharp_space_between_parentheses = false +csharp_space_before_colon_in_inheritance_clause = true +csharp_space_after_colon_in_inheritance_clause = true +csharp_space_around_binary_operators = before_and_after +csharp_space_between_method_declaration_parameter_list_parentheses = false +csharp_space_between_method_declaration_empty_parameter_list_parentheses = false +csharp_space_between_method_declaration_name_and_open_parenthesis = false +csharp_space_between_method_call_parameter_list_parentheses = false +csharp_space_between_method_call_empty_parameter_list_parentheses = false +csharp_space_between_method_call_name_and_opening_parenthesis = false +csharp_space_after_comma = true +csharp_space_before_comma = false +csharp_space_after_dot = false +csharp_space_before_dot = false +csharp_space_after_semicolon_in_for_statement = true +csharp_space_before_semicolon_in_for_statement = false +csharp_space_around_declaration_statements = false +csharp_space_before_open_square_brackets = false +csharp_space_between_empty_square_brackets = false +csharp_space_between_square_brackets = false + +### Wrap options +csharp_preserve_single_line_blocks = true +csharp_preserve_single_line_statements = false diff --git a/src/sdk/configuration/Geekeey.NamingConvention.editorconfig b/src/sdk/configuration/Geekeey.NamingConvention.editorconfig new file mode 100644 index 0000000..dfd3d98 --- /dev/null +++ b/src/sdk/configuration/Geekeey.NamingConvention.editorconfig @@ -0,0 +1,215 @@ +# global_level must be higher than the NET Analyzer files +is_global = true +global_level = 0 + +# IDE1006 (Naming rule violation) +# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide1006 +dotnet_diagnostic.IDE1006.severity = warning + +# types and namespaces should be PascalCase +dotnet_naming_rule.types_and_namespaces_should_be_pascalcase.severity = suggestion +dotnet_naming_rule.types_and_namespaces_should_be_pascalcase.symbols = types_and_namespaces +dotnet_naming_rule.types_and_namespaces_should_be_pascalcase.style = pascalcase + +dotnet_naming_symbols.types_and_namespaces.applicable_kinds = namespace, class, struct, interface, enum +dotnet_naming_symbols.types_and_namespaces.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.types_and_namespaces.required_modifiers = + +# interfaces should be PascalCase with I prefix +dotnet_naming_rule.interfaces_should_be_ipascalcase.severity = suggestion +dotnet_naming_rule.interfaces_should_be_ipascalcase.symbols = interfaces +dotnet_naming_rule.interfaces_should_be_ipascalcase.style = ipascalcase + +dotnet_naming_symbols.interfaces.applicable_kinds = interface +dotnet_naming_symbols.interfaces.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.interfaces.required_modifiers = + +# enums should be PascalCase +dotnet_naming_rule.enums_should_be_pascalcase.severity = suggestion +dotnet_naming_rule.enums_should_be_pascalcase.symbols = enums +dotnet_naming_rule.enums_should_be_pascalcase.style = pascalcase + +dotnet_naming_symbols.enums.applicable_kinds = enum +dotnet_naming_symbols.enums.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.enums.required_modifiers = + +# type parameters should be PascalCase with T prefix +dotnet_naming_rule.type_parameters_should_be_tpascalcase.severity = suggestion +dotnet_naming_rule.type_parameters_should_be_tpascalcase.symbols = type_parameters +dotnet_naming_rule.type_parameters_should_be_tpascalcase.style = tpascalcase + +dotnet_naming_symbols.type_parameters.applicable_kinds = namespace +dotnet_naming_symbols.type_parameters.applicable_accessibilities = * +dotnet_naming_symbols.type_parameters.required_modifiers = + +# methods should be PascalCase +dotnet_naming_rule.methods_should_be_pascalcase.severity = suggestion +dotnet_naming_rule.methods_should_be_pascalcase.symbols = methods +dotnet_naming_rule.methods_should_be_pascalcase.style = pascalcase + +dotnet_naming_symbols.methods.applicable_kinds = method +dotnet_naming_symbols.methods.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.methods.required_modifiers = + +# parameters should be camelCase +dotnet_naming_rule.parameters_should_be_camelcase.severity = suggestion +dotnet_naming_rule.parameters_should_be_camelcase.symbols = parameters +dotnet_naming_rule.parameters_should_be_camelcase.style = camelcase + +dotnet_naming_symbols.parameters.applicable_kinds = parameter +dotnet_naming_symbols.parameters.applicable_accessibilities = * +dotnet_naming_symbols.parameters.required_modifiers = + +# properties should be PascalCase +dotnet_naming_rule.properties_should_be_pascalcase.severity = suggestion +dotnet_naming_rule.properties_should_be_pascalcase.symbols = properties +dotnet_naming_rule.properties_should_be_pascalcase.style = pascalcase + +dotnet_naming_symbols.properties.applicable_kinds = property +dotnet_naming_symbols.properties.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.properties.required_modifiers = + +# events should be PascalCase +dotnet_naming_rule.events_should_be_pascalcase.severity = suggestion +dotnet_naming_rule.events_should_be_pascalcase.symbols = events +dotnet_naming_rule.events_should_be_pascalcase.style = pascalcase + +dotnet_naming_symbols.events.applicable_kinds = event +dotnet_naming_symbols.events.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.events.required_modifiers = + +# local + +dotnet_naming_rule.local_variables_should_be_camelcase.severity = suggestion +dotnet_naming_rule.local_variables_should_be_camelcase.symbols = local_variables +dotnet_naming_rule.local_variables_should_be_camelcase.style = camelcase + +dotnet_naming_symbols.local_variables.applicable_kinds = local +dotnet_naming_symbols.local_variables.applicable_accessibilities = local +dotnet_naming_symbols.local_variables.required_modifiers = + + +dotnet_naming_rule.local_functions_should_be_pascalcase.severity = suggestion +dotnet_naming_rule.local_functions_should_be_pascalcase.symbols = local_functions +dotnet_naming_rule.local_functions_should_be_pascalcase.style = pascalcase + +dotnet_naming_symbols.local_functions.applicable_kinds = local_function +dotnet_naming_symbols.local_functions.applicable_accessibilities = * +dotnet_naming_symbols.local_functions.required_modifiers = + + +dotnet_naming_rule.local_constants_should_be_camelcase.severity = suggestion +dotnet_naming_rule.local_constants_should_be_camelcase.symbols = local_constants +dotnet_naming_rule.local_constants_should_be_camelcase.style = camelcase + +dotnet_naming_symbols.local_constants.applicable_kinds = local +dotnet_naming_symbols.local_constants.applicable_accessibilities = local +dotnet_naming_symbols.local_constants.required_modifiers = const + +# private + +dotnet_naming_rule.private_fields_should_be__camelcase.severity = suggestion +dotnet_naming_rule.private_fields_should_be__camelcase.symbols = private_fields +dotnet_naming_rule.private_fields_should_be__camelcase.style = _camelcase + +dotnet_naming_symbols.private_fields.applicable_kinds = field +dotnet_naming_symbols.private_fields.applicable_accessibilities = private, protected, protected_internal, private_protected +dotnet_naming_symbols.private_fields.required_modifiers = + + +dotnet_naming_rule.private_static_fields_should_be_s_camelcase.severity = suggestion +dotnet_naming_rule.private_static_fields_should_be_s_camelcase.symbols = private_static_fields +dotnet_naming_rule.private_static_fields_should_be_s_camelcase.style = s_camelcase + +dotnet_naming_symbols.private_static_fields.applicable_kinds = field +dotnet_naming_symbols.private_static_fields.applicable_accessibilities = private, protected, protected_internal, private_protected +dotnet_naming_symbols.private_static_fields.required_modifiers = static + + +dotnet_naming_rule.private_static_readonly_fields_should_be_pascalcase.severity = suggestion +dotnet_naming_rule.private_static_readonly_fields_should_be_pascalcase.symbols = private_static_readonly_fields +dotnet_naming_rule.private_static_readonly_fields_should_be_pascalcase.style = pascalcase + +dotnet_naming_symbols.private_static_readonly_fields.applicable_kinds = field +dotnet_naming_symbols.private_static_readonly_fields.applicable_accessibilities = private, protected, protected_internal, private_protected +dotnet_naming_symbols.private_static_readonly_fields.required_modifiers = readonly, static + + +dotnet_naming_rule.private_constant_fields_should_be_pascalcase.severity = suggestion +dotnet_naming_rule.private_constant_fields_should_be_pascalcase.symbols = private_constant_fields +dotnet_naming_rule.private_constant_fields_should_be_pascalcase.style = pascalcase + +dotnet_naming_symbols.private_constant_fields.applicable_kinds = field +dotnet_naming_symbols.private_constant_fields.applicable_accessibilities = private, protected, protected_internal, private_protected +dotnet_naming_symbols.private_constant_fields.required_modifiers = const + +# public + +dotnet_naming_rule.public_fields_should_be_pascalcase.severity = suggestion +dotnet_naming_rule.public_fields_should_be_pascalcase.symbols = public_fields +dotnet_naming_rule.public_fields_should_be_pascalcase.style = pascalcase + +dotnet_naming_symbols.public_fields.applicable_kinds = field +dotnet_naming_symbols.public_fields.applicable_accessibilities = public, internal +dotnet_naming_symbols.public_fields.required_modifiers = + + +dotnet_naming_rule.public_static_readonly_fields_should_be_pascalcase.severity = suggestion +dotnet_naming_rule.public_static_readonly_fields_should_be_pascalcase.symbols = public_static_readonly_fields +dotnet_naming_rule.public_static_readonly_fields_should_be_pascalcase.style = pascalcase + +dotnet_naming_symbols.public_static_readonly_fields.applicable_kinds = field +dotnet_naming_symbols.public_static_readonly_fields.applicable_accessibilities = public, internal +dotnet_naming_symbols.public_static_readonly_fields.required_modifiers = readonly, static + + +dotnet_naming_rule.public_constant_fields_should_be_pascalcase.severity = suggestion +dotnet_naming_rule.public_constant_fields_should_be_pascalcase.symbols = public_constant_fields +dotnet_naming_rule.public_constant_fields_should_be_pascalcase.style = pascalcase + +dotnet_naming_symbols.public_constant_fields.applicable_kinds = field +dotnet_naming_symbols.public_constant_fields.applicable_accessibilities = public, internal +dotnet_naming_symbols.public_constant_fields.required_modifiers = const + +# others + +dotnet_naming_rule.non_field_members_should_be_pascalcase.severity = suggestion +dotnet_naming_rule.non_field_members_should_be_pascalcase.symbols = non_field_members +dotnet_naming_rule.non_field_members_should_be_pascalcase.style = pascalcase + +dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method +dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.non_field_members.required_modifiers = + + +# Naming styles + +dotnet_naming_style.pascalcase.required_prefix = +dotnet_naming_style.pascalcase.required_suffix = +dotnet_naming_style.pascalcase.word_separator = +dotnet_naming_style.pascalcase.capitalization = pascal_case + +dotnet_naming_style.ipascalcase.required_prefix = I +dotnet_naming_style.ipascalcase.required_suffix = +dotnet_naming_style.ipascalcase.word_separator = +dotnet_naming_style.ipascalcase.capitalization = pascal_case + +dotnet_naming_style.tpascalcase.required_prefix = T +dotnet_naming_style.tpascalcase.required_suffix = +dotnet_naming_style.tpascalcase.word_separator = +dotnet_naming_style.tpascalcase.capitalization = pascal_case + +dotnet_naming_style._camelcase.required_prefix = _ +dotnet_naming_style._camelcase.required_suffix = +dotnet_naming_style._camelcase.word_separator = +dotnet_naming_style._camelcase.capitalization = camel_case + +dotnet_naming_style.camelcase.required_prefix = +dotnet_naming_style.camelcase.required_suffix = +dotnet_naming_style.camelcase.word_separator = +dotnet_naming_style.camelcase.capitalization = camel_case + +dotnet_naming_style.s_camelcase.required_prefix = s_ +dotnet_naming_style.s_camelcase.required_suffix = +dotnet_naming_style.s_camelcase.word_separator = +dotnet_naming_style.s_camelcase.capitalization = camel_case