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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions .github/workflows/code-style.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: code-style

# Trial of the ecosystem's code-style policy (OCCTSwiftIO#36, following the
# reference rollout at OCCTSwiftScripts#114/#115); see
# docs/code-style-policy-proposal-2026-08.md in the `ecosystem` repo for the
# full rationale. Full sweep rather than a gradual exemption manifest because
# this repo is small enough to bring fully into compliance in one PR and go
# straight to a blocking gate.
#
# Pure text analysis (formatting + lint), no compiled output needed by any of
# the three checks, so this stays a macOS runner only because that's where
# swift-format and swiftlint are both readily available via Homebrew.
#
# swift-format and SwiftLint are blocking: formatting has no judgment call in
# it. The comment-ratio check is report-only by design (see the script's own
# header) and is not a gate; it always exits 0.

on:
push:
paths:
- 'Sources/**'
- 'Tests/**'
- '.swift-format'
- '.swiftlint.yml'
- 'Scripts/comment-ratio-check.sh'
- '.github/workflows/code-style.yml'
pull_request:
paths:
- 'Sources/**'
- 'Tests/**'
- '.swift-format'
- '.swiftlint.yml'
- 'Scripts/comment-ratio-check.sh'
- '.github/workflows/code-style.yml'
workflow_dispatch:

jobs:
code-style:
runs-on: macos-15
steps:
- uses: actions/checkout@v4

- name: Install swift-format and SwiftLint
run: brew install swift-format swiftlint

- name: swift-format lint --strict
run: |
find Sources Tests -name '*.swift' -print0 \
| xargs -0 swift-format lint --strict --configuration .swift-format

- name: swiftlint lint --strict
run: swiftlint lint --strict --config .swiftlint.yml

- name: Comment:code ratio (report-only, never fails)
run: Scripts/comment-ratio-check.sh
75 changes: 75 additions & 0 deletions .swift-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
{
"version" : 1,
"lineLength" : 100,
"indentation" : {
"spaces" : 4
},
"tabWidth" : 4,
"maximumBlankLines" : 1,
"respectsExistingLineBreaks" : true,
"lineBreakBeforeControlFlowKeywords" : false,
"lineBreakBeforeEachArgument" : false,
"lineBreakBeforeEachGenericRequirement" : false,
"lineBreakBetweenDeclarationAttributes" : false,
"multiElementCollectionTrailingCommas" : true,
"prioritizeKeepingFunctionOutputTogether" : false,
"reflowMultilineStringLiterals" : "never",
"spacesAroundRangeFormationOperators" : false,
"spacesBeforeEndOfLineComments" : 2,
"fileScopedDeclarationPrivacy" : {
"accessLevel" : "private"
},
"orderedImports" : {
"includeConditionalImports" : false
},
"noAssignmentInExpressions" : {
"allowedFunctions" : [
"XCTAssertNoThrow"
]
},
"rules" : {
"AllPublicDeclarationsHaveDocumentation" : false,
"AlwaysUseLiteralForEmptyCollectionInit" : false,
"AlwaysUseLowerCamelCase" : true,
"AmbiguousTrailingClosureOverload" : true,
"AvoidRetroactiveConformances" : true,
"BeginDocumentationCommentWithOneLineSummary" : true,
"DoNotUseSemicolons" : true,
"DontRepeatTypeInStaticProperties" : true,
"FileScopedDeclarationPrivacy" : true,
"FullyIndirectEnum" : true,
"GroupNumericLiterals" : true,
"IdentifiersMustBeASCII" : true,
"NeverForceUnwrap" : false,
"NeverUseForceTry" : false,
"NeverUseImplicitlyUnwrappedOptionals" : false,
"NoAccessLevelOnExtensionDeclaration" : true,
"NoAssignmentInExpressions" : true,
"NoBlockComments" : true,
"NoCasesWithOnlyFallthrough" : true,
"NoEmptyLinesOpeningClosingBraces" : false,
"NoEmptyTrailingClosureParentheses" : true,
"NoLabelsInCasePatterns" : true,
"NoLeadingUnderscores" : false,
"NoParensAroundConditions" : true,
"NoPlaygroundLiterals" : true,
"NoVoidReturnOnFunctionSignature" : true,
"OmitExplicitReturns" : false,
"OneCasePerLine" : true,
"OneVariableDeclarationPerLine" : true,
"OnlyOneTrailingClosureArgument" : true,
"OrderedImports" : true,
"ReplaceForEachWithForLoop" : true,
"ReturnVoidInsteadOfEmptyTuple" : true,
"TypeNamesShouldBeCapitalized" : true,
"UseEarlyExits" : false,
"UseExplicitNilCheckInConditions" : true,
"UseLetInEveryBoundCaseVariable" : true,
"UseShorthandTypeNames" : true,
"UseSingleLinePropertyGetter" : true,
"UseSynthesizedInitializer" : true,
"UseTripleSlashForDocumentationComments" : true,
"UseWhereClausesInForLoops" : false,
"ValidateDocumentationComments" : true
}
}
27 changes: 27 additions & 0 deletions .swiftlint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Deliberately narrow: `only_rules`, not `disabled_rules`. SwiftLint's default
# rule set covers two kinds of territory this repo doesn't want it opining on:
#
# - Layout (colon/comma/opening_brace/line_length/...): swift-format already
# owns this; running both fights, since they can disagree on the same line.
# - Code-quality/complexity (identifier_name, cyclomatic_complexity,
# function_body_length, nesting, type_body_length, file_length, ...): a
# separate concern from code style, and one that overlaps the ecosystem's
# own code-structure policy (a repo that needs a structural pass runs one
# as its own scoped initiative, not as a side effect of a style-lint gate).
# identifier_name's default 3-char minimum in particular is not a fit for
# this codebase's short, conventional locals in dense numerical/graph code
# (i, db, g, sv, ev): 548 hits on first run in OCCTSwiftScripts, the sibling
# repo this config is ported from; none of them real problems.
#
# What's left is the one rule that catches something swift-format has no
# equivalent for: a doc comment not attached to any declaration.
#
# See docs/code-style-policy-proposal-2026-08.md in the ecosystem repo for
# the full rationale.

