sym 2.8.0 → 2.10.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.
Files changed (50) hide show
  1. checksums.yaml +5 -5
  2. data/.circleci/config.yml +30 -31
  3. data/.envrc +7 -0
  4. data/.gitignore +1 -0
  5. data/.rubocop.yml +150 -928
  6. data/.travis.yml +16 -26
  7. data/CHANGELOG.md +206 -167
  8. data/Gemfile +1 -0
  9. data/README.adoc +650 -0
  10. data/Rakefile +9 -3
  11. data/bin/{sym.completion → sym.completion.bash} +9 -14
  12. data/bin/sym.symit.bash +781 -0
  13. data/codecov.yml +29 -0
  14. data/design/sym-help.png +0 -0
  15. data/exe/keychain +1 -1
  16. data/exe/sym +5 -2
  17. data/lib/ruby_warnings.rb +7 -0
  18. data/lib/sym.rb +1 -7
  19. data/lib/sym/app.rb +1 -1
  20. data/lib/sym/app/args.rb +3 -2
  21. data/lib/sym/app/cli.rb +1 -2
  22. data/lib/sym/app/cli_slop.rb +1 -1
  23. data/lib/sym/app/commands.rb +1 -1
  24. data/lib/sym/app/commands/base_command.rb +1 -1
  25. data/lib/sym/app/commands/bash_completion.rb +20 -8
  26. data/lib/sym/app/commands/open_editor.rb +1 -1
  27. data/lib/sym/app/commands/password_protect_key.rb +4 -4
  28. data/lib/sym/app/commands/show_examples.rb +1 -1
  29. data/lib/sym/app/input/handler.rb +7 -1
  30. data/lib/sym/app/keychain.rb +15 -9
  31. data/lib/sym/app/output/noop.rb +2 -1
  32. data/lib/sym/app/password/cache.rb +1 -1
  33. data/lib/sym/app/password/providers.rb +2 -3
  34. data/lib/sym/app/private_key/decryptor.rb +2 -2
  35. data/lib/sym/app/private_key/detector.rb +4 -7
  36. data/lib/sym/application.rb +6 -11
  37. data/lib/sym/constants.rb +28 -13
  38. data/lib/sym/data/wrapper_struct.rb +20 -12
  39. data/lib/sym/errors.rb +11 -2
  40. data/lib/sym/extensions/instance_methods.rb +7 -8
  41. data/lib/sym/extensions/stdlib.rb +0 -1
  42. data/lib/sym/extensions/with_retry.rb +1 -1
  43. data/lib/sym/extensions/with_timeout.rb +1 -1
  44. data/lib/sym/version.rb +30 -5
  45. data/sym.gemspec +35 -35
  46. metadata +88 -71
  47. data/.codeclimate.yml +0 -30
  48. data/README.md +0 -623
  49. data/bin/sym.symit +0 -565
  50. data/lib/sym/app/password/providers/drb_provider.rb +0 -41
