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
|
#!/usr/bin/env sh
# POSIX shell implementation of Gitrect
#
# Operate on a tempfile and generate a listing of:
#
# prefix-trim-directory,remote=URL,...
#
# For all directories found in $WORKDIR
usage="$(basename "$0") [-h] [-v -w WORKDIR -f FILE]
where:
-w set the working directory (default: $HOME)
-f set the git list file (default: $HOME/.local/share/gitlist)
-y yes to all prompts (no confirmation)
-h show this help text
-v verbose output (multiple flags increase verbosity)
(ex: '-v -v')
"
# Operate on tempfile
TEMPFILE="/tmp/gitrect.temp.$(xxd -l6 -p /dev/urandom)"
touch $TEMPFILE
# Reset all variables that might be set
DEFAULT_STATE="$HOME/.local/share/gitlist"
WORKDIR="$HOME/.code"
verbose=0 # Variables to be evaluated as shell arithmetic should be initialized to a default or validated beforehand.
noconfirm=0
while :; do
case $1 in
-h | -\? | --help) # Call a "show_help" function to display a synopsis, then exit.
echo "$usage"
exit
;;
-f) # Takes an option argument, ensuring it has been specified.
if [ -n "$2" ]; then
DEFAULT_STATE=$2
shift
fi
;;
-f=?*)
DEFAULT_STATE=${1#*=} # Delete everything up to "=" and assign the remainder.
;;
-f=) # Handle the case of an empty --file=
printf 'ERROR: "-f" requires a non-empty option argument.\n' >&2
exit 1
;;
-w) # Takes an option argument, ensuring it has been specified.
if [ -n "$2" ]; then
WORKDIR=$2
shift
fi
;;
-w=?*)
WORKDIR=${1#*=} # Delete everything up to "=" and assign the remainder.
;;
-w=) # Handle the case of an empty --file=
printf 'ERROR: "-w" requires a non-empty option argument.\n' >&2
exit 1
;;
-y)
noconfirm=1
;;
-v)
verbose=$((verbose + 1)) # Each -v argument adds 1 to verbosity.
;;
--) # End of all options.
shift
break
;;
-?*)
printf 'WARN: Unknown option (ignored): %s\n' "$1" >&2
;;
*) # Default case: If no more options then break out of the loop.
break ;;
esac
shift
done
# Make sure local state folder is available
if [ ! -d "$HOME/.local/share" ]; then
if [ $verbose -gt 0 ]; then
echo "Creating directory: $HOME/.local/share"
fi
mkdir -p ~/.local/share
fi
# Rest of the program here.
# If there are input files (for example) that follow the options, they
# will remain in the "$@" positional parameters.
if [ "$(command -v fd)" ]; then
LIST=$(eval "fd -H -t d '\.git$' ${WORKDIR}")
else
LIST=$(eval "find -type d -name \.git ${WORKDIR}")
fi
# for each directory, create a line in TEMPFILE equivalent to:
# short/path/here,origin=url1,upstream=url2,...
#
for dirpath in $LIST; do
# shortpath trims the working directory prefix and the '.git' suffix from the directory
shortpath=$(eval "echo $dirpath | sed -e 's,${WORKDIR}/,,' -e 's,/\.git/,,'")
printf "%s" $shortpath >>$TEMPFILE
if [ $verbose -gt 1 ]; then
echo "Repository found: ${shortpath}" >&2
fi
cd "${dirpath}/.." # change into the parent of the git directory
rems=$(eval "git remote") # list all remotes
for r in $rems; do
url=$(eval "git remote get-url ${r}")
printf ",%s=%s" $r $url >>$TEMPFILE
if [ $verbose -gt 1 ]; then
echo "remote: ${r} ${url} " >&2
fi
done
printf "\n" >>$TEMPFILE
done
# Sort results
sort -o ${TEMPFILE} ${TEMPFILE}
diffval=$(eval "diff -b ${DEFAULT_STATE} ${TEMPFILE}")
if [ $? -eq 0 ]; then
if [ $verbose -gt 0 ]; then
echo "No change. Configuration already up to date." >&2
fi
# Cleanup temp file
rm "${TEMPFILE}"
else
if [ $verbose -gt 0 ]; then
echo "Diff between current and updated state: " >&2
echo "$diffval" >&2
fi
if [ $noconfirm -ne 0 ]; then
# Overwite origiaal with the new
mv "${TEMPFILE}" "${DEFAULT_STATE}"
else
printf 'Accept changes (y/n)? \n'
old_stty_cfg=$(stty -g)
stty raw -echo
answer=$(while ! head -c 1 | grep -i '[ny]'; do true; done)
stty $old_stty_cfg
if [ "$answer" != "${answer#[Yy]}" ]; then
echo "Updating file..."
# Overwite origiaal with the new
mv "${TEMPFILE}" "${DEFAULT_STATE}"
else
echo "Discarding changes..."
rm "${TEMPFILE}"
fi
fi
fi
|