← back to Dw Vendor Microsites

lib/manifest-lib.sh

62 lines

#!/usr/bin/env bash
# manifest-lib.sh — helpers for reading/writing manifest.json (flock-safe).
#
#   manifest_upsert <vendor_code> <json_fragment>   # merge keys into vendors.<code>
#   manifest_get <vendor_code> [key]                # print whole entry or one key
#
# manifest.json shape:
#   { "updated_at": "...", "vendors": { "<code>": { ...entry... } } }
set -euo pipefail

_REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
MANIFEST="${MANIFEST:-$_REPO/manifest.json}"
_MLOCK="$_REPO/.manifest.lock"

manifest_upsert() {
  local vendor="$1"; local frag="$2"
  # macOS has no flock(1); portable mkdir mutex (atomic create)
  local _ld="${_MLOCK}.d"; local _i
  for _i in $(seq 1 100); do mkdir "$_ld" 2>/dev/null && break; sleep 0.1; done
  python3 - "$MANIFEST" "$vendor" "$frag" <<'PY'
import sys, json, os, datetime
path, vendor, frag = sys.argv[1], sys.argv[2], sys.argv[3]
try:
    m = json.load(open(path))
except Exception:
    m = {}
m.setdefault('vendors', {})
entry = m['vendors'].get(vendor, {})
try:
    patch = json.loads(frag)
except Exception as e:
    print("manifest_upsert: bad json fragment:", e, file=sys.stderr); sys.exit(1)
entry.update(patch)
entry['vendor_code'] = vendor
m['vendors'][vendor] = entry
m['updated_at'] = datetime.datetime.now().isoformat()
tmp = path + '.tmp'
json.dump(m, open(tmp, 'w'), indent=2)
os.replace(tmp, path)
PY
  rmdir "$_ld" 2>/dev/null || true
}

manifest_get() {
  local vendor="$1"; local key="${2:-}"
  python3 - "$MANIFEST" "$vendor" "$key" <<'PY'
import sys, json
path, vendor, key = sys.argv[1], sys.argv[2], sys.argv[3]
try:
    m = json.load(open(path))
except Exception:
    sys.exit(0)
e = (m.get('vendors') or {}).get(vendor)
if not e: sys.exit(0)
if key:
    v = e.get(key)
    print('' if v is None else (v if isinstance(v,str) else json.dumps(v)))
else:
    print(json.dumps(e, indent=2))
PY
}