cl-magic 0.3.9 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/cl/magic/cl-dk CHANGED
@@ -10,327 +10,42 @@ require 'cl/magic/common/common_options.rb'
10
10
  require 'cl/magic/common/logging.rb'
11
11
  require 'cl/magic/common/parse_and_pick.rb'
12
12
 
13
- @logger = get_logger()
14
-
15
- #
16
- # Util Methods
17
- #
18
-
19
- def get_base_compose_hash()
20
- cmd = "cd #{@working_dir} && docker compose config 2> /dev/null"
21
- return YAML.load(`#{cmd}`)
22
- end
23
-
24
- def get_save_parts_filepath()
25
- return File.join(@working_dir, ".cl-dk-parts.yml")
26
- end
27
-
28
- def get_base_compose_parts_and_make_hashes()
29
- compose_hash = get_base_compose_hash()
30
- dk_parts_hash = {}
31
- dk_make_hash = {}
32
- if compose_hash
33
- compose_hash = merge_world_files(compose_hash, show_help=ARGV.include?("--help"))
34
- dk_parts_hash = compose_hash['x-dk-parts'] ? compose_hash.delete('x-dk-parts') : {}
35
- dk_make_hash = compose_hash['x-dk-make'] ? compose_hash.delete('x-dk-make') : {}
36
- end
37
- return compose_hash, dk_parts_hash, dk_make_hash
38
- end
13
+ require_relative 'dk/help_printer'
14
+ require_relative 'dk/yaml_arg_munger'
15
+ require_relative 'dk/world_settings'
16
+ require_relative 'dk/parts_merger'
39
17
 
40
- # world
41
-
42
- def get_repo_basename()
43
- command = "cd #{@working_dir} && basename $(git remote get-url origin 2> /dev/null) .git"
44
- return TTY::Command.new(:printer => :null).run(command).out.gsub('.git', '').strip.chomp
45
- end
46
-
47
- def get_world_settings_filepath()
48
- return File.join(".cl-dk-world.yml")
49
- end
50
-
51
- def get_world_settings_hash()
52
- filepath = get_world_settings_filepath()
53
- return File.exist?(filepath) ? YAML.load_file(filepath) : {}
54
- end
55
-
56
- def get_world_path_from_settings()
57
- world_settings = get_world_settings_hash()
58
- if world_settings.key?(:world_path) and world_settings.key?(:context)
59
- return File.join(world_settings[:world_path], world_settings[:context])
60
- end
61
- return ""
62
- end
63
-
64
- def save_world_settings(world_settings_hash)
65
- filepath = get_world_settings_filepath()
66
- tempfile = File.new(filepath, 'w')
67
- tempfile.write(world_settings_hash.to_yaml)
68
- tempfile.close
69
- end
70
-
71
- def get_world_project_path()
72
- repo_basename = get_repo_basename()
73
- world_path = get_world_path_from_settings()
74
- return File.join(world_path, repo_basename) if world_path and repo_basename
75
- return nil
76
- end
18
+ @logger = get_logger()
77
19
 
78
20
  #
79
21
  # Help Methods
80
22
  #
81
23
 
82
- def print_dk_help_line(key, help)
83
- if $stdout.isatty
84
- if help.nil?
85
- @logger.puts("#{key.ljust(15, ' ')} ???no help???")
86
- else
87
- key = key.ljust(15, ' ')
88
- help_parts = help.split(";")
89
-
90
- # first line
91
- @logger.puts(key, help_parts.shift)
92
-
93
- # following lines
94
- padding = "".ljust(15, ' ')
95
- help_parts.each do |p|
96
- @logger.puts(padding, p)
97
- end
98
- @logger.puts("") if help.end_with?(";")
99
- end
100
- end
101
- end
102
-
103
- def print_dk_help(dk_parts_hash, dk_make_hash, args)
24
+ def try_print_dk_help(dk_parts_hash, dk_make_hash, args)
104
25
  no_args = args.empty?()
105
26
  asked_for_help = args.include?('--help')
106
27
  has_dk_commands = dk_parts_hash.keys.any?
107
28
 
108
29
  if no_args or asked_for_help
