summaryrefslogtreecommitdiff
path: root/src/gitget/gitget
diff options
context:
space:
mode:
Diffstat (limited to 'src/gitget/gitget')
-rwxr-xr-xsrc/gitget/gitget221
1 files changed, 221 insertions, 0 deletions
diff --git a/src/gitget/gitget b/src/gitget/gitget
new file mode 100755
index 0000000..4d127c7
--- /dev/null
+++ b/src/gitget/gitget
@@ -0,0 +1,221 @@
+#!/usr/bin/env bash
+
+# Copyright (C) 2012-2013 Pacman Development Team <pacman-dev@archlinux.org>
+# Copyright (C) 2012-2013 Luke Shumaker <lukeshu@sbcglobal.net>
+#
+# License: GNU GPLv2+
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+. libremessages
+
+# from makepkg
+dir_is_empty() {
+ (
+ shopt -s dotglob nullglob
+ files=("$1"/*)
+ (( ${#files} == 0 ))
+ )
+}
+
+# from makepkg
+cd_safe() {
+ if ! cd "$1"; then
+ error "Failed to change to directory %s" "$1"
+ plain "Aborting..."
+ exit 1
+ fi
+}
+
+# from makepkg
+download_git_checkout() {
+ local url=$1
+ local ref=$2
+ local dir=$3
+ local name=$4
+ local push=${5:-}
+
+ if [[ ! -d "$dir/.git" ]] ; then
+ msg2 "Cloning %s %s repo..." "${name}" "git"
+ if ! git clone "$url" "$dir"; then
+ error "Failure while downloading %s %s repo" "${name}" "git"
+ plain "Aborting..."
+ exit 1
+ fi
+ cd_safe "$dir"
+ if [[ -n $push ]]; then
+ git config remote.origin.pushUrl "$push"
+ fi
+ git checkout "$ref"
+ else
+ cd_safe "$dir"
+ # Make sure we are fetching the right repo
+ if [[ "$url" != "$(git config --get remote.origin.url)" ]] ; then
+ if $FORCE; then
+ git config remote.origin.url "$url"
+ else
+ error "%s is not a clone of %s" "$dir" "$url"
+ plain "Aborting..."
+ exit 1
+ fi
+ fi
+ if [[ -n $push ]] ; then
+ if $FORCE; then
+ git config remote.origin.pushUrl "$push"
+ else
+ local curpush="$(git config --get remote.origin.pushUrl)"
+ if [[ $? != 0 ]] ; then
+ error "%s does not have a %s configured" pushUrl "$name"
+ plain "Aborting..."
+ exit 1
+ elif [[ $curpush != "$push" ]]; then
+ error "%s has %s configured, but it doesn't match %s" "$name" pushUrl "$push"
+ plain "Aborting..."
+ exit 1
+ fi
+ fi
+ fi
+ msg2 "Updating %s %s repo..." "${name}" "git"
+ if ! { git fetch --all -p && git checkout "$ref" && git pull origin "$ref"; } ; then
+ # only warn on failure to allow offline builds
+ warning "Failure while updating %s %s repo" "${repo}" "git"
+ fi
+ fi
+}
+
+# from makepkg
+download_git_bare() {
+ local url=$1
+ local dir=$2
+ local name=$3
+ local push=${4:-}
+
+ if [[ ! -d "$dir" ]] || dir_is_empty "$dir" ; then
+ msg2 "Cloning %s %s repo..." "${name}" "git"
+ if ! git clone --mirror "$url" "$dir"; then
+ error "Failure while downloading %s %s repo" "${name}" "git"
+ plain "Aborting..."
+ exit 1
+ fi
+ if [[ -n $push ]]; then
+ cd_safe "$dir"
+ git config remote.origin.pushUrl "$push"
+ fi
+ else
+ cd_safe "$dir"
+ # Make sure we are fetching the right repo
+ if [[ "$url" != "$(git config --get remote.origin.url)" ]] ; then
+ error "%s is not a clone of %s" "$dir" "$url"
+ plain "Aborting..."
+ exit 1
+ fi
+ if [[ -n $push ]] ; then
+ if $FORCE; then
+ git config remote.origin.pushUrl "$push"
+ else
+ local curpush="$(git config --get remote.origin.pushUrl)"
+ if [[ $? != 0 ]] ; then
+ error "%s does not have a %s configured" pushUrl "$name"
+ plain "Aborting..."
+ exit 1
+ elif [[ $curpush != "$push" ]]; then
+ error "%s has %s configured, but it doesn't match %s" "$name" pushUrl "$push"
+ plain "Aborting..."
+ exit 1
+ fi
+ fi
+ fi
+ msg2 "Updating %s %s repo..." "${name}" "git"
+ if ! git fetch --all -p; then
+ # only warn on failure to allow offline builds
+ warning "Failure while updating %s %s repo" "${name}" "git"
+ fi
+ fi
+}
+
+usage() {
+ print 'Usage: %s [OPTIONS] [bare|checkout] URL DIRECTORY' "${0##*/}"
+ print 'A URL-handler for git urls. Capable of updating or cloning.'
+ echo
+ prose "Clones or pulls from the git URL, to a local DIRECTORY. If
+ \`bare\` is specified, it will create a bare repository; if
+ \`checkout\` is specified, it will create or update a working tree."
+ echo
+ prose 'For a checkout, the tree to checkout is specified by appending
+ `#ANYTHING=TREE-ISH` to the URL. For example, `#branch=stable`,
+ or `#tag=v12.3`. Whatever is on the left side of the equal sign
+ is ignored, this is for compatibility with `makepkg` source
+ URLs.'
+ echo
+ prose "The URL may be prefixed with \`git+\`. This is also for
+ compatibility with \`makepkg\` source URLs."
+ echo
+ prose "It does safety checks, figures out whether to clone or pull, and
+ other helpful things. This exists because the same
+ \`download_git\` function from makepkg was being copied and
+ pasted again and again."
+ echo
+ print "Options:"
+ flag '-f' \
+ 'Instead of checking to make sure configured URLs match, force
+ the update, and set the URLs.'
+ flag "-p $(_ URL)" \
+ 'In addition to setting or checking `remotes.origin.url`, also
+ set or check `remotes.origin.pushUrl`'
+ flag "-n $(_ NAME)" \
+ 'In messages, instead of using the basename of DIRECTORY as the
+ repository name, use NAME'
+ flag '-h' 'Show this message'
+}
+
+FORCE=false
+main() {
+ local push=''
+ local name=''
+ while getopts 'fp:n:h' flag; do
+ case "${flag}" in
+ f) FORCE=true;;
+ p) push=$OPTARG;;
+ n) name=$OPTARG;;
+ h) usage; return 0;;
+ *) usage >&2; return 1;;
+ esac
+ done
+ shift $(($OPTIND - 1))
+ [[ $# == 3 ]] || { usage >&2; return 1; }
+ local mode=$1
+ local url=${2#git+}
+ local dir=$3
+
+ local urlmain=${url%%#*}
+ local urlfrag=${url#*#}
+ if [[ "$urlfrag" == "$urlmain" ]]; then
+ urlfrag=''
+ fi
+ local ref=${urlfrag#*=}
+
+ if [[ -z $ref ]]; then
+ ref=master
+ fi
+
+ name=${name:-${dir##*/}}
+
+ case "$mode" in
+ checkout) download_git_checkout "$urlmain" "$ref" "$dir" "$name" "$push";;
+ bare) download_git_bare "$urlmain" "$dir" "$name" "$push";;
+ *) usage >&2; return 1;;
+ esac
+}
+
+main "$@"