#!/bin/bash ASP_VERSION=@ASP_VERSION@ ARCH_GIT_REPOS=(packages64 community64 packages32) OPT_ARCH=$(uname -m) OPT_FORCE=0 OPT_UPSTREAM=0 : "${ASPROOT:=${XDG_CACHE_HOME:-$HOME/.cache}/asp32}" : "${ASPCACHE:=$ASPROOT/cache}" m4_include(util.inc.sh) m4_include(remote.inc.sh) m4_include(package.inc.sh) m4_include(archweb.inc.sh) usage() { cat< max )); then log_fatal '%s expects at most %d args, got %d' "${FUNCNAME[1]#action__}" "$max" "$argc" elif (( argc < min )); then log_fatal '%s expects at least %d args, got %d' "${FUNCNAME[1]#action__}" "$min" "$argc" fi } version() { printf 'asp %s\n' "$ASP_VERSION" } update_all() { local r for r in "${ARCH_GIT_REPOS[@]}"; do log_info "updating remote '%s'" "$r" remote_update "$r" done } update_local_branches() { local r=0 while read -r branchname; do git branch -qf "$branchname" "refs/remotes/$branchname" || r=1 done < <(git branch --no-color) return "$r" } update_remote_branches() { local refspecs=() remote pkgname declare -A refspec_map if (( $# == 0 )); then update_all return fi # map packages to remotes for pkgname; do package_init -n "$pkgname" remote || return 1 refspec_map["$remote"]+=" packages/$pkgname" done # update each remote all at once for remote in "${!refspec_map[@]}"; do read -ra refspecs <<<"${refspec_map["$remote"]}" remote_update_refs "$remote" "${refspecs[@]}" done } update_packages() { update_remote_branches "$@" && update_local_branches } initialize() { local remote umask 0022 export GIT_DIR=$ASPROOT/.git if [[ ! -f $ASPROOT/.asp ]]; then git init -q "$ASPROOT" || return 1 for remote in "${ARCH_GIT_REPOS[@]}"; do if [[ "${remote}" = *64 ]]; then git remote add "$remote" "https://git.archlinux.org/svntogit/${remote%64}.git" || return 1 elif [[ "${remote}" = *32 ]]; then git remote add "$remote" "https://git.archlinux32.org/${remote%32}" || return 1 fi done touch "$ASPROOT/.asp" || return 1 fi if [[ ! -d $ASPCACHE ]]; then mkdir -p "$ASPCACHE" || return 1 fi return 0 } dump_packages() { local remote refspecs dumpfn case $1 in all) dumpfn=remote_get_all_refs ;; local) dumpfn=remote_get_tracked_refs ;; *) log_fatal 'BUG: invalid dump type: "%s"' "$1" ;; esac for remote in "${ARCH_GIT_REPOS[@]}"; do "$dumpfn" "$remote" refspecs if [[ $refspecs ]]; then printf '%s\n' "${refspecs[@]##*/}" fi done | sort } list_local() { dump_packages 'local' } list_all() { dump_packages 'all' } shortlog() { package_log "$@" "${FUNCNAME[0]}" } log() { package_log "$@" "${FUNCNAME[0]}" } difflog() { package_log "$@" "${FUNCNAME[0]}" } gc() { git gc --prune=all } untrack() { local pkgname=$1 remote package_init -n "$pkgname" remote || return 1 remote_untrack "$remote" "$pkgname" package_untrack "$pkgname" "$remote" } disk_usage() { local usage read -r usage _ < <(du -sh "$ASPROOT") log_info 'Using %s on disk.' "$usage" } action__checkout() { __require_argc 1- $# map package_checkout "$@" } action__difflog() { __require_argc 1 $# difflog "$1" } action__disk-usage() { __require_argc 0 $# disk_usage } action__export() { __require_argc 1- $# map package_export "$@" } action__gc() { __require_argc 0 $# gc } action__help() { __require_argc 0 $# usage } action__list-all() { __require_argc 0 $# list_all } action__list-arches() { __require_argc 1- $# map package_get_arches "$@" } action__list-local() { __require_argc 0 $# list_local } action__list-repos() { __require_argc 1- $# map package_get_repos "$@" } action__log() { __require_argc 1 $# log "$1" } action__shortlog() { __require_argc 1 $# shortlog "$1" } action__show() { __require_argc 1-2 $# package_show_file "$@" } action__untrack() { __require_argc 1- $# map untrack "$@" } action__update() { update_packages "$@" } action__ls-files() { __require_argc 1 $# package_list_files "$1" } action__set-git-protocol() { __require_argc 1 $# case $1 in git|http|https) ;; *) log_fatal 'invalid protocol: %s' "$1" ;; esac for remote in "${ARCH_GIT_REPOS[@]}"; do if [[ "${remote}" = *64 ]]; then git remote set-url "$remote" "$1://git.archlinux.org/svntogit/${remote%64}.git" elif [[ "${remote}" = *32 ]]; then git remote set-url "$remote" "$1://git.archlinux32.org/${remote%32}" fi done } dispatch_action() { local candidates [[ $1 ]] || log_fatal 'no action specified (use -h for help)' # exact match if declare -F "action__$1" &>/dev/null; then "action__$1" "${@:2}" return fi # prefix match mapfile -t candidates < <(compgen -A function "action__$1") case ${#candidates[*]} in 0) log_fatal 'unknown action: %s' "$1" ;; 1) "${candidates[0]}" "${@:2}" return ;; *) { printf "error: verb '%s' is ambiguous; possibilities:" "$1" printf " '%s'" "${candidates[@]#action__}" echo } >&2 return 1 ;; esac } initialize || log_fatal 'failed to initialize asp repository in %s' "$ASPROOT" while getopts ':a:fhuV' flag; do case $flag in a) OPT_ARCH=$OPTARG ;; f) OPT_FORCE=1 ;; h) usage exit 0 ;; u) OPT_UPSTREAM=1 ;; V) version exit 0 ;; \?) log_fatal "invalid option -- '%s'" "$OPTARG" ;; :) log_fatal "option '-%s' requires an argument" "$OPTARG" ;; esac done shift $(( OPTIND - 1 )) dispatch_action "$@"