sym 2.7.0 → 2.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,87 +1,266 @@
1
1
  #!/usr/bin/env bash
2
- #==============================================================================
3
2
  #
4
- # (c) 2017 Konstantin Gredeskoul
5
- # MIT License, distributed as part of `sym` ruby gem.
6
- # https://github.com/kigster/sym
3
+ # (c) 2017-2018 Konstantin Gredeskoul
4
+ #
5
+ # MIT License, distributed as part of `sym` ruby gem.
6
+ # • https://github.com/kigster/sym
7
7
  #
8
8
  #==============================================================================
9
- # Purpuse of this script is to transparently edit application secrets in a
10
- # Rails app. It's a simple enough wrapper around sym.
11
9
  #
12
- # What the fuck?
10
+ # The purpose of this script is to transparently edit application secrets in a
11
+ # Rails apps or other repos. It simplifies the process of key import, as well
12
+ # as the direct editing.
13
13
  #
14
- # 1) This assumes you are storing application secrets in a file, say named,
15
- # RAILS_ROOT/config/special/secrets/production.yml.enc
14
+ # If you set some or (ideally) ALL variables below to values specific to your
15
+ # system, things will get easy.
16
16
  #
17
- # 2) You want to be able to easily and transparently edit it with sym, without
18
- # having to remember sym's CLI.
17
+ # SYMIT__FOLDER is a relative folder to your project root, under which you
18
+ # might keep ALL of your encrypted files. Alternatively, if you keep encrypted
19
+ # files sprinkled around your project, just leave it out, because it defaults
20
+ # to "." — the current folder, and search anything beneath.
19
21
  #
20
- # 3) You may want to have a search paths to look for the file in...
22
+ # Variables:
21
23
  #
22
- # 4) You may want to override the file extension assumed (instead of .yml.enc).
24
+ # # only search ./config folder
25
+ # export SYMIT__FOLDER="config"
23
26
  #
24
- # SO: here is what you do:
27
+ # # this will be the name of your key in OS-X KeyChain
28
+ # export SYMIT__KEY="MY_KEYCHAIN_NAME"
25
29
  #
26
- # export sym__ext="json.enc"
27
- # export sym__folder="config/special/secrets"
28
- # export sym__key="application-key"
30
+ # # This is the extension given to the encrypted files. Ideally, leave it
31
+ # # be as ".enc"
32
+ # export SYMIT__EXTENSION=".enc"
29
33
  #
30
34
  # And then
31
35
  #
32
- # symit production
36
+ # symit import key [ insecure ] # import a key and password-protect it (or not)
37
+ # symit auto application.yml.enc # auto-decrypts it
38
+ # symit auto application.yml # auto-encrypts it
39
+ # symit decrypt application.yml # finds application.yml.enc and decrypts that.
40
+ #
33
41
  #
34
42
  # ...and vola! You are editing the encrypted file with sym from the root of
35
43
  # your Rails application. Neat, no?
36
44
  #
