diff options
-rw-r--r-- | src/cpt-lib | 174 |
1 files changed, 86 insertions, 88 deletions
diff --git a/src/cpt-lib b/src/cpt-lib index db7f26a..55b1b2b 100644 --- a/src/cpt-lib +++ b/src/cpt-lib @@ -514,61 +514,14 @@ pkg_sources() { repo_dir=$(pkg_find "$1") while read -r src dest || [ "$src" ]; do - # Comment. - if [ -z "${src##\#*}" ]; then : + # Remote git/hg repository or comment. + if [ -z "${src##\#*}" ] || [ -z "${src##git+*}" ] || [ -z "${src##hg+*}" ] + then : # Remote source (cached). elif [ -f "${src##*/}" ]; then log "$1" "Found cached source '${src##*/}'" - # Remote git repository. - elif [ -z "${src##git+*}" ]; then - # This is a checksums check, skip it. - [ "$2" ] && continue - - # Since git is an optional dependency, make sure - # it is available on the system. - command -v git >/dev/null || - die "git must be installed in order to acquire ${src##git+}" - - mkdir -p "$mak_dir/$1/$dest" - - # Run in a subshell to keep the variables, path and - # argument list local to each loop iteration. - ( - repo_src=${src##git+} - - log "$1" "Cloning ${repo_src%[@#]*}" - - # Git has no option to clone a repository to a - # specific location so we must do it ourselves - # beforehand. - cd "$mak_dir/$1/$dest" 2>/dev/null || die - - # Clear the argument list as we'll be overwriting - # it below based on what kind of checkout we're - # dealing with. - set -- "$repo_src" - - # If a branch was given, shallow clone it directly. - # This speeds things up as we don't have to grab - # a lot of unneeded commits. - [ "${src##*@*}" ] || - set -- -b "${src##*@}" "${repo_src%@*}" - - # Maintain compatibility with older versions of - # cpt by shallow cloning all branches. This has - # the added benefit of allowing checkouts of - # specific commits in specific branches. - [ "${src##*#*}" ] || - set -- --no-single-branch "${repo_src%#*}" - - # Always do a shallow clone as we will unshallow it if - # needed later (when a commit is desired). - git clone --depth=1 "$@" . - - ) || die "$1" "Failed to clone $src" - # Remote source. elif [ -z "${src##*://*}" ]; then log "$1" "Downloading $src" @@ -591,31 +544,43 @@ pkg_sources() { pkg_extract() { # Extract all source archives to the build directory and copy over # any local repository files. - log "$1" "Extracting sources" - repo_dir=$(pkg_find "$1") + # Support packages without sources. Simply do nothing. + [ -f "$repo_dir/sources" ] || return 0 + + log "$1" "Extracting sources" + while read -r src dest || [ "$src" ]; do mkdir -p "$mak_dir/$1/$dest" && cd "$mak_dir/$1/$dest" case $src in - # Git repository with supplied commit hash. - git+*\#*) - log "Checking out ${src##*#}" - - # A commit was requested, unshallow the repository. - # This will convert it to a regular repository with - # full history. - git fetch --unshallow - - # Try to checkout the repository. If we fail here, - # the requested commit doesn't exist. - git -c advice.detachedHead=false checkout "${src##*#}" || - die "Commit hash ${src##*#} doesn't exist" + # Git repository. + git+*) + # Split the source into URL + OBJECT (branch or commit). + url=${src##git+} com=${url##*[@#]} com=${com#${url%[@#]*}} + + log "$1" "Cloning ${url%[@#]*}"; { + git init + git remote add origin "${url%[@#]*}" + git fetch --depth=1 origin "$com" || git fetch + git checkout "${com:-FETCH_HEAD}" + } || die "$1" "Failed to clone $src" ;; - # Git repository, comment or blank line. - git+*|\#*|'') continue ;; + # Mercurial repository. + hg+*) + # Split the source into URL + OBJECT (branch or commit). + url=${src##hg+} com=${url##*[@#]} com=${com#${url%[@#]*}} + + # Unfortunately, there is no shallow cloning with Mercurial. + log "$1" "Cloning ${url%[@#]*}" + hg clone -u "${com:-tip}" + + ;; + + # Comment or blank line. + \#*|'') continue ;; # Only 'tar' an 'zip' archives are currently supported for # extraction. Other filetypes are simply copied to '$mak_dir' @@ -1529,7 +1494,7 @@ pkg_fetch() { # Update each repository in '$CPT_PATH'. It is assumed that # each repository is 'git' tracked. - for repo do + for repo; do # Go to the root of the repository (if it exists). cd "$repo" cd "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null ||: @@ -1554,7 +1519,7 @@ pkg_fetch() { # Display a tick if signing is enabled for this # repository. case $(git config merge.verifySignatures) in - true) log "$PWD" "[signed ✓] " ;; + true) log "$PWD" "[signed] " ;; *) log "$PWD" " " ;; esac @@ -1573,7 +1538,7 @@ pkg_fetch() { # ownership of files and directories in the rare # case that the repository is owned by a 3rd user. ( - user=$(cpt-stat "$PWD") || user=root + user=$(cpt-stat "$PWD") || user=root id -u "$user" >/dev/null 2>&1 || user=root [ "$user" = root ] || @@ -1590,25 +1555,58 @@ pkg_fetch() { ) fi } + elif hg root >/dev/null 2>&1; then + cd "$(hg root)" + contains "$repos $PWD" || { + repos="$repos $PWD" + if [ -w "$PWD" ] && [ "$uid" != 0 ]; then + hg pull + hg update + else + [ "$uid" ] || log "$PWD" "Need root to update" + + # We are going to do the same operation as above, to + # find the owner of the repository. + ( + user=$(cpt-stat "$PWD") || user=root + id -u "$user" >/dev/null 2>&1 || user=root + + [ "$user" = root ] || + log "Dropping permissions to $user for pull" + + hg_cmd="hg pull && hg update" + + case $su in *su) hg_cmd="'$hg_cmd'"; esac + user=$user as_root sh -c "$hg_cmd" + ) + fi + } elif [ -f .rsync ]; then - read -r remote < .rsync - if [ -w "$PWD" ] && [ "$uid" != 0 ]; then - rsync -acvzzC --include=core --delete "$remote/" "$PWD" - else - [ "$uid" = 0 ] || log "$PWD" "Need root to update" - - # Similar to the git update, we find the owner of - # the repository and spawn rsync as that user. - ( - user=$(cpt-stat "$PWD") || user=root - id -u "$user" >/dev/null 2>&1 || user=root - - [ "$user" = root ] || - log "Dropping permissions to $user for pull" - - user=$user as_root rsync -acvzzC --include=core --delete "$remote/" "$PWD" - ) - fi + [ -f .rsync_root ] && { + read -r rsync_root < .rsync_root + [ -f "$rsync_root/.rsync" ] && cd "$rsync_root" + } + contains "$repos" "$PWD" || { + repos="$repos $PWD" + read -r remote < .rsync + if [ -w "$PWD" ] && [ "$uid" != 0 ]; then + rsync -acvzzC --include=core --delete "$remote/" "$PWD" + else + [ "$uid" = 0 ] || log "$PWD" "Need root to update" + + # Similar to the git update, we find the owner of + # the repository and spawn rsync as that user. + ( + user=$(cpt-stat "$PWD") || user=root + id -u "$user" >/dev/null 2>&1 || user=root + + [ "$user" = root ] || + log "Dropping permissions to $user for pull" + + user=$user as_root rsync -acvzzC --include=core --delete "$remote/" "$PWD" + ) + fi + } else log "$repo" " " printf '%s\n' "Not a remote repository, skipping." |