cl-magic 0.3.9 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 42235afcff8b801982ca721b3217756dad15a401063e59310900dd595c05a4e2
4
- data.tar.gz: a49e3798271b7cef9f8e82d9b0a6e9846e9a56a1de1d4d75d91ed81e2291d237
3
+ metadata.gz: '08b4655abcd92a0d5e3a779fdc7e0e09231c7cb15d073e06878c085227ef3f9d'
4
+ data.tar.gz: 63999d535d6ad18d22b8cff1e259b9b054bbf7faf75939e54c9819885ca24feb
5
5
  SHA512:
6
- metadata.gz: 5319a3c52cc59b51c2a6a0e8469cc7085e6485765c335ba44bf6709937c8eb7d12b4b410c78ebb71b283faabd466d647b9109399b20ea9e72ffc4d5fdfa6b252
7
- data.tar.gz: 5f016f4f25736f492b0985fe4ebe5cfb0f33597cf8a365d240743f7635c8142db1726c6c17ffac9a4f6a34946e6864e8a0eabda6b8ef89dd5068f6f14161dc06
6
+ metadata.gz: 4157d207e824e2d0a309790187873d3b6b02c41bd892fc3436e359cc1f4639044576129d1a8d36ac9a0faee8afa6dc2366db506f93401bf4165e93766435f3d7
7
+ data.tar.gz: 0bce3b21105e81dd1bc1d5656e941ceec30814bb01e19c16a7a5ee57eba98403093d7359eb9e113bd60b0850a87764b1241a08febe1881dcde74c303fb9d35be
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cl-magic (0.3.9)
4
+ cl-magic (0.4.0)
5
5
  activesupport
6
6
  optparse-subcommand
7
7
  pastel
data/lib/cl/magic/cl-auth CHANGED
@@ -61,6 +61,18 @@ def aws_okta(options)
61
61
  # cmd = "aws-okta add" # old
62
62
  # do work
63
63
  if is_tty
64
+
65
+ # ensure we are logged in
66
+ begin
67
+ TTY::Command.new(:printer => :null).run("aws-okta exec #{options[:aws_profile]} -- env")
68
+ rescue TTY::Command::ExitError => e
69
+ if e.message.include? "Failed to authenticate"
70
+ @logger.info "authenticate first with: aws-okta add"
71
+ else
72
+ raise
73
+ end
74
+ end
75
+
64
76
  puts
65
77
  @logger.info "now export into your environment with"
66
78
  puts
data/lib/cl/magic/cl-dk CHANGED
@@ -41,7 +41,11 @@ end
41
41
 
42
42
  def get_repo_basename()
43
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
44
+ repo_basename = TTY::Command.new(:printer => :null).run(command).out.gsub('.git', '').strip.chomp
45
+ if repo_basename==".git" or repo_basename==""
46
+ return File.basename(@working_dir)
47
+ end
48
+ return repo_basename
45
49
  end
46
50
 
47
51
  def get_world_settings_filepath()
@@ -106,37 +110,35 @@ def print_dk_help(dk_parts_hash, dk_make_hash, args)
106
110
  has_dk_commands = dk_parts_hash.keys.any?
107
111
 
108
112
  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"
113
+ puts ""
114
+ puts "Usage: dk [DK_PARTS] [COMPOSE_OPTIONS] COMPOSE_COMMAND"
115
+ puts ""
116
+ puts "Run docker compose while munging yamls in sophisticated ways."
117
+ puts ""
118
+ if get_repo_basename
119
+ puts "PROJ INFO"
120
+ puts " - Repo basename: #{get_repo_basename}"
121
+ puts " - World filepath: #{get_world_project_path()}"
137
122
  puts ""
138
- puts "-------------------------"
139
123
  end
124
+ puts "PROJ PARTS"
125
+ dk_parts_hash.keys.each do |key|
126
+ print_dk_help_line(key, dk_parts_hash[key].fetch('help'))
127
+ end
128
+ puts ""
129
+ puts "YML TOKENS"
130
+ puts " - <dk-remove> removes section of yaml"
131
+ puts " - <dk-replace> replaces values in a yaml array"
132
+ puts " - <dk-world-path> absolute filepath to world directory"
133
+ puts " - <dk-project-path> absolute filepath to world/project directory"
134
+ puts " - <dk-working-path> absolute filepath to location dk command was run from"
135
+ puts ""
136
+ puts "ADDITIONAL TURNKEY COMMANDS"
137
+ puts " - dk set-world sets the location of the world directory"
138
+ puts " - dk make turnkey commands for a project"
139
+ puts " - dk set-parts save parts so they are automatically applied to commands"
140
+ puts ""
141
+ puts "-------------------------"
140
142
  end
