2121
2222set -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
3073error ( ) {
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
79129CONFIG 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
81131in 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+
86149GENERAL USAGE
87150 # get a list of cookbooks that differ
88151 $ $0
@@ -103,9 +166,55 @@ GENERAL USAGE
103166EOF
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
140258done
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
171266fi
172267
173- info "Using upstream: $upstreamdir | internal: $internaldir"
174-
175268if [ -z "$mode" ] ; then
176269 if [ -n "$cookbook" ] ; then
177270 mode = 'diff'
@@ -180,6 +273,11 @@ if [ -z "$mode" ]; then
180273 fi
181274fi
182275
276+ rsyncargs = "-avz"
277+ if [ "$dryrun" -eq 1 ] ; then
278+ rsyncargs = "${rsyncargs}n"
279+ fi
280+
183281cd "$internaldir/cookbooks" || die "where am I?"
184282[ -z "$cookbook" ] && cookbook = "$(ls -d fb_*)"
185283for 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