only_rules:
- orphaned_doc_comment

excluded:
- .build
- Tests
59 changes: 59 additions & 0 deletions Scripts/comment-ratio-check.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#!/usr/bin/env bash
# comment-ratio-check.sh: flag Swift files where comment lines outnumber code
# lines, as a signal for a human to look, not a fail.
#
# Part of the ecosystem's code-style policy trial (OCCTSwiftIO#36, following
# the reference rollout at OCCTSwiftScripts#114); see
# docs/code-style-policy-proposal-2026-08.md in the `ecosystem` repo for the
# full rationale. A high ratio is sometimes legitimate (a small function with
# several real caveats worth spelling out) and sometimes means a doc comment
# has drifted into restating design rationale that belongs in docs/ instead
# (see the proposal's own CurveAdaptors.md finding for what that looks like
# once it's had years to drift): this script surfaces the number, it doesn't
# judge which case it is. Report-only: always exits 0, same as
# check-docs-existence.py's own `--coverage` mode in OCCTSwift/Scripts, and
# for the same reason: failing every file above a threshold on day one, in a
# codebase nobody has swept yet, punishes the report instead of the problem.
#
# Usage:
# Scripts/comment-ratio-check.sh # default threshold: 1.0
# Scripts/comment-ratio-check.sh 1.5 # custom threshold
set -euo pipefail

threshold="${1:-1.0}"

[ -d Sources ] || { echo "FAIL: Sources/ not found; run from the repo root" >&2; exit 1; }

flagged=0

while IFS= read -r -d '' file; do
comment=0
code=0
while IFS= read -r line; do
trimmed="${line#"${line%%[![:space:]]*}"}"
[ -z "$trimmed" ] && continue
case "$trimmed" in
//*) comment=$((comment + 1)) ;;
*) code=$((code + 1)) ;;
esac
done < "$file"

[ "$code" -eq 0 ] && continue

# POSIX sh has no float math; compare as comment*100 >= threshold*code so
# a fractional threshold (the common case: 1.0, 1.5) still works exactly.
threshold_x100=$(awk -v t="$threshold" 'BEGIN { printf "%d", t * 100 }')
if [ $((comment * 100)) -ge $((threshold_x100 * code)) ]; then
ratio=$(awk -v c="$comment" -v d="$code" 'BEGIN { printf "%.2f", c / d }')
printf ' %-55s comment=%-5d code=%-5d ratio=%s\n' "$file" "$comment" "$code" "$ratio"
flagged=$((flagged + 1))
fi
done < <(find Sources -name '*.swift' -print0 | sort -z)

if [ "$flagged" -eq 0 ]; then
echo "comment-ratio-check: no files at or above ${threshold}x comment:code (Sources/)"
else
echo "comment-ratio-check: $flagged file(s) at or above ${threshold}x comment:code (Sources/), not a failure, a signal to look"
fi

exit 0
Loading
Loading