5
SUPPORTED_VCS="bzr hg git url"
13
Usage: ${0##*/} [ options ] repo-url [command [arguments]]
15
obtain repository from repo-url, and execute 'command' with 'arguments'
17
Command will default to '$DEF_COMMAND' in the top level of the repository.
20
-t | --target DIR checkout branch to DIR [./(basename repo)]
21
--vcs-type V repo-url is of type 'V' [auto]
22
supported: auto $SUPPORTED_VCS
23
-v | --verbose increase verbosity
24
-D | --deps attempt to install dependencies if necessary
28
bad_Usage() { Usage 1>&2; [ $# -eq 0 ] || error "$@"; return 1; }
29
error() { echo "$@" 1>&2; }
31
local level=${1}; shift;
32
[ "${level}" -gt "${VERBOSITY}" ] && return
37
command -v "$1" >/dev/null 2>&1
41
# get_cmd(cmd, get_deps, packages)
42
# get command 'cmd' if necessary by installing 'packages'
43
# if 'get_deps' is false, then return error.
44
local cmd="$1" deps="$2"
46
has_cmd "$1" && return 0
47
$deps || { error "No cmd '$cmd', but nodeps specified"; return 1; }
53
cmd=( env DEBIAN_FRONTEND=noninteractive apt-get --quiet
54
--assume-yes install "$@" )
55
[ "$(id -u)" = "0" ] ||
56
cmd=( sudo "${cmd[@]}" )
57
debug 1 "installing dependencies:" "${cmd[@]}"
62
# deps type src target cmd
63
local deps="$1" rtype="$2" src="$3" target="$4" tmp=""
64
if [ "$rtype" = "auto" ]; then
68
if ! [ -d "$src" -a -d "$src/.bzr" ]; then
71
src=$(cd "$src" && pwd) || return $RET_FAIL
75
get_cmd bzr "$deps" bzr || return $RET_FAIL
76
if [ -z "$target" ]; then
80
local cmd="" q="--quiet"
81
[ $VERBOSITY -gt 1 ] && q=""
83
if [ -d "$target/.bzr" ]; then
84
debug 1 "updating $target: bzr pull ${q:+$q }$src"
85
( cd "$target" && bzr pull $q "$src" )
87
debug 1 "branching to $target: bzr branch ${q:+$q }$src"
88
bzr branch $q "$src" "$target"
90
[ $? -eq 0 ] || return $RET_FAIL
96
# deps type src target cmd
97
local deps="$1" rtype="$2" src="$3" target="$4" tmp=""
98
if [ "$rtype" = "auto" ]; then
102
if ! [ -d "$src" -a -d "$src/.git" ]; then
103
return $RET_UNCLAIMED
105
src=$(cd "$src" && pwd) || return $RET_FAIL
109
get_cmd git "$deps" git || return $RET_FAIL
110
if [ -z "$target" ]; then
115
[ $VERBOSITY -gt 1 ] && q=""
116
if [ -d "$target/.git" ]; then
117
debug 1 "updating $target: git pull ${q:+$q }${src}"
118
( cd "$target" && git pull $q "$src" )
120
debug 1 "cloning to $target: git clone ${q:+$q }$src $target"
121
git clone $q "$src" "$target" || return $RET_FAIL
123
[ $? -eq 0 ] || return $RET_FAIL
129
# deps type src target cmd
130
local deps="$1" rtype="$2" src="$3" target="$4" tmp=""
131
if [ "$rtype" = "auto" ]; then
134
*) return $RET_UNCLAIMED;;
137
get_cmd hg "$deps" mercurial || return $RET_FAIL
138
if [ -z "$target" ]; then
142
local quiet="--quiet"
143
[ $VERBOSITY -gt 1 ] && quiet=""
144
hg clone $quiet "$src" "$target" || return $RET_FAIL
150
# deps type src target cmd
151
# if target is not specified, target directory is md5sum
152
# of the url. If cmd does not start with a /, then use it
153
# as the output filename. If it does start with a /, then
154
# store the url in DEF_COMMAND in this directory.
155
local deps="$1" rtype="$2" src="$3" target="$4" cmd="$5" tmp=""
156
if [ "$rtype" = "auto" ]; then
158
http://*|https://*) :;;
159
*) return $RET_UNCLAIMED;;
162
get_cmd wget "$deps" wget || return $RET_FAIL
163
if [ -z "$target" ]; then
164
target=$(echo "$src" | md5sum)
169
if [ "${cmd#/}" != "$cmd" ]; then
170
cmdname="./$DEF_COMMAND"
173
local quiet="--quiet"
174
[ $VERBOSITY -gt 1 ] && quiet=""
176
mkdir -p "$target" ||
177
{ error "failed mkdir -p '$target'"; return $RET_FAIL; }
178
debug 1 "wget -O '$target/$cmdname' '$src'"
179
wget $quiet -O "$target/$cmdname" "$src" || {
180
error "failed wget -O '$target/$cmdname' '$src'"
189
local short_opts="hDt:v"
190
local long_opts="help,deps:,target:,vcs-type:,verbose"
191
local getopt_out=$(getopt --name "${0##*/}" \
192
--options "${short_opts}" --long "${long_opts}" -- "$@") &&
193
eval set -- "${getopt_out}" ||
194
{ bad_Usage; return; }
196
local cur="" next="" target="" rtype="auto" tmp=""
197
local def_target="" deps="" getdeps=false arg0=""
199
while [ $# -ne 0 ]; do
202
-h|--help) Usage ; exit 0;;
203
-D|--deps) getdeps=true;;
204
-t|--target) target=$next; shift;;
205
--vcs-type) rtype=$next; shift;;
206
-v|--verbose) VERBOSITY=$((${VERBOSITY}+1));;
212
[ $# -gt 0 ] || { bad_Usage "must provide at least repo"; return; }
216
[ -n "$src_repo" ] || { error "empty source repo?"; return 1; }
218
if [ -n "$target" ]; then
219
tmp=$(dirname "${target}")
220
[ -d "$tmp" ] || mkdir -p "$tmp" ||
221
{ error "failed to create $tmp for '$target'"; return 1; }
224
if [ $# -eq 0 ]; then
225
set -- "$DEF_COMMAND"
229
local vcs vcslist="${SUPPORTED_VCS}"
230
[ "$rtype" = "auto" ] || vcslist="$rtype"
233
for vcs in $vcslist; do
234
has_cmd "vcsget_$vcs" ||
235
{ error "unknown vcs type '$vcs'"; return 1; }
236
"vcsget_$vcs" "$getdeps" "$rtype" "$src_repo" "$target" "$arg0"
239
$RET_UNCLAIMED) :;; # not claimed
240
$RET_SUCCESS) workd="$_RET"; break;;
241
*) error "failed to get '$src_repo' of type '$vcs'";
247
{ error "unknown source repo '$src_repo'"; return 1; }
250
{ error "failed to enter target dir '$workd'"; return 1; }
252
if [ -f "./$1" ]; then
253
if [ ! -x "./$1" ]; then
254
debug 1 "adding execute to ./$1"
255
chmod ugo+x "./$1" ||
256
{ error "failed add execute to ./$1"; return 1; }
261
elif ! has_cmd "$1"; then
262
error "command '$1' not available anywhere"
266
debug 1 "executing command in $PWD:" "$@"
271
# vi: ts=4 noexpandtab