APP-MANAGER 55 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536
  1. #!/usr/bin/env bash
  2. AMVERSION="9.4.2-1"
  3. # Determine main repository and branch
  4. AMREPO="https://raw.githubusercontent.com/ivan-hc/AM/main"
  5. AMBRANCH=$(basename "$AMREPO")
  6. MODULES_SOURCE="$AMREPO/modules"
  7. # Determine the name of this script and its working directory
  8. export REALDIR="$PWD"
  9. DIR="$( cd "$( dirname "$0" )" && pwd )"
  10. CLI=$(basename "$0")
  11. # Determine system architecture and current user
  12. ARCH="$(uname -m)"
  13. [ "$ARCH" = "amd64" ] && ARCH=x86_64
  14. export ARCH
  15. # Fixes issue with less on bsd
  16. if uname | grep -q "BSD\|DragonFly\|DynFi\|FreeNAS\|helloSystem\|OPNsense\|pfSense\|TrueNAS\|XigmaNAS"; then
  17. TERM=xterm-clear
  18. export TERM
  19. fi
  20. # XDG Variables
  21. export BINDIR="${XDG_BIN_HOME:-$HOME/.local/bin}"
  22. export DATADIR="${XDG_DATA_HOME:-$HOME/.local/share}"
  23. export CONFIGDIR="${XDG_CONFIG_HOME:-$HOME/.config}"
  24. export CACHEDIR="${XDG_CACHE_HOME:-$HOME/.cache}"
  25. export APPMANCONFIG="$CONFIGDIR/appman"
  26. APPMANCONFIG="$CONFIGDIR/appman"
  27. SCRIPTDIR="${SCRIPTDIR:-$(xdg-user-dir DESKTOP 2>/dev/null)}"
  28. [ -d "$SCRIPTDIR" ] || SCRIPTDIR="$PWD"
  29. export SCRIPTDIR
  30. # Colors
  31. RED='\033[0;31m'
  32. Gold='\033[0;33m'
  33. Green='\033[0;32m'
  34. LightBlue='\033[1;34m'
  35. DIVIDING_LINE="-----------------------------------------------------------------------------"
  36. # Prevent the use of "sudo" ("AM")
  37. if [ -n "${SUDO_USER:-$DOAS_USER}" ]; then
  38. printf "\n Please do not use \"sudo\" to execute \"%b\", try again.\n\n" "$CLI"
  39. exit 1
  40. fi
  41. if ! sed --version 2>/dev/null | grep -qi "gnu"; then
  42. NO_SED_I=true
  43. fi
  44. _create_cache_dir() {
  45. AMCACHEDIR="$CACHEDIR/$AMCLI"
  46. mkdir -p "$AMCACHEDIR"
  47. }
  48. _clean_amcachedir() {
  49. [ "$AMCLI" = am ] && [ -d "$CACHEDIR"/am ] && rm -f "$CACHEDIR"/am/*
  50. [ -d "$CACHEDIR"/appman ] && rm -f "$CACHEDIR"/appman/*
  51. }
  52. # Fit texts to an acceptable width
  53. _fit() {
  54. fold -sw 77 | sed 's/^/ /g'
  55. }
  56. # Makes "less" optional
  57. less() {
  58. if ! command less "$@" 2>/dev/null; then
  59. while read -r line; do echo "$line"; done
  60. echo "Install 'less' if you want to scroll this list"
  61. fi
  62. }
  63. # Force usage of a GNU implementation of "sed"
  64. sed() {
  65. if [ "$NO_SED_I" = true ] && [ "$1" = '-i' ]; then
  66. if command -v gsed >/dev/null 2>&1; then
  67. command gsed "$@"
  68. else
  69. shift
  70. tmpsedYYY="$(command sed "$@" 2>/dev/null)"
  71. while [ "$#" -gt 1 ]; do shift; done
  72. if [ -n "$tmpsedYYY" ] && [ -f "$1" ]; then
  73. echo "$tmpsedYYY" > "$1"
  74. unset tmpsedYYY
  75. else
  76. >&2 echo " 💀 ERROR: Your version of sed does not support '-i' flag"
  77. >&2 echo " without extension, we tried to workaround and failed"
  78. >&2 echo " Please install gsed"
  79. unset tmpsedYYY
  80. return 1
  81. fi
  82. fi
  83. else
  84. command sed "$@"
  85. fi
  86. }
  87. ################################################################################
  88. # AM/APPMAN
  89. ################################################################################
  90. # "APPMAN" CORE VARIABLES AND FUNCTIONS
  91. APPMAN_SETUP_MSG="Before proceeding with any task, where do you want to install apps?
  92. SYNTAX: /FULLPATH/TO/DIRNAME
  93. EXAMPLE: $HOME/My-apps
  94. NOTE: Any spaces in the path will be replaced for dashes
  95. NOTE: If no input is given then \"~/Applications\" will be used as default
  96. if you wish to later change the location, first remove all the programs and then edit the \"$APPMANCONFIG/appman-config\" file."
  97. _appman_check() {
  98. if [ ! -f "$APPMANCONFIG"/appman-config ]; then
  99. echo "$DIVIDING_LINE"
  100. [ "$AMCLI" = am ] && echo ">>> Configure AppMan" || echo ">>> Thank you for choosing AppMan!"
  101. echo "$DIVIDING_LINE"
  102. echo "$APPMAN_SETUP_MSG" | _fit
  103. echo "$DIVIDING_LINE"
  104. read -r -ep " Write the path or just press enter to use default:$(printf "\n\n ")" location
  105. location="$(echo "$location" | sed 's/[ \t]/-/g; s|^\./||' 2>/dev/null)"
  106. [ -z "$location" ] && location="$HOME/Applications"
  107. if ! echo "$location" | grep "^/" >/dev/null 2>&1; then
  108. location="$HOME/$location"
  109. fi
  110. if echo "$location" | grep "$BINDIR" >/dev/null 2>&1; then
  111. echo "$DIVIDING_LINE"
  112. echo " 💀 ERROR, you can't install applications in \"$BINDIR\""
  113. echo " $BINDIR is normally used for executables, Please choose a different path and retry!"
  114. echo "$DIVIDING_LINE"
  115. exit 1
  116. elif ! mkdir -p "$location" 2>/dev/null || [ ! -w "$location" ]; then
  117. echo " 💀 ERROR: You don't have write access to $location or it is invalid"
  118. exit 1
  119. fi
  120. mkdir -p "$APPMANCONFIG" || exit 1
  121. echo "${location%/}" > "$APPMANCONFIG"/appman-config || exit 1
  122. echo "$DIVIDING_LINE"
  123. echo " You are ready! Start installing your favorite apps locally!"
  124. echo " All apps will be installed in $location"
  125. echo " In case of problems, use the option \"-h\"."
  126. echo "$DIVIDING_LINE"
  127. fi
  128. }
  129. _appman() {
  130. _appman_check
  131. if ! grep -q "^/" "$APPMANCONFIG"/appman-config; then
  132. APPSDIR="$HOME/$(head -1 "$APPMANCONFIG"/appman-config 2>/dev/null)"
  133. else
  134. APPSDIR="$(head -1 "$APPMANCONFIG"/appman-config 2>/dev/null)"
  135. fi
  136. [ -n "$APPSDIR" ] && mkdir -p "$APPSDIR"/appman || exit 1
  137. mkdir -p "$BINDIR" "$DATADIR"/applications "$DATADIR"/icons || exit 1
  138. AMCLI="appman"
  139. AMCLIPATH="$DIR/$AMCLI"
  140. SUDOCMD=""
  141. APPSPATH="$APPSDIR"
  142. AMPATH="$APPSDIR/$AMCLI"
  143. _create_cache_dir
  144. if [ ! -w "$APPSPATH" ]; then
  145. echo "ERROR: You don't have write access to $APPSPATH" | _fit
  146. exit 1
  147. elif ! echo "$PATH" | grep "$BINDIR" >/dev/null 2>&1; then
  148. echo "$DIVIDING_LINE"
  149. printf "%b ⚠️ WARNING\033[0m: \"%b%b\033[0m\" is not in PATH, local apps may not run.\n" "${RED}" "${LightBlue}" "$BINDIR"
  150. fi
  151. MODULES_PATH="$AMPATH/modules"
  152. mkdir -p "$MODULES_PATH" || exit 1
  153. }
  154. # "AM" CORE VARIABLES
  155. _am() {
  156. AMCLI="am"
  157. AMCLIPATH="$AMCLI"
  158. if command -v sudo >/dev/null 2>&1; then
  159. export SUDOCMD="sudo"
  160. elif command -v doas >/dev/null 2>&1; then
  161. export SUDOCMD="doas"
  162. else
  163. echo 'ERROR: No sudo or doas found'
  164. exit 1
  165. fi
  166. APPSPATH="/opt"
  167. AMPATH="$APPSPATH/$AMCLI"
  168. _create_cache_dir
  169. MODULES_PATH="$AMPATH/modules"
  170. }
  171. # DETERMINE WHEN TO USE "AM" OR "APPMAN"
  172. if [ "$(realpath "$0")" = "/opt/am/APP-MANAGER" ]; then
  173. _am
  174. mkdir -p "$MODULES_PATH" || exit 1
  175. elif [ "$(realpath "$0")" = "/usr/bin/am" ]; then
  176. _am
  177. AMPATH="$AMCACHEDIR"
  178. MODULES_PATH="/usr/lib/am/modules"
  179. else
  180. _appman
  181. fi
  182. _detect_appman_apps() {
  183. [ -f "$APPMANCONFIG/appman-config" ] && APPMAN_APPSPATH=$(<"$APPMANCONFIG/appman-config")
  184. if ! echo "$APPMAN_APPSPATH" | grep -q "^/"; then
  185. [ -f "$APPMANCONFIG/appman-config" ] && APPMAN_APPSPATH="$HOME/$(<"$APPMANCONFIG/appman-config")"
  186. fi
  187. }
  188. _determine_args() {
  189. ARGPATHS=$(find "$APPSPATH" -maxdepth 2 -name 'remove' -print 2>/dev/null | sort -u | sed 's|/remove||g')
  190. ARGS=$(echo "$ARGPATHS" | xargs -n 1 basename 2>/dev/null)
  191. if [ "$AMCLI" = am ]; then
  192. _detect_appman_apps
  193. if [ -d "$APPMAN_APPSPATH" ]; then
  194. APPMAN_PATHS=$(find "$APPMAN_APPSPATH" -maxdepth 2 -name 'remove' -print 2>/dev/null | sort -u | sed 's|/remove||g')
  195. ARGPATHS=$(printf "%b\n%b" "$ARGPATHS" "$APPMAN_PATHS")
  196. ARGS=$(echo "$ARGPATHS" | xargs -n 1 basename 2>/dev/null)
  197. fi
  198. fi
  199. # use "argpath=$(echo "$ARGPATHS" | grep "/$arg$")" to determine the full path of "arg"
  200. }
  201. _icon_theme_export_to_datadir() {
  202. PNG="$(file "$APPSPATH"/*/icons/* | grep -i '.png' | awk -F":" '{print $1}' | grep -vi .png)"
  203. SVG="$(file "$APPSPATH"/*/icons/* | grep -i '.svg' | awk -F":" '{print $1}' | grep -vi .svg)"
  204. for file in $PNG; do ln -s "$file" "${file}".png; done
  205. for file in $SVG; do ln -s "$file" "${file}".svg; done
  206. if [ -n "$APPMAN_APPSPATH" ]; then
  207. PNG="$(file "$APPMAN_APPSPATH"/*/icons/* | grep -i '.png' | awk -F":" '{print $1}' | grep -vi .png)"
  208. SVG="$(file "$APPMAN_APPSPATH"/*/icons/* | grep -i '.svg' | awk -F":" '{print $1}' | grep -vi .svg)"
  209. for file in $PNG; do ln -s "$file" "${file}".png; done
  210. for file in $SVG; do ln -s "$file" "${file}".svg; done
  211. fi
  212. mkdir -p "$DATADIR"/icons/hicolor/scalable/apps
  213. find "$DATADIR"/icons/hicolor/scalable/apps -xtype l -exec rm {} \;
  214. ln -s "$APPSPATH"/*/icons/*.* "$DATADIR"/icons/hicolor/scalable/apps
  215. [ -n "$APPMAN_APPSPATH" ] && ln -s "$APPMAN_APPSPATH"/*/icons/*.* "$DATADIR"/icons/hicolor/scalable/apps
  216. }
  217. ################################################################################
  218. # FINALIZE
  219. ################################################################################
  220. AMCLIUPPER=$(echo "$AMCLI" | tr '[:lower:]' '[:upper:]')
  221. # Create new data directory and move important files there
  222. AMDATADIR="$DATADIR/AM"
  223. mkdir -p "$AMDATADIR"
  224. # DEVELOPER MODE
  225. if [ -f "$AMDATADIR"/betatester ]; then
  226. AMREPO="https://raw.githubusercontent.com/ivan-hc/AM/dev"
  227. AMBRANCH=$(basename "$AMREPO")
  228. MODULES_SOURCE="$AMREPO/modules"
  229. fi
  230. _betatester_message_on() {
  231. if [ -f "$AMDATADIR"/betatester ]; then
  232. echo "$DIVIDING_LINE"; echo "\"$AMCLIUPPER\" $AMVERSION: DEVELOPER MODE"; echo "$DIVIDING_LINE"
  233. fi
  234. }
  235. ################################################################################
  236. # APPS DATABASE
  237. ################################################################################
  238. # Apps database in use
  239. APPSDB="${APPSDB:-$AMREPO/programs/$ARCH}"
  240. APPSLISTDB="${APPSLISTDB:-$AMREPO/programs/$ARCH-apps}"
  241. ################################################################################
  242. # SECURITY
  243. ################################################################################
  244. # SAFETY CHECKS
  245. _am_dependences_check() {
  246. # Check for essential commands required by the application
  247. missing_deps=""
  248. AMDEPENDENCES="cat chmod chown curl file grep sed wget"
  249. for name in $AMDEPENDENCES; do
  250. if ! command -v "$name" >/dev/null 2>&1; then
  251. missing_deps="$name $missing_deps"
  252. fi
  253. done
  254. # Exit if any essential command is missing
  255. if [ -n "$missing_deps" ]; then
  256. echo "$DIVIDING_LINE"
  257. printf " ${RED}💀 ERROR! MISSING ESSENTIAL COMMANDS\033[0m: %s\n\n Install the above and try again! \n" "${missing_deps[*]}"
  258. echo "$DIVIDING_LINE"
  259. printf "%bList of the %b core dependences\033[0m:\n\n%b\n" "${Green}" "$AMCLIUPPER $AMVERSION" "$AMDEPENDENCES" | _fit
  260. echo "$DIVIDING_LINE"
  261. printf "If this message appears it is because you are missing some dependency and if its the first time its because something new has been introduced.\n\n" | _fit
  262. printf " See %bhttps://github.com/ivan-hc/AM#core-dependences\033[0m for more information\n" "${LightBlue}"
  263. echo "$DIVIDING_LINE"
  264. exit 1
  265. fi
  266. }
  267. _check_ubuntu_mess() {
  268. if command -v unshare >/dev/null 2>&1 && ! unshare --user -p /bin/true >/dev/null 2>&1; then
  269. echo "$DIVIDING_LINE"
  270. printf "\n %b⚠️ WARNING: ACCESS TO USER NAMESPACES IS RESTRICTED! \033[0m\n\n" "${RED}"
  271. echo " Some apps may not run, you need to enable access to user namespaces, see"
  272. printf " %bhttps://github.com/ivan-hc/AM/blob/main/docs/troubleshooting.md#ubuntu-mess\033[0m\n" "${LightBlue}"
  273. echo " to know more."
  274. echo ""
  275. echo "$DIVIDING_LINE"
  276. fi
  277. }
  278. _am_dependences_check
  279. _check_ubuntu_mess
  280. # Function to check online connections (uses github.com by default, as the database and CLI itself are stored/hosted there)
  281. _online_check() {
  282. if ! wget -q --tries=10 --timeout=20 --spider https://github.com; then
  283. printf "\n %b is offline, please check your internet connection and try again\n\n" "$AMCLI"
  284. exit 0
  285. fi
  286. }
  287. # BLACKLIST FILES
  288. appimagelauncher_msg="Your installation of AppImageLauncher may have been done via DEB, RPM, or AUR, which interrupts the \
  289. natural operation of \"systemd-binfmt\" in addition to launching the aforementioned daemon. To avoid problems with \"$AMCLIUPPER\" \
  290. and any other AppImages helper, it's preferable to use \"only\" the standalone AppImage of AppImageLauncher, whose official \
  291. updated release can also be installed via \"$AMCLIUPPER\". But as long as you have the currently installed version, you can't use this CLI."
  292. _blacklisted_file() {
  293. printf "\n %b💀WARNING! Detected \"%b\"\033[0m\n\n" "${RED}" "$blacklisted_file"
  294. echo "It will prevent \"$AMCLIUPPER\" from working correctly with AppImages, especially when extracting, integrating and updating them." | _fit
  295. echo ""
  296. if echo "$blacklisted_file" | grep -q appimagelauncherd; then
  297. echo "$appimagelauncher_msg" | _fit
  298. echo "" && echo " Please remove \"AppImageLauncher\", reboot and retry!"
  299. else
  300. echo " Please remove \"$blacklisted_file\", reboot and retry!"
  301. fi
  302. echo ""
  303. exit 0
  304. }
  305. if command -v appimaged &>/dev/null; then
  306. blacklisted_file=$(command -v appimaged)
  307. _blacklisted_file
  308. elif command -v appimagelauncherd &>/dev/null; then
  309. blacklisted_file=$(command -v appimagelauncherd)
  310. _blacklisted_file
  311. fi
  312. ################################################################################
  313. # 3RD PARTY
  314. ################################################################################
  315. _use_newrepo() {
  316. [ -z "$2" ] && echo " USAGE: $AMCLI $1 [ARGUMENT]" && exit 1
  317. case $2 in
  318. 'add')
  319. if [ -z "$3" ]; then
  320. echo " USAGE: $AMCLI $1 $2 /path/to/dir"; echo " $AMCLI $1 $2 {URL}"; exit 1
  321. else
  322. echo "$3" >> "$AMDATADIR/newrepo-lists"
  323. fi
  324. ;;
  325. 'enable'|'on')
  326. [ ! -f "$AMDATADIR/newrepo-lists" ] && echo " ERROR, \"$AMDATADIR/newrepo-lists\" file not found" && exit 1
  327. [ -f "$AMDATADIR/newrepo-off" ] && mv "$AMDATADIR/newrepo-off" "$AMDATADIR/newrepo-on" && echo " New repo ON!"
  328. ;;
  329. 'disable'|'off')
  330. [ ! -f "$AMDATADIR/newrepo-lists" ] && echo " ERROR, \"$AMDATADIR/newrepo-lists\" file not found" && exit 1
  331. [ -f "$AMDATADIR/newrepo-on" ] && mv "$AMDATADIR/newrepo-on" "$AMDATADIR/newrepo-off" && echo " New repo OFF!"
  332. ;;
  333. 'info')
  334. printf " Source: %b\n Apps: %b\n List: %b\n" "$AMREPO" "$APPSDB" "$APPSLISTDB"
  335. ;;
  336. 'purge')
  337. [ -f "$AMDATADIR/newrepo-lists" ] && rm -f "$AMDATADIR"/newrepo* && echo " Removed all 3rd party repositories"
  338. ;;
  339. 'select')
  340. [ ! -f "$AMDATADIR/newrepo-lists" ] && echo " ERROR, \"$AMDATADIR/newrepo-lists\" file not found" && exit 1
  341. printf "Select a repo from the list or press CTRL+C to abort:\n%b\n" "$DIVIDING_LINE"; sleep 1
  342. select repo in $(sort -u "$AMDATADIR/newrepo-lists" | uniq); do
  343. test -n "$repo" && break
  344. echo ">>> Invalid Selection"
  345. done
  346. echo "$repo" > "$AMDATADIR/newrepo-on"
  347. ;;
  348. esac
  349. }
  350. # 3RD PARTY DATABASES
  351. _am_newrepo_check() {
  352. # Determine if the CLI uses the "main" branch of https://github.com/ivan-hc/AM or an alternative one
  353. if [ -f "$AMDATADIR/newrepo-on" ]; then
  354. if grep -q "^http" "$AMDATADIR/newrepo-on"; then
  355. AMREPO=$(<"$AMDATADIR/newrepo-on")
  356. elif grep -q "^/" "$AMDATADIR/newrepo-on"; then
  357. AMREPO="file://$(<"$AMDATADIR/newrepo-on")"
  358. fi
  359. AMBRANCH=$(basename "$AMREPO")
  360. export APPSDB="$AMREPO/programs/$ARCH"
  361. export APPSLISTDB="$AMREPO/programs/$ARCH-apps"
  362. export MODULES_PATH="$AMPATH/modules"
  363. if [ "$1" != "newrepo" ] && [ "$1" != "neodb" ]; then
  364. echo "$DIVIDING_LINE"; echo " Source: $AMREPO"; echo "$DIVIDING_LINE"
  365. fi
  366. fi
  367. }
  368. _am_newrepo_check "$@"
  369. ################################################################################
  370. # 3RD PARTY SOURCES
  371. ################################################################################
  372. third_party_flags_message=""
  373. # APPBUNDLEHUB
  374. export appbundle_repo="https://github.com/xplshn/AppBundleHUB"
  375. appbundle_readme="https://raw.githubusercontent.com/xplshn/dbin-metadata/refs/heads/master/misc/cmd/AM-support/AM.txt"
  376. _sync_appbundle_list() {
  377. rm -f "$AMDATADIR/$ARCH-appbundle"
  378. [ -n "$appbundle_readme" ] && curl -Ls "$appbundle_readme" | grep -v "\.appimage \|?" | grep "\.appbundle " | cut -d":" -f1 | cut -d"@" -f2 \
  379. | sed 's/^| /◆ /g; s/ https$//g; s/ :$//g; s/ | / : /g; s/ |$/./g; s/\.\.$/./g;' | sort > "$AMDATADIR/$ARCH-appbundle" \
  380. || touch "$AMDATADIR/$ARCH-appbundle"
  381. }
  382. # TOOLPACKS
  383. toolpack_repo="https://github.com/Azathothas/Toolpacks"
  384. toolpack_readme="https://bin.pkgforge.dev/${ARCH}/AM.txt"
  385. [ -n "$toolpack_readme" ] && third_party_flags="$third_party_flags --toolpack"
  386. [ -n "$toolpack_readme" ] && third_party_flags_message="$third_party_flags_message\n
  387. ${Gold}--toolpack\033[0m
  388. ${LightBlue}$AMCLI -i --toolpack {PROGRAM}\033[0m
  389. ${LightBlue}am -i --toolpack --user {PROGRAM}\033[0m
  390. ${LightBlue}$AMCLI -l --toolpack\033[0m
  391. ${LightBlue}$AMCLI -q --toolpack {KEYWORD}\033[0m
  392. Description: This is a flag to use in \"-i\" to install Toolpack programs, in \"-l\" to list all available \
  393. Toolpacks, and \"-q\" to search the Toolpack list. Toolpack is a collection of programs external to the \"AM\" \
  394. database. Visit $toolpack_repo to learn more.
  395. NOTE, for installations you can use \".toolpack\" as the package extension instead of using the flag.
  396. "
  397. _sync_toolpacks_list() {
  398. rm -f "$AMDATADIR/$ARCH-toolpack"
  399. [ -n "$toolpack_readme" ] && curl -Ls "$toolpack_readme" | grep -v "\.appimage \|.appbundle \|?" | cut -d":" -f1 | cut -d"@" -f2 \
  400. | sed 's/^| /◆ /g; s/ | https$/. To install it use the "--toolpack" flag./g; s/ | / : /g' | sort > "$AMDATADIR/$ARCH-toolpack" \
  401. || touch "$AMDATADIR/$ARCH-toolpack"
  402. }
  403. ################################
  404. # ALL THE ABOVE
  405. ################################
  406. export third_party_lists="appbundle toolpack"
  407. _completion_list_third_party() {
  408. [ -f "$AMDATADIR"/"$ARCH"-appbundle ] && awk '{print $2}' "$AMDATADIR"/"$ARCH"-appbundle >> "$AMDATADIR"/list
  409. [ -f "$AMDATADIR"/"$ARCH"-toolpack ] && awk '{print $2}' "$AMDATADIR"/"$ARCH"-toolpack | sed -e 's/$/.toolpack/' >> "$AMDATADIR"/list
  410. }
  411. _sync_third_party_lists() {
  412. _sync_appbundle_list
  413. _sync_toolpacks_list
  414. }
  415. export awk_name="1" awk_description="2" awk_site="3" awk_dl="4" awk_ver="5" # Numbers to use in "awk" to determine columns
  416. [ -z "$third_party_flags_message" ] && third_party_flags_message="none\n"
  417. ################################################################################
  418. # UTILITIES
  419. ################################################################################
  420. # COMPLETION LIST
  421. available_options="about add apikey backup clean config disable downgrade download enable extra files home icons info \
  422. install install-appimage launcher list lock neodb newrepo nolibfuse off on overwrite purge query remove sandbox \
  423. select sync template test unlock update --all --appimages --apps --byname --config --convert --debug \
  424. --devmode-disable --devmode-enable --disable-notifications --enable-notifications --force-latest --home --icons \
  425. -ias --launcher --less --pkg --rollback --disable-sandbox --sandbox --system --user $third_party_flags"
  426. _completion_lists() {
  427. # Remove existing lists and download new ones
  428. curl -Ls "$APPSLISTDB" > "$AMDATADIR/$ARCH-apps"
  429. awk -v FS="(◆ | : )" '{print $2}' <"$AMDATADIR"/"$ARCH"-apps > "$AMDATADIR"/list
  430. _completion_list_third_party
  431. # Append options to the list
  432. for o in $available_options; do
  433. echo "$o" >> "$AMDATADIR"/list
  434. done
  435. }
  436. # BASH, FISH AND ZSH COMPLETION
  437. completion_file="$DATADIR/bash-completion/completions/$AMCLI"
  438. mkdir -p "$DATADIR/bash-completion/completions" || exit 1
  439. if ! grep -o " $AMCLI$" "$completion_file" >/dev/null 2>&1; then
  440. echo "complete -W \"\$(cat $AMDATADIR/list 2>/dev/null)\" $AMCLI" >> "$completion_file"
  441. if [ -f "${ZDOTDIR:-$HOME}"/.zshrc ] && echo "$SHELL" | grep -q "zsh"; then
  442. cat <<-HEREDOC >> "${ZDOTDIR:-$HOME}"/.zshrc
  443. autoload bashcompinit
  444. bashcompinit
  445. source "$completion_file"
  446. HEREDOC
  447. fi
  448. echo "Shell completion has been enabled!"
  449. fi
  450. if [ -d "$DATADIR"/fish/completions ] || [ -d /etc/fish/completions ] || [ -d /usr/share/fish/completions ]; then
  451. command -v fish 1>/dev/null && [ ! -f "$CONFIGDIR"/fish/completions/am.fish ] && mkdir -p "$CONFIGDIR"/fish/completions && echo "complete -c am -f -a \"(cat $DATADIR/AM/list 2>/dev/null)\"" > "$CONFIGDIR"/fish/completions/am.fish
  452. fi
  453. # VERSION OF THE INSTALLED APPS
  454. # Filters
  455. _check_version_filters() {
  456. sed -E "s/$ARCH|amd64|x86-64|x64|basic|standard|full|help|Qt[0-9]//g; s/-/\n/g; s/_/\n/g;" |\
  457. grep -vi "appimage\|$arg\|?\|tar." | grep "[0-9]" | head -1 | sed 's/^v//g; s/^\.//g; s/\.$//g;'
  458. }
  459. _check_version_grep_numbers() {
  460. grep -Eo "([0-9]{1,}\.)+[0-9]{1,}" | head -1
  461. }
  462. # Versions
  463. _check_version_if_any_version_reference_is_somewhere() {
  464. txt_files=$(file "$argpath"/* | awk -F: '/ASCII text/ {print $1}')
  465. for txtf in $txt_files; do
  466. if [ -f "$argpath"/tbb_version.json ] && grep -qi "\"version\":" "$argpath"/tbb_version.json; then
  467. APPVERSION=$(sort "$argpath"/tbb_version.json | tr '"' '\n' | grep "^[0-9]" | head -1)
  468. elif grep -qi "^version=" "$txtf" && grep -qi "^name=" "$txtf"; then
  469. APPVERSION=$(grep -i "^version=" "$txtf" | cut -c 9- | tr -cd '[:alnum:]._-')
  470. fi
  471. done
  472. }
  473. _check_version_if_version_file_exists() {
  474. APPVERSION=$(sort "$argpath"/version | head -1 | sed 's:.*/::' | _check_version_filters)
  475. if [ -z "$APPVERSION" ]; then
  476. if grep -q "download$" "$argpath"/version; then
  477. APPVERSION=$(sort "$argpath"/version | tr '/' '\n' | _check_version_filters)
  478. elif grep -q "://" "$argpath"/version; then
  479. APPVERSION=$(sort "$argpath"/version | tr '/' '\n' | _check_version_grep_numbers)
  480. elif grep -q "/v[0-9]*" "$argpath"/version; then
  481. APPVERSION=$(sort "$argpath"/version | tr '/' '\n' | grep "^v[0-9]" | head -1 | sed 's/^v//g')
  482. elif [ "$(sort "$argpath"/version | wc -w | sed 's/ //g')" = 1 ]; then
  483. APPVERSION=$(sort "$argpath"/version | head -1)
  484. fi
  485. fi
  486. if [ -z "$APPVERSION" ]; then
  487. if grep -q "http.*download/.*[0-9].*/" "$argpath"/version; then
  488. APPVERSION=$(sort "$argpath"/version | tr '/-' '\n' | grep "[0-9]" | _check_version_filters | tail -1)
  489. fi
  490. fi
  491. }
  492. _check_version_if_library() {
  493. LIBNAME=$(sort "$argpath"/remove | tr ' ' '\n' | grep "usr/local/lib" | head -1 | sed 's:.*/::')
  494. APPVERSION=$(find /usr/local/lib -type f -name "$LIBNAME" -type f | sed 's:.*.so.::' | tail -1)
  495. }
  496. _check_version_if_binary_in_place() {
  497. APPVERSION=$(date -r "$argpath"/"$arg" "+%Y.%m.%d")
  498. }
  499. _check_version() {
  500. rm -f "$AMCACHEDIR"/version-args
  501. _determine_args
  502. for arg in $ARGS; do
  503. argpath=$(echo "$ARGPATHS" | grep "/$arg$")
  504. if [ -f "$argpath"/remove ]; then
  505. if [ -f "$argpath"/version ]; then
  506. _check_version_if_version_file_exists
  507. elif [ "$arg" = "$AMCLI" ]; then
  508. APPVERSION="$AMVERSION"
  509. elif echo "$arg" | grep -q "ffwa-"; then
  510. APPVERSION="WebApp"
  511. elif grep -q "usr/local/lib" "$argpath"/remove 2>/dev/null; then
  512. _check_version_if_library
  513. elif [ -f "$argpath"/updater ] || grep -qi "version=" "$argpath"/*; then
  514. _check_version_if_any_version_reference_is_somewhere
  515. else
  516. APPVERSION="unknown"
  517. fi
  518. if [ -z "$APPVERSION" ]; then
  519. [ -f "$argpath"/"$arg" ] && _check_version_if_binary_in_place || APPVERSION="unknown"
  520. fi
  521. echo " ◆ $arg | $APPVERSION" >> "$AMCACHEDIR"/version-args
  522. fi
  523. done
  524. }
  525. _check_version_for_auto_updatable_apps() {
  526. _determine_args
  527. for arg in $ARGS; do
  528. argpath=$(echo "$ARGPATHS" | grep "/$arg$")
  529. if [ -f "$argpath"/updater ]; then
  530. _check_version_if_any_version_reference_is_somewhere
  531. if [ "$AMCLI" = am ] && [ -d "$CACHEDIR"/am ] && grep -q " ◆ $arg |" "$CACHEDIR"/am/version-args; then
  532. OLDAPPVERSION=$(grep " ◆ $arg |" "$CACHEDIR"/am/version-args | awk 'END {print $NF}')
  533. sed -i "/ ◆ $arg |/s#$OLDAPPVERSION#$APPVERSION#" "$CACHEDIR"/am/*args*
  534. fi
  535. if [ -d "$CACHEDIR"/appman ] && grep -q " ◆ $arg |" "$CACHEDIR"/appman/version-args; then
  536. OLDAPPVERSION=$(grep " ◆ $arg |" "$CACHEDIR"/appman/version-args | awk 'END {print $NF}')
  537. sed -i "/ ◆ $arg |/s#$OLDAPPVERSION#$APPVERSION#" "$CACHEDIR"/appman/*args*
  538. fi
  539. fi
  540. done
  541. }
  542. if [ -f "$AMCACHEDIR"/version-args ]; then
  543. _check_version_for_auto_updatable_apps 2>/dev/null
  544. fi
  545. # This function removes all info and versions from the register
  546. _remove_info_files() {
  547. rm -f "$AMCACHEDIR"/files*
  548. rm -f "$AMCACHEDIR"/version-args
  549. }
  550. ################################################################################
  551. # APIKEY
  552. ################################################################################
  553. ghapikey_file="$AMDATADIR/ghapikey.txt"
  554. # Set header authorization if GitHub API key file exists
  555. [ -f "$ghapikey_file" ] && HeaderAuthWithGITPAT=" --header \"Authorization: token $(<"$ghapikey_file")\" "
  556. _use_apikey() {
  557. case $2 in
  558. 'del'|'delete'|'remove')
  559. [ -f "$ghapikey_file" ] || { echo " ✖ No file named $ghapikey_file has been found"; exit 1; }
  560. rm -f "$ghapikey_file" && echo " ✔ $ghapikey_file has been removed"
  561. exit 0
  562. esac
  563. if [[ "$2" =~ ^(gh[ps]_[a-zA-Z0-9]{36}|github_pat_[a-zA-Z0-9]{22}_[a-zA-Z0-9]{59})$ ]]; then
  564. test_apikey_output_with_wget=$(curl -Ls --header "Authorization: token $2" 'https://api.github.com/repos/ivan-hc/AM/releases' | head -1)
  565. [ -n "$test_apikey_output_with_wget" ] && echo "$2" > "$ghapikey_file" \
  566. && echo "Validation successful!" || echo "ERROR: This is not a valid key!"
  567. else
  568. echo "ERROR: Wrong expression, validation failed!"
  569. fi
  570. }
  571. _update_github_api_key_in_the_updater_files() {
  572. if [ -f "$ghapikey_file" ]; then
  573. ghapikey=$(<"$ghapikey_file")
  574. updater_files=("$APPSPATH"/*/AM-updater) # Assuming AM-updater is one level deeper
  575. for f in "${updater_files[@]}"; do
  576. if [ -f "$f" ] && grep -q "https://api.github.com" "$f"; then
  577. # Check if the file already contains a valid API key
  578. if ! grep -qE "(gh[ps]_[a-zA-Z0-9]{36}|github_pat_[a-zA-Z0-9]{22}_[a-zA-Z0-9]{59})" "$f"; then
  579. # Insert HeaderAuthWithGITPAT before the GitHub API URL
  580. sed -i "s#https://api.github.com#$HeaderAuthWithGITPAT https://api.github.com#g" "$f"
  581. else
  582. # Replace existing API key with the one from ghapikey.txt
  583. sed -i "s#\(gh[ps]_[a-zA-Z0-9]\{36\}\|github_pat_[a-zA-Z0-9]\{22\}_[a-zA-Z0-9]\{59\}\)#$ghapikey#g" "$f"
  584. fi
  585. fi
  586. done
  587. fi
  588. }
  589. ################################################################################
  590. # APPMAN MODE
  591. ################################################################################
  592. APPMAN_MSG="$DIVIDING_LINE\n \"AM\" is running as \"AppMan\", use ${Green}am --system\033[0m to switch it back to \"AM\"\n$DIVIDING_LINE\n"
  593. APPMAN_MSG_OFF="$DIVIDING_LINE\n \"AppMan Mode\" disabled! \n$DIVIDING_LINE\n"
  594. APPMAN_MSG_THINK="$DIVIDING_LINE\nNOTE: You can also choose to simply use \"--user\" as a flag to install apps locally \
  595. (options \"-i\", \"-ia\" and \"-e\") instead of going fully into \"AppMan Mode\". \"AM\" can handle local applications as well.\n$DIVIDING_LINE\n"
  596. _use_appman() {
  597. _online_check
  598. [ "$CLI" = appman ] && echo " This function only works for AM" && exit 0
  599. printf "%b" "$APPMAN_MSG_THINK" | _fit
  600. read -r -p " Do you wish to enter \"AppMan Mode\" (y,N)?" yn
  601. if ! echo "$yn" | grep -i '^y' >/dev/null 2>&1; then
  602. echo "$DIVIDING_LINE"
  603. else
  604. [ ! -f "$APPMANCONFIG"/appman-mode ] && mkdir -p "$APPMANCONFIG" && touch "$APPMANCONFIG"/appman-mode
  605. _appman && printf "%b" "$APPMAN_MSG"
  606. fi
  607. }
  608. if [ "$AMCLI" = am ]; then
  609. if [ -f "$APPMANCONFIG"/appman-mode ]; then
  610. [ ! -f "$APPMANCONFIG"/appman-config ] && printf "%b" "$APPMAN_MSG"
  611. _appman
  612. AMCLIPATH="$(realpath "$0")"
  613. elif [ ! -w "$AMPATH" ]; then
  614. read -r -p " \"AM\" is read-only, want to use it in \"AppMan Mode\" (Y,n)? " yn
  615. if echo "$yn" | grep -i '^n' >/dev/null 2>&1; then
  616. exit 0
  617. else
  618. echo "$DIVIDING_LINE"; echo "\"AppMan Mode\" enabled!"; echo "$DIVIDING_LINE"
  619. _use_appman 1>/dev/null
  620. fi
  621. fi
  622. fi
  623. ################################################################################
  624. # CLEAN
  625. ################################################################################
  626. _clean_amcachedir_message() {
  627. _clean_amcachedir
  628. [ "$AMCLI" = am ] && [ -d "$CACHEDIR"/am ] && echo " ✔ Clear the contents of $CACHEDIR/am"
  629. [ -d "$CACHEDIR"/appman ] && echo " ✔ Clear the contents of $CACHEDIR/appman"
  630. }
  631. _clean_all_home_cache_directories_of_appimages() {
  632. for arg in $ARGPATHS; do
  633. if test -d "$arg"/*.home/.cache; then
  634. rm -Rf "$arg"/*/*.home/.cache/* && echo " ✔ Clear the contents of $arg/*.home/.cache"
  635. fi
  636. done
  637. }
  638. _clean_all_tmp_directories_from_appspath() {
  639. _determine_args
  640. for arg in $ARGPATHS; do
  641. if [ -d "$arg"/tmp ]; then
  642. rm -Rf "$arg"/tmp && echo " ✔ Removed $arg/tmp"
  643. fi
  644. done
  645. }
  646. _clean_launchers() {
  647. if [ -d "$DATADIR"/applications/AppImages ]; then
  648. rm -f "$AMCACHEDIR"/mountpoints
  649. for var in "$DATADIR"/applications/AppImages/*.desktop; do
  650. # full path to appimage
  651. appimagename=$(awk -F'=| ' '/Exec=/{print $2; exit}' "$var" | sed 's/"//g; s/\s.*$//')
  652. # name of the appimage
  653. launcher2del=$(basename -- "$(echo "$appimagename" | tr '[:upper:]' '[:lower:]')")
  654. # removable mount point where the appimage may be stored
  655. mountpoint=$(echo "$appimagename" | cut -d'/' -f1-4)
  656. if [ ! -f "$appimagename" ]; then
  657. if echo "$appimagename" | grep -q "^/media/\|^/mnt/"; then
  658. mountpoint=$(echo "$appimagename" | cut -d'/' -f1-4)
  659. unmounted_point=$(echo "$mountpoint" | cut -d'/' -f1-2)
  660. elif echo "$appimagename" | grep -q "^/run/media/"; then
  661. mountpoint=$(echo "$appimagename" | cut -d'/' -f1-5)
  662. unmounted_point="/run/media"
  663. else
  664. mountpoint=""
  665. fi
  666. if [ -n "$mountpoint" ] && [ ! -d "$mountpoint" ]; then
  667. echo "$mountpoint" >> "$AMCACHEDIR"/mountpoints
  668. echo " ✖ ERROR: cannot remove \"$(basename "$var")\""
  669. echo " related AppImage is located in an unmounted path of $unmounted_point"
  670. else
  671. rm -f "$var"
  672. [ -n "$BINDIR" ] && [ -n "$launcher2del" ] && rm -f "$BINDIR"/"$launcher2del"*
  673. fi
  674. fi
  675. done
  676. if [ -f "$AMCACHEDIR"/mountpoints ]; then
  677. mountpoints=$(sort "$AMCACHEDIR"/mountpoints)
  678. for m in $mountpoints; do
  679. [ ! -d "$m" ] && mountpoint_enabled=1
  680. done
  681. fi
  682. [ -z "$mountpoint_enabled" ] && [ -n "$BINDIR" ] && cd "$BINDIR" && find . -xtype l -delete
  683. rm -f "$AMCACHEDIR"/mountpoints
  684. echo ' ✔ Removed orphaned launchers produced with the "--launcher" option'
  685. rmdir "$DATADIR"/applications/AppImages
  686. else
  687. [ -n "$BINDIR" ] && cd "$BINDIR" && find . -xtype l -delete
  688. fi
  689. }
  690. _clean_old_modules() {
  691. MODULES=$(sort "$(realpath "$0")" | tr '"' '\n' | grep "[a-z]\.am$" | uniq)
  692. [ -z "$MODULES_PATH" ] && exit 1
  693. for m in "$MODULES_PATH"/*; do
  694. if [[ "${MODULES}" != *"$(basename -- "$m")"* ]];then
  695. rm -f "$m" 2>/dev/null
  696. echo " ✔ Removed obsolete module named \"$(basename -- "$m")\""
  697. fi
  698. done
  699. }
  700. _use_clean() {
  701. echo " Cleaning temporary files and folders..." && sleep 0.1
  702. i=100 && while [ "$i" -ge 0 ]; do
  703. printf " %03d\r" "$i" && sleep 0.0001 && i=$((i - 1))
  704. done
  705. _detect_appman_apps
  706. _determine_args
  707. _clean_amcachedir_message
  708. _clean_all_home_cache_directories_of_appimages
  709. _clean_all_tmp_directories_from_appspath
  710. _clean_launchers 2>/dev/null
  711. _clean_old_modules
  712. }
  713. ################################################################################
  714. # SYNC
  715. ################################################################################
  716. _sync_installation_scripts() {
  717. printf "%b\n Checking for changes of the installation scripts in the online database...\n" "$DIVIDING_LINE"
  718. _determine_args
  719. for arg in $ARGS; do
  720. argpath=$(echo "$ARGPATHS" | grep "/$arg$")
  721. if [ -f "$argpath"/AM-updater ]; then
  722. mkdir -p "$argpath"/.am-installer
  723. scriptname=$(ls "$argpath/.am-installer/" | head -1)
  724. if [ -n "$scriptname" ]; then
  725. CURRENT=$(cat "$argpath"/.am-installer/"$scriptname")
  726. SOURCE=$(curl -Ls "$APPSDB"/"$scriptname")
  727. if [ "$CURRENT" = "$SOURCE" ]; then
  728. echo -ne "\r" 2>/dev/null
  729. else
  730. printf " ◆ Changed https://github.com/ivan-hc/AM/blob/main/programs/%b/%b\n" "$ARCH" "$scriptname"
  731. fi
  732. else
  733. if curl --output /dev/null --silent --head --fail "$APPSDB"/"$arg" 1>/dev/null; then
  734. printf " ◆ No installation script for %b, downloading one...\n" "$arg"
  735. mkdir -p "$argpath"/.am-installer
  736. wget -q "$APPSDB/$arg" -O "$argpath"/.am-installer/"$arg"
  737. fi
  738. fi
  739. fi
  740. done
  741. }
  742. _sync_appimages_list() {
  743. APPIMAGES_LIST="${APPIMAGES_LIST:-$AMREPO/programs/$ARCH-appimages}"
  744. curl -Ls "$APPIMAGES_LIST" > "$AMDATADIR/$ARCH-appimages"
  745. }
  746. _sync_databases() {
  747. printf "%b\n Check and update offline lists of additional databases...\n" "$DIVIDING_LINE"
  748. _sync_appimages_list
  749. _sync_third_party_lists 2>/dev/null
  750. _completion_lists
  751. }
  752. _sync_modules() {
  753. printf "%b\n Check for updates in modules...\n" "$DIVIDING_LINE"
  754. MODULES=$(curl -Ls "$AMREPO/APP-MANAGER" | tr '"' '\n' | grep "[a-z]\.am$")
  755. for module_name in $MODULES; do
  756. cd "$MODULES_PATH" || return 1
  757. if ! test -f ./"$module_name"; then
  758. echo " ◆ Downloading $module_name (not previously installed)..."
  759. curl -Os "$MODULES_SOURCE/$module_name" 2>/dev/null
  760. chmod a+x ./"$MODULENAME"
  761. fi
  762. CURRENT=$(cat ./"$module_name" 2>/dev/null)
  763. SOURCE=$(curl -Ls "$MODULES_SOURCE/$module_name")
  764. if [ "$CURRENT" = "$SOURCE" ]; then
  765. echo -ne "\r" 2>/dev/null
  766. else
  767. echo " ◆ Updating $module_name..."
  768. curl -Ls "$MODULES_SOURCE/$module_name" > ./"$module_name" 2>/dev/null
  769. fi
  770. done
  771. _clean_old_modules
  772. }
  773. _sync_amcli() {
  774. echo "$DIVIDING_LINE"
  775. CURRENT_AM_VERSION="$AMVERSION"
  776. echo -ne "\n ◆ SYNCHRONIZING \"$AMCLIUPPER\" VERSION \"$CURRENT_AM_VERSION\"...\r" && sleep 0.25
  777. _clean_amcachedir 1>/dev/null
  778. cd "$AMCACHEDIR" || return 1
  779. curl -Ls "$AMREPO"/APP-MANAGER > ./APP-MANAGER && chmod a+x ./APP-MANAGER
  780. echo y | mv ./APP-MANAGER "$(realpath "$0")"
  781. NEW_AM_VERSION=$("$AMCLIPATH" -v)
  782. if [ ! "$CURRENT_AM_VERSION" = "$NEW_AM_VERSION" ]; then
  783. echo -ne " A new release of \"$AMCLIUPPER\" is available, please wait...\r"
  784. echo " ◆ \"$AMCLIUPPER\" IS NOW UPDATED TO THE BRAND NEW \"$NEW_AM_VERSION\" VERSION!"
  785. printf "\n Replacement of version \"%b\" currently in use, COMPLETED! \n" "$CURRENT_AM_VERSION"
  786. printf "\n See https://github.com/ivan-hc/AM/commits/main\n\n"
  787. else
  788. echo " ◆ \"$AMCLIUPPER\" IS ALREADY UPDATED, CURRENT VERSION \"$CURRENT_AM_VERSION\""
  789. printf "\n See https://github.com/ivan-hc/AM/commits/%b\n\n" "$AMBRANCH"
  790. fi
  791. }
  792. _use_sync() {
  793. _online_check
  794. _betatester_message_on
  795. _sync_installation_scripts
  796. _sync_databases
  797. if [ "$(realpath "$0")" != "/usr/bin/am" ] && [ "$AMSYNC" != 1 ]; then
  798. _sync_modules
  799. _sync_amcli
  800. fi
  801. echo "$DIVIDING_LINE"
  802. }
  803. ################################################################################
  804. # UPDATE
  805. ################################################################################
  806. _update_updatable_apps_msg_head() {
  807. printf " \"%b\" CAN MANAGE UPDATES FOR THE FOLLOWING PROGRAMS:\n%b\n\n" "$AMCLIUPPER" "$DIVIDING_LINE"
  808. [ -f "$AMCACHEDIR/updatable-args-list" ] && grep "◆" "$AMCACHEDIR/updatable-args-list" | sort || echo " None"
  809. printf "\n All self-updatable programs are excluded\n"
  810. echo "$DIVIDING_LINE"
  811. }
  812. _update_list_updatable_apps() {
  813. _determine_args
  814. _check_version
  815. for arg in $ARGS; do
  816. argpath=$(echo "$ARGPATHS" | grep "/$arg$")
  817. if [ -d "$argpath" ]; then
  818. if [ -f "$argpath/AM-updater" ]; then
  819. app_version=$(grep -w " ◆ $arg |" "$AMCACHEDIR/version-args" | sed 's:.*| ::')
  820. echo " ◆ $arg $app_version" >> "$AMCACHEDIR"/updatable-args-list
  821. fi
  822. fi
  823. done
  824. }
  825. _update_determine_apps_version_changes() {
  826. [ -z "$debug_update" ] && echo "$DIVIDING_LINE"
  827. if [ -f "$AMCACHEDIR"/updatable-args-list ]; then
  828. mv "$AMCACHEDIR"/updatable-args-list "$AMCACHEDIR"/updatable-args-list-old
  829. _update_list_updatable_apps
  830. OLDVER="$AMCACHEDIR/updatable-args-list-old"
  831. NEWVER="$AMCACHEDIR/updatable-args-list"
  832. if cmp --silent -- "$NEWVER" "$OLDVER"; then
  833. echo ' Nothing to do here!'
  834. else
  835. printf " The following apps have been updated:\n\n"
  836. diff "$OLDVER" "$NEWVER" | grep "^>" | sed 's/^> //g'
  837. echo ""
  838. fi
  839. else
  840. echo ' No apps to update here!'
  841. fi
  842. }
  843. _update_run_updater() {
  844. if grep -q "api.github.com" "$argpath"/AM-updater; then
  845. 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)
  846. if [ -z "$GH_API_ALLOWED" ]; then
  847. if command -v torsocks 1>/dev/null; then
  848. if [ -z "$debug_update" ]; then
  849. torsocks "$argpath"/AM-updater >/dev/null 2>&1
  850. else
  851. torsocks "$argpath"/AM-updater
  852. fi
  853. else
  854. echo " ✖ $APPNAME cannot be updated, you have reached GitHub API limit. Install \"torsocks\" from your system package manager and retry!" \
  855. | fold -sw 72 | sed 's/^/ /g; s/ ✖/✖/g'
  856. fi
  857. else
  858. if [ -z "$debug_update" ]; then
  859. "$argpath"/AM-updater >/dev/null 2>&1
  860. else
  861. "$argpath"/AM-updater
  862. fi
  863. fi
  864. else
  865. if [ -z "$debug_update" ]; then
  866. "$argpath"/AM-updater >/dev/null 2>&1
  867. else
  868. "$argpath"/AM-updater
  869. fi
  870. fi
  871. end=$(date +%s)
  872. echo " ◆ $APPNAME is updated, $((end - start)) seconds elapsed!"
  873. [ -n "$debug_update" ] && echo "$DIVIDING_LINE"
  874. }
  875. _update_app() {
  876. APPNAME=$(echo "$arg" | tr '[:lower:]' '[:upper:]')
  877. start=$(date +%s)
  878. if [ -w "$argpath"/AM-updater ]; then
  879. _update_run_updater &
  880. else
  881. echo " ✖ $APPNAME is read-only, cannot update it!"
  882. fi
  883. }
  884. _update_all_apps() {
  885. for arg in $ARGS; do
  886. argpath=$(echo "$ARGPATHS" | grep "/$arg$")
  887. cd "$argpath" || exit 1
  888. arg=$(printf '%s\n' "${PWD##*/}")
  889. if [ -f "$argpath"/AM-updater ]; then
  890. _update_app
  891. fi
  892. done
  893. wait
  894. _update_determine_apps_version_changes
  895. rm -Rf "$APPSPATH"/*/tmp
  896. [ -d "$APPMAN_APPSPATH" ] && rm -Rf "$APPMAN_APPSPATH"/*/tmp
  897. }
  898. _update_launchers_not_found_msg() {
  899. MISSING_LAUNCHERS_MSG=" No launcher found."
  900. printf "%b\n%b\n%b\n" "$DIVIDING_LINE" "$MISSING_LAUNCHERS_MSG" "$DIVIDING_LINE"
  901. }
  902. _update_launchers() {
  903. _clean_launchers 2>/dev/null 1>/dev/null
  904. MISSING_LAUNCHERS_MSG="No launcher found, use option \"--launcher\" to create them."
  905. [ ! -d "$DATADIR"/applications/AppImages ] && _update_launchers_not_found_msg && exit 0
  906. [ -d "$DATADIR"/applications/AppImages ] && [ -z "$( ls -A "$DATADIR"/applications/AppImages )" ] && _update_launchers_not_found_msg && exit 0
  907. if ! command -v appimageupdatetool 1>/dev/null; then
  908. update_launchers_error_message=" 💀 ERROR! Missing command \"${RED}appimageupdatetool\033[0m\", install it and retry!"
  909. printf "%b\n%b\n%b\n" "$DIVIDING_LINE" "$update_launchers_error_message" "$DIVIDING_LINE"
  910. else
  911. echo " ◆ Update local AppImages integrated manually"
  912. for var in "$DATADIR"/applications/AppImages/*.desktop; do
  913. appimage_full_path=$(awk -F'=| ' '/Exec=/{print $2; exit}' "$var" | sed 's/"//g; s/\s.*$//')
  914. appimagename=$(basename -- "$appimage_full_path")
  915. appimage_path=$(echo "$appimage_full_path" | sed -E 's|/[^/]+$|/|; s/\/*$//g')
  916. printf "%b\n File: %b%b\033[0m\n Path: %b" "$DIVIDING_LINE" "${Green}" "$appimagename" "$appimage_path"
  917. if [ ! -f "$appimage_full_path" ]; then
  918. echo "(unmounted)" | _fit
  919. else
  920. printf "\n\n"
  921. appimageupdatetool -Or "$appimage_full_path"
  922. fi
  923. done
  924. fi
  925. }
  926. _use_update() {
  927. _online_check
  928. _update_github_api_key_in_the_updater_files
  929. _clean_all_tmp_directories_from_appspath >/dev/null
  930. ENTRIES="$(echo "$@" | cut -f2- -d ' ' | tr ' ' '\n' | grep -v -- "^-\|^$1$")"
  931. FLAGS=$(echo "$@" | tr ' ' '\n' | grep -- "--" | tr '\n ' ' ')
  932. if echo "$FLAGS" | grep -q -- "--debug"; then
  933. debug_update="1"
  934. fi
  935. if [ -z "$ENTRIES" ]; then
  936. _clean_amcachedir
  937. _update_list_updatable_apps
  938. printf "%b\n >> START OF ALL PROCESSES << \n%b\n" "$DIVIDING_LINE" "$DIVIDING_LINE"
  939. if echo "$FLAGS" | grep -q -- "--apps"; then
  940. _update_updatable_apps_msg_head
  941. _update_all_apps
  942. elif echo "$FLAGS" | grep -q -- "--launcher"; then
  943. _update_launchers
  944. else
  945. _update_updatable_apps_msg_head
  946. _update_all_apps
  947. _use_sync
  948. printf " >> END OF ALL PROCESSES << \n%b\n" "$DIVIDING_LINE"
  949. sleep 0.2
  950. exit 0
  951. fi
  952. printf "%b\n >> END OF ALL PROCESSES << \n%b\n" "$DIVIDING_LINE" "$DIVIDING_LINE"
  953. sleep 0.2
  954. exit 0
  955. else
  956. [ -n "$debug_update" ] && echo "$DIVIDING_LINE"
  957. _determine_args
  958. for arg in $ENTRIES; do
  959. argpath=$(echo "$ARGPATHS" | grep "/$arg$")
  960. if [ -f "$argpath"/AM-updater ]; then
  961. cd "$argpath" 2>/dev/null || exit 1
  962. _update_app
  963. else
  964. UPDATERS=$(cd "$argpath" 2>/dev/null && find . -name "*update*" -print 2>/dev/null)
  965. [ -n "$UPDATERS" ] && arg_autoupdatable=", it may have its update system"
  966. echo " ✖ Cannot manage updates for \"$(echo "$arg" | tr '[:lower:]' '[:upper:]')\"$arg_autoupdatable"
  967. fi
  968. done
  969. wait
  970. exit 0
  971. fi
  972. }
  973. _use_force_latest() {
  974. _online_check
  975. _determine_args
  976. ENTRIES="$(echo "$@" | cut -f2- -d ' ')"
  977. for arg in $ENTRIES; do
  978. argpath=$(echo "$ARGPATHS" | grep "/$arg$")
  979. if [ ! -d "$argpath" ]; then
  980. echo " ERROR: \"$arg\" is not installed, see \"-f\""
  981. elif [ ! -f "$argpath"/AM-updater ]; then
  982. echo " ERROR: \"$AMCLI\" cannot manage updates for \"$arg\""
  983. elif ! grep -q "api.github.com" "$argpath"/AM-updater; then
  984. echo " ERROR: \"$arg\" source is not on Github"
  985. elif ! grep -q "/releases | " "$argpath"/AM-updater; then
  986. echo " ERROR: \"$arg\" does not redirect to a generic \"releases\""
  987. else
  988. sed -i 's#/releases | #/releases/latest | #g' "$argpath"/AM-updater
  989. APPNAME=$(echo "$arg" | tr '[:lower:]' '[:upper:]')
  990. start=$(date +%s)
  991. _update_run_updater
  992. fi
  993. done
  994. }
  995. ################################################################################
  996. # USAGE
  997. ################################################################################
  998. # HANDLE ALL THE EXTERNAL MODULES
  999. _use_module() {
  1000. # Test if module exists
  1001. if [ ! -f "$MODULES_PATH/$MODULE" ]; then
  1002. _online_check
  1003. if ! wget -q "$MODULES_SOURCE/$MODULE" -O "$MODULES_PATH/$MODULE"; then
  1004. echo " Module not found, run \"$AMCLI -s\" to update \"$AMCLIUPPER\""
  1005. exit 1
  1006. fi
  1007. chmod a+x "$MODULES_PATH/$MODULE"
  1008. fi
  1009. # Source module
  1010. source "$MODULES_PATH/$MODULE" "$@"
  1011. }
  1012. case "$1" in
  1013. '')
  1014. echo " USAGE: $AMCLI [OPTION]"
  1015. echo " $AMCLI [OPTION] [ARGUMENT]"
  1016. echo ""
  1017. echo " Run the \"$AMCLI -h\" command to find out more"
  1018. exit 0
  1019. ;;
  1020. 'about'|'-a'|\
  1021. 'files'|'-f'|'-fi'|\
  1022. 'list'|'-l'|\
  1023. 'query'|'-q')
  1024. MODULE="database.am"
  1025. if [ -t 1 ]; then _use_module "$@"; else _use_module "$@" | sed -e 's/\x1b\[[0-9;]*m//g'; fi
  1026. ;;
  1027. 'backup'|'-b'|\
  1028. 'downgrade'|'--rollback'|\
  1029. 'icons'|'--icons'|\
  1030. 'launcher'|'--launcher'|\
  1031. 'lock'|'unlock'|\
  1032. 'nolibfuse'|\
  1033. 'overwrite'|'-o'|\
  1034. 'remove'|'-R'|'-r')
  1035. MODULE="management.am"
  1036. _use_module "$@"
  1037. ;;
  1038. 'config'|'-C'|'--config'|\
  1039. 'home'|'-H'|'--home'|\
  1040. 'sandbox'|'--sandbox'|\
  1041. '--disable-sandbox')
  1042. MODULE="sandboxes.am"
  1043. _use_module "$@"
  1044. ;;
  1045. 'download'|'-d'|\
  1046. 'extra'|'-e'|\
  1047. 'install'|'-i'|'-ias'|\
  1048. 'install-appimage'|'-ia')
  1049. MODULE="install.am"
  1050. _online_check
  1051. [ "$CLI" = am ] && [ -f "$APPMANCONFIG"/appman-mode ] && printf "%b" "$APPMAN_MSG"
  1052. _use_module "$@"
  1053. ;;
  1054. 'template'|'-t')
  1055. MODULE="template.am"
  1056. _online_check
  1057. _use_module "$@"
  1058. ;;
  1059. # INBUILT OPTIONS
  1060. '--devmode-disable'|'--devmode-enable')
  1061. [ "$1" = "--devmode-disable" ] && rm -f "$AMDATADIR"/betatester \
  1062. || touch "$AMDATADIR"/betatester && _betatester_message_on
  1063. ;;
  1064. '--force-latest')
  1065. _use_force_latest "$@"
  1066. ;;
  1067. '--system')
  1068. [ -f "$APPMANCONFIG"/appman-mode ] && rm -f "$APPMANCONFIG"/appman-mode && printf "%b" "$APPMAN_MSG_OFF"
  1069. ;;
  1070. 'apikey')
  1071. _use_apikey "$@"
  1072. ;;
  1073. 'appman'|'--user')
  1074. _use_appman
  1075. ;;
  1076. 'clean'|'-c')
  1077. _use_clean
  1078. ;;
  1079. 'newrepo'|'neodb')
  1080. _use_newrepo "$@"
  1081. ;;
  1082. 'sync'|'-s')
  1083. _use_sync
  1084. ;;
  1085. 'update'|'-u'|'-U')
  1086. _use_update "$@"
  1087. ;;
  1088. 'version'|'-v'|'--version')
  1089. echo "$AMVERSION"
  1090. ;;
  1091. '--disable-notifications')
  1092. _determine_args
  1093. for n in $ARGPATHS; do sed -e '/notify-send/ s/^#*/#/' -i "$n/AM-updater" 2>/dev/null; done
  1094. ;;
  1095. '--enable-notifications')
  1096. _determine_args
  1097. for n in $ARGPATHS; do sed -e '/notify-send/ s/^#*//' -i "$n/AM-updater" 2>/dev/null; done
  1098. ;;
  1099. 'help'|'-h')
  1100. ################################################################################
  1101. # HELP
  1102. ################################################################################
  1103. _use_help() {
  1104. [ "$CLI" = am ] && [ -f "$APPMANCONFIG"/appman-mode ] && printf "%b" "$APPMAN_MSG"
  1105. echo -e "
  1106. NAME: ${Green}$AMCLIUPPER\033[0m VERSION: ${Green}$AMVERSION\033[0m
  1107. SYNOPSIS: ${LightBlue}$AMCLI {OPTION}\033[0m
  1108. ${LightBlue}$AMCLI {OPTION} {PROGRAM}\033[0m
  1109. DESCRIPTION: A command line utility to install and manage AppImages and other portable programs for GNU/Linux thanks to its AUR-inspired database.
  1110. OPTIONS:
  1111. ${Gold}about, -a\033[0m
  1112. ${LightBlue}$AMCLI -a {PROGRAM}\033[0m
  1113. Description: Shows more info about one or more apps.
  1114. ${Gold}apikey\033[0m
  1115. ${LightBlue}$AMCLI apikey {Github Token}
  1116. ${LightBlue}$AMCLI apikey delete\033[0m
  1117. Description: Accede to github APIs using your personal access tokens. The file named \"ghapikey.txt\" will be saved in $AMDATADIR. Use \"del\" to remove it.
  1118. ${Gold}backup, -b\033[0m
  1119. ${LightBlue}$AMCLI -b {PROGRAM}\033[0m
  1120. Description: Create a snapshot of the current version of an installed program.
  1121. ${Gold}clean, -c\033[0m
  1122. ${LightBlue}$AMCLI -c\033[0m
  1123. Description: Removes all the unnecessary files and folders.
  1124. ${Gold}config, -C, --config\033[0m
  1125. ${LightBlue}$AMCLI -C {PROGRAM}\033[0m
  1126. Description: Set a dedicated \$XDD_CONFIG_HOME for one or more AppImages.
  1127. ${Gold}downgrade, --rollback\033[0m
  1128. ${LightBlue}$AMCLI --rollback {PROGRAM}\033[0m
  1129. Description: Download an older or specific app version.
  1130. ${Gold}download, -d\033[0m
  1131. ${LightBlue}$AMCLI -d {PROGRAM}
  1132. ${LightBlue}$AMCLI -d --convert {PROGRAM}\033[0m
  1133. Description: Download one or more installation scripts to your desktop or convert them to local installers for \"AppMan\". To test the scripts, use the \"${LightBlue}$AMCLI -i '/path/to/script'\033[0m\" command or enter the directory of the script and run the \"${LightBlue}$AMCLI -i ./script\033[0m\" command, even using dedicated flags, if necessary (see \"-i\").
  1134. ${Gold}extra, -e\033[0m
  1135. ${LightBlue}$AMCLI -e user/project {APPNAME}
  1136. ${LightBlue}$AMCLI -e user/project {APPNAME} {KEYWORD}\033[0m
  1137. Description: Install AppImages from github.com, outside the database. This allows you to install, update and manage them all like the others. Where \"user/project\" can be the whole URL to the github repository, give a name to the program so that it can be used from the command line. Optionally, add an \"univoque\" keyword if multiple AppImages are listed.
  1138. ${Gold}files, -f, -fi\033[0m
  1139. ${LightBlue}$AMCLI -f
  1140. ${LightBlue}$AMCLI -f --byname
  1141. ${LightBlue}$AMCLI -f --less\033[0m
  1142. Description: Shows the list of all installed programs, with sizes. By default apps are sorted by size, use \"--byname\" to sort by name. With the option \"--less\" it shows only the number of installed apps. Option \"-fi\" only shows installed apps, not the AppImages integrated with the \"--launcher\" option.
  1143. ${Gold}help, -h\033[0m
  1144. ${LightBlue}$AMCLI -h\033[0m
  1145. Description: Prints this message.
  1146. ${Gold}home, -H, --home\033[0m
  1147. ${LightBlue}$AMCLI -H {PROGRAM}\033[0m
  1148. Description: Set a dedicated \$HOME directory for one or more AppImages.
  1149. ${Gold}icons, --icons\033[0m
  1150. ${LightBlue}$AMCLI --icons {PROGRAM}
  1151. ${LightBlue}$AMCLI --icons --all\033[0m
  1152. Description: Allow installed apps to use system icon themes. You can specify the name of the apps to change or use the \"--all\" flag to change all of them at once. This will remove the icon path from the .desktop file and add the symbolic link of all available icons in the $DATADIR/icons/hicolor/scalable/apps directory. The \"--icons\" option can be used as \"flag\" in the \"-i\" and \"-ia\" options.
  1153. ${Gold}install, -i\033[0m
  1154. ${LightBlue}$AMCLI -i {PROGRAM}
  1155. ${LightBlue}$AMCLI -i --debug {PROGRAM}
  1156. ${LightBlue}$AMCLI -i --force-latest {PROGRAM}
  1157. ${LightBlue}$AMCLI -i --icons {PROGRAM}
  1158. ${LightBlue}$AMCLI -i --sandbox {PROGRAM}\033[0m
  1159. Description: Install one or more programs or libraries from the list. With the \"--debug\" option you can see log messages to debug the script. For more details on \"--force-latest\", see the dedicated option, below. Use the \"--icons\" flag to allow the program to use icon themes. It can also be extended with additional flags (see third-party flags, at the bottom of this message). The \"--sandbox\" flag allows you to set sandboxes for AppImage packages.
  1160. ${Gold}install-appimage, -ia, -ias\033[0m
  1161. ${LightBlue}$AMCLI -ia {PROGRAM}
  1162. ${LightBlue}$AMCLI -ia --debug {PROGRAM}
  1163. ${LightBlue}$AMCLI -ia --force-latest {PROGRAM}
  1164. ${LightBlue}$AMCLI -ia --icons {PROGRAM}
  1165. ${LightBlue}$AMCLI -ia --sandbox {PROGRAM}
  1166. ${LightBlue}$AMCLI -ias {PROGRAM}\033[0m
  1167. Description: Same as \"install\" (see above) but for AppImages only. Option \"-ias\" (aka Install AppImage & Sandbox) is equivalent to \"-ia --sandbox\", to set sandboxes for AppImage packages.
  1168. ${Gold}lock\033[0m
  1169. ${LightBlue}$AMCLI lock {PROGRAM}\033[0m
  1170. Description: Prevent an application being updated, if it has an\"AM-updater\" script.
  1171. ${Gold}list, -l\033[0m
  1172. ${LightBlue}$AMCLI -l
  1173. ${LightBlue}$AMCLI -l --all
  1174. ${LightBlue}$AMCLI -l --appimages\033[0m
  1175. Description: Shows the list of all the apps available, or just the AppImages. It can also be extended with additional flags, the \"--all\" flag allows you to consult the set of all supported databases (see third-party flags, at the bottom of this message).
  1176. ${Gold}newrepo, neodb\033[0m
  1177. ${LightBlue}$AMCLI newrepo add {URL}\\{PATH}
  1178. ${LightBlue}$AMCLI newrepo select
  1179. ${LightBlue}$AMCLI newrepo on\\off
  1180. ${LightBlue}$AMCLI newrepo purge
  1181. ${LightBlue}$AMCLI newrepo info\033[0m
  1182. Description: Set a new default repo, use \"add\" to append the path to a local directory or an online URL, then use \"select\" to use it by default, a message will warn you about the usage of this repo instead of the default one. Use \"on\"/\"off\" to enable/disable it. Use \"purge\" to remove all 3rd party repos. Use \"info\" to see the source from where installation scripts and lists are taken.
  1183. ${Gold}nolibfuse\033[0m
  1184. ${LightBlue}$AMCLI nolibfuse {PROGRAM}\033[0m
  1185. Description: Convert old AppImages and get rid of \"libfuse2\" dependence.
  1186. ${Gold}overwrite, -o\033[0m
  1187. ${LightBlue}$AMCLI -o {PROGRAM}\033[0m
  1188. Description: Overwrite apps with snapshots saved previously (see \"-b\").
  1189. ${Gold}query, -q\033[0m
  1190. ${LightBlue}$AMCLI -q {KEYWORD}
  1191. ${LightBlue}$AMCLI -q --all {KEYWORD}
  1192. ${LightBlue}$AMCLI -q --appimages {KEYWORD}
  1193. ${LightBlue}$AMCLI -q --pkg {PROGRAM1} {PROGRAM2}[0m
  1194. Description: Search for keywords in the list of available applications, add the \"--appimages\" option to list only the AppImages or add \"--pkg\" to list multiple programs at once. It can also be extended with additional flags, the \"--all\" flag allows you to consult the set of all supported databases (see third-party flags, at the bottom of this message).
  1195. ${Gold}remove, -r\033[0m
  1196. ${LightBlue}$AMCLI -r {PROGRAM}\033[0m
  1197. Description: Removes one or more apps, requires confirmation.
  1198. ${Gold}-R\033[0m
  1199. ${LightBlue}$AMCLI -R {PROGRAM}\033[0m
  1200. Description: Removes one or more apps without asking.
  1201. ${Gold}sandbox, --sandbox\033[0m
  1202. ${LightBlue}$AMCLI sandbox {PROGRAM}\033[0m
  1203. Description: Run an AppImage in a sandbox using Aisap.
  1204. NOTE, \"--sandbox\" can be used as a flag in \"-i\" and \"-ia\" or can be replaced using the option \"-ias\" (aka Install AppImage & Sandbox).
  1205. ${Gold}sync, -s\033[0m
  1206. ${LightBlue}$AMCLI -s\033[0m
  1207. Description: Updates this script to the latest version hosted.
  1208. ${Gold}template, -t\033[0m
  1209. ${LightBlue}$AMCLI -t {PROGRAM}\033[0m
  1210. Description: Generate a custom installation script. To test the scripts, use the \"${LightBlue}$AMCLI -i '/path/to/script'\033[0m\" command or enter the directory of the script and run the \"${LightBlue}$AMCLI -i ./script\033[0m\" command, even using dedicated flags, if necessary (see \"-i\").
  1211. ${Gold}unlock\033[0m
  1212. ${LightBlue}$AMCLI unlock {PROGRAM}\033[0m
  1213. Description: Unlock updates for the selected program (nulls \"lock\").
  1214. ${Gold}update, -u, -U\033[0m
  1215. ${LightBlue}$AMCLI -u
  1216. ${LightBlue}$AMCLI -u --apps
  1217. ${LightBlue}$AMCLI -u --debug
  1218. ${LightBlue}$AMCLI -u --apps --debug
  1219. ${LightBlue}$AMCLI -u {PROGRAM}\033[0m
  1220. ${LightBlue}$AMCLI -u --debug {PROGRAM}
  1221. ${LightBlue}$AMCLI -u --launcher\033[0m
  1222. Description: Update everything. Add \"--apps\" to update only the apps or write only the apps you want to update by adding their names. Add the \"--debug\" flag to view the output of AM-updater scripts. Add the \"--launcher\" flag to try to update only local AppImages integrated with the \"--launcher\" option (see \"--launcher\").
  1223. ${Gold}version, -v\033[0m
  1224. ${LightBlue}$AMCLI -v\033[0m
  1225. Description: Shows the version.
  1226. ${Gold}--devmode-disable\033[0m
  1227. ${LightBlue}$AMCLI --devmode-disable\033[0m
  1228. Description: Undo \"--devmode-enable\" (see below).
  1229. ${Gold}--devmode-enable\033[0m
  1230. ${LightBlue}$AMCLI --devmode-enable\033[0m
  1231. Description: Use the development branch (at your own risk).
  1232. ${Gold}--disable-notifications\033[0m
  1233. ${LightBlue}$AMCLI --disable-notifications\033[0m
  1234. Description: Disable notifications during apps update.
  1235. ${Gold}--disable-sandbox\033[0m
  1236. ${LightBlue}$AMCLI --disable-sandbox {PROGRAM}\033[0m
  1237. Description: Disable the sandbox for the selected app.
  1238. ${Gold}--enable-notifications\033[0m
  1239. ${LightBlue}$AMCLI --enable-notifications\033[0m
  1240. Description: Enable notifications during apps update (nulls \"--disable-notifications\").
  1241. ${Gold}--force-latest\033[0m
  1242. ${LightBlue}$AMCLI --force-latest {PROGRAM}\033[0m
  1243. Description: Downgrades an installed app from pre-release to \"latest\".
  1244. ${Gold}--launcher\033[0m
  1245. ${LightBlue}$AMCLI --launcher /path/to/\${APPIMAGE}\033[0m
  1246. Description: Drag/drop one or more AppImages in the terminal and embed them in the apps menu and customize a command to use from the CLI.
  1247. NOTE that \"--launcher\" can be used as a flag in \"-u\" to try to update the integrated AppImages (see \"-u\"). This works only if \"appimageupdatetool\" is installed and delta updates are supported. This flag does not work miracles, I strongly suggest to use options \"-ia\" and \"-e\" instead.
  1248. ${Gold}--system\033[0m
  1249. ${LightBlue}am --system\033[0m
  1250. ${Gold}--user\033[0m
  1251. ${LightBlue}am --user\033[0m
  1252. Description: Made \"AM\" run in \"AppMan Mode\", locally, useful for unprivileged users. This option only works with \"AM\".
  1253. The \"--user\" option can also be used just as a flag for installation options. For example:
  1254. - Use it to install applications locally, option \"-i\" or \"install\":
  1255. ${LightBlue}am -i --user {PROGRAM}\033[0m
  1256. - Also suboptions of \"-i\" can work with this flag:
  1257. ${LightBlue}am -i --user --debug {PROGRAM}\033[0m
  1258. ${LightBlue}am -i --user --force-latest {PROGRAM}
  1259. ${LightBlue}am -i --user --icons {PROGRAM}
  1260. ${LightBlue}am -i --user --debug --force-latest {PROGRAM}
  1261. ${LightBlue}am -i --user --debug --force-latest --icons {PROGRAM}\033[0m
  1262. - Same for AppImages only, option \"-ia\" or \"install-appimage\":
  1263. ${LightBlue}am -ia --user {PROGRAM}\033[0m
  1264. ${LightBlue}am -ia --user --debug {PROGRAM}
  1265. ${LightBlue}am -ia --user --force-latest {PROGRAM}
  1266. ${LightBlue}am -ia --user --icons {PROGRAM}
  1267. ${LightBlue}am -ia --user --debug --force-latest {PROGRAM}\033[0m
  1268. ${LightBlue}am -ia --user --debug --force-latest --icons {PROGRAM}\033[0m
  1269. - External AppImages can be installed like this as well, option \"-e\" or \"extra\":
  1270. ${LightBlue}am -e --user user/project {APPNAME}\033[0m
  1271. ${LightBlue}am -e --user user/project {APPNAME} {KEYWORD}\033[0m
  1272. NOTE, \"AM\" 9 or higher is also able to, update and manage apps locally, by default, and without having to switch to \"AppMan Mode\".
  1273. Description: Switch \"AM\" back to \"AM\" from \"AppMan Mode\" (see \"--user\").
  1274. $DIVIDING_LINE
  1275. THIRD-PARTY FLAGS: $third_party_flags_message
  1276. $DIVIDING_LINE
  1277. SITES:
  1278. https://github.com/ivan-hc/AM
  1279. https://portable-linux-apps.github.io
  1280. \n" | sed 's/^ //g' | _fit | less -Ir
  1281. }
  1282. if [ -t 1 ]; then _use_help; else _use_help | sed -e 's/\x1b\[[0-9;]*m//g'; fi
  1283. ;;
  1284. *)
  1285. exec "$AMCLIPATH"
  1286. ;;
  1287. esac
  1288. # vim:tabstop=4:shiftwidth=4:expandtab