Skip to content

Commit 5953af5

Browse files
committed
Use swift-format + Lint CI
1 parent 15002ee commit 5953af5

27 files changed

Lines changed: 859 additions & 808 deletions

.github/workflows/tests.yml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,34 @@ jobs:
7777
with:
7878
build_parameters: "-c ${{ matrix.config.mode }}"
7979
codecov_token: "${{ secrets.CODECOV_TOKEN }}"
80+
81+
lint:
82+
runs-on: ubuntu-latest
83+
84+
timeout-minutes: 20
85+
86+
container: swift:6.1-noble
87+
88+
defaults:
89+
run:
90+
shell: bash
91+
92+
steps:
93+
- name: Configure git
94+
run: |
95+
git config --global --add safe.directory '*'
96+
97+
- name: Check out ${{ github.event.repository.name }}
98+
uses: actions/checkout@v4
99+
100+
- name: Check config file
101+
run: |
102+
if [ ! -f .swift-format ]; then
103+
echo "No .swift-format file found."
104+
exit 1
105+
fi
106+
107+
- name: Lint
108+
run: |
109+
apt -q update && apt -yq install curl
110+
curl -s https://raw.githubusercontent.com/swiftlang/github-workflows/refs/heads/main/.github/workflows/scripts/check-swift-format.sh | bash

.swift-format

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
{
2+
"version": 1,
3+
"indentation": {
4+
"spaces": 4
5+
},
6+
"tabWidth": 4,
7+
"fileScopedDeclarationPrivacy": {
8+
"accessLevel": "private"
9+
},
10+
"spacesAroundRangeFormationOperators": false,
11+
"indentConditionalCompilationBlocks": false,
12+
"indentSwitchCaseLabels": false,
13+
"lineBreakAroundMultilineExpressionChainComponents": false,
14+
"lineBreakBeforeControlFlowKeywords": false,
15+
"lineBreakBeforeEachArgument": true,
16+
"lineBreakBeforeEachGenericRequirement": true,
17+
"lineLength": 100,
18+
"maximumBlankLines": 1,
19+
"respectsExistingLineBreaks": true,
20+
"prioritizeKeepingFunctionOutputTogether": true,
21+
"rules": {
22+
"AllPublicDeclarationsHaveDocumentation": false,
23+
"AlwaysUseLiteralForEmptyCollectionInit": false,
24+
"AlwaysUseLowerCamelCase": false,
25+
"AmbiguousTrailingClosureOverload": true,
26+
"BeginDocumentationCommentWithOneLineSummary": false,
27+
"DoNotUseSemicolons": true,
28+
"DontRepeatTypeInStaticProperties": false,
29+
"FileScopedDeclarationPrivacy": true,
30+
"FullyIndirectEnum": true,
31+
"GroupNumericLiterals": true,
32+
"IdentifiersMustBeASCII": true,
33+
"NeverForceUnwrap": false,
34+
"NeverUseForceTry": false,
35+
"NeverUseImplicitlyUnwrappedOptionals": false,
36+
"NoAccessLevelOnExtensionDeclaration": true,
37+
"NoAssignmentInExpressions": true,
38+
"NoBlockComments": true,
39+
"NoCasesWithOnlyFallthrough": true,
40+
"NoEmptyTrailingClosureParentheses": true,
41+
"NoLabelsInCasePatterns": true,
42+
"NoLeadingUnderscores": false,
43+
"NoParensAroundConditions": true,
44+
"NoVoidReturnOnFunctionSignature": true,
45+
"OmitExplicitReturns": true,
46+
"OneCasePerLine": true,
47+
"OneVariableDeclarationPerLine": true,
48+
"OnlyOneTrailingClosureArgument": true,
49+
"OrderedImports": true,
50+
"ReplaceForEachWithForLoop": true,
51+
"ReturnVoidInsteadOfEmptyTuple": true,
52+
"UseEarlyExits": false,
53+
"UseExplicitNilCheckInConditions": false,
54+
"UseLetInEveryBoundCaseVariable": false,
55+
"UseShorthandTypeNames": true,
56+
"UseSingleLinePropertyGetter": false,
57+
"UseSynthesizedInitializer": false,
58+
"UseTripleSlashForDocumentationComments": true,
59+
"UseWhereClausesInForLoops": false,
60+
"ValidateDocumentationComments": false
61+
}
62+
}

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@
186186
same "printed page" as the copyright notice for easier
187187
identification within third-party archives.
188188

189-
Copyright [yyyy] [name of copyright owner]
189+
Copyright [2025] [Mahdi Bahrami]
190190

191191
Licensed under the Apache License, Version 2.0 (the "License");
192192
you may not use this file except in compliance with the License.