141
143
  end
142
144
 
@@ -12,8 +12,6 @@ require 'cl/magic/common/jira.rb'
12
12
  require 'net/http'
13
13
  require 'json'
14
14
 
15
- require 'byebug'
16
-
17
15
  @logger = get_logger()
18
16
  @cl_cmd_name = File.basename(__FILE__).split('-').join(' ')
19
17
 
@@ -27,7 +25,7 @@ def do_work(options)
27
25
 
28
26
  puts ""
29
27
  @logger.wait "fetch epics"
30
- epic_ids = jira.get_epic_ids(options[:project], options[:epic_wildcard])
28
+ epic_ids, epics = jira.get_epic_ids(options[:project], options[:epic_wildcard])
31
29
  @logger.success "#{epic_ids.count} epics"
32
30
 
33
31
  puts ""
@@ -44,8 +42,8 @@ def do_work(options)
44
42
  @logger.wait "saving file"
45
43
  output_filepath = File.join(@working_dir, options[:output_filename])
46
44
  File.open(output_filepath, 'w') do |file|
47
- issues.each do |issue|
48
- file.puts(issue.to_json)
45
+ issues.each do |o|
46
+ file.puts(o.to_json)
49
47
  end
50
48
  end
51
49
 
@@ -122,7 +120,8 @@ write_history("""#{@cl_cmd_name} \\
122
120
  --base-uri=#{options[:base_uri]} \\
123
121
  --username=#{options[:username]} \\
124
122
  --project=#{options[:project]} \\
125
- --epic-wildcard=#{options[:epic_wildcard]}
123
+ --epic-wildcard=#{options[:epic_wildcard]} \\
124
+ --token
126
125
  """)
127
126
 
128
127
  do_work(options)
@@ -13,8 +13,6 @@ require 'cl/magic/common/jira.rb'
13
13
  require 'net/http'
14
14
  require 'json'
15
15
 
16
- require 'byebug'
17
-
18
16
  @logger = get_logger()
19
17
  @cl_cmd_name = File.basename(__FILE__).split('-').join(' ')
20
18
 
@@ -28,70 +26,50 @@ def get_issues_from_datafile(options)
28
26
  File.foreach(filepath) do |line|
29
27
  issue = JSON.parse(line)
30
28
  issuetype = issue["fields"]["issuetype"]["name"]
29
+ labels = issue["fields"]["labels"]
31
30
 
32
- # filter if needed
33
- issues << issue unless options[:exclude_issuetypes].include?(issuetype)
31
+ has_excluded_labels = (labels & options[:exclude_labels]).any?
32
+ is_excluded_issuetype = options[:exclude_issuetypes].include?(issuetype.downcase)
33
+ issues << issue unless has_excluded_labels or is_excluded_issuetype
34
34
  end
35
35
  return issues
36
36
  end
37
37
 
38
- def oldest_issue_date(issues)
39
- return issues.collect {|i| Date.parse(i["fields"]["created"])}.sort.first
40
- end
38
+ def in_range_issue_stats(issues, start_date, end_date, options)
41
39
 
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
40
+ def in_range_logs(start_date, end_date, issue)
41
+ return issue["status_changelogs"].select do |log|
42
+ (start_date..end_date).cover?(Date.parse(log["created"]))
43
+ end
49
44
  end
50
- end
51
45
 
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
46
+ # in-range
47
+ in_range_issues = issues.select do |issue|
59
48
 
60
- def issues_to_stat_hashes(issues, start_date, end_date, options)
49
+ # issue created date?
50
+ issue_in_range = Date.parse(issue["fields"]["created"]) < end_date
61
51
 
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
52
+ # logs created date?
53
+ logs_in_range = in_range_logs(start_date, end_date, issue).any?
54
+
55
+ # select if
56
+ (logs_in_range or issue_in_range)
68
57
  end
