abide_dev_utils 0.17.0 → 0.17.2

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: 0216511efe504da6597b81a7b494975377b8afe013697e37f9985467a6a4fa14
4
- data.tar.gz: '08265323331b31cb17e875b951ce89dfcb83bbb9649c0df97513cff26355f713'
3
+ metadata.gz: 69b32737c24844c999bd460d836d6eef7d87be94363c4b2ba277807042b646a5
4
+ data.tar.gz: a391723e49202b26efbf77b24e5ae65a4114889eb56c8c1428784d6da84be0b8
5
5
  SHA512:
6
- metadata.gz: 9cbd439058affe3311587d81d4dfe75191abe9f9fb1a1f8c964c2a8187f02cf9057943e4bacd5aaeb1676c936cccdd5e196b9d4a0822ed0c725d06fe0c46f0d3
7
- data.tar.gz: f01c66b8079d9d257de1158f4a1f9f529b2e9e31c8eb04a19fa21fee63f34b2fa018b8e3bba8eefce2bf90d20f23249e27a83126f54057232aef6bd7658cbe0a
6
+ metadata.gz: f30ad258bce39e8a9801440998ad6f4fd80caced6779f0836c288434539acb817e8d31e221cc143b2e5b431e193333d84f211cd47d18449a0d1d5abaa7be0811
7
+ data.tar.gz: adfeaa5dc2da9bb80f6da347115bf4f102387fd936763f0c7ac0a74e3c146b6d84e7a4c00b81bc32c6fad923871d86af8e609b8c346c2f18d7a57ad4a04ba019
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- abide_dev_utils (0.17.0)
4
+ abide_dev_utils (0.17.2)
5
5
  cmdparse (~> 3.0)
6
6
  facterdb (>= 1.21)
7
7
  google-cloud-storage (~> 1.34)
@@ -118,7 +118,12 @@ module Abide
118
118
  short_desc(CMD_SHORT)
119
119
  long_desc(CMD_LONG)
120
120
  argument_desc(PATH: 'An XCCDF file', PROJECT: 'A Jira project')
121
- options.on('-d', '--dry-run', 'Print to console instead of saving objects') { |_| @data[:dry_run] = true }
121
+ options.on('-d', '--dry-run', 'Runs through mock issue creation. Useful for testing, but not reliable for knowing what exactly will be created. Use --explain for more accurate information.') do
122
+ @data[:dry_run] = true
123
+ end
124
+ options.on('-x', '--explain', 'Shows a report of all the controls that will and won\'t be created as issues, and why. DOES NOT create issues.') do
125
+ @data[:explain] = true
126
+ end
122
127
  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
128
  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
129
  @data[:level] = x
@@ -136,12 +141,13 @@ module Abide
136
141
  @data[:label_include] = nil
137
142
  @data[:label_include] = "level_#{@data[:level]}_" if @data[:level]
138
143
  @data[:label_include] = "#{@data[:label_include]}#{@data[:profile]}" if @data[:profile]
139
- Abide::CLI::Output.simple "Label include: #{@data[:label_include]}"
144
+ Abide::CLI::OUTPUT.simple "Label include: #{@data[:label_include]}"
140
145
  AbideDevUtils::Jira.new_issues_from_xccdf(
141
146
  project,
142
147
  path,
143
148
  epic: @data[:epic],
144
149
  dry_run: @data[:dry_run],
150
+ explain: @data[:explain],
145
151
  label_include: @data[:label_include],
146
152
  )
147
153
  end
@@ -157,6 +163,11 @@ module Abide
157
163
  long_desc(CMD_LONG)
158
164
  argument_desc(PATH1: 'An XCCDF file', PATH2: 'An XCCDF file', PROJECT: 'A Jira project')
159
165
  options.on('-d', '--dry-run', 'Print to console instead of saving objects') { |_| @data[:dry_run] = true }
166
+ options.on('-z', '--print-only', 'Prints a list of issues that would be created. Implies dry-run, and auto-approve, but less verbose than --dry-run.') do
167
+ @data[:print_only] = true
168
+ @data[:dry_run] = true
169
+ @data[:auto_approve] = true
170
+ end
160
171
  options.on('-y', '--yes', 'Automatically approve all yes / no prompts') { |_| @data[:auto_approve] = true }
