forked from danielraffel/SwiftCatalyst
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgit-commits.mdc
More file actions
413 lines (358 loc) · 16.9 KB
/
git-commits.mdc
File metadata and controls
413 lines (358 loc) · 16.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
---
title: Git Conventional Commits for Swift Projects
description: Guidelines for automatically committing changes made by CursorAI using conventional commits format for Swift projects and all related assets
glob: "**/*.{mdc,swift,yml,yaml,plist,pbxproj,xcodeproj,xcworkspace,xcconfig,strings,storyboard,xib,png,jpg,jpeg,gif,svg,pdf,mp3,mp4,mov,wav,otf,ttf,json,md,txt}"
alwaysApply: true
---
# Git Conventional Commits for Swift Projects
This rule establishes a framework for automatically generating Git commits in the conventional commits format for Swift projects, including all configuration files and asset types.
## Conventional Commits Format
All commits should follow the conventional commits format:
```
<type>(<scope>): <description>
```
Where:
- **type**: Indicates the kind of change being made
- **scope**: Optional field indicating the section of the codebase affected
- **description**: Brief description of the change in imperative mood
## Swift-Specific Types and Scopes
### Commit Types
- **feat**: A new feature or functionality
- **fix**: A bug fix
- **refactor**: Code change that neither fixes a bug nor adds a feature
- **docs**: Documentation only changes
- **style**: Changes that do not affect code logic (whitespace, formatting, etc.)
- **test**: Adding or correcting tests
- **perf**: Performance improvements
- **chore**: Changes to build process or auxiliary tools
- **ui**: UI/UX improvements (specific to Swift UI components)
- **config**: Changes to configuration files
- **build**: Changes to Xcode build settings, project files, or build scripts
- **i18n**: Internationalization and localization changes
- **assets**: Adding or updating media and other resource files
### Scope Conventions for Swift Projects
- **app**: App-level changes (e.g., AppDelegate, SceneDelegate)
- **view**: View layer changes (UIView, SwiftUI View components)
- **controller**: View controller changes
- **presenter**: Presenter layer (VIPER/MVP)
- **interactor**: Interactor layer (VIPER)
- **entity**: Model/entity changes
- **router**: Navigation/routing logic
- **networking**: API/networking code
- **persistence**: CoreData or other persistence mechanisms
- **utils**: Utility functions
- **extensions**: Swift extensions
- **config**: Configuration changes
- **project**: Xcode project settings
- **assets**: Images, colors, and other resources
- **i18n**: Localization files
- **deps**: Dependencies and packages
- **media**: Audio, video, and other media files
- **fonts**: Typography assets
- **docs**: Documentation files
## Automated Commit Rule
<rule>
name: swift_conventional_commits
description: Automatically commit changes made by CursorAI using conventional commits format for Swift projects and all related assets
filters:
- type: event
pattern: "build_success"
- type: file_change
pattern: "*"
actions:
- type: execute
command: |
# Extract the change type and scope from the changes and description
CHANGE_TYPE=""
# Determine type based on what was changed
case "$CHANGE_DESCRIPTION" in
*"add"*|*"create"*|*"implement"*|*"new feature"*)
CHANGE_TYPE="feat";;
*"fix"*|*"correct"*|*"resolve"*|*"bug"*)
CHANGE_TYPE="fix";;
*"refactor"*|*"restructure"*|*"reorganize"*)
CHANGE_TYPE="refactor";;
*"test"*|*"unit test"*|*"ui test"*)
CHANGE_TYPE="test";;
*"doc"*|*"comment"*|*"documentation"*|*"readme"*)
CHANGE_TYPE="docs";;
*"style"*|*"format"*|*"whitespace"*|*"indent"*)
CHANGE_TYPE="style";;
*"perf"*|*"optimize"*|*"performance"*)
CHANGE_TYPE="perf";;
*"ui"*|*"interface"*|*"visual"*)
CHANGE_TYPE="ui";;
*"localize"*|*"translate"*|*"i18n"*)
CHANGE_TYPE="i18n";;
*"image"*|*"icon"*|*"graphic"*|*"asset"*)
CHANGE_TYPE="assets";;
*"audio"*|*"sound"*|*"music"*|*"video"*)
CHANGE_TYPE="assets";;
*)
# Look at file extension to determine type for non-keyword cases
if [[ "$FILE" == *".xcodeproj"* || "$FILE" == *".pbxproj"* || "$FILE" == *".xcworkspace"* ]]; then
CHANGE_TYPE="build"
elif [[ "$FILE" == *".plist"* || "$FILE" == *".xcconfig"* || "$FILE" == *".yml"* || "$FILE" == *".yaml"* || "$FILE" == *".json"* ]]; then
CHANGE_TYPE="config"
elif [[ "$FILE" == *".strings"* || "$FILE" == *".stringsdict"* ]]; then
CHANGE_TYPE="i18n"
elif [[ "$FILE" == *".png"* || "$FILE" == *".jpg"* || "$FILE" == *".jpeg"* || "$FILE" == *".gif"* || "$FILE" == *".svg"* || "$FILE" == *".pdf"* ]]; then
CHANGE_TYPE="assets"
elif [[ "$FILE" == *".mp3"* || "$FILE" == *".mp4"* || "$FILE" == *".mov"* || "$FILE" == *".wav"* ]]; then
CHANGE_TYPE="assets"
elif [[ "$FILE" == *".otf"* || "$FILE" == *".ttf"* || "$FILE" == *".woff"* ]]; then
CHANGE_TYPE="assets"
elif [[ "$FILE" == *".md"* || "$FILE" == *".txt"* || "$FILE" == *"README"* || "$FILE" == *"LICENSE"* ]]; then
CHANGE_TYPE="docs"
else
CHANGE_TYPE="chore"
fi
;;
esac
# Extract scope based on file type and location
if [[ "$FILE" == *".swift" ]]; then
# Swift files follow the standard Swift scoping
if [[ "$FILE" == *"View.swift" || "$FILE" == *"/Views/"* || "$FILE" == *"/View/"* ]]; then
SCOPE="view"
elif [[ "$FILE" == *"ViewController.swift" || "$FILE" == *"/ViewControllers/"* ]]; then
SCOPE="controller"
elif [[ "$FILE" == *"Presenter.swift" || "$FILE" == *"/Presenters/"* ]]; then
SCOPE="presenter"
elif [[ "$FILE" == *"Interactor.swift" || "$FILE" == *"/Interactors/"* ]]; then
SCOPE="interactor"
elif [[ "$FILE" == *"Router.swift" || "$FILE" == *"/Routers/"* ]]; then
SCOPE="router"
elif [[ "$FILE" == *"Model.swift" || "$FILE" == *"Entity.swift" || "$FILE" == *"/Models/"* || "$FILE" == *"/Entities/"* ]]; then
SCOPE="entity"
elif [[ "$FILE" == *"Network"* || "$FILE" == *"API"* || "$FILE" == *"/Networking/"* ]]; then
SCOPE="networking"
elif [[ "$FILE" == *"CoreData"* || "$FILE" == *"Storage"* || "$FILE" == *"/Persistence/"* ]]; then
SCOPE="persistence"
elif [[ "$FILE" == *"Extension"* || "$FILE" == *"/Extensions/"* ]]; then
SCOPE="extensions"
elif [[ "$FILE" == *"Util"* || "$FILE" == *"Helper"* || "$FILE" == *"/Utils/"* || "$FILE" == *"/Helpers/"* ]]; then
SCOPE="utils"
elif [[ "$FILE" == *"AppDelegate.swift" || "$FILE" == *"SceneDelegate.swift" ]]; then
SCOPE="app"
else
# Default: use the directory name
SCOPE=$(dirname "$FILE" | sed 's/.*\///' | tr '[:upper:]' '[:lower:]')
fi
elif [[ "$FILE" == *".plist" ]]; then
SCOPE="config"
elif [[ "$FILE" == *".xcodeproj"* || "$FILE" == *".pbxproj"* || "$FILE" == *".xcworkspace"* || "$FILE" == *".xcconfig"* ]]; then
SCOPE="project"
elif [[ "$FILE" == *".yml"* || "$FILE" == *".yaml"* || "$FILE" == *".json"* ]]; then
# For YAML/JSON files, try to determine their purpose
if [[ "$FILE" == *"fastlane"* || "$FILE" == *"ci"* || "$FILE" == *".github/"* ]]; then
SCOPE="ci"
elif [[ "$FILE" == *"pod"* || "$FILE" == *"package"* || "$FILE" == *"cartfile"* ]]; then
SCOPE="deps"
else
SCOPE="config"
fi
elif [[ "$FILE" == *".strings"* || "$FILE" == *".stringsdict"* ]]; then
SCOPE="i18n"
elif [[ "$FILE" == *".storyboard"* || "$FILE" == *".xib"* ]]; then
SCOPE="view"
elif [[ "$FILE" == *"/Assets.xcassets/"* || "$FILE" == *".imageset/"* || "$FILE" == *".colorset/"* ]]; then
SCOPE="assets"
elif [[ "$FILE" == *".png"* || "$FILE" == *".jpg"* || "$FILE" == *".jpeg"* || "$FILE" == *".gif"* || "$FILE" == *".svg"* || "$FILE" == *".pdf"* ]]; then
SCOPE="assets"
elif [[ "$FILE" == *".mp3"* || "$FILE" == *".wav"* ]]; then
SCOPE="media"
elif [[ "$FILE" == *".mp4"* || "$FILE" == *".mov"* ]]; then
SCOPE="media"
elif [[ "$FILE" == *".otf"* || "$FILE" == *".ttf"* || "$FILE" == *".woff"* ]]; then
SCOPE="fonts"
elif [[ "$FILE" == *".md"* || "$FILE" == *"README"* || "$FILE" == *"LICENSE"* ]]; then
SCOPE="docs"
else
# Fallback: derive scope from directory structure
if [[ "$FILE" == *"/Resources/"* || "$FILE" == *"/Assets/"* ]]; then
SCOPE="assets"
elif [[ "$FILE" == *"/Media/"* || "$FILE" == *"/Audio/"* || "$FILE" == *"/Video/"* ]]; then
SCOPE="media"
elif [[ "$FILE" == *"/Fonts/"* ]]; then
SCOPE="fonts"
elif [[ "$FILE" == *"/Configuration/"* || "$FILE" == *"/Config/"* ]]; then
SCOPE="config"
elif [[ "$FILE" == *"/Documentation/"* || "$FILE" == *"/Docs/"* ]]; then
SCOPE="docs"
else
# Use the parent directory name
SCOPE=$(dirname "$FILE" | sed 's/.*\///' | tr '[:upper:]' '[:lower:]')
fi
fi
# Format the commit message
COMMIT_MSG="$CHANGE_TYPE($SCOPE): $CHANGE_DESCRIPTION"
# Determine which files to add based on the file type
if [[ "$FILE" == *".swift" && -n "$MODULE_NAME" ]]; then
# For Swift files in modules, try to group related module files
MODULE_NAME=$(basename "$FILE" | sed 's/[A-Z][a-z]*\.swift$//')
git add $(find . -name "$MODULE_NAME*.swift")
elif [[ "$FILE" == *".xcodeproj"* || "$FILE" == *".pbxproj"* ]]; then
# For Xcode project files, add the entire project
PROJECT_DIR=$(dirname "$FILE")
git add "$PROJECT_DIR"
elif [[ "$FILE" == *"/Assets.xcassets/"* ]]; then
# For asset changes, add the entire asset catalog
ASSET_CATALOG=$(echo "$FILE" | sed 's/\(.*\.xcassets\).*/\1/')
git add "$ASSET_CATALOG"
elif [[ "$FILE" == *".imageset/"* || "$FILE" == *".colorset/"* ]]; then
# Add the entire imageset/colorset directory
ASSET_SET=$(echo "$FILE" | sed 's/\(.*\.imageset\|.*\.colorset\).*/\1/')
git add "$ASSET_SET"
elif [[ "$FILE" == *"/Fonts/"* && ("$FILE" == *".otf"* || "$FILE" == *".ttf"* || "$FILE" == *".woff"*) ]]; then
# For font files, add all related files in the directory
FONT_NAME=$(basename "$FILE" | sed 's/\.[^.]*$//')
FONT_DIR=$(dirname "$FILE")
git add "$FONT_DIR/$FONT_NAME"*
elif [[ ("$FILE" == *".mp3"* || "$FILE" == *".wav"* || "$FILE" == *".mp4"* || "$FILE" == *".mov"*) ]]; then
# For media files, just add the specific file
git add "$FILE"
else
# Default: just add the specific file
git add "$FILE"
fi
# Commit with the formatted message
git commit -m "$COMMIT_MSG"
- type: suggest
message: |
All changes should be committed using conventional commits format with Swift and asset-specific scopes:
Format: <type>(<scope>): <description>
Types:
- feat: A new feature or functionality
- fix: A bug fix
- refactor: Code refactoring
- docs: Documentation updates
- style: Formatting changes
- test: Adding/fixing tests
- perf: Performance improvements
- ui: UI/UX improvements
- config: Configuration changes
- build: Xcode project/build changes
- i18n: Localization changes
- assets: Adding or updating assets
- chore: Other changes
Common scopes:
- view: SwiftUI/UIKit views or storyboards
- controller/presenter/interactor/router: VIPER components
- entity: Model/entity changes
- networking: API/networking code
- persistence: Data storage
- utils/extensions: Utilities
- project: Xcode project settings
- config: Configuration files
- assets: Images and static resources
- media: Audio and video files
- fonts: Typography resources
- docs: Documentation files
- i18n: Localization files
- deps: Dependencies
The description should be clear and concise in imperative mood.
examples:
- input: |
# After adding image assets
CHANGE_DESCRIPTION="add app icon set"
FILE="Assets.xcassets/AppIcon.imageset/icon.png"
output: "assets(assets): add app icon set"
- input: |
# After adding audio files
CHANGE_DESCRIPTION="add notification sound effects"
FILE="Resources/Sounds/notification.mp3"
output: "assets(media): add notification sound effects"
- input: |
# After adding custom fonts
CHANGE_DESCRIPTION="integrate SF Mono font family"
FILE="Fonts/SFMono-Regular.otf"
output: "assets(fonts): integrate SF Mono font family"
- input: |
# After adding video tutorial
CHANGE_DESCRIPTION="add onboarding tutorial video"
FILE="Resources/Videos/onboarding.mp4"
output: "assets(media): add onboarding tutorial video"
- input: |
# After updating documentation
CHANGE_DESCRIPTION="update installation instructions"
FILE="README.md"
output: "docs(docs): update installation instructions"
metadata:
priority: high
version: 1.0
</rule>
## File Type Handling
This rule handles all file types commonly found in Swift/Xcode projects:
### Code Files
- **Swift (.swift)**: Primary source code files
- **Objective-C (.m, .h)**: Legacy or bridging code
### Configuration Files
- **Property Lists (.plist)**: App configuration
- **YAML (.yml, .yaml)**: Build configuration, CI/CD
- **JSON (.json)**: Data configuration
- **XCConfig (.xcconfig)**: Xcode build settings
### Xcode Project Files
- **Project Files (.xcodeproj, .pbxproj)**: Project structure
- **Workspace Files (.xcworkspace)**: Multi-project workspaces
### Interface Files
- **Storyboards (.storyboard)**: Visual UI layouts
- **XIB Files (.xib)**: Individual view controllers/views
### Image Assets
- **Asset Catalogs (.xcassets)**: Images, colors, etc.
- **Bitmap Images (.png, .jpg, .jpeg)**: Raster graphics
- **Vector Graphics (.svg, .pdf)**: Scalable graphics
- **Animated Graphics (.gif)**: Animated images
### Audio Assets
- **Audio Files (.mp3, .wav)**: Sound effects, music
- **Audio Configuration**: Audio session settings
### Video Assets
- **Video Files (.mp4, .mov)**: Video content
- **Video Thumbnails**: Preview images
### Typography Assets
- **Font Files (.otf, .ttf, .woff)**: Custom typefaces
### Documentation
- **Markdown (.md)**: Documentation files
- **Text (.txt)**: Plain text notes
- **License Files**: Legal documentation
### Localization
- **Strings Files (.strings, .stringsdict)**: Translations
## Asset Management Strategy
Different types of assets require different handling strategies:
### Image Assets
- **Asset Catalogs**: When an asset in a catalog changes, the entire image/color set is added
- **Individual Images**: When loose image files change, only that specific file is added
- **App Icons**: Special handling for app icons, adding the entire icon set
### Audio/Video Assets
- Typically committed individually, as they can be large files
- Consider using Git LFS for large media files
- Group related sound effects or video clips when logical
### Font Assets
- When adding or changing a font, add all related font weights and styles together
- Consider the licensing requirements of fonts when committing
### Documentation Assets
- Commit documentation with related code changes when possible
- For standalone documentation updates, group related files
## Commit Message Examples for Different Asset Types
### Image Assets
- `assets(assets): add user profile placeholder images`
- `ui(assets): update tab bar icons with new design language`
- `fix(assets): correct app icon transparency issue`
### Audio/Video Assets
- `assets(media): add tutorial voice-over narration`
- `feat(media): implement custom sound effects for interactions`
- `perf(media): optimize video assets for size reduction`
### Typography Assets
- `assets(fonts): integrate custom brand typeface`
- `feat(fonts): add variable font support for dynamic sizing`
- `fix(fonts): resolve font rendering issues on iOS 16`
### Configuration Assets
- `config(project): update build settings for TestFlight distribution`
- `build(config): modify code signing settings for CI pipeline`
- `feat(config): add new feature flags for A/B testing`
## Best Practices for Asset Commits
1. **Group Related Changes**: Commit related assets together (e.g., all button icons at once)
2. **Clear Descriptions**: Describe what the assets are for, not just that you added them
3. **Specify Platform/Device**: Note when assets are specific to certain devices (`assets(assets): add iPad-specific launch screens`)
4. **Mention Optimization**: Note when assets have been optimized (`perf(assets): compress PNG images for faster loading`)
5. **Include Source References**: Reference design tools or sources (`assets(assets): implement Figma-approved icon set`)
<!-- Copyright (c) 2025 Daniel Raffel. All rights reserved. SPDX-License-Identifier: Proprietary -->