69
58
 
70
- # collect stat hashes
71
- return issues.collect do |issue|
59
+ # stat hashes
60
+ return in_range_issues.collect do |issue|
72
61
 
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
62
+ # most recent in-range log?
63
+ changelog = in_range_logs(start_date, end_date, issue)
64
+ .sort_by { |l| Date.parse(l["created"]) }.last
65
+
66
+ # yield stat hash
67
+ status = changelog ? changelog["toString"] : issue["fields"]["status"]["name"]
68
+ {
69
+ key: issue["key"],
70
+ issuetype: issue["fields"]["issuetype"]["name"],
71
+ status: status
72
+ }
95
73
  end.compact
96
74
  end
97
75
 
@@ -99,37 +77,70 @@ def print_stats(stat_hashes, start_date, end_date)
99
77
  counts = {
100
78
  start_date: start_date.strftime("%m-%d-%Y"),
101
79
  end_date: end_date.strftime("%m-%d-%Y"),
80
+ total: 0,
102
81
  total_todo: 0,
103
82
  total_done: 0,
104
- total: stat_hashes ? stat_hashes.count : 0
83
+ by_type: {}
105
84
  }
106
- return counts unless stat_hashes.any?
107
- stat_hashes.each do |stat|
108
85
 
86
+ stat_hashes.each do |stat|
109
87
  issuetype = stat[:issuetype]
110
88
  status = stat[:status]
111
89
 
112
- # count all
113
- increment(counts, "status_#{issuetype.downcase.underscore}")
114
-
115
90
  # count by status
116
91
  case status
117
- when "Ready","Rework","In Progress","In QA","Ready For Code Review","In Code Review"
92
+ when "To Do","Ready","Rework","In Progress","In QA","Ready For Code Review","In Code Review"
93
+ increment_type(counts, issuetype, :to_do)
118
94
  increment(counts, :total_todo)
119
95
  when "Ready to Deploy","Closed"
96
+ increment_type(counts, issuetype, :done)
120
97
  increment(counts, :total_done)
121
- # else
122
- # raise "invalid ticket status: #{status}"
98
+ else
99
+ # if status != "Won't Do"
100
+ # debugger
101
+ # end
123
102
  end
103
+
104
+ # count totals
105
+ unless status=="Won't Do"
106
+ increment(counts, :total)
107
+ increment_type(counts, issuetype, :total)
108
+ end
109
+
124
110
  end
125
111
  return counts
126
112
  end
127
113
 
114
+ def oldest_issue_date(issues)
115
+ return issues.collect {|i| Date.parse(i["fields"]["created"])}.sort.first.beginning_of_day
116
+ end
117
+
118
+ def increment_type(hash, type, status_category)
119
+ type = type.downcase.underscore
120
+ hash[:by_type][type] = {} unless hash[:by_type].key?(type)
121
+ hash[:by_type][type][status_category] ||= 0
122
+ hash[:by_type][type][status_category] += 1
123
+ end
124
+
128
125
  def increment(hash, key)
129
- if hash.key? key
130
- hash[key] += 1
131
- else
132
- hash[key] = 1
126
+ hash[key] ||= 0
127
+ hash[key] += 1
128
+ end
129
+
130
+ def iter_date_range(start_date)
131
+ while start_date < Date.today.end_of_week
132
+ yield start_date.beginning_of_week.beginning_of_day, start_date.end_of_week.end_of_day
133
+ start_date += 1.weeks # increment
134
+ end
135
+ end
136
+
137
+ def do_work(options)
138
+ issues = get_issues_from_datafile(options)
139
+ oldest_date = oldest_issue_date(issues).beginning_of_week
140
+ iter_date_range(oldest_date) do |start_date, end_date|
141
+ stat_hashes = in_range_issue_stats(issues, start_date, end_date, options)
142
+ counts = print_stats(stat_hashes, start_date, end_date)
143
+ puts counts # print each time range
133
144
  end
134
145
  end
135
146
 
@@ -160,6 +171,10 @@ global = OptionParser.new do |g|
160
171
  options[:exclude_issuetypes] = v.split(',')
161
172
  options[:exclude_issuetypes] << "Won't Do"
162
173
  end
