-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsourcerer.sh
More file actions
executable file
·164 lines (138 loc) · 4.53 KB
/
Copy pathsourcerer.sh
File metadata and controls
executable file
·164 lines (138 loc) · 4.53 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
#!/usr/bin/env bash
set -euo pipefail
NC="\033[0m" # No Color
RED="\033[38;5;203m" # #f38ba8
sourcerer_error() {
echo -e "${RED}[ERROR]${NC} $*"
}
# ORANGE="\033[38;5;215m" # #fab387
# warn() {
# echo -e "${ORANGE}[WARN]${NC} $*"
# }
# GREEN="\033[38;5;114m" # #a6e3a1
# success() {
# echo -e "${GREEN}[SUCCESS]${NC} $*"
# }
BLUE="\033[38;5;109m" # #89b4fa
sourcerer_info() {
echo -e "${BLUE}[INFO]${NC} $*"
}
SOURCE=${SOURCERER_DEST:-"$HOME/.local/share/sourcerer"}
mkdir -p "$SOURCE"
function check_source_state() {
export SOURCE_NAME=${1:?1st arg SOURCE_NAME is required}
export SOURCE_GITREV=${2:?2nd arg SOURCE_GITREV is required}
export SOURCE_DEST="$SOURCE/$SOURCE_NAME"
if [[ -d "$SOURCE_DEST" ]]; then
# quick and dirty, fetch everything, so we dont have to bother with origin/checks
# do not use --jobs=10. which will cause gh rate limits to block (not logged in) requests in rare occasions.
git -C "$SOURCE_DEST" fetch --all --tags --prune
if [[ "$SOURCE_GITREV" == "latest-tag" ]]; then
# my solution gets the latest tag, using git tag aware versioning.
# to to use the latest git tag, based on commit dates, you can use this instead:
# git describe --tags $(git rev-list --tags --max-count=1)
SOURCE_GITREV=$(git -C "$SOURCE_DEST" tag --sort=v:refname | tail -n 1)
sourcerer_info "latest tag is: $SOURCE_GITREV"
fi
requested_commit=$(git -C "$SOURCE_DEST" rev-parse "$SOURCE_GITREV^{commit}")
HEAD=$(git -C "$SOURCE_DEST" rev-parse "HEAD^{commit}")
if [[ "$requested_commit" == "$HEAD" ]]; then
export SOURCE_STATE="gitrev equals"
else
export SOURCE_STATE="gitrev differs"
fi
else
export SOURCE_STATE="source n/a"
fi
}
function clean_source() {
# NOTE: has to be called after check_source_state
# in order for SOURCE_DEST to be set
(
cd "$SOURCE_DEST"
# moving staged modifcations to unstaged
git reset .
git submodule foreach --recursive git reset .
# removing unstaged modification
git checkout .
git submodule foreach --recursive git checkout .
# removing build and other cache files
# -d recurse into directories
# -x remove all untracked files (ignoring gitignore rules)
git clean -fdx
git submodule foreach --recursive git clean -fdx
)
}
function init_source() {
giturl=$1
if [[ "${SOURCE_STATE:-"unset"}" == "unset" ]]; then
sourcerer_error "incorrect use of init_source. call check_source_state before initilasing."
exit 1
fi
if [[ "$SOURCE_STATE" != "source n/a" ]]; then
sourcerer_error "source already exists. cannot initialize."
exit 1
fi
sourcerer_info "[$SOURCE_NAME] initialising..."
git clone "$giturl" "$SOURCE_DEST"
(
cd "$SOURCE_DEST"
git checkout --detach "$SOURCE_GITREV"
git submodule update --init --recursive
)
}
function update_source() {
if [[ "${SOURCE_STATE:-"unset"}" == "unset" ]]; then
sourcerer_error "incorrect use of update_source. call check_source_state before updating."
exit 1
fi
if [[ "$SOURCE_STATE" == "source n/a" ]]; then
sourcerer_error "source does not exist. cannot update."
exit 1
elif [[ "$SOURCE_STATE" == "gitrev equals" ]]; then
sourcerer_error "source is already at requested gitrev. no reason to update."
exit 1
fi
(
cd "$SOURCE_DEST"
git checkout --detach "$SOURCE_GITREV"
git submodule update --init --recursive
)
}
# calling code has to declare two functions, called
# <sourcename>_installed
# <sourcename>_build_and_install
# pass in the url as arg
function source_git() {
SOURCE_STATE=${SOURCE_STATE:?call check_source_state before run}
giturl=${1:?git url is required}
is_installed="${SOURCE_NAME}_installed"
build_and_install="${SOURCE_NAME}_build_and_install"
if ! declare -F "$build_and_install" >/dev/null; then
echo "Error: Function '$build_and_install' does not exist." >&2
exit 1
fi
if ! declare -F "$is_installed" >/dev/null; then
echo "Error: Function '$is_installed' does not exist." >&2
exit 1
fi
if [[ "$SOURCE_STATE" == "source n/a" ]]; then
init_source "$giturl"
sourcerer_info "[$SOURCE_NAME] installing..."
(cd "$SOURCE_DEST" && "$build_and_install")
elif [[ "$SOURCE_STATE" == "gitrev equals" ]]; then
if $is_installed; then
sourcerer_info "$SOURCE_NAME already installed. Skipping."
else
# edge case. means its already cloned, but build probably failed
clean_source
sourcerer_info "[$SOURCE_NAME] installing..."
(cd "$SOURCE_DEST" && "$build_and_install")
fi
elif [[ "$SOURCE_STATE" == "gitrev differs" ]]; then
clean_source
update_source "$giturl"
sourcerer_info "[$SOURCE_NAME] updating..."
(cd "$SOURCE_DEST" && "$build_and_install")
fi
}