sym 2.7.0 → 2.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
  }