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.
- checksums.yaml +4 -4
- data/Gemfile.lock +16 -2
- data/cl-magic.gemspec +5 -0
- data/lib/cl/magic/cl +21 -14
- data/lib/cl/magic/cl-ai-chat +117 -0
- data/lib/cl/magic/cl-ai-query +116 -0
- data/lib/cl/magic/cl-ai-store-jira +158 -0
- data/lib/cl/magic/cl-auth +12 -0
- data/lib/cl/magic/cl-dk +33 -464
- data/lib/cl/magic/cl-dk-make +174 -0
- data/lib/cl/magic/cl-dk-make-world +163 -0
- data/lib/cl/magic/cl-dk-parts +253 -0
- data/lib/cl/magic/cl-dk-world +140 -0
- data/lib/cl/magic/cl-jira-fetch +15 -48
- data/lib/cl/magic/cl-jira-fetch-by-epics +112 -0
- data/lib/cl/magic/cl-jira-to-elastic +126 -0
- data/lib/cl/magic/cl-jira-to-markdown +68 -0
- data/lib/cl/magic/cl-jira-to-stats +202 -0
- data/lib/cl/magic/cl-kube-logs +3 -1
- data/lib/cl/magic/cl-poll +20 -5
- data/lib/cl/magic/common/ai_prompt.rb +169 -0
- data/lib/cl/magic/common/ai_text_splitter.rb +78 -0
- data/lib/cl/magic/common/common_options.rb +1 -1
- data/lib/cl/magic/common/elastic.rb +41 -0
- data/lib/cl/magic/common/jira.rb +173 -45
- data/lib/cl/magic/common/milvus.rb +78 -0
- data/lib/cl/magic/dk/help_printer.rb +29 -0
- data/lib/cl/magic/dk/parts_merger.rb +67 -0
- data/lib/cl/magic/dk/world_settings.rb +52 -0
- data/lib/cl/magic/dk/yaml_arg_munger.rb +107 -0
- data/lib/cl/magic/version.rb +1 -1
- metadata +77 -3
- data/lib/cl/magic/cl-jira-stats +0 -180
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'tty-command'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
class PartsMerger
|
5
|
+
|
6
|
+
def initialize(working_dir, yaml_arg_munger, help_printer, logger)
|
7
|
+
@working_dir = working_dir
|
8
|
+
@yaml_arg_munger = yaml_arg_munger
|
9
|
+
@help_printer = help_printer
|
10
|
+
@logger = logger
|
11
|
+
end
|
12
|
+
|
13
|
+
def merge_parts(compose_hash, dk_parts_hash, args)
|
14
|
+
selected_part_keys = []
|
15
|
+
|
16
|
+
# merge: saved parts
|
17
|
+
saved_part_keys = get_saved_parts(dk_parts_hash)
|
18
|
+
saved_part_keys.each do |potential_part_key|
|
19
|
+
dk_part = dk_parts_hash.fetch(potential_part_key, nil) # yml detail
|
20
|
+
if dk_part
|
21
|
+
compose_hash = print_and_merge_part(potential_part_key, dk_part, compose_hash)
|
22
|
+
selected_part_keys << potential_part_key
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# merge: arg parts
|
27
|
+
while true
|
28
|
+
potential_part_key = args.first
|
29
|
+
dk_part = dk_parts_hash.fetch(potential_part_key, nil) # yml detail
|
30
|
+
if dk_part
|
31
|
+
unless selected_part_keys.include?(potential_part_key)
|
32
|
+
compose_hash = print_and_merge_part(potential_part_key, dk_part, compose_hash)
|
33
|
+
selected_part_keys << potential_part_key
|
34
|
+
end
|
35
|
+
args.shift # remove part arg
|
36
|
+
else
|
37
|
+
break
|
38
|
+
end
|
39
|
+
end
|
40
|
+
@logger.puts "" if $stdout.isatty # tailing line break
|
41
|
+
|
42
|
+
return compose_hash, selected_part_keys, args
|
43
|
+
end
|
44
|
+
|
45
|
+
def get_saved_parts(dk_parts_hash)
|
46
|
+
|
47
|
+
# get saved parts
|
48
|
+
cmd = "cd #{@working_dir} && cl dk parts list"
|
49
|
+
out, err = TTY::Command.new(:printer => :null).run("#{cmd}")
|
50
|
+
return out.split("\n")
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def print_and_merge_part(part_key, dk_part, compose_hash)
|
57
|
+
|
58
|
+
# print
|
59
|
+
if $stdout.isatty
|
60
|
+
help_str = dk_part.fetch('help')
|
61
|
+
@help_printer.print_dk_help_line("#{part_key}", "#{help_str ? '- ' + help_str : ''}") if dk_part.keys.any?
|
62
|
+
end
|
63
|
+
# merge
|
64
|
+
return @yaml_arg_munger.dk_merge_and_remove(compose_hash, dk_part)
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'tty-command'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
class WorldSettings
|
5
|
+
|
6
|
+
def initialize(working_dir)
|
7
|
+
@working_dir = working_dir
|
8
|
+
end
|
9
|
+
|
10
|
+
def get_world_settings_hash()
|
11
|
+
filepath = get_world_settings_filepath()
|
12
|
+
return File.exist?(filepath) ? YAML.load_file(filepath) : {}
|
13
|
+
end
|
14
|
+
|
15
|
+
def save_world_settings(world_settings_hash)
|
16
|
+
filepath = get_world_settings_filepath()
|
17
|
+
tempfile = File.new(filepath, 'w')
|
18
|
+
tempfile.write(world_settings_hash.to_yaml)
|
19
|
+
tempfile.close
|
20
|
+
end
|
21
|
+
|
22
|
+
def get_world_project_path()
|
23
|
+
repo_basename = get_repo_basename()
|
24
|
+
world_path = get_world_path_from_settings()
|
25
|
+
return File.join(world_path, repo_basename) if world_path and repo_basename
|
26
|
+
return nil
|
27
|
+
end
|
28
|
+
|
29
|
+
def get_world_path_from_settings()
|
30
|
+
world_settings = get_world_settings_hash()
|
31
|
+
if world_settings.key?(:world_path) and world_settings.key?(:context)
|
32
|
+
return File.join(world_settings[:world_path], world_settings[:context])
|
33
|
+
end
|
34
|
+
return ""
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def get_repo_basename()
|
40
|
+
command = "cd #{@working_dir} && basename $(git remote get-url origin 2> /dev/null) .git"
|
41
|
+
repo_basename = TTY::Command.new(:printer => :null).run(command).out.gsub('.git', '').strip.chomp
|
42
|
+
if repo_basename==".git" or repo_basename==""
|
43
|
+
return File.basename(@working_dir)
|
44
|
+
end
|
45
|
+
return repo_basename
|
46
|
+
end
|
47
|
+
|
48
|
+
def get_world_settings_filepath()
|
49
|
+
return File.join(".cl-dk-world.yml")
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
class YamlArgMunger
|
4
|
+
|
5
|
+
def initialize(working_dir, world_settings)
|
6
|
+
@working_dir = working_dir
|
7
|
+
@world_path = world_settings.get_world_path_from_settings()
|
8
|
+
@dk_proj_path = world_settings.get_world_project_path()
|
9
|
+
end
|
10
|
+
|
11
|
+
def get_base_compose_parts_and_make_hashes()
|
12
|
+
compose_hash = get_base_compose_hash()
|
13
|
+
dk_parts_hash = {}
|
14
|
+
dk_make_hash = {}
|
15
|
+
if compose_hash
|
16
|
+
compose_hash = merge_world_files(compose_hash, show_help=ARGV.include?("--help"))
|
17
|
+
dk_parts_hash = compose_hash['x-dk-parts'] ? compose_hash.delete('x-dk-parts') : {}
|
18
|
+
dk_make_hash = compose_hash['x-dk-make'] ? compose_hash.delete('x-dk-make') : {}
|
19
|
+
end
|
20
|
+
return compose_hash, dk_parts_hash, dk_make_hash
|
21
|
+
end
|
22
|
+
|
23
|
+
def dk_merge_and_remove(compose_hash, yml_hash)
|
24
|
+
# remove help & merge
|
25
|
+
clean_yml = yml_hash.clone
|
26
|
+
clean_yml.delete('help')
|
27
|
+
return compose_hash.dk_merge(clean_yml).dk_reject! { |k, v| v=='<dk-remove>' }
|
28
|
+
end
|
29
|
+
|
30
|
+
def save_yaml_and_adjust_args(compose_hash, args)
|
31
|
+
|
32
|
+
# generate final compose file
|
33
|
+
tempfile = File.new(File.join(@working_dir, ".cl-dk.yml"), 'w')
|
34
|
+
tempfile.write(compose_hash.to_yaml) # write it to the tempfile
|
35
|
+
|
36
|
+
# remove existing '-f' flag, if needed
|
37
|
+
file_flag_index = args.index('-f')
|
38
|
+
if file_flag_index==0
|
39
|
+
args.delete_at(file_flag_index)
|
40
|
+
args.delete_at(file_flag_index)
|
41
|
+
end
|
42
|
+
args.unshift('-f', tempfile.path) # add new '-f' flag
|
43
|
+
|
44
|
+
tempfile.close
|
45
|
+
return args
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def get_base_compose_hash()
|
51
|
+
cmd = "cd #{@working_dir} && docker compose config 2> /dev/null"
|
52
|
+
return YAML.load(`#{cmd}`)
|
53
|
+
end
|
54
|
+
|
55
|
+
def merge_world_files(compose_hash, show_help=false)
|
56
|
+
if @dk_proj_path
|
57
|
+
print_dk_help_line("dk-project-path", "#{@dk_proj_path}") if show_help and $stdout.isatty
|
58
|
+
|
59
|
+
Dir.glob("#{@dk_proj_path}/*.yml").sort.each do |filepath|
|
60
|
+
print_dk_help_line("dk-world", "#{filepath}") if show_help and $stdout.isatty
|
61
|
+
|
62
|
+
# read file and replace
|
63
|
+
contents = File.read(filepath)
|
64
|
+
contents.gsub!('<dk-world-path>', @world_path)
|
65
|
+
contents.gsub!('<dk-project-path>', @dk_proj_path)
|
66
|
+
contents.gsub!('<dk-working-path>', @working_dir)
|
67
|
+
|
68
|
+
# yml merge
|
69
|
+
yml_hash = YAML.load(contents)
|
70
|
+
compose_hash = dk_merge_and_remove(compose_hash, yml_hash)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
return compose_hash
|
74
|
+
end
|
75
|
+
|
76
|
+
class ::Hash
|
77
|
+
def dk_merge(second)
|
78
|
+
merger = proc { |_, v1, v2|
|
79
|
+
if Hash === v1 && Hash === v2
|
80
|
+
v1.merge(v2, &merger)
|
81
|
+
else
|
82
|
+
if Array === v1 && Array === v2
|
83
|
+
if v2.first=="<dk-replace>"
|
84
|
+
v2[1..-1] # everything but the first item
|
85
|
+
else
|
86
|
+
v1 | v2 # union arrays
|
87
|
+
end
|
88
|
+
else
|
89
|
+
if [:undefined, nil, :nil].include?(v2)
|
90
|
+
v1
|
91
|
+
else
|
92
|
+
v2
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
}
|
97
|
+
merge(second.to_h, &merger)
|
98
|
+
end
|
99
|
+
def dk_reject!(&blk)
|
100
|
+
self.each do |k, v|
|
101
|
+
v.dk_reject!(&blk) if v.is_a?(Hash)
|
102
|
+
self.delete(k) if blk.call(k, v)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
data/lib/cl/magic/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cl-magic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Don Najd
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-08-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -80,6 +80,48 @@ dependencies:
|
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: tty-spinner
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: tty-progressbar
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: concurrent-ruby
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
83
125
|
- !ruby/object:Gem::Dependency
|
84
126
|
name: pastel
|
85
127
|
requirement: !ruby/object:Gem::Requirement
|
@@ -108,6 +150,20 @@ dependencies:
|
|
108
150
|
- - ">="
|
109
151
|
- !ruby/object:Gem::Version
|
110
152
|
version: '0'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: baran
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
type: :runtime
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
111
167
|
- !ruby/object:Gem::Dependency
|
112
168
|
name: byebug
|
113
169
|
requirement: !ruby/object:Gem::Requirement
|
@@ -139,15 +195,25 @@ files:
|
|
139
195
|
- cl-magic.gemspec
|
140
196
|
- lib/cl/magic.rb
|
141
197
|
- lib/cl/magic/cl
|
198
|
+
- lib/cl/magic/cl-ai-chat
|
199
|
+
- lib/cl/magic/cl-ai-query
|
200
|
+
- lib/cl/magic/cl-ai-store-jira
|
142
201
|
- lib/cl/magic/cl-auth
|
143
202
|
- lib/cl/magic/cl-dk
|
203
|
+
- lib/cl/magic/cl-dk-make
|
204
|
+
- lib/cl/magic/cl-dk-make-world
|
205
|
+
- lib/cl/magic/cl-dk-parts
|
206
|
+
- lib/cl/magic/cl-dk-world
|
144
207
|
- lib/cl/magic/cl-envkey
|
145
208
|
- lib/cl/magic/cl-gc-sql
|
146
209
|
- lib/cl/magic/cl-gc-tags
|
147
210
|
- lib/cl/magic/cl-glab-commit
|
148
211
|
- lib/cl/magic/cl-history
|
149
212
|
- lib/cl/magic/cl-jira-fetch
|
150
|
-
- lib/cl/magic/cl-jira-
|
213
|
+
- lib/cl/magic/cl-jira-fetch-by-epics
|
214
|
+
- lib/cl/magic/cl-jira-to-elastic
|
215
|
+
- lib/cl/magic/cl-jira-to-markdown
|
216
|
+
- lib/cl/magic/cl-jira-to-stats
|
151
217
|
- lib/cl/magic/cl-kube-cp
|
152
218
|
- lib/cl/magic/cl-kube-deployment
|
153
219
|
- lib/cl/magic/cl-kube-ktx
|
@@ -159,12 +225,20 @@ files:
|
|
159
225
|
- lib/cl/magic/cl-poll
|
160
226
|
- lib/cl/magic/cl-sandbox
|
161
227
|
- lib/cl/magic/cl-vault
|
228
|
+
- lib/cl/magic/common/ai_prompt.rb
|
229
|
+
- lib/cl/magic/common/ai_text_splitter.rb
|
162
230
|
- lib/cl/magic/common/common_options.rb
|
231
|
+
- lib/cl/magic/common/elastic.rb
|
163
232
|
- lib/cl/magic/common/gcloud.rb
|
164
233
|
- lib/cl/magic/common/jira.rb
|
165
234
|
- lib/cl/magic/common/kubectl.rb
|
166
235
|
- lib/cl/magic/common/logging.rb
|
236
|
+
- lib/cl/magic/common/milvus.rb
|
167
237
|
- lib/cl/magic/common/parse_and_pick.rb
|
238
|
+
- lib/cl/magic/dk/help_printer.rb
|
239
|
+
- lib/cl/magic/dk/parts_merger.rb
|
240
|
+
- lib/cl/magic/dk/world_settings.rb
|
241
|
+
- lib/cl/magic/dk/yaml_arg_munger.rb
|
168
242
|
- lib/cl/magic/version.rb
|
169
243
|
homepage: https://gitlab.com/beesbot/cl-magic
|
170
244
|
licenses:
|
data/lib/cl/magic/cl-jira-stats
DELETED
@@ -1,180 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# Fetch jira issues print stats
|
3
|
-
require 'optparse'
|
4
|
-
require 'optparse/subcommand'
|
5
|
-
require 'tty-command'
|
6
|
-
require 'tty-prompt'
|
7
|
-
require 'active_support/all'
|
8
|
-
|
9
|
-
require 'cl/magic/common/common_options.rb'
|
10
|
-
require 'cl/magic/common/logging.rb'
|
11
|
-
require 'cl/magic/common/jira.rb'
|
12
|
-
|
13
|
-
require 'net/http'
|
14
|
-
require 'json'
|
15
|
-
|
16
|
-
require 'byebug'
|
17
|
-
|
18
|
-
@logger = get_logger()
|
19
|
-
@cl_cmd_name = File.basename(__FILE__).split('-').join(' ')
|
20
|
-
|
21
|
-
#
|
22
|
-
# Features
|
23
|
-
#
|
24
|
-
|
25
|
-
def get_issues_from_datafile(options)
|
26
|
-
issues = []
|
27
|
-
filepath = File.join(@working_dir, options[:data_filepath])
|
28
|
-
File.foreach(filepath) do |line|
|
29
|
-
issue = JSON.parse(line)
|
30
|
-
issuetype = issue["fields"]["issuetype"]["name"]
|
31
|
-
|
32
|
-
# filter if needed
|
33
|
-
issues << issue unless options[:exclude_issuetypes].include?(issuetype)
|
34
|
-
end
|
35
|
-
return issues
|
36
|
-
end
|
37
|
-
|
38
|
-
def oldest_issue_date(issues)
|
39
|
-
return issues.collect {|i| Date.parse(i["fields"]["created"])}.sort.first
|
40
|
-
end
|
41
|
-
|
42
|
-
def do_work(options)
|
43
|
-
issues = get_issues_from_datafile(options)
|
44
|
-
oldest_date = oldest_issue_date(issues)
|
45
|
-
iter_date_range(oldest_date) do |start_date, end_date|
|
46
|
-
stat_hashes = issues_to_stat_hashes(issues, start_date, end_date, options)
|
47
|
-
counts = print_stats(stat_hashes, start_date, end_date)
|
48
|
-
puts counts # print each time range
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
def iter_date_range(start_date)
|
53
|
-
current_date = start_date.beginning_of_week
|
54
|
-
while current_date < 1.week.ago.end_of_week
|
55
|
-
yield current_date, current_date.end_of_week
|
56
|
-
current_date += 2.weeks # increment
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
def issues_to_stat_hashes(issues, start_date, end_date, options)
|
61
|
-
|
62
|
-
# parse dates for changelogs
|
63
|
-
issues.each do |issue|
|
64
|
-
issue["status_changelogs"].each do |l|
|
65
|
-
date_string = l["created"]
|
66
|
-
l["created"] = Date.parse(date_string) unless date_string.class == Date
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
# collect stat hashes
|
71
|
-
return issues.collect do |issue|
|
72
|
-
|
73
|
-
# skip if issue is out of range
|
74
|
-
issue_created = Date.parse(issue["fields"]["created"])
|
75
|
-
if issue_created > end_date
|
76
|
-
nil
|
77
|
-
else
|
78
|
-
# get in-range status change
|
79
|
-
status_changelog = nil
|
80
|
-
status_changelog = issue["status_changelogs"]
|
81
|
-
.select { |l| l["created"] > end_date }
|
82
|
-
.sort_by { |l| l["created"] }.last if start_date && end_date
|
83
|
-
|
84
|
-
# exclude issue types
|
85
|
-
if status_changelog and options[:exclude_issuetypes].include?(status_changelog["toString"])
|
86
|
-
nil
|
87
|
-
else
|
88
|
-
# yield stat hash
|
89
|
-
{
|
90
|
-
issuetype: issue["fields"]["issuetype"]["name"],
|
91
|
-
status: status_changelog ? status_changelog["toString"] : issue["fields"]["status"]["name"]
|
92
|
-
}
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end.compact
|
96
|
-
end
|
97
|
-
|
98
|
-
def print_stats(stat_hashes, start_date, end_date)
|
99
|
-
counts = {
|
100
|
-
start_date: start_date.strftime("%m-%d-%Y"),
|
101
|
-
end_date: end_date.strftime("%m-%d-%Y"),
|
102
|
-
total_todo: 0,
|
103
|
-
total_done: 0,
|
104
|
-
total: stat_hashes ? stat_hashes.count : 0
|
105
|
-
}
|
106
|
-
return counts unless stat_hashes.any?
|
107
|
-
stat_hashes.each do |stat|
|
108
|
-
|
109
|
-
issuetype = stat[:issuetype]
|
110
|
-
status = stat[:status]
|
111
|
-
|
112
|
-
# count all
|
113
|
-
increment(counts, "status_#{issuetype.downcase.underscore}")
|
114
|
-
|
115
|
-
# count by status
|
116
|
-
case status
|
117
|
-
when "Ready","Rework","In Progress","In QA","Ready For Code Review","In Code Review"
|
118
|
-
increment(counts, :total_todo)
|
119
|
-
when "Ready to Deploy","Closed"
|
120
|
-
increment(counts, :total_done)
|
121
|
-
# else
|
122
|
-
# raise "invalid ticket status: #{status}"
|
123
|
-
end
|
124
|
-
end
|
125
|
-
return counts
|
126
|
-
end
|
127
|
-
|
128
|
-
def increment(hash, key)
|
129
|
-
if hash.key? key
|
130
|
-
hash[key] += 1
|
131
|
-
else
|
132
|
-
hash[key] = 1
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
#
|
137
|
-
# Options
|
138
|
-
#
|
139
|
-
|
140
|
-
options = {
|
141
|
-
exclude_issuetypes: []
|
142
|
-
}
|
143
|
-
global_banner = <<DOC
|
144
|
-
|
145
|
-
Process jira fetch file an return stats
|
146
|
-
|
147
|
-
Usage: #{@cl_cmd_name} [options]
|
148
|
-
|
149
|
-
DOC
|
150
|
-
|
151
|
-
global = OptionParser.new do |g|
|
152
|
-
g.banner = global_banner
|
153
|
-
add_help_and_verbose(g)
|
154
|
-
|
155
|
-
g.on("-f", "--data-filepath FILEPATH", "relative path to file produced by 'cl jira fetch' command") do |v|
|
156
|
-
options[:data_filepath] = v
|
157
|
-
end
|
158
|
-
|
159
|
-
g.on("-e", "--exclude-issuetypes CSV", "comma separated list of issuetypes you want to exclude") do |v|
|
160
|
-
options[:exclude_issuetypes] = v.split(',')
|
161
|
-
options[:exclude_issuetypes] << "Won't Do"
|
162
|
-
end
|
163
|
-
end
|
164
|
-
|
165
|
-
#
|
166
|
-
# Run
|
167
|
-
#
|
168
|
-
|
169
|
-
@working_dir = ENV['CL_WORKING_DIR'] # passed through cl-magic to here
|
170
|
-
global.parse(ARGV)
|
171
|
-
|
172
|
-
# prompt for missing options
|
173
|
-
ask_and_store_option(options, :data_filepath, "data_filepath: ")
|
174
|
-
|
175
|
-
# display full command
|
176
|
-
write_history("""#{@cl_cmd_name} \\
|
177
|
-
--data-filepath=#{options[:data_filepath]}
|
178
|
-
""")
|
179
|
-
|
180
|
-
do_work(options)
|