37
- symit::init() {
38
- [[ -z "${sym__ext}" ]] && export sym__ext="yml.enc"
39
- [[ -z "${sym__folder}" ]] && export sym__folder="config/settings/secrets"
40
45
 
41
- export true=1
42
- export false=0
46
+ ( [[ -n $ZSH_EVAL_CONTEXT && $ZSH_EVAL_CONTEXT =~ :file$ ]] || \
47
+ [[ -n $BASH_VERSION && $0 != "$BASH_SOURCE" ]]) && _s_=1 || _s_=0
48
+
49
+ (( $_s_ )) && _is_sourced=1
50
+ (( $_s_ )) || _is_sourced=0
51
+
52
+ bash_version=$(/usr/bin/env bash --version | awk '{FS="version"}{print $4}')
53
+ bash_version=${bash_version:0:1}
54
+
55
+ if [[ "${bash_version}" -lt 4 ]]; then
56
+ (( $_s_ )) && return 1
57
+ (( $_s_ )) || exit 1
58
+ fi
59
+
60
+ function __lib::color::setup() {
61
+ if [[ -z "${setup_colors_loaded}" ]]; then
62
+
63
+ export txtblk='\e[0;30m' # Black - Regular
64
+ export txtred='\e[0;31m' # Red
65
+ export txtgrn='\e[0;32m' # Green
66
+ export txtylw='\e[0;33m' # Yellow
67
+ export txtblu='\e[0;34m' # Blue
68
+ export txtpur='\e[0;35m' # Purple
69
+ export txtcyn='\e[0;36m' # Cyan
70
+ export txtwht='\e[0;37m' # White
71
+
72
+ export bldblk='\e[1;30m' # Black - Bold
73
+ export bldred='\e[1;31m' # Red
74
+ export bldgrn='\e[1;32m' # Green
75
+ export bldylw='\e[1;33m' # Yellow
76
+ export bldblu='\e[1;34m' # Blue
77
+ export bldpur='\e[1;35m' # Purple
78
+ export bldcyn='\e[1;36m' # Cyan
79
+ export bldwht='\e[1;37m' # White
80
+
81
+ export unkblk='\e[4;30m' # Black - Underline
82
+ export undred='\e[4;31m' # Red
83
+ export undgrn='\e[4;32m' # Green
84
+ export undylw='\e[4;33m' # Yellow
85
+ export undblu='\e[4;34m' # Blue
86
+ export undpur='\e[4;35m' # Purple
87
+ export undcyn='\e[4;36m' # Cyan
88
+ export undwht='\e[4;37m' # White
89
+
90
+ export bakblk='\e[40m' # Black - Background
91
+ export bakred='\e[41m' # Red
92
+ export bakgrn='\e[42m' # Green
93
+ export bakylw='\e[43m' # Yellow
94
+ export bakblu='\e[44m' # Blue
95
+ export bakpur='\e[45m' # Purple
96
+ export bakcyn='\e[46m' # Cyan
97
+ export bakwht='\e[47m' # White
98
+
99
+ export clr='\e[0m' # Text Reset
100
+ export txtrst='\e[0m' # Text Reset
101
+ export rst='\e[0m' # Text Reset
102
+ export GREP_COLOR=32
103
+ export setup_colors_loaded=1
104
+ else
105
+ [[ -n ${DEBUG} ]] && echo "colors already loaded..."
106
+ fi
107
+ }
43
108
 
44
- export txtrst='\e[0m' # Text Reset
45
- export bldred='\e[1;31m' # Red
46
- export bldgrn='\e[1;32m' # Green
47
- export bldylw='\e[1;33m' # Yellow
48
- export bldblu='\e[1;34m' # Blue
109
+ function __lib::color::hr() {
110
+ local cols=${1:-${COLUMNS}}
111
+ local char=${2:-"—"}
112
+ local color=${3:-${txtylw}}
49
113
 
50
- unset cli__opts
114
+ printf "${color}"
115
+ eval "printf \"%0.s${char}\" {1..${cols}}"
116
+ printf "${clr}\n"
117
+ }
118
+
119
+ function __lib::color::h1() {
120
+ local title=$(echo "$*" | tr 'a-z' 'A-Z')
121
+ len=${#title}
122
+ printf "${bldylw}${title}\n"
123
+ __lib::color::hr ${len} '—'
124
+ }
125
+
126
+ function __lib::color::h2() {
127
+ printf "${bldpur}$*${clr}\n"
128
+ }
129
+
130
+ function __lib::color::cursor_to_col() {
131
+ position=$1
132
+ echo -en "\e[${position}C"
133
+ }
134
+
135
+ function __lib::color::cursor_to_row() {
136
+ position=$1
137
+ echo -en "\e[${position}H"
51
138
  }
52
139
 
53
- symit::usage() {
54
- printf "${bldblu}symit: ${txtrst}edit an encrypted file using configuration from environment\n\n"
140
+ ((${setup_colors_loaded})) ||__lib::color::setup
55
141
 
56
- printf " Usage: ${bldgrn}symit ${bldylw}[file-spec] [options]${txtrst}\n\n"
57
142
 
58
- printf " Eg: To edit an encrypted file config/settings/secrets/development.yml.enc${txtrst}\n"
59
- printf " ${bldgrn}symit${bldylw} development${txtrst}\n\n"
143
+ (( $_s_ )) || {
144
+ printf "${bldred}This script is meant to be sourced into your environment,\n"
145
+ printf "not run on a command line.${clr} \n\n"
60
146
 
61
- printf "options: \n"
62
- printf " -k | --key [key-spec] Pass an alternative key, other than ${sym__key}\n"
63
- printf " -x | --extension [extension] Use extension other than ${bldylw}${sym__ext}${txtrst}\n"
64
- printf " -l | --locations Print search locations for [file-spec]\n"
65
- printf " -i | --install Install the latest version of ${bldylw}sym${txtrst}\n"
66
- printf " -h | --help Show this help message\n"
67
- printf " -n | --dry-run Show the generated sym command\n\n"
147
+ printf "Please add 'source $0' to your BASH initialization file,\n"
148
+ printf "or run the following command:\n\n"
68
149
 
69
- printf "configuration:
150
+ printf " \$ ${bldgrn}sym -B ~/.bash_profile${clr}\n\n"
151
+
152
+ printf "${bldblu}Thanks for using Sym!${clr}\n"
153
+ exit 1
70
154
 
71
- export sym__ext=yml.enc
72
- export sym__folder=config/special/secrets
73
- export sym__key=my-encryption-key
155
+ }
74
156
 
75
- And then, eg from RAILS_ROOT of your app:
157
+ function __symit::init() {
158
+ export SYMIT__EXTENSION=${SYMIT__EXTENSION:-'.enc'}
159
+ export SYMIT__FOLDER=${SYMIT__FOLDER:-'.'}
160
+ export SYMIT__KEY=${SYMIT__KEY}
161
+ }
162
+ function __symit::usage() {
163
+ __lib::color::setup
164
+ __lib::color::h1 "symit"
165
+ printf "
166
+ This a BASH wrapper for the encryption tool (ruby gem) 'Sym'. It streamlines
167
+ editing encrypted of files, importing and securing your key, and other
168
+ actions. The wrapper can be configured with ENV variables, or CLI flags.\n"
169
+
170
+ printf "
171
+ The easiest way to take advantage of this wrapper is to set the following
172
+ environment variables, which removes the need to pass these values via the
173
+ flags. These variables default to the shown values if not set elsewhere:${txtylw}
174
+
175
+ export SYMIT__EXTENSION='${SYMIT__EXTENSION}'
176
+ export SYMIT__FOLDER='${SYMIT__FOLDER}'
177
+ export SYMIT__KEY='${SYMIT__KEY}'
178
+ ${clr}\n"
179
+
180
+ __lib::color::h2 "Usage:"
181
+ printf " ${bldgrn}symit [ action ] [ partial-file-path ] [ flags ]${clr}\n\n"
182
+
183
+ __lib::color::h2 "Actions:"
184
+ printf " Action is the first word that defaults to ${bldylw}edit${clr}.\n\n"
185
+ printf " Valid actions are:\n"
186
+ printf " ${bldylw}— install ${bldblk}ensures you are on the latest gem version\n"
187
+ printf " ${bldylw}— generate ${bldblk}create a new secure key, and copies it to \n"
188
+ printf " clipboard (if supported), otherwise prints to STDOUT\n"
189
+ printf " Key is required, and used as a name within OSX KeyChain\n\n"
190
+ printf " ${bldylw}— import [key] [insecure]\n"
191
+ printf " ${bldblk}imports the key from clipboard and adds password\n"
192
+ printf " encryption unless 'insecure' is passed in\n\n"
193
+ printf " ${bldylw}— edit ${bldblk}Finds all files, and opens them in $EDITOR\n"
194
+ printf " ${bldylw}— encrypt ${bldblk}Encrypts files matching file-path\n"
195
+ printf " ${bldylw}— decrypt ${bldblk}Adds the extension to file pattern and decrypts\n"
196
+ printf " ${bldylw}— auto ${bldblk}encrypts decrypted file, and vice versa\n"
197
+
198
+ echo
199
+ __lib::color::h2 "Flags:"
200
+ printf " -f | --folder DIR ${bldblk}Top level folder to search.${clr}\n"
201
+ printf " -k | --key KEY ${bldblk}Key identifier${clr}\n"
202
+ printf " -x | --extension EXT ${bldblk}Default extension of encrypted files.${clr}\n"
203
+ printf " -n | --dry-run ${bldblk}Print stuff, but don't do it${clr}\n"
204
+ printf " -h | --help ${bldblk}Show this help message${clr}\n"
205
+
206
+ echo
207
+ __lib::color::h2 'Encryption key identifier can be:'
208
+ printf "${clr}\
209
+ 1. name of the keychain item storing the keychain (secure)
210
+ 2. name of the environment variable storing the Key (*)
211
+ 3. name of the file storing the key (*)
212
+ 4. the key itself (*)
213
+
214
+ ${bldred}(*) 2-4 are insecure UNLESS the key is encrypted with a password.${clr}
215
+
216
+ Please refer to README about generating password protected keys:
217
+ ${bldblu}${undblu}https://github.com/kigster/sym#generating-the-key--examples${clr}\n\n"
218
+
219
+ echo
220
+
221
+ __lib::color::h1 'Examples:'
222
+
223
+ printf " Ex1: To import a key securely,\n"
224
+ printf " \$ ${bldgrn}symit${bldblu} import key ${clr}\n\n"
225
+
226
+ printf " Ex2.: To encrypt (or decrypt) ALL files in the 'config' directory:${clr}\n"
227
+ printf " \$ ${bldgrn}symit${bldblu} encrypt|decrypt -a -f config ${clr}\n\n"
228
+
229
+ printf " Ex3: To decrypt all *.yml.enc files in the 'config' directory:${clr}\n"
230
+ printf " \$ ${bldgrn}symit${bldblu} decrypt '*.yml' -f config ${clr}\n\n"
231
+
232
+ printf " Ex4: To edit an encrypted file ${txtblu}config/application.yml.enc${clr}\n"
233
+ printf " \$ ${bldgrn}symit${bldblu} application.yml${clr}\n\n"
234
+
235
+ printf " Ex5.: To auto decrypt a file ${txtblu}config/settings/crypt/pass.yml.enc${clr}\n"
236
+ printf " \$ ${bldgrn}symit${bldblu} auto config/settings/crypt/pass.yml.enc${clr}\n\n"
237
+
238
+ printf " Ex6.: To automatically decide to either encrypt or decrypt a file,\n"
239
+ printf " based on the file extension. First example encrypts the file, second\n"
240
+ printf " decrypts it (because file extension is .enc):${clr}\n"
241
+ printf " \$ ${bldgrn}symit${bldblu} auto config/settings/crypt/pass.yml${clr}\n"
242
+ printf " \$ ${bldgrn}symit${bldblu} auto config/settings/crypt/pass.yml.enc${clr}\n\n"
243
+
244
+ printf " Ex7.: To encrypt a file ${txtblu}config/settings.yml${clr}\n"
245
+ printf " \$ ${bldgrn}symit${bldblu} encrypt config/settings.yml${clr}\n\n"
76
246
 
77
- ${bldgrn}symit production${txtrst}\n\n"
247
+ }
248
+ function __datum() {
249
+ date +"%m/%d/%Y.%H:%M:%S"
78
250
  }
79
251
 
80
- symit::error() {
81
- printf "${bldred}error: $* ${bldylw}\n\n"
252
+ function __err() {
253
+ #__lib::color::cursor_to_col 0
254
+ printf "${txtpur}[$(__datum)] ${bldred}ERROR: ${txterr}$* ${bldylw}\n"
82
255
  }
83
256
 
84
- symit::install() {
257
+ function __inf() {
258
+ #__lib::color::cursor_to_col 0
259
+ printf "${txtpur}[$(__datum)] ${bldgrn}INFO: ${clr}${bldblu}$*${clr}\n"
260
+ }
261
+
262
+ function __symit::install::gem() {
263
+ __inf "Verifying current Sym version, please wait..."
85
264
  if [[ -z "${_symit__installed}" ]]; then
86
265
  current_version=$(gem list | grep sym | awk '{print $2}' | sed 's/(//g;s/)//g')
87
266
  if [[ -z "${current_version}" ]]; then
@@ -91,75 +270,170 @@ symit::install() {
91
270
  unset SYM_ARGS
92
271
  remote_version=$(gem search sym | egrep '^sym \(' | awk '{print $2}' | sed 's/(//g;s/)//g')
93
272
  if [[ "${remote_version}" != "${current_version}" ]]; then
94
- printf "detected an older ${bldgrn}sym (${current_version}), installing ${bldgrn}sym (${remote_version})${txtrst}...\n"
95
- echo y | gem uninstall sym -a 2>/dev/null
273
+ __inf "detected an older ${bldgrn}sym (${current_version})"
274
+ __inf "installing ${bldgrn}sym (${remote_version})${clr}..."
275
+ echo y | gem uninstall sym -a 2> /dev/null
96
276
  gem install sym
97
277
  export _symit__installed="yes"
278
+ __inf "Installed sym version ${bldylw}$(sym --version)"
98
279
  else
99
- printf "${bldgrn}sym${txtrst} is on the latest version ${remote_version} already\n"
280
+ __inf "${bldgrn}sym${clr} ${txtblu}is on the latest version ${remote_version} already\n"
100
281
  fi
101
282
  fi
102
283
  fi
103
284
  }
285
+ function __symit::files() {
286
+ eval $(__symit::files::cmd)
287
+ }
104
288
 
105
- symit::locs() {
106
- if [[ -n ${encrypted_file} ]]; then
107
- [[ -n ${cli__opts[extension]} ]] && export sym__ext=${cli__opts[extension]}
108
- declare -a locations=("${sym__folder}/${encrypted_file}.${sym__ext}" "${sym__folder}/${encrypted_file}" "${encrypted_file}")
289
+ function __symit::files::cmd() {
290
+ if [[ -n ${cli__opts[file]} && -n ${cli__opts[extension]} ]]; then
291
+ local folder
292
+ if [[ ${cli__opts[file]} =~ '/' ]]; then
293
+ folder="${cli__opts[folder]}/$(dirname ${cli__opts[file]})"
294
+ else
295
+ folder="${cli__opts[folder]}"
296
+ fi
297
+ local file="$(basename ${cli__opts[file]})"
298
+ local ext="${cli__opts[extension]}"
299
+
300
+ if [[ "${cli__opts[action]}" == "auto" || "${cli__opts[action]}" == "encrypt" ]] ; then
301
+ #find ${folder} -name "${file}" >&2
302
+ printf "find ${folder} -name '${file}' -and -not -name '*${ext}'"
303
+ else
304
+ #find ${folder} -name "${file}${ext}" >&2
305
+ printf "find ${folder} -name '${file}${ext}'"
306
+ fi
109
307
  fi
110
- echo -n ${locations[*]}
111
308
  }
112
309
 
113
- symit::locs::print() {
114
- printf "Search locations:\n"
115
- for loc in ${locations[@]}; do
116
- if [[ -n "${loc}" ]] ; then
117
- printf "\t - ${bldblu}${loc}${txtrst}\n"
310
+ function __symit::command() {
311
+ file=${1}
312
+ if [[ -n "${cli__opts[key]}" && -n "${cli__opts[extension]}" ]]; then
313
+ action="${cli__opts[action]}"
314
+ flags="${sym__actions[${action}]}"
315
+ if [[ ${action} =~ "key" ]]; then
316
+ [[ -n ${cli__opts[verbose]} ]] && printf "processing key import action ${bldylw}${action}${clr}\n" >&2
317
+ printf "sym ${flags} ${cli__opts[key]} "
318
+ elif [[ ${action} =~ "generate" ]] ; then
319
+ [[ -n ${cli__opts[verbose]} ]] && printf "processing generate key action ${bldylw}${action}${clr}\n" >&2
320
+ if [[ -n $(which pbcopy) ]]; then
321
+ out_key=/tmp/outkey
322
+ command="sym ${flags} ${cli__opts[key]} -q -o ${out_key}; cat ${out_key} | pbcopy; rm -f ${out_key}"
323
+ printf "${command}"
324
+ else
325
+ printf "sym ${flags} ${cli__opts[key]} "
326
+ fi
327
+ elif [[ -n ${file} ]] ; then
328
+ ext="${cli__opts[extension]}"
329
+ [[ -z ${ext} ]] && ext='.enc'
330
+ ext=$(echo ${ext} | sed -E 's/[\*\/,.]//g')
331
+ if [[ ${action} =~ "encrypt" ]]; then
332
+ printf "sym ${flags} ${file} -ck ${cli__opts[key]} -o ${file}.${ext}"
333
+ elif [[ ${action} =~ "decrypt" ]]; then
334
+ new_name=$(echo ${file} | sed "s/\.${ext}//g")
335
+ [[ "${new_name}" == "${file}" ]] && name="${file}.decrypted"
336
+ printf "sym ${flags} ${file} -ck ${cli__opts[key]} -o ${new_name}"
337
+ else
338
+ printf "sym ${flags} ${file} -ck ${cli__opts[key]} "
339
+ fi
340
+ else
341
+ printf "printf \"ERROR: not sure how to generate a correct command\\n\""
118
342
  fi
119
- done
343
+ fi
120
344
  }
121
345
 
122
- symit::exit() {
346
+ function __symit::cleanup() {
347
+ unset sym__actions
348
+ unset cli__opts
349
+ }
350
+
351
+ function __symit::exit() {
123
352
  code=${1:-0}
353
+ __symit::cleanup
124
354
  echo -n ${code}
125
355
  }
126
356
 
127
- symit::cleanup() {
128
- unset encrypted_file
129
- unset cli__opts
130
- unset locations
357
+ function __symit::print_cli_args() {
358
+ local -A args=$@
359
+ __inf "action ${bldylw}: ${cli__opts[action]}${clr}"
360
+ __inf "key ${bldylw}: ${cli__opts[key]}${clr}"
361
+ __inf "file ${bldylw}: ${cli__opts[file]}${clr}"
362
+ __inf "extension ${bldylw}: ${cli__opts[extension]}${clr}"
363
+ __inf "folder ${bldylw}: ${cli__opts[folder]}${clr}"
364
+ __inf "verbose ${bldylw}: ${cli__opts[verbose]}${clr}"
365
+ __inf "dry_run ${bldylw}: ${cli__opts[dry_run]}${clr}"
366
+ }
367
+
368
+ function __symit::args::needs_file() {
369
+ if [[ "${cli__opts[action]}" == 'edit' || \
370
+ "${cli__opts[action]}" == 'auto' || \
371
+ "${cli__opts[action]}" == 'encrypt' || \
372
+ "${cli__opts[action]}" == 'decrypt' ]]; then
373
+ printf 'yes'
374
+ fi
131
375
  }
132
376
 
133
- symit() {
134
- [[ -n "${1}" && "${1:0:1}" != "-" ]] && {
135
- export encrypted_file=$1
136
- shift
137
- }
377
+ function __symit::validate_args() {
378
+ if [[ -n $(__symit::args::needs_file) && -z ${cli__opts[file]} ]]; then
379
+ __err "missing file argument, config/application.yml"
380
+ return $(__symit::exit 2)
381
+ fi
138
382
 
139
- symit::init
383
+ if [[ -z "${cli__opts[key]}" ]]; then
384
+ __err "Key was not defined, pass it with ${bldblu}-k KEY_ID${bldred}"
385
+ __err "or set it via ${bldgrn}\$SYMIT__KEY${bldred} variable."
386
+ return $(__symit::exit 4)
387
+ fi
388
+
389
+ if [[ -z ${cli__opts[extension]} ]]; then
390
+ cli__opts[extension]='.enc'
391
+ fi
392
+ }
393
+
394
+ function __symit::run() {
395
+
396
+ __symit::cleanup
397
+ __symit::init
140
398
 
141
399
  declare -A cli__opts=(
142
- [verbose]=${true}
143
- [key]=${sym__key}
144
- [extension]=${sym__ext}
145
- [dry_run]=${false}
400
+ [verbose]=''
401
+ [key]=${SYMIT__KEY}
402
+ [extension]=${SYMIT__EXTENSION}
403
+ [folder]=${SYMIT__FOLDER}
404
+ [dry_run]=''
405
+ [action]=edit
406
+ [file]=''
146
407
  )
147
408
 
148
- [[ -z ${encrypted_file} && -z $* ]] && symit::usage
409
+ declare -A sym__actions=(
410
+ [generate]=' -cpgx '
411
+ [edit]=' -t '
412
+ [encrypt]='-e -f '
413
+ [decrypt]='-d -f '
414
+ [auto]=' -n '
415
+ [key_secure]=' -iqcpx '
416
+ [key_insecure]=' -iqcx '
417
+ )
418
+
419
+ if [[ -z $1 ]]; then
420
+ __symit::usage
421
+ return $(__symit::exit 0)
422
+ fi
149
423
 
150
424
  while :; do
151
425
  case $1 in
152
426
  -h|-\?|--help)
153
427
  shift
154
- symit::usage
155
- symit::cleanup
156
- return $(symit::exit 0)
428
+ __symit::usage
429
+ __symit::cleanup
430
+ return $(__symit::exit 0)
157
431
  ;;
158
432
 
159
433
  -k|--key)
160
434
  shift
161
435
  if [[ -z $1 ]]; then
162
- symit::error "-k/--key requires an argument" && return $(symit::exit 1)
436
+ __err "-k/--key requires an argument" && return $(__symit::exit 1)
163
437
  else
164
438
  cli__opts[key]=$1
165
439
  shift
@@ -169,94 +443,123 @@ symit() {
169
443
  -x|--extension)
170
444
  shift
171
445
  if [[ -z $1 ]]; then
172
- symit::error "-x/--extension requires an argument" && return $(symit::exit 1)
446
+ __err "-x/--extension requires an argument" && return $(__symit::exit 1)
173
447
  else
174
448
  cli__opts[extension]=${1}
175
449
  shift
176
450
  fi
177
451
  ;;
178
452
 
179
- -l|--locations)
453
+ -f|--folder)
180
454
  shift
181
- cli__opts[locations]=${true}
455
+ if [[ -z $1 ]]; then
456
+ __err "-f/--folder requires an argument" && return $(__symit::exit 1)
457
+ else
458
+ cli__opts[folder]=${1}
459
+ shift
460
+ fi
182
461
  ;;
183
462
 
184
- -i|--install)
463
+ -a|--all-files)
185
464
  shift
186
- symit::install
187
- symit::cleanup
188
- return $(symit::exit 0)
465
+ cli__opts[file]="'*'"
189
466
  ;;
190
467
 
191
468
  -n|--dry-run)
192
469
  shift
193
- cli__opts[dry_run]=${true}
470
+ cli__opts[dry_run]="yes"
471
+ ;;
472
+
473
+ -v|--verbose)
474
+ shift
475
+ cli__opts[verbose]="yes"
476
+ ;;
477
+
478
+ import|key)
479
+ shift
480
+ cli__opts[action]="key_secure"
481
+ ;;
482
+
483
+ insecure)
484
+ shift
485
+ if [[ "${cli__opts[action]}" == 'key_secure' ]] ; then
486
+ cli__opts[action]="key_insecure"
487
+ fi
194
488
  ;;
195
489
 
196
- --) # End of all options.
490
+ --) # End of all options.
197
491
  shift
