Skip to content

Commit ca886d8

Browse files
minsoo-webclaude
andcommitted
feat: add update notifier and self-update command
Add passive update check that queries GitHub Releases API after normal CLI execution, with 7-day cache TTL. Users see a one-line notice on stderr when a newer version is available. Add `chromaport update` subcommand that auto-detects install method (Homebrew/Cargo) and runs the appropriate upgrade command. Skip checks silently in CI, non-TTY, or when CHROMAPORT_NO_UPDATE_CHECK is set. Network/parse failures never disrupt the main flow. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 5b7a74b commit ca886d8

File tree

9 files changed

+1536
-5
lines changed

9 files changed

+1536
-5
lines changed

โ€ŽCargo.lockโ€Ž

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

โ€ŽCargo.tomlโ€Ž

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ serde_json = "1"
2525
similar = { version = "2", features = ["inline"] }
2626
console = "0.15"
2727
tempfile = "3"
28+
ureq = { version = "3", features = ["json"] }
29+
semver = "1"
2830

2931
[dev-dependencies]
3032
assert_cmd = "2"

โ€ŽREADME.mdโ€Ž

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66

77
Your favorite editor theme, everywhere.
88

9+
## Name
10+
11+
**chroma** (color) + **port** (carry across) โ€” carry your editor colors everywhere.
12+
913
## Install
1014

