swap_source.sh #3

  • //
  • test-install_sdp/
  • dev/
  • swap_source.sh
  • View
  • Commits
  • Open Download .zip Download (4 KB)
#!/bin/bash
# swap_source.sh <StreamPath>
#
# Sets /opt/perforce/dev/sdp or /opt/perforce/dev/bin to pull from a
# different stream, e.g.:
#
#   ./swap_source.sh p4-sdp/dev_rebrand
#   ./swap_source.sh p4-sdp/dev
#   ./swap_source.sh p4-sdp/main
#   ./swap_source.sh test-install_sdp/dev
#   ./swap_source.sh test-install_sdp/main
#
# This is also how the initial clone is done on a fresh machine -- there's
# no separate bootstrap step. The first time a given StreamPath is used on a
# machine, this does a fresh 'p4 clone -r' using a matching remote spec
# (StreamPath with '/' replaced by '_', e.g. p4-sdp_dev_rebrand). On later
# calls, if the target directory was previously parked by this script for a
# different source, that source is parked in turn and the requested one is
# moved back into place -- no re-clone needed.
#
# Read-only access (P4USER=ftp) is used for a fresh clone unless
# P4_SWAP_USER is set in the environment, e.g. for read/write access:
#   P4_SWAP_USER=yourP4user ./swap_source.sh p4-sdp/dev_rebrand

set -u

ThisScript=${0##*/}

function msg () { echo -e "$*"; }
function bail () { echo -e "\\nError: ${1:-Unknown Error}\\n"; exit 1; }

# Mirrors the DEV_HOME logic in dev_env.sh.
if [[ "$HOSTNAME" == p4c-bos-01.p4demo.com ]]; then
   DevHome=/opt/perforce/.dev
else
   DevHome=/opt/perforce/dev
fi

P4Port=public.perforce.com:1666
P4CloneUser=${P4_SWAP_USER:-ftp}

StreamPath="${1:-}"
[[ -n "$StreamPath" ]] || bail "Usage: $ThisScript <StreamPath>, e.g. $ThisScript p4-sdp/dev_rebrand"

case "$StreamPath" in
   p4-sdp/*)           Target=sdp ;;
   test-install_sdp/*) Target=bin ;;
   *) bail "Unrecognized stream path '$StreamPath'; expected p4-sdp/<stream> or test-install_sdp/<stream>." ;;
esac

RemoteSpec="${StreamPath//\//_}"
ActiveDir="$DevHome/$Target"
MarkerFile="$ActiveDir/.current-source"

if [[ -e "$ActiveDir" && ! -d "$ActiveDir" ]]; then
   bail "$ActiveDir exists and is not a directory."
fi

CurrentSuffix=
[[ -f "$MarkerFile" ]] && CurrentSuffix="$(cat "$MarkerFile")"

if [[ "$CurrentSuffix" == "$RemoteSpec" ]]; then
   msg "$Target is already sourced from $StreamPath. Nothing to do."
   exit 0
fi

ParkedTargetDir="${ActiveDir}.${RemoteSpec}"

if [[ -d "$ActiveDir" ]]; then
   if [[ -z "$CurrentSuffix" ]]; then
      bail "$ActiveDir exists but has no $MarkerFile identifying its source; refusing to move it aside blindly. Investigate manually."
   fi
   ParkedCurrentDir="${ActiveDir}.${CurrentSuffix}"
   [[ -e "$ParkedCurrentDir" ]] && bail "Cannot park $ActiveDir at $ParkedCurrentDir; that path already exists."
   msg "Parking current $Target checkout ($CurrentSuffix) at $ParkedCurrentDir ..."
   mv "$ActiveDir" "$ParkedCurrentDir" || bail "mv \"$ActiveDir\" \"$ParkedCurrentDir\" failed."
fi

if [[ -d "$ParkedTargetDir" ]]; then
   msg "Restoring previously-parked $Target checkout for $StreamPath from $ParkedTargetDir ..."
   mv "$ParkedTargetDir" "$ActiveDir" || bail "mv \"$ParkedTargetDir\" \"$ActiveDir\" failed."
else
   msg "No prior checkout found for $StreamPath; cloning fresh via remote spec $RemoteSpec (as $P4CloneUser) ..."
   mkdir -p "$ActiveDir" || bail "mkdir -p \"$ActiveDir\" failed."
   (
      cd "$ActiveDir" || exit 1
      export P4CONFIG=.p4config.local
      p4 -u "$P4CloneUser" clone -p "$P4Port" -r "$RemoteSpec" || exit 1
      # The cloned repo ships its own .p4ignore, which collides with the
      # DVCS-generated default of the same name; force a sync to let the
      # real one land.
      p4 sync -f .p4ignore || exit 1
      if [[ "$Target" == bin ]]; then
         # test-install_sdp ships its own tracked .p4ignore.local, a more
         # comprehensive ignore list (p4/p4d binaries, logs, test_sdp.*.cfg,
         # and .current-source itself) curated for exactly this kind of
         # clone -- just point P4IGNORE at it.
         sed -i -E -e "s/^P4IGNORE=.*/P4IGNORE=.p4ignore.local/" .p4config.local || exit 1
      else
         # p4-sdp has no such file, and we shouldn't be adding our own
         # tooling-specific patterns to the SDP's real .p4ignore -- so chain
         # a local-only one onto it instead (P4IGNORE supports a ';'-
         # separated list) just to cover our own .current-source marker.
         printf '%s\n' .current-source .p4ignore.local > .p4ignore.local || exit 1
         sed -i -E -e "s/^P4IGNORE=.*/&;.p4ignore.local/" .p4config.local || exit 1
      fi
      echo "$RemoteSpec" > .current-source
   ) || bail "Fresh clone/setup of $StreamPath failed."
