abide_dev_utils 0.16.0 → 0.17.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: 220a0a755c0e337d22a853e106935f4355564e51a759eb93967e3aeba5a9f020
4
- data.tar.gz: e0272122e07a4e53d3efa71486de5dc7a0229ca0d22214b3311c94df0c90100b
3
+ metadata.gz: 0216511efe504da6597b81a7b494975377b8afe013697e37f9985467a6a4fa14
4
+ data.tar.gz: '08265323331b31cb17e875b951ce89dfcb83bbb9649c0df97513cff26355f713'
5
5
  SHA512:
6
- metadata.gz: c7710f102655653f4181694c8dd076acff1dfd8040120c54157bc77a89f3db4a892854d2110ac4a47974ead2fdc23c3b3028c4459aa9e7bf75145e71fcebad0b
7
- data.tar.gz: a5d0d101010f6ba4129346c4c4447f433b5a61e36e9000c3dab653a1709b78ff08203ec2dd014e61489d09eb2a78badfb51e233d8cbe33d85c903c3654cae90f
6
+ metadata.gz: 9cbd439058affe3311587d81d4dfe75191abe9f9fb1a1f8c964c2a8187f02cf9057943e4bacd5aaeb1676c936cccdd5e196b9d4a0822ed0c725d06fe0c46f0d3
7
+ data.tar.gz: f01c66b8079d9d257de1158f4a1f9f529b2e9e31c8eb04a19fa21fee63f34b2fa018b8e3bba8eefce2bf90d20f23249e27a83126f54057232aef6bd7658cbe0a
data/Gemfile.lock CHANGED
@@ -1,14 +1,14 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- abide_dev_utils (0.16.0)
4
+ abide_dev_utils (0.17.0)
5
5
  cmdparse (~> 3.0)
6
6
  facterdb (>= 1.21)
7
7
  google-cloud-storage (~> 1.34)
8
8
  hashdiff (~> 1.0)
9
9
  jira-ruby (~> 2.2)
10
10
  nokogiri (~> 1.13)
11
- puppet (>= 6.23)
11
+ puppet (>= 7.0.0)
12
12
  puppet-strings (>= 2.7)
13
13
  ruby-progressbar (~> 1.11)
14
14
  selenium-webdriver (~> 4.0.0.beta4)
@@ -17,7 +17,7 @@ GEM
17
17
  remote: https://rubygems.org/
18
18
  specs:
19
19
  CFPropertyList (2.3.6)
20
- activesupport (7.0.4.3)
20
+ activesupport (7.0.7.2)
21
21
  concurrent-ruby (~> 1.0, >= 1.0.2)
22
22
  i18n (>= 1.6, < 2)
23
23
  minitest (>= 5.1)
@@ -29,15 +29,15 @@ GEM
29
29
  console (~> 1.10)
30
30
  nio4r (~> 2.3)
31
31
  timers (~> 4.1)
32
- async-http (0.56.6)
32
+ async-http (0.60.2)
33
33
  async (>= 1.25)
34
34
  async-io (>= 1.28)
35
35
  async-pool (>= 0.2)
36
- protocol-http (~> 0.22.0)
37
- protocol-http1 (~> 0.14.0)
38
- protocol-http2 (~> 0.14.0)
39
- traces (~> 0.4.0)
40
- async-http-faraday (0.11.0)
36
+ protocol-http (~> 0.24.0)
37
+ protocol-http1 (~> 0.15.0)
38
+ protocol-http2 (~> 0.15.0)
39
+ traces (>= 0.10.0)
40
+ async-http-faraday (0.12.0)
41
41
  async-http (~> 0.42)
42
42
  faraday
43
43
  async-io (1.33.0)
@@ -69,7 +69,7 @@ GEM
69
69
  faraday-http-cache (2.3.0)
70
70
  faraday (>= 0.8)
71
71
  faraday-net_http (2.0.3)
72
- fast_gettext (1.8.0)
72
+ fast_gettext (2.3.0)
73
73
  fiber-local (1.0.0)
74
74
  gem-release (2.2.2)
75
75
  github_changelog_generator (1.16.4)
@@ -120,7 +120,7 @@ GEM
120
120
  hiera (3.12.0)
121
121
  hocon (1.4.0)
122
122
  httpclient (2.8.3)
123
- i18n (1.12.0)
123
+ i18n (1.14.1)
124
124
  concurrent-ruby (~> 1.0)
125
125
  jgrep (1.5.4)
126
126
  jira-ruby (2.3.0)
@@ -133,12 +133,16 @@ GEM
133
133
  memoist (0.16.2)
134
134
  method_source (1.0.0)
135
135
  mini_mime (1.1.2)
136
- minitest (5.18.0)
136
+ minitest (5.19.0)
137
137
  multi_json (1.15.0)
138
138
  multipart-post (2.3.0)
139
139
  nio4r (2.5.8)
140
+ nokogiri (1.15.2-arm64-darwin)
141
+ racc (~> 1.4)
140
142
  nokogiri (1.15.2-x86_64-darwin)
141
143
  racc (~> 1.4)
144
+ nokogiri (1.15.2-x86_64-linux)
145
+ racc (~> 1.4)
142
146
  oauth (0.6.2)
143
147
  snaky_hash (~> 2.0)
144
148
  version_gem (~> 1.1)
@@ -150,16 +154,27 @@ GEM
150
154
  parser (3.1.2.0)
151
155
  ast (~> 2.4.1)
152
156
  protocol-hpack (1.4.2)
153
- protocol-http (0.22.6)
154
- protocol-http1 (0.14.4)
157
+ protocol-http (0.24.7)
158
+ protocol-http1 (0.15.1)
155
159
  protocol-http (~> 0.22)
156
- protocol-http2 (0.14.2)
160
+ protocol-http2 (0.15.1)
157
161
  protocol-hpack (~> 1.4)
158
162
  protocol-http (~> 0.18)
159
163
  pry (0.14.1)
160
164
  coderay (~> 1.1)
161
165
  method_source (~> 1.0)
162
166
  public_suffix (4.0.7)
167
+ puppet (7.24.0)
168
+ concurrent-ruby (~> 1.0, < 1.2.0)
169
+ deep_merge (~> 1.0)
170
+ facter (> 2.0.1, < 5)
171
+ fast_gettext (>= 1.1, < 3)
172
+ hiera (>= 3.2.1, < 4)
173
+ locale (~> 2.1)
174
+ multi_json (~> 1.10)
175
+ puppet-resource_api (~> 1.5)
176
+ scanf (~> 1.0)
177
+ semantic_puppet (~> 1.0)
163
178
  puppet (7.24.0-universal-darwin)
