PageRenderTime 49ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/aurget/aurget

https://bitbucket.org/kaendfinger/aur-mirror
#! | 929 lines | 710 code | 219 blank | 0 comment | 0 complexity | 5145b2c0f43483ec0ccc5beb51d7759d MD5 | raw file
Possible License(s): LGPL-2.0, Unlicense, AGPL-1.0, BitTorrent-1.0, EPL-1.0, GPL-3.0, BSD-3-Clause, GPL-2.0, MIT, CC-BY-SA-3.0, BSD-2-Clause, MPL-2.0, BSD-3-Clause-No-Nuclear-License-2014, JSON, AGPL-3.0, MPL-2.0-no-copyleft-exception, IPL-1.0, LGPL-2.1, ISC, CC-BY-3.0, WTFPL, 0BSD, CC0-1.0, LGPL-3.0, Cube, Apache-2.0
  1. #!/bin/bash
  2. #
  3. # pbrisbin 2010
  4. #
  5. # aurget: A simple pacman-like interface to the AUR
  6. #
  7. # http://pbrisbin.com/posts/aurget/
  8. #
  9. ###
  10. # script info {{{
  11. SCRIPT_NAME='Aurget'
  12. SCRIPT_DESCRIPTION='A simple pacman-like interface to the AUR'
  13. SCRIPT_AUTHOR='Patrick Brisbin <pbrisbin@gmail.com>'
  14. SCRIPT_VERSION='3.4.2'
  15. SCRIPT_DATE='11/8/2012'
  16. # }}}
  17. # script utilities {{{
  18. display() { echo -e "${colorB}:: ${colorW}$*${nocolor}"; }
  19. warn() { echo -e "${colorY}warning: ${nocolor}$*" >&2; }
  20. errorout() {
  21. echo -e "${colorR}error: ${nocolor}$*" >&2
  22. [[ -d "$tmpdir" ]] && rm -r "$tmpdir"
  23. exit 1
  24. }
  25. dieonlock() {
  26. cat << EOF
  27. Lock file found at $lock_file.
  28. Another aurget process is currently running. Please wait until it has
  29. finished.
  30. EOF
  31. exit 1
  32. }
  33. builderror() {
  34. local pkg="$1" src="$2" dep="$3" msg
  35. msg="notice: $pkg failed while building, remove source files ($src)"
  36. # $src must be nonzero so we don't attempt to rm -rf /*
  37. prompt "$msg" && [[ -n "$src" ]] && rm -rf "$src/"*
  38. # if it's a dep we need to errorout entirely
  39. if (($dep == 1)); then
  40. errorout "dependency package $pkg failed to build. unable to continue."
  41. # otherwise, warn but continue
  42. else
  43. warn "package $pkg failed to build and won't be installed."
  44. fi
  45. }
  46. # prompt and return based on choice
  47. prompt() {
  48. local a
  49. echo -en "$*? [Y/n] "
  50. if $noconfirm; then
  51. echo 'Y'
  52. return 0
  53. else
  54. read a
  55. fi
  56. case "${a:-y}" in
  57. y|Y) return 0 ;;
  58. q|Q) clean_exit 1 ;;
  59. *) return 1 ;;
  60. esac
  61. }
  62. # uses eval to process --option=value type arguments
  63. runtime_flag() { eval ${1/--/}; }
  64. # check for development
  65. is_devel() { echo "$1" | grep -q -- "$development_regex"; }
  66. # clear our temp dir
  67. clear_temp() {
  68. [[ -d "$tmpdir" ]] && rm -r "$tmpdir"
  69. mkdir -p "$tmpdir"
  70. }
  71. # }}}
  72. # message {{{
  73. message() {
  74. cat << EOF
  75. usage: aurget [ -v | -h | -S* [ --options ] [ -- ] <arguments> ]
  76. options:
  77. -S <package> process <package> using your default sync_mode
  78. -Sd <package> download <package>
  79. -Sb <package> download and build <package>
  80. -Sy <package> download, build, and install <package>
  81. -Su process available upgrades using your default sync_mode
  82. -Sdu download available upgrades
  83. -Sbu download and build available upgrades
  84. -Syu download, build, and install available upgrades
  85. -Ss <term> search aur for <term>
  86. -Ssq <term> search aur for <term>, print only package names
  87. -Sp <package> print the PKGBUILD for <package>
  88. -Si <package> print extended info for <package>
  89. --rebuild always rebuild (ignore your cache)
  90. --devel only affects -Su, add all development packages
  91. --deps resolve dependencies
  92. --nodeps don't resolve dependencies
  93. --edit prompt to edit all pkgbuilds
  94. --noedit don't prompt to edit any pkgbuilds
  95. --discard discard source files after building
  96. --nodiscard don't discard source files after building
  97. --nocolor disable colorized output
  98. --noconfirm auto-answer y to all prompts
  99. --ignore '<package> <package> <...>'
  100. add additional packages to be ignored
  101. --mopt '-opt -opt ...'
  102. add additional options to the build command
  103. --popt '-opt -opt ...'
  104. add additional options to the install command
  105. -v, --version display version info
  106. -h, --help display this
  107. --option=value set config <option> as <value> for this run only
  108. EOF
  109. clean_exit 1
  110. }
  111. # }}}
  112. # version_info {{{
  113. version_info() {
  114. cat << EOF
  115. $SCRIPT_NAME: $SCRIPT_DESCRIPTION
  116. author: $SCRIPT_AUTHOR
  117. version: $SCRIPT_VERSION
  118. last update: $SCRIPT_DATE
  119. EOF
  120. clean_exit
  121. }
  122. # }}}
  123. # prompt_to_edit {{{
  124. prompt_to_edit() {
  125. local pkgbuild reason
  126. pkgbuild="$1"; shift
  127. reason="${*:-sourcing for deps}"
  128. [[ ! -f "$pkgbuild" ]] && errorout "$Name: no PKGBUILD found"
  129. # default is to prompt
  130. case "${edit_pkgbuilds:-prompt}" in
  131. never) return 0 ;;
  132. prompt) prompt "Edit PKGBUILD before $reason" || return 0 ;;
  133. esac
  134. $editor "$pkgbuild" || errorout 'problem editing PKGBUILD'
  135. prompt "Continue $reason"
  136. }
  137. # }}}
  138. # source_pkgbuild {{{
  139. source_pkgbuild() {
  140. local pkgbuild="$1"
  141. [[ ! -f "$pkgbuild" ]] && errorout 'pkgbuild not found'
  142. # source pkgbuild variables
  143. source <(awk '/^build.*(.*)|^function.*build.*(.*)/{exit};1' "$pkgbuild")
  144. # this should always be defined by makepkg.conf. apparently it can
  145. # also be overridden in PKGBUILDs. only at this point will we default
  146. # it if not set.
  147. PKGEXT="${PKGEXT:-.pkg.tar.gz}"
  148. }
  149. # }}}
  150. # try_discard {{{
  151. try_discard() {
  152. # we never discard sources
  153. $discard_sources || return
  154. # we keep devels and this is a devel package
  155. $dont_discard_devels && is_devel ${1##*/} && return
  156. # use find -delete incase the built package is still in the directory
  157. #display "Discarding sources..."
  158. #find "$1" -depth ! -name "${1##*/}*$PKGEXT" -delete 2>/dev/null
  159. # turns out, the built package is _always_ in the directory
  160. display 'Discarding sources...'
  161. rm -rf "$1"
  162. }
  163. # }}}
  164. # print_pkgbuild {{{
  165. print_pkgbuild() {
  166. local multiple=false ret=0 url
  167. # no args returns 1
  168. ((${#args[@]} == 0)) && clean_exit 1
  169. # more than one means print names and whitespace
  170. ((${#args[@]} > 1)) && multiple=true
  171. for name in "${args[@]}"; do
  172. $multiple && display "$name/PKGBUILD ==>"
  173. url="$aur_pkgs/$(url_encode "${name:0:2}/$name")/PKGBUILD"
  174. curl -fsS "$url" 2>/dev/null || ret=1
  175. $multiple && echo
  176. done
  177. # finally, exit
  178. clean_exit $ret
  179. }
  180. # }}}
  181. # url_encode {{{
  182. url_encode() {
  183. local string="$1" awkscript
  184. awkscript='
  185. $1 == "20" { printf("%s", "+"); next } # space becomes plus
  186. $1 ~ /0[adAD]/ { next } # strip newlines
  187. $2 ~ /^[a-zA-Z0-9.*()\/-]$/ { printf("%s", $2); next } # pass through what we can
  188. { printf("%%%s", $1) } # take hex value of everything else
  189. '
  190. # 6/19/2010 + thanks to Irm for this bit of magic
  191. hexdump -v -e '1/1 "%02x\t"' -e '1/1 "%_c\n"' <<< "$string" | LANG=C awk "$awkscript"
  192. }
  193. # }}}
  194. # search_aur {{{
  195. search_aur() {
  196. # just print pkgbuild?
  197. [[ "$search_mode" = 'print' ]] && print_pkgbuild "${args[@]}"
  198. # continue with other searches
  199. local awkscript results term Name Version Description URL URLPath OutOfDate
  200. term="${args[*]}"
  201. awkscript='
  202. function unstring(str) {
  203. sub(/[^:]+:/, "", str)
  204. gsub(/\\\"/, "\"", str)
  205. gsub(/"$/, "", str)
  206. return substr(str, 2, length(str))
  207. }
  208. /Name":/ { printf "%s", unstring($0) }
  209. /Version":/ { printf "|%s", unstring($0) }
  210. /Description":/ { printf "|%s", unstring($0) }
  211. /URL":/ { printf "|%s", unstring($0) }
  212. /OutOfDate":/ { printf "|%s", unstring($0) }
  213. /URLPath":/ { printf "|%s\n", unstring($0) }
  214. '
  215. # parse JSON data
  216. results="$(curl -fsS "${aur_srch}$(url_encode "$term")" | awk -F '[^\\\\]"' -v RS='{"|,"|"}' "$awkscript")"
  217. [[ -z "$results" ]] && clean_exit 1
  218. while IFS='|' read -r Name Version Description URL OutOfDate URLPath; do
  219. [[ -z "$Name" ]] && continue
  220. [[ "$search_mode" = 'info' ]] && [[ "$Name" != "$term" ]] && continue
  221. # FYI: http://old.nabble.com/echo-interrupted-by-SIGCHLD-from-a-dying-coprocess-td28028050.html
  222. case "$search_mode" in
  223. quiet) echo "$Name" 2>/dev/null ;;
  224. info) [[ "$OutOfDate" =~ ^(1|OutOfDate)$ ]] && outofdate="${colorR}Yes${nocolor}" || outofdate='No'
  225. echo -e "${colorW}Repository \t: ${colorM}aur${nocolor}" 2>/dev/null
  226. echo -e "${colorW}Name \t\t: $Name${nocolor}" 2>/dev/null
  227. echo -e "${colorW}Version \t: ${colorG}$Version${nocolor}" 2>/dev/null
  228. echo -e "${colorW}URL \t\t: ${colorC}${URL//\\\///}${nocolor}" 2>/dev/null
  229. echo -e "${colorW}Out of date \t: ${nocolor}$outofdate" 2>/dev/null
  230. echo -e "${colorW}Description \t: ${nocolor}${Description//\\\///}\n" 2>/dev/null ;;
  231. search) [[ "$OutOfDate" =~ ^(1|OutOfDate)$ ]] && outofdate="${colorR}[out of date]${nocolor}" || outofdate=''
  232. echo -en "${colorM}aur/${colorW}$Name" 2>/dev/null
  233. echo -en " ${colorG}$Version${nocolor}" 2>/dev/null
  234. echo -e " $outofdate" 2>/dev/null
  235. echo -e " ${Description//\\\///}" 2>/dev/null ;;
  236. *) errorout 'invalid search_mode'
  237. esac
  238. done < <(sort <<< "$results")
  239. }
  240. # }}}
  241. # upgrade {{{
  242. upgrade() {
  243. args=()
  244. display 'Starting AUR upgrade...'
  245. while read -r name vers; do
  246. if is_devel $name; then
  247. $devels && args+=("$name")
  248. else
  249. # available version
  250. versN="$(curl -fsS "${aur_info}$(url_encode "$name")" | sed -e '/.*"Version":"\([^"]*\)".*/!d; s//\1/g')"
  251. [[ -z "$versN" ]] && continue
  252. # check against ignores
  253. if echo " $ignore_packages " | grep -Fq -- " $name "; then
  254. warn "$name: ignoring package upgrade ($vers => $versN)"
  255. continue
  256. fi
  257. # use vercmp
  258. check=$(vercmp "$vers" "$versN")
  259. [[ $check -gt 0 ]] && warn "$name: local ($vers) is newer than aur ($versN)"
  260. [[ $check -lt 0 ]] && args+=("$name")
  261. fi
  262. done < <(pacman -Qm)
  263. ((${#args[@]} > 0)) && setup_targets || echo ' there is nothing to do'
  264. }
  265. # }}}
  266. # find_pkg {{{
  267. find_pkg() {
  268. local name="$1" version="$2"
  269. # try full path
  270. pkg="$package_directory/$name-$version-${CARCH}$PKGEXT"
  271. if [[ ! -f "$pkg" ]]; then
  272. # try any packages
  273. pkg="$package_directory/$name-$version-any$PKGEXT"
  274. fi
  275. if [[ ! -f "$pkg" ]]; then
  276. # no result
  277. pkg=''
  278. fi
  279. echo "$pkg"
  280. }
  281. # }}}
  282. # download_tarball {{{
  283. download_tarball() {
  284. local name="$1" url="$2" target
  285. display 'Retrieving source tarball from AUR...'
  286. target="$build_directory/$name.tar.gz"
  287. url="${aur}$(url_encode "${url//\\\///}")"
  288. curl -f#o "$target" "$url" || errorout 'failed to retrieve aur sources'
  289. # JSON often reports a url, it'll download but won't be a tarball
  290. if ! grep -Fq 'gzip' <(file "$target"); then
  291. warn "$name: not a valid tarball, trying alternate url..."
  292. curl -f#o "$target" "$aur_pkgs/$(url_encode "${name:0:2}/$name/$name").tar.gz" || errorout 'failed to retrieve aur sources'
  293. fi
  294. # stop here if that's how we roll
  295. [[ "$sync_mode" = 'download' ]] && clean_exit
  296. # extract
  297. display 'Extracting source tarball...'
  298. (cd "$build_directory" && tar xvzf "$target" &>/dev/null) || errorout "$build_directory/$name.tar.gz: failed unpacking the tarball"
  299. # remove the tarball post extract
  300. rm "$target"
  301. # specify sub-sourcedir
  302. _srcdir="$build_directory/$name"
  303. }
  304. # }}}
  305. # build_package {{{
  306. build_package() {
  307. local dep="$1" pkgbuild
  308. display 'Building package...'
  309. pushd "$_srcdir" &>/dev/null || errorout 'failed to change directory'
  310. if [[ -f "/etc/customizepkg.d/$Name" ]]; then
  311. display 'Calling customizepkg...'
  312. customizepkg --modify || warn 'customizepkg had a problem'
  313. fi
  314. if ! prompt_to_edit 'PKGBUILD' "building $Name"; then
  315. popd &>/dev/null
  316. try_discard "$_srcdir"
  317. continue
  318. fi
  319. # if we fail building, errorout on dep or just return 1 on
  320. # non-dep
  321. if ! PKGDEST="$package_directory" $makepkg $mopts; then
  322. builderror "$Name" "$_srcdir" "$dep"
  323. return 1
  324. fi
  325. popd &>/dev/null
  326. # this may or may not discard things
  327. try_discard "$_srcdir"
  328. # stop here if that's how we roll
  329. [[ "$sync_mode" = 'build' ]] && clean_exit
  330. # look for package and any package by name
  331. pkg="$(find_pkg "$Name" "$Version")"
  332. # last resort
  333. if [[ -z "$pkg" ]]; then
  334. # don't build two dev packages of the same name within the same
  335. # minute; this is the only way to find git/svn/etc packages' exact
  336. # filenames
  337. pkg="$(find "$package_directory" -ctime -1 -name "$Name-*$PKGEXT" -print -quit)"
  338. fi
  339. return 0
  340. }
  341. # }}}
  342. # install_package {{{
  343. install_package() {
  344. local pkg="$1" dep="$2"
  345. display 'Installing package...'
  346. if [[ -f "$pkg" ]]; then
  347. if (($dep == 1)); then
  348. $pacman --asdep $popts "$pkg" || errorout 'failed installing the package'
  349. else
  350. $pacman $popts "$pkg" || errorout 'failed installing the package'
  351. fi
  352. else
  353. errorout "$pkg: package not found"
  354. fi
  355. }
  356. # }}}
  357. # source_for_deps {{{
  358. source_for_deps() {
  359. local pkgbuild="$tmpdir/${1}_PKGBUILD"
  360. # we've already checked this
  361. [[ -f "$pkgbuild" ]] && continue
  362. # if this errors, we know it's not aur-available so return 1
  363. if ! curl -fso "$pkgbuild" "$aur/packages/$(url_encode "${1:0:2}/$1")/PKGBUILD"; then
  364. touch "$pkgbuild"
  365. return 1
  366. fi
  367. prompt_to_edit "$pkgbuild" "sourcing $1 for dependencies" && source_pkgbuild "$pkgbuild" || continue
  368. }
  369. # }}}
  370. # dep_check {{{
  371. dep_check() {
  372. echo 'resolving dependencies...'
  373. local dep all_deps pac_deps
  374. all_deps=(); aur_deps=(); pac_deps=(); mk_deps=()
  375. while true; do
  376. n=${#all_deps[@]}
  377. for name in "${args[@]}" "${all_deps[@]}"; do
  378. # keep args out of deps so error messages are more sane
  379. if ! source_for_deps "$name"; then
  380. # assume it's a pacman dep for now
  381. grep -Fq -- " $name " <<< " ${args[@]} " || pac_deps+=("$name")
  382. else
  383. grep -Fq -- " $name " <<< " ${args[@]} " || aur_deps=("$name" "${aur_deps[@]}")
  384. # filter satasfied deps, clear versioning
  385. depends=($(pacman -T -- ${depends[@]} ${makedepends[@]}))
  386. depends=("${depends[@]%>*}")
  387. depends=("${depends[@]%=*}")
  388. depends=("${depends[@]%<*}")
  389. # store make depends for later removal
  390. mk_deps+=("${makedepends[@]}")
  391. # track unsatisfied deps
  392. ((${#depends[@]} > 0)) && all_deps+=("${depends[@]}")
  393. fi
  394. done
  395. # if we found no more deps this round, we can stop
  396. ((${#all_deps[@]} == $n)) && break
  397. done
  398. if ((${#pac_deps[@]} > 0)); then
  399. # check a list quickly for availability
  400. while IFS=\' read -r _ dep _; do
  401. # check only the error cases as a possible provides
  402. pacman -Ssq -- "^$dep$" &>/dev/null || errorout "$dep: dependency cannot be met."
  403. done < <(pacman -Si -- "${pac_deps[@]}" 2>&1 >/dev/null)
  404. # sort and unique
  405. pac_deps=($(sort -u <(printf '%s\n' "${pac_deps[@]}")))
  406. echo; warn "the following (${#pac_deps[@]}) packages will be installed by pacman: ${pac_deps[@]}"; echo
  407. fi
  408. }
  409. # }}}
  410. # add_targets_to_list {{{
  411. add_targets_to_list() {
  412. local name dep Name Version URLPath
  413. # are we adding these to be installed --asdeps?
  414. dep="$1"; shift
  415. for name in "$@"; do
  416. if grep -Fq -- " $name " <<< " $ignore_packages "; then
  417. if ! prompt "$name is in ignore_packages. Install anyway"; then
  418. warn "skipping target: $name"
  419. continue
  420. fi
  421. fi
  422. # fetch JSON
  423. read -r Name Version URLPath < <(curl -s "${aur_info}$(url_encode "$name")" | sed -e '/.*"Name":"\([^"]*\)".*"Version":"\([^"]*\)".*"URLPath":"\([^"]*\)".*/!d; s//\1 \2 \3/g')
  424. [[ -z "$Name" ]] && errorout "$name: package not found in AUR."
  425. # is it already up to date?
  426. grep -Fqx -- "$Name $Version" "$tmpdir/installed.lst" && warn "$Name-$Version is up to date -- reinstalling"
  427. # add non-dupes to list of targets
  428. if ! grep -Fx -- " $Name " <<< " ${list_names[@]} "; then
  429. list_names+=("$Name")
  430. list_versions+=("$Version")
  431. list_urls+=("$URLPath")
  432. list_deps+=("$dep")
  433. fi
  434. done
  435. }
  436. # }}}
  437. # setup_targets {{{
  438. setup_targets() {
  439. ((${#args[@]} == 0)) && errorout 'no targets specified (use -h for help)'
  440. $resolve_dependencies && dep_check
  441. list_names=(); list_versions=(); list_urls=(); list_deps=()
  442. pacman -Qm > "$tmpdir/installed.lst"
  443. echo 'searching AUR...'
  444. add_targets_to_list 1 "${aur_deps[@]}"
  445. add_targets_to_list 0 "${args[@]}"
  446. if ((${#list_names[@]} > 0)); then
  447. echo -en "\n${colorY}Targets (${#list_names[@]}):${nocolor} "
  448. for ((i=0; i<${#list_names[@]}; i++)); do
  449. echo -n "${list_names[i]}-${list_versions[i]} "
  450. done
  451. prompt "\n\nProceed with installation" || clean_exit
  452. process_targets
  453. else
  454. errorout 'no targets specified (use -h for help)'
  455. fi
  456. }
  457. # }}}
  458. # process_targets {{{
  459. process_targets() {
  460. Name=
  461. Version=
  462. URLPath=
  463. dep=
  464. pkg=
  465. for ((i=0; i<${#list_names[@]}; i++)); do
  466. Name="${list_names[i]}"
  467. Version="${list_versions[i]}"
  468. URLPath="${list_urls[i]}"
  469. dep="${list_deps[i]}"
  470. # check in the cache
  471. pkg="$(find_pkg "$Name" "$Version")"
  472. if ! $rebuild && [[ -n "$pkg" ]] && [[ "$sync_mode" = 'install' ]] && ! is_devel "$pkg"; then
  473. # use cached package
  474. display "Installing cached $pkg..."
  475. else
  476. # download from aur, sets $pkg variable
  477. download_tarball "$Name" "$URLPath"
  478. build_package "$dep" || continue
  479. fi
  480. install_package "$pkg" "$dep"
  481. done
  482. # remove make depends
  483. if $remove_makedepends && ((${#mk_deps[@]} > 0)); then
  484. display 'Removing make depends...'
  485. for mk_dep in ${mk_deps[@]}; do
  486. pacman --noconfirm -R $mk_dep || warn "unable to remove makedepend $mk_dep"
  487. done
  488. fi
  489. }
  490. # }}}
  491. # set_defaults {{{
  492. set_defaults() {
  493. # just true/false and non-config options
  494. discard_sources=true
  495. dont_discard_devels=true
  496. resolve_dependencies=false
  497. remove_makedepends=false
  498. devels=false
  499. noconfirm=false
  500. rebuild=false
  501. asroot=false
  502. search_mode='search'
  503. # default to no color
  504. nocolor=''
  505. colorW=''
  506. colorC=''
  507. colorB=''
  508. colorR=''
  509. colorG=''
  510. colorY=''
  511. colorM=''
  512. }
  513. # }}}
  514. # source_config {{{
  515. source_config() {
  516. local config _sourced=false
  517. # global config file is always sourced
  518. config='/etc/aurgetrc'
  519. if [[ -r "$config" ]]; then
  520. . "$config" || errorout "$config: invalid configuration"
  521. _sourced=true
  522. fi
  523. # try xdg directory first
  524. config="${XDG_CONFIG_HOME:-$HOME/.config}/aurgetrc"
  525. if [[ -r "$config" ]]; then
  526. . "$config" || errorout "$config: invalid configuration"
  527. _sourced=true
  528. else
  529. # use home dot-file
  530. config="$HOME/.aurgetrc"
  531. if [[ -r "$config" ]]; then
  532. . "$config" || errorout "$config: invalid configuration"
  533. _sourced=true
  534. fi
  535. fi
  536. if ! $_sourced; then
  537. warn 'no config found, this could get weird...'
  538. fi
  539. }
  540. # }}}
  541. # source_makepkg {{{
  542. source_makepkg() {
  543. local IFS=':' conf confs _PKGDEST
  544. # todo: preserve a PKGDEST environment variable?
  545. # source these in order
  546. confs="/etc/makepkg.conf:$HOME/.makepkg.conf"
  547. for conf in $confs; do
  548. [[ -r "$conf" ]] && . "$conf"
  549. done
  550. # set package_directory
  551. package_directory="${package_directory:-$PKGDEST}"
  552. package_directory="${package_directory:-$PWD}"
  553. [[ -d "$package_directory" ]] || mkdir -p "$package_directory"
  554. # set build_directory
  555. # don't use SRCDEST, do check deprecated source_directory
  556. #build_directory="${source_directory:-$SRCDEST}"
  557. build_directory="${build_directory:-$source_directory}"
  558. build_directory="${build_directory:-$PWD}"
  559. [[ -d "$build_directory" ]] || mkdir -p "$build_directory"
  560. }
  561. # }}}
  562. # parse_options {{{
  563. parse_options() {
  564. local _opmode='' donocolor=false
  565. # global var, used by main
  566. opmode=''
  567. while [[ -n "$1" ]]; do
  568. [[ -n "$opmode" ]] && _opmode="$opmode"
  569. case "$1" in
  570. -h|--help) message ;;
  571. -v|--version) version_info ;;
  572. --) break ;;
  573. -S) opmode='install' ;;
  574. -Sy) opmode='install'; sync_mode='install' ;;
  575. -Sb) opmode='install'; sync_mode='build' ;;
  576. -Sd) opmode='install'; sync_mode='download' ;;
  577. -Su) opmode='upgrade' ;;
  578. -Syu|-Suy) opmode='upgrade'; sync_mode='install' ;;
  579. -Sbu|-Sub) opmode='upgrade'; sync_mode='build' ;;
  580. -Sdu|-Sud) opmode='upgrade'; sync_mode='download' ;;
  581. -Ss) opmode='search' ; search_mode='search' ;;
  582. -Ssq|-Sqs) opmode='search' ; search_mode='quiet' ;;
  583. -Si|-Ssi|-Sis) opmode='search' ; search_mode='info' ;;
  584. -Sp|-Ssp|-Sps) opmode='search' ; search_mode='print' ;;
  585. --ignore) shift; ignore_packages+=" $1" ;;
  586. --mopt) shift; mopts+=" $1" ;;
  587. --popt) shift; popts+=" $1" ;;
  588. --nocolor) donocolor=true ;;
  589. --noconfirm) noconfirm=true ;;
  590. --rebuild) rebuild=true ;;
  591. --asroot) asroot=true ;;
  592. --devel) devels=true ;;
  593. --deps) resolve_dependencies=true ;;
  594. --nodeps) resolve_dependencies=false ;;
  595. --edit) edit_pkgbuilds='always' ;;
  596. --noedit) edit_pkgbuilds='never' ;;
  597. --discard) discard_sources=true ;;
  598. --nodiscard) discard_sources=false ;;
  599. --*=*) runtime_flag "$1" ;;
  600. -*) message ;;
  601. *) args+=("$1") ;;
  602. esac
  603. shift
  604. # show help if multiple -S* commands are passed
  605. [[ -n "$_opmode" ]] && [[ "$_opmode" != "$opmode" ]] && message
  606. done
  607. # grab possible args after --
  608. [[ $* ]] && args+=("$@")
  609. # verify enums
  610. [[ "$edit_pkgbuilds" =~ ^(always|never|prompt)$ ]] || edit_pkgbuilds='prompt'
  611. [[ "$sync_mode" =~ ^(download|build|install)$ ]] || errorout 'invalid sync mode specified'
  612. [[ "$search_mode" =~ ^(search|info|quiet|print)$ ]] || errorout 'invalid search mode specified'
  613. # no dep checking unless installing
  614. [[ "$sync_mode" != 'install' ]] && resolve_dependencies=false
  615. # (re)set user binaries
  616. pacman="${pacman_command:-sudo pacman -U}"
  617. makepkg="${makepkg_command:-makepkg --noconfirm}"
  618. editor="${pkgbuild_editor:-$EDITOR}"
  619. editor="${editor:-vi}" # a failsafe
  620. # (re)set dev regex, it can't be blank
  621. development_regex=${development_regex:-.*-git$\|.*-hg$\|.*-svn$\|.*-darcs$\|.*-cvs$\|.*-bzr$}
  622. # prevent root unless desired
  623. if [[ $(id -u) == 0 ]]; then
  624. $asroot || errorout 'You must pass --asroot to allow running aurget as root (not recommended).'
  625. # fixes for root
  626. pacman="${pacman/sudo /}"
  627. mopts+=' --asroot'
  628. fi
  629. if $noconfirm; then
  630. # change some things to go along with --noconfirm
  631. grep -Fqw -- '--noconfirm' <<< "$popts" || popts+=' --noconfirm'
  632. grep -Fqw -- '--noconfirm' <<< "$mopts" || mopts+=' --noconfirm'
  633. edit_pkgbuilds='never'
  634. fi
  635. # if resolving deps, tell makepkg so
  636. if $resolve_dependencies; then
  637. grep -Fqw -- '--syncdeps' <<< "$mopts" || mopts+=' --syncdeps'
  638. fi
  639. # thanks falconindy
  640. if $donocolor || [[ ! -t 1 ]]; then
  641. # disable pacman color
  642. pacman="${pacman/pacman-color/pacman}"
  643. # disable makepkg color
  644. grep -Fqw -- '--nocolor' <<< "$mopts" || mopts+=' --nocolor'
  645. # disable aurget color
  646. nocolor=''
  647. colorW=''
  648. colorC=''
  649. colorB=''
  650. colorR=''
  651. colorG=''
  652. colorY=''
  653. colorM=''
  654. fi
  655. }
  656. # }}}
  657. # main {{{
  658. main() {
  659. case "$opmode" in
  660. upgrade) upgrade ;;
  661. install) setup_targets ;;
  662. search) search_aur ;;
  663. *) message ;;
  664. esac
  665. }
  666. # }}}
  667. # clean_exit {{{
  668. clean_exit() {
  669. [[ -d "$tmpdir" ]] && rm -r "$tmpdir"
  670. exit ${1:-0}
  671. }
  672. # }}}
  673. # boot_strap {{{
  674. boot_strap() {
  675. [[ "$1" != 'bootstrap' ]] && return
  676. cat << EOF
  677. Boot-strapping aurget...
  678. Once built, please use pacman to install the package in this
  679. directory.
  680. EOF
  681. clear_temp
  682. set_defaults
  683. args=('aurget')
  684. sync_mode='build'
  685. makepkg='makepkg'
  686. build_directory="$tmpdir/bootstrap"
  687. source_makepkg
  688. setup_targets
  689. }
  690. # }}}
  691. # clean up if we catch signals
  692. trap 'clean_exit 1' TERM HUP QUIT INT
  693. aur='https://aur.archlinux.org'
  694. aur_srch="$aur/rpc.php?type=search&arg="
  695. aur_info="$aur/rpc.php?type=info&arg="
  696. aur_pkgs="$aur/packages"
  697. tmpdir="${TMPDIR:-/tmp}/aurget"
  698. lock_file="$tmpdir/aurget.lock"
  699. boot_strap "$1"
  700. clear_temp
  701. (
  702. flock -n 9 || dieonlock
  703. set_defaults
  704. source_config
  705. source_makepkg
  706. parse_options "$@"
  707. main
  708. ) 9>"$lock_file"
  709. clean_exit
  710. # vim:foldmethod=marker foldmarker={{{,}}}