cl-magic 0.4.0 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,163 @@
1
+ #!/usr/bin/env ruby
2
+ # cli for your world
3
+ require 'yaml'
4
+ require 'optparse'
5
+ require 'optparse/subcommand'
6
+ require 'tty-command'
7
+
8
+ require 'cl/magic/common/common_options.rb'
9
+ require 'cl/magic/common/logging.rb'
10
+
11
+ require_relative 'dk/help_printer'
12
+ require_relative 'dk/world_settings'
13
+
14
+ @logger = get_logger()
15
+ @cl_cmd_name = File.basename(__FILE__).split('-').join(' ')
16
+
17
+ def print_make_help(dk_make_hash)
18
+ if $stdout.isatty
19
+ puts ""
20
+ puts "Usage: dk make-world COMMAND"
21
+ puts ""
22
+ puts "Make commands for your world"
23
+ puts ""
24
+ puts "Commands:"
25
+ dk_make_hash.keys.each do |key|
26
+ @help_printer.print_dk_help_line(key, dk_make_hash[key].fetch('help'))
27
+ end
28
+ puts ""
29
+ else
30
+ dk_make_hash.keys.each do |key|
31
+ puts key
32
+ end
33
+ end
34
+ end
35
+
36
+ def run_dk_make(final_args, dk_make_hash)
37
+
38
+ # print help?
39
+ if final_args.empty?
40
+ print_make_help(dk_make_hash)
41
+ else
42
+
43
+ #
44
+ # supports running multiple commands in a row
45
+ # ex. dk make down up
46
+ #
47
+
48
+ final_args.each_with_index do |key, i|
49
+
50
+ if not dk_make_hash.has_key?(key)
51
+ @logger.error "#{key} - command not found"
52
+ exit 1
53
+ else
54
+
55
+ all_commands = dk_make_hash[key]["commands"]
56
+
57
+ #
58
+ # all commands run in a subprocess except the last one, so
59
+ # the last command can run in the forground and be
60
+ # interactive (ex. dk make down up bash)
61
+ #
62
+
63
+ # construct last command
64
+ last_cmd = if final_args.length == i+1
65
+ all_commands.pop
66
+ else
67
+ nil
68
+ end
69
+
70
+ # run background commands
71
+ all_commands.each do |c|
72
+ cmd = prep_make_command(c)
73
+ puts `#{cmd}` # run in sub-process
74
+ end
75
+
76
+ # run last command in foreground
77
+ if last_cmd
78
+ cmd = prep_make_command(last_cmd)
79
+ exec(cmd)
80
+ end
81
+ end
82
+ end
83
+
84
+ end
85
+ end
86
+
87
+ def prep_make_command(c)
88
+ # logging
89
+ @logger.puts "" if $stdout.isatty
90
+ @logger.wait(c.gsub("cl dk", "dk"))
91
+
92
+ # run command - from world path
93
+ cmd = "cd #{@world_path} && WORKING_DIR=#{@working_dir} #{c}"
94
+ end
95
+
96
+ #
97
+ # Features
98
+ #
99
+
100
+ def do_work()
101
+
102
+ # world yaml
103
+ world_yaml_filepath = File.join(@world_path, "world.yml")
104
+ if File.exist?(world_yaml_filepath)
105
+
106
+ # read file, replace & yaml load
107
+ contents = File.read(world_yaml_filepath)
108
+ contents.gsub!('<dk-working-path>', @working_dir)
109
+ yml_hash = YAML.load(contents)
110
+
111
+ # run command
112
+ if yml_hash and yml_hash.key? "x-dk-make-world"
113
+ run_dk_make(ARGV, yml_hash["x-dk-make-world"])
114
+ else
115
+ @logger.puts ""
116
+ @logger.warn "no commands available"
117
+ @logger.info "#{world_yaml_filepath}"
118
+ @logger.puts ""
119
+ end
120
+ else
121
+ @logger.puts ""
122
+ @logger.warn "Current world context has no world.yml"
123
+ @logger.info "#{world_path}"
124
+ @logger.puts ""
125
+ end
126
+ end
127
+
128
+ #
129
+ # Options
130
+ #
131
+
132
+
133
+ options = {}
134
+ global_banner = <<DOC
135
+
136
+ Dk make world
137
+
138
+ Usage: #{@cl_cmd_name} [options]
139
+
140
+ DOC
141
+
142
+
143
+ global = OptionParser.new do |g|
144
+ g.banner = global_banner
145
+ add_help_and_verbose(g)
146
+ end
147
+
148
+ #
149
+ # Run
150
+ #
151
+
152
+ @working_dir = ENV['CL_WORKING_DIR'] # passed through cl-magic to here
153
+
154
+ global.parse(ARGV)
155
+
156
+ # utils
157
+ @world_settings = WorldSettings.new(@working_dir)
158
+ @help_printer = HelpPrinter.new(@logger)
159
+
160
+ # world path
161
+ @world_path = @world_settings.get_world_path_from_settings()
162
+
163
+ do_work()
@@ -0,0 +1,261 @@
1
+ #!/usr/bin/env ruby
2
+ # set, list and clear parts for a compose project
3
+ require 'yaml'
4
+ require 'optparse'
5
+ require 'optparse/subcommand'
6
+ require 'tty-command'
7
+
8
+ require 'cl/magic/common/common_options.rb'
9
+ require 'cl/magic/common/logging.rb'
10
+ require 'cl/magic/common/parse_and_pick.rb'
11
+
12
+ require_relative 'dk/help_printer'
13
+ require_relative 'dk/yaml_arg_munger'
14
+ require_relative 'dk/world_settings'
15
+ require_relative 'dk/parts_merger'
16
+
17
+ @logger = get_logger()
18
+ @cl_cmd_name = File.basename(__FILE__).split('-').join(' ')
19
+
20
+ def get_save_parts_filepath()
21
+ return File.join(@working_dir, ".cl-dk-parts.yml")
22
+ end
23
+
24
+ def yield_all_parts
25
+
26
+ # utils
27
+ @help_printer = HelpPrinter.new(@logger)
28
+ @world_settings = WorldSettings.new(@working_dir)
29
+ @yaml_arg_munger = YamlArgMunger.new(@working_dir, @world_settings)
30
+ @parts_merger = PartsMerger.new(@working_dir, @yaml_arg_munger, @help_printer, @logger)
31
+
32
+ # world files
33
+ compose_hash, dk_parts_hash, dk_make_hash = @yaml_arg_munger.get_base_compose_parts_and_make_hashes()
34
+ if compose_hash
35
+ yield dk_parts_hash
36
+ else
37
+ @logger.error "no docker configuration found"
38
+ exit 1
39
+ end
40
+ end
41
+
42
+ #
43
+ # Features
44
+ #
45
+
46
+ def do_set(options)
47
+
48
+ yield_all_parts do |dk_parts_hash|
49
+ parts = ARGV[1..]
50
+
51
+ if parts.any? or options[:action] == :set
52
+
53
+ # validate parts
54
+ parts.each do |part|
55
+ unless dk_parts_hash.include? part
56
+ puts ""
57
+ @logger.error "invalid part: #{part}"
58
+ @logger.info "allowed parts: #{dk_parts_hash.keys.join(", ")}"
59
+ puts ""
60
+ exit 1
61
+ end
62
+ end
63
+
64
+ create_file_unless_exists(options)
65
+
66
+ # save parts
67
+ filepath = get_save_parts_filepath()
68
+ parts = ARGV[1..]
69
+ case options[:action]
70
+ when :set
71
+ unless parts.any?
72
+ options = dk_parts_hash.keys.collect {|k| [k.ljust(25, ' '), dk_parts_hash[k]['help'].rjust(25, ' ')]}
73
+ selected_parts = pick_multiple_result(options, "Which parts?", nil, false)
74
+ parts = selected_parts.collect {|o| o.first.strip}
75
+ end
76
+ File.open(filepath, 'w') { |file| file.write(parts.to_yaml) }
77
+ @logger.success "parts set"
78
+ when :add
79
+ data = YAML.load_file(filepath)
80
+ parts.each {|p| data << p}
81
+ File.open(filepath, 'w') { |file| file.write(data.uniq.to_yaml) }
82
+ @logger.success "parts added"
83
+ when :remove
84
+ data = YAML.load_file(filepath)
85
+ data.reject! { |p| parts.include?(p) }
86
+ File.open(filepath, 'w') { |file| file.write(data.to_yaml) }
87
+ @logger.success "parts removed"
88
+ end
89
+ else
90
+ @logger.warn "you didn't pass any parts to set"
91
+ exit 1
92
+ end
93
+ exit
94
+
95
+ end
96
+
97
+ end
98
+
99
+ def create_file_unless_exists(options)
100
+ filepath = get_save_parts_filepath()
101
+ unless File.exist?(filepath)
102
+ File.open(filepath, 'w') { |file| file.write([].to_yaml) }
103
+ end
104
+ end
105
+
106
+ def do_clear(options)
107
+ filepath = get_save_parts_filepath()
108
+ if File.exist?(filepath)
109
+ File.delete(filepath)
110
+ @logger.info "parts cleared"
111
+ end
112
+ end
113
+
114
+ def get_saved_parts()
115
+ filepath = get_save_parts_filepath()
116
+ return YAML.load_file(filepath) if File.exist?(filepath)
117
+ return []
118
+ end
119
+
120
+ def do_list_saved_parts(options)
121
+
122
+ is_tty = $stdout.isatty
123
+
124
+ yield_all_parts do |dk_parts_hash|
125
+
126
+ saved_parts = get_saved_parts()
127
+ if saved_parts.any?
128
+ puts "" if is_tty
129
+ dk_parts_hash.keys.each do |part|
130
+ if is_tty
131
+ part_desc = "#{part.ljust(27, ' ')} | #{dk_parts_hash[part]['help']}"
132
+ if saved_parts.include? part
133
+ puts "* #{part_desc}"
134
+ else
135
+ puts " #{part_desc}"
136
+ end
137
+ else
138
+ puts part if saved_parts.include? part # terminal only
139
+ end
140
+ end
141
+ puts "" if is_tty
142
+ else
143
+ if is_tty
144
+ puts ""
145
+ @logger.info "no saved parts"
146
+ puts ""
147
+ dk_parts_hash.keys.each do |part|
148
+ puts " #{part}"
149
+ end
150
+ puts ""
151
+ end
152
+ end
153
+ end
154
+ end
155
+
156
+ #
157
+ # Options
158
+ #
159
+
160
+ options = {}
161
+ global_banner = <<DOC
162
+
163
+ Dk parts
164
+
165
+ Usage: #{@cl_cmd_name} [options]
166
+
167
+ DOC
168
+
169
+ dk_parts_set_banner = <<DOC
170
+
171
+ Set parts
172
+
173
+ Usage: #{@cl_cmd_name} set [options]
174
+
175
+ DOC
176
+
177
+ dk_parts_add_banner = <<DOC
178
+
179
+ Add parts
180
+
181
+ Usage: #{@cl_cmd_name} set [options]
182
+
183
+ DOC
184
+
185
+ dk_parts_remove_banner = <<DOC
186
+
187
+ Remove parts
188
+
189
+ Usage: #{@cl_cmd_name} set [options]
190
+
191
+ DOC
192
+
193
+ dk_parts_clear_banner = <<DOC
194
+
195
+ Clear parts
196
+
197
+ Usage: #{@cl_cmd_name} set [options]
198
+
199
+ DOC
200
+
201
+ dk_parts_list_banner = <<DOC
202
+
203
+ List saved parts
204
+
205
+ Usage: #{@cl_cmd_name} set [options]
206
+
207
+ DOC
208
+
209
+ global = OptionParser.new do |g|
210
+ g.banner = global_banner
211
+ add_help_and_verbose(g)
212
+
213
+ g.subcommand 'set' do |s|
214
+ s.banner = dk_parts_set_banner
215
+ options[:action] = :set
216
+ end
217
+
218
+ g.subcommand 'add' do |s|
219
+ s.banner = dk_parts_set_banner
220
+ options[:action] = :add
221
+ end
222
+
223
+ g.subcommand 'remove' do |s|
224
+ s.banner = dk_parts_set_banner
225
+ options[:action] = :remove
226
+ end
227
+
228
+ g.subcommand 'clear' do |s|
229
+ s.banner = dk_parts_clear_banner
230
+ options[:action] = :clear
231
+ end
232
+
233
+ g.subcommand 'list' do |s|
234
+ s.banner = dk_parts_list_banner
235
+ options[:action] = :list
236
+ end
237
+
238
+ end
239
+
240
+ #
241
+ # Run
242
+ #
243
+
244
+ @working_dir = ENV['CL_WORKING_DIR'] # passed through cl-magic to here
245
+
246
+ global.parse(ARGV)
247
+
248
+ case options[:action]
249
+ when :set
250
+ do_set(options)
251
+ when :add
252
+ do_set(options)
253
+ when :remove
254
+ do_set(options)
255
+ when :clear
256
+ do_clear(options)
257
+ when :list
258
+ do_list_saved_parts(options)
259
+ else
260
+ puts global.parse! %w[--help]
261
+ end
@@ -0,0 +1,140 @@
1
+ #!/usr/bin/env ruby
2
+ # set world and context for dk tool
3
+ require 'yaml'
4
+ require 'optparse'
5
+ require 'optparse/subcommand'
6
+ require 'tty-command'
7
+
8
+ require 'cl/magic/common/common_options.rb'
9
+ require 'cl/magic/common/parse_and_pick.rb'
10
+ require 'cl/magic/common/logging.rb'
11
+
12
+ require_relative 'dk/world_settings'
13
+
14
+ @logger = get_logger()
15
+ @cl_cmd_name = File.basename(__FILE__).split('-').join(' ')
16
+
17
+ #
18
+ # Features
19
+ #
20
+
21
+ def set(options, world_settings)
22
+ world_settings_hash = world_settings.get_world_settings_hash()
23
+
24
+ # world path
25
+ world_path = options[:world_path]
26
+
27
+ if world_path.start_with?("/") or world_path.start_with?("~")
28
+ world_path = File.expand_path(world_path)
29
+ else
30
+ world_path = File.expand_path(File.join(@working_dir, world_path))
31
+ end
32
+
33
+ if TTY::Prompt.new.yes?("Set world to: #{world_path}?")
34
+ world_settings_hash[:world_path] = world_path
35
+ world_settings.save_world_settings(world_settings_hash)
36
+ switch_context(world_settings)
37
+ else
38
+ exit
39
+ end
40
+
41
+ end
42
+
43
+ def switch_context(world_settings)
44
+ world_settings_hash = world_settings.get_world_settings_hash()
45
+ unless world_settings_hash[:world_path] and File.directory?(world_settings_hash[:world_path])
46
+ @logger.error "no world path set."
47
+ exit 1
48
+ end
49
+
50
+ # read folder from world path (aka. context)
51
+ all_dir = Dir.chdir(world_settings_hash[:world_path]) do
52
+ Dir.glob('*').select { |f| File.directory? f and f != "common" }
53
+ end
54
+ selected_dir = pick_single_result(all_dir.collect {|f| [f]}, "select context").first
55
+ world_settings_hash[:context] = selected_dir
56
+ world_settings.save_world_settings(world_settings_hash)
57
+
58
+ @logger.puts "world set!"
59
+ exit
60
+ end
61
+
62
+ #
63
+ # Options
64
+ #
65
+
66
+
67
+ options = {}
68
+ global_banner = <<DOC
69
+
70
+ Dk world
71
+
72
+ Usage: #{@cl_cmd_name} [options]
73
+
74
+ DOC
75
+
76
+ dk_world_set_banner = <<DOC
77
+
78
+ Set world
79
+
80
+ Usage: #{@cl_cmd_name} set [options]
81
+
82
+ DOC
83
+
84
+ dk_world_switch_context_banner = <<DOC
85
+
86
+ Set context
87
+
88
+ Usage: #{@cl_cmd_name} switch_context [options]
89
+
90
+ DOC
91
+
92
+
93
+ global = OptionParser.new do |g|
94
+ g.banner = global_banner
95
+ add_help_and_verbose(g)
96
+
97
+ g.subcommand 'set' do |s|
98
+ s.banner = dk_world_set_banner
99
+ options[:action] = :set
100
+
101
+ s.on("-p", "--path PATH", "path to world folder") do |v|
102
+ options[:world_path] = v
103
+ end
104
+ end
105
+
106
+ g.subcommand 'switch_context' do |s|
107
+ s.banner = dk_world_switch_context_banner
108
+ options[:action] = :switch_context
109
+ end
110
+
111
+ end
112
+
113
+ #
114
+ # Run
115
+ #
116
+
117
+ @working_dir = ENV['CL_WORKING_DIR'] # passed through cl-magic to here
118
+
119
+ global.parse(ARGV)
120
+
121
+ world_settings = WorldSettings.new(@working_dir)
122
+
123
+ case options[:action]
124
+ when :set
125
+ if options[:world_path].nil?
126
+ @logger.error("missing --path")
127
+ exit 1
128
+ end
129
+
130
+ history_command = """#{@cl_cmd_name} world set \\
131
+ --path #{options[:world_path]}
132
+ """
133
+ write_history(history_command)
134
+
135
+ set(options, world_settings)
136
+ when :switch_context
137
+ switch_context(world_settings)
138
+ else
139
+ puts global.parse! %w[--help]
140
+ end
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
- # Fetch jira issues, status changelogs and save them to a file
2
+ # Fetch jira issues by jql
3
3
  require 'optparse'
