1b1994897Sopenharmony_ci#!/usr/bin/env ruby 2b1994897Sopenharmony_ci# Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3b1994897Sopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License"); 4b1994897Sopenharmony_ci# you may not use this file except in compliance with the License. 5b1994897Sopenharmony_ci# You may obtain a copy of the License at 6b1994897Sopenharmony_ci# 7b1994897Sopenharmony_ci# http://www.apache.org/licenses/LICENSE-2.0 8b1994897Sopenharmony_ci# 9b1994897Sopenharmony_ci# Unless required by applicable law or agreed to in writing, software 10b1994897Sopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS, 11b1994897Sopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12b1994897Sopenharmony_ci# See the License for the specific language governing permissions and 13b1994897Sopenharmony_ci# limitations under the License. 14b1994897Sopenharmony_ci# frozen_string_literal: true 15b1994897Sopenharmony_ci 16b1994897Sopenharmony_ci# Huawei Technologies Co.,Ltd. 17b1994897Sopenharmony_cirequire 'optparse' 18b1994897Sopenharmony_cirequire 'yaml' 19b1994897Sopenharmony_cirequire 'json' 20b1994897Sopenharmony_cirequire 'ostruct' 21b1994897Sopenharmony_ci 22b1994897Sopenharmony_ciDir[File.join(__dir__, '..', 'lib', '*.rb')].each { |file| require file } # rubocop:disable Lint/NonDeterministicRequireOrder 23b1994897Sopenharmony_ci 24b1994897Sopenharmony_cidef check_file(file) 25b1994897Sopenharmony_ci raise OptionParser::InvalidOption, "File #{file} not found" unless File.exist? File.expand_path(file) 26b1994897Sopenharmony_ciend 27b1994897Sopenharmony_ci 28b1994897Sopenharmony_cidef check_files(arr) 29b1994897Sopenharmony_ci raise OptionParser::InvalidOption, 'No ISA spec files found' if arr.length.zero? 30b1994897Sopenharmony_ci 31b1994897Sopenharmony_ci arr.each do |f| 32b1994897Sopenharmony_ci check_file(f) 33b1994897Sopenharmony_ci end 34b1994897Sopenharmony_ciend 35b1994897Sopenharmony_ci 36b1994897Sopenharmony_cidef check_dir(dir) 37b1994897Sopenharmony_ci raise OptionParser::InvalidOption, "Directory #{dir} not found." unless File.directory? File.expand_path(dir) 38b1994897Sopenharmony_ciend 39b1994897Sopenharmony_ci 40b1994897Sopenharmony_cioptions = OpenStruct.new 41b1994897Sopenharmony_cioptparser = OptionParser.new do |opts| 42b1994897Sopenharmony_ci opts.banner = 'Usage: spectrac.rb [options]' 43b1994897Sopenharmony_ci opts.on('-r', '--report [FILE]', 'Output the test coverage summary report in yaml') 44b1994897Sopenharmony_ci opts.on('-d', '--testdir DIR', 'Directory with the test files (required)') 45b1994897Sopenharmony_ci opts.on('-g', '--testglob GLOB', 'Glob for finding test files in testdir (required)') 46b1994897Sopenharmony_ci opts.on('-s', '--spec FILE1,FILE2,FILE3', Array, 'ISA spec file(s) (at least one required)') 47b1994897Sopenharmony_ci opts.on('-n', '--non_testable [FILE]', 'Non testable assertions') 48b1994897Sopenharmony_ci opts.on('-u', '--uncovered [FILE]', 'Output yaml document with ISA spec areas not covered by tests') 49b1994897Sopenharmony_ci opts.on('-U', '--uncovered_md [FILE]', 'Output markdown document with ISA spec areas not covered by tests') 50b1994897Sopenharmony_ci opts.on('-o', '--orphaned [FILE]', 'Output yaml file with the list of tests not relevant to the spec') 51b1994897Sopenharmony_ci opts.on('-O', '--orphaned_md [FILE]', 'Output markdown file with the list of tests not relevant to the spec') 52b1994897Sopenharmony_ci opts.on('-f', '--full [FILE]', 'Output spec file with additional coverage-specific fields in yaml') 53b1994897Sopenharmony_ci opts.on('-F', '--full_md [FILE]', 'Output spec file with additional coverage-specific fields in markdown') 54b1994897Sopenharmony_ci opts.on('-h', '--help', 'Prints this help') do 55b1994897Sopenharmony_ci puts opts 56b1994897Sopenharmony_ci exit 57b1994897Sopenharmony_ci end 58b1994897Sopenharmony_ciend 59b1994897Sopenharmony_ci 60b1994897Sopenharmony_cibegin 61b1994897Sopenharmony_ci optparser.parse!(into: options) 62b1994897Sopenharmony_ci 63b1994897Sopenharmony_ci # check that required arguments aren't missing 64b1994897Sopenharmony_ci missing = %i[spec testdir testglob].select { |param| options[param].nil? } 65b1994897Sopenharmony_ci raise OptionParser::MissingArgument, missing.join(', ') unless missing.empty? 66b1994897Sopenharmony_ci 67b1994897Sopenharmony_ci # check that specified paths are valid 68b1994897Sopenharmony_ci check_files(options.spec) 69b1994897Sopenharmony_ci check_dir(options.testdir) 70b1994897Sopenharmony_ci check_file(options.non_testable) if options.non_testable 71b1994897Sopenharmony_cirescue OptionParser::InvalidOption, OptionParser::MissingArgument => e 72b1994897Sopenharmony_ci puts e 73b1994897Sopenharmony_ci puts optparser 74b1994897Sopenharmony_ci exit false 75b1994897Sopenharmony_ciend 76b1994897Sopenharmony_ci 77b1994897Sopenharmony_cispec = options.spec.map { |f| YAML.load_file(File.expand_path(f)) } 78b1994897Sopenharmony_ci 79b1994897Sopenharmony_cifullspec = Spec.new(spec) 80b1994897Sopenharmony_cifullspec.load_non_testable(YAML.load_file(File.expand_path(options.non_testable))) if options.non_testable 81b1994897Sopenharmony_cifullspec.load_tests(options.testdir, options.testglob) 82b1994897Sopenharmony_ci 83b1994897Sopenharmony_cisummary = Summary.new(fullspec) 84b1994897Sopenharmony_cisummary.compute 85b1994897Sopenharmony_ci 86b1994897Sopenharmony_ciFile.write(options.report, summary.report.to_yaml) if options.report 87b1994897Sopenharmony_ciFile.write(options.uncovered, summary.uncovered.to_yaml) if options.uncovered 88b1994897Sopenharmony_ciFile.write(options.full, fullspec.data.to_yaml) if options.full 89b1994897Sopenharmony_ciFile.write(options.orphaned, fullspec.orphaned.to_yaml) if options.orphaned 90b1994897Sopenharmony_ci 91b1994897Sopenharmony_ciReportMd.new(summary.report).generate 92b1994897Sopenharmony_ciUncoveredMd.new(summary.uncovered).generate(options.uncovered_md) if options.uncovered_md 93b1994897Sopenharmony_ciFullMd.new(fullspec.data).generate(options.full_md) if options.full_md 94b1994897Sopenharmony_ciOrphanedMd.new(fullspec.orphaned).generate(options.orphaned_md) if options.orphaned_md 95