174
+
175
+ g.on("-l", "--exclude-labels CSV", "comma separated list of labels that will cause a ticket to be excluded") do |v|
176
+ options[:exclude_labels] = v.split(',')
177
+ end
163
178
  end
164
179
 
165
180
  #
@@ -171,10 +186,14 @@ global.parse(ARGV)
171
186
 
172
187
  # prompt for missing options
173
188
  ask_and_store_option(options, :data_filepath, "data_filepath: ")
189
+ options[:exclude_issuetypes] = [] if options[:exclude_issuetypes].nil?
190
+ options[:exclude_labels] = [] if options[:exclude_labels].nil?
174
191
 
175
192
  # display full command
176
193
  write_history("""#{@cl_cmd_name} \\
177
- --data-filepath=#{options[:data_filepath]}
194
+ --data-filepath=#{options[:data_filepath]} \\
195
+ --exclude-issuetypes=#{options[:exclude_issuetypes].join(',')} \\
196
+ --exclude-labels=#{options[:exclude_labels].join(',')}
178
197
  """)
179
198
 
180
199
  do_work(options)
data/lib/cl/magic/cl-poll CHANGED
@@ -17,10 +17,10 @@ require 'cl/magic/common/kubectl.rb'
17
17
  # Features
18
18
  #
19
19
 
20
- def do_work(options)
20
+ def do_work(options, remaining_options)
21
21
  while true
22
- tty_command = TTY::Command.new(printer: :null)
23
- out, err = tty_command.run(ARGV.join(' '))
22
+ tty_command = TTY::Command.new(printer: :null, pty: options[:pty])
23
+ out, err = tty_command.run("cd #{@working_dir} && #{remaining_options.join(' ')}")
24
24
  puts out
25
25
  puts
26
26
  sleep(1)
@@ -31,7 +31,9 @@ end
31
31
  # Options
32
32
  #
33
33
 
34
- options = {}
34
+ options = {
35
+ pty: true
36
+ }
35
37
  global_banner = <<DOC
36
38
 
37
39
  A sandbox to try things
@@ -43,10 +45,23 @@ DOC
43
45
  global = OptionParser.new do |g|
44
46
  g.banner = global_banner
45
47
  add_help_and_verbose(g)
48
+
49
+ g.on("--no-pty", "disable pseudo terminal") do |v|
50
+ options[:pty] = v
51
+ end
46
52
  end
47
53
 
48
54
  #
49
55
  # Run
50
56
  #
51
57
 
52
- do_work(options)
58
+ remaining_options = []
59
+ global.order! do |option|
60
+ remaining_options << option
61
+ end
62
+
63
+ global.parse(ARGV)
64
+
65
+ @working_dir = ENV['CL_WORKING_DIR'] # passed through cl-magic to here
66
+
67
+ do_work(options, remaining_options)
@@ -1,4 +1,3 @@
1
- require 'byebug'
2
1
 
3
2
  class Jira
4
3
 
@@ -16,7 +15,9 @@ class Jira
16
15
  def get_epic_ids(project, epic_wildcard)
17
16
  jql_query = "project = \"#{project}\" AND issuetype = Epic AND text ~ \"#{epic_wildcard}\""
18
17
  results = run_jql_query(jql_query)
19
- return results.select{|h| h['fields']['summary'].start_with? epic_wildcard}.map {|h| h['id']}
18
+ epics = results.select{|h| h['fields']['summary'].start_with? epic_wildcard}
19
+ epic_ids = epics.map {|h| h['id']}
20
+ return epic_ids, epics
20
21
  end
21
22
 
22
23
  def get_issues(project, epic_ids)
@@ -153,7 +154,7 @@ def collect_status_changelogs(jira, issues, options)
153
154
  # append them to issue
154
155
  status_logs.each do |status_log|
155
156
  issue["status_changelogs"] << status_log
156
- end if status_logs.count > 0
157
+ end
157
158
  end
158
159
 
159
160
  final_issue_hashes << issue # save
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Cl
4
4
  module Magic
5
- VERSION = "0.3.9"
5
+ VERSION = "0.4.0"
6
6
  end
7
7
  end
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: 0.3.9
4
+ version: 0.4.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-07-03 00:00:00.000000000 Z
11
+ date: 2023-07-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake