Skip to content

Commit d3ecf1e

Browse files
committed
chore: remove Rainbow dependency and update Package.resolved
Remove the Rainbow dependency from Package.swift and corresponding import statements in source files. This change is necessary to streamline the project's dependencies and improve maintainability. Replace Rainbow usage with NooraUI formatting in terminal UI components to retain colored output functionality. Additionally, update Package.resolved to reflect the removal of Rainbow and the corrections of version specifications for swift-custom-dump and xctest-dynamic-overlay to match actual needs in the codebase.
1 parent 2bae75d commit d3ecf1e

16 files changed

Lines changed: 141 additions & 86 deletions

.claude/rules/gotchas.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,23 @@ func withContext<T>(operation: () async -> T) async -> T
9595
- Add `// swiftlint:disable:next force_try` before `try!` in tests
9696
- Add `// swiftlint:disable file_length` for files > 400 lines
9797

98+
### void_function_in_ternary False Positive
99+
100+
SwiftLint flags `NooraUI.format()` calls in ternary operators as `void_function_in_ternary` even though they return `String`.
101+
Fix by extracting into separate `let` variables:
102+
103+
```swift
104+
// BAD - triggers SwiftLint
105+
let icon: String = if useColors {
106+
success ? NooraUI.format(.success("")) : NooraUI.format(.danger(""))
107+
} else { ... }
108+
109+
// GOOD
110+
let successIcon = useColors ? NooraUI.format(.success("")) : ""
111+
let failIcon = useColors ? NooraUI.format(.danger("")) : ""
112+
let icon = success ? successIcon : failIcon
113+
```
114+
98115
## Test Helpers for Codable Types
99116