161
172
  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 }
162
173
  options.on('-p [PROFILE]', '--profile', 'Only diff rules belonging to the matching profile. Takes a string that is treated as RegExp') do |x|
@@ -182,8 +193,9 @@ module Abide
182
193
  path2,
183
194
  epic: @data[:epic],
184
195
  dry_run: @data[:dry_run],
196
+ print_only: @data[:print_only],
185
197
  auto_approve: @data[:auto_approve],
186
- diff_opts: @data[:diff_opts],
198
+ diff_opts: @data[:diff_opts] || {},
187
199
  )
188
200
  end
189
201
  end
@@ -47,6 +47,10 @@ module AbideDevUtils
47
47
  @helper ||= Helper.new(self, dry_run: @dry_run)
48
48
  end
49
49
 
50
+ def translate_issue_custom_field(name)
51
+ IssueBuilder::CUSTOM_FIELDS[name] || IssueBuilder::CUSTOM_FIELDS.invert[name]
52
+ end
53
+
50
54
  private
51
55
 
52
56
  def client
@@ -12,19 +12,20 @@ module AbideDevUtils
12
12
  if !!@dry_run
13
13
  case method_name
14
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(', ')})")
15
+ AbideDevUtils::Output.simple("DRY RUN: #{self.class.name}##{method_name}(#{args[0]}, #{kwargs.map { |k, v| "#{k}: #{v.inspect}" }.join(', ')})")
16
16
  sleep 0.1
17
17
  return DummyIssue.new if args[0].match?(%r{^issue$})
18
18
  return DummySubtask.new if args[0].match?(%r{^subtask$})
19
19
  when %r{^find}
20
- AbideDevUtils::Output.simple("DRY RUN: #{self.class.name}##{method_name}(#{args[0]}, #{args[1].inspect})")
20
+ AbideDevUtils::Output.simple("DRY RUN: #{self.class.name}##{method_name}(#{args[0]}, #{kwargs.inspect})")
21
21
  return DummyIssue.new if args[0].match?(%r{^issue$})
22
22
  return DummySubtask.new if args[0].match?(%r{^subtask$})
23
23
  return DummyProject.new if args[0].match?(%r{^project$})
24
+ return [] if args[0].match?(%r{^issues_by_jql$})
24
25
 
25
26
  "Dummy #{args[0].capitalize}"
26
27
  else
27
- AbideDevUtils::Output.simple("DRY RUN: #{self.class.name}##{method_name}(#{args.map(&:inspect).join(', ')})")
28
+ AbideDevUtils::Output.simple("DRY RUN: #{self.class.name}##{method_name}(#{args.map(&:inspect).join(', ')}, #{kwargs.map { |k, v| "#{k}: #{v.inspect}" }.join(', ')})")
28
29
  end
29
30
  else
30
31
  super(*args, **kwargs)
@@ -77,7 +78,7 @@ module AbideDevUtils
77
78
  class Dummy
78
79
  attr_reader :dummy
79
80
 
80
- def initialize
81
+ def initialize(*_args, **_kwargs)
81
82
  @dummy = true
82
83
  end
83
84
  end
@@ -85,10 +86,14 @@ module AbideDevUtils
85
86
  class DummyIssue < Dummy
86
87
  attr_reader :summary, :key
87
88
 
88
- def initialize
89
+ def initialize(summary = 'Dummy Issue', key = 'DUM-111')
89
90
  super
90
- @summary = 'Dummy Issue'
91
- @key = 'DUM-111'
91
+ @summary = summary
92
+ @key = key
93
+ end
94
+
95
+ def labels
96
+ @labels ||= ['abide_dev_utils']
92
97
  end
93
98
 
94
99
  def attrs
@@ -102,10 +107,8 @@ module AbideDevUtils
102
107
  end
103
108
 
104
109
  class DummySubtask < DummyIssue
105
- def initialize
106
- super
107
- @summary = 'Dummy Subtask'
108
- @key = 'DUM-222'
110
+ def initialize(summary = 'Dummy Subtask', key = 'DUM-222')
111
+ super(summary, key)
109
112
  end
110
113
 
111
114
  def attrs
@@ -122,7 +125,7 @@ module AbideDevUtils
122
125
  class DummyProject < Dummy
123
126
  attr_reader :key, :issues
124
127
 
125
- def initialize
128
+ def initialize(key = 'DUM', issues = [DummyIssue.new, DummySubtask.new])
126
129
  super
127
130
  @key = 'DUM'
128
131
  @issues = [DummyIssue.new, DummySubtask.new]
@@ -32,6 +32,12 @@ module AbideDevUtils
32
32
  iss
33
33
  end
34
34
 
35
+ # @param jql [String] The JQL query
36
+ # @return [Array<JIRA::Resource::Issue>]
37
+ def issues_by_jql(jql)
38
+ client.Issue.jql(jql, max_results: 1000)
39
+ end
40
+
35
41
  # @param id [String] The issuetype ID or name
36
42
  def issuetype(id)
37
43
  return id if id.is_a?(client.Issuetype.target_class)
@@ -43,7 +43,9 @@ module AbideDevUtils
43
43
  end
44
44
  end
45
45
 
46
- def self.new_issues_from_xccdf(project, xccdf_path, epic: nil, dry_run: false, label_include: nil)
46
+ ToCreateData = Struct.new(:summary, :labels, :should_create, :metadata)
47
+
48
+ def self.new_issues_from_xccdf(project, xccdf_path, epic: nil, dry_run: false, explain: false, label_include: nil)
47
49
  client(dry_run: dry_run) # Initializes the client if needed
48
50
  i_attrs = client.helper.all_project_issues_attrs(project)
49
51
  xccdf = AbideDevUtils::XCCDF::Benchmark.new(xccdf_path)
@@ -64,54 +66,124 @@ module AbideDevUtils
64
66
  end
65
67
  # Now we need to find out which issues we need to create for the benchmark
66
68
  # The profiles that the control belongs to will be added as an issue label
67
- to_create = {}
69
+ to_create = []
68
70
  summaries_from_xccdf(xccdf).each do |profile_summary, control_summaries|
69
- control_summaries.reject { |s| client.helper.summary_exist?(s, i_attrs) }.each do |control_summary|
70
- if to_create.key?(control_summary)
71
- to_create[control_summary] << profile_summary.split.join('_').downcase
71
+ control_summaries.each do |control_summary|
72
+ existing_to_create = to_create.find { |tc| tc.summary == control_summary }
73
+ if existing_to_create
74
+ existing_to_create.labels << profile_summary.split.join('_').downcase
72
75
  else
73
- to_create[control_summary] = [profile_summary.split.join('_').downcase]
76
+ new_to_create = ToCreateData.new(
77
+ summary: control_summary,
78
+ labels: [profile_summary.split.join('_').downcase],
79
+ should_create: true,
80
+ metadata: {
81
+ epic_key: epic.key,
82
+ project: project,
83
+ },
84
+ )
85
+ to_create << new_to_create
74
86
  end
75
87
  end
76
88
  end
77
89
 
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
90
+ final_to_create = filter_to_create(to_create, label_include, project, epic)
84
91
 
85
- unless AbideDevUtils::Prompt.yes_no("#{dr_prefix(dry_run)}Create #{to_create.keys.count} new Jira issues?")
92
+ return explain_this(to_create) if explain
93
+
94
+ unless AbideDevUtils::Prompt.yes_no("#{dr_prefix(dry_run)}Create #{final_to_create.count} new Jira issues?")
86
95
  AbideDevUtils::Output.simple("#{dr_prefix(dry_run)}Aborting")
87
96
  exit(0)
88
97
  end
89
98
 
90
99
  progress = AbideDevUtils::Output.progress(title: "#{dr_prefix(dry_run)}Creating issues",
91
- total: to_create.keys.count,
100
+ total: final_to_create.count,
92
101
  format: PROGRESS_BAR_FORMAT)
93
- to_create.each do |control_summary, labels|
94
- abrev = control_summary.length > 40 ? control_summary[0..60] : control_summary
102
+ final_to_create.each do |tc|
103
+ abrev = tc.summary.length > 40 ? tc.summary[0..60] : tc.summary
95
104
  progress.log("#{dr_prefix(dry_run)}Creating #{abrev}...")
96
- client.create(:issue, project: project, summary: control_summary, labels: labels, epic_link: epic)
105
+ client.create(:issue, project: project, summary: tc.summary, labels: tc.labels, epic_link: epic)
97
106
  progress.increment
98
107
  end
99
108
  progress.finish
100
109
  AbideDevUtils::Output.simple("#{dr_prefix(dry_run)}Done creating tasks in Epic '#{epic.summary}'")
101
110
  end
102
111
 
103
- def self.new_issues_from_xccdf_diff(project, xccdf1_path, xccdf2_path, epic: nil, dry_run: false, auto_approve: false, diff_opts: {})
112
+ def self.filter_to_create(to_create, label_include, project, epic)
113
+ not_already_exists = filter_already_exists(to_create, project, epic)
114
+ AbideDevUtils::Output.simple(
115
+ "Filtered out #{to_create.count - not_already_exists.count} issues that already existed",
116
+ )
117
+ only_label_include = filter_label_include(not_already_exists, label_include)
118
+ AbideDevUtils::Output.simple(
119
+ "Filtered out #{not_already_exists.count - only_label_include.count} issues that didn't include the label #{label_include}",
120
+ )
121
+ only_label_include
122
+ end
123
+
124
+ def self.filter_already_exists(to_create, project, epic)
125
+ AbideDevUtils::Output.simple('Checking if issues already exist...')
126
+ project = client.find(:project, project)
127
+ epic = client.find(:issue, epic)
128
+ issues = client.find(:issues_by_jql, "project = \"#{project.key}\" AND 'Epic Link' = \"#{epic.key}\"")
129
+ to_create.reject do |tc|
130
+ if issues.any? { |i| i.summary == tc.summary }
131
+ tc.metadata[:already_exists] = true
132
+ tc.should_create = false
133
+ true
134
+ else
135
+ tc.metadata[:already_exists] = false
136
+ false
137
+ end
138
+ end
139
+ end
140
+
141
+ # If we have a label_include, we need to filter out any controls that don't have that label
142
+ def self.filter_label_include(to_create, label_include)
143
+ return to_create if label_include.nil?
144
+
145
+ AbideDevUtils::Output.simple("Filtering out controls that don't match label include: #{label_include}")
146
+ to_create.select do |tc|
147
+ if tc.labels.any? { |l| l.match?(label_include) }
148
+ tc.metadata[:label_include] = true
149
+ true
150
+ else
151
+ tc.metadata[:label_include] = false
152
+ tc.should_create = false
153
+ false
154
+ end
155
+ end
156
+ end
157
+
158
+ def self.explain_this(to_create)
159
+ should_create = to_create.select(&:should_create)
160
+ should_not_create = to_create.reject(&:should_create)
161
+ AbideDevUtils::Output.simple(AbideDevUtils::Output.simple_section_separator('EXPLAIN'))
162
+ AbideDevUtils::Output.simple("Will create #{should_create.count} issues")
163
+ AbideDevUtils::Output.simple("Will not create #{should_not_create.count} issues")
164
+ AbideDevUtils::Output.simple(AbideDevUtils::Output.simple_section_separator('WILL CREATE'))
165
+ should_create.each do |tc|
166
+ AbideDevUtils::Output.simple("\"#{tc.summary}\"; labels: #{tc.labels}; metadata: #{tc.metadata}")
167
+ end
168
+ AbideDevUtils::Output.simple(AbideDevUtils::Output.simple_section_separator('WILL NOT CREATE'))
169
+ should_not_create.each do |tc|
170
+ AbideDevUtils::Output.simple("\"#{tc.summary}\"; labels: #{tc.labels}; metadata: #{tc.metadata}")
171
+ end
172
+ exit(0)
173
+ end
174
+
175
+ def self.new_issues_from_xccdf_diff(project, xccdf1_path, xccdf2_path, epic: nil, dry_run: false, print_only: false, auto_approve: false, diff_opts: {})
104
176
  require 'abide_dev_utils/xccdf/diff'
105
177
  diff = AbideDevUtils::XCCDF::Diff::BenchmarkDiff.new(xccdf1_path, xccdf2_path, diff_opts)
106
178
  client(dry_run: dry_run) # Initializes the client if needed
107
179
  i_attrs = client.helper.all_project_issues_attrs(project)
108
180
  # We need to get the actual epic Issue object, or create it if it doesn't exist
109
181
  epic = if epic.nil?
110
- new_epic_summary = "#{COV_PARENT_SUMMARY_PREFIX}#{xccdf.title}"
182
+ new_epic_summary = "#{COV_PARENT_SUMMARY_PREFIX}#{diff.this.title}: #{diff.this.version} -> #{diff.other.version}"
111
183
  if client.helper.summary_exist?(new_epic_summary, i_attrs)
112
184
  client.find(:issue, new_epic_summary)
113
185
  else
114
- unless AbideDevUtils::Prompt.yes_no("#{dr_prefix(dry_run)}Create new epic '#{new_epic_summary}'?")
186
+ unless AbideDevUtils::Prompt.yes_no("#{dr_prefix(dry_run)}Create new epic '#{new_epic_summary}'?", auto_approve: auto_approve)
115
187
  AbideDevUtils::Output.simple("#{dr_prefix(dry_run)}Aborting")
116
188
  exit(0)
117
189
  end
@@ -130,30 +202,57 @@ module AbideDevUtils
130
202
  sum = "Add rule #{v[:number]} - #{v[:title]}"
131
203
  sum = "#{sum[0..60]}..." if sum.length > 60
132
204
  to_create[sum] = <<~DESC
133
- Rule #{v[:number]} - #{v[:title]} is added with #{diff.other.title} #{diff.other.version}
205
+ Rule #{v[:number]} - #{v[:title]} is added
206
+
207
+ * From:
208
+ * Benchmark: #{diff.this.title} #{diff.this.version}
209
+ * To:
210
+ * Benchmark: #{diff.other.title} #{diff.other.version}
134
211
  DESC
135
212
  when :removed
136
213
  sum = "Remove rule #{v[:number]} - #{v[:title]}"
137
214
  sum = "#{sum[0..60]}..." if sum.length > 60
138
215
  to_create[sum] = <<~DESC
139
- Rule #{v[:number]} - #{v[:title]} is removed from #{diff.this.title} #{diff.this.version}
216
+ Remove rule #{v[:number]} - #{v[:title]}
217
+
218
+ * From:
219
+ * Benchmark: #{diff.this.title} #{diff.this.version}
220
+ * To:
221
+ * Benchmark: #{diff.other.title} #{diff.other.version}
140
222
  DESC
141
223
  else
142
- sum = "Update rule \"#{v[:from]}\""
224
+ sum = "Changed rule \"#{v[:from]}\""
143
225
  sum = "#{sum[0..60]}..." if sum.length > 60
144
226
  to_create[sum] = <<~DESC
145
- Rule #{v[:from]} is updated in #{diff.other.title} #{diff.other.version}:
146
- #{v[:changes].collect { |k, v| "#{k}: #{v}" }.join("\n")}
227
+ #{v[:changes].collect { |ck, cv| "Property \"#{ck}\" changed: \"#{cv.last}\" changed to \"#{cv.first}\"" }.join("\n ")}
228
+
229
+ * From:
230
+ * Rule: #{v[:from]}
231
+ * Benchmark: #{diff.this.title} #{diff.this.version}
232
+ * To:
233
+ * Rule: #{v[:to]}
234
+ * Benchmark: #{diff.other.title} #{diff.other.version}
147
235
  DESC
148
236
  end
149
237
  end
150
238
  end
151
239
  approved_create = {}
152
240
  to_create.each do |summary, description|
153
- if AbideDevUtils::Prompt.yes_no("#{dr_prefix(dry_run)}Create new issue '#{summary}' with description:\n#{description}", auto_approve: auto_approve)
241
+ section_header = "#{dr_prefix(dry_run)}NEW ISSUE"
242
+ prompt_msg = <<~PROMPT
243
+ #{AbideDevUtils::Output.simple_section_separator(section_header, width: 90)}
244
+ Title: '#{summary}'
245
+ Description:
246
+ #{description}
247
+ PROMPT
248
+ if print_only
249
+ AbideDevUtils::Output.simple(prompt_msg)
250
+ elsif AbideDevUtils::Prompt.yes_no("#{prompt_msg.strip}\nCreate?", auto_approve: auto_approve)
154
251
  approved_create[summary] = description
155
252
  end
156
253
  end
254
+ return if approved_create.empty?
255
+
157
256
  AbideDevUtils::Output.simple("#{dr_prefix(dry_run)}Creating #{approved_create.keys.count} new Jira issues")
158
257
  progress = AbideDevUtils::Output.progress(title: "#{dr_prefix(dry_run)}Creating issues",
159
258
  total: approved_create.keys.count,
@@ -10,6 +10,14 @@ require 'abide_dev_utils/files'
10
10
  module AbideDevUtils
11
11
  module Output
12
12
  FWRITER = AbideDevUtils::Files::Writer.new
13
+ def self.simple_section_separator(section_text, sepchar: '#', width: 60, **_)
14
+ section_text = section_text.to_s
15
+ section_text = section_text[0..width - 4] if section_text.length > width
16
+ section_text = " #{section_text} "
17
+ section_sep_line = sepchar * width
18
+ [section_sep_line, section_text.center(width, sepchar), section_sep_line].join("\n")
19
+ end
20
+
13
21
  def self.simple(msg, stream: $stdout, **_)
14
22
  case msg
15
23
  when Hash
@@ -19,6 +27,10 @@ module AbideDevUtils
19
27
  end
20
28
  end
21
29
 
30
+ def self.print(msg, stream: $stdout, **_)
31
+ stream.print msg
32
+ end
33
+
22
34
  def self.text(msg, console: false, file: nil, **_)
23
35
  simple(msg) if console
24
36
  FWRITER.write_text(msg, file: file) unless file.nil?
@@ -1,25 +1,30 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'io/console'
4
+ require_relative 'output'
4
5
 
5
6
  module AbideDevUtils
6
7
  module Prompt
7
- def self.yes_no(msg, auto_approve: false)
8
- return true if auto_approve
9
-
10
- print "#{msg} (Y/n): "
8
+ def self.yes_no(msg, auto_approve: false, stream: $stdout)
9
+ prompt_msg = "#{msg} (Y/n): "
10
+ if auto_approve
11
+ AbideDevUtils::Output.simple("#{prompt_msg}Y", stream: stream)
12
+ return true
13
+ end
14
+
15
+ AbideDevUtils::Output.print(prompt_msg, stream: stream)
11
16
  return true if $stdin.cooked(&:gets).match?(/^[Yy].*/)
12
17
 
13
18
  false
14
19
  end
15
20
 
16
- def self.single_line(msg)
17
- print "#{msg}: "
21
+ def self.single_line(msg, stream: $stdout)
22
+ AbideDevUtils::Output.print("#{msg}: ", stream: stream)
18
23
  $stdin.cooked(&:gets).chomp
19
24
  end
20
25
 
21
- def self.username
22
- print 'Username: '
26
+ def self.username(stream: $stdout)
27
+ AbideDevUtils::Output.print('Username: ', stream: stream)
23
28
  $stdin.cooked(&:gets).chomp
24
29
  end
25
30
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AbideDevUtils
4
- VERSION = "0.17.0"
4
+ VERSION = "0.17.2"
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.17.0
4
+ version: 0.17.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - abide-team
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-11-02 00:00:00.000000000 Z
11
+ date: 2023-11-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -469,7 +469,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
469
469
  - !ruby/object:Gem::Version
470
470
  version: '0'
471
471
  requirements: []
472
- rubygems_version: 3.4.18
472
+ rubygems_version: 3.4.22
473
473
  signing_key:
474
474
  specification_version: 4
475
475
  summary: Helper utilities for developing compliance Puppet code