1
+ #! /usr/bin/env bash
2
+
3
+ # Check if the platform is Windows
4
+ if [[ " $OSTYPE " == " msys" || " $OSTYPE " == " cygwin" ]]; then
5
+ echo " Note: Dipin does not support Powershell or Cmd on Windows."
6
+ echo " Please use Git BASH (https://gitforwindows.org/) or WSL (https://learn.microsoft.com/en-us/windows/wsl/install)."
7
+ fi
8
+
9
+ set -e
10
+
11
+ BASE_DIR=${XDG_CONFIG_HOME:- $HOME }
12
+ DIP_DIR=${DIP_DIR-" $BASE_DIR /.dip" }
13
+ DIP_BIN_DIR=" $DIP_DIR /bin"
14
+
15
+ BINS=(dip)
16
+
17
+ export RUSTFLAGS=" -C target-cpu=native"
18
+
19
+ main () {
20
+ need_cmd git
21
+ need_cmd curl
22
+
23
+ while [[ $1 ]]; do
24
+ case $1 in
25
+ --) shift ; break ;;
26
+
27
+ -r|--repo) shift ; DIPIN_REPO=$1 ;;
28
+ -b|--branch) shift ; DIPIN_BRANCH=$1 ;;
29
+ -t|--tag) shift ; DIPIN_USER_TAG=$1 ;;
30
+ -v|--version) shift ; DIPIN_VERSION=$1 ;;
31
+ -p|--path) shift ; DIPIN_LOCAL_REPO=$1 ;;
32
+ -P|--pr) shift ; DIPIN_PR=$1 ;;
33
+ -c|--commit) shift ; DIPIN_COMMIT=$1 ;;
34
+ -h|--help)
35
+ usage
36
+ exit 0
37
+ ;;
38
+ * )
39
+ warn " unknown option: $1 "
40
+ usage
41
+ exit 1
42
+ esac ; shift
43
+ done
44
+
45
+ if [ -n " $DIPIN_BRANCH " ] || [ -n " $DIPIN_USER_TAG " ] || [ -n " $DIPIN_PR " ] || [ -n " $DIPIN_COMMIT " ] || [ -n " $DIPIN_LOCAL_REPO " ] || [ -n " $DIPIN_REPO " ]; then
46
+ if ! command -v rustc & > /dev/null; then
47
+ err " Rust is required for building from source. Please install Rust from https://www.rust-lang.org/tools/install."
48
+ fi
49
+ fi
50
+
51
+ REMOTE_OPTION=$( check_exclusive_options DIPIN_BRANCH DIPIN_USER_TAG DIPIN_PR)
52
+
53
+ if [ -n " $REMOTE_OPTION " ]; then
54
+ if [ " $REMOTE_OPTION " = " DIPIN_PR" ]; then
55
+ say " Using $REMOTE_OPTION : $DIPIN_PR "
56
+ DIPIN_BRANCH=" refs/pull/$DIPIN_PR /head"
57
+ else
58
+ say " Using $REMOTE_OPTION : ${! REMOTE_OPTION} "
59
+ fi
60
+ fi
61
+
62
+ # Installs dip from a local repository if --path parameter is provided
63
+ if [[ -n " $DIPIN_LOCAL_REPO " ]]; then
64
+ need_cmd cargo
65
+
66
+ # Ignore branches/versions as we do not want to modify local git state
67
+ if [ -n " $DIPIN_REPO " ] || [ -n " $DIPIN_BRANCH " ] || [ -n " $DIPIN_VERSION " ]; then
68
+ warn " --branch, --version, and --repo arguments are ignored during local install"
69
+ fi
70
+
71
+ # Enter local repo and build
72
+ say " installing from $DIPIN_LOCAL_REPO "
73
+ cd " $DIPIN_LOCAL_REPO "
74
+ ensure cargo build --release # need 4 speed
75
+
76
+ for bin in " ${BINS[@]} " ; do
77
+ # Remove prior installations if they exist
78
+ rm -f " $DIP_BIN_DIR /$bin "
79
+ # Symlink from local repo binaries to bin dir
80
+ ensure ln -s " $PWD /target/release/$bin " " $DIP_BIN_DIR /$bin "
81
+ done
82
+
83
+ say " done"
84
+ welcome_msg
85
+ exit 0
86
+ fi
87
+
88
+ DIPIN_REPO=${DIPIN_REPO-diptools/ dip}
89
+
90
+ # Store user specified version seperately.
91
+ DIPIN_USER_VERSION=${DIPIN_VERSION}
92
+
93
+ # Install by downloading binaries
94
+ if [[ " $DIPIN_REPO " == " diptools/dip" && -z " $DIPIN_BRANCH " && -z " $DIPIN_COMMIT " ]]; then
95
+ DIPIN_VERSION=${DIPIN_VERSION-stable}
96
+
97
+ if [ -n " $DIPIN_USER_TAG " ]; then
98
+ DIPIN_TAG=$DIPIN_USER_TAG
99
+ DIPIN_VERSION=$DIPIN_USER_TAG
100
+ else
101
+ DIPIN_TAG=$DIPIN_VERSION
102
+ fi
103
+
104
+ # Normalize versions (handle channels, versions without v prefix
105
+ if [[ " $DIPIN_VERSION " == " stable" ]]; then
106
+ # Fetch the list of releases from the GitHub API and filter out `prerelease`` releases and `alpha`` releases
107
+ DIPIN_TAG=$( curl -s " https://api.github.com/repos/${DIPIN_REPO} /releases" \
108
+ | grep -oE ' "tag_name": "[^"]*"|"prerelease": (true|false)' \
109
+ | grep -B1 ' "prerelease": false' \
110
+ | grep ' "tag_name":' \
111
+ | grep -oE ' "v[0-9]*\.[0-9]*\.[0-9]*"' \
112
+ | tr -d ' "' \
113
+ | head -n 1)
114
+ DIPIN_VERSION=$DIPIN_TAG
115
+ elif [[ " $DIPIN_VERSION " == [[:digit:]]* ]]; then
116
+ # Add v prefix
117
+ DIPIN_VERSION=" v${DIPIN_VERSION} "
118
+ DIPIN_TAG=" ${DIPIN_VERSION} "
119
+ fi
120
+
121
+ say " installing dip (version ${DIPIN_VERSION} , tag ${DIPIN_TAG} )"
122
+
123
+ PLATFORM=" $( uname -s) "
124
+ EXT=" tar.gz"
125
+ case $PLATFORM in
126
+ Linux)
127
+ PLATFORM=" linux"
128
+ ;;
129
+ Darwin)
130
+ PLATFORM=" darwin"
131
+ ;;
132
+ MINGW* )
133
+ EXT=" zip"
134
+ PLATFORM=" win32"
135
+ ;;
136
+ * )
137
+ err " unsupported platform: $PLATFORM "
138
+ ;;
139
+ esac
140
+
141
+ ARCHITECTURE=" $( uname -m) "
142
+ if [ " ${ARCHITECTURE} " = " x86_64" ]; then
143
+ # Redirect stderr to /dev/null to avoid printing errors if non Rosetta.
144
+ if [ " $( sysctl -n sysctl.proc_translated 2> /dev/null) " = " 1" ]; then
145
+ ARCHITECTURE=" arm64" # Rosetta.
146
+ else
147
+ ARCHITECTURE=" amd64" # Intel.
148
+ fi
149
+ elif [ " ${ARCHITECTURE} " = " arm64" ] || [ " ${ARCHITECTURE} " = " aarch64" ] ; then
150
+ ARCHITECTURE=" arm64" # Arm.
151
+ else
152
+ ARCHITECTURE=" amd64" # Amd.
153
+ fi
154
+
155
+ # Compute the URL of the release tarball in the Dip repository.
156
+ RELEASE_URL=" https://github.com/${DIPIN_REPO} /releases/download/${DIPIN_TAG} /"
157
+ BIN_ARCHIVE_URL=" ${RELEASE_URL} dip${DIPIN_VERSION} _${PLATFORM} _${ARCHITECTURE} .$EXT "
158
+
159
+ # Check if the version mentioned by user exists in the Dip repository.
160
+ if ! curl --output /dev/null --silent --head --fail " $BIN_ARCHIVE_URL " ; then
161
+ say " Version ${DIPIN_VERSION} does not match any release listed at https://github.com/diptools/dip/releases."
162
+ say " Please specify a valid version, or omit -v to install the latest stable version automatically."
163
+ err " Aborting installation."
164
+ fi
165
+
166
+ echo " $BIN_ARCHIVE_URL "
167
+
168
+ # Display message only if version is not mentioned by user.
169
+ if [ -z " $DIPIN_USER_VERSION " ] && [ -z " $DIPIN_USER_TAG " ]; then
170
+ say " downloading latest dip"
171
+ fi
172
+
173
+ # Download and extract the binaries archive
174
+ if [ " $PLATFORM " = " win32" ]; then
175
+ tmp=" $( mktemp -d 2> /dev/null || echo " ." ) /dip.zip"
176
+ ensure download " $BIN_ARCHIVE_URL " " $tmp "
177
+ ensure unzip " $tmp " -d " $DIP_BIN_DIR "
178
+ rm -f " $tmp "
179
+ else
180
+ ensure download " $BIN_ARCHIVE_URL " | ensure tar -xzC " $DIP_BIN_DIR "
181
+ fi
182
+
183
+ for bin in " ${BINS[@]} " ; do
184
+ bin_path=" $DIP_BIN_DIR /$bin "
185
+
186
+ # Print installed msg
187
+ say " installed - $( ensure " $bin_path " --version) "
188
+
189
+ # Check if the default path of the binary is not in DIP_BIN_DIR
190
+ which_path=" $( which " $bin " ) "
191
+ if [ " $which_path " != " $bin_path " ]; then
192
+ warn " "
193
+ cat 1>&2 << EOF
194
+ There are multiple binaries with the name '$bin ' present in your 'PATH'.
195
+ This may be the result of installing '$bin ' using another method,
196
+ like Cargo or other package managers.
197
+ You may need to run 'rm $which_path ' or move '$DIP_BIN_DIR '
198
+ in your 'PATH' to allow the newly installed version to take precedence!
199
+
200
+ EOF
201
+ fi
202
+ done
203
+
204
+ # Extracting the scarb version from the output of 'sozo --version'
205
+ scarb_version=$( echo " $( sozo --version) " | grep -o ' scarb: [0-9.]*' | cut -d ' ' -f 2)
206
+
207
+ # Check if scarb is already installed
208
+ if [ " $( scarb --version 2> /dev/null) " != " scarb $scarb_version " ]; then
209
+ # Check if scarb is managed by asdf
210
+ if command -v asdf & > /dev/null; then
211
+ if asdf list | grep -q " scarb" ; then
212
+ # Check if default version is set
213
+ if ! asdf current scarb & > /dev/null; then
214
+ asdf global scarb $scarb_version
215
+ fi
216
+ else
217
+ # Install scarb using asdf
218
+ asdf plugin add scarb
219
+ asdf install scarb $scarb_version
220
+ fi
221
+ else
222
+ # Install scarb using the install script
223
+ curl --proto ' =https' --tlsv1.2 -sSf https://docs.swmansion.com/scarb/install.sh | sh -s -- -v $scarb_version
224
+ fi
225
+ fi
226
+
227
+ say " done!"
228
+ welcome_msg
229
+
230
+ # Install by cloning the repo with the provided branch/tag
231
+ else
232
+ need_cmd cargo
233
+ DIPIN_BRANCH=${DIPIN_BRANCH-main}
234
+ REPO_PATH=" $DIP_DIR /$DIPIN_REPO "
235
+
236
+ # If repo path does not exist, grab the author from the repo, make a directory in .dip, cd to it and clone.
237
+ if [ ! -d " $REPO_PATH " ]; then
238
+ AUTHOR=" $( echo " $DIPIN_REPO " | cut -d' /' -f1 -) "
239
+ ensure mkdir -p " $DIP_DIR /$AUTHOR "
240
+ cd " $DIP_DIR /$AUTHOR "
241
+ ensure git clone " https://github.com/$DIPIN_REPO "
242
+ fi
243
+
244
+ # Force checkout, discarding any local changes
245
+ cd " $REPO_PATH "
246
+ ensure git fetch origin " ${DIPIN_BRANCH} :remotes/origin/${DIPIN_BRANCH} "
247
+ ensure git checkout " origin/${DIPIN_BRANCH} "
248
+
249
+ # If set, checkout specific commit from branch
250
+ if [ -n " $DIPIN_COMMIT " ]; then
251
+ say " installing at commit $DIPIN_COMMIT "
252
+ ensure git checkout " $DIPIN_COMMIT "
253
+ fi
254
+
255
+ for bin in " ${BINS[@]} " ; do
256
+ # Build the repo and install the binaries locally to the .dip bin directory.
257
+ # --root appends /bin to the directory it is given, so we pass DIP_DIR.
258
+ ensure cargo install --path ./bin/$bin $bin --locked --force --root " $DIP_DIR "
259
+ done
260
+
261
+ say " done"
262
+ welcome_msg
263
+ fi
264
+ }
265
+
266
+ usage () {
267
+ cat 1>&2 << 'EOF '
268
+ The installer for Dip.
269
+
270
+ Update or revert to a specific Dip version with ease.
271
+
272
+ USAGE:
273
+ dipin <OPTIONS>
274
+
275
+ OPTIONS:
276
+ -h, --help Print help information
277
+ -v, --version Install a specific version (e.g., `dipin --version nightly`)
278
+ -b, --branch Install a specific branch (e.g., `dipin --branch release/0.1.0`)
279
+ -P, --pr Install a specific Pull Request (e.g., `dipin --pr 1071`)
280
+ -c, --commit Install a specific commit (e.g., `dipin -c 94bfdb2`)
281
+ -r, --repo Install from a remote GitHub repo (uses default branch if no other options are set) (e.g., `dipin --repo JunichiSugiura/dip`)
282
+ -p, --path Install a local repository (e.g., `dipin --path ./git/dip`)
283
+ EOF
284
+ }
285
+
286
+ say () {
287
+ printf " dipin: %s\n" " $1 "
288
+ }
289
+
290
+ warn () {
291
+ say " warning: ${1} " >&2
292
+ }
293
+
294
+ err () {
295
+ say " $1 " >&2
296
+ exit 1
297
+ }
298
+
299
+ need_cmd () {
300
+ if ! check_cmd " $1 " ; then
301
+ err " need '$1 ' (command not found)"
302
+ fi
303
+ }
304
+
305
+ check_cmd () {
306
+ command -v " $1 " & > /dev/null
307
+ }
308
+
309
+ # Run a command that should never fail. If the command fails execution
310
+ # will immediately terminate with an error showing the failing
311
+ # command.
312
+ ensure () {
313
+ if ! " $@ " ; then err " command failed: $* " ; fi
314
+ }
315
+
316
+ # Downloads $1 into $2 or stdout
317
+ download () {
318
+ if [ " $2 " ]; then
319
+ # output into $2
320
+ if check_cmd curl; then
321
+ curl -#o " $2 " -L " $1 "
322
+ else
323
+ wget --show-progress -qO " $2 " " $1 "
324
+ fi
325
+ else
326
+ # output to stdout
327
+ if check_cmd curl; then
328
+ curl -#L " $1 "
329
+ else
330
+ wget --show-progress -qO- " $1 "
331
+ fi
332
+ fi
333
+ }
334
+
335
+ # Function to check mutual exclusivity of options.
336
+ check_exclusive_options () {
337
+ local options=(" $@ " )
338
+ local count=0
339
+ local set_option=" "
340
+
341
+ for option in " ${options[@]} " ; do
342
+ if [ -n " ${! option} " ]; then
343
+ (( count++ ))
344
+ set_option=" $option "
345
+ fi
346
+ done
347
+
348
+ if [ " $count " -gt 1 ]; then
349
+ err " only one of ${options[*]} can be specified"
350
+ elif [ " $count " -eq 1 ]; then
351
+ echo " $set_option "
352
+ fi
353
+ }
354
+
355
+ # Welcome message printed after having installed Dip.
356
+ welcome_msg () {
357
+ dip=' \033[1;34m'
358
+ title=' \033[0;32m'
359
+ emphasis=' \033[0;34m'
360
+ command=' \033[0;31m'
361
+ clear=' \033[0m'
362
+
363
+ printf "
364
+ ═════════════════════════════════════════════════════════════════════════
365
+
366
+
367
+ ██████╗ ██╗██████╗ ████████╗ ██████╗ ██████╗ ██╗ ███████╗
368
+ ██╔══██╗██║██╔══██╗ ╚══██╔══╝██╔═══██╗██╔═══██╗██║ ██╔════╝
369
+ ██║ ██║██║██████╔╝ ██║ ██║ ██║██║ ██║██║ ███████╗
370
+ ██║ ██║██║██╔═══╝ ██║ ██║ ██║██║ ██║██║ ╚════██║
371
+ ██████╔╝██║██║ ██║ ╚██████╔╝╚██████╔╝███████╗███████║
372
+ ╚═════╝ ╚═╝╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚══════╝╚══════╝
373
+
374
+
375
+
376
+ Repo : https://github.com/diptools/dip
377
+ Book : https://dip.tools/
378
+ Chat : https://discord.gg/4R8AtxAxk3
379
+
380
+ Congratulations on successfully installing ${dip} Dip${clear} ${DIPIN_VERSION} ! 🥷
381
+
382
+ For more info on how to get started, check out the Dip Getting Started Guide: https://dip.tools/getting-started/quick-start
383
+
384
+ ═════════════════════════════════════════════════════════════════════════
385
+
386
+ "
387
+ }
388
+
389
+ main " $@ " || exit 1
390
+
391
+
0 commit comments