164
179
  CFPropertyList (~> 2.2)
165
180
  concurrent-ruby (~> 1.0, < 1.2.0)
@@ -241,7 +256,7 @@ GEM
241
256
  version_gem (~> 1.1, >= 1.1.1)
242
257
  thor (1.2.2)
243
258
  timers (4.3.3)
244
- traces (0.4.1)
259
+ traces (0.11.1)
245
260
  trailblazer-option (0.1.2)
246
261
  tzinfo (2.0.6)
247
262
  concurrent-ruby (~> 1.0)
@@ -252,6 +267,7 @@ GEM
252
267
  yard (0.9.34)
253
268
 
254
269
  PLATFORMS
270
+ arm64-darwin-22
255
271
  x86_64-darwin-19
256
272
  x86_64-darwin-20
257
273
  x86_64-linux
@@ -260,7 +276,7 @@ DEPENDENCIES
260
276
  abide_dev_utils!
261
277
  bundler
262
278
  console
263
- fast_gettext (~> 1.8)
279
+ fast_gettext (>= 2.0)
264
280
  gem-release
265
281
  github_changelog_generator
266
282
  pry
@@ -273,4 +289,4 @@ DEPENDENCIES
273
289
  rubocop-rspec (~> 2.1)
274
290
 
275
291
  BUNDLED WITH
276
- 2.3.9
292
+ 2.4.19
@@ -34,7 +34,7 @@ Gem::Specification.new do |spec|
34
34
  # Prod dependencies
35
35
  spec.add_dependency 'nokogiri', '~> 1.13'
36
36
  spec.add_dependency 'cmdparse', '~> 3.0'
37
- spec.add_dependency 'puppet', '>= 6.23'
37
+ spec.add_dependency 'puppet', '>= 7.0.0'
38
38
  spec.add_dependency 'puppet-strings', '>= 2.7'
39
39
  spec.add_dependency 'jira-ruby', '~> 2.2'
40
40
  spec.add_dependency 'ruby-progressbar', '~> 1.11'
@@ -56,7 +56,7 @@ Gem::Specification.new do |spec|
56
56
  spec.add_development_dependency 'rubocop-ast', '~> 1.4'
57
57
  spec.add_development_dependency 'rubocop-performance', '~> 1.9'
58
58
  spec.add_development_dependency 'rubocop-i18n', '~> 3.0'
59
- spec.add_development_dependency 'fast_gettext', '~> 1.8'
59
+ spec.add_development_dependency 'fast_gettext', '>= 2.0'
60
60
 
61
61
  # For more information and examples about making a new gem, checkout our
62
62
  # guide at: https://bundler.io/guides/creating_gem.html
@@ -382,7 +382,12 @@ module AbideDevUtils
382
382
  # @valid_level is populated in verify_profile_and_level_selections from the fact that we've given
383
383
  # the generator a list of levels we want to use. If we didn't give it a list of levels, then we
384
384
  # want to use all of the levels that the control supports from @control.
385
- @md.add_ul('Supported Levels:')
385
+ if @framework == 'stig'
386
+ @md.add_ul('Supported MAC Levels:')
387
+ else
388
+ @md.add_ul('Supported Levels:')
389
+ end
390
+
386
391
  if @valid_level.empty?
387
392
  @control.levels.each do |l|
388
393
  @md.add_ul(@md.code(l), indent: 1)
@@ -400,7 +405,12 @@ module AbideDevUtils
400
405
  # @valid_profile is populated in verify_profile_and_level_selections from the fact that we've given
401
406
  # the generator a list of profiles we want to use. If we didn't give it a list of profiles, then we
402
407
  # want to use all of the profiles that the control supports from @control.
403
- @md.add_ul('Supported Profiles:')
408
+ if @framework == 'stig'
409
+ @md.add_ul('Supported Confidentiality:')
410
+ else
411
+ @md.add_ul('Supported Profiles:')
412
+ end
413
+
404
414
  if @valid_profile.empty?
405
415
  @control.profiles.each do |l|
406
416
  @md.add_ul(@md.code(l), indent: 1)
@@ -413,7 +423,7 @@ module AbideDevUtils
413
423
  end
414
424
 
415
425
  def control_alternate_ids_builder
416
- return if @framework == 'stig'
426
+ # return if @framework == 'stig'
417
427
 
418
428
  @md.add_ul('Alternate Config IDs:')
419
429
  @control.alternate_ids.each do |l|
@@ -459,7 +469,7 @@ module AbideDevUtils
459
469
 
460
470
  @control.title.nil? ? out_str.unshift(" #{@control.id.dump}:") : out_str.unshift(" #{@control.title.dump}:")
461
471
  out_str.unshift(' control_configs:')
462
- out_str.unshift("#{@module_name}::config:")
472
+ out_str.unshift("#{@module_name.split('-').last}::config:")
463
473
  @md.add_ul('Hiera Configuration Example:')
464
474
  @md.add_code_block(out_str.join("\n"), language: 'yaml')
465
475
  rescue StandardError => e
@@ -6,9 +6,6 @@ require 'abide_dev_utils/jira'
6
6
 
7
7
  module Abide
8
8
  module CLI
9
- CONFIG = AbideDevUtils::Config
10
- JIRA = AbideDevUtils::Jira
11
-
12
9
  class JiraCommand < CmdParse::Command
13
10
  CMD_NAME = 'jira'
14
11
  CMD_SHORT = 'Commands related to Jira tickets'
@@ -38,11 +35,9 @@ module Abide
38
35
  end
39
36
 
40
37
  def execute
41
- client = JIRA.client
42
- myself = JIRA.myself(client)
43
- return if myself.attrs['name'].empty?
38
+ return if AbideDevUtils::Jira.client.myself.attrs['displayName'].empty?
44
39
 
45
- Abide::CLI::OUTPUT.simple("Successfully authenticated user #{myself.attrs['name']}!")
40
+ Abide::CLI::OUTPUT.simple("Successfully authenticated user #{AbideDevUtils::Jira.client.myself.attrs['displayName']}!")
46
41
  end
47
42
  end
48
43
 
@@ -59,8 +54,7 @@ module Abide
59
54
  end
60
55
 
61
56
  def execute(issue)