fi

msg "$Target is now sourced from $StreamPath."
# Change User Description Committed
#3 33164 Claude (AI Agent by Anthropic) Correct the previous ignore-handling fix (change 33162/33163): test-install_sdp already ships a tracked, comprehensive .p4ignore.local (p4/p4d, logs, test_sdp.*.cfg, etc.) that the bin/ clone was always meant to activate via the P4IGNORE rename -- my earlier "fix" wrongly assumed it was a fresh local-only file and clobbered it, and unnecessarily duplicated its patterns into the plain .p4ignore (reverted here).
The only real gap was that .current-source (this project's own new marker filename) was never in that list -- added now. swap_source.sh updated to match: bin/ goes back to the simple P4IGNORE=.p4ignore.local rename (the tracked file now covers .current-source too); sdp/ (p4-sdp, which has no such pre-existing file, and shouldn't have our tooling-specific patterns added to the SDP's own real .p4ignore) keeps the new local-only chained-.p4ignore.local approach from change 33162.

Agent: Claude Code, Model: Claude Sonnet 5 (claude-sonnet-5), operating as bot_Claude_Anthropic.
#2 33162 Claude (AI Agent by Anthropic) Fix swap_source.sh: p4 status was flagging the .current-source marker file (and, for sdp, the new .p4ignore.local itself) as untracked, which broke test_preflight.sh/uat -- caught during the first real bootstrap run on the r9x86_64 canary.
Fix: chain a local-only .p4ignore.local onto P4IGNORE via P4's semicolon-list syntax (excluding both .current-source and itself) rather than bin's previous approach of replacing P4IGNORE outright, which had been silently discarding the repo's own real .p4ignore patterns. Unifies bin/sdp handling (both now sync -f .p4ignore + chain .p4ignore.local).

Agent: Claude Code, Model: Claude Sonnet 5 (claude-sonnet-5), operating as bot_Claude_Anthropic.
#1 33158 Claude (AI Agent by Anthropic) Task 1.2: SDP Installer Test Suite source-swapping capability.
Adds swap_source.sh (park/restore or fresh-clone via p4-sdp_*/test-install_sdp_* remote specs) and bootstrap_test_machine.sh (self-contained, curl-bootstrappable machine-join script, SDP Bash Coding Standard style with documented deviations, ShellCheck-clean). Fixes dev_env.sh's hardcoded P4USER/P4PORT, and init_root_dirs_for_local_installs.sh's stale r25.1 P4D default and a real bin.aarch64 URL bug (404; should be bin.linux26aarch64). Restructures InstallSDP-TestServerSetup.md around the new bootstrap script and adds a "Qualifying a New Platform" section.

Agent: Claude Code, Model: Claude Sonnet 5 (claude-sonnet-5), operating as bot_Claude_Anthropic.