4
4
  require 'optparse/subcommand'
5
5
  require 'tty-command'
@@ -23,43 +23,25 @@ def do_work(options)
23
23
  break_at_one_page = false # when developing, set this to true
24
24
  jira = Jira.new options[:base_uri], options[:username], options[:token], break_at_one_page
25
25
 
26
- puts ""
27
- @logger.wait "fetch epics"
28
- epic_ids, epics = jira.get_epic_ids(options[:project], options[:epic_wildcard])
29
- @logger.success "#{epic_ids.count} epics"
30
-
31
- puts ""
26
+ @logger.puts ""
32
27
  @logger.wait "fetch issues"
33
- issues = jira.get_issues(options[:project], epic_ids)
34
- @logger.success "#{issues.count} issues"
35
-
36
- puts ""
37
- @logger.wait "fetch & merge change logs"
38
- issues = collect_status_changelogs(jira, issues, options)
39
- @logger.success ""
40
-
41
- puts ""
42
- @logger.wait "saving file"
43
- output_filepath = File.join(@working_dir, options[:output_filename])
44
- File.open(output_filepath, 'w') do |file|
45
- issues.each do |o|
46
- file.puts(o.to_json)
47
- end
48
- end
28
+ issues = jira.run_jql_query(options[:jql])
29
+
30
+ @logger.puts ""
31
+ @logger.wait "fetch & merge comments"
32
+ issues = jira.collect_comments(jira, issues)
49
33
 
