abide_dev_utils 0.14.2 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b6af74f2a0eea495b7bf71fd843c668f556ee83cf45e3b6ebfafe4242278dcee
4
- data.tar.gz: 6e9f6f60bc30f135bd4f2c6f35962626e81db410fc0c17631761c84e4551e1db
3
+ metadata.gz: a8f5dc40bfe8e447b1440435f020db1fb63decccaa405d52301251d9b5786af9
4
+ data.tar.gz: 414c7c96cfb731b65ff942cac68cf078ac2d7e4bac01da3a567f0ace10599243
5
5
  SHA512:
6
- metadata.gz: d61f39d043c94ab0ee2db46bd0374c99803fc720022606361f319e3b245c429700bffec7e9157ef11045cc7f5e25b21833b8bdc820ca1dcb32e7022ae7c89e3c
7
- data.tar.gz: c2463568c53de7d0e0dfa0e4950484db5df6965888d2cae2b145f4dfba2816105f41aa413da4c07c9642da33c2a6b264a5cfd6504874db1de0f6de0eeef51675
6
+ metadata.gz: bee0317d5e0c9b745537771c5c9425fb74d8c3a1a745dbaf2b694d9e258730608bf1616404efb59380a6178e51308385f1c4d6bb120fc9f35dd953432569c518
7
+ data.tar.gz: 47b08b70d6e148804606222ecd9a5d53740483f57c87613bead2fb8292d6f668a4a2507a046c5edb452a353d27ca6193d04f4736d347ac8c6f04291a1dbd61d0
data/Gemfile.lock CHANGED
@@ -1,8 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- abide_dev_utils (0.14.2)
5
- amatch (~> 0.4)
4
+ abide_dev_utils (0.15.0)
6
5
  cmdparse (~> 3.0)
7
6
  facterdb (>= 1.21)
8
7
  google-cloud-storage (~> 1.34)
@@ -18,16 +17,13 @@ GEM
18
17
  remote: https://rubygems.org/
19
18
  specs:
20
19
  CFPropertyList (2.3.6)
21
- activesupport (7.0.4.1)
20
+ activesupport (7.0.4.3)
22
21
  concurrent-ruby (~> 1.0, >= 1.0.2)
23
22
  i18n (>= 1.6, < 2)
24
23
  minitest (>= 5.1)
25
24
  tzinfo (~> 2.0)
26
25
  addressable (2.8.0)
27
26
  public_suffix (>= 2.0.2, < 5.0)
28
- amatch (0.4.1)
29
- mize
30
- tins (~> 1.0)
31
27
  ast (2.4.2)
32
28
  async (1.30.2)
33
29
  console (~> 1.10)
@@ -61,7 +57,7 @@ GEM
61
57
  diff-lcs (1.5.0)
62
58
  digest-crc (0.6.4)
63
59
  rake (>= 12.0.0, < 14.0.0)
64
- facter (4.3.0)
60
+ facter (4.4.1)
65
61
  hocon (~> 1.3)
66
62
  thor (>= 1.0.1, < 2.0)
67
63
  facterdb (1.21.0)
@@ -112,7 +108,7 @@ GEM
112
108
  google-cloud-core (~> 1.6)
113
109
  googleauth (>= 0.16.2, < 2.a)
114
110
  mini_mime (~> 1.0)
115
- googleauth (1.3.0)
111
+ googleauth (1.5.2)
116
112
  faraday (>= 0.17.3, < 3.a)
117
113
  jwt (>= 1.4, < 3.0)
118
114
  memoist (~> 0.16)
@@ -122,7 +118,7 @@ GEM
122
118
  hashdiff (1.0.1)
123
119
  hashie (5.0.0)
124
120
  hiera (3.12.0)
125
- hocon (1.3.1)
121
+ hocon (1.4.0)
126
122
  httpclient (2.8.3)
127
123
  i18n (1.12.0)
128
124
  concurrent-ruby (~> 1.0)
@@ -132,18 +128,16 @@ GEM
132
128
  atlassian-jwt
133
129
  multipart-post
134
130
  oauth (~> 0.5, >= 0.5.0)
135
- jwt (2.7.0)
131
+ jwt (2.7.1)
136
132
  locale (2.1.3)
137
133
  memoist (0.16.2)
138
134
  method_source (1.0.0)
139
135
  mini_mime (1.1.2)
