Skip to content

Commit 07ed092

Browse files
committed
feat(lint): add icon color variable policies
1 parent c2d8b87 commit 07ed092

20 files changed

Lines changed: 1257 additions & 30 deletions

‎Sources/ExFigCLI/ExFig.docc/Usage.md‎

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,9 @@ Validate your Figma file structure against your PKL config before exporting:
298298
# Lint with default rules
299299
exfig lint -i exfig.pkl
300300

301+
# Add lint-only policies from a separate config
302+
exfig lint -i exfig.pkl --lint-config lint.pkl
303+
301304
# Only check specific rules
302305
exfig lint -i exfig.pkl --rules naming-convention,deleted-variables
303306

@@ -307,17 +310,18 @@ exfig lint -i exfig.pkl --format json --severity error
307310

308311
### Available Rules
309312

310-
| Rule | Severity | Description |
311-
| -------------------------- | -------- | ------------------------------------------------------ |
312-
| `frame-page-match` | error | Frame/page names in config exist in Figma file |
313-
| `naming-convention` | error | Component names match `nameValidateRegexp` patterns |
314-
| `component-not-frame` | error | Configured frames contain published components |
315-
| `duplicate-component-names`| error | No duplicate component names in configured frames |
316-
| `deleted-variables` | warning | No `deletedButReferenced` variables in collections |
317-
| `alias-chain-integrity` | warning | Variable alias chains resolve without broken refs |
318-
| `dark-mode-variables` | error | With `variablesDarkMode`, fills bound to Variables |
319-
| `dark-mode-suffix` | warning | With `suffixDarkMode`, light components have dark pair |
320-
| `path-data-length` | error | Icon SVG pathData within 32,767-byte AAPT limit |
313+
| Rule | Severity | Description |
314+
| --------------------------- | -------- | ------------------------------------------------------ |
315+
| `frame-page-match` | error | Frame/page names in config exist in Figma file |
316+
| `naming-convention` | error | Component names match `nameValidateRegexp` patterns |
317+
| `component-not-frame` | error | Configured frames contain published components |
318+
| `duplicate-component-names` | error | No duplicate component names in configured frames |
319+
| `deleted-variables` | warning | No `deletedButReferenced` variables in collections |
320+
| `alias-chain-integrity` | warning | Variable alias chains resolve without broken refs |
321+
| `dark-mode-variables` | error | With `variablesDarkMode`, fills bound to Variables |
322+
| `dark-mode-suffix` | warning | With `suffixDarkMode`, light components have dark pair |
323+
| `path-data-length` | error | Icon SVG pathData within 32,767-byte AAPT limit |
324+
| `icon-color-variables` | error | Icon paints use configured Figma Variables |
321325

322326
## Help and Version
323327

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import ExFigConfig
2+
import Foundation
3+
4+
/// Loads optional lint-only overlay configuration for `exfig lint`.
5+
enum LintConfigLoader {
6+
static let defaultFileName = "lint.pkl"
7+
8+
static func resolvePath(explicitPath: String?, mainConfigPath: String?) -> URL? {
9+
if let explicitPath, !explicitPath.isEmpty {
10+
return URL(fileURLWithPath: explicitPath)
11+
}
12+
13+
let mainPath = mainConfigPath ?? ExFigOptions.defaultConfigFilename
14+
let mainURL = URL(fileURLWithPath: mainPath)
15+
let lintURL = mainURL.deletingLastPathComponent().appendingPathComponent(defaultFileName)
16+
17+
guard FileManager.default.fileExists(atPath: lintURL.path) else {
18+
return nil
19+
}
20+
return lintURL
21+
}
22+
23+
static func load(explicitPath: String?, mainConfigPath: String?) async throws -> ExFigConfig.Lint.ModuleImpl? {
24+
guard let path = resolvePath(explicitPath: explicitPath, mainConfigPath: mainConfigPath) else {
25+
return nil
26+
}
27+
return try await PKLEvaluator.evaluateLintConfig(configPath: path)
28+
}
29+
}

‎Sources/ExFigCLI/Lint/LintEngine.swift‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,5 +63,6 @@ extension LintEngine {
6363
DarkModeSuffixRule(),
6464
PathDataLengthRule(),
6565
InvalidRTLVariantValueRule(),
66+
IconColorVariablesLintRule(),
6667
])
6768
}

‎Sources/ExFigCLI/Lint/LintTypes.swift‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ actor LintDataCache {
6464
struct LintContext {
6565
/// The resolved PKL configuration.
6666
let config: ExFig.ModuleImpl
67+
/// Optional lint-only overlay configuration.
68+
let lintConfig: ExFigConfig.Lint.ModuleImpl?
6769
/// Figma API client.
6870
let client: any FigmaAPI.Client
6971
/// Shared cache for Figma API responses across rules.

0 commit comments

Comments
 (0)