# frozen_string_literal: true require 'bundler/gem_tasks' require 'rubocop/rake_task' require 'open3' require 'yaml' require 'rubocop' require 'rubocop-performance' require 'rubocop-rspec' require 'rubocop-rails' require 'rubocop-rake' RuboCop::RakeTask.new(:rubocop) do |t| config_path = File.expand_path(File.join('.rubocop.yml'), __dir__) t.options = ['--config', config_path] t.requires << 'rubocop-performance' t.requires << 'rubocop-rails' t.requires << 'rubocop-rspec' t.requires << 'rubocop-rake' end ARMITAGE_RUBOCOP_PATH = Pathname.new(__FILE__).join('../.rubocop.yml') NON_CHECKABLE_COPS = %w[Rails].freeze # NOTE: Global "Rails" cop has only `Enabled` option # rubocop:disable Rails/RakeEnvironment namespace :armitage_rubocop do desc 'Full armitage-rubocop build (code style, cops validation, yaml validation)' task :build do build_processes = { code_style_check: Open3.popen3('bundle exec rake rubocop'), cops_validation: Open3.popen3('bundle exec rake armitage_rubocop:validation:recognizable_cops'), yaml_validation: Open3.popen3('bundle exec rake armitage_rubocop:validation:valid_yamls') } # NOTE: results structure { type => exit_code } results = {}.tap do |result_data| build_processes.each_pair do |build_type, build_process| # NOTE: build_process => [stdin, stdout, stderr, wtr] build_result = build_process[3].value.exitstatus result_data[build_type] = build_result end end result_message = results.each_pair.map do |(result_type, result_status)| type = "- \e[1;33m#{result_type}\e[0m\t=> " desc = result_status.zero? ? "\e[32msuccess\e[0m" : "\e[31mfail\e[0m" "#{type} #{desc}" end.join("\n") if results.values.all?(&:zero?) puts "[\e[32mARMITAGE_RUBOCOP BUILD\e[0m] => \e[1;33mSuccessful!\e[0m\n#{result_message}" else abort "[\e[31mARMITAGE_RUBOCOP BUILD\e[0m] => FAILED!\n#{result_message}" end end namespace :validation do desc 'Checks that all *.yml files has the valid structure' task :valid_yamls do yamls = Dir[Pathname.new(__FILE__).join('../lib/**/*.yml')] # NOTE: try to load without Psych exceptions invalid_yamls = yamls.each_with_object([]) do |file_name, invalid_files| YAML.safe_load(File.read(file_name)) rescue (invalid_files << "- \e[33m#{file_name}\e[0m") end if invalid_yamls.empty? puts "[\e[32mYAML FILE VALIDATION\e[0m] => \e[1;33mall files has valid strucutre!\e[0m" else invalid_yamls_message = invalid_yamls.join("\n") abort "[\e[31mYAML FILE VALIDATION\e[0m] => some files has invalid structure:\n" \ "#{invalid_yamls_message}" end end desc 'Checks that all defined cops can be used' task :recognizable_cops do RuboCop::ConfigLoader.load_file(ARMITAGE_RUBOCOP_PATH) # TODO: validate each configured cop individually puts "[\e[32mCOP RECOGNITION CHECK\e[0m] => \e[1;33mall cops are recognizable!\e[0m" rescue abort "[\e[31mCOP RECOGNITION CHECK\e[0m] => some cops can not be fully recognized!\n" \ "Run rake validation:recognize_and_show to show which cops have incompatabilities." end desc 'Show rubocop\'s validation result output' task :recognize_and_show do RuboCop::ConfigLoader.load_file(ARMITAGE_RUBOCOP_PATH) rescue nil end end end # rubocop:enable Rails/RakeEnvironment task default: :rubocop