50
- @logger.success " #{output_filepath}"
34
+ puts issues.to_json
51
35
  end
52
36
 
53
37
  #
54
38
  # Options
55
39
  #
56
40
 
57
- options = {
58
- output_filename: "jira-fetch-#{Time.now.strftime("%Y%m%d%H%M%S")}.datafile"
59
- }
41
+ options = {}
60
42
  global_banner = <<DOC
61
43
 
62
- Fetch jira issues, status changelogs and save them to a file
44
+ Fetch jira issues and their comments
63
45
 
64
46
  Usage: #{@cl_cmd_name} [options]
65
47
 
@@ -81,18 +63,6 @@ global = OptionParser.new do |g|
81
63
  options[:token] = v
82
64
  end
83
65
 
84
- g.on("-p", "--project KEY", "jira project to fetch from") do |v|
85
- options[:project] = v
86
- end
87
-
88
- g.on("-w", "--epic-wildcard TEXT", "wildcard to filter the epics by") do |v|
89
- options[:epic_wildcard] = v
90
- end
91
-
92
- g.on("-f", "--output-filename NAME", "the name of the output file (defaults to jira-fetch-timestamp.datafile)") do |v|
93
- options[:output_filename] = v
94
- end
95
-
96
66
  end
97
67
 
98
68
  #