109
- if has_dk_commands
110
- puts ""
111
- puts "Usage: dk [DK_PARTS] [COMPOSE_OPTIONS] COMPOSE_COMMAND"
112
- puts ""
113
- puts "Run docker compose while munging yamls in sophisticated ways."
114
- puts ""
115
- if get_repo_basename
116
- puts "PROJ INFO"
117
- puts " - Repo basename: #{get_repo_basename}"
118
- puts " - World filepath: #{get_world_project_path()}"
119
- puts ""
120
- end
121
- puts "PROJ PARTS"
122
- dk_parts_hash.keys.each do |key|
123
- print_dk_help_line(key, dk_parts_hash[key].fetch('help'))
124
- end
125
- puts ""
126
- puts "YML TOKENS"
127
- puts " - <dk-remove> removes section of yaml"
128
- puts " - <dk-replace> replaces values in a yaml array"
129
- puts " - <dk-world-path> absolute filepath to world directory"
130
- puts " - <dk-project-path> absolute filepath to world/project directory"
131
- puts " - <dk-working-path> absolute filepath to location dk command was run from"
132
- puts ""
133
- puts "ADDITIONAL TURNKEY COMMANDS"
134
- puts " - dk set-world sets the location of the world directory"
135
- puts " - dk make turnkey commands for a project"
136
- puts " - dk set-parts save parts so they are automatically applied to commands"
137
- puts ""
138
- puts "-------------------------"
139
- end
140
- end
141
- end
142
-
143
- def print_make_help(dk_parts_hash, dk_make_hash)
144
- if $stdout.isatty
145
30
  puts ""
146
- puts "Usage: dk [DK_PARTS] make COMMAND"
31
+ puts "Usage: dk [DK_PARTS] [COMPOSE_OPTIONS] COMPOSE_COMMAND"
147
32
  puts ""
148
- puts "Make commands designed to make your developer experience more turnkey"
33
+ puts "Run docker compose while munging yamls in sophisticated ways."
149
34
  puts ""
150
- puts "Parts:"
35
+ puts "PROJ PARTS"
151
36
  dk_parts_hash.keys.each do |key|
152
- print_dk_help_line(key, dk_parts_hash[key].fetch('help'))
37
+ @help_printer.print_dk_help_line(key, dk_parts_hash[key].fetch('help'))
153
38
  end
154
39
  puts ""
155
- puts "Commands:"
156
- dk_make_hash.keys.each do |key|
157
- print_dk_help_line(key, dk_make_hash[key].fetch('help'))
158
- end
40
+ puts "YML TOKENS"
41
+ puts " - <dk-remove> removes section of yaml"
42
+ puts " - <dk-replace> replaces values in a yaml array"
43
+ puts " - <dk-world-path> absolute filepath to world directory"
44
+ puts " - <dk-project-path> absolute filepath to world/project directory"
45
+ puts " - <dk-working-path> absolute filepath to location dk command was run from"
159
46
  puts ""
