Files
DodoSSH/.editorconfig
jaap-janandClaude Opus 5 ffab2be22a
ci / build and test (push) Successful in 1m11s
ci / android head (push) Failing after 4s
ci / api image (push) Successful in 43s
Drop the formatting step, which spent minutes agreeing with the build
`dotnet format --verify-no-changes` re-analysed the whole solution before the build did, to
reach a verdict the build reaches on its own: IDE0055 is an error in .editorconfig,
EnforceCodeStyleInBuild is on and warnings are errors, so a misformatted file fails the
build step. What the separate step bought was hearing about it a few minutes earlier, and
it charged those minutes on every run.

Checked rather than assumed, because the whole justification rests on it: appending a
badly-spaced member to a source file produces three `error IDE0055` lines and a failed
build with no format step in sight.

Three places said the old arrangement out loud and would now be wrong on their own — the
comment on the IDE0055 line, the conventions list in the README, and a note in
platform-flags telling people to run dotnet format before pushing or CI would fail them.
They say the build enforces it now. dotnet format is still how to fix what the build
complains about; it just no longer gates anything.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-01 21:43:32 +02:00

166 lines
7.9 KiB
INI

# EditorConfig for DodoSSH — https://editorconfig.org
root = true
[*]
charset = utf-8
end_of_line = lf
indent_style = space
indent_size = 4
insert_final_newline = true
trim_trailing_whitespace = true
[*.{json,yml,yaml,js,ts,css,html,axaml,xaml,csproj,props,targets,slnx}]
indent_size = 2
[*.md]
# Two trailing spaces are a hard line break in Markdown.
trim_trailing_whitespace = false
[*.{cmd,bat,ps1}]
end_of_line = crlf
[*.cs]
indent_size = 4
#### Language conventions ####
csharp_style_namespace_declarations = file_scoped:error
csharp_using_directive_placement = outside_namespace:error
csharp_style_var_for_built_in_types = false:suggestion
csharp_style_var_when_type_is_apparent = true:suggestion
csharp_style_var_elsewhere = false:suggestion
csharp_prefer_braces = true:suggestion
csharp_style_prefer_primary_constructors = true:suggestion
csharp_style_expression_bodied_methods = when_on_single_line:suggestion
csharp_style_expression_bodied_properties = true:suggestion
dotnet_sort_system_directives_first = true
dotnet_separate_import_directive_groups = false
dotnet_style_qualification_for_field = false:suggestion
dotnet_style_qualification_for_property = false:suggestion
dotnet_style_qualification_for_method = false:suggestion
dotnet_style_readonly_field = true:warning
dotnet_style_require_accessibility_modifiers = for_non_interface_members:warning
dotnet_style_coalesce_expression = true:suggestion
dotnet_style_null_propagation = true:suggestion
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
# Async methods must be suffixed Async (VSTHRD200 equivalent via naming rules below).
dotnet_naming_rule.async_methods_end_in_async.severity = warning
dotnet_naming_rule.async_methods_end_in_async.symbols = any_async_method
dotnet_naming_rule.async_methods_end_in_async.style = ends_with_async
dotnet_naming_symbols.any_async_method.applicable_kinds = method
dotnet_naming_symbols.any_async_method.required_modifiers = async
dotnet_naming_style.ends_with_async.required_suffix = Async
dotnet_naming_style.ends_with_async.capitalization = pascal_case
dotnet_naming_rule.interfaces_start_with_i.severity = warning
dotnet_naming_rule.interfaces_start_with_i.symbols = any_interface
dotnet_naming_rule.interfaces_start_with_i.style = starts_with_i
dotnet_naming_symbols.any_interface.applicable_kinds = interface
dotnet_naming_style.starts_with_i.required_prefix = I
dotnet_naming_style.starts_with_i.capitalization = pascal_case
# Constants and static readonly fields are PascalCase, per .NET convention. These rules must
# come before the camelCase rule below: the first matching rule wins, and a rule matching all
# private fields would otherwise force `const int Foo` to be named `foo`.
dotnet_naming_rule.constants_are_pascal_case.severity = warning
dotnet_naming_rule.constants_are_pascal_case.symbols = any_const_field
dotnet_naming_rule.constants_are_pascal_case.style = pascal_case_style
dotnet_naming_symbols.any_const_field.applicable_kinds = field
dotnet_naming_symbols.any_const_field.applicable_accessibilities = *
dotnet_naming_symbols.any_const_field.required_modifiers = const
dotnet_naming_rule.static_readonly_fields_are_pascal_case.severity = warning
dotnet_naming_rule.static_readonly_fields_are_pascal_case.symbols = static_readonly_field
dotnet_naming_rule.static_readonly_fields_are_pascal_case.style = pascal_case_style
dotnet_naming_symbols.static_readonly_field.applicable_kinds = field
dotnet_naming_symbols.static_readonly_field.applicable_accessibilities = *
dotnet_naming_symbols.static_readonly_field.required_modifiers = static, readonly
dotnet_naming_style.pascal_case_style.capitalization = pascal_case
# Private instance fields are camelCase.
dotnet_naming_rule.private_fields_are_camel_case.severity = warning
dotnet_naming_rule.private_fields_are_camel_case.symbols = private_field
dotnet_naming_rule.private_fields_are_camel_case.style = camel_case_style
dotnet_naming_symbols.private_field.applicable_kinds = field
dotnet_naming_symbols.private_field.applicable_accessibilities = private
dotnet_naming_style.camel_case_style.capitalization = camel_case
#### Diagnostics ####
# Formatting violations fail the build, and that is now the whole of the enforcement: CI
# has no `dotnet format --verify-no-changes` step any more, because this line already
# fails it.
dotnet_diagnostic.IDE0055.severity = error
# ConfigureAwait is not meaningful in ASP.NET Core (no SynchronizationContext). It IS
# meaningful in the Avalonia client, which re-enables CA2007 in its own .editorconfig.
dotnet_diagnostic.CA2007.severity = none
# Require LoggerMessage source generation over ILogger extension calls — allocation-free,
# and event ids plus message templates become a greppable inventory rather than string
# literals scattered through the code. Effectively an error, since warnings are errors;
# stated as such rather than pretending it is advisory.
dotnet_diagnostic.CA1848.severity = warning
# Exceptions carry ProblemDetails codes, not localised text.
dotnet_diagnostic.CA1303.severity = none
# CA1711 reserves the suffixes Flags, Permission, Collection, Stream and friends for
# .NET Framework CAS and BCL base types that have no bearing on this codebase. The BCL
# itself ships BindingFlags. PermissionFlags is the clearest name for a [Flags] enum of
# permissions, and contorting domain vocabulary to satisfy a legacy rule costs more than
# it returns.
dotnet_diagnostic.CA1711.severity = none
# CA1724 flags any type whose name collides with a BCL *namespace* (e.g. a type named
# Permissions vs System.Security.Permissions). Namespace-qualified resolution makes this
# a non-issue in practice and it heavily constrains domain naming.
dotnet_diagnostic.CA1724.severity = none
# MA0048 requires one type per file. Good for large types, actively worse for small DTO
# clusters: splitting SyncPullRequest from SyncPullResponse means a reviewer opens two files
# to understand one endpoint's contract. The BCL groups related types the same way.
dotnet_diagnostic.MA0048.severity = none
# We use file-scoped namespaces and modern C#; these fire on deliberate style choices.
dotnet_diagnostic.CA1812.severity = none # internal types instantiated by DI
dotnet_diagnostic.CA1849.severity = warning # sync call in async method
[tests/**/*.cs]
# Test classes are instantiated by xunit, and test data is often public static.
dotnet_diagnostic.CA1812.severity = none
dotnet_diagnostic.CA1034.severity = none
# A test name is documentation: Push_WithAStaleVersion_ReportsConflict says what is being
# asserted, and Push_WithAStaleVersion_ReportsConflictAsync says the same thing plus an
# implementation detail nobody reading a failure report cares about. The async suffix
# convention exists so callers can spot awaitables; a test method has no callers.
dotnet_diagnostic.IDE1006.severity = none
# Matches every project's Migrations folder, not just Infrastructure's: the client's local cache
# is migrated too. A glob rather than one block per project, so a third one is not a build break
# for whoever adds it.
[src/*/Migrations/*.cs]
# EF Core generates these; do not lint or format them.
generated_code = true
dotnet_analyzer_diagnostic.severity = none
dotnet_diagnostic.IDE0055.severity = none
# IDE style rules are not covered by dotnet_analyzer_diagnostic above and have to be named.
dotnet_diagnostic.IDE0161.severity = none
[*.{g,g.i,generated,designer}.cs]
# Source-generator output. In particular the System.Text.Json generator emits a public
# JsonTypeInfo member per serialisable type, which PublicApiAnalyzers would otherwise demand
# be tracked in PublicAPI.txt — hundreds of entries derived mechanically from the
# [JsonSerializable] list, drowning the entries that describe the actual wire contract.
generated_code = true
dotnet_analyzer_diagnostic.severity = none
dotnet_diagnostic.RS0016.severity = none
dotnet_diagnostic.RS0017.severity = none
dotnet_diagnostic.RS0041.severity = none
dotnet_diagnostic.IDE0055.severity = none