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
|
#!/usr/bin/env bash
#
# migrate-backlog-statuses.sh <repo-path> [--dry-run]
#
# Migrate a Backlog.md repo to the unified status vocabulary:
# ๐ฆ Backlog ยท ๐ข In progress ยท ๐ง Paused ยท ๐ Done
#
# Updates backlog/config.yml (statuses + default_status) and rewrites each task's
# status via the backlog CLI using the mapping below. Idempotent: tasks already
# on the new vocab are left alone.
#
# This is the pilot rollout helper โ run it per repo for the later full rollout.
# Claude project docs (Humdrum/Claude/Projects/*.md) are migrated separately:
# - frontmatter `status:` โ one of the four (judgement: ๐กโ๐ข, ๐ดโ๐ง, etc.)
# - any ```base``` filters referencing "Done" โ "๐ Done"
#
set -euo pipefail
repo="${1:?usage: migrate-backlog-statuses.sh <repo-path> [--dry-run]}"
dry=""; [ "${2:-}" = "--dry-run" ] && dry=1
cd "$repo"
[ -f backlog/config.yml ] || { echo "no backlog/config.yml in $repo โ skipping"; exit 0; }
NEW_STATUSES='["๐ฆ Backlog", "๐ข In progress", "๐ง Paused", "๐ Done"]'
map_status() {
case "$1" in
"To Do"|"Todo"|"Backlog") echo "๐ฆ Backlog" ;;
"In Progress"|"In progress"|"Doing") echo "๐ข In progress" ;;
"Paused"|"Blocked"|"On Hold"|"Hold") echo "๐ง Paused" ;;
"Done"|"Shipped"|"Complete"|"Completed") echo "๐ Done" ;;
*) echo "" ;; # already new vocab, or unknown โ leave it
esac
}
echo "== $repo =="
# config: statuses array (CLI refuses arrays, so edit the file) + default_status
if [ -z "$dry" ]; then
tmp=$(mktemp)
awk -v repl="statuses: $NEW_STATUSES" '/^statuses:/{print repl; next} {print}' backlog/config.yml > "$tmp" && mv "$tmp" backlog/config.yml
backlog config set defaultStatus "๐ฆ Backlog" >/dev/null 2>&1 || true
fi
echo " config: statuses + default_status โ new vocab"
# tasks: map current status โ new
shopt -s nullglob
for f in backlog/tasks/*.md; do
id=$(awk -F': ' '/^id:/{print $2; exit}' "$f")
cur=$(awk '/^status:/{sub(/^status:[ ]*/,""); gsub(/^["'\'']|["'\'']$/,""); print; exit}' "$f")
new=$(map_status "$cur")
[ -z "$new" ] && continue
[ "$new" = "$cur" ] && continue
echo " $id: $cur โ $new"
[ -z "$dry" ] && backlog task edit "$id" -s "$new" --plain >/dev/null 2>&1
done
echo " done"
|