summary refs log tree commit diff
path: root/bin/clone
blob: 8aef6ae56ce618a4167060795171d4504db65eaf (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#!/bin/bash
#
# To use this create a directory that you want to use for git repos, e.g. $HOME/git and copy/symlink this script into it.
# Then you can use it like this:
#
# ./clone github.com/robertgzr/dotfiles
# ./clone https://bitbucket.org/foo/bar
#
# If you don't have gitconfig set up like I have (using aliases for github/bitbucket ssh access) this won't really work
set -e
[ -n "$DEBUG" ] && set -x

SHALLOW=
RECURSE_SUBMODULES=
TEMP="$(mktemp -d -p /tmp clone.XXXXXXXXXX)"
URL=

usage() {
    printf "usage: clone [-s][-r] URL\n"
    printf "\n"
    printf " URL  example.com/user/repo\n"
    printf "      http[s]://example.com/user/repo\n"
    printf "\n"
    printf " -s   shallow clone\n"
    printf " -r   recurse submodules\n"
    printf "\n"
    exit 0
}

fail() {
    printf "error: %s\n" "${1:-error}"
    exit "${2:-1}"
}

confirm() {
    printf "%s, ok (y/n)? " "${1:-'do something'}"
    read -r yn
    if [[ "$yn" = "${yn#[Yy]}" ]]; then
        fail "ok, exiting" 0
    fi
}

git_clone() {
    declare -a GIT_FLAGS
    if [[ -n "${SHALLOW}" ]]; then
        printf "* shallow clone\n"
        GIT_FLAGS+=("--depth=${SHALLOW}")
    fi
    if [[ -n "${RECURSE_SUBMODULES}" ]]; then
        printf "* recurse submodules\n"
        GIT_FLAGS+=("--recurse-submodules")
    fi
    git clone "${GIT_FLAGS[@]}" "${@}"
}
ssh_clone() {
    prefix=$1
    in=$2
    to=$3
    IFS='/' read -r -a url <<< "${in}"
    ssh_url="${prefix}:${url[1]}/${url[2]}"

    printf "* via ssh: %s\n" "${ssh_url}"
    git_clone "${ssh_url}" "${to}"
}
http_clone() {
    to=$2
    http_url="https://${URL}"

    printf "* via http: %s\n" "${ssh_url}"
    git_clone "${http_url}" "${to}"
}
clone() {
    in=$1
    to=$2
    IFS='/' read -r -a url <<< "${in}"

    case "${url[0]}" in
    github.com)         ssh_clone git@github.com "${in}" "${to}";;
    gitlab.com)         ssh_clone git@gitlab.com "${in}" "${to}";;
    bitbucket.org)      ssh_clone git@bitbucket.org "${in}" "${to}";;
    git.sr.ht)          ssh_clone git@git.sr.ht "${in}" "${to}";;
    * )                 http_clone "${url/ /\/}" "${to}";;
    esac

    if [ -e "${to}/.gitmodules" ]; then
        git -C "${to}" submodule update --init --recursive
    fi
}


main() {
    while getopts ":hsr" opt; do
        case ${opt} in
        s)          SHALLOW=1 ;;
        r)          RECURSE_SUBMODULES=1 ;;
        h|\?)       usage ;;
        esac
    done
    shift $((OPTIND -1))

    URL=$1
    if [[ -z "${URL}" ]]; then
        fail "no input"
    else
        URL="${URL//(http|https):\/\//}"
    fi

    clone "${URL}" "${TEMP}/${URL}" || fail

    target="${PWD}/$(dirname "${URL}")"
    install -d "${target}" || fail
    mv "${TEMP}/${URL}" "${target}" || fail
}

main "${@}"