@etherscan-npm/cli 1.0.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/README.md +70 -7
- package/npm/bin/etherscan.js +3 -0
- package/npm/postinstall.js +58 -58
- package/npm/prepublish-check.js +81 -15
- package/package.json +3 -2
- package/scripts/install.ps1 +362 -262
- package/scripts/install.sh +340 -211
package/scripts/install.sh
CHANGED
|
@@ -1,211 +1,340 @@
|
|
|
1
|
-
#!/bin/sh
|
|
2
|
-
|
|
3
|
-
set -eu
|
|
4
|
-
|
|
5
|
-
repository="etherscan/etherscan-cli"
|
|
6
|
-
version=${ETHERSCAN_VERSION:-}
|
|
7
|
-
install_dir=${ETHERSCAN_INSTALL_DIR:-"$HOME/.local/bin"}
|
|
8
|
-
download_base=${ETHERSCAN_INSTALL_TEST_DOWNLOAD_BASE_URL:-}
|
|
9
|
-
update_path=1
|
|
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
|
-
shift
|
|
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
|
-
if
|
|
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
|
-
if [
|
|
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
|
-
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
|
|
3
|
+
set -eu
|
|
4
|
+
|
|
5
|
+
repository="etherscan/etherscan-cli"
|
|
6
|
+
version=${ETHERSCAN_VERSION:-}
|
|
7
|
+
install_dir=${ETHERSCAN_INSTALL_DIR:-"$HOME/.local/bin"}
|
|
8
|
+
download_base=${ETHERSCAN_INSTALL_TEST_DOWNLOAD_BASE_URL:-}
|
|
9
|
+
update_path=1
|
|
10
|
+
uninstall=0
|
|
11
|
+
marker_name=.etherscan-cli-path-added
|
|
12
|
+
marker_content=etherscan-cli:path-added:v1
|
|
13
|
+
|
|
14
|
+
usage() {
|
|
15
|
+
cat <<'EOF'
|
|
16
|
+
Install Etherscan CLI.
|
|
17
|
+
|
|
18
|
+
Usage: install.sh [options]
|
|
19
|
+
|
|
20
|
+
Options:
|
|
21
|
+
--version VERSION Install a specific version (for example, v1.1.0).
|
|
22
|
+
--install-dir DIRECTORY Install into DIRECTORY (default: ~/.local/bin).
|
|
23
|
+
--no-path-update Do not update the shell profile.
|
|
24
|
+
--uninstall Remove the CLI and saved configuration.
|
|
25
|
+
-h, --help Show this help.
|
|
26
|
+
EOF
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
die() {
|
|
30
|
+
printf 'error: %s\n' "$*" >&2
|
|
31
|
+
exit 1
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
while [ "$#" -gt 0 ]; do
|
|
35
|
+
case "$1" in
|
|
36
|
+
--version)
|
|
37
|
+
[ "$#" -ge 2 ] || die "--version requires a value"
|
|
38
|
+
version=$2
|
|
39
|
+
shift 2
|
|
40
|
+
;;
|
|
41
|
+
--install-dir)
|
|
42
|
+
[ "$#" -ge 2 ] || die "--install-dir requires a value"
|
|
43
|
+
install_dir=$2
|
|
44
|
+
shift 2
|
|
45
|
+
;;
|
|
46
|
+
--no-path-update)
|
|
47
|
+
update_path=0
|
|
48
|
+
shift
|
|
49
|
+
;;
|
|
50
|
+
--uninstall)
|
|
51
|
+
uninstall=1
|
|
52
|
+
shift
|
|
53
|
+
;;
|
|
54
|
+
-h|--help)
|
|
55
|
+
usage
|
|
56
|
+
exit 0
|
|
57
|
+
;;
|
|
58
|
+
*)
|
|
59
|
+
die "unknown option: $1"
|
|
60
|
+
;;
|
|
61
|
+
esac
|
|
62
|
+
done
|
|
63
|
+
|
|
64
|
+
if printf '%s' "$install_dir" | LC_ALL=C grep '[[:cntrl:]]' >/dev/null 2>&1; then
|
|
65
|
+
die "the installation directory cannot contain control characters"
|
|
66
|
+
fi
|
|
67
|
+
|
|
68
|
+
config_dir() {
|
|
69
|
+
if [ -n "${XDG_CONFIG_HOME:-}" ]; then
|
|
70
|
+
printf '%s\n' "$XDG_CONFIG_HOME/etherscan"
|
|
71
|
+
else
|
|
72
|
+
printf '%s\n' "$HOME/.etherscan"
|
|
73
|
+
fi
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
profile_has_block() {
|
|
77
|
+
profile=$1
|
|
78
|
+
target=$2
|
|
79
|
+
[ -f "$profile" ] && [ ! -L "$profile" ] || return 1
|
|
80
|
+
ETHERSCAN_PROFILE_TARGET=$target awk '
|
|
81
|
+
BEGIN { target = ENVIRON["ETHERSCAN_PROFILE_TARGET"] }
|
|
82
|
+
previous == "# Etherscan CLI" && $0 == target { found = 1; exit }
|
|
83
|
+
{ previous = $0 }
|
|
84
|
+
END { exit found ? 0 : 1 }
|
|
85
|
+
' "$profile"
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
remove_profile_block() {
|
|
89
|
+
profile=$1
|
|
90
|
+
target=$2
|
|
91
|
+
profile_has_block "$profile" "$target" || return 0
|
|
92
|
+
tmp=$(mktemp "${profile}.etherscan-uninstall.XXXXXX") || die "could not create a profile temporary file"
|
|
93
|
+
if ! cp -p "$profile" "$tmp"; then
|
|
94
|
+
rm -f "$tmp"
|
|
95
|
+
die "could not preserve permissions for $profile"
|
|
96
|
+
fi
|
|
97
|
+
if ! ETHERSCAN_PROFILE_TARGET=$target awk '
|
|
98
|
+
BEGIN { target = ENVIRON["ETHERSCAN_PROFILE_TARGET"] }
|
|
99
|
+
{
|
|
100
|
+
if (pending) {
|
|
101
|
+
if ($0 == target) { pending = 0; next }
|
|
102
|
+
print "# Etherscan CLI"
|
|
103
|
+
pending = 0
|
|
104
|
+
}
|
|
105
|
+
if ($0 == "# Etherscan CLI") { pending = 1; next }
|
|
106
|
+
print
|
|
107
|
+
}
|
|
108
|
+
END { if (pending) print "# Etherscan CLI" }
|
|
109
|
+
' "$profile" >"$tmp"; then
|
|
110
|
+
rm -f "$tmp"
|
|
111
|
+
die "could not update $profile"
|
|
112
|
+
fi
|
|
113
|
+
mv -f "$tmp" "$profile"
|
|
114
|
+
printf 'Removed the PATH entry from %s\n' "$profile"
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
directory_empty_except_marker() {
|
|
118
|
+
directory=$1
|
|
119
|
+
marker=$2
|
|
120
|
+
[ -d "$directory" ] || return 0
|
|
121
|
+
for entry in "$directory"/.[!.]* "$directory"/..?* "$directory"/*; do
|
|
122
|
+
[ -e "$entry" ] || [ -L "$entry" ] || continue
|
|
123
|
+
[ "$entry" = "$marker" ] && continue
|
|
124
|
+
return 1
|
|
125
|
+
done
|
|
126
|
+
return 0
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if [ "$uninstall" -eq 1 ]; then
|
|
130
|
+
binary="$install_dir/etherscan"
|
|
131
|
+
marker="$install_dir/$marker_name"
|
|
132
|
+
marker_valid=0
|
|
133
|
+
if [ -f "$marker" ] && [ ! -L "$marker" ] && [ "$(cat "$marker")" = "$marker_content" ]; then
|
|
134
|
+
marker_valid=1
|
|
135
|
+
fi
|
|
136
|
+
|
|
137
|
+
escaped_install_dir=$(printf '%s' "$install_dir" | sed 's/[\\"$`]/\\&/g')
|
|
138
|
+
posix_path_line="export PATH=\"$escaped_install_dir:\$PATH\""
|
|
139
|
+
fish_path_line="fish_add_path \"$escaped_install_dir\""
|
|
140
|
+
legacy_provenance=0
|
|
141
|
+
for candidate in "$HOME/.zshrc" "$HOME/.bashrc" "$HOME/.profile"; do
|
|
142
|
+
if profile_has_block "$candidate" "$posix_path_line"; then
|
|
143
|
+
legacy_provenance=1
|
|
144
|
+
fi
|
|
145
|
+
done
|
|
146
|
+
if profile_has_block "$HOME/.config/fish/config.fish" "$fish_path_line"; then
|
|
147
|
+
legacy_provenance=1
|
|
148
|
+
fi
|
|
149
|
+
|
|
150
|
+
removed=0
|
|
151
|
+
if [ -e "$binary" ] || [ -L "$binary" ]; then
|
|
152
|
+
rm -f "$binary"
|
|
153
|
+
printf 'Removed %s\n' "$binary"
|
|
154
|
+
removed=1
|
|
155
|
+
fi
|
|
156
|
+
|
|
157
|
+
if [ "$update_path" -eq 1 ] && { [ "$marker_valid" -eq 1 ] || [ "$legacy_provenance" -eq 1 ]; } && directory_empty_except_marker "$install_dir" "$marker"; then
|
|
158
|
+
for candidate in "$HOME/.zshrc" "$HOME/.bashrc" "$HOME/.profile"; do
|
|
159
|
+
remove_profile_block "$candidate" "$posix_path_line"
|
|
160
|
+
done
|
|
161
|
+
remove_profile_block "$HOME/.config/fish/config.fish" "$fish_path_line"
|
|
162
|
+
if [ "$marker_valid" -eq 1 ]; then
|
|
163
|
+
rm -f "$marker"
|
|
164
|
+
fi
|
|
165
|
+
rmdir "$install_dir" 2>/dev/null || true
|
|
166
|
+
removed=1
|
|
167
|
+
elif [ "$update_path" -eq 1 ] && [ -d "$install_dir" ]; then
|
|
168
|
+
printf 'Left %s on PATH because ownership was not proven or the directory is shared.\n' "$install_dir"
|
|
169
|
+
fi
|
|
170
|
+
|
|
171
|
+
etherscan_config=$(config_dir)
|
|
172
|
+
if [ -e "$etherscan_config" ] || [ -L "$etherscan_config" ]; then
|
|
173
|
+
rm -rf "$etherscan_config"
|
|
174
|
+
printf 'Removed %s\n' "$etherscan_config"
|
|
175
|
+
removed=1
|
|
176
|
+
fi
|
|
177
|
+
if [ "$removed" -eq 1 ]; then
|
|
178
|
+
printf 'Etherscan CLI uninstalled.\n'
|
|
179
|
+
else
|
|
180
|
+
printf 'Nothing to remove.\n'
|
|
181
|
+
fi
|
|
182
|
+
if [ -n "${ETHERSCAN_API_KEY:-}" ]; then
|
|
183
|
+
printf 'note: ETHERSCAN_API_KEY remains set; unset it in your shell.\n' >&2
|
|
184
|
+
fi
|
|
185
|
+
exit 0
|
|
186
|
+
fi
|
|
187
|
+
|
|
188
|
+
fetch_stdout() {
|
|
189
|
+
url=$1
|
|
190
|
+
if command -v curl >/dev/null 2>&1; then
|
|
191
|
+
curl -fsSL -A etherscan-cli-installer "$url"
|
|
192
|
+
elif command -v wget >/dev/null 2>&1; then
|
|
193
|
+
wget -qO- --user-agent=etherscan-cli-installer "$url"
|
|
194
|
+
else
|
|
195
|
+
die "curl or wget is required"
|
|
196
|
+
fi
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
fetch_file() {
|
|
200
|
+
base=$1
|
|
201
|
+
name=$2
|
|
202
|
+
destination=$3
|
|
203
|
+
|
|
204
|
+
if [ -d "$base" ]; then
|
|
205
|
+
cp "$base/$name" "$destination"
|
|
206
|
+
return
|
|
207
|
+
fi
|
|
208
|
+
|
|
209
|
+
case "$base" in
|
|
210
|
+
file://*)
|
|
211
|
+
cp "${base#file://}/$name" "$destination"
|
|
212
|
+
;;
|
|
213
|
+
https://*)
|
|
214
|
+
if command -v curl >/dev/null 2>&1; then
|
|
215
|
+
curl -fsSL -A etherscan-cli-installer "$base/$name" -o "$destination"
|
|
216
|
+
elif command -v wget >/dev/null 2>&1; then
|
|
217
|
+
wget -q --user-agent=etherscan-cli-installer "$base/$name" -O "$destination"
|
|
218
|
+
else
|
|
219
|
+
die "curl or wget is required"
|
|
220
|
+
fi
|
|
221
|
+
;;
|
|
222
|
+
*)
|
|
223
|
+
die "invalid download base URL or directory: $base"
|
|
224
|
+
;;
|
|
225
|
+
esac
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
if [ -z "$version" ] || [ "$version" = latest ]; then
|
|
229
|
+
[ -z "$download_base" ] || die "a version is required with the installer test download source"
|
|
230
|
+
release_json=$(fetch_stdout "https://api.github.com/repos/$repository/releases/latest")
|
|
231
|
+
version=$(printf '%s\n' "$release_json" | sed -n 's/.*"tag_name"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' | sed -n '1p')
|
|
232
|
+
[ -n "$version" ] || die "could not resolve the latest Etherscan CLI version"
|
|
233
|
+
fi
|
|
234
|
+
|
|
235
|
+
case "$version" in
|
|
236
|
+
v*) tag=$version; release_version=${version#v} ;;
|
|
237
|
+
*) tag="v$version"; release_version=$version ;;
|
|
238
|
+
esac
|
|
239
|
+
|
|
240
|
+
printf '%s\n' "$tag" | grep -Eq '^v[0-9]+\.[0-9]+\.[0-9]+([-+][0-9A-Za-z.-]+)?$' || die "invalid release version: $tag"
|
|
241
|
+
|
|
242
|
+
system_name=${ETHERSCAN_INSTALL_TEST_OS:-$(uname -s)}
|
|
243
|
+
case "$system_name" in
|
|
244
|
+
Linux|linux) os=linux ;;
|
|
245
|
+
Darwin|darwin) os=darwin ;;
|
|
246
|
+
*) die "unsupported operating system: $system_name" ;;
|
|
247
|
+
esac
|
|
248
|
+
|
|
249
|
+
machine_arch=${ETHERSCAN_INSTALL_TEST_ARCH:-$(uname -m)}
|
|
250
|
+
case "$machine_arch" in
|
|
251
|
+
x86_64|amd64) arch=amd64 ;;
|
|
252
|
+
arm64|aarch64) arch=arm64 ;;
|
|
253
|
+
*) die "unsupported architecture: $machine_arch. Etherscan CLI supports amd64 and arm64." ;;
|
|
254
|
+
esac
|
|
255
|
+
|
|
256
|
+
archive_name="etherscan_${release_version}_${os}_${arch}.tar.gz"
|
|
257
|
+
if [ -z "$download_base" ]; then
|
|
258
|
+
download_base="https://github.com/$repository/releases/download/$tag"
|
|
259
|
+
fi
|
|
260
|
+
|
|
261
|
+
temp_dir=$(mktemp -d 2>/dev/null || mktemp -d -t etherscan-install)
|
|
262
|
+
trap 'rm -rf "$temp_dir"' EXIT HUP INT TERM
|
|
263
|
+
archive_path="$temp_dir/$archive_name"
|
|
264
|
+
checksum_path="$temp_dir/checksums.txt"
|
|
265
|
+
source_executable="$temp_dir/etherscan"
|
|
266
|
+
|
|
267
|
+
printf 'Downloading Etherscan CLI %s for %s/%s...\n' "$release_version" "$os" "$arch"
|
|
268
|
+
fetch_file "$download_base" "$archive_name" "$archive_path"
|
|
269
|
+
fetch_file "$download_base" checksums.txt "$checksum_path"
|
|
270
|
+
|
|
271
|
+
expected_hash=$(awk -v name="$archive_name" '$2 == name || $2 == ("*" name) { print tolower($1); exit }' "$checksum_path")
|
|
272
|
+
[ -n "$expected_hash" ] || die "no checksum was published for $archive_name"
|
|
273
|
+
printf '%s\n' "$expected_hash" | grep -Eq '^[0-9a-f]{64}$' || die "invalid checksum published for $archive_name"
|
|
274
|
+
|
|
275
|
+
if command -v sha256sum >/dev/null 2>&1; then
|
|
276
|
+
actual_hash=$(sha256sum "$archive_path" | awk '{ print tolower($1) }')
|
|
277
|
+
elif command -v shasum >/dev/null 2>&1; then
|
|
278
|
+
actual_hash=$(shasum -a 256 "$archive_path" | awk '{ print tolower($1) }')
|
|
279
|
+
else
|
|
280
|
+
die "sha256sum or shasum is required to verify the download"
|
|
281
|
+
fi
|
|
282
|
+
|
|
283
|
+
[ "$actual_hash" = "$expected_hash" ] || die "checksum verification failed for $archive_name"
|
|
284
|
+
|
|
285
|
+
entry_count=$(tar -tzf "$archive_path" | awk '$0 == "etherscan" { count++ } END { print count + 0 }')
|
|
286
|
+
[ "$entry_count" -eq 1 ] || die "$archive_name must contain exactly one root-level etherscan"
|
|
287
|
+
tar -xOzf "$archive_path" etherscan >"$source_executable"
|
|
288
|
+
[ -s "$source_executable" ] || die "$archive_name contains an empty etherscan executable"
|
|
289
|
+
|
|
290
|
+
mkdir -p "$install_dir"
|
|
291
|
+
staged_executable="$install_dir/.etherscan.new.$$"
|
|
292
|
+
cp "$source_executable" "$staged_executable"
|
|
293
|
+
chmod 0755 "$staged_executable"
|
|
294
|
+
mv -f "$staged_executable" "$install_dir/etherscan"
|
|
295
|
+
|
|
296
|
+
path_updated=0
|
|
297
|
+
if [ "$update_path" -eq 1 ]; then
|
|
298
|
+
case ":$PATH:" in
|
|
299
|
+
*:"$install_dir":*) ;;
|
|
300
|
+
*)
|
|
301
|
+
shell_name=${SHELL:-sh}
|
|
302
|
+
shell_name=${shell_name##*/}
|
|
303
|
+
escaped_install_dir=$(printf '%s' "$install_dir" | sed 's/[\\"$`]/\\&/g')
|
|
304
|
+
if [ "$shell_name" = fish ]; then
|
|
305
|
+
profile="$HOME/.config/fish/config.fish"
|
|
306
|
+
mkdir -p "$(dirname "$profile")"
|
|
307
|
+
path_line="fish_add_path \"$escaped_install_dir\""
|
|
308
|
+
else
|
|
309
|
+
case "$shell_name" in
|
|
310
|
+
zsh) profile="$HOME/.zshrc" ;;
|
|
311
|
+
bash) profile="$HOME/.bashrc" ;;
|
|
312
|
+
*) profile="$HOME/.profile" ;;
|
|
313
|
+
esac
|
|
314
|
+
path_line="export PATH=\"$escaped_install_dir:\$PATH\""
|
|
315
|
+
fi
|
|
316
|
+
|
|
317
|
+
# Match the exact line we would write (whole-line, fixed-string) so an
|
|
318
|
+
# unrelated profile line that merely contains the path does not suppress
|
|
319
|
+
# the update, and a genuine duplicate is not appended.
|
|
320
|
+
if ! [ -f "$profile" ] || ! grep -Fx -e "$path_line" "$profile" >/dev/null 2>&1; then
|
|
321
|
+
{
|
|
322
|
+
printf '\n# Etherscan CLI\n'
|
|
323
|
+
printf '%s\n' "$path_line"
|
|
324
|
+
} >>"$profile"
|
|
325
|
+
path_updated=1
|
|
326
|
+
printf '%s' "$marker_content" >"$install_dir/$marker_name"
|
|
327
|
+
fi
|
|
328
|
+
;;
|
|
329
|
+
esac
|
|
330
|
+
fi
|
|
331
|
+
|
|
332
|
+
printf '\nEtherscan CLI %s installed successfully.\n' "$release_version"
|
|
333
|
+
printf 'Installed to: %s\n' "$install_dir/etherscan"
|
|
334
|
+
if [ "$update_path" -eq 0 ]; then
|
|
335
|
+
printf 'Add %s to PATH to run etherscan from any directory.\n' "$install_dir"
|
|
336
|
+
elif [ "$path_updated" -eq 1 ]; then
|
|
337
|
+
printf 'Open a new terminal, then run: etherscan version\n'
|
|
338
|
+
else
|
|
339
|
+
printf 'Run: etherscan version\n'
|
|
340
|
+
fi
|