-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathclone-fleet.sh
More file actions
executable file
·150 lines (134 loc) · 4.71 KB
/
Copy pathclone-fleet.sh
File metadata and controls
executable file
·150 lines (134 loc) · 4.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#!/usr/bin/env bash
# Clone (or update) every repo in structure/repos.json into the
# workspace, side by side. This is what turns an empty workspace — or the thin
# superproject — into the full org checkout the other scripts expect.
#
# repos.json is the single source of truth: there are no submodules, so adding a
# repo to the catalog is all it takes for this to clone it. Missing repos are
# cloned; repos already on disk are left untouched unless --update is given,
# which fast-forwards each to its remote. Reuses the same catalog filters as
# parse-repos.sh.
#
# Examples:
# # Populate the workspace (clone whatever is missing):
# scripts/clone-fleet.sh
#
# # Only the simulations, and fast-forward any already present:
# scripts/clone-fleet.sh --simulation --update
#
# # See the plan, change nothing:
# scripts/clone-fleet.sh --dry-run
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=lib/repos.sh
source "$SCRIPT_DIR/lib/repos.sh"
ORG="${FLEET_ORG:-${OPENPHYSICS_ORG:-$(repos_org)}}"
SCHEME="ssh"
UPDATE=0
DRY_RUN=0
SKIPS=()
usage() {
cat <<'EOF'
Usage: clone-fleet.sh [filters] [options]
Clone every repository in structure/repos.json into the workspace as a sibling
directory. Re-runnable: repos already present are skipped (use --update to
fast-forward them).
Filters (from structure/repos.json):
--simulation Only repositories with isSimulation=true
--no-simulation Only repositories with isSimulation=false
--type TYPE Filter by type field
--status STATUS Filter by status (active|template|draft|wip|archived)
--lineage LINEAGE Filter by lineage (original|phet|naap)
--only NAME Clone a single repo by name
--skip NAME Exclude a repo (repeatable)
--catalog PATH Override path to repos.json
Options:
--update Fast-forward (git pull --ff-only) repos already on disk
--https Clone over HTTPS instead of SSH (default: SSH)
--ssh Clone over SSH (default)
-n, --dry-run Print the plan and change nothing
-h, --help Show this help
Environment:
FLEET_WORKSPACE Workspace root to clone into (default: Baton/..)
EOF
}
repos_reset_filters
while [[ $# -gt 0 ]]; do
case "$1" in
--simulation) FILTER_SIMULATION=true; shift ;;
--no-simulation) FILTER_SIMULATION=false; shift ;;
--type) FILTER_TYPE="${2:?Missing value for --type}"; shift 2 ;;
--status) FILTER_STATUS="${2:?Missing value for --status}"; shift 2 ;;
--lineage) FILTER_LINEAGE="${2:?Missing value for --lineage}"; shift 2 ;;
--only) FILTER_NAME="${2:?Missing value for --only}"; shift 2 ;;
--skip) SKIPS+=("${2:?Missing value for --skip}"); shift 2 ;;
--catalog) REPOS_JSON="${2:?Missing value for --catalog}"; shift 2 ;;
--update) UPDATE=1; shift ;;
--https) SCHEME="https"; shift ;;
--ssh) SCHEME="ssh"; shift ;;
-n|--dry-run) DRY_RUN=1; shift ;;
-h|--help) usage; exit 0 ;;
*) echo "Unknown argument: $1" >&2; usage >&2; exit 2 ;;
esac
done
for tool in git jq; do
command -v "$tool" >/dev/null 2>&1 || { echo "$tool is required" >&2; exit 1; }
done
clone_url() {
local name="$1"
if [[ "$SCHEME" == "https" ]]; then
printf 'https://github.com/%s/%s.git\n' "$ORG" "$name"
else
printf 'git@github.com:%s/%s.git\n' "$ORG" "$name"
fi
}
is_skipped() {
local name="$1" s
for s in ${SKIPS[@]+"${SKIPS[@]}"}; do
[[ "$s" == "$name" ]] && return 0
done
return 1
}
WORKSPACE="$(repos_workspace_root)"
total=0 cloned=0 updated=0 present=0 failed=0
for repo in $(repos_names); do
if is_skipped "$repo"; then
echo "==== $repo (skipped) ===="
continue
fi
total=$((total + 1))
dest="$WORKSPACE/$repo"
url="$(clone_url "$repo")"
if [[ -d "$dest/.git" ]]; then
if [[ $UPDATE -eq 0 ]]; then
echo "==== $repo (present) ===="
present=$((present + 1))
continue
fi
echo "==== $repo (update) ===="
if [[ $DRY_RUN -eq 1 ]]; then
echo " [dry-run] git -C $dest pull --ff-only"
elif git -C "$dest" pull --ff-only --quiet; then
echo " updated"; updated=$((updated + 1))
else
echo " update failed (diverged from remote?)"; failed=$((failed + 1))
fi
continue
fi
echo "==== $repo (clone) ===="
if [[ $DRY_RUN -eq 1 ]]; then
echo " [dry-run] git clone $url $dest"
continue
fi
if git clone --quiet "$url" "$dest"; then
echo " cloned"; cloned=$((cloned + 1))
else
echo " clone failed: $url"; failed=$((failed + 1))
fi
done
echo "----"
echo "Summary: $total repo(s) — $cloned cloned, $updated updated, $present present, $failed failed."
if [[ $DRY_RUN -eq 1 ]]; then
echo "Dry-run only — re-run without --dry-run to clone/update."
fi
[[ $failed -eq 0 ]]