62
- client = JIRA.client(options: {})
63
- issue = client.Issue.find(issue)
57
+ issue = AbideDevUtils::Jira.client.find(:issue, issue)
64
58
  console = @data[:file].nil?
65
59
  out_json = issue.attrs.select { |_, v| !v.nil? || !v.empty? }
66
60
  Abide::CLI::OUTPUT.json(out_json, console: console, file: @data[:file])
@@ -83,13 +77,15 @@ module Abide
83
77
  end
84
78
 
85
79
  def execute(project, summary, *subtasks)
86
- client = JIRA.client(options: {})
87
- issue = JIRA.new_issue(client, project, summary)
80
+ issue = AbideDevUtils::Jira.client.create(:issue, project: project, summary: summary)
88
81
  Abide::CLI::OUTPUT.simple("Successfully created #{issue.attrs['key']}")
89
82
  return if subtasks.nil? || subtasks.empty?
90
83
 
91
84
  Abide::CLI::OUTPUT.simple('Creatings subtasks...')
92
- JIRA.bulk_new_subtask(client, JIRA.issue(client, issue.attrs['key']), subtasks) unless subtasks.empty?
85
+ subtasks.each do |sum|
86
+ subtask = AbideDevUtils::Jira.client.create(:subtask, parent: issue, summary: sum)
87
+ Abide::CLI::OUTPUT.simple("Successfully created #{subtask.attrs['key']}")
88
+ end
93
89
  end
94
90
  end
95
91
 
@@ -107,11 +103,8 @@ module Abide
107
103
 
108
104
  def execute(report, project)
109
105
  Abide::CLI::VALIDATE.file(report)
110
- @data[:dry_run] = false if @data[:dry_run].nil?
111
- client = JIRA.client(options: {})
112
- proj = JIRA.project(client, project)
113
106
  File.open(report) do |f|
114
- JIRA.new_issues_from_coverage(client, proj, JSON.parse(f.read), dry_run: @data[:dry_run])
107
+ AbideDevUtils::Jira.new_issues_from_coverage(project, JSON.parse(f.read), dry_run: @data[:dry_run])
115
108
  end
116
109
  end
117
110
  end
@@ -127,14 +120,30 @@ module Abide
127
120
  argument_desc(PATH: 'An XCCDF file', PROJECT: 'A Jira project')
128
121
  options.on('-d', '--dry-run', 'Print to console instead of saving objects') { |_| @data[:dry_run] = true }
129
122
  options.on('-e [EPIC]', '--epic [EPIC]', 'If given, tasks will be created and assigned to this epic. Takes form <PROJECT>-<NUM>') { |e| @data[:epic] = e }
123
+ options.on('-l [LEVEL]', '--level [LEVEL]', 'Only create tasks for rules belonging to the matching level. Takes a string that is treated as RegExp') do |x|
124
+ @data[:level] = x
125
+ end
126
+ options.on('-p [PROFILE]', '--profile [PROFILE]', 'Only create tasks for rules belonging to the matching profile. Takes a string that is treated as RegExp') do |x|
127
+ @data[:profile] = x
128
+ end
130
129
  end
131
130
 
132
131
  def execute(path, project)
133
132
  Abide::CLI::VALIDATE.file(path)
134
- @data[:dry_run] = false if @data[:dry_run].nil?
135
- client = JIRA.client(options: {})
136
- proj = JIRA.project(client, project)
137
- JIRA.new_issues_from_xccdf(client, proj, path, epic: @data[:epic], dry_run: @data[:dry_run])
133
+ # Each control gets assigned labels based on the levels and profiles it supports.
134
+ # Those labels all take the form "level_<level>_<profile>". This allows us to
135
+ # filter the controls we want to create tasks for by level and profile.
136
+ @data[:label_include] = nil
137
+ @data[:label_include] = "level_#{@data[:level]}_" if @data[:level]
138
+ @data[:label_include] = "#{@data[:label_include]}#{@data[:profile]}" if @data[:profile]
139
+ Abide::CLI::Output.simple "Label include: #{@data[:label_include]}"
140
+ AbideDevUtils::Jira.new_issues_from_xccdf(
141
+ project,
142
+ path,
143
+ epic: @data[:epic],
144
+ dry_run: @data[:dry_run],
145
+ label_include: @data[:label_include],
146
+ )
138
147
  end
139
148
  end
140
149
 
@@ -167,17 +176,15 @@ module Abide
167
176
  def execute(path1, path2, project)
168
177
  Abide::CLI::VALIDATE.file(path1)
169
178
  Abide::CLI::VALIDATE.file(path2)
170
- @data[:dry_run] = false if @data[:dry_run].nil?
171
- client = JIRA.client(options: {})
172
- proj = JIRA.project(client, project)
173
- JIRA.new_issues_from_xccdf_diff(client,
174
- proj,
175
- path1,
176
- path2,
177
- epic: @data[:epic],
178
- dry_run: @data[:dry_run],
179
- auto_approve: @data[:auto_approve],
180
- diff_opts: @data[:diff_opts])
179
+ AbideDevUtils::Jira.new_issues_from_xccdf_diff(
180
+ project,
181
+ path1,
182
+ path2,
183
+ epic: @data[:epic],
184
+ dry_run: @data[:dry_run],
185
+ auto_approve: @data[:auto_approve],
186
+ diff_opts: @data[:diff_opts],
187
+ )
181
188
  end
182
189
  end
183
190
  end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'client_builder'
