Last active
October 15, 2015 19:38
-
-
Save nilium/5de1dff359c142bb72a5 to your computer and use it in GitHub Desktop.
GitLab CLI tool (early days) — making it just because all the other CLI tools are apparently not intended for humans
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
export API="${API:-$(git config gitlab.endpoint)}" | |
export TOKEN="${TOKEN:-$(git config gitlab.token)}" | |
export API="${API%*/}" | |
export self="${BASH_SOURCE[0]}" | |
if [[ -z "$API" ]] || [[ -z "$TOKEN" ]] ; then | |
cat <<-EOF 1>&2 | |
API and TOKEN environment variables must be set, or you need to | |
set gitlab.endpoint and gitlab.token in your Git config. | |
API is the GitLab API endpoint and uses the Git config key | |
gitlab.endpoint by default. TOKEN is your personal GitLab API token, | |
and uses the Git config key gitlab.token by default. | |
git config --global gitlab.endpoint https://example.com/api/v3 | |
git config --global gitlab.token YOUR-PRIVATE-TOKEN | |
Your private token can be found in your user profile under the | |
account section (path /profile/account). | |
EOF | |
exit 1 | |
fi | |
if ! which nab 1>/dev/null 2>/dev/null ; then | |
cat <<-EOF 1>&2 | |
You must have nab v1.1.1 or newer in your PATH to use git-lab. | |
You can download nab for your OS at: | |
https://github.com/nilium/nab/releases | |
EOF | |
exit 1 | |
fi | |
stripnl () { | |
xargs echo -n | |
} | |
send () { | |
method="$1" | |
path="$2" | |
shift | |
shift | |
curl -s --request "${method}" \ | |
--header "PRIVATE-TOKEN: ${TOKEN}" \ | |
-L "${API}${path}" \ | |
"$@" | |
} | |
search_namespaces () { | |
send GET /namespaces -G -d search="$1" | nab '{{ range . }}{{ .id }}{{ nl }}{{ end }}' | |
} | |
first_namespace () { | |
search_namespaces "$1" | head -n1 | |
} | |
new_project () { | |
inargs=1 | |
unset desc | |
showresp=0 | |
openafter=0 | |
allowinit=0 | |
unset remotename | |
while [[ $# != 0 ]] ; do | |
if [[ $1 != '-'* ]] ; then break ; fi | |
if [[ $1 == '--' ]] ; then | |
shift | |
break | |
fi | |
arg="$1" | |
shift | |
case "$arg" in | |
-desc) | |
desc="description=$1" | |
shift | |
;; | |
-open) | |
openafter=1 | |
;; | |
-clone) | |
cloneafter=1 | |
;; | |
-clone=*) | |
cloneafter=1 | |
clonepath="${arg%/*}" | |
shift | |
;; | |
-origin) | |
remotename="origin" | |
;; | |
-remote) | |
if [[ "$1" != '--' ]] ; then | |
remotename="$1" | |
shift | |
else | |
remotename="origin" | |
fi | |
;; | |
-remote=*) | |
remotename="${1%-remote=*}" | |
;; | |
-init) | |
allowinit=1 | |
;; | |
-resp) | |
showresp=1 | |
;; | |
*) | |
echo "unknown argument '$arg'" 1>&2 | |
;; | |
esac | |
done | |
if [[ $# == 0 ]] ; then | |
echo "No project name given" 2>&1 | |
exit 1 | |
fi | |
namespace='' | |
name="$1" | |
case $name in | |
*/*) | |
namespace="$(first_namespace "${name%/*}" | stripnl)" | |
project="${name#*/}" | |
;; | |
*) | |
namespace="$("$self" user id | stripnl)" | |
project="$name" | |
;; | |
esac | |
data="$(send POST /projects -d name="$project" -d namespace_id="$namespace" ${desc:+-d} "$desc")" | |
msg="$(echo "$data" | nab "{{ if .message }}{{ .message }}{{ end }}}")" | |
if [[ -z $msg ]] ; then | |
echo "$data" | nab '{{ . | prettyjson }}' 1>&2 | |
exit 1 | |
fi | |
if [[ $openafter == 1 ]] ; then | |
open "$(echo "$data" | nab '{{ .web_url }}')" | |
fi | |
if [[ $cloneafter == 1 ]] ; then | |
if [[ -n $clonepath ]] ; then | |
git clone "$(echo "$data" | nab '{{ .ssh_url_to_repo }}')" "$clonepath" | |
else | |
git clone "$(echo "$data" | nab '{{ .ssh_url_to_repo }}')" | |
fi | |
remotename='' | |
fi | |
if [[ -n "$remotename" ]] ; then | |
echo "Trying to add remote named $remotename" 1>&2 | |
ok=0 | |
if git rev-parse --show-toplevel 2>/dev/null ; then | |
ok=1 | |
elif [[ $allowinit == 1 ]] ; then | |
if git init ; then | |
ok=1 | |
fi | |
fi | |
if [[ $ok == 1 ]] ; then | |
git remote add "$remotename" "$(echo "$data" | nab '{{ .ssh_url_to_repo }}')" | |
else | |
echo "Not in a git repo and -init not provided, cannot add remote $remotename" 1>&2 | |
fi | |
fi | |
if [[ $showresp == 1 ]] ; then | |
echo "$data" | nab '{{ . | prettyjson }}' | |
fi | |
} | |
project_cmd () { | |
cmd="$1" | |
shift | |
case "$cmd" in | |
new|create) | |
new_project "$@" | |
;; | |
esac | |
} | |
show_help () { | |
cat <<-EOF | |
git-lab CMD [OPTIONS] | |
Commands: | |
user | |
Prints your user ID or any number of fields from your user profile. | |
ns | |
Looks up a namespace ID by the search term given. | |
project new [NAMESPACE/]PROJECT | |
Creates a new project in GitLab. If you specify a namespace, the | |
first namespace found by searching for 'NAMESPACE' is used. Otherwise, | |
the project is created for your user. | |
OPTIONS | |
-init | |
Allow a git repository to be initialized in the working directory | |
if you are not already in a git repository. This only applies if | |
adding a remote for the new project. | |
-origin | |
-remote=NAME | |
-remote NAME | |
The remote name to use if adding it to a repo. -origin is a shortcut | |
for -remote=origin. | |
-resp | |
Pretty-print the JSON response. | |
-open | |
Open the new project page using your default browser. Requires | |
OS X-compatible 'open' command right now. | |
-clone | |
-clone=PATH | |
Clone the project after creating it. If a PATH is provided, the | |
project is cloned into that path. | |
-remote and -init cannot be specified with this option. | |
EOF | |
} | |
if [[ $# == 0 ]] ; then | |
show_help | |
exit 1 | |
fi | |
cmd="$1" | |
shift | |
case "$cmd" in | |
help) | |
show_help | |
exit 0 | |
;; | |
curl) | |
send "$@" | |
;; | |
user) | |
if [[ $# == 0 ]] ; then | |
send GET /user | nab '{{ range $k, $v := . }}{{ $k }}: {{ $v }}{{ nl }}{{ end }}' | |
else | |
send GET /user | nab "$(for arg in "$@" ; do echo "{{ .$arg }}" ; done){{ nl }}" | |
fi | |
;; | |
ns) | |
search_namespaces "$@" | |
;; | |
project) | |
project_cmd "$@" | |
;; | |
*) | |
echo "Unrecognized command '$cmd'" 1>&2 | |
echo '' 1>&2 | |
show_help | |
exit 1 | |
;; | |
esac |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment