-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbclean
More file actions
executable file
·173 lines (147 loc) · 4.83 KB
/
bclean
File metadata and controls
executable file
·173 lines (147 loc) · 4.83 KB
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
#!/bin/bash
set -eo pipefail
TEST_MODE=false
PUSH=false
DRY_RUN=true
REPO_PATH=./
ANNOTATED_TAGS=true
KEEP_BRANCHES="trunk master main"
# list_include_item "10 11 12" "2"
function list_include_item {
local list="$1"
local item="$2"
if [[ $list =~ (^|[[:space:]])"$item"($|[[:space:]]) ]] ; then
# yes, list include item
result=0
else
result=1
fi
return $result
}
usage() {
echo -e "\nUsage:\n" \
"\t$0 --test --push --apply\n" \
"\nFlags:\n" \
"\t--keep [branch] - keep a branch by name\n" \
"\t--path [path] - path to git repository, default to current directory\n" \
"\t--test - creates a git repository to self-test the cleanup procedure\n" \
"\t--apply - disable dry run and do it for real\n" \
"\t--unannotated - do not use annotated tags\n" \
"\t--push, -p - push after applying\n" \
"\t--v - verbose output (\`set -x\`)\n" \
"\t--help - prints this useful information\n" >&2
exit 1
}
# Process flags/options
while [ "$1" != "" ]; do
PARAM=$(echo "$1" | awk -F= '{print $1}')
VALUE=$(echo "$1" | awk -F= '{print $2}')
case $PARAM in
--v)
set -x
;;
--help)
usage
;;
--path|-p)
REPO_PATH=$VALUE
;;
--apply)
DRY_RUN=false
;;
--push)
PUSH=true
;;
--test)
TEST_MODE=true
;;
--keep)
KEEP_BRANCHES="$KEEP_BRANCHES $VALUE"
;;
--unannotated)
ANNOTATED_TAGS=false
;;
*)
echo "Unrecognized $PARAM"
break
;;
esac
shift
done
# check to see if this file is being run or sourced from another script
_is_sourced() {
# https://unix.stackexchange.com/a/215279
[ "${#FUNCNAME[@]}" -ge 2 ] \
&& [ "${FUNCNAME[0]}" = '_is_sourced' ] \
&& [ "${FUNCNAME[1]}" = 'source' ]
}
_main() {
if [ $TEST_MODE = true ]; then
REPO_PATH="./bclean-test"
REPO_TEST_ORIGIN="${REPO_PATH}2"
# Clean up any previous test
rm -rf $REPO_PATH
rm -rf $REPO_TEST_ORIGIN
# Create test repository
git init -b trunk "$REPO_PATH"
git -C "$REPO_PATH" config user.email "test@acrois.dev"
git -C "$REPO_PATH" config user.name "Test Runner"
# Commit to main branch
echo "Test" > $REPO_PATH/test.txt
git -C "$REPO_PATH" add .
git -C "$REPO_PATH" commit -m "Initial commit"
# Create new branch
git -C "$REPO_PATH" checkout -b test/branch
echo "Test Again" >> $REPO_PATH/test.txt
git -C "$REPO_PATH" add .
git -C "$REPO_PATH" commit -m "Another one"
# Switch to main
git -C "$REPO_PATH" checkout trunk
git init --bare "$REPO_TEST_ORIGIN"
git -C "$REPO_PATH" remote add origin "$(dirname "$(readlink -e $REPO_TEST_ORIGIN)")/$(basename $REPO_TEST_ORIGIN)"
git -C "$REPO_PATH" push origin --all
fi
git -C "$REPO_PATH" fetch --all
if [ $DRY_RUN = true ]; then
echo "================================="
echo "DRY RUN - NOTHING WILL BE CHANGED"
echo "================================="
fi
local current_date
current_date=$(date +%Y%m%d)
# Process branches
for branch in $(git -C "$REPO_PATH" for-each-ref --format='%(refname)' refs/heads/); do
branch_name="${branch/'refs/heads/'/''}"
if list_include_item "$KEEP_BRANCHES" "$branch_name"; then
echo "Skipping $branch_name (kept branch)"
continue
fi
# TODO: Optional - Check GitHub Repo Protected Branches?
# curl -L \
# -H "Accept: application/vnd.github+json" \
# -H "Authorization: Bearer <YOUR-TOKEN>"\
# -H "X-GitHub-Api-Version: 2022-11-28" \
# https://api.github.com/repos/OWNER/REPO/branches/BRANCH/protection
echo "Processing $branch_name"
# Tag branch
if [ $ANNOTATED_TAGS = true ]; then
git -C "$REPO_PATH" tag "archive/$current_date/$branch_name" -a -m "Archive of $branch_name on $current_date" "$branch_name"
else
git -C "$REPO_PATH" tag "archive/$current_date/$branch_name" "$branch_name"
fi
# Delete branch
git -C "$REPO_PATH" branch -D "$branch_name"
# Delete branch from origin
if [[ $DRY_RUN = false && $PUSH = true ]]; then
git -C "$REPO_PATH" push origin ":$branch_name"
fi
done
# Push tags to origin
if [[ $DRY_RUN = false && $PUSH = true ]]; then
git -C "$REPO_PATH" push origin --tags
fi
}
# If we are sourced from elsewhere, don't perform any further actions
if ! _is_sourced; then
_main "$@"
fi