-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathzipdiff
More file actions
199 lines (179 loc) · 6.73 KB
/
Copy pathzipdiff
File metadata and controls
199 lines (179 loc) · 6.73 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
#!/usr/bin/env bash
#
# Launcher for the zipdiff CLI.
#
# Works both from a source checkout (zipdiff-core/build/libs) and as a
# standalone download anywhere on your machine (it will fetch a released
# fat jar).
#
# Usage:
# ./zipdiff [options] [--] [args passed to the zipdiff CLI...]
#
# Options:
# --build Force a rebuild (:zipdiff-core:shadowJar). Source checkout only.
# --no-build Never build or download; fail if no jar is available.
# --update Re-download the release jar (standalone mode).
# --where Print the jar/mode that would be used, then exit.
# -h, --help Show this help.
#
# Environment:
# JAVA_HOME If set, $JAVA_HOME/bin/java is used.
# JAVA_OPTS Extra JVM options (word-split, e.g. "-Xmx2g -Dfoo=bar").
# ZIPDIFF_JAR Path to an existing *-all.jar; skips discovery/build entirely.
# ZIPDIFF_HOME Cache dir for downloads (default: ${XDG_CACHE_HOME:-~/.cache}/zipdiff).
# ZIPDIFF_REPO GitHub repo for releases (default: SimiaCryptus/zipdiff).
# ZIPDIFF_VERSION Release tag to download (default: latest).
set -Eeuo pipefail
MAIN_CLASS="io.cognotik.zipdiff.cli.ZipdiffCli"
# --- Locate ourselves (resolving symlinks) so the script is CWD-independent ----
self="${BASH_SOURCE[0]}"
while [[ -L "$self" ]]; do
target="$(readlink "$self")"
[[ "$target" == /* ]] && self="$target" || self="$(dirname -- "$self")/$target"
done
SCRIPT_DIR="$(cd -- "$(dirname -- "$self")" && pwd -P)"
log() { printf 'zipdiff: %s\n' "$*" >&2; }
die() { log "$*"; exit 1; }
have() { command -v "$1" >/dev/null 2>&1; }
usage() {
awk 'NR>1 { if (/^#/) { sub(/^# ?/, ""); print; next } else exit }' "$self"
}
case "${1:-}" in
-h|--help) usage; exit 0 ;;
esac
# --- Parse our own options; stop at the first unknown arg ----------------------
build_mode=auto
do_update=no
show_where=no
while [[ $# -gt 0 ]]; do
case "$1" in
--build) build_mode=force; shift ;;
--no-build) build_mode=never; shift ;;
--update) do_update=yes; shift ;;
--where) show_where=yes; shift ;;
-h|--help) usage; exit 0 ;;
--) shift; break ;;
*) break ;;
esac
done
# --- Java ----------------------------------------------------------------------
if [[ -n "${JAVA_HOME:-}" && -x "$JAVA_HOME/bin/java" ]]; then
JAVA_BIN="$JAVA_HOME/bin/java"
else
have java || die "no 'java' on PATH and JAVA_HOME is not usable"
JAVA_BIN="$(command -v java)"
fi
# --- Are we inside a zipdiff source checkout? ----------------------------------
find_project_root() {
local dir="$SCRIPT_DIR"
while :; do
if [[ -d "$dir/zipdiff-core" ]] \
&& { [[ -f "$dir/settings.gradle.kts" ]] || [[ -f "$dir/settings.gradle" ]]; }; then
printf '%s\n' "$dir"; return 0
fi
[[ "$dir" == "/" ]] && return 1
dir="$(dirname -- "$dir")"
done
}
CACHE_DIR="${ZIPDIFF_HOME:-${XDG_CACHE_HOME:-$HOME/.cache}/zipdiff}/jars"
REPO="${ZIPDIFF_REPO:-SimiaCryptus/ZipDiff}"
VERSION="${ZIPDIFF_VERSION:-latest}"
PROJECT_ROOT=""
if PROJECT_ROOT="$(find_project_root)"; then
LIBS_DIR="$PROJECT_ROOT/zipdiff-core/build/libs"
else
PROJECT_ROOT="" # standalone: download a release jar instead
LIBS_DIR="$CACHE_DIR"
fi
# --- Build (source checkout only) ----------------------------------------------
build() {
local gradlew="$PROJECT_ROOT/gradlew"
[[ -x "$gradlew" ]] || die "gradle wrapper not found or not executable: $gradlew"
log "building :zipdiff-core:shadowJar ..."
( cd -- "$PROJECT_ROOT" && "$gradlew" :zipdiff-core:shadowJar ) || die "build failed"
}
# --- Download (standalone mode) ------------------------------------------------
fetch_stdout() {
if have curl; then curl -fsSL --retry 3 -- "$1"
elif have wget; then wget -qO- -- "$1"
else die "need 'curl' or 'wget' to download the release jar"; fi
}
fetch_file() {
if have curl; then curl -fsSL --retry 3 -o "$2" -- "$1"
elif have wget; then wget -qO "$2" -- "$1"
else die "need 'curl' or 'wget' to download the release jar"; fi
}
download_jar() {
local api json url tmp
if [[ "$VERSION" == latest ]]; then
api="https://api.github.com/repos/$REPO/releases/latest"
else
api="https://api.github.com/repos/$REPO/releases/tags/$VERSION"
fi
log "resolving $VERSION release of $REPO ..."
json="$(fetch_stdout "$api")" || die "could not query $api"
url="$(printf '%s' "$json" \
| grep -o '"browser_download_url"[[:space:]]*:[[:space:]]*"[^"]*"' \
| sed 's/.*"\(https[^"]*\)"$/\1/' \
| grep -E -- '-all\.jar$' | head -n1)" || true
[[ -n "$url" ]] || die "no *-all.jar asset in the $VERSION release of $REPO; clone the repo and use --build, or set ZIPDIFF_JAR"
mkdir -p -- "$CACHE_DIR"
tmp="$(mktemp "$CACHE_DIR/.download.XXXXXX")"
log "downloading ${url##*/} -> $CACHE_DIR"
fetch_file "$url" "$tmp" || { rm -f -- "$tmp"; die "download failed: $url"; }
mv -f -- "$tmp" "$CACHE_DIR/${url##*/}"
}
# --- Resolve the newest shadow jar in a directory ------------------------------
find_jar() {
local dir="$1"
local -a jars=()
shopt -s nullglob
# Prefer the fat jar; ignore -sources/-javadoc artifacts.
jars=( "$dir"/*-all.jar )
shopt -u nullglob
(( ${#jars[@]} )) || return 1
local newest="${jars[0]}" j
for j in "${jars[@]}"; do
[[ "$j" -nt "$newest" ]] && newest="$j"
done
printf '%s\n' "$newest"
}
# --- Pick a jar ----------------------------------------------------------------
JAR=""
if [[ -n "${ZIPDIFF_JAR:-}" ]]; then
[[ -f "$ZIPDIFF_JAR" ]] || die "ZIPDIFF_JAR does not exist: $ZIPDIFF_JAR"
JAR="$ZIPDIFF_JAR"
mode="explicit (ZIPDIFF_JAR)"
elif [[ -n "$PROJECT_ROOT" ]]; then
mode="source checkout ($PROJECT_ROOT)"
if [[ "$build_mode" == force ]]; then
build
fi
if ! JAR="$(find_jar "$LIBS_DIR")"; then
if [[ "$build_mode" == never ]]; then
die "no *-all.jar in $LIBS_DIR (and --no-build was given)"
fi
build
JAR="$(find_jar "$LIBS_DIR")" || die "build produced no *-all.jar in $LIBS_DIR"
fi
else
mode="standalone (cache: $CACHE_DIR)"
if [[ "$build_mode" == force ]]; then
die "--build requires a zipdiff source checkout; this script is running standalone from $SCRIPT_DIR"
fi
if [[ "$do_update" == yes ]] || ! JAR="$(find_jar "$CACHE_DIR")"; then
if [[ "$build_mode" == never ]]; then
die "no *-all.jar in $CACHE_DIR (and --no-build was given)"
fi
download_jar
JAR="$(find_jar "$CACHE_DIR")" || die "download produced no *-all.jar in $CACHE_DIR"
fi
fi
if [[ "$show_where" == yes ]]; then
printf 'mode: %s\njar: %s\njava: %s\n' "$mode" "$JAR" "$JAVA_BIN"
exit 0
fi
# --- Run -----------------------------------------------------------------------
# shellcheck disable=SC2206 # deliberate word-splitting of JAVA_OPTS
read -r -a java_opts <<< "${JAVA_OPTS:-}"
exec "$JAVA_BIN" "${java_opts[@]}" -cp "$JAR" "$MAIN_CLASS" "$@"