@@ -1,565 +0,0 @@
1
- #!/usr/bin/env bash
2
- #
3
- # (c) 2017-2018 Konstantin Gredeskoul
4
- #
5
- # MIT License, distributed as part of `sym` ruby gem.
6
- # • https://github.com/kigster/sym
7
- #
8
- #==============================================================================
9
- #
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
- #
14
- # If you set some or (ideally) ALL variables below to values specific to your
15
- # system, things will get easy.
16
- #
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.
21
- #
22
- # Variables:
23
- #
24
- # # only search ./config folder
25
- # export SYMIT__FOLDER="config"
26
- #
27
- # # this will be the name of your key in OS-X KeyChain
28
- # export SYMIT__KEY="MY_KEYCHAIN_NAME"
29
- #
30
- # # This is the extension given to the encrypted files. Ideally, leave it
31
- # # be as ".enc"
32
- # export SYMIT__EXTENSION=".enc"
33
- #
34
- # And then
35
- #
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
- #
41
- #
42
- # ...and vola! You are editing the encrypted file with sym from the root of
43
- # your Rails application. Neat, no?
44
- #
45
-
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
- }
108
-
109
- function __lib::color::hr() {
110
- local cols=${1:-${COLUMNS}}
111
- local char=${2:-"—"}
112
- local color=${3:-${txtylw}}
113
-
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"
138
- }
139
-
140
- ((${setup_colors_loaded})) ||__lib::color::setup
141
-
142
-
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"
146
-
147
- printf "Please add 'source $0' to your BASH initialization file,\n"
148
- printf "or run the following command:\n\n"
149
-
150
- printf " \$ ${bldgrn}sym -B ~/.bash_profile${clr}\n\n"
151
-
152
- printf "${bldblu}Thanks for using Sym!${clr}\n"
153
- exit 1
154
-
155
- }
156
-
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"
246
-
247
- }
248
- function __datum() {
249
- date +"%m/%d/%Y.%H:%M:%S"
250
- }
251
-
252
- function __err() {
253
- #__lib::color::cursor_to_col 0
254
- printf "${txtpur}[$(__datum)] ${bldred}ERROR: ${txterr}$* ${bldylw}\n"
255
- }
256
-
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..."
264
- if [[ -z "${_symit__installed}" ]]; then
265
- current_version=$(gem list | grep sym | awk '{print $2}' | sed 's/(//g;s/)//g')
266
- if [[ -z "${current_version}" ]]; then
267
- gem install sym
268
- else
269
- local help=$(sym -h 2>&1)
270
- unset SYM_ARGS
271
- remote_version=$(gem search sym | egrep '^sym \(' | awk '{print $2}' | sed 's/(//g;s/)//g')
272
- if [[ "${remote_version}" != "${current_version}" ]]; then
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
276
- gem install sym
277
- export _symit__installed="yes"
278
- __inf "Installed sym version ${bldylw}$(sym --version)"
279
- else
280
- __inf "${bldgrn}sym${clr} ${txtblu}is on the latest version ${remote_version} already\n"
281
- fi
282
- fi
283
- fi
284
- }
285
- function __symit::files() {
286
- eval $(__symit::files::cmd)
287
- }
288
-
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
307
- fi
308
- }
309
-
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\""
342
- fi
343
- fi
344
- }
345
-
346
- function __symit::cleanup() {
347
- unset sym__actions
348
- unset cli__opts
349
- }
350
-
351
- function __symit::exit() {
352
- code=${1:-0}
353
- __symit::cleanup
354
- echo -n ${code}
355
- }
356
-
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
375
- }
376
-
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
382
-
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
398
-
399
- declare -A cli__opts=(
400
- [verbose]=''
401
- [key]=${SYMIT__KEY}
402
- [extension]=${SYMIT__EXTENSION}
403
- [folder]=${SYMIT__FOLDER}
404
- [dry_run]=''
405
- [action]=edit
406
- [file]=''
407
- )
408
-
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
423
-
424
- while :; do
425
- case $1 in
426
- -h|-\?|--help)
427
- shift
428
- __symit::usage
429
- __symit::cleanup
430
- return $(__symit::exit 0)
431
- ;;
432
-
433
- -k|--key)
434
- shift
435
- if [[ -z $1 ]]; then
436
- __err "-k/--key requires an argument" && return $(__symit::exit 1)
437
- else
438
- cli__opts[key]=$1
439
- shift
440
- fi
441
- ;;
442
-
443
- -x|--extension)
444
- shift
445
- if [[ -z $1 ]]; then
446
- __err "-x/--extension requires an argument" && return $(__symit::exit 1)
447
- else
448
- cli__opts[extension]=${1}
449
- shift
450
- fi
451
- ;;
452
-
453
- -f|--folder)
454
- shift
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
461
- ;;
462
-
463
- -a|--all-files)
464
- shift
465
- cli__opts[file]="'*'"
466
- ;;
467
-
468
- -n|--dry-run)
469
- shift
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
488
- ;;
489
-
490
- --) # End of all options.
491
- shift
492
- break
493
- ;;
494
-
495
- -?*)
496
- __err 'WARN: Unknown option: %s\n' "$1" >&2
497
- return $(__symit::exit 127)
498
- shift
499
- ;;
500
-
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.
513
- break
514
- shift
515
- esac
516
- done
517
-
518
- [[ -n ${cli__opts[verbose]} ]] &&__symit::print_cli_args
519
-
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)
525
- else
526
- __symit::install::gem
527
- return $(__symit::exit 0)
528
- fi
529
- fi
530
-
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})
560
- fi
561
- fi
562
- }
563
- function symit() {
564
- __symit::run $@
565
- }