198
492
  break
199
493
  ;;
200
494
 
201
495
  -?*)
202
- printf 'WARN: Unknown option (ignored): %s\n' "$1" >&2
203
- symit::cleanup
204
- return $(symit::exit 127)
496
+ __err 'WARN: Unknown option: %s\n' "$1" >&2
497
+ return $(__symit::exit 127)
205
498
  shift
206
499
  ;;
207
500
 
208
- *) # Default case: If no more options then break out of the loop.
501
+
502
+ ?*)
503
+ param=$1
504
+ if [[ -n "${sym__actions[${param}]}" ]]; then
505
+ cli__opts[action]=${param}
506
+ else
507
+ cli__opts[file]=${1}
508
+ fi
509
+ shift
510
+ ;;
511
+
512
+ *) # Default case: If no more options then break out of the loop.
209
513
  break
210
514
  shift
211
515
  esac
212
516
  done
213
517
 
214
- declare -a locations=$(symit::locs)
518
+ [[ -n ${cli__opts[verbose]} ]] &&__symit::print_cli_args
215
519
 
216
- if [[ ${cli__opts[locations]} == ${true} ]]; then
217
- if [[ -z ${encrypted_file} ]]; then
218
- symit::error "-l/--locations requires file-spec to be provided as the 1st argument"
219
- symit::cleanup
220
- return $(symit::exit 2)
520
+ if [[ "${cli__opts[action]}" == 'install' ]]; then
521
+ if [[ -n ${cli__opts[dry_run]} ]]; then
522
+ __inf "This command verifies that Sym is properly installed,"
523
+ __inf "and if not found — installs it."
524
+ return $(__symit::exit 0)
221
525
  else