4
+ require_relative 'dry_run'
5
+ require_relative 'finder'
6
+ require_relative 'helper'
7
+ require_relative 'issue_builder'
8
+ require_relative '../config'
9
+ require_relative '../errors/jira'
10
+
11
+ module AbideDevUtils
12
+ module Jira
13
+ class Client
14
+ extend DryRun
15
+
16
+ dry_run :create, :find, :myself
17
+
18
+ attr_accessor :default_project
19
+ attr_reader :config
20
+
21
+ def initialize(dry_run: false, **options)
22
+ @dry_run = dry_run
23
+ @options = options
24
+ @config = AbideDevUtils::Config.config_section('jira')
25
+ @default_project = @config[:default_project]
26
+ @client = nil
27
+ @finder = nil
28
+ @issue_builder = nil
29
+ @helper = nil
30
+ end
31
+
32
+ def myself
33
+ @myself ||= finder.myself
34
+ end
35
+
36
+ def find(type, id)
37
+ raise ArgumentError, "Invalid type #{type}" unless finder.respond_to?(type.to_sym)
38
+
39
+ finder.send(type.to_sym, id)
40
+ end
41
+
42
+ def create(type, **fields)
43
+ issue_builder.create(type, **fields)
44
+ end
45
+
46
+ def helper
47
+ @helper ||= Helper.new(self, dry_run: @dry_run)
48
+ end
49
+
50
+ private
51
+
52
+ def client
53
+ @client ||= ClientBuilder.new(@config, **@options).build
54
+ end
55
+
56
+ def finder
57
+ @finder ||= Finder.new(client)
58
+ end
59
+
60
+ def issue_builder
61
+ @issue_builder ||= IssueBuilder.new(client, finder)
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,107 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'jira-ruby'
4
+ require_relative '../prompt'
5
+
6
+ module AbideDevUtils
7
+ module Jira
8
+ class ClientBuilder
9
+ def initialize(config, **options)
10
+ @options = options
11
+ @config = config
12
+ end
13
+
14
+ def username
15
+ find_option_value(:username)
16
+ end
17
+
18
+ def username=(username)
19
+ @options[:username] = username
20
+ end
21
+
22
+ def password
23
+ if find_option_value(:password)
24
+ '********'
25
+ else
26
+ nil
27
+ end
28
+ end
29
+
30
+ def password=(password)
31
+ @options[:password] = password
32
+ end
33
+
34
+ def site
35
+ find_option_value(:site)
36
+ end
37
+
38
+ def site=(site)
39
+ @options[:site] = site
40
+ end
41
+
42
+ def context_path
43
+ find_option_value(:context_path, default: '')
44
+ end
45
+
46
+ def context_path=(context_path)
47
+ @options[:context_path] = context_path
48
+ end
49
+
50
+ def auth_type
51
+ find_option_value(:auth_type, default: :basic)
52
+ end
53
+
54
+ def auth_type=(auth_type)
55
+ @options[:auth_type] = auth_type
56
+ end
57
+
58
+ def http_debug
59
+ find_option_value(:http_debug, default: false)
60
+ end
61
+
62
+ def http_debug=(http_debug)
63
+ @options[:http_debug] = http_debug
64
+ end
65
+
66
+ def build
67
+ JIRA::Client.new({
68
+ username: find_option_value(:username, prompt: true),
69
+ password: find_option_value(:password, prompt: true),
70
+ site: find_option_value(:site, prompt: 'Jira site URL'),
71
+ context_path: find_option_value(:context_path, default: ''),
72
+ auth_type: find_option_value(:auth_type, default: :basic),
73
+ http_debug: find_option_value(:http_debug, default: false),
74
+ })
75
+ end
76
+
77
+ private
78
+
79
+ def find_option_value(key, default: nil, prompt: nil)
80
+ if prompt
81
+ find_option_value_or_prompt(key, prompt)
82
+ else
83
+ find_option_value_or_default(key, default)
84
+ end
85
+ end
86
+
87
+ def find_option_val(key)
88
+ @options[key] || @config[key] || ENV["JIRA_#{key.to_s.upcase}"]
89
+ end
90
+
91
+ def find_option_value_or_prompt(key, prompt = 'Enter value')
92
+ case key
93
+ when /password/i
94
+ find_option_val(key) || AbideDevUtils::Prompt.password
95
+ when /username/i
96
+ find_option_val(key) || AbideDevUtils::Prompt.username
97
+ else
98
+ find_option_val(key) || AbideDevUtils::Prompt.single_line(prompt)
99
+ end
100
+ end
101
+
102
+ def find_option_value_or_default(key, default)
103
+ find_option_val(key) || default
104
+ end
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,133 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../output'
4
+
5
+ module AbideDevUtils
6
+ module Jira
7
+ module DryRun
8
+ def dry_run(*method_names)
9
+ method_names.each do |method_name|
10
+ proxy = Module.new do
11
+ define_method(method_name) do |*args, **kwargs|
12
+ if !!@dry_run
13
+ case method_name
14
+ when %r{^create}
15
+ AbideDevUtils::Output.simple("DRY RUN: #{self.class.name}##{method_name}(#{args[0]}, #{args[1].map { |k, v| "#{k}: #{v.inspect}" }.join(', ')})")
16
+ sleep 0.1
17
+ return DummyIssue.new if args[0].match?(%r{^issue$})
18
+ return DummySubtask.new if args[0].match?(%r{^subtask$})
19
+ when %r{^find}
20
+ AbideDevUtils::Output.simple("DRY RUN: #{self.class.name}##{method_name}(#{args[0]}, #{args[1].inspect})")
21
+ return DummyIssue.new if args[0].match?(%r{^issue$})
22
+ return DummySubtask.new if args[0].match?(%r{^subtask$})
23
+ return DummyProject.new if args[0].match?(%r{^project$})
24
+
25
+ "Dummy #{args[0].capitalize}"
26
+ else
27
+ AbideDevUtils::Output.simple("DRY RUN: #{self.class.name}##{method_name}(#{args.map(&:inspect).join(', ')})")
28
+ end
29
+ else
30
+ super(*args, **kwargs)
31
+ end
32
+ end
33
+ end
34
+ self.prepend(proxy)
35
+ end
36
+ end
37
+
38
+ def dry_run_simple(*method_names)
39
+ method_names.each do |method_name|
40
+ proxy = Module.new do
41
+ define_method(method_name) do |*args, **kwargs|
42
+ return if !!@dry_run
43
+
44
+ super(*args, **kwargs)
45
+ end
46
+ end
47
+ self.prepend(proxy)
48
+ end
49
+ end
50
+
51
+ def dry_run_return_true(*method_names)
52
+ method_names.each do |method_name|
53
+ proxy = Module.new do
54
+ define_method(method_name) do |*args, **kwargs|
55
+ return true if !!@dry_run
56
+
57
+ super(*args, **kwargs)
58
+ end
59
+ end
60
+ self.prepend(proxy)
61
+ end
62
+ end
63
+
64
+ def dry_run_return_false(*method_names)
65
+ method_names.each do |method_name|
66
+ proxy = Module.new do
67
+ define_method(method_name) do |*args, **kwargs|
68
+ return false if !!@dry_run
69
+
70
+ super(*args, **kwargs)
71
+ end
72
+ end
73
+ self.prepend(proxy)
74
+ end
75
+ end
76
+
77
+ class Dummy
78
+ attr_reader :dummy
79
+
80
+ def initialize
81
+ @dummy = true
82
+ end
83
+ end
84
+
85
+ class DummyIssue < Dummy
86
+ attr_reader :summary, :key
87
+
88
+ def initialize
89
+ super
90
+ @summary = 'Dummy Issue'
91
+ @key = 'DUM-111'
92
+ end
93
+
94
+ def attrs
95
+ {
96
+ 'fields' => {
97
+ 'project' => 'dummy',
98
+ 'priority' => 'dummy',
99
+ },
100
+ }
101
+ end
102
+ end
103
+
104
+ class DummySubtask < DummyIssue
105
+ def initialize
106
+ super
107
+ @summary = 'Dummy Subtask'
108
+ @key = 'DUM-222'
109
+ end
110
+
111
+ def attrs
112
+ {
113
+ 'fields' => {
114
+ 'project' => 'dummy',
115
+ 'priority' => 'dummy',
116
+ 'parent' => DummyIssue.new,
117
+ },
118
+ }
119
+ end
120
+ end
121
+
122
+ class DummyProject < Dummy
123
+ attr_reader :key, :issues
124
+
125
+ def initialize
126
+ super
127
+ @key = 'DUM'
128
+ @issues = [DummyIssue.new, DummySubtask.new]
129
+ end
130
+ end
131
+ end
132
+ end
133
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../errors/jira'
4
+
5
+ module AbideDevUtils
6
+ module Jira
7
+ class Finder
8
+ def initialize(client)
9
+ @client = client
10
+ end
11
+
12
+ def myself
13
+ client.User.myself
14
+ end
15
+
16
+ # @param id [String] The project key or ID
17
+ def project(id)
18
+ return id if id.is_a?(client.Project.target_class)
19
+
20
+ client.Project.find(id)
21
+ end
22
+
23
+ # @param id [String] The issue key or summary
24
+ def issue(id)
25
+ return id if id.is_a?(client.Issue.target_class)
26
+
27
+ client.Issue.find(id)
28
+ rescue URI::InvalidURIError
29
+ iss = client.Issue.all.find { |i| i.summary == id }
30
+ raise AbideDevUtils::Errors::Jira::FindIssueError, id if iss.nil?
31
+
32
+ iss
33
+ end
34
+
35
+ # @param id [String] The issuetype ID or name
36
+ def issuetype(id)
37
+ return id if id.is_a?(client.Issuetype.target_class)
38
+
39
+ if id.match?(%r{^\d+$})
40
+ client.Issuetype.find(id)
41
+ else
42
+ client.Issuetype.all.find { |i| i.name == id }
43
+ end
44
+ end
45
+
46
+ # @param id [String] The priority ID or name
47
+ def priority(id)
48
+ return id if id.is_a?(client.Priority.target_class)
49
+
50
+ if id.match?(%r{^\d+$})
51
+ client.Priority.find(id)
52
+ else
53
+ client.Priority.all.find { |i| i.name == id }
54
+ end
55
+ end
56
+
57
+ private
58
+
59
+ attr_reader :client
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'dry_run'
4
+
5
+ module AbideDevUtils
6
+ module Jira
7
+ class Helper
8
+ extend DryRun
9
+
10
+ dry_run_simple :add_issue_label
11
+ dry_run_return_false :summary_exist?
12
+
13
+ def initialize(client, dry_run: false)
14
+ @client = client
15
+ @dry_run = dry_run
16
+ end
17
+
18
+ # @param project [JIRA::Resource::Project, String]
19
+ def all_project_issues_attrs(project)
20
+ project = @client.find(:project, project)
21
+ project.issues.collect(&:attrs)
22
+ end
23
+
24
+ # @param issue [JIRA::Resource::Issue, String]
25
+ # @param label [String]
26
+ def add_issue_label(issue, label)
27
+ issue = @client.find(:issue, issue)
28
+ return if issue.labels.include?(label)
29
+
30
+ issue.labels << label
31
+ issue.save
32
+ end
33
+
34
+ # @param summary [String]
35
+ # @param issue_attrs [Array<Hash>]
36
+ def summary_exist?(summary, issue_attrs)
37
+ issue_attrs.any? { |attrs| attrs['fields'].key?('summary') && attrs['fields']['summary'] == summary }
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,110 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../errors/jira'
4
+
5
+ module AbideDevUtils
6
+ module Jira
7
+ class IssueBuilder
8
+ CUSTOM_FIELDS = {
9
+ 'epic_link' => 'customfield_10014',
10
+ 'epic_name' => 'customfield_10011',
11
+ }.freeze
12
+
13
+ FIELD_DEFAULTS = {
14
+ 'issuetype' => 'Task',
15
+ 'priority' => 'Medium',
16
+ 'labels' => ['abide_dev_utils'],
17
+ }.freeze
18
+
19
+ REQUIRED_FIELDS = %w[project summary].freeze
20
+
21
+ def initialize(client, finder)
22
+ @client = client
23
+ @finder = finder
24
+ end
25
+
26
+ def can_create?(type)
27
+ respond_to?("create_#{type}".to_sym, true)
28
+ end
29
+
30
+ def create(type, **fields)
31
+ type = type.to_s.downcase.to_sym
32
+ raise ArgumentError, "Invalid type \"#{type}\"; no method \"create_#{type}\"" unless can_create?(type)
33
+
34
+ fields = process_fields(fields)
35
+ send("create_#{type}".to_sym, **fields)
36
+ end
37
+
38
+ private
39
+
40
+ attr_reader :client
41
+
42
+ def create_issue(**fields)
43
+ iss = client.Issue.build
44
+ iss.save({ 'fields' => fields })
45
+ iss
46
+ rescue StandardError => e
47
+ raise AbideDevUtils::Errors::Jira::CreateIssueError, e
48
+ end
49
+
50
+ def create_subtask(**fields)
51
+ fields['parent'] = find_if_not_type(:issue, client.Issue.target_class, fields['parent'])
52
+ issue_fields = fields['parent'].attrs['fields']
53
+ fields['project'] = issue_fields['project']
54
+ fields['issuetype'] = find_if_not_type(:issuetype, client.Issuetype.target_class, 'Sub-task')
55
+ fields['priority'] = issue_fields['priority']
56
+ iss = client.Issue.build
57
+ iss.save({ 'fields' => fields })
58
+ iss
59
+ rescue StandardError => e
60
+ raise AbideDevUtils::Errors::Jira::CreateSubtaskError, e
61
+ end
62
+
63
+ def process_fields(fields)
64
+ fields = fields.dup
65
+ normalize_field_keys!(fields)
66
+ validate_required_fields!(fields)
67
+ normalize_field_values(fields)
68
+ end
69
+
70
+ def validate_required_fields!(fields)
71
+ missing = REQUIRED_FIELDS.reject { |f| fields.key?(f) }
72
+ raise "Missing required field(s) \"#{missing}\"; present fields: \"#{fields.keys}\"" unless missing.empty?
73
+ end
74
+
75
+ def normalize_field_keys!(fields)
76
+ fields.transform_keys! { |k| k.to_s.downcase }
77
+ fields.transform_keys! { |k| CUSTOM_FIELDS[k] || k }
78
+ end
79
+
80
+ def normalize_field_values(fields)
81
+ fields = FIELD_DEFAULTS.merge(fields).map do |k, v|
82
+ v = case k
83
+ when 'labels'
84
+ v.is_a?(Array) ? v : [v]
85
+ when 'issuetype'
86
+ find_if_not_type(:issuetype, client.Issuetype.target_class, v)
87
+ when 'parent'
88
+ find_if_not_type(:issue, client.Issue.target_class, v)
89
+ when 'priority'
90
+ find_if_not_type(:priority, client.Priority.target_class, v)
91
+ when 'epic_link', CUSTOM_FIELDS['epic_link']
92
+ find_if_not_type(:issue, client.Issue.target_class, v)&.key || v
93
+ when 'project'
94
+ find_if_not_type(:project, client.Project.target_class, v)
95
+ else
96
+ v
97
+ end
98
+ [k, v]
99
+ end
100
+ fields.to_h
101
+ end
102
+
103
+ def find_if_not_type(typesym, typeklass, obj)
104
+ return obj if obj.is_a?(typeklass)
105
+
106
+ @finder.send(typesym, obj)
107
+ end
108
+ end
109
+ end
110
+ end
@@ -5,6 +5,7 @@ require 'abide_dev_utils/output'
5
5
  require 'abide_dev_utils/prompt'
6
6
  require 'abide_dev_utils/config'
7
7
  require 'abide_dev_utils/errors/jira'
8
+ require_relative 'jira/client'
8
9
 
9
10
  module AbideDevUtils
10
11
  module Jira
@@ -14,195 +15,58 @@ module AbideDevUtils
14
15
  UPD_EPIC_SUMMARY_PREFIX = '::BENCHMARK UPDATE::'
15
16
  PROGRESS_BAR_FORMAT = '%a %e %P% Created: %c of %C'
16
17
 
17
- def self.project(client, project)
18
- client.Project.find(project)
19
- end
20
-
21
- def self.issue(client, issue)
22
- client.Issue.find(issue)
23
- rescue URI::InvalidURIError
24
- iss = client.Issue.all.find { |i| i.summary == issue }
25
- raise ERRORS::FindIssueError, issue unless iss
26
-
27
- iss
28
- end
29
-
30
- def self.myself(client)
31
- client.User.myself
32
- end
33
-
34
- def self.issuetype(client, id)
35
- if id.match?(%r{^\d+$})
36
- client.Issuetype.find(id)
37
- else
38
- client.Issuetype.all.find { |i| i.name == id }
39
- end
40
- end
41
-
42
- def self.priority(client, id)
43
- if id.match?(%r{^\d+$})
44
- client.Priority.find(id)
45
- else
46
- client.Priority.all.find { |i| i.name == id }
47
- end
48
- end
49
-
50
- def self.all_project_issues_attrs(project)
51
- raw_issues = project.issues
52
- raw_issues.collect(&:attrs)
53
- end
54
-
55
- def self.add_issue_label(iss, label, dry_run: false)
56
- return if dry_run || iss.labels.include?(label)
57
-
58
- iss.labels << profile_summary
59
- iss.save
60
- end
61
-
62
- def self.new_issue(client, project, summary, description: nil, labels: ['abide_dev_utils'], epic: nil, dry_run: false)
63
- if dry_run
64
- sleep(0.2)
65
- return Dummy.new(summary)
66
- end
67
- fields = {}
68
- fields['summary'] = summary
69
- fields['project'] = project(client, project)
70
- fields['reporter'] = myself(client)
71
- fields['issuetype'] = issuetype(client, 'Task')
72
- fields['priority'] = priority(client, '6')
73
- fields['description'] = description if description
74
- fields['labels'] = labels
75
- epic = issue(client, epic) if epic && !epic.is_a?(JIRA::Resource::Issue)
76
- fields['customfield_10006'] = epic.key if epic # Epic_Link
77
- iss = client.Issue.build
78
- raise ERRORS::CreateIssueError, iss.attrs unless iss.save({ 'fields' => fields })
79
-
80
- iss
81
- end
82
-
83
- def self.new_epic(client, project, summary, dry_run: false)
84
- AbideDevUtils::Output.simple("#{dr_prefix(dry_run)}Creating epic '#{summary}'")
85
- if dry_run
86
- sleep(0.2)
87
- return Dummy.new(summary)
88
- end
89
- fields = {
90
- 'summary' => summary,
91
- 'project' => project(client, project),
92
- 'reporter' => myself(client),
93
- 'issuetype' => issuetype(client, 'Epic'),
94
- 'customfield_10007' => summary, # Epic Name
95
- }
96
- iss = client.Issue.build
97
- raise ERRORS::CreateEpicError, iss.attrs unless iss.save({ 'fields' => fields })
98
-
99
- iss
100
- end
101
-
102
- # This should probably be threaded in the future
103
- def self.bulk_new_issue(client, project, summaries, dry_run: false)
104
- summaries.each { |s| new_issue(client, project, s, dry_run: dry_run) }
105
- end
106
-
107
- def self.new_subtask(client, issue, summary, dry_run: false)
108
- if dry_run
109
- sleep(0.2)
110
- return Dummy.new
111
- end
112
- issue_fields = issue.attrs['fields']
113
- fields = {}
114
- fields['parent'] = issue
115
- fields['summary'] = summary
116
- fields['project'] = issue_fields['project']
117
- fields['reporter'] = myself(client)
118
- fields['issuetype'] = issuetype(client, '5')
119
- fields['priority'] = issue_fields['priority']
120
- subtask = client.Issue.build
121
- raise ERRORS::CreateSubtaskError, subtask.attrs unless subtask.save({ 'fields' => fields })
122
-
123
- subtask
124
- end
125
-
126
- def self.bulk_new_subtask(client, issue, summaries, dry_run: false)
127
- summaries.each do |s|
128
- new_subtask(client, issue, s, dry_run: dry_run)
129
- end
130
- end
131
-
132
- def self.client(options: {})
133
- opts = merge_options(options)
134
- return client_from_prompts if opts.empty?
135
-
136
- opts[:username] = AbideDevUtils::Prompt.username if opts[:username].nil?
137
- opts[:password] = AbideDevUtils::Prompt.password if opts[:password].nil?
138
- opts[:site] = AbideDevUtils::Prompt.single_line('Jira URL') if opts[:site].nil?
139
- opts[:context_path] = '' if opts[:context_path].nil?
140
- opts[:auth_type] = :basic if opts[:auth_type].nil?
141
- JIRA::Client.new(opts)
142
- end
143
-
144
- def self.client_from_prompts(http_debug: false)
145
- options = {}
146
- options[:username] = AbideDevUtils::Prompt.username
147
- options[:password] = AbideDevUtils::Prompt.password
148
- options[:site] = AbideDevUtils::Prompt.single_line('Jira URL')
149
- options[:context_path] = ''
150
- options[:auth_type] = :basic
151
- options[:http_debug] = http_debug
152
- JIRA::Client.new(options)
153
- end
18
+ def self.client(memo: true, dry_run: false, **options)
19
+ return AbideDevUtils::Jira::Client.new(dry_run: dry_run, **options) unless memo
154
20
 
155
- def self.project_from_prompts(http_debug: false)
156
- client = client_from_prompts(http_debug)
157
- project = AbideDevUtils::Prompt.single_line('Project').upcase
158
- client.Project.find(project)
21
+ @client ||= AbideDevUtils::Jira::Client.new(dry_run: dry_run, **options)
159
22
  end
160
23
 
161
24
  def self.new_issues_from_coverage(client, project, report, dry_run: false)
162
25
  dr_prefix = dry_run ? 'DRY RUN: ' : ''
163
- i_attrs = all_project_issues_attrs(project)
26
+ client(dry_run: dry_run) # Initializes the client if needed
27
+ i_attrs = client.helper.all_project_issues_attrs(project)
164
28
  rep_sums = summaries_from_coverage_report(report)
165
29
  rep_sums.each do |k, v|
166
- next if summary_exist?(k, i_attrs)
30
+ next if client.helper.summary_exist?(k, i_attrs)
167
31
 
168
- parent = new_issue(client, project.attrs['key'], k.to_s, dry_run: dry_run)
169
- AbideDevUtils::Output.simple("#{dr_prefix}Created parent issue #{k}")
170
- parent_issue = issue(client, parent.attrs['key']) unless parent.respond_to?(:dummy)
32
+ AbideDevUtils::Output.simple("#{dr_prefix}Creating parent issue #{k}...")
33
+ parent = client.create(:issue, project: project, summary: k.to_s)
171
34
  AbideDevUtils::Output.simple("#{dr_prefix}Creating subtasks, this can take a while...")
172
35
  progress = AbideDevUtils::Output.progress(title: "#{dr_prefix}Creating Subtasks", total: nil)
173
36
  v.each do |s|
174
- next if summary_exist?(s, i_attrs)
37
+ next if client.helper.summary_exist?(s, i_attrs)
175
38
 
176
39
  progress.title = "#{dr_prefix}#{s}"
177
- new_subtask(client, parent_issue, s, dry_run: dry_run)
40
+ client.create(:subtask, parent: parent, summary: s)
178
41
  progress.increment
179
42
  end
180
43
  end
181
44
  end
182
45
 
183
- def self.new_issues_from_xccdf(client, project, xccdf_path, epic: nil, dry_run: false)
184
- i_attrs = all_project_issues_attrs(project)
46
+ def self.new_issues_from_xccdf(project, xccdf_path, epic: nil, dry_run: false, label_include: nil)
47
+ client(dry_run: dry_run) # Initializes the client if needed
48
+ i_attrs = client.helper.all_project_issues_attrs(project)
185
49
  xccdf = AbideDevUtils::XCCDF::Benchmark.new(xccdf_path)
186
50
  # We need to get the actual epic Issue object, or create it if it doesn't exist
187
51
  epic = if epic.nil?
188
52
  new_epic_summary = "#{COV_PARENT_SUMMARY_PREFIX}#{xccdf.title}"
189
- if summary_exist?(new_epic_summary, i_attrs)
190
- issue(client, new_epic_summary)
53
+ if client.helper.summary_exist?(new_epic_summary, i_attrs)
54
+ client.find(:issue, new_epic_summary)
191
55
  else
192
56
  unless AbideDevUtils::Prompt.yes_no("#{dr_prefix(dry_run)}Create new epic '#{new_epic_summary}'?")
193
57
  AbideDevUtils::Output.simple("#{dr_prefix(dry_run)}Aborting")
194
58
  exit(0)
195
59
  end
196
- new_epic(client, project.key, new_epic_summary, dry_run: dry_run)
60
+ client.create(:issue, project: project, summary: new_epic_summary, issuetype: 'Epic', epic_name: new_epic_summary)
197
61
  end
198
62
  else
199
- issue(client, epic)
63
+ client.find(:issue, epic)
200
64
  end
201
65
  # Now we need to find out which issues we need to create for the benchmark
202
66
  # The profiles that the control belongs to will be added as an issue label
203
67
  to_create = {}
204
68
  summaries_from_xccdf(xccdf).each do |profile_summary, control_summaries|
205
- control_summaries.reject { |s| summary_exist?(s, i_attrs) }.each do |control_summary|
69
+ control_summaries.reject { |s| client.helper.summary_exist?(s, i_attrs) }.each do |control_summary|
206
70
  if to_create.key?(control_summary)
207
71
  to_create[control_summary] << profile_summary.split.join('_').downcase
208
72
  else
@@ -211,6 +75,13 @@ module AbideDevUtils
211
75
  end
212
76
  end
213
77
 
78
+ # If we have a label_include, we need to filter out any controls that don't have that label
79
+ unless label_include.nil?
80
+ to_create = to_create.select do |_control_summary, labels|
81
+ labels.any? { |l| l.match?(label_include) }
82
+ end
83
+ end
84
+
214
85
  unless AbideDevUtils::Prompt.yes_no("#{dr_prefix(dry_run)}Create #{to_create.keys.count} new Jira issues?")
215
86
  AbideDevUtils::Output.simple("#{dr_prefix(dry_run)}Aborting")
216
87
  exit(0)
@@ -222,31 +93,32 @@ module AbideDevUtils
222
93
  to_create.each do |control_summary, labels|
223
94
  abrev = control_summary.length > 40 ? control_summary[0..60] : control_summary
224
95
  progress.log("#{dr_prefix(dry_run)}Creating #{abrev}...")
225
- new_issue(client, project.key, control_summary, labels: labels, epic: epic, dry_run: dry_run)
96
+ client.create(:issue, project: project, summary: control_summary, labels: labels, epic_link: epic)
226
97
  progress.increment
227
98
  end
228
99
  progress.finish
229
100
  AbideDevUtils::Output.simple("#{dr_prefix(dry_run)}Done creating tasks in Epic '#{epic.summary}'")
230
101
  end
231
102
 
232
- def self.new_issues_from_xccdf_diff(client, project, xccdf1_path, xccdf2_path, epic: nil, dry_run: false, auto_approve: false, diff_opts: {})
103
+ def self.new_issues_from_xccdf_diff(project, xccdf1_path, xccdf2_path, epic: nil, dry_run: false, auto_approve: false, diff_opts: {})
233
104
  require 'abide_dev_utils/xccdf/diff'
234
105
  diff = AbideDevUtils::XCCDF::Diff::BenchmarkDiff.new(xccdf1_path, xccdf2_path, diff_opts)
235
- i_attrs = all_project_issues_attrs(project)
106
+ client(dry_run: dry_run) # Initializes the client if needed
107
+ i_attrs = client.helper.all_project_issues_attrs(project)
236
108
  # We need to get the actual epic Issue object, or create it if it doesn't exist
237
109
  epic = if epic.nil?
238
- new_epic_summary = "#{UPD_EPIC_SUMMARY_PREFIX}#{diff.this.title}: v#{diff.this.version} -> #{diff.other.version}"
239
- if summary_exist?(new_epic_summary, i_attrs)
240
- issue(client, new_epic_summary)
110
+ new_epic_summary = "#{COV_PARENT_SUMMARY_PREFIX}#{xccdf.title}"
111
+ if client.helper.summary_exist?(new_epic_summary, i_attrs)
112
+ client.find(:issue, new_epic_summary)
241
113
  else
242
- unless AbideDevUtils::Prompt.yes_no("#{dr_prefix(dry_run)}Create new epic '#{new_epic_summary}'?", auto_approve: auto_approve)
114
+ unless AbideDevUtils::Prompt.yes_no("#{dr_prefix(dry_run)}Create new epic '#{new_epic_summary}'?")
243
115
  AbideDevUtils::Output.simple("#{dr_prefix(dry_run)}Aborting")
244
116
  exit(0)
245
117
  end
246
- new_epic(client, project.key, new_epic_summary, dry_run: dry_run)
118
+ client.create(:issue, project: project, summary: new_epic_summary, issuetype: 'Epic', epic_name: new_epic_summary)
247
119
  end
248
120
  else
249
- issue(client, epic)
121
+ client.find(:issue, epic)
250
122
  end
251
123
  to_create = {}
252
124
  diff.diff[:rules].each do |key, val|
@@ -288,7 +160,7 @@ module AbideDevUtils
288
160
  format: PROGRESS_BAR_FORMAT)