1115
### Homebrew
@@ -29,6 +33,31 @@ cd chromaport
2933
cargo install --path .
3034
```
3135

36+
## Update
37+
38+
chromaport automatically checks for new releases once a week. When an update is available, you'll see a notice after running any command:
39+
40+
```
41+
A new release of chromaport is available: 0.2.0 โ†’ 0.3.0
42+
Run `chromaport update` to upgrade.
43+
```
44+
45+
To update, simply run:
46+
47+
```sh
48+
chromaport update
49+
```
50+
51+
This auto-detects your install method (Homebrew or Cargo) and runs the appropriate upgrade command.
52+
53+
To disable the automatic update check, set:
54+
55+
```sh
56+
export CHROMAPORT_NO_UPDATE_CHECK=1
57+
```
58+
59+
The check is also automatically disabled in CI environments and non-interactive shells.
60+
3261
## Usage
3362

3463
Run `chromaport` and follow the interactive prompts:
@@ -50,13 +79,16 @@ Converting 2 theme(s)...
5079
### Options
5180

5281
```
53-
chromaport [OPTIONS]
82+
chromaport [OPTIONS] [COMMAND]
83+
84+
Commands:
85+
update Check for updates and upgrade chromaport
5486
5587
Options:
5688
-e, --editor <EDITOR> Source editor [possible values: vscode, cursor]
57-
-t, --target <TARGET> Target app [possible values: superset, warp]
89+
-t, --target <TARGET> Target app [possible values: superset, warp, ghostty]
5890
-y, --yes Non-interactive mode (import active theme, overwrite if exists)
59-
--no-activate Do not change the active theme after import
91+
--activate Apply the theme to the target app's config
6092
-h, --help Print help
6193
-V, --version Print version
6294
```
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# Brainstorm: CLI Update Notifier
2+
3+
**Date:** 2026-03-09
4+
**Status:** Draft
5+
6+
## What We're Building
7+
8+
chromaport ์‹คํ–‰ ์‹œ ์ƒˆ ๋ฒ„์ „์ด ์ถœ์‹œ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•˜๊ณ , ์—…๋ฐ์ดํŠธ๊ฐ€ ์žˆ์œผ๋ฉด ์‹คํ–‰ ์™„๋ฃŒ ํ›„ ํ•˜๋‹จ์— ์•ˆ๋‚ด ๋ฉ”์‹œ์ง€๋ฅผ ํ‘œ์‹œํ•˜๋Š” ๊ธฐ๋Šฅ. gh CLI, yarn, oh-my-zsh ๋“ฑ์ด ์ œ๊ณตํ•˜๋Š” ๊ฒƒ๊ณผ ๋™์ผํ•œ ํŒจํ„ด.
9+
10+
**์˜ˆ์‹œ ์ถœ๋ ฅ:**
11+
```
12+
โœ” One Monokai โ†’ ~/.superset/app-state.json
13+
14+
A new release of chromaport is available: 0.2.0 โ†’ 0.3.0
15+
To update, run: brew upgrade chromaport
16+
https://github.com/hamsurang/chromaport/releases/tag/v0.3.0
17+
```
18+
19+
## Why This Approach
20+
21+
### GitHub Releases API
22+
23+
- chromaport๋Š” ์ด๋ฏธ GitHub Releases + cargo-dist๋กœ ๋ฐฐํฌ ์ค‘
24+
- `https://api.github.com/repos/hamsurang/chromaport/releases/latest` ํ•œ ๋ฒˆ์˜ GET ์š”์ฒญ์œผ๋กœ ์ตœ์‹  ๋ฒ„์ „ ์กฐํšŒ ๊ฐ€๋Šฅ
25+
- crates.io๋ณด๋‹ค Homebrew ๋ฆด๋ฆฌ์Šค์™€ ๋™๊ธฐํ™”๊ฐ€ ์ •ํ™•ํ•จ
26+
- ์ธ์ฆ ๋ถˆํ•„์š” (public repo)
27+
28+
### 24์‹œ๊ฐ„ ์ฃผ๊ธฐ ์ฒดํฌ
29+
30+
- ๋งค ์‹คํ–‰๋งˆ๋‹ค ๋„คํŠธ์›Œํฌ ์š”์ฒญ์„ ๋ณด๋‚ด์ง€ ์•Š์•„ ์„ฑ๋Šฅ ์˜ํ–ฅ ์ตœ์†Œํ™”
31+
- ๋กœ์ปฌ ์บ์‹œ ํŒŒ์ผ์— ๋งˆ์ง€๋ง‰ ์ฒดํฌ ํƒ€์ž„์Šคํƒฌํ”„ + ์ตœ์‹  ๋ฒ„์ „ ์ €์žฅ
32+
- ์บ์‹œ ์œ„์น˜: `~/.chromaport/update-check.json` ๋˜๋Š” `dirs::cache_dir()`
33+
- gh CLI๊ฐ€ ๋™์ผํ•œ ํŒจํ„ด ์‚ฌ์šฉ
34+
35+
### ์‹คํ–‰ ๋ ํ•˜๋‹จ ํ‘œ์‹œ
36+
37+
- ํ•ต์‹ฌ ์ž‘์—… ํ๋ฆ„์„ ๋ฐฉํ•ดํ•˜์ง€ ์•Š์Œ
38+
- ์‚ฌ์šฉ์ž๊ฐ€ ์ž‘์—… ๊ฒฐ๊ณผ๋ฅผ ๋จผ์ € ํ™•์ธํ•œ ๋’ค ์—…๋ฐ์ดํŠธ ์•ˆ๋‚ด๋ฅผ ๋ด„
39+
- stderr๊ฐ€ ์•„๋‹Œ stdout์œผ๋กœ ์ถœ๋ ฅ (์ธํ„ฐ๋ž™ํ‹ฐ๋ธŒ CLI์ด๋ฏ€๋กœ ํŒŒ์ดํ”„๋ผ์ธ ์šฐ๋ ค ๋‚ฎ์Œ)
40+
41+
### ์˜คํ”„๋ผ์ธ/์‹คํŒจ ์‹œ ์กฐ์šฉํžˆ ์Šคํ‚ต
42+
43+
- ์—…๋ฐ์ดํŠธ ์ฒดํฌ๋Š” ๋ถ€๊ฐ€ ๊ธฐ๋Šฅ์ด๋ฏ€๋กœ ํ•ต์‹ฌ ๊ธฐ๋Šฅ์„ ์ ˆ๋Œ€ ๋ฐฉํ•ดํ•˜์ง€ ์•Š์Œ
44+
- ํƒ€์ž„์•„์›ƒ ์งง๊ฒŒ ์„ค์ • (2-3์ดˆ)
45+
- ๋„คํŠธ์›Œํฌ ์˜ค๋ฅ˜ ์‹œ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ์—†์ด ์ •์ƒ ์ง„ํ–‰
46+
47+
## Key Decisions
48+
49+
| ๊ฒฐ์ • | ์„ ํƒ | ๊ทผ๊ฑฐ |
50+
|------|------|------|
51+
| ๋ฒ„์ „ ์†Œ์Šค | GitHub Releases API | ๋ฐฐํฌ ํŒŒ์ดํ”„๋ผ์ธ๊ณผ ์ผ์น˜, ์ธ์ฆ ๋ถˆํ•„์š” |
52+
| ์ฒดํฌ ์ฃผ๊ธฐ | 24์‹œ๊ฐ„ ์บ์‹œ | ๋„คํŠธ์›Œํฌ ๋ถ€ํ•˜ ์ตœ์†Œํ™”, gh CLI ํŒจํ„ด |
53+
| ํ‘œ์‹œ ์œ„์น˜ | ์‹คํ–‰ ์™„๋ฃŒ ํ›„ ํ•˜๋‹จ | ์ž‘์—… ํ๋ฆ„ ๋น„์นจํ•ด |
54+
| ์˜คํ”„๋ผ์ธ ๋™์ž‘ | ์กฐ์šฉํžˆ ์Šคํ‚ต | ๋ถ€๊ฐ€ ๊ธฐ๋Šฅ์ด ํ•ต์‹ฌ ๊ธฐ๋Šฅ ๋ฐฉํ•ด ๊ธˆ์ง€ |
55+
| HTTP ํด๋ผ์ด์–ธํŠธ | ureq | ๊ฒฝ๋Ÿ‰, blocking, async ๋Ÿฐํƒ€์ž„ ๋ถˆํ•„์š” |
56+
| ์บ์‹œ ์œ„์น˜ | `dirs::cache_dir()/chromaport/` | XDG ๊ทœ๊ฒฉ ์ค€์ˆ˜, OS ๊ด€๋ก€ ๋”ฐ๋ฆ„ |
57+
| ์ž์ฒด ์—…๋ฐ์ดํŠธ | `chromaport update` ์„œ๋ธŒ์ปค๋งจ๋“œ | ์„ค์น˜ ๊ฒฝ๋กœ ๊ฐ์ง€ ํ›„ ์ ์ ˆํ•œ ๋ช…๋ น์–ด ๋Œ€์‹  ์‹คํ–‰ |
58+
59+
## Implementation Sketch (High-Level)
60+
61+
1. **์บ์‹œ ํŒŒ์ผ ๊ด€๋ฆฌ** โ€” ๋งˆ์ง€๋ง‰ ์ฒดํฌ ์‹œ๊ฐ + ์ตœ์‹  ๋ฒ„์ „์„ `dirs::cache_dir()/chromaport/update-check.json`์— ์ €์žฅ
62+
2. **GitHub API ํ˜ธ์ถœ** โ€” `releases/latest` ์—”๋“œํฌ์ธํŠธ์—์„œ `tag_name` ํŒŒ์‹ฑ (ureq, ํƒ€์ž„์•„์›ƒ 3์ดˆ)
63+
3. **๋ฒ„์ „ ๋น„๊ต** โ€” semver ๋น„๊ต๋กœ ํ˜„์žฌ < ์ตœ์‹ ์ด๋ฉด ์•Œ๋ฆผ ํ”Œ๋ž˜๊ทธ ์„ค์ •
64+
4. **์•Œ๋ฆผ ์ถœ๋ ฅ** โ€” main ์ž‘์—… ์™„๋ฃŒ ํ›„ ์กฐ๊ฑด๋ถ€๋กœ ์—…๋ฐ์ดํŠธ ์•ˆ๋‚ด ๋ฉ”์‹œ์ง€ ์ถœ๋ ฅ
65+
5. **`chromaport update` ์„œ๋ธŒ์ปค๋งจ๋“œ** โ€” ์„ค์น˜ ๊ฒฝ๋กœ ๊ฐ์ง€(Homebrew prefix / cargo) ํ›„ ์ ์ ˆํ•œ ์—…๋ฐ์ดํŠธ ๋ช…๋ น์–ด ์‹คํ–‰
66+
6. **๋น„ํ™œ์„ฑํ™” ์˜ต์…˜** โ€” `CHROMAPORT_NO_UPDATE_CHECK=1` ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋กœ ๋„๊ธฐ
67+
68+
### `chromaport update` ๋™์ž‘
69+
70+
```
71+
$ chromaport update
72+
Checking for updates...
73+
Updating chromaport 0.2.0 โ†’ 0.3.0
74+
โœ” Updated successfully!
75+
```
76+
77+
์„ค์น˜ ๊ฒฝ๋กœ ๊ฐ์ง€ ์ „๋žต:
78+
- Homebrew: `brew --prefix chromaport` ์„ฑ๊ณต ์—ฌ๋ถ€๋กœ ํŒ๋‹จ โ†’ `brew upgrade chromaport` ์‹คํ–‰
79+
- Cargo: `cargo install --list | grep chromaport` ํ™•์ธ โ†’ `cargo install chromaport` ์‹คํ–‰
80+
- ๊ฐ์ง€ ์‹คํŒจ ์‹œ: ์ˆ˜๋™ ์—…๋ฐ์ดํŠธ ์•ˆ๋‚ด + ๋ฆด๋ฆฌ์ฆˆ URL ํ‘œ์‹œ
81+
82+
## Resolved Questions
83+
84+
- **HTTP ํด๋ผ์ด์–ธํŠธ**: `ureq` ์„ ํƒ. ๊ฒฝ๋Ÿ‰ blocking ํด๋ผ์ด์–ธํŠธ๋กœ ๊ธฐ์กด ๋™๊ธฐ CLI์™€ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๋งž์Œ.
85+
- **์บ์‹œ ์œ„์น˜**: `dirs::cache_dir()/chromaport/` ์„ ํƒ. XDG ๊ทœ๊ฒฉ ์ค€์ˆ˜, OS ๊ด€๋ก€ ๋”ฐ๋ฆ„.
86+
- **์—…๋ฐ์ดํŠธ ๋ฐฉ์‹**: `chromaport update` ์ž์ฒด ์—…๋ฐ์ดํŠธ ์„œ๋ธŒ์ปค๋งจ๋“œ ์ œ๊ณต. ์„ค์น˜ ๊ฒฝ๋กœ๋ฅผ ์ž๋™ ๊ฐ์ง€ํ•˜์—ฌ ์ ์ ˆํ•œ ๋ช…๋ น์–ด(brew upgrade / cargo install)๋ฅผ ๋Œ€์‹  ์‹คํ–‰.

0 commit comments

Comments
ย (0)