abide_dev_utils 0.17.0 → 0.17.1
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 +4 -4
- data/Gemfile.lock +1 -1
- data/lib/abide_dev_utils/cli/jira.rb +8 -2
- data/lib/abide_dev_utils/jira/client.rb +4 -0
- data/lib/abide_dev_utils/jira/dry_run.rb +15 -12
- data/lib/abide_dev_utils/jira/finder.rb +6 -0
- data/lib/abide_dev_utils/jira.rb +89 -17
- data/lib/abide_dev_utils/output.rb +8 -0
- data/lib/abide_dev_utils/version.rb +1 -1
- metadata +2 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: ba0491c8fbcaa0a69015c410a2aa7e61ac61e6b30caca6fb5b334d22fd77069c
         | 
| 4 | 
            +
              data.tar.gz: 119c837a5ea897957e63744ec3f38a7567222d7dbb5b952302ec71cd70aafc24
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 492066b562bee8dd3c3d3b465396a569d66a66200018bb74e606c8f3a78320853ecc71a8f30ee0c4f18194dbdc0d8679ff8c32fd38fbaf7936267eae1b35d5eb
         | 
| 7 | 
            +
              data.tar.gz: 2766d7c84c887b573cd9cb23f5d2aa869a4f238e5208ab2377832827e88d44056d180226a31c93ee242ed954d6aaf65b0e075d282b65ba53ea475ae1adb8e45a
         | 
    
        data/Gemfile.lock
    CHANGED
    
    
| @@ -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', ' | 
| 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:: | 
| 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
         | 
| @@ -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]}, #{ | 
| 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]}, #{ | 
| 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 =  | 
| 91 | 
            -
                      @key =  | 
| 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)
         | 
    
        data/lib/abide_dev_utils/jira.rb
    CHANGED
    
    | @@ -43,7 +43,9 @@ module AbideDevUtils | |
| 43 43 | 
             
                  end
         | 
| 44 44 | 
             
                end
         | 
| 45 45 |  | 
| 46 | 
            -
                 | 
| 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,42 +66,112 @@ 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. | 
| 70 | 
            -
                       | 
| 71 | 
            -
             | 
| 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 | 
            -
                         | 
| 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 | 
            -
                   | 
| 79 | 
            -
             | 
| 80 | 
            -
             | 
| 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)
         | 
| 91 | 
            +
             | 
| 92 | 
            +
                  return explain_this(to_create) if explain
         | 
| 84 93 |  | 
| 85 | 
            -
                  unless AbideDevUtils::Prompt.yes_no("#{dr_prefix(dry_run)}Create #{ | 
| 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:  | 
| 100 | 
            +
                                                            total: final_to_create.count,
         | 
| 92 101 | 
             
                                                            format: PROGRESS_BAR_FORMAT)
         | 
| 93 | 
            -
                   | 
| 94 | 
            -
                    abrev =  | 
| 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:  | 
| 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 |  | 
| 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 | 
            +
             | 
| 103 175 | 
             
                def self.new_issues_from_xccdf_diff(project, xccdf1_path, xccdf2_path, epic: nil, dry_run: 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)
         | 
| @@ -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
         | 
    
        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. | 
| 4 | 
            +
              version: 0.17.1
         | 
| 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- | 
| 11 | 
            +
            date: 2023-11-03 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: nokogiri
         |