140
- minitest (5.17.0)
141
- mize (0.4.1)
142
- protocol (~> 2.0)
136
+ minitest (5.18.0)
143
137
  multi_json (1.15.0)
144
138
  multipart-post (2.3.0)
145
139
  nio4r (2.5.8)
146
- nokogiri (1.14.2-x86_64-darwin)
140
+ nokogiri (1.15.2-x86_64-darwin)
147
141
  racc (~> 1.4)
148
142
  oauth (0.6.2)
149
143
  snaky_hash (~> 2.0)
@@ -155,8 +149,6 @@ GEM
155
149
  parallel (1.22.1)
156
150
  parser (3.1.2.0)
157
151
  ast (~> 2.4.1)
158
- protocol (2.0.0)
159
- ruby_parser (~> 3.0)
160
152
  protocol-hpack (1.4.2)
161
153
  protocol-http (0.22.6)
162
154
  protocol-http1 (0.14.4)
@@ -168,7 +160,7 @@ GEM
168
160
  coderay (~> 1.1)
169
161
  method_source (~> 1.0)
170
162
  public_suffix (4.0.7)
171
- puppet (7.23.0-universal-darwin)
163
+ puppet (7.24.0-universal-darwin)
172
164
  CFPropertyList (~> 2.2)
173
165
  concurrent-ruby (~> 1.0, < 1.2.0)
174
166
  deep_merge (~> 1.0)
@@ -182,9 +174,9 @@ GEM
182
174
  semantic_puppet (~> 1.0)
183
175
  puppet-resource_api (1.8.14)
184
176
  hocon (>= 1.0)
185
- puppet-strings (3.0.1)
186
- rgen (~> 0.9.0)
187
- yard (~> 0.9.5)
177
+ puppet-strings (4.0.0)
178
+ rgen (~> 0.9)
179
+ yard (~> 0.9)
188
180
  racc (1.6.2)
189
181
  rainbow (3.1.1)
190
182
  rake (13.0.6)
@@ -229,8 +221,6 @@ GEM
229
221
  rubocop (~> 1.19)
230
222
  ruby-progressbar (1.11.0)
231
223
  ruby2_keywords (0.0.5)
232
- ruby_parser (3.20.0)
233
- sexp_processor (~> 4.16)
234
224
  rubyzip (2.3.2)
235
225
  sawyer (0.9.2)
236
226
  addressable (>= 2.3.5)
@@ -240,8 +230,7 @@ GEM
240
230
  childprocess (>= 0.5, < 5.0)
241
231
  rexml (~> 3.2, >= 3.2.5)
242
232
  rubyzip (>= 1.2.2)
243
- semantic_puppet (1.0.4)
244
- sexp_processor (4.16.1)
233
+ semantic_puppet (1.1.0)
245
234
  signet (0.17.0)
246
235
  addressable (~> 2.8)
247
236
  faraday (>= 0.17.5, < 3.a)
@@ -250,24 +239,21 @@ GEM
250
239
  snaky_hash (2.0.1)
251
240
  hashie
252
241
  version_gem (~> 1.1, >= 1.1.1)
253
- sync (0.5.0)
254
- thor (1.2.1)
242
+ thor (1.2.2)
255
243
  timers (4.3.3)
256
- tins (1.32.1)
257
- sync
258
244
  traces (0.4.1)
259
245
  trailblazer-option (0.1.2)
260
- tzinfo (2.0.5)
246
+ tzinfo (2.0.6)
261
247
  concurrent-ruby (~> 1.0)
262
248
  uber (0.1.0)
263
249
  unicode-display_width (2.1.0)
264
- version_gem (1.1.1)
265
- webrick (1.7.0)
266
- yard (0.9.28)
267
- webrick (~> 1.7.0)
250
+ version_gem (1.1.2)
251
+ webrick (1.8.1)
252
+ yard (0.9.34)
268
253
 
269
254
  PLATFORMS
270
255
  x86_64-darwin-19
256
+ x86_64-darwin-20
271
257
  x86_64-linux
272
258
 
273
259
  DEPENDENCIES
@@ -41,7 +41,6 @@ Gem::Specification.new do |spec|
41
41
  spec.add_dependency 'selenium-webdriver', '~> 4.0.0.beta4'
42
42
  spec.add_dependency 'google-cloud-storage', '~> 1.34'
43
43
  spec.add_dependency 'hashdiff', '~> 1.0'
44
- spec.add_dependency 'amatch', '~> 0.4'
45
44
  spec.add_dependency 'facterdb', '>= 1.21'
46
45
 
47
46
  # Dev dependencies
@@ -4,7 +4,7 @@ require 'abide_dev_utils/cem'
4
4
  require 'abide_dev_utils/files'
5
5
  require 'abide_dev_utils/output'
6
6
  require 'abide_dev_utils/validate'
7
- require 'abide_dev_utils/xccdf/diff/benchmark'
7
+ require 'abide_dev_utils/xccdf/diff'
8
8
  require 'abide_dev_utils/cli/abstract'
9
9
 
10
10
  module Abide
@@ -162,13 +162,14 @@ module Abide
162
162
  end
163
163
 
164
164
  def execute(config_file, cur_xccdf, new_xccdf)
165
- AbideDevUtils::Validate.file(config_file, extension: 'yaml')
166
- AbideDevUtils::Validate.file(cur_xccdf, extension: 'xml')
167
- config_hiera = AbideDevUtils::Files::Reader.read(config_file, safe: true)
168
- diff = AbideDevUtils::XCCDF::Diff::BenchmarkDiff.new(cur_xccdf, new_xccdf).diff[:diff][:number_title]
169
- new_config_hiera, change_report = AbideDevUtils::CEM.update_legacy_config_from_diff(config_hiera, diff)
170
- AbideDevUtils::Output.yaml(new_config_hiera, console: @data[:verbose], file: @data[:out_file])
171
- AbideDevUtils::Output.simple(change_report) unless @data[:quiet]
165
+ warn 'This command is currently non-functional'
166
+ # AbideDevUtils::Validate.file(config_file, extension: 'yaml')
167
+ # AbideDevUtils::Validate.file(cur_xccdf, extension: 'xml')
168
+ # config_hiera = AbideDevUtils::Files::Reader.read(config_file, safe: true)
169
+ # diff = AbideDevUtils::XCCDF::Diff::BenchmarkDiff.new(cur_xccdf, new_xccdf).diff[:diff][:number_title]
170
+ # new_config_hiera, change_report = AbideDevUtils::CEM.update_legacy_config_from_diff(config_hiera, diff)
171
+ # AbideDevUtils::Output.yaml(new_config_hiera, console: @data[:verbose], file: @data[:out_file])
172
+ # AbideDevUtils::Output.simple(change_report) unless @data[:quiet]
172
173
  end
173
174
  end
174
175
 
@@ -23,6 +23,7 @@ module Abide
23
23
  add_command(JiraNewIssueCommand.new)
24
24
  add_command(JiraFromCoverageCommand.new)
25
25
  add_command(JiraFromXccdfCommand.new)
26
+ add_command(JiraFromXccdfDiffCommand.new)
26
27
  end
27
28
  end
28
29
 
@@ -46,7 +47,7 @@ module Abide
46
47
  end
47
48
 
48
49
  class JiraGetIssueCommand < CmdParse::Command
49
- CMD_NAME = 'get_issue'
50
+ CMD_NAME = 'get-issue'
50
51
  CMD_SHORT = 'Gets a specific issue'
51
52
  CMD_LONG = 'Returns JSON of a specific issue from key (<project>-<num>)'
52
53
  def initialize
@@ -67,7 +68,7 @@ module Abide
67
68
  end
68
69
 
69
70
  class JiraNewIssueCommand < CmdParse::Command
70
- CMD_NAME = 'new_issue'
71
+ CMD_NAME = 'new-issue'
71
72
  CMD_SHORT = 'Creates a new issue in a project'
72
73
  CMD_LONG = 'Allows you to create a new issue in a project'
73
74
  def initialize
@@ -93,7 +94,7 @@ module Abide
93
94
  end
94
95
 
95
96
  class JiraFromCoverageCommand < CmdParse::Command
96
- CMD_NAME = 'from_coverage'
97
+ CMD_NAME = 'from-coverage'
97
98
  CMD_SHORT = 'Creates a parent issue with subtasks from a coverage report'
98
99
  CMD_LONG = 'Creates a parent issue with subtasks for a benchmark and any uncovered controls'
99
100
  def initialize
@@ -116,7 +117,7 @@ module Abide
116
117
  end
117
118
 
118
119
  class JiraFromXccdfCommand < CmdParse::Command
119
- CMD_NAME = 'from_xccdf'
120
+ CMD_NAME = 'from-xccdf'
120
121
  CMD_SHORT = 'Creates a parent issue with subtasks from a xccdf file'