289
161
  approved_create.each do |summary, description|
290
162
  progress.log("#{dr_prefix(dry_run)}Creating #{summary}...")
291
- new_issue(client, project.key, summary, description: description, labels: [], epic: epic, dry_run: dry_run)
163
+ client.create(:issue, project: project, summary: summary, description: description, labels: [], epic_link: epic)
292
164
  progress.increment
293
165
  end
294
166
  progress.finish
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AbideDevUtils
4
- VERSION = "0.16.0"
4
+ VERSION = "0.17.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: abide_dev_utils
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.16.0
4
+ version: 0.17.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - abide-team
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-08-21 00:00:00.000000000 Z
11
+ date: 2023-11-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '6.23'
47
+ version: 7.0.0
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: '6.23'
54
+ version: 7.0.0
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: puppet-strings
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -322,16 +322,16 @@ dependencies:
322
322
  name: fast_gettext
323
323
  requirement: !ruby/object:Gem::Requirement
324
324
  requirements:
325
- - - "~>"
325
+ - - ">="
326
326
  - !ruby/object:Gem::Version
327
- version: '1.8'
327
+ version: '2.0'
328
328
  type: :development
329
329
  prerelease: false
330
330
  version_requirements: !ruby/object:Gem::Requirement
331
331
  requirements:
332
- - - "~>"
332
+ - - ">="
333
333
  - !ruby/object:Gem::Version
334
- version: '1.8'
334
+ version: '2.0'
335
335
  description: Provides a CLI with helpful utilities for developing compliance Puppet
336
336
  code
337
337
  email:
@@ -404,6 +404,12 @@ files:
404
404
  - lib/abide_dev_utils/files.rb
405
405
  - lib/abide_dev_utils/gcloud.rb
406
406
  - lib/abide_dev_utils/jira.rb
407
+ - lib/abide_dev_utils/jira/client.rb
408
+ - lib/abide_dev_utils/jira/client_builder.rb
409
+ - lib/abide_dev_utils/jira/dry_run.rb
410
+ - lib/abide_dev_utils/jira/finder.rb
411
+ - lib/abide_dev_utils/jira/helper.rb
412
+ - lib/abide_dev_utils/jira/issue_builder.rb
407
413
  - lib/abide_dev_utils/markdown.rb
408
414
  - lib/abide_dev_utils/mixins.rb
409
415
  - lib/abide_dev_utils/output.rb
@@ -448,7 +454,7 @@ metadata:
448
454
  homepage_uri: https://github.com/puppetlabs/abide_dev_utils
449
455
  source_code_uri: https://github.com/puppetlabs/abide_dev_utils
450
456
  changelog_uri: https://github.com/puppetlabs/abide_dev_utils
451
- post_install_message:
457
+ post_install_message:
452
458
  rdoc_options: []
453
459
  require_paths:
454
460
  - lib
@@ -463,8 +469,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
463
469
  - !ruby/object:Gem::Version
464
470
  version: '0'
465
471
  requirements: []
466
- rubygems_version: 3.1.6
467
- signing_key:
472
+ rubygems_version: 3.4.18
473
+ signing_key:
468
474
  specification_version: 4
469
475
  summary: Helper utilities for developing compliance Puppet code
470
476
  test_files: []