Class: Inferno::CLI::RequirementsExporter

Inherits:
Object
  • Object
show all
Defined in:
lib/inferno/apps/cli/requirements_exporter.rb

Constant Summary collapse

INPUT_HEADERS =
[
  'ID*',
  'URL*',
  'Requirement*',
  'Conformance*',
  'Actor*',
  'Sub-Requirement(s)',
  'Conditionality',
  'Verifiable?',
  'Verifiability Details',
  'Planning To Test?',
  'Planning To Test Details'
].freeze
REQUIREMENTS_OUTPUT_HEADERS =
[
  'Req Set',
  'ID',
  'URL',
  'Requirement',
  'Conformance',
  'Actor',
  'Sub-Requirement(s)',
  'Conditionality',
  'Not Tested Reason',
  'Not Tested Details'
].freeze

Instance Method Summary collapse

Instance Method Details

#available_input_worksheetsObject



55
56
57
58
59
# File 'lib/inferno/apps/cli/requirements_exporter.rb', line 55

def available_input_worksheets
  @available_input_worksheets ||=
    Dir.glob(File.join(base_requirements_folder, '*.xlsx'))
      .reject { |f| f.include?('~$') }
end

#base_requirements_folderObject



43
44
45
# File 'lib/inferno/apps/cli/requirements_exporter.rb', line 43

def base_requirements_folder
  @base_requirements_folder ||= Dir.glob(File.join(Dir.pwd, 'lib', '*', 'requirements')).first
end

#check_presence_of_input_filesObject



181
182
183
184
185
186
187
# File 'lib/inferno/apps/cli/requirements_exporter.rb', line 181

def check_presence_of_input_files
  return if available_input_worksheets.present?

  puts 'Could not find any input files in directory ' \
       "#{base_requirements_folder}. Aborting requirements collection."
  exit(1)
end

#input_requirement_setsObject

Of the form: { requirement_set_id_1: [row1, row2, row 3, …], requirement_set_id_2: [row1, row2, row 3, …] }



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/inferno/apps/cli/requirements_exporter.rb', line 72

def input_requirement_sets
  requirement_set_hash = Hash.new { |hash, key| hash[key] = [] }
  available_input_worksheets.each_with_object(requirement_set_hash) do |worksheet_file, requirement_sets|
    worksheet = Roo::Spreadsheet.open(worksheet_file)
    set_identifier = requirement_set_id(worksheet)

    CSV.parse(
      worksheet.sheet('Requirements').to_csv,
      headers: true
    ).each do |row|
      row_hash = row.to_h.slice(*INPUT_HEADERS)
      row_hash['Sub-Requirement(s)']&.delete_prefix!('mailto:')

      requirement_sets[set_identifier] << row_hash
    end
  end
end

#local_test_kit_gemObject



35
36
37
# File 'lib/inferno/apps/cli/requirements_exporter.rb', line 35

def local_test_kit_gem
  @local_test_kit_gem ||= Bundler.definition.specs.find { |spec| spec.full_gem_path == Dir.pwd }
end

#new_requirements_csvObject

rubocop:disable Metrics/CyclomaticComplexity



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/inferno/apps/cli/requirements_exporter.rb', line 90

def new_requirements_csv # rubocop:disable Metrics/CyclomaticComplexity
  @new_requirements_csv ||=
    CSV.generate(+"\xEF\xBB\xBF") do |csv| # start with an unnecessary BOM to make viewing in excel easier
      csv << REQUIREMENTS_OUTPUT_HEADERS

      input_requirement_sets.each do |requirement_set_id, input_rows|
        input_rows.each do |row| # NOTE: use row order from source file
          csv << REQUIREMENTS_OUTPUT_HEADERS.map do |header|
            (
              case header
              when 'Req Set'
                requirement_set_id
              when 'Not Tested Reason'
                if spreadsheet_value_falsy?(row['Verifiable?'])
                  'Not Verifiable'
                elsif spreadsheet_value_falsy?(row['Planning To Test?'])
                  'Not Tested'
                end
              when 'Not Tested Details'
                if spreadsheet_value_falsy?(row['Verifiable?'])
                  row['Verifiability Details']
                elsif spreadsheet_value_falsy?(row['Planning To Test?'])
                  row['Planning To Test Details']
                end
              else
                row[header] || row["#{header}*"]
              end
            )&.strip
          end
        end
      end
    end
end

#old_requirements_csvObject



124
125
126
# File 'lib/inferno/apps/cli/requirements_exporter.rb', line 124

def old_requirements_csv
  @old_requirements_csv ||= File.read(requirements_output_file_path)
end

#requirement_set_id(worksheet) ⇒ Object



61
62
63
64
65
# File 'lib/inferno/apps/cli/requirements_exporter.rb', line 61

def requirement_set_id(worksheet)
  sheet = worksheet.sheet('Metadata')
  id_row = sheet.column(1).find_index('Id') + 1
  sheet.row(id_row)[1]
end

#requirements_output_file_nameObject



47
48
49
# File 'lib/inferno/apps/cli/requirements_exporter.rb', line 47

def requirements_output_file_name
  "#{test_kit_name}_requirements.csv"
end

#requirements_output_file_pathObject



51
52
53
# File 'lib/inferno/apps/cli/requirements_exporter.rb', line 51

def requirements_output_file_path
  File.join(base_requirements_folder, requirements_output_file_name).freeze
end

#runObject



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/inferno/apps/cli/requirements_exporter.rb', line 128

def run
  check_presence_of_input_files

  update_requirements =
    if File.exist?(requirements_output_file_path)
      if old_requirements_csv == new_requirements_csv
        puts "'#{requirements_output_file_name}' file is up to date."
        false
      else
        puts 'Requirements set has changed.'
        true
      end
    else
      puts "No existing #{requirements_output_file_name}."
      true
    end

  if update_requirements
    puts "Writing to file #{requirements_output_file_name}..."
    File.write(requirements_output_file_path, new_requirements_csv, encoding: Encoding::UTF_8)
  end

  puts 'Done.'
end

#run_checkObject



153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/inferno/apps/cli/requirements_exporter.rb', line 153

def run_check
  check_presence_of_input_files

  requirements_ok =
    if File.exist?(requirements_output_file_path)
      if old_requirements_csv == new_requirements_csv
        puts "'#{requirements_output_file_name}' file is up to date."
        true
      else
        puts "#{requirements_output_file_name} file is out of date."
        false
      end
    else
      puts "No existing #{requirements_output_file_name} file."
      false
    end

  return if requirements_ok

  puts <<~MESSAGE
    Check Failed. To resolve, run:

          bundle exec inferno requirements export_csv

  MESSAGE
  exit(1)
end

#spreadsheet_value_falsy?(string) ⇒ Boolean

Returns:

  • (Boolean)


189
190
191
# File 'lib/inferno/apps/cli/requirements_exporter.rb', line 189

def spreadsheet_value_falsy?(string)
  ['no', 'false'].include? string&.downcase
end

#test_kit_nameObject



39
40
41
# File 'lib/inferno/apps/cli/requirements_exporter.rb', line 39

def test_kit_name
  local_test_kit_gem.name
end