-
-
Notifications
You must be signed in to change notification settings - Fork 38
/
install.am
467 lines (433 loc) · 17.2 KB
/
install.am
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
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
#!/bin/sh
#############################################################################
# THIS MODULE IS USED TO INSTALL APPS FROM THE DATABASE OR FROM LOCAL SCRIPTS
#############################################################################
BINDIR="${XDG_BIN_HOME:-$HOME/.local/bin}"
#--------------------------------------------------------------------------
# DOWNLOAD
_convert_to_appman_compatible_script() {
_detect_appman_apps
_appman
if [ -d "$APPMAN_APPSPATH" ]; then
sed -i "s# /usr/local/bin# $HOME/.local/bin#g" ./"$arg"
sed -i "s# /usr/local/share/applications# $DATADIR/applications#g" ./"$arg"
sed -i "s# /opt# $APPMAN_APPSPATH#g" ./"$arg"
sed -i "s# https://api.github.com#$HeaderAuthWithGITPAT https://api.github.com#g" ./"$arg"
cat <<-HEREDOC >> ./"$arg"
# POST INSTALLATION PATCH FOR ALL LAUNCHERS
sed -i "s#Exec=\$APP#Exec=$HOME/.local/bin/$APP#g" $DATADIR/applications/*-AM.desktop
sed -i "s#Exec=/usr/bin/#Exec=$HOME/.local/bin/#g" $DATADIR/applications/*-AM.desktop
sed -i "s#Exec=/opt/#Exec=$HOME/$APPSDIR#g" $DATADIR/applications/*-AM.desktop
sed -i "s#Icon=/opt/#Icon=$HOME/$APPSDIR#g" $DATADIR/applications/*-AM.desktop
HEREDOC
printf " Converting %s to an AppMan-compatible script.\r" "$arg" && sleep 0.25 &&
printf " \r"
else
echo ' 💀 ERROR: "--convert" requires a configuration file in ~/.config/appman'
fi
}
_download() {
if curl --output /dev/null --silent --head --fail "$APPSDB/$arg" 1>/dev/null; then
cd "$SCRIPTDIR" || return 1
[ ! -f ./"$arg" ] && wget -q "$APPSDB/$arg" || return 1
echo " ◆ \"$arg\" installation script downloaded! "
elif curl --output /dev/null --silent --head --fail "$AMREPO/testing/$ARCH/$arg" 1>/dev/null; then
cd "$SCRIPTDIR" || return 1
[ ! -f ./"$arg" ] && wget -q "$AMREPO/testing/$ARCH/$arg" || return 1
echo " ⚠️ \"$arg\" downloaded from \"testing\", the unstable branch, BE AWARE!"
else
echo " 💀 ERROR: \"$arg\" is NOT a valid argument"
fi
}
#--------------------------------------------------------------------------
# INSTALL
# If you use the --latest option, add the "latest" flag to scripts that point to a very common "release"
_if_latest() {
if echo "$FLAGS" | grep -q -- '--force-latest'; then
sed -i 's#/releases #/releases/latest #g' ./"$arg"
fi
}
_if_debug() {
if ! echo "$FLAGS" | grep -q -- "--debug" && wget --version | head -1 | grep -q ' 1.'; then
# Patch "wget" (version 1.x) to have a progress bar and fix errors when applying patches
sed -i "s#wget #wget -q --no-verbose --show-progress --progress=bar #g" ./"$arg"
fi
}
_spooky_check() {
if grep -i spooky ./"$arg" >/dev/null 2>&1; then
printf "%b%b" "\n ${RED}WARNING:" " \"$arg\" does not have a transparent build process! \033[0m\n\n"
echo " We can't be sure as to what is inside the application"
echo " We highly recommend that you sandbox this application"
echo ""
read -p " Do you wish to continue? (N/y): " yn
if ! echo "$yn" | grep -i '^y' >/dev/null 2>&1; then
printf "\n INSTALLATION ABORTED! \n"
return 1
fi
fi
}
# Patch to apply to installation scripts
_apply_patches() {
if [ "$AMCLI" = "appman" ]; then
# Patches /usr/local for $HOME equivalent for AppMan
sed -i -e "s#/usr/local/bin#$BINDIR#g" \
-e "s#/usr/local/share#$DATADIR#g" \
-e "s#/opt/#$APPSPATH/#g" ./"$arg"
else
"$SUDOCMD" mkdir -p /usr/local/share/applications /usr/local/bin
fi
sed -i "s# https://api.github.com#$HeaderAuthWithGITPAT https://api.github.com#g" ./"$arg"
sed -i "s#DirIcon\$#DirIcon 2>/dev/null#g" ./"$arg"
sed -i "s#DirIcon ./icons/\"\$APP\" 1#DirIcon ./icons/\"\$APP\" 2#g" ./"$arg"
}
_am_remover_check() {
# Put permission check in remove script and change ownership of directory
if [ "$AMCLI" = am ]; then
$SUDOCMD sed -i "1 a [ \"\$(id -u)\" -ne 0 ] && echo "Permission denied" && exit 1" \
"${LASTDIRPATH}"/remove 2>/dev/null
$SUDOCMD chown -R "$USER" "${LASTDIRPATH}" 2>/dev/null
fi
}
# Post-installation processes
_post_installation_processes() {
LASTDIR=$(ls -td "$APPSPATH"/* | head -1 | sed 's:.*/::')
LASTDIRPATH="${APPSPATH}/${LASTDIR}"
_am_remover_check
# Check for AM-updater script sothat CLI can manage updates
[ -f "${LASTDIRPATH}"/AM-updater ] && mkdir "${LASTDIRPATH}"/.am-installer 2>/dev/null \
&& curl -Ls "$APPSDB"/"$arg" > "${LASTDIRPATH}"/.am-installer/"$arg"
find "${LASTDIRPATH}"/icons/* -xtype l -delete 2>/dev/null # Removes broken links
# If you have a broken or missing icon in your "icons" directory, download one from the catalog
[ -z "$(ls -A "${LASTDIRPATH}"/icons 2>/dev/null)" ] \
&& wget -q "$AMCATALOGUEICONS"/"$arg".png -O "${LASTDIRPATH}"/icons/"$arg" 2>/dev/null
# Patch .desktop to change paths if the app is installed locally
if [ "$AMCLI" = "appman" ]; then
# Likely not needed anymore: "s#Icon=/opt#Icon=$HOME/$APPSDIR#g"
sed -i -e "s#Exec=$arg#Exec=$BINDIR/$arg#g" \
-e "s#Exec=\$APP#Exec=$BINDIR/\$APP#g" \
-e "s#Exec=/usr/bin/#Exec=$BINDIR/#g" \
-e "s#Exec=/opt/#Exec=$BINDIR/#g" "$DATADIR"/applications/*-AM.desktop 2>/dev/null
fi
}
# End of the installation process
_ending_the_installation() {
unset "$LASTDIR" # Is this needed?
LASTDIR=$(ls -td "$APPSPATH"/* | head -1 | sed 's:.*/::')
if [ -f "${LASTDIRPATH}"/remove ]; then
if test -d "${LASTDIRPATH}"/tmp; then
echo " 💀 ERROR DURING INSTALLATION, REMOVED $APPNAME!"
$SUDOCMD "$APPSPATH/$LASTDIR/remove" 1>/dev/null
elif test -f "$APPSPATH/$LASTDIR/version" && [ -z "$(cat "$APPSPATH/$LASTDIR/version")" ]; then
echo " 💀 ERROR DURING INSTALLATION, REMOVED $APPNAME!"
$SUDOCMD "$APPSPATH/$LASTDIR/remove" 1> /dev/null
else
APPSIZE=$(du -sm "${LASTDIRPATH}" | awk '{print $1}' )
LASTDIRNAME=$(echo "\"$LASTDIR\"" | tr '[:lower:]' '[:upper:]')
printf "%b%b%s\n" " ${Green}" "$LASTDIRNAME INSTALLED\033[0m" " ($APPSIZE MB OF DISK SPACE)"
$SUDOCMD rm "$AMCACHEDIR"/"$arg"
_check_version
app_version=$(grep -w " ◆ $LASTDIR |" 0<"$AMCACHEDIR"/version-args | sed 's:.*| ::')
echo " ◆ $LASTDIR $app_version" >> "$AMCACHEDIR"/installed
fi
else
echo " INSTALLATION ABORTED!"
fi
}
# Check if the installation script contain a keyword related to a missing dependence
_dependency_check_utils() {
app_deps="ar gcc glib-compile-schemas make tar unzip"
for name in $app_deps; do
if grep "^$name" ./"$arg" 1>/dev/null && ! command -v "$name" >/dev/null 2>&1; then
[ "$name" = "ar" ] && name="binutils"
echo " 💀 ERROR: cannot install \"$arg\" without \"$name\""
return 1
fi
done
}
# Check if the installation script is a metapackage (example one of the 40+ kdegames scripts)
_metapackage_check() {
for metapackage in $METAPACKAGES; do
if grep -q "$metapackage" ./"$arg" 2> /dev/null; then
if [ -d "$APPSPATH"/"$metapackage"/tmp ]; then
$SUDOCMD "$APPSPATH"/"$metapackage"/remove 2> /dev/null
elif [ -d "$APPSPATH"/"$metapackage" ]; then
METAPACKAGE_NAME=$(echo "$metapackage" | tr '[:lower:]' '[:upper:]')
echo " ◆ $APPNAME IS PART OF \"$METAPACKAGE_NAME\", ALREADY INSTALLED"
return 1
fi
fi
done
}
######################
# INSTALLATION PROCESS
######################
# This function is needed to parse the installation script and then execute it
_install_arg() {
APPNAME=$(echo "\"$arg\"" | tr '[:lower:]' '[:upper:]')
chmod a+x ./"$arg"
_metapackage_check || return 1
_dependency_check_utils || return 1
if grep -q 'ffwa-' ./"$arg"; then
ffbrowser=$(find ${PATH//:/ } -maxdepth 1 -name "firefox*" | sort | head -1)
if [ -z "$ffbrowser" ]; then
echo " 💀 ERROR: you cannot install \"$arg\" without installing \"firefox\""; return 0
else
sed -i 's#firefox --class#'"$(echo "$ffbrowser" | xargs -L 1 basename)"' --class#g' ./"$arg"
fi
elif grep -qi "^wget.*.sh.*chmod.*&&" ./"$arg"; then
appimage_bulder_script=$(grep "^wget " ./"$arg" | tr '"' '\n' | grep -i "^http" | sed "s/\$APP/$arg/g")
if curl --output /dev/null --silent --head --fail "$appimage_bulder_script" 1> /dev/null; then
for name in $app_deps; do
if curl -Ls "$appimage_bulder_script" | grep "^$name" 1>/dev/null; then
if ! command -v "$name" >/dev/null 2>&1; then
[ "$name" = "ar" ] && name="binutils"
echo " 💀 ERROR: cannot install \"$arg\" without \"$name\""
return 0
fi
fi
done
if curl -Ls "$appimage_bulder_script" | grep -ie "appimagetool\|pkg2appimage" 1>/dev/null; then
if ! command -v convert >/dev/null 2>&1; then
echo " 💀 ERROR: cannot create \"$arg\" without \"convert\" (from \"imagemagick\")"
return 0
fi
fi
else
echo " 💀 ERROR: cannot create \"$arg\", the builder does not exists"
return 0
fi
fi
# Check if you are installing an app or a library
echo " ◆ $APPNAME: starting installation script"
if grep -qi "^wget.*.sh.*chmod.*&&" ./"$arg"; then
printf "\n This script will create an AppImage on the fly, please wait...\n"
elif grep -q "/usr/local/lib" ./"$arg"; then
printf "\n ⚠️ This script will install a system library in /usr/local/lib\n\n"
read -p " Do you wish to continue? (N/y): " yn
if ! echo "$yn" | grep -i '^y' >/dev/null 2>&1; then
printf "\n INSTALLATION ABORTED! \n"
return 0
fi
fi
_spooky_check || return 1
_if_debug
_if_latest
_apply_patches
echo ""
# Install script
if grep -q "https://repology.org" ./"$arg"; then
REPOLOGY_API_ALLOWED=$(curl -Ls https://repology.org/)
if [ -z "$REPOLOGY_API_ALLOWED" ]; then
if command -v torsocks 1>/dev/null; then
sed -i "s/version=\$(wget/version=\$(torsocks wget/g" ./"$arg"
else
echo " 💀 Cannot install \"$arg\", you have no access to https://repology.org, needed to check the version of this program." \
| fold -sw 72 | sed 's/^/ /g; s/ ✖/✖/g'
echo ""
echo " Install \"torsocks\" from your system package manager and retry!"
return 0
fi
fi
fi
if grep -q "api.github.com" ./"$arg"; then
GH_API_ALLOWED=$(curl -Ls $HeaderAuthWithGITPAT https://api.github.com/repos/ivan-hc/AM/releases/latest | sed 's/[()",{} ]/\n/g' | grep "^ivan-hc" | head -1)
if [ -z "$GH_API_ALLOWED" ]; then
if command -v torsocks 1>/dev/null; then
$SUDOCMD torsocks ./"$arg"
else
echo " 💀 Cannot install \"$arg\", you have reached GitHub API limit." \
| fold -sw 72 | sed 's/^/ /g; s/ ✖/✖/g'
echo ""
echo " Install \"torsocks\" from your system package manager and retry!"
return 0
fi
else
$SUDOCMD ./"$arg"
fi
else
$SUDOCMD ./"$arg"
fi
echo ""
_post_installation_processes
_ending_the_installation
}
####################
# INSTALLATION CASES
####################
# This function is for local installation scripts
_install_local_script() {
path2arg="$arg"
arg=$(echo "$path2arg" | sed 's:.*/::')
mkdir -p "$AMCACHEDIR"/tmp && rm -f "$AMCACHEDIR"/tmp/* \
&& cp "$path2arg" "$AMCACHEDIR"/tmp/"$arg" && cd "$AMCACHEDIR" \
&& mv ./tmp/"$arg" ./"$arg" && rmdir ./tmp || return
if ! test -d "$APPSPATH"/"$arg"; then
_install_arg
else
echo " ◆ \"$arg\" is already installed!" | tr '[:lower:]' '[:upper:]'
fi
}
# This is for scripts hosted on the official online database
_install_normally() {
mkdir -p "$AMCACHEDIR"/tmp && rm -f "$AMCACHEDIR"/tmp/* || return
curl -Ls "$APPSDB"/"$arg" > "$AMCACHEDIR"/tmp/"$arg" || return
cd "$AMCACHEDIR" && mkdir -p tmp && cd tmp || return
cd "$AMCACHEDIR" && mv ./tmp/"$arg" ./"$arg" && rmdir ./tmp || return
_install_arg
}
################################################################################
# USAGE
################################################################################
case "$1" in
'-d'|'download')
case $2 in
'--convert')
[ -z "$3" ] && echo " USAGE: $AMCLI $1 $2 [ARGUMENT]" && exit 1
;;
'')
echo " USAGE: $AMCLI $1 [ARGUMENT]"
echo " USAGE: $AMCLI $1 --convert [ARGUMENT]"
exit 1
;;
esac
if [ "$2" = "--convert" ]; then
entries="$(echo "$@" | cut -f3- -d ' ')"
for arg in $entries; do
_download
_convert_to_appman_compatible_script
done
else
entries="$(echo "$@" | cut -f2- -d ' ')"
for arg in $entries; do
_download
done
fi
;;
'-i'|'install')
[ "$AMCLI" = "am" ] && echo "$@" | grep -q -- "--user" && _appman
case $2 in
'')
echo " USAGE: $AMCLI $1 [ARGUMENT]"
echo " USAGE: $AMCLI $1 --debug [ARGUMENT]"
echo " USAGE: $AMCLI $1 --force-latest [ARGUMENT]"
[ "$AMCLI" = "am" ] && echo " USAGE: $AMCLI $1 --user [ARGUMENT]"
exit 1
;;
esac
[ "$AMCLI" = "am" ] && { $SUDOCMD printf "\r" || exit 1; }
echo "============================================================================"
echo ""
printf " %bSTART OF ALL INSTALLATION PROCESSES\033[0m\n" "${LightBlue}"
echo ""
echo "============================================================================"
_clean_amcachedir 2>/dev/null
entries="$(echo "$@" | cut -f2- -d ' ' | tr ' ' '\n' | grep -v -- "--")"
FLAGS=$(echo "$@" | tr ' ' '\n' | grep -- "--" | tr '\n ' ' ')
METAPACKAGES="kdegames kdeutils node platform-tools"
for arg in $entries; do
echo ""
cd "$REALDIR" || return
# If the "tmp" directory is not removed, the installation failed, so remove the app
if [ -d "$APPSPATH"/"$arg"/tmp ]; then
$SUDOCMD "$APPSPATH"/"$arg"/remove 2> /dev/null
fi
# Various cases that may occur during installation
if test -f "$APPSPATH"/"$arg"/remove; then
echo " ◆ \"$arg\" is already installed!" | tr '[:lower:]' '[:upper:]'
else
if echo "$arg" | grep -q "/"; then
if test -f "$arg" 2> /dev/null; then
_install_local_script
else
echo " 💀 ERROR: the file \"$arg\" does NOT exist"
fi
elif curl --output /dev/null --silent --head --fail "$APPSDB"/"$arg" 1>/dev/null; then
_install_normally
else
echo " 💀 ERROR: \"$arg\" does NOT exist in the database, see \"$AMCLI -l\""
fi
fi
echo "____________________________________________________________________________"
done
if [ -f "$AMCACHEDIR"/installed ]; then
echo "============================================================================"
printf "\n %bEND OF ALL INSTALLATION PROCESSES\n\033[0m" "${LightBlue}"
printf "\n The following new programs have been installed:\n\n"
grep -w -v "◆ am" 0<"$AMCACHEDIR"/installed
echo ""
echo "============================================================================"
exit 0
else
exit 1
fi
;;
'-ia'|'install-appimage')
AMCLIPATH_ORIGIN="$AMCLIPATH"
[ "$AMCLI" = "am" ] && echo "$@" | grep -q -- "--user" && _appman
rm -f "$AMCACHEDIR"/install-args
entries="$(echo "$@" | cut -f2- -d ' ' | tr ' ' '\n' | grep -v -- "--")"
FLAGS=$(echo "$@" | tr ' ' '\n' | grep -- "--" | tr '\n ' ' ')
APPIMAGE_NAMES=$(curl -Ls https://portable-linux-apps.github.io/appimages.md | tr '/)' '\n' | grep -i ".md$" | uniq | sed 's/.md$//g' | grep -v "\[")
rm -f "$AMCACHEDIR/$ARCH-appimages"
for appimage in $APPIMAGE_NAMES; do
grep "◆ $appimage :" "$AMDATADIR/$ARCH-apps" >> "$AMCACHEDIR/$ARCH-appimages" &
done
for arg in $entries; do
if grep -q "^◆ $arg : " "$AMCACHEDIR/$ARCH-appimages"; then
echo "$arg" >> "$AMCACHEDIR"/install-args
else
arg="$arg-appimage"
if ! grep -q "^◆ $arg : " "$AMCACHEDIR/$ARCH-appimages"; then
echo " ✖ \"$(echo "$arg" | sed 's/-appimage//g')\" is not an Appimage"
else
echo "$arg" >> "$AMCACHEDIR"/install-args
fi
fi
done
APPIMAGES_ARGS=$(<"$AMCACHEDIR"/install-args sed 's/\n/ /g')
"$AMCLIPATH_ORIGIN" -i $FLAGS "$APPIMAGES_ARGS"
exit 1
;;
'-e'|'extra')
AMCLIPATH_ORIGIN="$AMCLIPATH"
if [ -z "$2" ] || [ -z "$3" ]; then
echo " USAGE: $AMCLI $1 user/project [ARGUMENT]"
echo " USAGE: $AMCLI $1 user/project [ARGUMENT] [KEYWORD]"
echo " USAGE: $AMCLI $1 --user user/project [ARGUMENT]"
echo " USAGE: $AMCLI $1 --user user/project [ARGUMENT] [KEYWORD]"
exit 1
fi
case $2 in
'--user')
USER_PROJECT=$(echo "$3" | sed 's#https://github.com/##g' | cut -f1,2 -d'/')
EXTERNAL_APP_NAME="$4"
APP_KEYWORD="$5"
;;
*)
USER_PROJECT=$(echo "$2" | sed 's#https://github.com/##g' | cut -f1,2 -d'/')
EXTERNAL_APP_NAME="$3"
APP_KEYWORD="$4"
;;
esac
mkdir -p "$CACHEDIR/extra"
curl -Ls "$AMREPO"/templates/AM-SAMPLE-AppImage > "$CACHEDIR/extra/$EXTERNAL_APP_NAME" || exit 1
sed -i "s#APP=SAMPLE#APP=$EXTERNAL_APP_NAME#g" "$CACHEDIR/extra/$EXTERNAL_APP_NAME"
API_GITHUB_REPO="https://api.github.com/repos/$USER_PROJECT/releases"
sed -i "s#REPLACETHIS#$USER_PROJECT#g" "$CACHEDIR/extra/$EXTERNAL_APP_NAME"
q="'"
if [ "$ARCH" = "x86_64" ]; then
FILTER=' | grep -vi "i386\\|i686\\|i586\\|i486\\|aarch64\\|arm64\\|armv7l"'
elif [ "$ARCH" = "i686" ]; then
FILTER=' | grep -ie "i386\\|i686\\|i586\\|i486" '
elif [ "$ARCH" = "aarch64" ]; then
FILTER=' | grep -ie "aarch64\\|arm64" '
fi
FUNCTION='curl -Ls '"$API_GITHUB_REPO"' | sed '"$q"'s/[()",{} ]/\\n/g'"$q"' | grep -oi "https.*mage$"'"$FILTER"' | head -1'
sed -i "s#FUNCTION)#$FUNCTION)#g" "$CACHEDIR/extra/$EXTERNAL_APP_NAME"
[ -n "$APP_KEYWORD" ] && sed -i "s# head -1# grep -i \"$APP_KEYWORD\" | head -1#g" "$CACHEDIR/extra/$EXTERNAL_APP_NAME"
chmod a+x "$CACHEDIR/extra/$EXTERNAL_APP_NAME"
[ "$AMCLI" = "am" ] && [ "$2" = "--user" ] && "$AMCLIPATH_ORIGIN" -i --user "$CACHEDIR/extra/$EXTERNAL_APP_NAME" \
|| "$AMCLIPATH_ORIGIN" -i "$CACHEDIR/extra/$EXTERNAL_APP_NAME"
exit 1
;;
esac