Package.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@ let package = Package(
1616
.library(
1717
name: "EnumeratorMacro",
1818
targets: ["EnumeratorMacro"]
19-
),
19+
)
2020
],
2121
dependencies: [
2222
.package(
2323
url: "https://github.com/swiftlang/swift-syntax.git",
24-
"509.0.0" ..< "603.0.0"
24+
"509.0.0"..<"603.0.0"
2525
),
2626
.package(
2727
url: "https://github.com/hummingbird-project/swift-mustache.git",

Sources/EnumeratorMacro/Enumerator.swift

Lines changed: 5 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -2,145 +2,8 @@
22
public macro Enumerator(
33
allowedComments: [String] = [],
44
_ templates: String...
5-
) = #externalMacro(
6-
module: "EnumeratorMacroImpl",
7-
type: "EnumeratorMacroType"
8-
)
9-
10-
@Enumerator("""
11-
var caseName: String {
12-
switch self {
13-
{{#cases}}
14-
case .{{name}}: "{{#first(parameters)}} {{name}} {{/first(parameters)}}"
15-
{{/cases}}
16-
}
17-
}
18-
""")
19-
enum TestEnum {
20-
case a(val1: String, val2: Int)
21-
case b
22-
case testCase(testValue: String)
23-
}
24-
25-
public protocol LocalizationServiceProtocol {
26-
static func localizedString(language: String, term: String, parameters: Any...) -> String
27-
}
28-
29-
package enum SharedConfiguration {
30-
package enum Env: String {
31-
case local
32-
case testing
33-
case prod
34-
}
35-
36-
package static var env: Env { fatalError() }
37-
}
38-
39-
@Enumerator(allowedComments: ["business_error", "l8n_params"],
40-
"""
41-
public enum Subtype: String, Equatable {
42-
{{#cases}}
43-
case {{name}}
44-
{{/cases}}
45-
}
46-
""",
47-
"""
48-
public var subtype: Subtype {
49-
switch self {
50-
{{#cases}}
51-
case .{{name}}:
52-
.{{name}}
53-
{{/cases}}
54-
}
55-
}
56-
""",
57-
"""
58-
public var errorCode: String {
59-
switch self {
60-
{{#cases}}
61-
case .{{name}}:
62-
"ERROR-{{plusOne(index)}}"
63-
{{/cases}}
64-
}
65-
}
66-
""",
67-
"""
68-
public var loggerMetadata: [String: String] {
69-
switch self {
70-
{{#cases}} {{^isEmpty(parameters)}}
71-
case let .{{name}}{{withParens(joined(names(parameters)))}}:
72-
[
73-
"caseName": self.caseName,
74-
{{#names(parameters)}}
75-
"case_{{.}}": String(reflecting: {{.}}),
76-
{{/names(parameters)}}
77-
]
78-
{{/isEmpty(parameters)}} {{/cases}}
79-
default:
80-
["caseName": self.caseName]
81-
}
82-
}
83-
""",
84-
"""
85-
private var localizationParameters: [Any] {
86-
switch self {
87-
{{#cases}} {{^isEmpty(parameters)}}
88-
89-
{{^isEmpty(l8n_params(comments))}}
90-
case let .{{name}}{{withParens(joined(names(parameters)))}}:
91-
[{{l8n_params(comments)}}]
92-
{{/isEmpty(l8n_params(comments))}}
93-
94-
{{^exists(l8n_params(comments))}}
95-
case let .{{name}}{{withParens(joined(names(parameters)))}}:
96-
[
97-
{{#parameters}}
98-
{{name}}{{#isOptional}} as Any{{/isOptional}},
99-
{{/parameters}}
100-
]
101-
{{/exists(l8n_params(comments))}}
102-
103-
{{/isEmpty(parameters)}} {{/cases}}
104-
default:
105-
[]
106-
}
107-
}
108-
""")
109-
@Enumerator(
110-
allowedComments: ["business_error", "l8n_params"],
111-
#"""
112-
package var isBusinessLogicError: Bool {
113-
switch self {
114-
case
115-
{{#cases}}{{#bool(business_error(comments))}}
116-
.{{name}},
117-
{{/bool(business_error(comments))}}{{/cases}}
118-
:
119-
return true
120-
default:
121-
return false
122-
}
123-
}
124-
"""#
125-
)
126-
public enum ErrorMessage {
127-
public static let localizationServiceType: (any LocalizationServiceProtocol.Type)? = nil
128-
129-
case allergenAlreadyAdded // business_error
130-
case alreadyOngoingInventory
131-
case apiKeyWithoutEnoughPermission(integration: String, other: Bool?, Int)
132-
case databaseError(error: any Error, isConstraintViolation: Bool) // business_error; l8n_params:
133-
134-
public var caseName: String {
135-
self.subtype.rawValue
136-
}
137-
138-
public func toString(_ language: String) -> String {
139-
let translation = Self.localizationServiceType?.localizedString(
140-
language: language,
141-
term: "api.\(self.caseName)",
142-
parameters: self.localizationParameters
143-
)
144-
return translation ?? (SharedConfiguration.env == .testing ? String(reflecting: self) : "<localization failed to load for \(self.caseName)>")
145-
}
146-
}
5+
) =
6+
#externalMacro(
7+
module: "EnumeratorMacroImpl",
8+
type: "EnumeratorMacroType"
9+
)

Sources/EnumeratorMacroImpl/Arguments.swift

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1+
import SwiftDiagnostics
12
import SwiftSyntax
23
import SwiftSyntaxMacros
3-
import SwiftDiagnostics
44

55
struct Arguments {
66

@@ -75,10 +75,12 @@ struct Arguments {
7575
)
7676
continue
7777
}
78-
guard let string = self.requireStringLiteralOrThrowDiagnostic(
79-
node: stringLiteral,
80-
context: context
81-
) else { continue }
78+
guard
79+
let string = self.requireStringLiteralOrThrowDiagnostic(
80+
node: stringLiteral,
81+
context: context
82+
)
83+
else { continue }
8284
self.allowedComments!.keys.append(string)
8385
}
8486
}
@@ -98,10 +100,12 @@ struct Arguments {
98100
)
99101
return
100102
}
101-
guard let template = self.requireStringLiteralOrThrowDiagnostic(
102-
node: stringLiteral,
103-
context: context
104-
) else {
103+
guard
104+
let template = self.requireStringLiteralOrThrowDiagnostic(
105+
node: stringLiteral,
106+
context: context
107+
)
108+
else {
105109
return
106110
}
107111
self.templates.append((template, stringLiteral))

0 commit comments

Comments
 (0)