@sebastienrousseau/dotfiles 0.2.511 → 0.2.512
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +42 -0
- package/README.md +2 -2
- package/docs/AI.md +2 -1
- package/docs/COPYRIGHT +1 -1
- package/docs/architecture/AI_COST_OPTIMIZATION.md +1 -0
- package/docs/archive/LEGACY_ROADMAP.md +4 -158
- package/docs/manual/00-introduction.md +1 -1
- package/docs/manual/02-tutorials/02-add-wallpaper.md +6 -6
- package/docs/manual/02-tutorials/03-create-profile.md +1 -1
- package/docs/manual/02-tutorials/05-deploy-fleet.md +1 -1
- package/docs/manual/03-reference/02-config-files.md +1 -1
- package/docs/manual/command-index.md +1 -0
- package/docs/operations/ARCHITECTURE_ROADMAP.md +5 -143
- package/docs/operations/COVERAGE.md +27 -4
- package/docs/operations/ROADMAP.md +3 -159
- package/docs/operations/ROADMAP_2026.md +5 -663
- package/docs/operations/ROADMAP_V0_2_503.md +5 -129
- package/docs/reference/THEMES.md +1 -1
- package/docs/reference/TOOLS.md +1 -0
- package/docs/reference/UTILS.md +1 -0
- package/install.sh +5 -5
- package/package.json +1 -1
- package/scripts/diagnostics/aliases-manifest.sh +33 -6
- package/scripts/diagnostics/benchmark.sh +27 -1
- package/scripts/diagnostics/doctor.sh +18 -11
- package/scripts/diagnostics/health.sh +8 -3
- package/scripts/diagnostics/mcp-doctor.sh +3 -0
- package/scripts/diagnostics/secret-governance.sh +7 -1
- package/scripts/diagnostics/security-score.sh +14 -5
- package/scripts/diagnostics/verify_state.sh +9 -1
- package/scripts/dot/commands/ai.sh +37 -30
- package/scripts/dot/commands/aliases.sh +28 -4
- package/scripts/dot/commands/appearance.sh +16 -0
- package/scripts/dot/commands/core.sh +17 -0
- package/scripts/dot/commands/diagnostics.sh +19 -0
- package/scripts/dot/commands/manual.sh +4 -4
- package/scripts/dot/commands/meta.sh +87 -12
- package/scripts/dot/commands/registry.sh +1 -1
- package/scripts/dot/commands/secrets.sh +17 -0
- package/scripts/dot/commands/security.sh +17 -0
- package/scripts/dot/commands/tools.sh +19 -0
- package/scripts/git-hooks/pre-commit-audit.sh +1 -1
- package/scripts/ops/ai-setup.sh +13 -6
- package/scripts/ops/bundle.sh +31 -5
- package/scripts/ops/chezmoi-apply.sh +5 -0
- package/scripts/ops/release.sh +14 -5
- package/scripts/qa/docs-coverage.sh +1 -1
- package/scripts/qa/reliability-audit.sh +2 -2
- package/scripts/secrets/age-init.sh +15 -4
- package/scripts/theme/apply-gnome-theme.sh +6 -2
- package/scripts/theme/extract-theme.py +97 -33
- package/scripts/theme/rebuild-themes.sh +240 -35
- package/scripts/theme/switch.sh +26 -16
- package/scripts/theme/wallpaper-sync.sh +95 -7
- package/scripts/version-sync.sh +81 -44
package/scripts/theme/switch.sh
CHANGED
|
@@ -78,15 +78,33 @@ fi
|
|
|
78
78
|
# Theme Database
|
|
79
79
|
# =============================================================================
|
|
80
80
|
|
|
81
|
-
# Default preferences
|
|
82
|
-
|
|
83
|
-
|
|
81
|
+
# Default preferences (must be present keys in themes.toml — the theme
|
|
82
|
+
# regeneration removed the old macos-monterey-* names; bloom is the current
|
|
83
|
+
# default family and always ships a dark+light pair).
|
|
84
|
+
DEFAULT_DARK="bloom-dark"
|
|
85
|
+
DEFAULT_LIGHT="bloom-light"
|
|
86
|
+
|
|
87
|
+
# Machine-local chezmoi override (chezmoi.toml [data] theme) takes precedence
|
|
88
|
+
# over .chezmoidata.toml when rendering, so it is the authoritative "current"
|
|
89
|
+
# value. Kept in sync by dot-theme-sync's write_theme().
|
|
90
|
+
CHEZMOI_CFG="${XDG_CONFIG_HOME:-$HOME/.config}/chezmoi/chezmoi.toml"
|
|
84
91
|
|
|
85
92
|
# =============================================================================
|
|
86
93
|
# Theme Functions
|
|
87
94
|
# =============================================================================
|
|
88
95
|
|
|
89
96
|
current_theme() {
|
|
97
|
+
# Prefer the machine-local override (what chezmoi actually renders), so
|
|
98
|
+
# `dot theme current` never disagrees with the deployed configs. Fall back
|
|
99
|
+
# to the repo default in .chezmoidata.toml when no override is set.
|
|
100
|
+
if [[ -f "$CHEZMOI_CFG" ]]; then
|
|
101
|
+
local override
|
|
102
|
+
override="$(awk -F'"' '/^theme =/ {print $2}' "$CHEZMOI_CFG" | head -n 1)"
|
|
103
|
+
if [[ -n "$override" ]]; then
|
|
104
|
+
echo "$override"
|
|
105
|
+
return 0
|
|
106
|
+
fi
|
|
107
|
+
fi
|
|
90
108
|
awk -F'"' '/^theme =/ {print $2}' "$DATA_FILE" | head -n 1
|
|
91
109
|
}
|
|
92
110
|
|
|
@@ -124,6 +142,9 @@ paired_families() {
|
|
|
124
142
|
done < <(all_theme_names)
|
|
125
143
|
|
|
126
144
|
for family in $(printf '%s\n' "${!has_dark[@]}" | sort); do
|
|
145
|
+
# `fallback` is a synthetic safety theme (see themes.toml) that templates
|
|
146
|
+
# degrade to when .theme is unset/invalid — never a user-selectable one.
|
|
147
|
+
[[ "$family" == "fallback" ]] && continue
|
|
127
148
|
[[ -n "${has_light[$family]+x}" ]] && echo "$family"
|
|
128
149
|
done
|
|
129
150
|
}
|
|
@@ -185,12 +206,6 @@ set_theme() {
|
|
|
185
206
|
|
|
186
207
|
# Interactive theme picker
|
|
187
208
|
pick_theme() {
|
|
188
|
-
if ! command -v fzf &>/dev/null; then
|
|
189
|
-
ui_err "fzf" "required for interactive picker"
|
|
190
|
-
ui_info "Usage" "dot theme set <name>"
|
|
191
|
-
exit 1
|
|
192
|
-
fi
|
|
193
|
-
|
|
194
209
|
local current
|
|
195
210
|
current="$(current_theme)"
|
|
196
211
|
|
|
@@ -220,14 +235,9 @@ pick_theme() {
|
|
|
220
235
|
done < <(paired_families)
|
|
221
236
|
|
|
222
237
|
local selected_family
|
|
223
|
-
selected_family="$(
|
|
238
|
+
selected_family="$(printf '%s' "$theme_list" | ui_pick \
|
|
224
239
|
--header "Select wallpaper theme (current: $current_family [$current_mode])" \
|
|
225
|
-
--prompt "Theme >
|
|
226
|
-
--height 30 \
|
|
227
|
-
--reverse \
|
|
228
|
-
--no-sort \
|
|
229
|
-
--no-preview \
|
|
230
|
-
--ansi |
|
|
240
|
+
--prompt "Theme >" |
|
|
231
241
|
awk '$1 !~ /^#/ && NF >= 2 {print $2}')" || return 0
|
|
232
242
|
|
|
233
243
|
if [[ -n "$selected_family" ]]; then
|
|
@@ -43,6 +43,16 @@ detect_mode() {
|
|
|
43
43
|
esac
|
|
44
44
|
fi
|
|
45
45
|
|
|
46
|
+
if [[ "$(uname -s)" == "Darwin" ]]; then
|
|
47
|
+
# AppleInterfaceStyle is "Dark" in dark mode and unset in light mode.
|
|
48
|
+
if [[ "$(defaults read -g AppleInterfaceStyle 2>/dev/null || true)" == "Dark" ]]; then
|
|
49
|
+
echo "dark"
|
|
50
|
+
else
|
|
51
|
+
echo "light"
|
|
52
|
+
fi
|
|
53
|
+
return 0
|
|
54
|
+
fi
|
|
55
|
+
|
|
46
56
|
if command -v gsettings &>/dev/null; then
|
|
47
57
|
local scheme
|
|
48
58
|
scheme="$(gsettings get org.gnome.desktop.interface color-scheme 2>/dev/null || echo "")"
|
|
@@ -125,10 +135,16 @@ wallpaper_for_theme() {
|
|
|
125
135
|
found && /^wallpaper/ { sub(/.*= *"/, ""); sub(/".*/, ""); print; exit }
|
|
126
136
|
' "$themes_file")"
|
|
127
137
|
if [[ -n "$stored_wp" ]]; then
|
|
128
|
-
#
|
|
138
|
+
# Home-relative form (current generator): ~/Pictures/... → $HOME/Pictures/...
|
|
139
|
+
# Prefix-strip comparison avoids a quoted-tilde glob (SC2088); the tilde
|
|
140
|
+
# here is a literal leading character, not a path to expand.
|
|
141
|
+
if [[ "$stored_wp" != "${stored_wp#\~/}" ]]; then
|
|
142
|
+
stored_wp="${HOME}/${stored_wp#\~/}"
|
|
143
|
+
fi
|
|
144
|
+
# Cross-platform: resolve legacy absolute macOS paths on Linux
|
|
129
145
|
if [[ ! -f "$stored_wp" ]]; then
|
|
130
146
|
if [[ "$stored_wp" == /Users/* ]]; then
|
|
131
|
-
# /Users/<user>/Pictures/... → $HOME/Pictures/...
|
|
147
|
+
# /Users/<user>/Pictures/... → $HOME/Pictures/... (pre-relativize data)
|
|
132
148
|
stored_wp="${HOME}/${stored_wp#/Users/*/}"
|
|
133
149
|
elif [[ "$stored_wp" == /System/* ]]; then
|
|
134
150
|
# macOS system wallpapers don't exist on Linux — skip to next fallback
|
|
@@ -397,6 +413,56 @@ ensure_linux_compatible() {
|
|
|
397
413
|
printf '%s\n' "$wp"
|
|
398
414
|
}
|
|
399
415
|
|
|
416
|
+
# macOS: a dynamic appearance HEIC (two frames + apple_desktop:apr metadata)
|
|
417
|
+
# set as a plain imageFile gets pinned to a single frame and stops tracking
|
|
418
|
+
# Light/Dark — so Light mode can show the dark frame. Extract the frame that
|
|
419
|
+
# matches the requested mode (0 = light, 1 = dark, per Apple's apr convention,
|
|
420
|
+
# same as the Linux -0/-1 path) to a small single-image HEIC and apply that
|
|
421
|
+
# instead. Single-image HEICs and non-HEICs are returned unchanged.
|
|
422
|
+
macos_appearance_frame() {
|
|
423
|
+
local wp="$1" mode="$2"
|
|
424
|
+
[[ "${wp##*.}" == "heic" ]] || {
|
|
425
|
+
printf '%s\n' "$wp"
|
|
426
|
+
return
|
|
427
|
+
}
|
|
428
|
+
command -v magick &>/dev/null || {
|
|
429
|
+
printf '%s\n' "$wp"
|
|
430
|
+
return
|
|
431
|
+
}
|
|
432
|
+
local frames
|
|
433
|
+
frames="$(magick identify "$wp" 2>/dev/null | wc -l | tr -d ' ')"
|
|
434
|
+
[[ "${frames:-0}" -ge 2 ]] || {
|
|
435
|
+
printf '%s\n' "$wp"
|
|
436
|
+
return
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
local idx=0
|
|
440
|
+
[[ "$mode" == "dark" ]] && idx=1
|
|
441
|
+
local cache_dir="$WALLPAPER_DIR/.dot-frames"
|
|
442
|
+
mkdir -p "$cache_dir" 2>/dev/null || {
|
|
443
|
+
printf '%s\n' "$wp"
|
|
444
|
+
return
|
|
445
|
+
}
|
|
446
|
+
local frame
|
|
447
|
+
frame="$cache_dir/$(basename "${wp%.heic}")-${mode}.heic"
|
|
448
|
+
|
|
449
|
+
# Reuse a cached frame that is newer than its source wallpaper.
|
|
450
|
+
if [[ -f "$frame" && "$frame" -nt "$wp" ]]; then
|
|
451
|
+
printf '%s\n' "$frame"
|
|
452
|
+
return
|
|
453
|
+
fi
|
|
454
|
+
local tmp
|
|
455
|
+
tmp="$(mktemp "${frame%.heic}.XXXXXX.heic")"
|
|
456
|
+
if magick "${wp}[${idx}]" "$tmp" 2>/dev/null && [[ -s "$tmp" ]]; then
|
|
457
|
+
if mv -f "$tmp" "$frame" 2>/dev/null; then
|
|
458
|
+
printf '%s\n' "$frame"
|
|
459
|
+
return
|
|
460
|
+
fi
|
|
461
|
+
fi
|
|
462
|
+
rm -f "$tmp" 2>/dev/null
|
|
463
|
+
printf '%s\n' "$wp"
|
|
464
|
+
}
|
|
465
|
+
|
|
400
466
|
# Apply wallpaper based on platform and compositor
|
|
401
467
|
apply_wallpaper() {
|
|
402
468
|
local wp="$1"
|
|
@@ -408,6 +474,10 @@ apply_wallpaper() {
|
|
|
408
474
|
|
|
409
475
|
case "$(uname -s)" in
|
|
410
476
|
Darwin)
|
|
477
|
+
# Resolve a dynamic HEIC down to the mode-appropriate static frame so
|
|
478
|
+
# macOS renders the right appearance instead of pinning one frame.
|
|
479
|
+
wp="$(macos_appearance_frame "$wp" "$mode")"
|
|
480
|
+
|
|
411
481
|
# macOS Sonoma+ moved wallpaper state to ~/Library/Application Support/
|
|
412
482
|
# com.apple.wallpaper/Store/Index.plist, owned by WallpaperAgent. Each
|
|
413
483
|
# Space and Display has its own entry, and AppleScript's `every desktop`
|
|
@@ -494,12 +564,29 @@ if updated:
|
|
|
494
564
|
print(updated)
|
|
495
565
|
PYEOF
|
|
496
566
|
|
|
497
|
-
# Restart WallpaperAgent so it re-reads the store
|
|
498
|
-
|
|
567
|
+
# Restart WallpaperAgent so it re-reads the store and repaints EVERY
|
|
568
|
+
# Space (the store rewrite above covers all Spaces; the agent only
|
|
569
|
+
# applies it on respawn). Then BLOCK until it's actually back and the
|
|
570
|
+
# wallpaper has re-applied — the caller reports "Done" once this returns,
|
|
571
|
+
# so it must not return while Spaces are still repainting. Set
|
|
572
|
+
# DOT_THEME_SKIP_WALLPAPER_AGENT=1 to skip the restart (faster, but
|
|
573
|
+
# background Spaces won't refresh until next login).
|
|
574
|
+
if [[ "${DOT_THEME_SKIP_WALLPAPER_AGENT:-0}" != "1" ]]; then
|
|
575
|
+
killall WallpaperAgent 2>/dev/null || true
|
|
576
|
+
|
|
577
|
+
# Wait for launchd to bring WallpaperAgent back (KeepAlive respawns it
|
|
578
|
+
# within ~1s; cap the wait so a theme switch can never hang).
|
|
579
|
+
local _waited=0
|
|
580
|
+
while ! pgrep -x WallpaperAgent >/dev/null 2>&1; do
|
|
581
|
+
sleep 0.1
|
|
582
|
+
_waited=$((_waited + 1))
|
|
583
|
+
[[ "$_waited" -ge 60 ]] && break
|
|
584
|
+
done
|
|
585
|
+
fi
|
|
499
586
|
|
|
500
|
-
#
|
|
501
|
-
#
|
|
502
|
-
#
|
|
587
|
+
# Re-assert the wallpaper through the (now running) agent — covers the
|
|
588
|
+
# active Space's first paint and any screen the store rewrite missed —
|
|
589
|
+
# then give that paint a moment to finish before returning.
|
|
503
590
|
if command -v wallpaper &>/dev/null; then
|
|
504
591
|
wallpaper set "$wp" --screen all 2>/dev/null || true
|
|
505
592
|
else
|
|
@@ -511,6 +598,7 @@ tell application \"System Events\"
|
|
|
511
598
|
end repeat
|
|
512
599
|
end tell" 2>/dev/null || true
|
|
513
600
|
fi
|
|
601
|
+
sleep 0.5
|
|
514
602
|
;;
|
|
515
603
|
Linux)
|
|
516
604
|
# DMS owns wallpaper display and runs matugen for color extraction.
|
package/scripts/version-sync.sh
CHANGED
|
@@ -86,7 +86,7 @@ EXCLUDE_FILES=(
|
|
|
86
86
|
"docs/operations/ARCHITECTURE_ROADMAP.md"
|
|
87
87
|
|
|
88
88
|
# Dated release write-ups: each article records the release it
|
|
89
|
-
# shipped in (e.g. "shipped in
|
|
89
|
+
# shipped in (e.g. "shipped in vX.Y.Z" + a link to that release
|
|
90
90
|
# tag). Those refs are historical fact, not current-version claims —
|
|
91
91
|
# bumping them would falsify the history.
|
|
92
92
|
"docs/articles/2026-07-05-fish-startup-abbr.md"
|
|
@@ -156,7 +156,11 @@ get_package_version() {
|
|
|
156
156
|
fi
|
|
157
157
|
|
|
158
158
|
local version
|
|
159
|
-
|
|
159
|
+
if command -v jq &>/dev/null; then
|
|
160
|
+
version=$(jq -r '.version' "$package_file" 2>/dev/null)
|
|
161
|
+
else
|
|
162
|
+
version=$(sed -nE 's/^[[:space:]]*"version"[[:space:]]*:[[:space:]]*"([^"]+)".*/\1/p' "$package_file" | head -n 1)
|
|
163
|
+
fi
|
|
160
164
|
if [[ "$version" == "null" || -z "$version" ]]; then
|
|
161
165
|
log_error "Could not extract version from package.json"
|
|
162
166
|
exit 1
|
|
@@ -186,22 +190,32 @@ find_version_files() {
|
|
|
186
190
|
# the paths match the EXCLUDE_FILES entries (which have no "./"),
|
|
187
191
|
# otherwise excluded historical docs get rewritten.
|
|
188
192
|
cd "$PROJECT_ROOT"
|
|
189
|
-
|
|
193
|
+
if command -v rg &>/dev/null; then
|
|
194
|
+
rg -l "v?$VERSION_PATTERN" --type md . 2>/dev/null | sed 's|^\./||' >"$temp_file" || true
|
|
195
|
+
else
|
|
196
|
+
{
|
|
197
|
+
while IFS= read -r file; do
|
|
198
|
+
if grep -Eq "v?$VERSION_PATTERN" "$file" 2>/dev/null; then
|
|
199
|
+
printf '%s\n' "${file#./}"
|
|
200
|
+
fi
|
|
201
|
+
done < <(find . -type f -name '*.md' -print)
|
|
202
|
+
} >"$temp_file"
|
|
203
|
+
fi
|
|
190
204
|
|
|
191
205
|
# Add known files that should be checked even if they don't have versions yet
|
|
192
|
-
echo "README.md" >>"$temp_file"
|
|
193
|
-
echo "docs/reference/FEATURES.md" >>"$temp_file"
|
|
194
|
-
echo "docs/COPYRIGHT" >>"$temp_file"
|
|
195
|
-
|
|
196
206
|
# Non-markdown and hidden-directory surfaces rg's `--type md` scan above
|
|
197
207
|
# cannot reach: a shell script, and READMEs under the dotfile-hidden
|
|
198
208
|
# `.chezmoitemplates/` tree (rg skips dot-dirs without --hidden). These
|
|
199
209
|
# carry "current version" stamps that check-version-consistency.sh and
|
|
200
210
|
# the test_version_consistency unit test enforce, so keep them in sync.
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
211
|
+
printf '%s\n' \
|
|
212
|
+
"README.md" \
|
|
213
|
+
"docs/reference/FEATURES.md" \
|
|
214
|
+
"docs/COPYRIGHT" \
|
|
215
|
+
"scripts/git-hooks/pre-commit-audit.sh" \
|
|
216
|
+
"defaults/.chezmoitemplates/README.md" \
|
|
217
|
+
"defaults/.chezmoitemplates/functions/README.md" \
|
|
218
|
+
"defaults/.chezmoitemplates/aliases/README.md" >>"$temp_file"
|
|
205
219
|
|
|
206
220
|
# Remove duplicates and filter existing files
|
|
207
221
|
sort -u "$temp_file" | while IFS= read -r file; do
|
|
@@ -268,6 +282,7 @@ update_version_references() {
|
|
|
268
282
|
log_warning "File not found: $file"
|
|
269
283
|
continue
|
|
270
284
|
fi
|
|
285
|
+
files_processed=$((files_processed + 1))
|
|
271
286
|
|
|
272
287
|
# Skip milestone and other historical files
|
|
273
288
|
if [[ "$(basename "$file")" == MILESTONE_* ]]; then
|
|
@@ -328,6 +343,7 @@ update_version_references() {
|
|
|
328
343
|
cat "$temp_file" >"$file"
|
|
329
344
|
log_success "Updated: $file"
|
|
330
345
|
fi
|
|
346
|
+
rm -f "$temp_file"
|
|
331
347
|
changes_made=$((changes_made + 1))
|
|
332
348
|
else
|
|
333
349
|
log_info "No changes needed: $file"
|
|
@@ -367,26 +383,49 @@ verify_version_consistency() {
|
|
|
367
383
|
|
|
368
384
|
# Extract only dotfiles-targeted version references (ignore unrelated tool versions).
|
|
369
385
|
local versions_in_file=()
|
|
370
|
-
|
|
371
|
-
while IFS= read -r
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
386
|
+
if command -v rg &>/dev/null; then
|
|
387
|
+
while IFS= read -r match; do
|
|
388
|
+
while IFS= read -r version; do
|
|
389
|
+
versions_in_file+=("$version")
|
|
390
|
+
done < <(printf "%s\n" "$match" | rg -o "v?$VERSION_PATTERN" || true)
|
|
391
|
+
done < <(
|
|
392
|
+
rg -v "MILESTONE" "$file" 2>/dev/null | rg -o \
|
|
393
|
+
-e "Version-v$VERSION_PATTERN" \
|
|
394
|
+
-e "/releases/tag/v$VERSION_PATTERN" \
|
|
395
|
+
-e "/dotfiles/v$VERSION_PATTERN/" \
|
|
396
|
+
-e "\\*\\*Version\\*\\*:[[:space:]]*v?$VERSION_PATTERN" \
|
|
397
|
+
-e "\\*\\*Dotfiles Version\\*\\*:[[:space:]]*v?$VERSION_PATTERN" \
|
|
398
|
+
-e "(^|[[:space:]])Version:[[:space:]]*v?$VERSION_PATTERN" \
|
|
399
|
+
-e "(^|[[:space:]])Dotfiles Version:[[:space:]]*v?$VERSION_PATTERN" \
|
|
400
|
+
-e "Version[[:space:]]*\`v?$VERSION_PATTERN\`" \
|
|
401
|
+
-e "\\(v$VERSION_PATTERN\\)" \
|
|
402
|
+
-e "/v$VERSION_PATTERN/" \
|
|
403
|
+
-e "v$VERSION_PATTERN\\b" \
|
|
404
|
+
-e "dotfiles:v?$VERSION_PATTERN" \
|
|
405
|
+
-e "notes — v$VERSION_PATTERN" || true
|
|
406
|
+
)
|
|
407
|
+
else
|
|
408
|
+
while IFS= read -r match; do
|
|
409
|
+
while IFS= read -r version; do
|
|
410
|
+
versions_in_file+=("$version")
|
|
411
|
+
done < <(printf "%s\n" "$match" | grep -Eo "v?$VERSION_PATTERN" || true)
|
|
412
|
+
done < <(
|
|
413
|
+
grep -Ev "MILESTONE" "$file" 2>/dev/null | grep -Eo \
|
|
414
|
+
-e "Version-v$VERSION_PATTERN" \
|
|
415
|
+
-e "/releases/tag/v$VERSION_PATTERN" \
|
|
416
|
+
-e "/dotfiles/v$VERSION_PATTERN/" \
|
|
417
|
+
-e "\\*\\*Version\\*\\*:[[:space:]]*v?$VERSION_PATTERN" \
|
|
418
|
+
-e "\\*\\*Dotfiles Version\\*\\*:[[:space:]]*v?$VERSION_PATTERN" \
|
|
419
|
+
-e "(^|[[:space:]])Version:[[:space:]]*v?$VERSION_PATTERN" \
|
|
420
|
+
-e "(^|[[:space:]])Dotfiles Version:[[:space:]]*v?$VERSION_PATTERN" \
|
|
421
|
+
-e "Version[[:space:]]*\`v?$VERSION_PATTERN\`" \
|
|
422
|
+
-e "\\(v$VERSION_PATTERN\\)" \
|
|
423
|
+
-e "/v$VERSION_PATTERN/" \
|
|
424
|
+
-e "v$VERSION_PATTERN([^0-9.]|$)" \
|
|
425
|
+
-e "dotfiles:v?$VERSION_PATTERN" \
|
|
426
|
+
-e "notes — v$VERSION_PATTERN" || true
|
|
427
|
+
)
|
|
428
|
+
fi
|
|
390
429
|
|
|
391
430
|
if [[ ${#versions_in_file[@]} -eq 0 ]]; then
|
|
392
431
|
continue
|
|
@@ -457,6 +496,12 @@ main() {
|
|
|
457
496
|
esac
|
|
458
497
|
done
|
|
459
498
|
|
|
499
|
+
if [[ -n "${DOTFILES_COV_TMPDIR:-}" && "${DOTFILES_ALLOW_COVERAGE_WRITES:-0}" != "1" ]]; then
|
|
500
|
+
dry_run="true"
|
|
501
|
+
create_backup_flag="false"
|
|
502
|
+
log_info "Coverage sandbox detected; forcing --dry-run"
|
|
503
|
+
fi
|
|
504
|
+
|
|
460
505
|
# Change to project root
|
|
461
506
|
cd "$PROJECT_ROOT"
|
|
462
507
|
|
|
@@ -470,8 +515,11 @@ main() {
|
|
|
470
515
|
fi
|
|
471
516
|
|
|
472
517
|
# Find files with version references
|
|
473
|
-
local version_files
|
|
474
|
-
|
|
518
|
+
local version_files=()
|
|
519
|
+
local version_file
|
|
520
|
+
while IFS= read -r version_file; do
|
|
521
|
+
version_files+=("$version_file")
|
|
522
|
+
done < <(find_version_files)
|
|
475
523
|
|
|
476
524
|
if [[ ${#version_files[@]} -eq 0 ]]; then
|
|
477
525
|
log_warning "No files with version references found"
|
|
@@ -574,16 +622,5 @@ EOF
|
|
|
574
622
|
fi
|
|
575
623
|
}
|
|
576
624
|
|
|
577
|
-
# Ensure we have required tools
|
|
578
|
-
if ! command -v jq &>/dev/null; then
|
|
579
|
-
log_warning "jq is not installed — skipping version sync"
|
|
580
|
-
exit 0
|
|
581
|
-
fi
|
|
582
|
-
|
|
583
|
-
if ! command -v rg &>/dev/null; then
|
|
584
|
-
log_warning "ripgrep (rg) is not installed — skipping version sync"
|
|
585
|
-
exit 0
|
|
586
|
-
fi
|
|
587
|
-
|
|
588
625
|
# Run main function
|
|
589
626
|
main "$@"
|