diff options
-rwxr-xr-x | bin/ct | 104 | ||||
-rwxr-xr-x | include/pkglist | 9 | ||||
-rw-r--r-- | man/5/caretaker.conf.pod | 5 | ||||
-rw-r--r-- | man/7/caretaker.pod | 9 |
4 files changed, 86 insertions, 41 deletions
@@ -16,7 +16,7 @@ setopt extended_glob typeset -a -U triggers -typeset -a CL_OPTIONS +typeset -a PKG_ROOTS CL_OPTIONS c_info=$'\e[0;36m' c_error=$'\e[0;31m' @@ -82,7 +82,14 @@ while [[ $1 == --* ]] { action=$1 ((#)) && shift -[[ -n $PKG_ROOT ]] || die "No PKG_ROOT specified. Please edit your caretaker.conf\n" +if [[ -n $PKG_ROOT ]] { + PKG_ROOTS+=($PKG_ROOT) + unset PKG_ROOT +} + +if (( $#PKG_ROOTS == 0 )) { + die "No PKG_ROOT specified. Please edit your caretaker.conf\n" +} : ${PKG_DIR:="$HOME/packages"} : ${PKGLIST_LOCAL=0} : ${CL_OPTIONS:=--quiet} @@ -139,29 +146,36 @@ if [[ ! -d $PKG_DIR ]] { ## Setup some additional variables related to PKG_ROOT ## -# Protocol -case $PKG_ROOT in - ssh://*) PKG_PROTO='ssh' ;; - git://*) PKG_PROTO='git' ;; - /*) PKG_PROTO='file' ;; - *) die "Error: Unknown protocol in PKG_ROOT '$PKG_ROOT'\n" ;; -esac +function pkgroot_parse { + PKG_ROOT=$1 + # Protocol + case $PKG_ROOT in + ssh://*) PKG_PROTO='ssh' ;; + git://*) PKG_PROTO='git' ;; + /*) PKG_PROTO='file' ;; + *) die "Error: Unknown protocol in PKG_ROOT '$PKG_ROOT'\n" ;; + esac -# user, host, path -if [[ $PKG_PROTO == (git|ssh) ]] { - PKG_HOST=${${PKG_ROOT#"${PKG_PROTO}://"}%%/*} - PKG_PATH=${PKG_ROOT#"${PKG_PROTO}://$PKG_HOST"} - if [[ $PKG_HOST == *@* ]] { - PKG_USER=${PKG_HOST%%@*} - PKG_HOST=${PKG_HOST#*@} - } else { - PKG_USER=$USERNAME + # user, host, path + if [[ $PKG_PROTO == (git|ssh) ]] { + PKG_HOST=${${PKG_ROOT#"${PKG_PROTO}://"}%%/*} + PKG_PATH=${PKG_ROOT#"${PKG_PROTO}://$PKG_HOST"} + if [[ $PKG_HOST == *@* ]] { + PKG_USER=${PKG_HOST%%@*} + PKG_HOST=${PKG_HOST#*@} + } else { + PKG_USER=$USERNAME + } + } elif [[ $PKG_PROTO == 'file' ]] { + PKG_PATH=$PKG_ROOT } -} elif [[ $PKG_PROTO == 'file' ]] { - PKG_PATH=$PKG_ROOT + : ${PKGLIST_PATH:=$PKG_PATH/pkglist} } -: ${PKGLIST_PATH:=$PKG_PATH/pkglist} +function pkgroot_clean { + unset PKG_ROOT PKG_PROTO PKG_HOST PKG_PATH PKG_USER + ((PKGLIST_LOCAL)) || unset PKGLIST_PATH +} if ((DEBUG)) { info "caretaker: running in debug mode. Infos follow:\n" @@ -170,12 +184,16 @@ if ((DEBUG)) { echo " git "${$(git --version)[3]} echo " caretaker "${$(git --git-dir=$PKG_DIR/${${(s:/:)$(readlink $0)}[-3]}/.git/ log -n 1)[2]} echo "--- settings ---" - echo " PKG_ROOT $PKG_ROOT" - echo " PKG_PROTO $PKG_PROTO" - echo " PKG_USER $PKG_USER" - echo " PKG_HOST $PKG_HOST" - echo " PKGLIST_PATH $PKGLIST_PATH" echo " PKGLIST_LOCAL $PKGLIST_LOCAL" + for PKG_ROOT in $PKG_ROOTS; { + pkgroot_parse $PKG_ROOT + echo " PKG_ROOT $PKG_ROOT" + echo " PKG_PROTO $PKG_PROTO" + echo " PKG_USER $PKG_USER" + echo " PKG_HOST $PKG_HOST" + echo " PKGLIST_PATH $PKGLIST_PATH" + pkgroot_clean + } echo " PKG_DIR $PKG_DIR" echo " CL_OPTIONS $CL_OPTIONS" echo " SILENT $SILENT" @@ -257,6 +275,8 @@ function vcs_to_list ( ) function vcs_add ( + pkgroot_parse $(list_get_root $1) + cd $PKG_DIR if [[ $(list_type $1) == git ]] { git clone "$PKG_ROOT/$1" vcs_setup $1 @@ -264,6 +284,7 @@ function vcs_add ( } else { die "$1: Cannot handle repository format '$(list_type $1)'\n" } + pkgroot_clean ) function vcs_log ( @@ -292,7 +313,9 @@ function vcs_pull ( vcs_fix_origin $1 git pull } else { + pkgroot_parse $(list_get_root $1) vcs_branch_is_master $1 && git pull $PKG_ROOT/${PWD:t} master + pkgroot_clean } ) @@ -303,6 +326,7 @@ function vcs_push ( vcs_fix_origin $1 git push } else { + pkgroot_parse $(list_get_root $1) vcs_branch_is_master $1 && git push $PKG_ROOT/${PWD:t} master } ) @@ -315,8 +339,11 @@ function vcs_status ( function vcs_fix_origin ( vcs_setup $1 if [[ ! -r .git/remotes/origin && ! -r .git/refs/remotes/origin/HEAD ]] { - fgrep -q '[remote "origin"]' .git/config || + if ! fgrep -q '[remote "origin"]' .git/config; then + pkgroot_parse $(list_get_root $1) git remote add origin $PKG_ROOT/$1 + pkgroot_clean + fi } ) @@ -343,6 +370,10 @@ function list_incoming { [[ $(list_version_local $1) != $(list_version_remote $1) ]] } +function list_get_root { + echo - ${$(grep "^$1 " $PKG_DIR/.list-remote)[4]} +} + function list_type { echo - ${$(grep "^$1 " $PKG_DIR/.list-remote)[2]} } @@ -352,12 +383,16 @@ function list_type_local { } function list_update_remote { - typeset tmpfile=$(mktemp -t pkglist.XXXXXX) + typeset tmpfile=$(mktemp -t pkglist.XXXXXX) PKG_ROOT typeset -i ret=0 - if [[ $PKGLIST_LOCAL == 1 || $PKG_PROTO == 'file' ]] { - $PKGLIST_PATH $PKG_PATH > $tmpfile - } elif [[ $PKG_PROTO == 'ssh' ]] { - ssh $PKG_USER@$PKG_HOST "$PKGLIST_PATH $PKG_PATH" > $tmpfile + for PKG_ROOT in $PKG_ROOTS; { + pkgroot_parse $PKG_ROOT + if [[ $PKGLIST_LOCAL == 1 || $PKG_PROTO == 'file' ]] { + $PKGLIST_PATH $PKG_PATH $PKG_ROOT >> $tmpfile + } elif [[ $PKG_PROTO == 'ssh' ]] { + ssh $PKG_USER@$PKG_HOST "$PKGLIST_PATH $PKG_PATH $PKG_ROOT" >> $tmpfile + } + pkgroot_clean } if [[ -n $(cat $tmpfile) ]] { cp $tmpfile .list-remote @@ -761,10 +796,12 @@ function pkg_update { function pkg_info { list_is_installed $1 || list_exists $1 || die "No such package: $1\n" - typeset name=$1 + list_exists $1 && pkgroot_parse $(list_get_root $1) + typeset name=$1 package_root=$PKG_ROOT typeset repo_type=$(list_type $1) typeset priority priority_name typeset hooks makefile discription state + pkgroot_clean if [[ -d $1 ]] { cd $1 if [[ -r priority ]] { @@ -798,6 +835,7 @@ function pkg_info { } show_info 'Package' $name + show_info 'Source' $package_root show_info 'State' $state [[ -n $priority ]] && show_info 'Priority' "$priority ($priority_name)" show_info 'Local Version' $(list_version_local $1) diff --git a/include/pkglist b/include/pkglist index 660036b..2182f4b 100755 --- a/include/pkglist +++ b/include/pkglist @@ -8,16 +8,21 @@ if [[ ! -d $1 ]] { exit 1 } +setopt err_exit + # change into package root directory (first argument) cd $1 +shift for i in *(-/); { if [[ -d $i/.git ]] { echo -n "$i git " - echo ${$(git --git-dir=$i/.git log -n 1)[2]} + echo -n ${$(git --git-dir=$i/.git log -n 1)[2]} + echo " $*" } elif [[ -d $i/objects && -d $i/refs ]] { echo -n "$i git " - echo ${$(git --git-dir=$i log -n 1)[2]} + echo -n ${$(git --git-dir=$i log -n 1)[2]} + echo " $*" } else { echo "$i: Unsupported or no repository" >&2 } diff --git a/man/5/caretaker.conf.pod b/man/5/caretaker.conf.pod index 2fe9089..b1564b3 100644 --- a/man/5/caretaker.conf.pod +++ b/man/5/caretaker.conf.pod @@ -22,10 +22,11 @@ The text in [these braces] is the default value. =over -=item B<PKG_ROOT>=I<url> (--packageroot I<url>) +=item B<PKG_ROOTS>=(I<url1> I<url2> I<...>) (--packageroot I<url>) -the package root path. +the package root paths. I<url> may either be of the form C<ssh://host/path> or C</path>. +At least one must be set. =item B<PKGLIST_PATH>=I<path> [$PKG_PATH/pkglist] diff --git a/man/7/caretaker.pod b/man/7/caretaker.pod index 096c651..4601ff6 100644 --- a/man/7/caretaker.pod +++ b/man/7/caretaker.pod @@ -57,11 +57,12 @@ Also, the 'ct add' completion relies on .list-remote, and back in the days when caretaker supported more than one DVCS, it was used to determine which DVCS to use for which package. -It consists of one line per package, each line containing three items separated -by a single whitespace. The first item is the package name, the second one the -repository type (DVCS), the third the current revision. Example: +It consists of one line per package, each line containing three or four items separated +by a single whitespace. The first item is the package name, the second one the +repository type (DVCS), the third the current revision; in the remote list, the fourth +is the package root to which this package belongs. Example: - caretaker git 82d716d01dee0329af7df5e67b55558fe3ff1466 + caretaker git 82d716d01dee0329af7df5e67b55558fe3ff1466 git://git.tabularazor.org/~derf The package list is generated by the script set in the config var $PKGLIST_PATH, by default F<include/pkglist>. Depending on $PKGLIST_LOCAL and $PKG_ROOT, it |