docs: bootstrap vault, roadmap and research
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env bash
|
||||
# viexp Gitea bootstrap — create labels, sprint milestones and seed issues.
|
||||
# Re-runnable: existing items are detected and reused.
|
||||
# Auth: reads the token saved by `tea login add` from ~/.config/tea/config.yml.
|
||||
# NOTE (Gitea 1.26.2): the repo *project board* has no API on this instance —
|
||||
# create "viexp development" once via the web UI (Issues → Projects).
|
||||
set -u
|
||||
TOKEN=$(grep -E '^\s*token:' ~/.config/tea/config.yml | head -1 | sed -E 's/^\s*token:\s*//; s/"//g')
|
||||
API=https://git.v-port.ru/api/v1
|
||||
REPO=vaskes/viexp
|
||||
TZOFF=$(date +%:z)
|
||||
|
||||
req() { local m=$1 p=$2 d=${3:-}
|
||||
if [ -n "$d" ]; then curl -s -X "$m" "$API$p" -H "Authorization: token $TOKEN" -H 'Content-Type: application/json' -d "$d"
|
||||
else curl -s -X "$m" "$API$p" -H "Authorization: token $TOKEN"; fi
|
||||
}
|
||||
|
||||
echo "== labels =="
|
||||
declare -a LABELS=(
|
||||
'type/bug|ee0701|Something broken in shipped code'
|
||||
'type/feature|84b6eb|New app capability'
|
||||
'type/docs|d4c5f9|Documentation and vault work'
|
||||
'type/research|fad8c7|Investigation / spike output expected'
|
||||
'type/chore|ededed|Tooling, CI, maintenance'
|
||||
'type/spike|fef2c0|Time-boxed experiment'
|
||||
'priority/P0|b60205|Blocks the sprint'
|
||||
'priority/P1|d93f0b|Important this sprint'
|
||||
'priority/P2|fbca04|Normal'
|
||||
'priority/P3|0e8a16|Nice to have'
|
||||
'lang/english|5319e7|English-practice artifact'
|
||||
)
|
||||
for L in "${LABELS[@]}"; do
|
||||
IFS='|' read -r name color desc <<< "$L"
|
||||
req POST "/repos/$REPO/labels" "{\"name\":\"$name\",\"color\":\"$color\",\"description\":\"$desc\"}" >/dev/null
|
||||
done
|
||||
req GET "/repos/$REPO/labels" | jq -r '.[].name' | tr '\n' ' '; echo
|
||||
|
||||
echo "== milestones (sprints; see docs/roadmap.md) =="
|
||||
create_ms() { # title description due
|
||||
local existing
|
||||
existing=$(req GET "/repos/$REPO/milestones?state=all" | jq -r --arg t "$1" '.[] | select(.title==$t) | .id')
|
||||
if [ -n "$existing" ] && [ "$existing" != "null" ]; then echo "$existing"; return; fi
|
||||
req POST "/repos/$REPO/milestones" "{\"title\":\"$1\",\"description\":\"$2\",\"due_on\":\"$3\"}" | jq -r '.id // empty'
|
||||
}
|
||||
S0="Sprint 0 — Setup & deconstruction"
|
||||
S1="Sprint 1 — Rust core via vls"
|
||||
create_ms "$S0" "Toolchain, CI, board, vault. ~6h." "2026-10-31T23:59:59$TZOFF" >/dev/null
|
||||
create_ms "$S1" "viexp ls subcommand: colors, sizes, sorting, tests. 20h." "2026-11-30T23:59:59$TZOFF" >/dev/null
|
||||
req GET "/repos/$REPO/milestones?state=all" | jq -r '.[] | "\(.id) \(.title)"'
|
||||
|
||||
echo "== issues =="
|
||||
bash "$(dirname "$0")/gitea-issues.sh"
|
||||
|
||||
echo "== project board =="
|
||||
echo "No API on Gitea 1.26.2 — create 'viexp development' board in the web UI (Issues → Projects), columns:"
|
||||
echo " Backlog → In Progress → Review → Done (sprints tracked by milestones)"
|
||||
@@ -0,0 +1,58 @@
|
||||
#!/usr/bin/env bash
|
||||
# Fix-up: create issues with label IDs; diagnose projects API.
|
||||
set -u
|
||||
TOKEN=$(grep -E '^\s*token:' ~/.config/tea/config.yml | head -1 | sed -E 's/^\s*token:\s*//; s/"//g')
|
||||
API=https://git.v-port.ru/api/v1
|
||||
REPO=vaskes/viexp
|
||||
|
||||
req() { local m=$1 p=$2 d=${3:-}
|
||||
if [ -n "$d" ]; then curl -s -X "$m" "$API$p" -H "Authorization: token $TOKEN" -H 'Content-Type: application/json' -d "$d"
|
||||
else curl -s -X "$m" "$API$p" -H "Authorization: token $TOKEN"; fi
|
||||
}
|
||||
|
||||
echo "== raw projects GET (first 200 chars) =="
|
||||
req GET "/repos/$REPO/projects" | head -c 200; echo; echo
|
||||
|
||||
declare -A LMAP MMAP
|
||||
while IFS=$'\t' read -r id name; do LMAP[$name]=$id; done < <(req GET "/repos/$REPO/labels" | jq -r '.[] | "\(.id)\t\(.name)"')
|
||||
while IFS=$'\t' read -r id title; do MMAP[$title]=$id; done < <(req GET "/repos/$REPO/milestones?state=all" | jq -r '.[] | "\(.id)\t\(.title)"')
|
||||
|
||||
EXISTING=$(req GET "/repos/$REPO/issues?state=all&type=issues")
|
||||
|
||||
create_issue() { # title body milestone_title labels_csv -> $1 $2 $3 $4
|
||||
local exist
|
||||
exist=$(echo "$EXISTING" | jq -r --arg t "$1" '.[]? | select(.title==$t) | .number')
|
||||
if [ -n "$exist" ] && [ "$exist" != "null" ]; then echo "#$exist (existing) $1"; return; fi
|
||||
local ids=() n
|
||||
IFS=',' read -ra names <<< "$4"
|
||||
for n in "${names[@]}"; do [ -n "$n" ] && ids+=("${LMAP[$n]}"); done
|
||||
local ids_json
|
||||
ids_json=$(printf '%s\n' "${ids[@]}" | jq -R -s 'split("\n") | map(select(length>0) | tonumber) | map(select(. != null))')
|
||||
local ms=${MMAP[$3]:-}
|
||||
local body
|
||||
if [ -n "$ms" ]; then
|
||||
body=$(jq -n --arg t "$1" --arg b "$2" --argjson ms "$ms" --argjson ids "$ids_json" '{title:$t, body:$b, milestone:$ms, labels:$ids}')
|
||||
else
|
||||
body=$(jq -n --arg t "$1" --arg b "$2" --argjson ids "$ids_json" '{title:$t, body:$b, labels:$ids}')
|
||||
fi
|
||||
local num
|
||||
num=$(req POST "/repos/$REPO/issues" "$body" | jq -r '.number // "FAIL \(.message)"')
|
||||
echo "#$num $1"
|
||||
}
|
||||
|
||||
MS0="Sprint 0 — Setup & deconstruction"
|
||||
MS1="Sprint 1 — Rust core via vls"
|
||||
|
||||
create_issue "Bootstrap cargo project skeleton (lib/bin split + sanity test)" "From docs/tasks/0001. Acceptance: src/main.rs + src/lib.rs (main calls viexp::run()), cargo test green, first conventional commit pushed." "$MS0" "type/chore,priority/P0"
|
||||
create_issue "Add Gitea Actions CI: fmt --check + clippy -D warnings + test" ".gitea/workflows/ci.yml on push to main; green run required." "$MS0" "type/chore,priority/P0"
|
||||
create_issue "Install bacon and verify fast-feedback loop" "cargo install --locked bacon; bacon runs check+test on save; rust-analyzer inline errors verified once." "$MS0" "type/chore,priority/P0"
|
||||
create_issue "ErrorJournal: 3 deliberate compiler errors with self-correction cues" "Break code on purpose (E0382, E0308, E0384), record in docs/learning with cues. Learning artifact." "$MS0" "type/docs,priority/P1,lang/english"
|
||||
create_issue "vls: read directory and print entries" "fs::read_dir + anyhow at main boundary. Sprint-1 drill D1." "$MS1" "type/feature,priority/P0"
|
||||
create_issue "vls: FileEntry struct with metadata" "name, is_dir, is_symlink, size, mtime. Drill D2." "$MS1" "type/feature,priority/P0"
|
||||
create_issue "vls: human-readable sizes + unit tests" "B/K/M/G boundary tests. Drill D3." "$MS1" "type/feature,priority/P1"
|
||||
create_issue "vls: sorting modes (name|size|mtime) via flags" "std::env parsing first, clap later. Drill D4." "$MS1" "type/feature,priority/P1"
|
||||
create_issue "vls: ANSI colors by file type (no crate)" "Hand-rolled escape codes. Drill D5." "$MS1" "type/feature,priority/P2"
|
||||
create_issue "vls: --hidden toggle and --long view" "Dotfile filter; rwx perms string; dates. Drills D6-D7." "$MS1" "type/feature,priority/P2"
|
||||
create_issue "vls: modularize + --json + clap derive" "entry/render/cli modules, serde golden-file test. Drills D8-D10." "$MS1" "type/chore,priority/P1"
|
||||
create_issue "Article: Why build a file manager in Rust (draft)" "150-200 words, English, docs/articles/. Sprint-1 English artifact." "$MS1" "type/docs,priority/P2,lang/english"
|
||||
echo "== done =="
|
||||
Reference in New Issue
Block a user