@sdd-method/sdd-cli 0.110.0 → 0.111.0

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.
@@ -1,274 +0,0 @@
1
- #!/bin/bash
2
- #
3
- # sync-method-baseline.sh
4
- # Apply a built method baseline bundle to a target repository.
5
- #
6
- # Usage:
7
- # ./orchestration/scripts/sync-method-baseline.sh --bundle dist/method-baseline/method-baseline-v0.1.0.tar.gz
8
- # ./orchestration/scripts/sync-method-baseline.sh --bundle ... --target-repo /path/to/repo --dry-run
9
-
10
- set -euo pipefail
11
-
12
- RED='\033[0;31m'
13
- GREEN='\033[0;32m'
14
- BLUE='\033[0;34m'
15
- NC='\033[0m'
16
- REPO_KIND_FILE=".sdd-repo-kind"
17
- PROTECTED_PREFIXES=("content/")
18
-
19
- log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
20
- log_fail() { echo -e "${RED}[FAIL]${NC} $1"; }
21
- log_pass() { echo -e "${GREEN}[PASS]${NC} $1"; }
22
- log_section() {
23
- echo -e "\n${BLUE}═══════════════════════════════════════════════════════════${NC}"
24
- echo -e "${BLUE} $1${NC}"
25
- echo -e "${BLUE}═══════════════════════════════════════════════════════════${NC}\n"
26
- }
27
-
28
- usage() {
29
- cat <<USAGE
30
- Usage: $(basename "$0") --bundle <path.tar.gz> [--target-repo <dir>] [--dry-run] [--allow-overwrite] [--no-delete]
31
-
32
- Options:
33
- --bundle Required bundle archive generated by build-method-baseline-bundle.sh
34
- --target-repo Target repository root (default: current working directory)
35
- --dry-run Report plan only; do not modify files
36
- --allow-overwrite Overwrite conflicting managed files (default: fail on conflict)
37
- --no-delete Do not delete previously managed files removed from the incoming bundle
38
- USAGE
39
- }
40
-
41
- BUNDLE=""
42
- TARGET_REPO="$(pwd)"
43
- DRY_RUN=0
44
- ALLOW_OVERWRITE=0
45
- NO_DELETE=0
46
-
47
- while [[ $# -gt 0 ]]; do
48
- case "$1" in
49
- --bundle)
50
- BUNDLE="${2:-}"
51
- shift 2
52
- ;;
53
- --target-repo)
54
- TARGET_REPO="${2:-}"
55
- shift 2
56
- ;;
57
- --dry-run)
58
- DRY_RUN=1
59
- shift
60
- ;;
61
- --allow-overwrite)
62
- ALLOW_OVERWRITE=1
63
- shift
64
- ;;
65
- --no-delete)
66
- NO_DELETE=1
67
- shift
68
- ;;
69
- -h|--help)
70
- usage
71
- exit 0
72
- ;;
73
- *)
74
- log_fail "Unknown argument: $1"
75
- usage
76
- exit 1
77
- ;;
78
- esac
79
- done
80
-
81
- if [[ -z "$BUNDLE" ]]; then
82
- log_fail "--bundle is required"
83
- usage
84
- exit 1
85
- fi
86
-
87
- if [[ ! -f "$BUNDLE" ]]; then
88
- log_fail "Bundle not found: $BUNDLE"
89
- exit 1
90
- fi
91
-
92
- if [[ ! -d "$TARGET_REPO" ]]; then
93
- log_fail "Target repo not found: $TARGET_REPO"
94
- exit 1
95
- fi
96
-
97
- log_section "Sync Method Baseline"
98
-
99
- TMP_DIR="$(mktemp -d)"
100
- trap 'rm -rf "$TMP_DIR"' EXIT
101
-
102
- tar -xzf "$BUNDLE" -C "$TMP_DIR"
103
- BUNDLE_ROOT="$(find "$TMP_DIR" -mindepth 1 -maxdepth 1 -type d | head -n 1)"
104
- if [[ -z "$BUNDLE_ROOT" ]]; then
105
- log_fail "Could not find extracted bundle root"
106
- exit 1
107
- fi
108
-
109
- MANAGED_PATHS_FILE="$BUNDLE_ROOT/MANAGED_PATHS.txt"
110
- PAYLOAD_DIR="$BUNDLE_ROOT/payload"
111
- MANIFEST_FILE="$BUNDLE_ROOT/BUNDLE_MANIFEST.yaml"
112
- LOCK_FILE="$TARGET_REPO/method-baseline.lock"
113
-
114
- if [[ ! -f "$MANAGED_PATHS_FILE" || ! -d "$PAYLOAD_DIR" || ! -f "$MANIFEST_FILE" ]]; then
115
- log_fail "Bundle missing required files (MANAGED_PATHS.txt, payload/, or BUNDLE_MANIFEST.yaml)"
116
- exit 1
117
- fi
118
-
119
- BUNDLE_VERSION="$(awk -F': ' '/^bundle_version:/{gsub(/"/,"",$2); print $2}' "$MANIFEST_FILE")"
120
- SOURCE_COMMIT="$(awk -F': ' '/^source_commit:/{gsub(/"/,"",$2); print $2}' "$MANIFEST_FILE")"
121
- BUNDLE_NAME="$(awk -F': ' '/^bundle_name:/{gsub(/"/,"",$2); print $2}' "$MANIFEST_FILE")"
122
-
123
- case "$BUNDLE_NAME" in
124
- platform-baseline)
125
- REPO_KIND_VALUE="platform-product"
126
- ;;
127
- app-baseline)
128
- REPO_KIND_VALUE="application-product"
129
- ;;
130
- integration-baseline)
131
- REPO_KIND_VALUE="integration-product"
132
- ;;
133
- *)
134
- log_fail "Unknown bundle_name in manifest: $BUNDLE_NAME"
135
- exit 1
136
- ;;
137
- esac
138
-
139
- mapfile -t INCOMING_PATHS < "$MANAGED_PATHS_FILE"
140
-
141
- for p in "${INCOMING_PATHS[@]}"; do
142
- if [[ ! -f "$PAYLOAD_DIR/$p" ]]; then
143
- log_fail "Missing payload file listed in MANAGED_PATHS.txt: $p"
144
- exit 1
145
- fi
146
- for prefix in "${PROTECTED_PREFIXES[@]}"; do
147
- if [[ "$p" == "$prefix"* ]]; then
148
- log_fail "Incoming bundle attempts to manage protected product-owned path: $p"
149
- log_fail "Method baseline bundles must not manage files under: ${PROTECTED_PREFIXES[*]}"
150
- exit 1
151
- fi
152
- done
153
- done
154
-
155
- # Detect conflicts unless caller explicitly allows overwrite.
156
- CONFLICTS=()
157
- for p in "${INCOMING_PATHS[@]}"; do
158
- target_file="$TARGET_REPO/$p"
159
- incoming_file="$PAYLOAD_DIR/$p"
160
- if [[ -f "$target_file" ]] && ! cmp -s "$incoming_file" "$target_file"; then
161
- CONFLICTS+=("$p")
162
- fi
163
- done
164
-
165
- if [[ ${#CONFLICTS[@]} -gt 0 && "$ALLOW_OVERWRITE" -ne 1 ]]; then
166
- log_fail "Found ${#CONFLICTS[@]} conflicting managed file(s). Re-run with --allow-overwrite to apply."
167
- printf '%s\n' "${CONFLICTS[@]}" | sed 's/^/ - /'
168
- exit 1
169
- fi
170
-
171
- # Load previously managed paths from lock file (if present).
172
- # Supports v2 format (lock_version: 2) with bundles array.
173
- PREV_PATHS=()
174
- if [[ -f "$LOCK_FILE" ]]; then
175
- while IFS= read -r p; do
176
- PREV_PATHS+=("$p")
177
- done < <(awk '
178
- /managed_paths:/ {in_list=1; next}
179
- in_list && /^ - / {sub(/^ - /, ""); print; next}
180
- in_list && /^ - / {sub(/^ - /, ""); print; next}
181
- in_list && !/^ / {in_list=0}
182
- ' "$LOCK_FILE")
183
- fi
184
-
185
- for p in "${PREV_PATHS[@]}"; do
186
- for prefix in "${PROTECTED_PREFIXES[@]}"; do
187
- if [[ "$p" == "$prefix"* ]]; then
188
- log_fail "Existing lock file contains protected product-owned path: $p"
189
- log_fail "Resolve this manually before refreshing the method baseline."
190
- exit 1
191
- fi
192
- done
193
- done
194
-
195
- # Compute removal set: paths previously managed but not in incoming list.
196
- REMOVE_PATHS=()
197
- if [[ "$NO_DELETE" -ne 1 && ${#PREV_PATHS[@]} -gt 0 ]]; then
198
- for prev in "${PREV_PATHS[@]}"; do
199
- keep=0
200
- for cur in "${INCOMING_PATHS[@]}"; do
201
- if [[ "$prev" == "$cur" ]]; then
202
- keep=1
203
- break
204
- fi
205
- done
206
- if [[ "$keep" -eq 0 ]]; then
207
- REMOVE_PATHS+=("$prev")
208
- fi
209
- done
210
- fi
211
-
212
- log_info "Bundle: $BUNDLE_NAME (version: $BUNDLE_VERSION)"
213
- log_info "Incoming managed files: ${#INCOMING_PATHS[@]}"
214
- log_info "Conflicts: ${#CONFLICTS[@]}"
215
- log_info "Removals from previous sync of this bundle: ${#REMOVE_PATHS[@]}"
216
- log_info "Protected ownership prefixes: ${PROTECTED_PREFIXES[*]}"
217
-
218
- if [[ "$DRY_RUN" -eq 1 ]]; then
219
- log_info "Dry run enabled. No files modified."
220
- if [[ ${#CONFLICTS[@]} -gt 0 ]]; then
221
- log_info "Conflicting files:"
222
- printf '%s\n' "${CONFLICTS[@]}" | sed 's/^/ - /'
223
- fi
224
- if [[ ${#REMOVE_PATHS[@]} -gt 0 ]]; then
225
- log_info "Files that would be removed:"
226
- printf '%s\n' "${REMOVE_PATHS[@]}" | sed 's/^/ - /'
227
- fi
228
- exit 0
229
- fi
230
-
231
- # Apply incoming managed files.
232
- for p in "${INCOMING_PATHS[@]}"; do
233
- mkdir -p "$TARGET_REPO/$(dirname "$p")"
234
- cp "$PAYLOAD_DIR/$p" "$TARGET_REPO/$p"
235
- done
236
-
237
- # Remove files no longer managed by this baseline.
238
- for p in "${REMOVE_PATHS[@]}"; do
239
- rm -f "$TARGET_REPO/$p"
240
- done
241
-
242
- printf '%s\n' "$REPO_KIND_VALUE" > "$TARGET_REPO/$REPO_KIND_FILE"
243
-
244
- SYNCED_AT_UTC="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
245
- BUNDLE_SHA="$(sha256sum "$BUNDLE" | awk '{print $1}')"
246
-
247
- {
248
- echo "method_repo: sdd-method"
249
- echo "lock_version: 3"
250
- echo "bundles:"
251
- echo " - name: $BUNDLE_NAME"
252
- echo " bundle_version: \"$BUNDLE_VERSION\""
253
- echo " source_commit: \"$SOURCE_COMMIT\""
254
- echo " bundle_sha256: \"$BUNDLE_SHA\""
255
- echo " synced_at_utc: \"$SYNCED_AT_UTC\""
256
- echo " is_forward_base: true"
257
- echo " managed_paths:"
258
- # lock_version 3: `- <sha256> <path>`. The digest comes from the PAYLOAD —
259
- # what this sync applied — matching sdd-cli exactly, because the parity test
260
- # asserts byte equality. Updated in lockstep deliberately: a bash path still
261
- # writing version 2 would DOWNGRADE a v3 lock on its next run and destroy the
262
- # digests that make pristine-vs-edited decidable.
263
- for p in "${INCOMING_PATHS[@]}"; do
264
- if [[ -f "$PAYLOAD_DIR/$p" ]]; then
265
- echo " - $(sha256sum "$PAYLOAD_DIR/$p" | awk '{print $1}') $p"
266
- else
267
- echo " - $p"
268
- fi
269
- done
270
- } > "$LOCK_FILE"
271
-
272
- log_pass "Method baseline synced to: $TARGET_REPO"
273
- log_info "Updated lock file: method-baseline.lock (lock_version: 3)"
274
- log_info "Set repo kind marker: $REPO_KIND_FILE = $REPO_KIND_VALUE"