|
#!/usr/bin/env bash |
|
|
|
# ============================================================================== |
|
# Copyright (C) 2018 Potherca |
|
# |
|
# 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 3 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/>. |
|
# ============================================================================== |
|
# There are a few standards this code tries to adhere to, these are listed below. |
|
# |
|
# - Code follows the BASH style-guide described at: |
|
# http://guides.dealerdirect.io/code-styling/bash/ |
|
# |
|
# - Variables are named using an adaption of Systems Hungarian explained at: |
|
# http://blog.pother.ca/VariableNamingConvention |
|
# |
|
# ============================================================================== |
|
|
|
set -o errexit # Exit script when a command exits with non-zero status. |
|
set -o errtrace # Exit on error inside any functions or sub-shells. |
|
set -o nounset # Exit script on use of an undefined variable. |
|
set -o pipefail # Return exit status of the last command in the pipe that exited with a non-zero exit code |
|
|
|
# ============================================================================== |
|
# Git Clone All Projects in Gitlab Group |
|
# ------------------------------------------------------------------------------ |
|
## Usage: $0 [-lh] <gitlab-domain> <group-name> <gitlab-token> |
|
## |
|
## Where: |
|
## - <gitlab-domain> is the domain where gitlab lives (for instance: 'gitlab.com') |
|
## - <group-name> is the name of the group who's repos should be cloned |
|
## - <gitlab-token> is the API access token to make REST API calls with |
|
## |
|
## Options: |
|
## -h|--help Print this help dialogue and exit |
|
## -L|--list List the repositories that would be cloned and exit |
|
## |
|
## The repositories will be cloned into a sub-directory under the path from Where |
|
## this script has been called. The repository will be cloned into ./${group-name}/${repo-name} |
|
## |
|
## The git executable can be overridden by setting the GIT environmental variable |
|
## before calling this script: |
|
## |
|
## GIT=/usr/local/git-plus $0 <gitlab-domain> <group-name> <gitlab-token> |
|
# ============================================================================== |
|
|
|
: readonly "${GIT:=git}" |
|
|
|
usage() { |
|
local sScript sUsage |
|
|
|
readonly sScript="$(basename "$0")" |
|
readonly sUsage="$(grep '^##' <"$0" | cut -c4-)" |
|
|
|
echo -e "${sUsage//\$0/${sScript}}" |
|
} |
|
|
|
gitlab-clone-projects() { |
|
|
|
local -a aParameters aRepos |
|
local g_sGitlabDomain g_sGitlabToken g_sGroupName |
|
local bListOnly |
|
local sDirectory sRepo |
|
call-api() { |
|
local -r sSubject="${1?One parameter required: <api-subject>}" |
|
curl --silent --header "PRIVATE-TOKEN: ${g_sGitlabToken}" "https://${g_sGitlabDomain}/api/v4/${sSubject}?per_page=100" |
|
} |
|
|
|
fetch-projects() { |
|
call-api "groups/${g_sGroupName}/projects" \ |
|
| grep -E -o '"ssh_url_to_repo":"[^"]+"' \ |
|
| cut -d '"' -f4 |
|
} |
|
|
|
bListOnly=false |
|
aParameters=() |
|
|
|
for arg in "$@";do |
|
case $arg in |
|
-h|--help ) |
|
usage |
|
exit |
|
;; |
|
|
|
-l|--list ) |
|
readonly bListOnly=true |
|
shift |
|
;; |
|
|
|
* ) |
|
aParameters+=( "$1" ) |
|
shift |
|
;; |
|
esac |
|
done |
|
readonly aParameters |
|
|
|
readonly g_sGitlabDomain="${aParameters[0]?Three parameters required: <gitlab-domain> <group-name> <gitlab-token>}" |
|
readonly g_sGroupName="${aParameters[1]?Three parameters required: <gitlab-domain> <group-name> <gitlab-token>}" |
|
readonly g_sGitlabToken="${aParameters[2]?Three parameters required: <gitlab-domain> <group-name> <gitlab-token>}" |
|
|
|
readonly sRepos=$(fetch-projects) |
|
|
|
for sRepo in ${sRepos[*]}; do |
|
aRepos+=("${sRepo}") |
|
done |
|
|
|
echo ' =====> Found ' ${#aRepos[@]} ' repositories' |
|
|
|
for sRepo in "${aRepos[@]}"; do |
|
sDirectory="$(echo "${sRepo}" | grep -o -E ':(.*)\.')" |
|
sDirectory="$(realpath --canonicalize-missing --relative-to=./ "${sDirectory:1:-1}")" |
|
|
|
if [[ -d "${sDirectory}" ]];then |
|
echo " -----> Skipping '${sRepo}', directory '${sDirectory}' already exists" |
|
elif [[ "${bListOnly}" = 'true' ]];then |
|
echo " -----> Cloning '${sRepo}' into directory '${sDirectory}'" |
|
else |
|
echo -e "\n -----> Cloning '${sRepo}' into directory '${sDirectory}'" |
|
mkdir -p "${sDirectory}" |
|
"${GIT}" --recursive clone "${sRepo}" "${sDirectory}" \ |
|
|| { |
|
rm -rf "${sDirectory}" |
|
echo -e "\n ! ERROR !\n Could not clone ${sRepo}" |
|
} |
|
fi |
|
done |
|
} |
|
|
|
if [[ "${BASH_SOURCE[0]}" != "$0" ]]; then |
|
export -f gitlab-clone-projects |
|
else |
|
gitlab-clone-projects "${@}" |
|
exit $? |
|
fi |
|
|
|
#EOF |