121
122
  CMD_LONG = 'Creates a parent issue with subtasks for a benchmark and any uncovered controls'
122
123
  def initialize
@@ -136,5 +137,48 @@ module Abide
136
137
  JIRA.new_issues_from_xccdf(client, proj, path, epic: @data[:epic], dry_run: @data[:dry_run])
137
138
  end
138
139
  end
140
+
141
+ class JiraFromXccdfDiffCommand < CmdParse::Command
142
+ CMD_NAME = 'from-xccdf-diff'
143
+ CMD_SHORT = 'Creates an Epic with tasks from a xccdf diff'
144
+ CMD_LONG = 'Creates an Epic with tasks for changes in a diff of two XCCDF files'
145
+ def initialize
146
+ super(CMD_NAME, takes_commands: false)
147
+ short_desc(CMD_SHORT)
148
+ long_desc(CMD_LONG)
149
+ argument_desc(PATH1: 'An XCCDF file', PATH2: 'An XCCDF file', PROJECT: 'A Jira project')
150
+ options.on('-d', '--dry-run', 'Print to console instead of saving objects') { |_| @data[:dry_run] = true }
151
+ options.on('-y', '--yes', 'Automatically approve all yes / no prompts') { |_| @data[:auto_approve] = true }
152
+ 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 }
153
+ options.on('-p [PROFILE]', '--profile', 'Only diff rules belonging to the matching profile. Takes a string that is treated as RegExp') do |x|
154
+ @data[:diff_opts] ||= {}
155
+ @data[:diff_opts][:profile] = x
156
+ end
157
+ options.on('-l [LEVEL]', '--level', 'Only diff rules belonging to the matching level. Takes a string that is treated as RegExp') do |x|
158
+ @data[:diff_opts] ||= {}
159
+ @data[:diff_opts][:level] = x
160
+ end
161
+ options.on('-i [PROPS]', '--ignore-changed-properties', 'Ignore changes to specified properties. Takes a comma-separated list.') do |x|
162
+ @data[:diff_opts] ||= {}
163
+ @data[:diff_opts][:ignore_changed_properties] = x.split(',')
164
+ end
165
+ end
166
+
167
+ def execute(path1, path2, project)
168
+ Abide::CLI::VALIDATE.file(path1)
169
+ 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])
181
+ end
182
+ end
139
183
  end
140
184
  end
@@ -104,27 +104,21 @@ module Abide
104
104
  super(CMD_NAME, CMD_SHORT, CMD_LONG, takes_commands: false)
105
105
  argument_desc(FILE1: CMD_FILE1_ARG, FILE2: CMD_FILE2_ARG)
106
106
  options.on('-o [PATH]', '--out-file', 'Save the report as a yaml file') { |x| @data[:outfile] = x }
107
- options.on('-p [PROFILE]', '--profile', 'Only diff and specific profile in the benchmarks') do |x|
107
+ options.on('-p [PROFILE]', '--profile', 'Only diff rules belonging to the matching profile. Takes a string that is treated as RegExp') do |x|
108
108
  @data[:profile] = x
109
109
  end
110
- options.on('-l [LEVEL]', '--level', 'Only diff the specific level in the benchmarks') do |x|
110
+ options.on('-l [LEVEL]', '--level', 'Only diff rules belonging to the matching level. Takes a string that is treated as RegExp') do |x|
111
111
  @data[:level] = x
112
112
  end
113
- options.on('-r', '--raw', 'Output the diff in raw hash format') { @data[:raw] = true }
113
+ options.on('-i [PROPS]', '--ignore-changed-properties', 'Ignore changes to specified properties. Takes a comma-separated list.') do |x|
114
+ @data[:ignore_changed_properties] = x.split(',')
115
+ end
116
+ options.on('-r', '--raw', 'Output the diff in raw format') { @data[:raw] = true }
114
117
  options.on('-q', '--quiet', 'Show no output in the terminal') { @data[:quiet] = false }
115
- options.on('--no-diff-profiles', 'Do not diff the profiles in the XCCDF files') { @data[:diff_profiles] = false }
116
- options.on('--no-diff-controls', 'Do not diff the controls in the XCCDF files') { @data[:diff_controls] = false }
117
- options.on('--old-style', 'Use old-style diffs') { @data[:old_style] = true }
118
118
  end
119
119
 
120
120
  def execute(file1, file2)