100117
```swift

CLAUDE.md

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -211,25 +211,38 @@ let jsonData = try JSONCodec.encode(myValue)
211211

212212
**Noora usage:** See `.claude/rules/terminal-ui.md` for full patterns.
213213

214+
**NooraUI quick reference:**
215+
216+
```swift
217+
// Format a single component (uses format(_ component:) overload)
218+
NooraUI.format(.primary("text")) // cyan
219+
NooraUI.format(.success("")) // green
220+
NooraUI.format(.danger("")) // red
221+
NooraUI.format(.accent("")) // yellow
222+
NooraUI.format(.muted("dim")) // gray
223+
NooraUI.format(.command("bold")) // bold/secondary
224+
NooraUI.formatLink("url", useColors: true) // underlined primary
225+
```
226+
214227
## Dependencies
215228

216-
| Package | Version | Purpose |
217-
| --------------------- | ------- | --------------------------- |
218-
| swift-argument-parser | 1.5.0+ | CLI framework |
219-
| swift-collections | 1.2.x | Ordered collections |
220-
| Yams | 5.3.0+ | YAML parsing |
221-
| Stencil | 0.15.1+ | Template engine |
222-
| StencilSwiftKit | 2.10.1+ | Swift Stencil extensions |
223-
| XcodeProj | 8.27.0+ | Xcode project manipulation |
224-
| swift-log | 1.6.0+ | Logging |
225-
| Rainbow | 4.2.0+ | Terminal colors |
226-
| libwebp | 1.4.1+ | WebP encoding |
227-
| libpng | 1.6.45+ | PNG decoding |
228-
| swift-custom-dump | 1.3.0+ | Test assertions |
229-
| Noora | 0.54.0+ | Terminal UI design system |
230-
| swift-resvg | 0.45.1 | SVG parsing/rendering |
231-
| swift-docc-plugin | 1.4.5+ | DocC documentation |
232-
| swift-yyjson | 0.4.0+ | High-performance JSON codec |
229+
| Package | Version | Purpose |
230+
| --------------------- | ------- | -------------------------- |
231+
| swift-argument-parser | 1.5.0+ | CLI framework |
232+
| swift-collections | 1.2.x | Ordered collections |
233+
| Yams | 5.3.0+ | YAML parsing |
234+
| Stencil | 0.15.1+ | Template engine |
235+
| StencilSwiftKit | 2.10.1+ | Swift Stencil extensions |
236+
| XcodeProj | 8.27.0+ | Xcode project manipulation |
237+
| swift-log | 1.6.0+ | Logging |
238+
239+
| libwebp | 1.4.1+ | WebP encoding |
240+
| libpng | 1.6.45+ | PNG decoding |
241+
| swift-custom-dump | 1.3.0+ | Test assertions |
242+
| Noora | 0.54.0+ | Terminal UI design system |
243+
| swift-resvg | 0.45.1 | SVG parsing/rendering |
244+
| swift-docc-plugin | 1.4.5+ | DocC documentation |
245+
| swift-yyjson | 0.4.0+ | High-performance JSON codec |
233246

234247
## Troubleshooting
235248

@@ -260,3 +273,7 @@ Contextual documentation is in `.claude/rules/`:
260273
| `testing-workflow.md` | Testing guidelines, commit format |
261274

262275
These rules are loaded lazily when working with related files.
276+
277+
## Session Wrap-Up
278+
279+
After completing a task, call `Skill(claude-md-management:revise-claude-md)` to capture learnings and update CLAUDE.md.

Package.resolved

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Package.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ let package = Package(
2020
.package(url: "https://github.com/SwiftGen/StencilSwiftKit", from: "2.10.1"),
2121
.package(url: "https://github.com/tuist/XcodeProj.git", from: "8.27.0"),
2222
.package(url: "https://github.com/pointfreeco/swift-custom-dump", from: "1.3.0"),
23-
.package(url: "https://github.com/onevcat/Rainbow", from: "4.2.0"),
23+
2424
.package(url: "https://github.com/the-swift-collective/libwebp.git", from: "1.4.1"),
2525
.package(url: "https://github.com/the-swift-collective/libpng.git", from: "1.6.45"),
2626
.package(url: "https://github.com/tuist/Noora", from: "0.54.0"),
@@ -45,7 +45,7 @@ let package = Package(
4545
.product(name: "ArgumentParser", package: "swift-argument-parser"),
4646
.product(name: "Yams", package: "Yams"),
4747
.product(name: "Logging", package: "swift-log"),
48-
.product(name: "Rainbow", package: "Rainbow"),
48+
4949
.product(name: "WebP", package: "libwebp"),
5050
.product(name: "LibPNG", package: "libpng"),
5151
.product(name: "Noora", package: "Noora"),

Sources/ExFig/Batch/BatchExecutor.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import FigmaAPI
22
import Foundation
3-
import Rainbow
43

54
/// Type alias for config processing handler.
65
typealias ConfigHandler = @Sendable (ConfigFile) async -> ConfigResult

Sources/ExFig/ExFigCommand.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import ArgumentParser
22
import Foundation
33
import Logging
4-
import Rainbow
54
import SVGKit
65

76
enum ExFigError: LocalizedError {

Sources/ExFig/Subcommands/Migrate.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import ArgumentParser
22
import Foundation
3-
import Rainbow
3+
import Noora
44
import Yams
55

66
extension ExFigCommand {
@@ -285,7 +285,7 @@ extension ExFigCommand {
285285
if !trimmed.isEmpty {
286286
let formatted = " + \(line)"
287287
if useColors {
288-
TerminalOutputManager.shared.print(formatted.green)
288+
TerminalOutputManager.shared.print(NooraUI.format(.success(formatted)))
289289
} else {
290290
TerminalOutputManager.shared.print(formatted)
291291
}

Sources/ExFig/Subcommands/checkForUpdate.swift

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import ArgumentParser
22
import FigmaAPI
33
import Foundation
44
import Logging
5-
import Rainbow
5+
import Noora
66

77
func checkForUpdate(logger: Logger) async {
88
let client = GitHubClient()
@@ -15,18 +15,23 @@ func checkForUpdate(logger: Logger) async {
1515
if ExFigCommand.version != latestVersion {
1616
if TTYDetector.colorsEnabled {
1717
let border = "──────────────────────────────────────────────────────────────"
18+
let p = { (s: String) in NooraUI.format(.primary(s)) }
19+
let url = NooraUI.formatLink(
20+
"https://github.com/alexey1312/ExFig/releases",
21+
useColors: true
22+
)
1823

1924
let message = """
2025
21-
\("\(border)".cyan)
22-
\("".cyan)
23-
\("".cyan) \("🚀 Update Available: \(latestVersion)".bold.green)
24-
\("".cyan) Current version: \(ExFigCommand.version)
25-
\("".cyan)
26-
\("".cyan) To update, visit:
27-
\("".cyan) \("https://github.com/alexey1312/ExFig/releases".blue.underline)
28-
\("".cyan)
29-
\("\(border)".cyan)
26+
\(p("\(border)"))
27+
\(p(""))
28+
\(p("")) \(NooraUI.format(.success("🚀 Update Available: \(latestVersion)")))
29+
\(p("")) Current version: \(ExFigCommand.version)
30+
\(p(""))
31+
\(p("")) To update, visit:
32+
\(p("")) \(url)
33+
\(p(""))
34+
\(p("\(border)"))
3035
"""
3136
logger.info(Logger.Message(stringLiteral: message))
3237
} else {

Sources/ExFig/TerminalUI/BatchProgressView.swift

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// swiftlint:disable file_length type_body_length
22
import FigmaAPI
33
import Foundation
4-
import Rainbow
4+
import Noora
55

66
/// Progress display for batch processing of multiple configs.
77
///
@@ -220,7 +220,7 @@ actor BatchProgressView {
220220
let completed = configStates.values.filter { isCompleted($0.status) }.count
221221
let total = configStates.count
222222
let header = "Batch Export (\(completed)/\(total) configs)"
223-
lines.append(useColors ? header.bold : header)
223+
lines.append(useColors ? NooraUI.format(.command(header)) : header)
224224

225225
// Config lines
226226
let sortedConfigs = configOrder.compactMap { configStates[$0] }
@@ -270,13 +270,13 @@ actor BatchProgressView {
270270
private func statusIcon(_ status: ConfigState.Status) -> String {
271271
switch status {
272272
case .pending:
273-
useColors ? "".lightBlack : ""
273+
useColors ? NooraUI.format(.muted("")) : ""
274274
case .running:
275-
useColors ? "".cyan : ""
275+
useColors ? NooraUI.format(.primary("")) : ""
276276
case .succeeded:
277-
useColors ? "".green : ""
277+
useColors ? NooraUI.format(.success("")) : ""
278278
case .failed:
279-
useColors ? "".red : ""
279+
useColors ? NooraUI.format(.danger("")) : ""
280280
}
281281
}
282282

@@ -289,7 +289,7 @@ actor BatchProgressView {
289289
let emptyBar = String(repeating: "", count: empty)
290290

291291
if useColors {
292-
return "[\(filledBar.cyan)\(emptyBar.lightBlack)]"
292+
return "[\(NooraUI.format(.primary(filledBar)))\(NooraUI.format(.muted(emptyBar)))]"
293293
}
294294
return "[\(filledBar)\(emptyBar)]"
295295
}
@@ -362,19 +362,20 @@ actor BatchProgressView {
362362
private func formatStatusText(_ config: ConfigState) -> String {
363363
switch config.status {
364364
case .pending:
365-
return useColors ? "Waiting...".lightBlack : "Waiting..."
365+
return useColors ? NooraUI.format(.muted("Waiting...")) : "Waiting..."
366366
case .running:
367367
var text = formatExportProgress(config.exportProgress)
368368
if let eta = calculateETA(config), eta > 1 {
369369
let etaStr = formatDuration(eta)
370-
text += useColors ? " ETA: \(etaStr)".lightBlack : " ETA: \(etaStr)"
370+
text += useColors ? " " + NooraUI.format(.muted("ETA: \(etaStr)")) : " ETA: \(etaStr)"
371371
}
372372
return text
373373
case .succeeded:
374-
return formatExportProgress(config.exportProgress) + (useColors ? "".green : "")
374+
return formatExportProgress(config.exportProgress) +
375+
(useColors ? " " + NooraUI.format(.success("")) : "")
375376
case let .failed(error):
376377
let truncated = String(error.prefix(30))
377-
return useColors ? truncated.red : truncated
378+
return useColors ? NooraUI.format(.danger(truncated)) : truncated
378379
}
379380
}
380381

@@ -383,28 +384,28 @@ actor BatchProgressView {
383384

384385
if let colors = progress.colors, colors.total > 0 {
385386
let status = colors.current >= colors.total
386-
? (useColors ? "".green : "")
387+
? (useColors ? NooraUI.format(.success("")) : "")
387388
: "\(colors.current)/\(colors.total)"
388389
parts.append("Colors: \(status)")
389390
}
390391

391392
if let icons = progress.icons, icons.total > 0 {
392393
let status = icons.current >= icons.total
393-
? (useColors ? "".green : "")
394+
? (useColors ? NooraUI.format(.success("")) : "")
394395
: "\(icons.current)/\(icons.total)"
395396
parts.append("Icons: \(status)")
396397
}
397398

398399
if let images = progress.images, images.total > 0 {
399400
let status = images.current >= images.total
400-
? (useColors ? "".green : "")
401+
? (useColors ? NooraUI.format(.success("")) : "")
401402
: "\(images.current)/\(images.total)"
402403
parts.append("Images: \(status)")
403404
}
404405

405406
if let typography = progress.typography, typography.total > 0 {
406407
let status = typography.current >= typography.total
407-
? (useColors ? "".green : "")
408+
? (useColors ? NooraUI.format(.success("")) : "")
408409
: "\(typography.current)/\(typography.total)"
409410
parts.append("Typography: \(status)")
410411
}
@@ -418,9 +419,10 @@ actor BatchProgressView {
418419

419420
if status.isPaused {
420421
let retryStr = status.retryAfter.map { String(format: "%.0fs", $0) } ?? "unknown"
422+
let pausedMsg = "Rate limit: Paused (retry after \(retryStr))"
421423
rateText = useColors
422-
? "Rate limit: Paused (retry after \(retryStr))".yellow
423-
: "Rate limit: Paused (retry after \(retryStr))"
424+
? NooraUI.format(.accent(pausedMsg))
425+
: pausedMsg
424426
} else {
425427
let currentRate = String(format: "%.1f", status.currentRate)
426428
let maxRate = String(format: "%.0f", status.requestsPerMinute / 60.0)

Sources/ExFig/TerminalUI/ExFigLogHandler.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import Foundation
22
import Logging
3-
import Rainbow
3+
import Noora
44

55
/// Custom log handler that routes output through TerminalUI
66
struct ExFigLogHandler: LogHandler {
@@ -69,13 +69,13 @@ struct ExFigLogHandler: LogHandler {
6969

7070
switch level {
7171
case .trace, .debug:
72-
return levelText.lightBlack
72+
return NooraUI.format(.muted(levelText))
7373
case .info, .notice:
74-
return levelText.cyan
74+
return NooraUI.format(.primary(levelText))
7575
case .warning:
76-
return levelText.yellow
76+
return NooraUI.format(.accent(levelText))
7777
case .error, .critical:
78-
return levelText.red
78+
return NooraUI.format(.danger(levelText))
7979
}
8080
}
8181

@@ -86,9 +86,9 @@ struct ExFigLogHandler: LogHandler {
8686

8787
switch level {
8888
case .warning:
89-
return "\(message)".yellow
89+
return NooraUI.format(.accent("\(message)"))
9090
case .error, .critical:
91-
return "\(message)".red
91+
return NooraUI.format(.danger("\(message)"))
9292
default:
9393
return "\(message)"
9494
}

0 commit comments

Comments
 (0)