222
- symit::locs::print
223
- symit::cleanup
224
- return $(symit::exit 0)
526
+ __symit::install::gem
527
+ return $(__symit::exit 0)
225
528
  fi
226
529
  fi
227
530
 
228
- if [[ -z "${encrypted_file}" ]]; then
229
- symit::error "Missing 1st argument — file name to be loaded, eg 'production', etc."
230
- symit::cleanup
231
- return $(symit::exit 3)
232
- fi
233
-
234
- if [[ -z "${cli__opts[key]}" ]]; then
235
- symit::error "Key was not defined, pass it with ${bldblu}-k key-spec${bldred} or set it via ${bldgrn}\$sym__key${bldred} variable."
236
- symit::cleanup
237
- return $(symit::exit 4)
238
- fi
239
-
240
- file=
241
- for loc in ${locations[@]}; do
242
- if [[ -s "${loc}" ]] ; then
243
- file=${loc}
244
- break
531
+ __symit::validate_args
532
+
533
+ changed_count=0
534
+
535
+ if [[ -n "${cli__opts[dry_run]}" ]] ; then
536
+ __lib::color::h1 "Dry Run — printing commands that would be run:"
537
+ for file in $(__symit::files); do
538
+ printf " \$ ${bldblu}$(__symit::command ${file})${clr}\n"
539
+ done
540
+ else
541
+ if [[ -n "${cli__opts[file]}" ]]; then
542
+ [[ -n ${cli__opts[verbose]} ]] && __inf $(__symit::files)
543
+ declare -a file_list
544
+ for file in $(__symit::files); do
545
+ file_list=(${file} "${file_list[*]}")
546
+ __inf "❯ ${bldblu}$(__symit::command ${file})${clr}"
547
+ eval $(__symit::command ${file})
548
+ code=$?; [[ ${code} != 0 ]] && __err "sym returned non-zero code ${code}"
549
+ done
550
+ if [[ ${#file_list} == 0 ]]; then
551
+ __inf "No files matched your specification. The following 'find' command"
552
+ __inf "ran to find them: \n"
553
+ __inf " ${bldylw}$(__symit::files::cmd)${clr}\n\n"
554
+ return $(__symit::exit 5)
555
+ fi
556
+ else
557
+ [[ -n ${cli__opts[verbose]} ]] && __inf $(__symit::command)
558
+ eval $(__symit::command)
559
+ code=$?; [[ ${code} != 0 ]] && return $(__symits::exit ${code})
245
560
  fi
246
- done
247
-
248
- [[ -z "${file}" ]] && {
249
- symit::error "${bldylw}${encrypted_file}${bldred} could not be found."
250
- symit::locs::print
251
- symit::cleanup
252
- return $(symit::exit 5)
253
- }
254
-
255
- command="sym -ck ${cli__opts[key]} -t ${file}"
256
-
257
- [[ ${cli_opts[dry_run]} ]] && printf "[dry_run] "
258
-
259
- printf "${bldgrn}${command}${txtrst}\n"
260
-
261
- [[ ${cli_opts[dry_run]} ]] || ${command}
561
+ fi
562
+ }
563
+ function symit() {
564
+ __symit::run $@
262
565
  }