160
- else
161
- dk_make_hash.keys.each do |key|
162
- puts key
163
- end
164
- end
165
- end
166
-
167
- def print_set_world_help()
168
- puts ""
169
- puts "Usage: dk set-world PATH"
170
- puts ""
171
- puts "Set the folder that contains dk-world configuration"
172
- puts ""
173
- end
174
-
175
- def print_set_parts_help()
176
- compose_hash, dk_parts_hash, dk_make_hash = get_base_compose_parts_and_make_hashes()
177
-
178
- # print help
179
- puts ""
180
- puts "Usage: dk [DK_PARTS] set-parts"
181
- puts ""
182
- puts "Set parts for a project and apply to every 'dk' command"
183
- puts ""
184
- if dk_parts_hash.keys.any?
185
- puts "Parts:"
186
- dk_parts_hash.keys.each do |key|
187
- print_dk_help_line(key, dk_parts_hash[key].fetch('help'))
188
- end
189
- puts ""
190
- end
191
- end
192
-
193
- #
194
- # Yaml Merging
195
- #
196
-
197
- class ::Hash
198
- def dk_merge(second)
199
- merger = proc { |_, v1, v2|
200
- if Hash === v1 && Hash === v2
201
- v1.merge(v2, &merger)
202
- else
203
- if Array === v1 && Array === v2
204
- if v2.first=="<dk-replace>"
205
- v2[1..-1] # everything but the first item
206
- else
207
- v1 | v2 # union arrays
208
- end
209
- else
210
- if [:undefined, nil, :nil].include?(v2)
211
- v1
212
- else
213
- v2
214
- end
215
- end
216
- end
217
- }
218
- merge(second.to_h, &merger)
219
- end
220
- def dk_reject!(&blk)
221
- self.each do |k, v|
222
- v.dk_reject!(&blk) if v.is_a?(Hash)
223
- self.delete(k) if blk.call(k, v)
224
- end
225
- end
226
- end
227
-
228
- def dk_merge_and_remove(compose_hash, yml_hash)
229
- # remove help & merge
230
- clean_yml = yml_hash.clone
231
- clean_yml.delete('help')
232
- return compose_hash.dk_merge(clean_yml).dk_reject! { |k, v| v=='<dk-remove>' }
233
- end
234
-
235
- def merge_world_files(compose_hash, show_help=false)
236
- dk_proj_path = get_world_project_path()
237
- if dk_proj_path
238
- print_dk_help_line("dk-project-path", "#{dk_proj_path}") if show_help and $stdout.isatty
239
-
240
- Dir.glob("#{dk_proj_path}/*.yml").sort.each do |filepath|
241
- print_dk_help_line("dk-world", "#{filepath}") if show_help and $stdout.isatty
242
-
243
- # read file and replace
244
- contents = File.read(filepath)
245
- contents.gsub!('<dk-world-path>', get_world_path_from_settings())
246
- contents.gsub!('<dk-project-path>', dk_proj_path)
247
- contents.gsub!('<dk-working-path>', @working_dir)
248
-
249
- # yml merge
250
- yml_hash = YAML.load(contents)
251
- compose_hash = dk_merge_and_remove(compose_hash, yml_hash)
252
- end
253
- end
254
- return compose_hash
255
- end
256
-
257
- def get_saved_parts(dk_parts_hash)
258
- saved_part_keys = []
259
- filepath = get_save_parts_filepath()
260
-
261
- # merge
262
- if File.exist?(filepath)
263
- saved_parts = YAML.load_file(filepath)
264
- saved_parts.each do |potential_part_key|
265
- dk_part = dk_parts_hash.fetch(potential_part_key, nil) # yml detail
266
- if dk_part
267
- saved_part_keys << potential_part_key
268
- else
269
- @logger.error "invalid saved part: #{potential_part_key}"
270
- exit 1
271
- end
272
- end
273
- end
274
- return saved_part_keys
275
- end
276
-
277
- def merge_parts_save_and_prep_args(compose_hash, dk_parts_hash, dk_make_hash, saved_part_keys)
278
- tempfile = File.new(File.join(@working_dir, ".cl-dk.yml"), 'w')
279
- args = ARGV.clone
280
-
281
- # dk help
282
- print_dk_help(dk_parts_hash, dk_make_hash, args)
283
-
284
- def print_and_merge_part(part_key, dk_part, compose_hash)
285
-
286
- # print
287
- if $stdout.isatty
288
- help_str = dk_part.fetch('help')
289
- print_dk_help_line("#{part_key}", "#{help_str ? '- ' + help_str : ''}") if dk_part.keys.any?
290
- end
291
- # merge
292
- return dk_merge_and_remove(compose_hash, dk_part)
293
- end
294
-
295
- # saved parts
296
- saved_part_keys.each do |potential_part_key|
297
- dk_part = dk_parts_hash.fetch(potential_part_key, nil) # yml detail
298
- compose_hash = print_and_merge_part(potential_part_key, dk_part, compose_hash) if dk_part
299
- end
300
-
301
- # arg parts
302
- selected_part_keys = []
303
- while true
304
- potential_part_key = args.first
305
- dk_part = dk_parts_hash.fetch(potential_part_key, nil) # yml detail
306
- if dk_part
307
-
308
- # unless already applied
309
- unless saved_part_keys.include?(potential_part_key)
310
- compose_hash = print_and_merge_part(potential_part_key, dk_part, compose_hash)
311
- end
312
- selected_part_keys << potential_part_key
313
- args.shift # remove part arg
314
- else
315
- break
316
- end
47
+ puts "-------------------------"
317
48
  end
318
- @logger.puts "" if $stdout.isatty # tailing line break
319
- tempfile.write(compose_hash.to_yaml) # write it to the tempfile
320
-
321
- # clone args
322
- args = args.clone
323
-
324
- # remove existing '-f' flag, if needed
325
- file_flag_index = args.index('-f')
326
- if file_flag_index==0
327
- args.delete_at(file_flag_index)
328
- args.delete_at(file_flag_index)
329
- end
330
- args.unshift('-f', tempfile.path) # add new '-f' flag
331
-
332
- tempfile.close
333
- return args, selected_part_keys
334
49
  end