121
- diffreport = if @data[:old_style]
122
- AbideDevUtils::XCCDF.diff(file1, file2, @data)
123
- else
124
- dr = AbideDevUtils::XCCDF.new_style_diff(file1, file2, @data)
125
- dr[:diff][:number_title].map! { |d| d[:text] }
126
- dr
127
- end
121
+ diffreport = AbideDevUtils::XCCDF.diff(file1, file2, @data)
128
122
  AbideDevUtils::Output.yaml(diffreport, console: @data.fetch(:quiet, true), file: @data.fetch(:outfile, nil))
129
123
  end
130
124
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'yaml'
3
+ require_relative 'files'
4
4
 
5
5
  module AbideDevUtils
6
6
  module Config
@@ -9,15 +9,12 @@ module AbideDevUtils
9
9
  def self.to_h(path = DEFAULT_PATH)
10
10
  return {} unless File.file?(path)
11
11
 
12
- h = YAML.safe_load(File.open(path), [Symbol])
12
+ h = AbideDevUtils::Files::Reader.read(path)
13
13
  h.transform_keys(&:to_sym)
14
14
  end
15
15
 
16
16
  def to_h(path = DEFAULT_PATH)
17
- return {} unless File.file?(path)
18
-
19
- h = YAML.safe_load(File.open(path), [Symbol])
20
- h.transform_keys(&:to_sym)
17
+ self.class.to_h(path)
21
18
  end
22
19
 
23
20
  def self.config_section(section, path = DEFAULT_PATH)
@@ -12,12 +12,7 @@ module AbideDevUtils
12
12
  extension = File.extname(path)
13
13
  case extension
14
14
  when /\.yaml|\.yml/
15
- require 'yaml'
16
- if safe
17
- YAML.safe_load(File.read(path))
18
- else
19
- YAML.load_file(path)
20
- end
15
+ read_yaml(path, safe: safe, opts: opts)
21
16
  when '.json'
22
17
  require 'json'
23
18
  return JSON.parse(File.read(path), opts) if safe
@@ -34,6 +29,21 @@ module AbideDevUtils
34
29
  File.read(path)
35
30
  end
36
31
  end
32
+
33
+ def self.read_yaml(path, safe: true, opts: { permitted_classes: [Symbol] })
34
+ permitted_classes = opts[:permitted_classes] || [Symbol]
35
+ if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('3.0.0')
36
+ require 'psych'
37
+ return Psych.safe_load_file(path, permitted_classes: permitted_classes) if safe
38
+
39
+ Psych.load_file(path)
40
+ else
41
+ require 'yaml'
42
+ return YAML.safe_load(File.read(path), permitted_classes) if safe
43
+
44
+ YAML.load(File.read(path)) # rubocop:disable Security/YAMLLoad
45
+ end
46
+ end
37
47
  end
38
48
 
39
49
  class Writer
@@ -11,6 +11,7 @@ module AbideDevUtils
11
11
  ERRORS = AbideDevUtils::Errors::Jira
12
12
  COV_PARENT_SUMMARY_PREFIX = '::BENCHMARK:: '
13
13
  COV_CHILD_SUMMARY_PREFIX = '::CONTROL:: '
14
+ UPD_EPIC_SUMMARY_PREFIX = '::BENCHMARK UPDATE::'
14
15
  PROGRESS_BAR_FORMAT = '%a %e %P% Created: %c of %C'
15
16
 
16
17
  def self.project(client, project)
@@ -58,7 +59,7 @@ module AbideDevUtils
58
59
  iss.save
59
60
  end
60
61
 
61
- def self.new_issue(client, project, summary, labels: ['abide_dev_utils'], epic: nil, dry_run: false)
62
+ def self.new_issue(client, project, summary, description: nil, labels: ['abide_dev_utils'], epic: nil, dry_run: false)
62
63
  if dry_run
63
64
  sleep(0.2)
64
65
  return Dummy.new(summary)
@@ -69,6 +70,7 @@ module AbideDevUtils
69
70
  fields['reporter'] = myself(client)
70
71
  fields['issuetype'] = issuetype(client, 'Task')
71
72
  fields['priority'] = priority(client, '6')
73
+ fields['description'] = description if description
72
74
  fields['labels'] = labels
73
75
  epic = issue(client, epic) if epic && !epic.is_a?(JIRA::Resource::Issue)
74
76
  fields['customfield_10006'] = epic.key if epic # Epic_Link
