Skip to content

Commit 5e728ba

Browse files
Add dipin script
1 parent e0fd8e6 commit 5e728ba

File tree

1 file changed

+391
-0
lines changed

1 file changed

+391
-0
lines changed

dipin/dipin

+391
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,391 @@
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

Comments
 (0)