bigpowers 2.73.5 → 2.73.7
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/.pi/package.json +1 -1
- package/CHANGELOG.md +14 -0
- package/package.json +1 -1
- package/scripts/check-spec-version-gap.sh +37 -9
- package/scripts/lib/migrate-version-common.sh +113 -0
- package/scripts/lib/migrate-version-execute.sh +81 -0
- package/scripts/lib/migrate-version-plan.sh +119 -0
- package/scripts/lib/migrate-version-post.sh +170 -0
- package/scripts/lib/migrate-version-run.sh +53 -0
- package/scripts/lib/migrate-version-transforms.sh +231 -0
- package/scripts/migrate-version.sh +7 -679
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# story: e44s03
|
|
3
|
+
if [ -n "${MIGRATE_VERSION_TRANSFORMS_LOADED:-}" ]; then return 0; fi
|
|
4
|
+
MIGRATE_VERSION_TRANSFORMS_LOADED=1
|
|
5
|
+
yaml_get() { migrate_yaml_get "$@"; }
|
|
6
|
+
apply_transform() {
|
|
7
|
+
local mig_id="$1" action="$2" tjson="$3"
|
|
8
|
+
|
|
9
|
+
case "$action" in
|
|
10
|
+
convert_md_to_yaml)
|
|
11
|
+
local src tgt hm unc_count arch
|
|
12
|
+
src="$(echo "$tjson" | $PYTHON -c "import json,sys; print(json.load(sys.stdin).get('source',''))")"
|
|
13
|
+
tgt="$(echo "$tjson" | $PYTHON -c "import json,sys; print(json.load(sys.stdin).get('target',''))")"
|
|
14
|
+
arch="$(echo "$tjson" | $PYTHON -c "import json,sys; print(json.load(sys.stdin).get('archive_source','false'))" 2>/dev/null)" || arch="false"
|
|
15
|
+
if [ ! -f "$REPO_ROOT/$src" ]; then
|
|
16
|
+
log_skip "$action: source '$src' not found"
|
|
17
|
+
SKIPPED+=("$action:$src"); return
|
|
18
|
+
fi
|
|
19
|
+
hm="$(echo "$tjson" | $PYTHON -c "import json,sys; print(json.dumps(json.load(sys.stdin).get('heuristic_map',{})))")"
|
|
20
|
+
$PYTHON -c "
|
|
21
|
+
import json, re, yaml, sys, os
|
|
22
|
+
src = '$REPO_ROOT/$src'
|
|
23
|
+
tgt = '$REPO_ROOT/$tgt'
|
|
24
|
+
heuristic_map = json.loads('''$hm''')
|
|
25
|
+
content = open(src).read()
|
|
26
|
+
result = {}
|
|
27
|
+
for md_key, yaml_key in heuristic_map.items():
|
|
28
|
+
pat = re.compile(r'^' + re.escape(md_key.rstrip(':')) + r'\\s*[:=]\\s*(.+)$', re.MULTILINE | re.IGNORECASE)
|
|
29
|
+
m = pat.search(content)
|
|
30
|
+
if m:
|
|
31
|
+
val = m.group(1).strip()
|
|
32
|
+
try: val = yaml.safe_load(val) or val
|
|
33
|
+
except: pass
|
|
34
|
+
parts = yaml_key.split('.')
|
|
35
|
+
cur = result
|
|
36
|
+
for p in parts[:-1]:
|
|
37
|
+
if p not in cur or not isinstance(cur[p], dict):
|
|
38
|
+
cur[p] = {}
|
|
39
|
+
cur = cur[p]
|
|
40
|
+
cur[parts[-1]] = val
|
|
41
|
+
os.makedirs(os.path.dirname(tgt), exist_ok=True)
|
|
42
|
+
with open(tgt, 'w') as f:
|
|
43
|
+
yaml.safe_dump(result, f, sort_keys=False, allow_unicode=True, width=100)
|
|
44
|
+
"
|
|
45
|
+
unc_count="$(echo "$tjson" | $PYTHON -c "import json,sys; print(len(json.load(sys.stdin).get('uncertainty',[])))")"
|
|
46
|
+
UNCERTAINTY_COUNT=$((UNCERTAINTY_COUNT + unc_count))
|
|
47
|
+
# Archive source file if requested
|
|
48
|
+
if [ "$arch" = "true" ] || [ "$arch" = "True" ]; then
|
|
49
|
+
local archive_dir="$REPO_ROOT/specs/archive"
|
|
50
|
+
mkdir -p "$archive_dir"
|
|
51
|
+
mv "$REPO_ROOT/$src" "$archive_dir/"
|
|
52
|
+
log_done "$action: $src -> $tgt (source archived to specs/archive/)"
|
|
53
|
+
else
|
|
54
|
+
log_done "$action: $src -> $tgt"
|
|
55
|
+
fi
|
|
56
|
+
;;
|
|
57
|
+
|
|
58
|
+
rename_file)
|
|
59
|
+
local src tgt
|
|
60
|
+
src="$(echo "$tjson" | $PYTHON -c "import json,sys; print(json.load(sys.stdin).get('source',''))")"
|
|
61
|
+
tgt="$(echo "$tjson" | $PYTHON -c "import json,sys; print(json.load(sys.stdin).get('target',''))")"
|
|
62
|
+
if [ ! -e "$REPO_ROOT/$src" ]; then
|
|
63
|
+
log_skip "$action: source '$src' not found — idempotent"
|
|
64
|
+
SKIPPED+=("$action:$src"); return
|
|
65
|
+
fi
|
|
66
|
+
if [ -e "$REPO_ROOT/$tgt" ]; then
|
|
67
|
+
log_skip "$action: target '$tgt' already exists — idempotent"
|
|
68
|
+
SKIPPED+=("$action:$src"); return
|
|
69
|
+
fi
|
|
70
|
+
mkdir -p "$(dirname "$REPO_ROOT/$tgt")"
|
|
71
|
+
mv "$REPO_ROOT/$src" "$REPO_ROOT/$tgt"
|
|
72
|
+
log_done "$action: $src -> $tgt"
|
|
73
|
+
;;
|
|
74
|
+
|
|
75
|
+
move_file)
|
|
76
|
+
local src tgt
|
|
77
|
+
src="$(echo "$tjson" | $PYTHON -c "import json,sys; print(json.load(sys.stdin).get('source',''))")"
|
|
78
|
+
tgt="$(echo "$tjson" | $PYTHON -c "import json,sys; print(json.load(sys.stdin).get('target',''))")"
|
|
79
|
+
if [ ! -e "$REPO_ROOT/$src" ]; then
|
|
80
|
+
log_skip "$action: source '$src' not found"
|
|
81
|
+
SKIPPED+=("$action:$src"); return
|
|
82
|
+
fi
|
|
83
|
+
if [ -e "$REPO_ROOT/$tgt" ]; then
|
|
84
|
+
log_skip "$action: target '$tgt' already exists — idempotent"
|
|
85
|
+
SKIPPED+=("$action:$src"); return
|
|
86
|
+
fi
|
|
87
|
+
mkdir -p "$(dirname "$REPO_ROOT/$tgt")"
|
|
88
|
+
mv "$REPO_ROOT/$src" "$REPO_ROOT/$tgt"
|
|
89
|
+
log_done "$action: $src -> $tgt"
|
|
90
|
+
;;
|
|
91
|
+
|
|
92
|
+
delete_file)
|
|
93
|
+
local path
|
|
94
|
+
path="$(echo "$tjson" | $PYTHON -c "import json,sys; print(json.load(sys.stdin).get('path',''))")"
|
|
95
|
+
if [ ! -e "$REPO_ROOT/$path" ]; then
|
|
96
|
+
log_skip "$action: '$path' not found — idempotent"
|
|
97
|
+
SKIPPED+=("$action:$path"); return
|
|
98
|
+
fi
|
|
99
|
+
rm -f "$REPO_ROOT/$path"
|
|
100
|
+
log_done "$action: $path"
|
|
101
|
+
;;
|
|
102
|
+
|
|
103
|
+
set_yaml_key)
|
|
104
|
+
local file key val if_missing
|
|
105
|
+
file="$(echo "$tjson" | $PYTHON -c "import json,sys; print(json.load(sys.stdin).get('file',''))")"
|
|
106
|
+
key="$(echo "$tjson" | $PYTHON -c "import json,sys; d=json.load(sys.stdin); print(d.get('path') or d.get('key',''))")"
|
|
107
|
+
val="$(echo "$tjson" | $PYTHON -c "import json,sys; print(json.load(sys.stdin).get('value',''))")"
|
|
108
|
+
if_missing="$(echo "$tjson" | $PYTHON -c "import json,sys; print(json.load(sys.stdin).get('if_missing','false'))" 2>/dev/null)" || if_missing="false"
|
|
109
|
+
if [ "$if_missing" = "true" ] || [ "$if_missing" = "True" ]; then
|
|
110
|
+
if yaml_get "$REPO_ROOT/$file" "$key" >/dev/null 2>&1; then
|
|
111
|
+
log_skip "$action: $file $key already set (if_missing=true) — idempotent"
|
|
112
|
+
SKIPPED+=("$action:$key")
|
|
113
|
+
return
|
|
114
|
+
fi
|
|
115
|
+
fi
|
|
116
|
+
$PYTHON "$YAML_TOOLS" set "$REPO_ROOT/$file" "$key" "$val"
|
|
117
|
+
log_done "$action: $file $key = $val"
|
|
118
|
+
;;
|
|
119
|
+
|
|
120
|
+
rename_yaml_key)
|
|
121
|
+
local file old_key new_key old_val
|
|
122
|
+
file="$(echo "$tjson" | $PYTHON -c "import json,sys; print(json.load(sys.stdin).get('file',''))")"
|
|
123
|
+
old_key="$(echo "$tjson" | $PYTHON -c "import json,sys; print(json.load(sys.stdin).get('old_key',''))")"
|
|
124
|
+
new_key="$(echo "$tjson" | $PYTHON -c "import json,sys; print(json.load(sys.stdin).get('new_key',''))")"
|
|
125
|
+
old_val="$(yaml_get "$REPO_ROOT/$file" "$old_key" 2>/dev/null)" || true
|
|
126
|
+
if [ -z "${old_val:-}" ]; then
|
|
127
|
+
log_skip "$action: key '$old_key' not found in $file"
|
|
128
|
+
SKIPPED+=("$action:$old_key"); return
|
|
129
|
+
fi
|
|
130
|
+
$PYTHON "$YAML_TOOLS" set "$REPO_ROOT/$file" "$new_key" "$old_val"
|
|
131
|
+
$PYTHON -c "
|
|
132
|
+
import yaml
|
|
133
|
+
data = yaml.safe_load(open('$REPO_ROOT/$file'))
|
|
134
|
+
parts = '$old_key'.split('.')
|
|
135
|
+
cur = data
|
|
136
|
+
for p in parts[:-1]:
|
|
137
|
+
if not isinstance(cur, dict): break
|
|
138
|
+
cur = cur.get(p, {})
|
|
139
|
+
if isinstance(cur, dict) and parts[-1] in cur:
|
|
140
|
+
del cur[parts[-1]]
|
|
141
|
+
with open('$REPO_ROOT/$file', 'w') as f:
|
|
142
|
+
yaml.safe_dump(data, f, sort_keys=False, allow_unicode=True, width=100)
|
|
143
|
+
" 2>/dev/null
|
|
144
|
+
log_done "$action: $file $old_key -> $new_key = $old_val"
|
|
145
|
+
;;
|
|
146
|
+
|
|
147
|
+
delete_yaml_key)
|
|
148
|
+
local file key
|
|
149
|
+
file="$(echo "$tjson" | $PYTHON -c "import json,sys; print(json.load(sys.stdin).get('file',''))")"
|
|
150
|
+
key="$(echo "$tjson" | $PYTHON -c "import json,sys; d=json.load(sys.stdin); print(d.get('path') or d.get('key',''))")"
|
|
151
|
+
if ! yaml_get "$REPO_ROOT/$file" "$key" >/dev/null 2>&1; then
|
|
152
|
+
log_skip "$action: key '$key' not found in $file — idempotent"
|
|
153
|
+
SKIPPED+=("$action:$key"); return
|
|
154
|
+
fi
|
|
155
|
+
$PYTHON -c "
|
|
156
|
+
import yaml
|
|
157
|
+
data = yaml.safe_load(open('$REPO_ROOT/$file'))
|
|
158
|
+
parts = '$key'.split('.')
|
|
159
|
+
cur = data
|
|
160
|
+
for p in parts[:-1]:
|
|
161
|
+
if not isinstance(cur, dict): break
|
|
162
|
+
cur = cur.get(p, {})
|
|
163
|
+
if isinstance(cur, dict) and parts[-1] in cur:
|
|
164
|
+
del cur[parts[-1]]
|
|
165
|
+
with open('$REPO_ROOT/$file', 'w') as f:
|
|
166
|
+
yaml.safe_dump(data, f, sort_keys=False, allow_unicode=True, width=100)
|
|
167
|
+
" 2>/dev/null
|
|
168
|
+
log_done "$action: $file $key"
|
|
169
|
+
;;
|
|
170
|
+
|
|
171
|
+
create_file_from_template)
|
|
172
|
+
local src tgt subs inline_tmpl
|
|
173
|
+
src="$(echo "$tjson" | $PYTHON -c "import json,sys; print(json.load(sys.stdin).get('source',''))")"
|
|
174
|
+
tgt="$(echo "$tjson" | $PYTHON -c "import json,sys; print(json.load(sys.stdin).get('target',''))")"
|
|
175
|
+
subs="$(echo "$tjson" | $PYTHON -c "import json,sys; print(json.dumps(json.load(sys.stdin).get('substitutions',{})))")"
|
|
176
|
+
inline_tmpl="$(echo "$tjson" | $PYTHON -c "import json,sys; print(json.load(sys.stdin).get('template',''))")"
|
|
177
|
+
if [ -e "$REPO_ROOT/$tgt" ]; then
|
|
178
|
+
log_skip "$action: target '$tgt' already exists — idempotent"
|
|
179
|
+
SKIPPED+=("$action:$tgt"); return
|
|
180
|
+
fi
|
|
181
|
+
mkdir -p "$(dirname "$REPO_ROOT/$tgt")"
|
|
182
|
+
# Inline template (content embedded in OKF bundle)
|
|
183
|
+
if [ -n "$inline_tmpl" ]; then
|
|
184
|
+
echo "$inline_tmpl" > "$REPO_ROOT/$tgt"
|
|
185
|
+
if [ "$subs" != "{}" ]; then
|
|
186
|
+
$PYTHON -c "
|
|
187
|
+
import json
|
|
188
|
+
subs = json.loads('''$subs''')
|
|
189
|
+
content = open('$REPO_ROOT/$tgt').read()
|
|
190
|
+
for k, v in subs.items():
|
|
191
|
+
content = content.replace(k, v)
|
|
192
|
+
with open('$REPO_ROOT/$tgt', 'w') as f:
|
|
193
|
+
f.write(content)
|
|
194
|
+
" 2>/dev/null
|
|
195
|
+
fi
|
|
196
|
+
log_done "$action: inline template -> $tgt"
|
|
197
|
+
return
|
|
198
|
+
fi
|
|
199
|
+
# File-based template resolution
|
|
200
|
+
template_path=""
|
|
201
|
+
if [ -n "$src" ]; then
|
|
202
|
+
# Try source as relative path first, then as template name
|
|
203
|
+
if [ -f "$REPO_ROOT/$src" ]; then
|
|
204
|
+
template_path="$REPO_ROOT/$src"
|
|
205
|
+
elif [ -f "$REPO_ROOT/specs/templates/${src##*/}" ]; then
|
|
206
|
+
template_path="$REPO_ROOT/specs/templates/${src##*/}"
|
|
207
|
+
fi
|
|
208
|
+
fi
|
|
209
|
+
if [ -z "$template_path" ] || [ ! -f "$template_path" ]; then
|
|
210
|
+
log_skip "$action: template not found (src='$src')"
|
|
211
|
+
SKIPPED+=("$action:$src"); return
|
|
212
|
+
fi
|
|
213
|
+
cp "$template_path" "$REPO_ROOT/$tgt"
|
|
214
|
+
$PYTHON -c "
|
|
215
|
+
import json
|
|
216
|
+
subs = json.loads('''$subs''')
|
|
217
|
+
content = open('$REPO_ROOT/$tgt').read()
|
|
218
|
+
for k, v in subs.items():
|
|
219
|
+
content = content.replace(k, v)
|
|
220
|
+
with open('$REPO_ROOT/$tgt', 'w') as f:
|
|
221
|
+
f.write(content)
|
|
222
|
+
" 2>/dev/null
|
|
223
|
+
log_done "$action: $src -> $tgt"
|
|
224
|
+
;;
|
|
225
|
+
|
|
226
|
+
*)
|
|
227
|
+
log_skip "$action: unknown transform type"
|
|
228
|
+
SKIPPED+=("$action")
|
|
229
|
+
;;
|
|
230
|
+
esac
|
|
231
|
+
}
|