cl-magic 0.3.9 → 1.2.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.
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()