-
Notifications
You must be signed in to change notification settings - Fork 220
Expand file tree
/
Copy pathtest-pkg-pr-new-migrate.sh
More file actions
executable file
·242 lines (208 loc) · 7.38 KB
/
Copy pathtest-pkg-pr-new-migrate.sh
File metadata and controls
executable file
·242 lines (208 loc) · 7.38 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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
#!/usr/bin/env bash
set -euo pipefail
usage() {
cat <<'EOF'
Usage: .github/scripts/test-pkg-pr-new-migrate.sh <PR-or-SHA> <project-path> [migrate-options...]
Examples:
.github/scripts/test-pkg-pr-new-migrate.sh 1891 /path/to/npmx.dev
.github/scripts/test-pkg-pr-new-migrate.sh 4eb2104c /path/to/project --no-interactive
Environment variables:
VP_PKG_PR_NEW_HOME Override the isolated global CLI installation directory.
ALLOW_DIRTY=1 Allow migration in a dirty Git worktree.
EOF
}
if [ "$#" -lt 2 ]; then
usage >&2
exit 2
fi
pr_ref="$1"
project_input="$2"
shift 2
case "$pr_ref" in
'' | *[![:alnum:]._-]*)
echo "error: PR or SHA contains unsupported characters: $pr_ref" >&2
exit 2
;;
esac
if [ ! -d "$project_input" ]; then
echo "error: project directory does not exist: $project_input" >&2
exit 2
fi
project_dir="$(cd "$project_input" && pwd -P)"
if [ ! -f "$project_dir/package.json" ]; then
echo "error: package.json not found in project: $project_dir" >&2
exit 2
fi
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
repo_root="$(cd "$script_dir/../.." && pwd -P)"
installer="$repo_root/packages/cli/install.sh"
if [ ! -f "$installer" ]; then
echo "error: Vite+ installer not found: $installer" >&2
exit 2
fi
is_git_repo=0
if command -v git >/dev/null 2>&1 && git -C "$project_dir" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
is_git_repo=1
if [ "${ALLOW_DIRTY:-0}" != "1" ] && [ -n "$(git -C "$project_dir" status --porcelain)" ]; then
echo "error: project worktree is dirty: $project_dir" >&2
echo "Commit or stash its changes, or rerun with ALLOW_DIRTY=1." >&2
exit 2
fi
fi
original_home="$HOME"
cache_root="${XDG_CACHE_HOME:-$original_home/.cache}"
pr_home="${VP_PKG_PR_NEW_HOME:-$cache_root/vite-plus/pkg-pr-new/$pr_ref}"
installer_home="$(mktemp -d "${TMPDIR:-/tmp}/vite-plus-pr-installer.XXXXXX")"
pkg_pr_new_base="https://pkg.pr.new/voidzero-dev/vite-plus"
requested_vite_plus_spec="$pkg_pr_new_base@$pr_ref"
resolve_pkg_pr_new_commit() {
curl -fsSIL "$requested_vite_plus_spec" | tr -d '\r' | awk -F ': ' '
tolower($1) == "x-commit-key" {
count = split($2, parts, ":")
print parts[count]
exit
}
'
}
available_commit="$(resolve_pkg_pr_new_commit || true)"
case "$available_commit" in
'' | *[!0-9a-fA-F]*)
echo "error: could not resolve an immutable pkg.pr.new commit for $pr_ref" >&2
exit 1
;;
esac
if [ "${#available_commit}" -ne 40 ]; then
echo "error: pkg.pr.new returned an invalid commit for $pr_ref: $available_commit" >&2
exit 1
fi
# PR-number URLs are mutable and pkg.pr.new packages reference their internal
# workspace dependencies by commit SHA. Persisting the PR URL alongside those
# SHA URLs makes package managers install duplicate copies of the same package.
# Resolve once, then use the immutable SHA for the global install and every
# dependency spec written by migration.
resolved_ref="$available_commit"
cached_version_dir="$pr_home/pkg-pr-new-$resolved_ref"
vp_bin="$pr_home/bin/vp"
vite_plus_package_json="$pr_home/current/node_modules/vite-plus/package.json"
global_cli_entry="$pr_home/current/node_modules/vite-plus/dist/bin.js"
commit_marker="$cached_version_dir/.pkg-pr-new-commit"
vite_plus_spec="$pkg_pr_new_base@$resolved_ref"
vite_plus_core_spec="$pkg_pr_new_base/@voidzero-dev/vite-plus-core@$resolved_ref"
read_installed_commit() {
if [ -f "$commit_marker" ]; then
head -n 1 "$commit_marker"
return
fi
if [ -f "$vite_plus_package_json" ]; then
awk -F '"' '
$2 == "@voidzero-dev/vite-plus-core" {
value = $4
sub(/^.*@/, "", value)
print value
exit
}
' "$vite_plus_package_json"
fi
}
installed_commit="$(read_installed_commit || true)"
current_target="$(readlink "$pr_home/current" 2>/dev/null || true)"
reuse_install=0
if [ "$installed_commit" = "$resolved_ref" ] &&
[ "$current_target" = "pkg-pr-new-$resolved_ref" ] &&
[ -x "$vp_bin" ] &&
[ -f "$vite_plus_package_json" ] &&
[ -f "$global_cli_entry" ]; then
reuse_install=1
fi
cleanup() {
rm -rf "$installer_home"
}
trap cleanup EXIT
if [ "$reuse_install" -eq 1 ]; then
printf '%s\n' "$resolved_ref" > "$commit_marker"
echo "Reusing installed Vite+ pkg.pr.new build $resolved_ref (requested $pr_ref) from $pr_home"
else
if [ -n "$installed_commit" ] && [ "$installed_commit" != "$resolved_ref" ]; then
echo "pkg.pr.new build changed: $installed_commit -> $resolved_ref"
elif [ -n "$installed_commit" ]; then
echo "Reinstalling pkg.pr.new build $resolved_ref with an immutable cache key"
fi
# This helper owns a dedicated VP_HOME for each requested PR/ref. Remember
# the previous immutable install so it can be removed only after the new one
# succeeds, while retaining shared runtime and package-manager caches.
previous_target=""
if [ -n "$current_target" ] && [ "$current_target" != "pkg-pr-new-$resolved_ref" ]; then
case "$current_target" in
pkg-pr-new-*) previous_target="$current_target" ;;
esac
fi
echo "Installing Vite+ pkg.pr.new build $resolved_ref (requested $pr_ref) into $pr_home"
HOME="$installer_home" \
VP_HOME="$pr_home" \
VP_PR_VERSION="$resolved_ref" \
VP_NODE_MANAGER=no \
bash "$installer"
if [ -n "$previous_target" ]; then
rm -rf "$pr_home/$previous_target"
fi
printf '%s\n' "$resolved_ref" > "$commit_marker"
fi
if [ ! -x "$vp_bin" ]; then
echo "error: installed vp executable not found: $vp_bin" >&2
exit 1
fi
if [ ! -f "$vite_plus_package_json" ]; then
echo "error: installed vite-plus package not found: $vite_plus_package_json" >&2
exit 1
fi
if [ ! -f "$global_cli_entry" ]; then
echo "error: installed Vite+ CLI entry not found: $global_cli_entry" >&2
exit 1
fi
vitest_version="$(awk -F '"' '$2 == "vitest" { print $4; exit }' "$vite_plus_package_json")"
if [ -z "$vitest_version" ]; then
echo "error: could not determine the bundled Vitest version from $vite_plus_package_json" >&2
exit 1
fi
export VP_HOME="$pr_home"
export PATH="$VP_HOME/bin:$PATH"
export VP_VERSION="$vite_plus_spec"
export VP_OVERRIDE_PACKAGES="$(printf \
'{"vite":"%s","vitest":"%s"}' \
"$vite_plus_core_spec" \
"$vitest_version")"
export VP_FORCE_MIGRATE=1
# pkg.pr.new packages depend on URL-resolved platform binaries. pnpm blocks
# those transitive URL dependencies when blockExoticSubdeps is enabled. The
# migration persists the corresponding workspace setting, while this temporary
# override also lets its pre-rewrite install recover a partially migrated tree.
export PNPM_CONFIG_BLOCK_EXOTIC_SUBDEPS=false
hash -r
echo
echo "Using isolated global CLI:"
echo " requested ref: $pr_ref"
echo " resolved commit: $resolved_ref"
echo " executable: $vp_bin"
echo " installation: $(readlink "$pr_home/current" 2>/dev/null || echo unknown)"
echo " vite-plus spec: $VP_VERSION"
echo " vite spec: $vite_plus_core_spec"
"$vp_bin" --version
echo
echo "Running vp migrate in $project_dir"
set +e
(
# Run the installed JS entry directly so a project-local vite-plus at the
# same semver cannot take precedence. Keep cwd at the project root because
# project config and plugins may resolve dependencies from process.cwd().
cd "$project_dir"
"$vp_bin" node "$global_cli_entry" migrate "$project_dir" "$@"
)
migrate_status=$?
set -e
if [ "$is_git_repo" -eq 1 ]; then
echo
echo "Migration worktree changes:"
git -C "$project_dir" status --short
git -C "$project_dir" diff --stat
fi
exit "$migrate_status"