335
50
 
336
51
  #
@@ -343,147 +58,29 @@ def run_dk(compose_args)
343
58
  end
344
59
 
345
60
  #
346
- # Run: SET WORLD
61
+ # Features
347
62
  #
348
63
 
349
- def run_dk_set_world()
350
- world_settings = get_world_settings_hash()
64
+ def do_work()
351
65
 
352
- # world path
353
- world_path = ARGV[1]
354
- if world_path.nil?
355
- print_set_world_help
356
- exit
357
- else
358
- if world_path.start_with?("/") or world_path.start_with?("~")
359
- world_path = File.expand_path(world_path)
360
- else
361
- world_path = File.expand_path(File.join(@working_dir, world_path))
362
- end
363
- end
66
+ # utils
67
+ @help_printer = HelpPrinter.new(@logger)
68
+ @world_settings = WorldSettings.new(@working_dir)
69
+ @yaml_arg_munger = YamlArgMunger.new(@working_dir, @world_settings)
70
+ @parts_merger = PartsMerger.new(@working_dir, @yaml_arg_munger, @help_printer, @logger)
364
71
 
365
- if TTY::Prompt.new.yes?("Set world to: #{world_path}?")
366
- world_settings[:world_path] = world_path
367
- save_world_settings(world_settings)
368
- run_dk_set_context()
72
+ # world files
73
+ compose_hash, dk_parts_hash, dk_make_hash = @yaml_arg_munger.get_base_compose_parts_and_make_hashes()
74
+ if compose_hash
75
+ try_print_dk_help(dk_parts_hash, dk_make_hash, ARGV.clone)
76
+ compose_hash, selected_parts, shifted_args = @parts_merger.merge_parts(compose_hash, dk_parts_hash, ARGV.clone)
77
+ final_args = @yaml_arg_munger.save_yaml_and_adjust_args(compose_hash, shifted_args)
78
+ run_dk(final_args)
369
79
  else
370
- exit
371
- end
372
-
373
- end
374
-
375
- def run_dk_set_context()
376
- world_settings = get_world_settings_hash()
377
- unless world_settings[:world_path] and File.directory?(world_settings[:world_path])
378
- @logger.error "no world path set."
80
+ @logger.error "no docker configuration found"
379
81
  exit 1
380
82
  end
381
83
 
382
- # read folder from world path (aka. context)
383
- all_dir = Dir.chdir(world_settings[:world_path]) do
384
- Dir.glob('*').select { |f| File.directory? f and f != "common" }
385
- end
386
- selected_dir = pick_single_result(all_dir.collect {|f| [f]}, "select context").first
387
- world_settings[:context] = selected_dir
388
- save_world_settings(world_settings)
389
-
390
- @logger.puts "world set!"
391
- exit
392
- end
393
-
394
- #
395
- # Run: SET PARTS
396
- #
397
-
398
- def run_dk_set_parts()
399
- parts = ARGV[1..]
400
- filepath = get_save_parts_filepath()
401
- if parts.any?
402
- tempfile = File.new(filepath, 'w')
403
- tempfile.write(ARGV[1..].to_yaml) # write it to the tempfile
404
- tempfile.close
405
- else
406
- if File.exist?(filepath)
407
- File.delete(filepath)
408
- @logger.info "parts cleared"
409
- else
410
- print_set_parts_help()
411
- end
412
- end
413
- exit
414
- end
415
-
416
- #
417
- # Run: MAKE
418
- #
419
-
420
- def run_dk_make(compose_args, dk_make_hash, dk_parts_hash, selected_part_keys)
421
- # print help?
422
- no_make_command = (compose_args.count == 3)
423
- if no_make_command
424
- print_make_help(dk_parts_hash, dk_make_hash)
425
- else
426
-
427
- #
428
- # supports running multiple commands in a row
429
- # ex. dk make down up
430
- #
431
-
432
- make_commands = compose_args[3..]
433
- make_commands.each_with_index do |key, i|
434
-
435
- if not dk_make_hash.has_key?(key)
436
- @logger.error "#{key} - command not found"
437
- exit 1
438
- else
439
-
440
- all_commands = dk_make_hash[key]["commands"]
441
-
442
- #
443
- # all commands run in a subprocess except the last one, so
444
- # the last command can run in the forground and be
445
- # interactive (ex. dk make down up bash)
446
- #
447
-
448
- # construct last command
449
- last_cmd = if make_commands.length == i+1
450
- all_commands.pop
451
- else
452
- nil
453
- end
454
-
455
- # run background commands
456
- all_commands.each do |c|
457
- cmd = prep_make_command(c, selected_part_keys)
458
- `#{cmd}` # run in sub-process
459
- end
460
-
461
- # run last command in foreground
462
- if last_cmd
463
- cmd = prep_make_command(last_cmd, selected_part_keys)
464
- exec(cmd)
465
- end
466
- end
467
- end
468
-
469
- end
470
- end
471
-
472
- def prep_make_command(c, selected_part_keys)
473
- c = interpolate_parts_into_command(c, selected_part_keys)
474
-
475
- # logging
476
- @logger.puts "" if $stdout.isatty
477
- @logger.wait(c)
478
- cmd = "cd #{@working_dir} && #{c}"
479
- end
480
-
481
- def interpolate_parts_into_command(cmd, selected_part_keys)
482
- if selected_part_keys.any?
483
- parts = selected_part_keys.join(' ')
484
- return cmd.gsub("cl dk", "cl dk #{parts}")
485
- end
486
- return cmd
487
84
  end
