upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/docs/archive/2026-01-relay-ngit-dev-migration/scripts/20-categorize.sh
diff options
context:
space:
mode:
authorDanConwayDev <DanConwayDev@protonmail.com>2026-02-23 15:20:59 +0000
committerDanConwayDev <DanConwayDev@protonmail.com>2026-02-23 15:20:59 +0000
commit113928aa84894ea8f65c247d9987527e792b32a9 (patch)
treeec967d6195d9f7ec4f061449596611afe3a0950f /docs/archive/2026-01-relay-ngit-dev-migration/scripts/20-categorize.sh
parent26f608e5011b9d1ad6036da75b89272835e69695 (diff)
parente0ad39a489b3398f8208713bf728db0cb11475b0 (diff)
Merge master into 3ca0-announcements-purgatory
Diffstat (limited to 'docs/archive/2026-01-relay-ngit-dev-migration/scripts/20-categorize.sh')
-rwxr-xr-xdocs/archive/2026-01-relay-ngit-dev-migration/scripts/20-categorize.sh212
1 files changed, 212 insertions, 0 deletions
diff --git a/docs/archive/2026-01-relay-ngit-dev-migration/scripts/20-categorize.sh b/docs/archive/2026-01-relay-ngit-dev-migration/scripts/20-categorize.sh
new file mode 100755
index 0000000..b38dc00
--- /dev/null
+++ b/docs/archive/2026-01-relay-ngit-dev-migration/scripts/20-categorize.sh
@@ -0,0 +1,212 @@
1#!/usr/bin/env bash
2#
3# 20-categorize.sh - Categorize git sync status into 4 categories
4#
5# PHASE 3a of the GRASP relay to ngit-grasp migration analysis pipeline.
6# Takes git-sync-status.tsv from Phase 2 and categorizes into 4 files.
7#
8# USAGE:
9# ./20-categorize.sh <git-sync-status.tsv> <output-dir>
10#
11# EXAMPLES:
12# ./20-categorize.sh output/prod/git-sync-status.tsv output/prod
13# ./20-categorize.sh output/archive/git-sync-status.tsv output/archive
14#
15# INPUT FORMAT (git-sync-status.tsv):
16# Tab-separated values with columns:
17# repo<TAB>npub<TAB>state_refs<TAB>git_refs<TAB>matches<TAB>reason
18#
19# Where reason is optional and can be: no_git_dir, empty_refs, no_state_refs
20#
21# OUTPUT:
22# <output-dir>/category1-complete-match.txt - All refs match perfectly
23# <output-dir>/category2-empty-blank.txt - No git data available
24# <output-dir>/category3-partial-match.txt - Some refs match
25# <output-dir>/category4-no-match.txt - Git exists but refs don't match
26#
27# OUTPUT FORMAT:
28# repo | npub | state_refs=N | git_refs=N | matches=N [| reason=X]
29#
30# CATEGORIES:
31# 1. Complete Match: state_refs == git_refs == matches (all > 0)
32# 2. Empty/Blank: git_refs == 0 OR reason in (no_git_dir, empty_refs, no_state_refs)
33# 3. Partial Match: matches > 0 AND matches < state_refs
34# 4. No Match: git_refs > 0 AND matches == 0
35#
36# PREREQUISITES:
37# - awk (standard Unix tool)
38#
39# RUNTIME: < 1 second (local processing only)
40#
41# SEE ALSO:
42# docs/how-to/migrate-to-ngit-grasp.md - Full migration guide
43# 10-check-git-sync.sh - Phase 2 script that produces input for this script
44#
45
46set -euo pipefail
47
48# Colors for output (disabled if not a terminal)
49if [[ -t 1 ]]; then
50 RED='\033[0;31m'
51 GREEN='\033[0;32m'
52 YELLOW='\033[0;33m'
53 BLUE='\033[0;34m'
54 NC='\033[0m'
55else
56 RED=''
57 GREEN=''
58 YELLOW=''
59 BLUE=''
60 NC=''
61fi
62
63log_info() {
64 echo -e "${BLUE}[INFO]${NC} $*" >&2
65}
66
67log_success() {
68 echo -e "${GREEN}[OK]${NC} $*" >&2
69}
70
71log_warn() {
72 echo -e "${YELLOW}[WARN]${NC} $*" >&2
73}
74
75log_error() {
76 echo -e "${RED}[ERROR]${NC} $*" >&2
77}
78
79usage() {
80 echo "Usage: $0 <git-sync-status.tsv> <output-dir>"
81 echo ""
82 echo "Arguments:"
83 echo " git-sync-status.tsv TSV file from Phase 2 (10-check-git-sync.sh)"
84 echo " output-dir Directory to store categorized output"
85 echo ""
86 echo "Examples:"
87 echo " $0 output/prod/git-sync-status.tsv output/prod"
88 echo " $0 output/archive/git-sync-status.tsv output/archive"
89 echo ""
90 echo "Input format (TSV):"
91 echo " repo<TAB>npub<TAB>state_refs<TAB>git_refs<TAB>matches<TAB>reason"
92 echo ""
93 echo "Output files:"
94 echo " category1-complete-match.txt - All refs match"
95 echo " category2-empty-blank.txt - No git data"
96 echo " category3-partial-match.txt - Some refs match"
97 echo " category4-no-match.txt - Git exists, refs don't match"
98 exit 1
99}
100
101# Main
102main() {
103 if [[ $# -ne 2 ]]; then
104 usage
105 fi
106
107 local input_file="$1"
108 local output_dir="$2"
109
110 # Validate input file
111 if [[ ! -f "$input_file" ]]; then
112 log_error "Input file not found: $input_file"
113 exit 1
114 fi
115
116 log_info "Categorizing git sync status"
117 log_info "Input: $input_file"
118 log_info "Output: $output_dir"
119
120 # Create output directory
121 mkdir -p "$output_dir"
122
123 # Output files
124 local cat1="$output_dir/category1-complete-match.txt"
125 local cat2="$output_dir/category2-empty-blank.txt"
126 local cat3="$output_dir/category3-partial-match.txt"
127 local cat4="$output_dir/category4-no-match.txt"
128
129 # Clear previous results
130 > "$cat1"
131 > "$cat2"
132 > "$cat3"
133 > "$cat4"
134
135 # Process input file with awk
136 # Input: repo<TAB>npub<TAB>state_refs<TAB>git_refs<TAB>matches<TAB>reason
137 awk -F'\t' -v cat1="$cat1" -v cat2="$cat2" -v cat3="$cat3" -v cat4="$cat4" '
138 BEGIN {
139 count1 = 0; count2 = 0; count3 = 0; count4 = 0
140 }
141 NR == 1 && /^repo/ { next } # Skip header if present
142 NF >= 5 {
143 repo = $1
144 npub = $2
145 state_refs = int($3)
146 git_refs = int($4)
147 matches = int($5)
148 reason = (NF >= 6) ? $6 : ""
149
150 # Format output line
151 if (reason != "") {
152 line = repo " | " npub " | state_refs=" state_refs " | git_refs=" git_refs " | matches=" matches " | reason=" reason
153 } else {
154 line = repo " | " npub " | state_refs=" state_refs " | git_refs=" git_refs " | matches=" matches
155 }
156
157 # Categorize
158 if (reason == "no_git_dir" || reason == "empty_refs" || reason == "no_state_refs" || git_refs == 0) {
159 # Category 2: Empty/Blank
160 print line >> cat2
161 count2++
162 } else if (state_refs > 0 && state_refs == git_refs && matches == state_refs) {
163 # Category 1: Complete Match
164 print line >> cat1
165 count1++
166 } else if (matches > 0 && matches < state_refs) {
167 # Category 3: Partial Match
168 print line >> cat3
169 count3++
170 } else if (git_refs > 0 && matches == 0) {
171 # Category 4: No Match
172 print line >> cat4
173 count4++
174 } else if (matches > 0) {
175 # Edge case: matches > 0 but does not fit other categories
176 # This can happen when git_refs > state_refs but all state refs match
177 # Treat as partial match
178 print line >> cat3
179 count3++
180 } else {
181 # Fallback: treat as category 2 (empty/blank)
182 print line >> cat2
183 count2++
184 }
185 }
186 END {
187 total = count1 + count2 + count3 + count4
188 print "COUNTS:" count1 ":" count2 ":" count3 ":" count4 ":" total
189 }
190 ' "$input_file" 2>&1 | while IFS= read -r line; do
191 if [[ "$line" =~ ^COUNTS: ]]; then
192 # Parse counts from awk output
193 IFS=':' read -r _ c1 c2 c3 c4 total <<< "$line"
194
195 echo ""
196 log_info "=== Categorization Summary ==="
197 log_info "Total entries: $total"
198 log_success "Category 1 (Complete Match): $c1"
199 log_warn "Category 2 (Empty/Blank): $c2"
200 log_warn "Category 3 (Partial Match): $c3"
201 log_error "Category 4 (No Match): $c4"
202 echo ""
203 log_info "Output files:"
204 echo " $cat1"
205 echo " $cat2"
206 echo " $cat3"
207 echo " $cat4"
208 fi
209 done
210}
211
212main "$@"