mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-03-30 13:43:26 +08:00
feat: add Swift language-specific rules
Add 5 rule files for Swift following the established pattern used by TypeScript, Python, and Go rule sets. Covers Swift 6 strict concurrency, Swift Testing framework, protocol-oriented patterns, Keychain-based secret management, and SwiftFormat/SwiftLint hooks.
This commit is contained in:
@@ -17,7 +17,8 @@ rules/
|
||||
│ └── security.md
|
||||
├── typescript/ # TypeScript/JavaScript specific
|
||||
├── python/ # Python specific
|
||||
└── golang/ # Go specific
|
||||
├── golang/ # Go specific
|
||||
└── swift/ # Swift specific
|
||||
```
|
||||
|
||||
- **common/** contains universal principles — no language-specific code examples.
|
||||
@@ -32,6 +33,7 @@ rules/
|
||||
./install.sh typescript
|
||||
./install.sh python
|
||||
./install.sh golang
|
||||
./install.sh swift
|
||||
|
||||
# Install multiple languages at once
|
||||
./install.sh typescript python
|
||||
@@ -53,6 +55,7 @@ cp -r rules/common ~/.claude/rules/common
|
||||
cp -r rules/typescript ~/.claude/rules/typescript
|
||||
cp -r rules/python ~/.claude/rules/python
|
||||
cp -r rules/golang ~/.claude/rules/golang
|
||||
cp -r rules/swift ~/.claude/rules/swift
|
||||
|
||||
# Attention ! ! ! Configure according to your actual project requirements; the configuration here is for reference only.
|
||||
```
|
||||
|
||||
47
rules/swift/coding-style.md
Normal file
47
rules/swift/coding-style.md
Normal file
@@ -0,0 +1,47 @@
|
||||
---
|
||||
paths:
|
||||
- "**/*.swift"
|
||||
- "**/Package.swift"
|
||||
---
|
||||
# Swift Coding Style
|
||||
|
||||
> This file extends [common/coding-style.md](../common/coding-style.md) with Swift specific content.
|
||||
|
||||
## Formatting
|
||||
|
||||
- **SwiftFormat** for auto-formatting, **SwiftLint** for style enforcement
|
||||
- `swift-format` is bundled with Xcode 16+ as an alternative
|
||||
|
||||
## Immutability
|
||||
|
||||
- Prefer `let` over `var` — define everything as `let` and only change to `var` if the compiler requires it
|
||||
- Use `struct` with value semantics by default; use `class` only when identity or reference semantics are needed
|
||||
|
||||
## Naming
|
||||
|
||||
Follow [Apple API Design Guidelines](https://www.swift.org/documentation/api-design-guidelines/):
|
||||
|
||||
- Clarity at the point of use — omit needless words
|
||||
- Name methods and properties for their roles, not their types
|
||||
- Use `static let` for constants over global constants
|
||||
|
||||
## Error Handling
|
||||
|
||||
Use typed throws (Swift 6+) and pattern matching:
|
||||
|
||||
```swift
|
||||
func load(id: String) throws(LoadError) -> Item {
|
||||
guard let data = try? read(from: path) else {
|
||||
throw .fileNotFound(id)
|
||||
}
|
||||
return try decode(data)
|
||||
}
|
||||
```
|
||||
|
||||
## Concurrency
|
||||
|
||||
Enable Swift 6 strict concurrency checking. Prefer:
|
||||
|
||||
- `Sendable` value types for data crossing isolation boundaries
|
||||
- Actors for shared mutable state
|
||||
- Structured concurrency (`async let`, `TaskGroup`) over unstructured `Task {}`
|
||||
20
rules/swift/hooks.md
Normal file
20
rules/swift/hooks.md
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
paths:
|
||||
- "**/*.swift"
|
||||
- "**/Package.swift"
|
||||
---
|
||||
# Swift Hooks
|
||||
|
||||
> This file extends [common/hooks.md](../common/hooks.md) with Swift specific content.
|
||||
|
||||
## PostToolUse Hooks
|
||||
|
||||
Configure in `~/.claude/settings.json`:
|
||||
|
||||
- **SwiftFormat**: Auto-format `.swift` files after edit
|
||||
- **SwiftLint**: Run lint checks after editing `.swift` files
|
||||
- **swift build**: Type-check modified packages after edit
|
||||
|
||||
## Warning
|
||||
|
||||
Flag `print()` statements — use `os.Logger` or structured logging instead for production code.
|
||||
66
rules/swift/patterns.md
Normal file
66
rules/swift/patterns.md
Normal file
@@ -0,0 +1,66 @@
|
||||
---
|
||||
paths:
|
||||
- "**/*.swift"
|
||||
- "**/Package.swift"
|
||||
---
|
||||
# Swift Patterns
|
||||
|
||||
> This file extends [common/patterns.md](../common/patterns.md) with Swift specific content.
|
||||
|
||||
## Protocol-Oriented Design
|
||||
|
||||
Define small, focused protocols. Use protocol extensions for shared defaults:
|
||||
|
||||
```swift
|
||||
protocol Repository: Sendable {
|
||||
associatedtype Item: Identifiable & Sendable
|
||||
func find(by id: Item.ID) async throws -> Item?
|
||||
func save(_ item: Item) async throws
|
||||
}
|
||||
```
|
||||
|
||||
## Value Types
|
||||
|
||||
- Use structs for data transfer objects and models
|
||||
- Use enums with associated values to model distinct states:
|
||||
|
||||
```swift
|
||||
enum LoadState<T: Sendable>: Sendable {
|
||||
case idle
|
||||
case loading
|
||||
case loaded(T)
|
||||
case failed(Error)
|
||||
}
|
||||
```
|
||||
|
||||
## Actor Pattern
|
||||
|
||||
Use actors for shared mutable state instead of locks or dispatch queues:
|
||||
|
||||
```swift
|
||||
actor Cache<Key: Hashable & Sendable, Value: Sendable> {
|
||||
private var storage: [Key: Value] = [:]
|
||||
|
||||
func get(_ key: Key) -> Value? { storage[key] }
|
||||
func set(_ key: Key, value: Value) { storage[key] = value }
|
||||
}
|
||||
```
|
||||
|
||||
## Dependency Injection
|
||||
|
||||
Inject protocols with default parameters — production uses defaults, tests inject mocks:
|
||||
|
||||
```swift
|
||||
struct UserService {
|
||||
private let repository: any UserRepository
|
||||
|
||||
init(repository: any UserRepository = DefaultUserRepository()) {
|
||||
self.repository = repository
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## References
|
||||
|
||||
See skill: `swift-actor-persistence` for actor-based persistence patterns.
|
||||
See skill: `swift-protocol-di-testing` for protocol-based DI and testing.
|
||||
33
rules/swift/security.md
Normal file
33
rules/swift/security.md
Normal file
@@ -0,0 +1,33 @@
|
||||
---
|
||||
paths:
|
||||
- "**/*.swift"
|
||||
- "**/Package.swift"
|
||||
---
|
||||
# Swift Security
|
||||
|
||||
> This file extends [common/security.md](../common/security.md) with Swift specific content.
|
||||
|
||||
## Secret Management
|
||||
|
||||
- Use **Keychain Services** for sensitive data (tokens, passwords, keys) — never `UserDefaults`
|
||||
- Use environment variables or `.xcconfig` files for build-time secrets
|
||||
- Never hardcode secrets in source — decompilation tools extract them trivially
|
||||
|
||||
```swift
|
||||
let apiKey = ProcessInfo.processInfo.environment["API_KEY"]
|
||||
guard let apiKey, !apiKey.isEmpty else {
|
||||
fatalError("API_KEY not configured")
|
||||
}
|
||||
```
|
||||
|
||||
## Transport Security
|
||||
|
||||
- App Transport Security (ATS) is enforced by default — do not disable it
|
||||
- Use certificate pinning for critical endpoints
|
||||
- Validate all server certificates
|
||||
|
||||
## Input Validation
|
||||
|
||||
- Sanitize all user input before display to prevent injection
|
||||
- Use `URL(string:)` with validation rather than force-unwrapping
|
||||
- Validate data from external sources (APIs, deep links, pasteboard) before processing
|
||||
45
rules/swift/testing.md
Normal file
45
rules/swift/testing.md
Normal file
@@ -0,0 +1,45 @@
|
||||
---
|
||||
paths:
|
||||
- "**/*.swift"
|
||||
- "**/Package.swift"
|
||||
---
|
||||
# Swift Testing
|
||||
|
||||
> This file extends [common/testing.md](../common/testing.md) with Swift specific content.
|
||||
|
||||
## Framework
|
||||
|
||||
Use **Swift Testing** (`import Testing`) for new tests. Use `@Test` and `#expect`:
|
||||
|
||||
```swift
|
||||
@Test("User creation validates email")
|
||||
func userCreationValidatesEmail() throws {
|
||||
#expect(throws: ValidationError.invalidEmail) {
|
||||
try User(email: "not-an-email")
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Test Isolation
|
||||
|
||||
Each test gets a fresh instance — set up in `init`, tear down in `deinit`. No shared mutable state between tests.
|
||||
|
||||
## Parameterized Tests
|
||||
|
||||
```swift
|
||||
@Test("Validates formats", arguments: ["json", "xml", "csv"])
|
||||
func validatesFormat(format: String) throws {
|
||||
let parser = try Parser(format: format)
|
||||
#expect(parser.isValid)
|
||||
}
|
||||
```
|
||||
|
||||
## Coverage
|
||||
|
||||
```bash
|
||||
swift test --enable-code-coverage
|
||||
```
|
||||
|
||||
## Reference
|
||||
|
||||
See skill: `swift-protocol-di-testing` for protocol-based dependency injection and mock patterns with Swift Testing.
|
||||
Reference in New Issue
Block a user