Skip to content

Commit 5c29549

Browse files
jaymzhfacebook-github-bot
authored andcommitted
sync_fb_cookbooks: pre-repo configs and other nicities (facebook#276)
Summary: This should be configurable per-repo or per-user and cascade nicely. Signed-off-by: Phil Dibowitz <phil@ipom.com> Pull Request resolved: facebook#276 Differential Revision: D69857904 fbshipit-source-id: dc1366f1984b78faf6f40dbcb3b1180f687e3e56
1 parent 522d36e commit 5c29549

File tree

1 file changed

+143
-45
lines changed

1 file changed

+143
-45
lines changed

scripts/sync_fb_cookbooks.sh

Lines changed: 143 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,55 @@
2121

2222
set -u
2323

24-
# defaults
25-
config="$HOME/.config/sync_fb_cookbooks.conf"
26-
default_upstreamdir="$HOME/src/chef-cookbooks"
27-
default_internaldir="$HOME/src/chef"
24+
# Constants
25+
CONFIG_FILE_NAME='sync_fb_cookbooks.conf'
26+
DEFAULT_UPSTREAMDIR="$HOME/src/chef-cookbooks"
27+
DEFAULT_INTERNALDIR="$HOME/src/chef"
28+
STATIC_CONFIG_OPTIONS=(
29+
"$HOME/.config/$CONFIG_FILE_NAME"
30+
"/etc/$CONFIG_FILE_NAME"
31+
)
32+
33+
# Globals
34+
mode=''
35+
cookbook=''
36+
config=''
37+
debug=0
38+
dryrun=0
39+
40+
inside_git() {
41+
git rev-parse --is-inside-work-tree &>/dev/null
42+
}
43+
44+
determine_config() {
45+
# if we're inside a git repo..
46+
if inside_git; then
47+
debug "Inside git repo..."
48+
# then find the root
49+
root=$(git rev-parse --show-toplevel)
50+
attempt="${root}/.${CONFIG_FILE_NAME}"
51+
if [ -r "${attempt}" ]; then
52+
debug "Using $attempt"
53+
echo "$attempt"
54+
return
55+
fi
56+
fi
57+
for attempt in "${STATIC_CONFIG_OPTIONS[@]}"; do
58+
debug "checking $attempt"
59+
if [ -r "$attempt" ]; then
60+
echo "$attempt"
61+
return
62+
fi
63+
done
64+
}
65+
66+
debug() {
67+
if [ "$debug" -eq 0 ]; then
68+
return
69+
fi
70+
echo "DEBUG: $*" >&2
71+
}
2872

29-
# methods
3073
error() {
3174
echo "ERROR: $*"
3275
}
@@ -54,18 +97,22 @@ OPTIONS
5497
5598
-C <config_file>
5699
Path to config file
57-
Default: $config
58100
59101
-d
60102
Diff mode
61103
104+
-D
105+
Enable debug
106+
62107
-h
63108
This
64109
65110
-i <dir>
66111
Where your clone of the INTERNAL repo is
67-
Default: $default_internaldir
112+
Default: $DEFAULT_INTERNALDIR
68113
114+
-n
115+
Run rsync in dryrun mode
69116
-p
70117
Push changes internal -> upstream
71118
@@ -74,15 +121,31 @@ OPTIONS
74121
75122
-u <dir>
76123
Where your clone of the UPSTREAM repo is
77-
Default: $default_internaldir
124+
Default: $DEFAULT_INTERNALDIR
125+
126+
-x
127+
Exit after printing config
78128
79129
CONFIG FILE
80-
You can also tell this script where your repos are by creating $config
130+
You can also tell this script where your repos are by creating config
81131
in shell format and defining 'upstreamdir' and 'internaldir', like so:
82132
83133
upstreamdir="\$HOME/mycheckouts/chef-cookbooks"
84134
internaldir="\$HOME/mycheckouts/chef"
85135
136+
$0 will look for config files in the following places, and use the first
137+
one it finds:
138+
139+
- \$REPO_ROOT/.sync_fb_cookbooks.conf # note the dot
140+
- ~/.config/sync_fb_cookbooks.conf
141+
- /etc/sync_fb_cookbooks.conf
142+
143+
Where \$REPO_ROOT is the toplevel of your git repo.
144+
145+
CONFIGURATION VIA ENVIRONMENT VARIABLE
146+
You can pass upstreamdir and internaldir via environment variables
147+
as well.
148+
86149
GENERAL USAGE
87150
# get a list of cookbooks that differ
88151
$ $0
@@ -103,9 +166,55 @@ GENERAL USAGE
103166
EOF
104167
}
105168

