require 'thor' require_relative 'api' require_relative 'configuration' require_relative 'test_report' require_relative 'reporters/verbose' require_relative 'reporters/simple' require_relative 'job_info' require_relative 'filters/failed' require_relative 'filters/flaky' module Korinthenkacker class CLI < Thor package_name 'korinthenkacker' desc 'jobs', 'Show all jobs' method_option :simple, aliases: '-s', type: :boolean, desc: 'simple output formatting' def jobs jobs = api.jobs['jobs'].map { |job| JobInfo.new(job) } reporter(options.simple).print_jobs_report(jobs) end desc 'builds JOBNAME', 'Display JOBNAME builds and their status' method_option :limit, aliases: '-l', type: :numeric method_option :simple, aliases: '-s', type: :boolean, desc: 'simple output formatting' def builds(jobname) reports = test_reports(jobname, options.limit) reporter(options.simple).print_builds_report(reports) end desc 'failed_scenarios JOBNAME [BUILD]', 'Display JOBNAME failing scenarios' method_option :limit, aliases: '-l', type: :numeric method_option :simple, aliases: '-s', type: :boolean, desc: 'simple output formatting' def failed_scenarios(jobname, build=nil) failed_cases = failed_cases_for(jobname, build) reporter(options.simple).print_scenario_reports(failed_cases) end desc 'flaky_scenarios JOBNAME', 'Display JOBNAME flaky scenarios' method_option :limit, aliases: '-l', type: :numeric method_option :simple, aliases: '-s', type: :boolean, desc: 'simple output formatting' def flaky_scenarios(jobname) failed_cases = failed_cases_for(jobname) flaky_cases = flaky_filter.filter(failed_cases) reporter(options.simple).print_scenario_reports(flaky_cases) end desc 'report [JOBS...]', 'Display failing scenario for jobs' method_option :limit, aliases: '-l', type: :numeric def report(*jobs) jobs.each do |job| puts job failed_scenarios(job, nil) end end desc 'verify [JOBS...]', 'exit with 0 if all recent jobs green, exit with 1 if any recent job red' def verify(*jobs) jobs.each do |job| reports = test_reports(job, 1) exit(1) if reports.empty? || !reports.first.success? end end private def failed_cases_for(jobname, build=nil) test_reports = build.nil? ? test_reports(jobname, options.limit) : [test_report(jobname, build)] failed_filter.filter(test_reports.map(&:cases).flatten) end def test_report(jobname, build) TestReport.new(jobname, build, api.test_report(jobname, build)) end def test_reports(jobname, limit=nil) job_info = JobInfo.new(api.job(jobname)) builds = limit ? job_info.build_numbers.first(limit) : job_info.build_numbers builds.map { |build| test_report(jobname, build) rescue nil }.compact # TODO: proper catching end def reporter(simple=false) @reporter ||= simple ? Reporters::Simple.new : Reporters::Verbose.new end def failed_filter @failed_filter ||= Filters::Failed.new end def flaky_filter @flaky_filter ||= Filters::Flaky.new end def api @api ||= API.new(Configuration.jenkins_url) end end end