#!/usr/bin/env bash # tools/rename-to-scadabridge.sh # # Renames the codebase from ScadaLink → ZB.MOM.WW.ScadaBridge. # Multi-pass substitution, most-specific-first to avoid double-replacement. # Operates on git-tracked files only (skips .git/, untracked, binaries via git grep). # # Usage: # tools/rename-to-scadabridge.sh --dry-run # print affected files, no changes # tools/rename-to-scadabridge.sh # apply text substitutions + git mv folder/file moves # # After running, follow with: # dotnet restore # dotnet build ZB.MOM.WW.ScadaBridge.slnx # # See docs/plans/2026-05-28-scadabridge-rename-design.md for the full design. set -euo pipefail cd "$(git rev-parse --show-toplevel)" DRY_RUN=0 if [[ "${1:-}" == "--dry-run" ]]; then DRY_RUN=1 echo "DRY RUN mode: no changes will be made" echo fi # Exclude the design doc itself from text substitutions — it documents the # rename and contains both old and new names on purpose. EXCLUDE=(':(exclude)docs/plans/2026-05-28-scadabridge-rename-design.md') run_sed() { local pattern="$1" local replacement="$2" local desc="$3" # git grep with --fixed-strings finds files containing the literal pattern. # It's binary-aware and respects .gitignore. local file_list file_list=$(git grep -l --fixed-strings -- "$pattern" "${EXCLUDE[@]}" 2>/dev/null || true) local count=0 if [[ -n "$file_list" ]]; then count=$(printf '%s\n' "$file_list" | wc -l | tr -d ' ') fi if [[ "$count" -eq 0 ]]; then printf ' %-50s no files match\n' "$desc" return fi printf ' %-50s %d files\n' "$desc" "$count" if [[ "$DRY_RUN" -eq 1 ]]; then printf '%s\n' "$file_list" | head -5 | sed 's/^/ /' [[ "$count" -gt 5 ]] && echo " ... ($((count - 5)) more)" return fi # Escape pattern (BRE metacharacters) and replacement (& \ /). local esc_pattern esc_replacement esc_pattern=$(printf '%s' "$pattern" | sed 's/[][\.*^$/]/\\&/g') esc_replacement=$(printf '%s' "$replacement" | sed 's/[\&/]/\\&/g') printf '%s\n' "$file_list" | tr '\n' '\0' | xargs -0 sed -i '' -e "s/$esc_pattern/$esc_replacement/g" } echo "=== Phase B: text substitutions ===" # Order matters: most-specific patterns first so later passes don't catch substrings. run_sed "ScadaLinkDbContext" "ScadaBridgeDbContext" "1. ScadaLinkDbContext" run_sed "ScadaLinkMachineData" "ScadaBridgeMachineData" "2. ScadaLinkMachineData" run_sed "ScadaLinkConfig" "ScadaBridgeConfig" "3. ScadaLinkConfig" run_sed "ScadaLink." "ZB.MOM.WW.ScadaBridge." "4. ScadaLink. (namespace/path)" run_sed "ScadaLink" "ScadaBridge" "5. ScadaLink (bare ident)" run_sed "scadalink-" "scadabridge-" "6. scadalink- (container/network)" run_sed "scadalink:" "scadabridge:" "7. scadalink: (image tag)" run_sed ".scadalink/" ".scadabridge/" "8. .scadalink/ (CLI config dir)" run_sed "scadalink" "scadabridge" "9. scadalink (bare lowercase)" if [[ "$DRY_RUN" -eq 1 ]]; then echo echo "DRY RUN complete. No file moves performed." exit 0 fi echo echo "=== Phase C: file/folder moves ===" # Rename project folders: src/ScadaLink.X → src/ZB.MOM.WW.ScadaBridge.X (and tests/) shopt -s nullglob for old in src/ScadaLink.* tests/ScadaLink.*; do [[ -d "$old" ]] || continue new="${old/ScadaLink./ZB.MOM.WW.ScadaBridge.}" echo " git mv $old $new" git mv "$old" "$new" done # Rename .csproj files inside each renamed folder for d in src/ZB.MOM.WW.ScadaBridge.* tests/ZB.MOM.WW.ScadaBridge.*; do [[ -d "$d" ]] || continue for csproj in "$d"/ScadaLink.*.csproj; do [[ -f "$csproj" ]] || continue newcsproj="${csproj/ScadaLink./ZB.MOM.WW.ScadaBridge.}" echo " git mv $csproj $newcsproj" git mv "$csproj" "$newcsproj" done done # Rename .cs files whose basename starts with ScadaLink (DbContext, WebApplicationFactory, snapshot). while IFS= read -r f; do new="${f//ScadaLink/ScadaBridge}" echo " git mv $f $new" git mv "$f" "$new" done < <(git ls-files | awk -F/ '$NF ~ /^ScadaLink[A-Za-z]+\.cs$/') # Rename solution file. if [[ -f "ScadaLink.slnx" ]]; then echo " git mv ScadaLink.slnx ZB.MOM.WW.ScadaBridge.slnx" git mv ScadaLink.slnx ZB.MOM.WW.ScadaBridge.slnx fi shopt -u nullglob echo echo "=== Done. Next: dotnet restore && dotnet build ZB.MOM.WW.ScadaBridge.slnx ==="