488
85
 
489
86
  #
@@ -492,32 +89,4 @@ end
492
89
 
493
90
  @working_dir = ENV['CL_WORKING_DIR'] # passed through cl-magic to here
494
91
 
495
- # SET commands first
496
- case ARGV.first
497
- when "set-world"
498
- run_dk_set_world()
499
- when "set-context"
500
- run_dk_set_context()
501
- when "set-parts"
502
- run_dk_set_parts()
503
- else
504
- compose_hash, dk_parts_hash, dk_make_hash = get_base_compose_parts_and_make_hashes()
505
- if compose_hash
506
-
507
- # parts & args
508
- saved_part_keys = get_saved_parts(dk_parts_hash)
509
- compose_args, selected_part_keys = merge_parts_save_and_prep_args(compose_hash, dk_parts_hash, dk_make_hash, saved_part_keys)
510
-
511
- # sub-command
512
- case compose_args[2]
513
- when "make"
514
- all_part_keys = selected_part_keys + saved_part_keys
515
- run_dk_make(compose_args, dk_make_hash, dk_parts_hash, all_part_keys)
516
- else
517
- run_dk(compose_args)
518
- end
519
- else
520
- @logger.error "no docker configuration found"
521
- exit 1
522
- end
523
- end
92
+ do_work()
@@ -0,0 +1,174 @@
1
+ #!/usr/bin/env ruby
2
+ # cli for your compose projects
3
+ require 'optparse'
4
+ require 'optparse/subcommand'
5
+
6
+ require 'cl/magic/common/common_options.rb'
7
+ require 'cl/magic/common/logging.rb'
8
+
9
+ require_relative 'dk/help_printer'
10
+ require_relative 'dk/yaml_arg_munger'
11
+ require_relative 'dk/world_settings'
12
+ require_relative 'dk/parts_merger'
13
+
14
+ @logger = get_logger()
15
+ @cl_cmd_name = File.basename(__FILE__).split('-').join(' ')
16
+
17
+ def print_make_help(dk_parts_hash, dk_make_hash)
18
+ if $stdout.isatty
19
+ puts ""
20
+ puts "Usage: dk make [DK_PARTS] COMMAND"
21
+ puts ""
22
+ puts "Make commands designed to make your developer experience more turnkey"
23
+ puts ""
24
+ puts "Parts:"
25
+ dk_parts_hash.keys.each do |key|
26
+ @help_printer.print_dk_help_line(key, dk_parts_hash[key].fetch('help'))
27
+ end
28
+ puts ""
29
+ puts "Commands:"
30
+ dk_make_hash.keys.each do |key|
31
+ @help_printer.print_dk_help_line(key, dk_make_hash[key].fetch('help'))
32
+ end
33
+ puts ""
34
+ else
35
+ dk_make_hash.keys.each do |key|
36
+ puts key
37
+ end
38
+ end
39
+ end
40
+
41
+ def run_dk_make(final_args, dk_make_hash, dk_parts_hash, selected_parts)
42
+
43
+ # print help?
44
+ no_make_command = (final_args.count == 2)
45
+ if no_make_command
46
+ print_make_help(dk_parts_hash, dk_make_hash)
47
+ else
48
+
49
+ #
50
+ # supports running multiple commands in a row
51
+ # ex. dk make down up
52
+ #
53
+
54
+ make_commands = final_args[2..]
55
+ make_commands.each_with_index do |key, i|
56
+
57
+ if not dk_make_hash.has_key?(key)
58
+ @logger.error "#{key} - command not found"
59
+ exit 1
60
+ else
61
+
62
+ all_commands = dk_make_hash[key]["commands"]
63
+
64
+ #
65
+ # all commands run in a subprocess except the last one, so
66
+ # the last command can run in the forground and be
67
+ # interactive (ex. dk make down up bash)
68
+ #
69
+
70
+ # construct last command
71
+ last_cmd = if make_commands.length == i+1
72
+ all_commands.pop
73
+ else
74
+ nil
75
+ end
76
+
77
+ # run background commands
78
+ all_commands.each do |c|
79
+ cmd = prep_make_command(c, selected_parts)
80
+ `#{cmd}` # run in sub-process
81
+ end
82
+
83
+ # run last command in foreground
84
+ if last_cmd
85
+ cmd = prep_make_command(last_cmd, selected_parts)
86
+ exec(cmd)
87
+ end
88
+ end
89
+ end
90
+
91
+ end
92
+ end
93
+
94
+ def prep_make_command(c, selected_parts)
95
+ # logging
96
+ @logger.puts "" if $stdout.isatty
97
+ @logger.wait(c.gsub("cl dk", "dk"))
98
+
99
+ # run command
100
+ c = interpolate_parts_into_command(c, selected_parts)
101
+ cmd = "cd #{@working_dir} && #{c}"
102
+ end
103
+
104
+ def interpolate_parts_into_command(cmd, selected_parts)
105
+ cmd = "cl #{cmd}" if cmd.start_with?("dk")
106
+
107
+ # subcommands: don't need interpolated parts
108
+ ['parts', 'make', 'make-world', 'world'].each do |subcommand|
109
+ return cmd if cmd.start_with?("cl dk #{subcommand}")
110
+ end
111
+
112
+ if selected_parts.any?
113
+ parts = selected_parts.join(' ')
114
+ if cmd.include? "cl dk make"
115
+ return cmd.gsub("cl dk make", "cl dk make #{parts}")
116
+ else
117
+ return cmd.gsub("cl dk", "cl dk #{parts}")
118
+ end
119
+ end
120
+ return cmd
121
+ end
122
+
123
+ #
124
+ # Features
125
+ #
126
+
127
+ def do_work()
128
+
129
+ # utils
130
+ @help_printer = HelpPrinter.new(@logger)
131
+ @world_settings = WorldSettings.new(@working_dir)
132
+ @yaml_arg_munger = YamlArgMunger.new(@working_dir, @world_settings)
133
+ @parts_merger = PartsMerger.new(@working_dir, @yaml_arg_munger, @help_printer, @logger)
134
+
135
+ # world files
136
+ compose_hash, dk_parts_hash, dk_make_hash = @yaml_arg_munger.get_base_compose_parts_and_make_hashes()
137
+ if compose_hash
138
+ compose_hash, selected_parts, shifted_args = @parts_merger.merge_parts(compose_hash, dk_parts_hash, ARGV.clone)
139
+ final_args = @yaml_arg_munger.save_yaml_and_adjust_args(compose_hash, shifted_args)
140
+ run_dk_make(final_args, dk_make_hash, dk_parts_hash, selected_parts)
141
+ else
142
+ @logger.error "no docker configuration found"
143
+ exit 1
144
+ end
145
+
146
+ end
147
+
148
+ #
149
+ # Options
150
+ #
151
+
152
+ options = {}
153
+ global_banner = <<DOC
154
+
155
+ Cli for your compose projects
156
+
157
+ Usage: #{@cl_cmd_name} [options]
158
+
159
+ DOC
160
+
161
+ global = OptionParser.new do |g|
162
+ g.banner = global_banner
163
+ add_help_and_verbose(g)
164
+ end
165
+
166
+ #
167
+ # Run
168
+ #
169
+
170
+ @working_dir = ENV['CL_WORKING_DIR'] # passed through cl-magic to here
171
+
172
+ global.parse(ARGV)
173
+
174
+ do_work()