@@ -100,7 +70,8 @@ end
100
70
  #
101
71
 
102
72
  @working_dir = ENV['CL_WORKING_DIR'] # passed through cl-magic to here
103
- global.parse(ARGV)
73
+ global.parse!(ARGV)
74
+ options[:jql] = ARGV.join(' ')
104
75
 
105
76
  # error on token right away
106
77
  if options[:token].nil?
@@ -111,17 +82,14 @@ end
111
82
  # prompt for missing options
112
83
  ask_and_store_option(options, :base_uri, "base_uri: ")
113
84
  ask_and_store_option(options, :username, "username: ")
114
- ask_and_store_option(options, :project, "project: ")
115
- ask_and_store_option(options, :epic_wildcard, "epic_wildcard: ")
116
- ask_and_store_option(options, :output_filename, "output_filename: ")
85
+ ask_and_store_option(options, :jql, "jql: ")
117
86
 
118
87
  # display full command
119
88
  write_history("""#{@cl_cmd_name} \\
120
89
  --base-uri=#{options[:base_uri]} \\
121
90
  --username=#{options[:username]} \\
122
- --project=#{options[:project]} \\
123
- --epic-wildcard=#{options[:epic_wildcard]} \\
124
- --token
91
+ --token REDACTED \\
92
+ -- #{options[:jql]}
125
93
  """)
126
94
 
127
95
  do_work(options)