106-
mode=''
107-
cookbook=''
108-
while getopts 'c:C:dhi:psu:' opt; do
169+
# loads config in default -> configfile -> environment -> cli order
170+
load_config() {
171+
# save what was passed in either through env vars, if they exist,
172+
# that should win over config file
173+
# or command-line...
174+
env_internaldir=""
175+
env_upstreamdir=""
176+
# +x syntax required to not trip up -u
177+
if [[ -n "${internaldir+x}" ]]; then
178+
env_internaldir="$internaldir"
179+
fi
180+
if [[ -n "${upstreamdir+x}" ]]; then
181+
env_upstreamdir="$upstreamdir"
182+
fi
183+
184+
# initialize with defaults
185+
internaldir="$DEFAULT_INTERNALDIR"
186+
upstreamdir="$DEFAULT_UPSTREAMDIR"
187+
188+
# if a configuration file was not passed in on the command line,
189+
# walk our possible config paths...
190+
if [ -z "$config" ]; then
191+
config=$(determine_config)
192+
fi
193+
194+
# if we have a config, load it...
195+
if [ -n "$config" ]; then
196+
info "Loading config from $config"
197+
# shellcheck disable=SC1090
198+
source "$config" || die "Configuration file $config malformed"
199+
fi
200+
201+
# env/cli (cli wins)
202+
if [ -n "$cli_internaldir" ]; then
203+
internaldir="$cli_internaldir"
204+
elif [ -n "$env_internaldir" ]; then
205+
internaldir="$env_internaldir"
206+
fi
207+
208+
if [ -n "$cli_upstreamdir" ]; then
209+
upstreamdir="$cli_upstreamdir"
210+
elif [ -n "$env_upstreamdir" ]; then
211+
upstreamdir="$env_upstreamdir"
212+
fi
213+
}
214+
215+
cli_internaldir=''
216+
cli_upstreamdir=''
217+
while getopts 'c:C:dDhi:npsu:x' opt; do
109218
case $opt in
110219
c)
111220
cookbook="$OPTARG"
@@ -116,12 +225,18 @@ while getopts 'c:C:dhi:psu:' opt; do
116225
d)
117226
mode='diff'
118227
;;
228+
D)
229+
debug=1
230+
;;
119231
h)
120232
ourhelp
121233
exit
122234
;;
123235
i)
124-
internaldir="$OPTARG"
236+
cli_internaldir="$OPTARG"
237+
;;
238+
n)
239+
dryrun=1
125240
;;
126241
p)
127242
mode='push'
@@ -130,7 +245,10 @@ while getopts 'c:C:dhi:psu:' opt; do
130245
mode='sync'
131246
;;
132247
u)
133-
upstreamdir="$OPTARG"
248+
cli_upstreamdir="$OPTARG"
249+
;;
250+
x)
251+
mode='dumpconfig'
134252
;;
135253
?)
136254
ourhelp
@@ -139,39 +257,14 @@ while getopts 'c:C:dhi:psu:' opt; do
139257
esac
140258
done
141259

142-
# save what was passed in either through env
143-
# or command-line...
144-
save_internaldir=""
145-
save_upstreamdir=""
146-
# +x syntax required to not trip up -u
147-
if [[ -n "${internaldir+x}" ]]; then
148-
save_internaldir="$internaldir"
149-
fi
150-
if [[ -n "${upstreamdir+x}" ]]; then
151-
save_upstreamdir="$upstreamdir"
152-
fi
153-
154-
# initialize with defaults
155-
internaldir="$default_internaldir"
156-
upstreamdir="$default_upstreamdir"
260+
load_config
157261

158-
# now read the config file, if we have one
159-
if [ -e "$config" ]; then
160-
info "Loading config from $config"
161-
# shellcheck disable=SC1090
162-
source "$config" || die "Configuration file $config malformed"
163-
fi
262+
info "Using upstreamdir: $upstreamdir | internaldir: $internaldir"
164263

165-
# Now merge in passed-in config
166-
if [ -n "$save_internaldir" ]; then
167-
internaldir="$save_internaldir"
168-
fi
169-
if [ -n "$save_upstreamdir" ]; then
170-
upstreamdir="$save_upstreamdir"
264+
if [[ $mode == 'dumpconfig' ]]; then
265+
exit
171266
fi
172267

173-
info "Using upstream: $upstreamdir | internal: $internaldir"
174-
175268
if [ -z "$mode" ]; then
176269
if [ -n "$cookbook" ]; then
177270
mode='diff'
@@ -180,6 +273,11 @@ if [ -z "$mode" ]; then
180273
fi
181274
fi
182275

276+
rsyncargs="-avz"
277+
if [ "$dryrun" -eq 1 ];then
278+
rsyncargs="${rsyncargs}n"
279+
fi
280+
183281
cd "$internaldir/cookbooks" || die "where am I?"
184282
[ -z "$cookbook" ] && cookbook="$(ls -d fb_*)"
185283
for cb in $cookbook; do
@@ -193,9 +291,9 @@ for cb in $cookbook; do
193291
elif [ "$mode" = 'diff' ]; then
194292
diff -Nru "$ours" "$upstream"
195293
elif [ "$mode" = 'push' ]; then
196-
rsync -avz "$ours" "$upstream"
294+
rsync "$rsyncargs" "$ours" "$upstream"
197295
elif [ "$mode" = 'sync' ]; then
198-
rsync -avz "$upstream" "$ours"
296+
rsync "$rsyncargs" "$upstream" "$ours"
199297
else
200298
die "wut? wut mode is '$mode'"
201299
fi

0 commit comments

Comments
 (0)