1+ #! /usr/bin/env bash
2+
3+ # Provides safe-guarded (security checked parameters) git repository cloning.
4+
5+ # Note: This script needs the path to target directory to clone the git repository to. It defaults to SOURCE_DIRECTORY ("source").
6+ # Note: This script needs git to be installed.
7+
8+ # Fail on any error ("-e" = exit on first error, "-o pipefail" exist on errors within piped commands)
9+ set -o errexit -o pipefail
10+
11+ # Overrideable Defaults
12+ SOURCE_DIRECTORY=${SOURCE_DIRECTORY:- " source" } # Get the source repository directory (defaults to "source")
13+
14+ # Local constants
15+ SCRIPT_NAME=$( basename " ${0} " )
16+
17+ fail () {
18+ local ERROR_COLOR=' \033[0;31m' # red
19+ local DEFAULT_COLOR=' \033[0m'
20+ local errorMessage=" ${1} "
21+ echo -e " ${ERROR_COLOR}${SCRIPT_NAME} : Error: ${errorMessage}${DEFAULT_COLOR} " >&2
22+ exit 1
23+ }
24+
25+ # Default and initial values for command line options
26+ url=" "
27+ branch=" main"
28+ history_only=" false"
29+ target=" ${SOURCE_DIRECTORY} "
30+ dry_run=" false"
31+
32+ # Read command line options
33+ USAGE=" ${SCRIPT_NAME} : Usage: $0 --url <github-repository-url> --branch <branch-name> [--history-only <true|false>] [--target <clone directory>(default=source)]"
34+
35+ while [ " $# " -gt " 0" ]; do
36+ key=" $1 "
37+ case ${key} in
38+ --url)
39+ url=" $2 "
40+ shift
41+ ;;
42+ --branch)
43+ branch=" $2 "
44+ shift
45+ ;;
46+ --history-only)
47+ history_only=" $2 "
48+ shift
49+ ;;
50+ --target)
51+ target=" $2 "
52+ shift
53+ ;;
54+ --dry-run)
55+ dry_run=" true"
56+ ;;
57+ * )
58+ fail " Unknown option: ${key} "
59+ echo " ${USAGE} " >&2
60+ exit 1
61+ esac
62+ shift
63+ done
64+
65+ # --- Validate URL (mandatory)
66+ if [ " ${url} " = " " ] ; then
67+ fail " The git repository URL (--url) must be provided."
68+ echo " ${USAGE} " >&2
69+ exit 1
70+ fi
71+ case " ${url} " in
72+ https://github.com/* /* |https://github.com/* /* .git)
73+ ;;
74+ * )
75+ fail " The source repository must be a valid GitHub repository URL."
76+ ;;
77+ esac
78+
79+ # --- Validate branch (mandatory, defaults to "main")
80+ case " ${branch} " in
81+ * [\ ~ ^:?* [\]\\ ]* )
82+ fail " The source repository branch contains invalid characters."
83+ ;;
84+ esac
85+
86+ # --- Validate history-only (mandatory, defaults to "false")
87+ case " ${history_only} " in
88+ true|false)
89+ ;;
90+ * )
91+ fail " The source repository history-only option must be either 'true' or 'false'."
92+ echo " ${USAGE} " >&2
93+ ;;
94+ esac
95+
96+ # --- Validate target directory (mandatory, defaults to SOURCE_DIRECTORY)
97+ if [ ! -d " ${target} " ] ; then
98+ fail " The given target ${target} is not a directory" >&2
99+ echo " ${USAGE} " >&2
100+ exit 1
101+ fi
102+
103+ if [ dry_run = " true" ] ; then
104+ echo " Dry run mode enabled. The following command(s) would be executed:" >&2
105+ fi
106+
107+ # --- Clone the git repository
108+ branch_option=" --single-branch"
109+ if [ " ${branch} " != " " ]; then
110+ branch_option=" ${branch_option} --branch \" ${branch} \" "
111+ fi
112+ if [ " ${history_only} " = " true" ]; then
113+ if [ ${dry_run} = " true" ] ; then
114+ echo " git clone --bare ${branch_option} \" ${url} \" \" ${target} /.git\" "
115+ exit 0
116+ else
117+ git clone --bare ${branch_option} " ${url} " " ${target} /.git"
118+ fi
119+ else
120+ if [ ${dry_run} = " true" ] ; then
121+ echo " git clone ${branch_option} \" ${url} \" \" ${target} \" "
122+ exit 0
123+ else
124+ git clone ${branch_option} " ${url} " " ${target} "
125+ fi
126+ fi
0 commit comments