abide_dev_utils 0.17.0 → 0.17.2

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 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