@@ -227,6 +229,72 @@ module AbideDevUtils
227
229
  AbideDevUtils::Output.simple("#{dr_prefix(dry_run)}Done creating tasks in Epic '#{epic.summary}'")
228
230
  end
229
231
 
232
+ def self.new_issues_from_xccdf_diff(client, project, xccdf1_path, xccdf2_path, epic: nil, dry_run: false, auto_approve: false, diff_opts: {})
233
+ require 'abide_dev_utils/xccdf/diff'
234
+ diff = AbideDevUtils::XCCDF::Diff::BenchmarkDiff.new(xccdf1_path, xccdf2_path, diff_opts)
235
+ i_attrs = all_project_issues_attrs(project)
236
+ # We need to get the actual epic Issue object, or create it if it doesn't exist
237
+ 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)
241
+ else
242
+ unless AbideDevUtils::Prompt.yes_no("#{dr_prefix(dry_run)}Create new epic '#{new_epic_summary}'?", auto_approve: auto_approve)
243
+ AbideDevUtils::Output.simple("#{dr_prefix(dry_run)}Aborting")
244
+ exit(0)
245
+ end
246
+ new_epic(client, project.key, new_epic_summary, dry_run: dry_run)
247
+ end
248
+ else
249
+ issue(client, epic)
250
+ end
251
+ to_create = {}
252
+ diff.diff[:rules].each do |key, val|
253
+ next if val.empty?
254
+
255
+ val.each do |v|
256
+ case key
257
+ when :added
258
+ sum = "Add rule #{v[:number]} - #{v[:title]}"
259
+ sum = "#{sum[0..60]}..." if sum.length > 60
260
+ to_create[sum] = <<~DESC
261
+ Rule #{v[:number]} - #{v[:title]} is added with #{diff.other.title} #{diff.other.version}
262
+ DESC
263
+ when :removed
264
+ sum = "Remove rule #{v[:number]} - #{v[:title]}"
265
+ sum = "#{sum[0..60]}..." if sum.length > 60
266
+ to_create[sum] = <<~DESC
267
+ Rule #{v[:number]} - #{v[:title]} is removed from #{diff.this.title} #{diff.this.version}
268
+ DESC
269
+ else
270
+ sum = "Update rule \"#{v[:from]}\""
271
+ sum = "#{sum[0..60]}..." if sum.length > 60
272
+ to_create[sum] = <<~DESC
273
+ Rule #{v[:from]} is updated in #{diff.other.title} #{diff.other.version}:
274
+ #{v[:changes].collect { |k, v| "#{k}: #{v}" }.join("\n")}
275
+ DESC
276
+ end
277
+ end
278
+ end
279
+ approved_create = {}
280
+ to_create.each do |summary, description|
281
+ if AbideDevUtils::Prompt.yes_no("#{dr_prefix(dry_run)}Create new issue '#{summary}' with description:\n#{description}", auto_approve: auto_approve)
282
+ approved_create[summary] = description
283
+ end
284
+ end
285
+ AbideDevUtils::Output.simple("#{dr_prefix(dry_run)}Creating #{approved_create.keys.count} new Jira issues")
286
+ progress = AbideDevUtils::Output.progress(title: "#{dr_prefix(dry_run)}Creating issues",
287
+ total: approved_create.keys.count,
288
+ format: PROGRESS_BAR_FORMAT)
289
+ approved_create.each do |summary, description|
290
+ progress.log("#{dr_prefix(dry_run)}Creating #{summary}...")
291
+ new_issue(client, project.key, summary, description: description, labels: [], epic: epic, dry_run: dry_run)
292
+ progress.increment
293
+ end
294
+ progress.finish
295
+ AbideDevUtils::Output.simple("#{dr_prefix(dry_run)}Done creating tasks in Epic '#{epic.summary}'")
296
+ end
297
+
230
298
  def self.merge_options(options)
231
299
  config.merge(options)
232
300
  end
@@ -4,7 +4,9 @@ require 'io/console'
4
4
 
5
5
  module AbideDevUtils
6
6
  module Prompt
7
- def self.yes_no(msg)
7
+ def self.yes_no(msg, auto_approve: false)
8
+ return true if auto_approve
9
+
8
10
  print "#{msg} (Y/n): "
9
11
  return true if $stdin.cooked(&:gets).match?(/^[Yy].*/)
10
12
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module AbideDevUtils
4
- VERSION = "0.14.2"
4
+ VERSION = "0.15.0"
5
5
  end