cl-magic 0.4.0 → 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.
@@ -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,253 @@
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
+
11
+ require_relative 'dk/help_printer'
12
+ require_relative 'dk/yaml_arg_munger'
13
+ require_relative 'dk/world_settings'
14
+ require_relative 'dk/parts_merger'
15
+
16
+ @logger = get_logger()
17
+ @cl_cmd_name = File.basename(__FILE__).split('-').join(' ')
18
+
19
+ def get_save_parts_filepath()
20
+ return File.join(@working_dir, ".cl-dk-parts.yml")
21
+ end
22
+
23
+ def yield_all_parts
24
+
25
+ # utils
26
+ @help_printer = HelpPrinter.new(@logger)
27
+ @world_settings = WorldSettings.new(@working_dir)
28
+ @yaml_arg_munger = YamlArgMunger.new(@working_dir, @world_settings)
29
+ @parts_merger = PartsMerger.new(@working_dir, @yaml_arg_munger, @help_printer, @logger)
30
+
31
+ # world files
32
+ compose_hash, dk_parts_hash, dk_make_hash = @yaml_arg_munger.get_base_compose_parts_and_make_hashes()
33
+ if compose_hash
34
+ yield dk_parts_hash
35
+ else
36
+ @logger.error "no docker configuration found"
37
+ exit 1
38
+ end
39
+ end
40
+
41
+ #
42
+ # Features
43
+ #
44
+
45
+ def do_set(options)
46
+
47
+ yield_all_parts do |dk_parts_hash|
48
+ parts = ARGV[1..]
49
+
50
+ if parts.any?
51
+
52
+ # validate parts
53
+ parts.each do |part|
54
+ unless dk_parts_hash.include? part
55
+ puts ""
56
+ @logger.error "invalid part: #{part}"
57
+ @logger.info "allowed parts: #{dk_parts_hash.keys.join(", ")}"
58
+ puts ""
59
+ exit 1
60
+ end
61
+ end
62
+
63
+ create_file_unless_exists(options)
64
+
65
+ # save parts
66
+ filepath = get_save_parts_filepath()
67
+ parts = ARGV[1..]
68
+ case options[:action]
69
+ when :set
70
+ File.open(filepath, 'w') { |file| file.write(parts.to_yaml) }
71
+ @logger.success "parts set"
72
+ when :add
73
+ data = YAML.load_file(filepath)
74
+ parts.each {|p| data << p}
75
+ File.open(filepath, 'w') { |file| file.write(data.uniq.to_yaml) }
76
+ @logger.success "parts added"
77
+ when :remove
78
+ data = YAML.load_file(filepath)
79
+ data.reject! { |p| parts.include?(p) }
80
+ File.open(filepath, 'w') { |file| file.write(data.to_yaml) }
81
+ @logger.success "parts removed"
82
+ end
83
+ else
84
+ @logger.warn "you didn't pass any parts to set"
85
+ exit 1
86
+ end
87
+ exit
88
+
89
+ end
90
+
91
+ end
92
+
93
+ def create_file_unless_exists(options)
94
+ filepath = get_save_parts_filepath()
95
+ unless File.exist?(filepath)
96
+ File.open(filepath, 'w') { |file| file.write([].to_yaml) }
97
+ end
98
+ end
99
+
100
+ def do_clear(options)
101
+ filepath = get_save_parts_filepath()
102
+ if File.exist?(filepath)
103
+ File.delete(filepath)
104
+ @logger.info "parts cleared"
105
+ end
106
+ end
107
+
108
+ def do_list_saved_parts(options)
109
+
110
+ is_tty = $stdout.isatty
111
+
112
+ yield_all_parts do |dk_parts_hash|
113
+
114
+ saved_part_keys = []
115
+ filepath = get_save_parts_filepath()
116
+
117
+ # merge
118
+ if File.exist?(filepath)
119
+ saved_parts = YAML.load_file(filepath)
120
+
121
+ puts "" if is_tty
122
+ dk_parts_hash.keys.each do |part|
123
+ if is_tty
124
+ if saved_parts.include? part
125
+ puts "* #{part}"
126
+ else
127
+ puts " #{part}"
128
+ end
129
+ else
130
+ puts part if saved_parts.include? part # terminal only
131
+ end
132
+ end
133
+ puts "" if is_tty
134
+ else
135
+ if is_tty
136
+ puts ""
137
+ @logger.info "no saved parts"
138
+ puts ""
139
+ dk_parts_hash.keys.each do |part|
140
+ puts " #{part}"
141
+ end
142
+ puts ""
143
+ end
144
+ end
145
+ end
146
+ end
147
+
148
+ #
149
+ # Options
150
+ #
151
+
152
+ options = {}
153
+ global_banner = <<DOC
154
+
155
+ Dk parts
156
+
157
+ Usage: #{@cl_cmd_name} [options]
158
+
159
+ DOC
160
+
161
+ dk_parts_set_banner = <<DOC
162
+
163
+ Set parts
164
+
165
+ Usage: #{@cl_cmd_name} set [options]
166
+
167
+ DOC
168
+
169
+ dk_parts_add_banner = <<DOC
170
+
171
+ Add parts
172
+
173
+ Usage: #{@cl_cmd_name} set [options]
174
+
175
+ DOC
176
+
177
+ dk_parts_remove_banner = <<DOC
178
+
179
+ Remove parts
180
+
181
+ Usage: #{@cl_cmd_name} set [options]
182
+
183
+ DOC
184
+
185
+ dk_parts_clear_banner = <<DOC
186
+
187
+ Clear parts
188
+
189
+ Usage: #{@cl_cmd_name} set [options]
190
+
191
+ DOC
192
+
193
+ dk_parts_list_banner = <<DOC
194
+
195
+ List saved parts
196
+
197
+ Usage: #{@cl_cmd_name} set [options]
198
+
199
+ DOC
200
+
201
+ global = OptionParser.new do |g|
202
+ g.banner = global_banner
203
+ add_help_and_verbose(g)
204
+
205
+ g.subcommand 'set' do |s|
206
+ s.banner = dk_parts_set_banner
207
+ options[:action] = :set
208
+ end
209
+
210
+ g.subcommand 'add' do |s|
211
+ s.banner = dk_parts_set_banner
212
+ options[:action] = :add
213
+ end
214
+
215
+ g.subcommand 'remove' do |s|
216
+ s.banner = dk_parts_set_banner
217
+ options[:action] = :remove
218
+ end
219
+
220
+ g.subcommand 'clear' do |s|
221
+ s.banner = dk_parts_clear_banner
222
+ options[:action] = :clear
223
+ end
224
+
225
+ g.subcommand 'list' do |s|
226
+ s.banner = dk_parts_list_banner
227
+ options[:action] = :list
228
+ end
229
+
230
+ end
231
+
232
+ #
233
+ # Run
234
+ #
235
+
236
+ @working_dir = ENV['CL_WORKING_DIR'] # passed through cl-magic to here
237
+
238
+ global.parse(ARGV)
239
+
240
+ case options[:action]
241
+ when :set
242
+ do_set(options)
243
+ when :add
244
+ do_set(options)
245
+ when :remove
246
+ do_set(options)
247
+ when :clear
248
+ do_clear(options)
249
+ when :list
250
+ do_list_saved_parts(options)
251
+ else
252
+ puts global.parse! %w[--help]
253
+ 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)