class Nucop::Cli
Public Instance Methods
diff()
click to toggle source
# File lib/nucop/cli.rb, line 25 def diff puts "Running on files changed relative to '#{options[:"commit-spec"]}' (specify using the 'commit-spec' option)" diff_filter = options[:"added-only"] ? "A" : "d" diff_base = capture_std_out("git merge-base HEAD #{options[:"commit-spec"]}").chomp files, diff_status = Open3.capture2("git diff #{diff_base} --diff-filter=#{diff_filter} --name-only | grep \"\\.rb$\"") if diff_status != 0 if options[:exit] puts "There are no rb files present in diff. Exiting." exit 0 else puts "There are no rb files present in diff." return true end end if options[:ignore] && File.exist?(options[:diffignore_file]) && !File.zero?(options[:diffignore_file]) files, non_ignored_diff_status = Open3.capture2("grep -v -f #{options[:diffignore_file]}", stdin_data: files) if non_ignored_diff_status != 0 if options[:exit] puts "There are no non-ignored rb files present in diff. Exiting." exit 0 else puts "There are no non-ignored rb files present in diff." return true end end end no_violations_detected = invoke :rubocop, [multi_line_to_single_line(files)], options exit 1 unless no_violations_detected return true unless options[:exit] exit 0 end
diff_enforced()
click to toggle source
# File lib/nucop/cli.rb, line 14 def diff_enforced invoke :diff, nil, options.merge(only: cops_to_enforce.join(",")) end
modified_lines()
click to toggle source
# File lib/nucop/cli.rb, line 110 def modified_lines diff_files, diff_status = Open3.capture2("git diff #{options[:'commit-spec']} --diff-filter=d --name-only | grep \"\\.rb$\"") exit 1 unless diff_status.exitstatus.zero? command = [ "bundle exec rubocop", "--parallel", "--format Nucop::Formatters::GitDiffFormatter", "--config #{options[:rubocop_todo_config_file]}", multi_line_to_single_line(diff_files).to_s ].join(" ") # HACK: use ENVVAR to parameterize GitDiffFormatter system({ "RUBOCOP_COMMIT_SPEC" => options[:"commit-spec"] }, command) end
ready_for_promotion()
click to toggle source
# File lib/nucop/cli.rb, line 129 def ready_for_promotion finder = Helpers::NextCopForPromotion.new(options[:rubocop_todo_file]) todo_config = YAML.load_file(options[:rubocop_todo_file]) puts "The following cop(s) are ready to be promoted to enforced. Good luck!" puts "Remember to run `nucop:regen_backlog` to capture your hard work." puts finder.find(options["n"].to_i).each do |todo| puts "#{todo.name} with #{todo.offenses} offenses:" puts files = todo_config.fetch(todo.name, {}).fetch("Exclude", []) system("bundle exec rubocop --parallel --config #{options[:rubocop_todo_config_file]} --only #{todo.name} #{files.join(' ')}") puts("*" * 100) if options["n"] > 1 puts end end
regen_backlog()
click to toggle source
# File lib/nucop/cli.rb, line 98 def regen_backlog regenerate_rubocop_todos update_enforced_cops end
rubocop(files = nil)
click to toggle source
# File lib/nucop/cli.rb, line 67 def rubocop(files = nil) print_cops_being_run(options[:only]) config_file = options[:"exclude-backlog"] ? RUBOCOP_DEFAULT_CONFIG_FILE : options[:rubocop_todo_config_file] rubocop_requires = [ "--require rubocop-rspec", "--require rubocop-performance", "--require rubocop-rails" ] formatters = [] formatters << "--format Nucop::Formatters::JUnitFormatter --out #{options[:junit_report]}" if options[:junit_report] formatters << "--format json --out #{options[:json]}" if options[:json] formatters << "--format progress" if formatters.any? command = [ "bundle exec rubocop", "--parallel", rubocop_requires.join(" "), formatters.join(" "), "--force-exclusion", "--config", config_file, pass_through_option(options, "auto-correct"), pass_through_flag(options, "only"), files ].join(" ") system(command) end
update_enforced()
click to toggle source
# File lib/nucop/cli.rb, line 104 def update_enforced update_enforced_cops end
Private Instance Methods
capture_std_out(command, error_message = nil, stdin_data = nil)
click to toggle source
# File lib/nucop/cli.rb, line 164 def capture_std_out(command, error_message = nil, stdin_data = nil) std_out, std_error, status = Open3.capture3(command, stdin_data: stdin_data) print_errors_and_exit(std_error, error_message) unless status.success? std_out end
configuration_options()
click to toggle source
# File lib/nucop/cli.rb, line 268 def configuration_options if File.exist?(CONFIGURATION_FILEPATH) default_configuration.merge(YAML.load_file(CONFIGURATION_FILEPATH)) else default_configuration end end
cops_to_enforce()
click to toggle source
some cops cannot be used with the –only option and will raise an error this filters them out
# File lib/nucop/cli.rb, line 152 def cops_to_enforce cops = enforced_cops cops.delete("Lint/UnneededCopDisableDirective") cops end
cops_without_violations()
click to toggle source
# File lib/nucop/cli.rb, line 246 def cops_without_violations cops_with_violations = YAML.load_file(options[:rubocop_todo_file]).map(&:first) enabled_cops - cops_with_violations end
default_configuration()
click to toggle source
# File lib/nucop/cli.rb, line 276 def default_configuration { enforced_cops_file: ".rubocop.enforced.yml", rubocop_todo_file: ".rubocop_todo.yml", rubocop_todo_config_file: ".rubocop.backlog.yml", diffignore_file: ".nucop_diffignore" } end
enabled_cops()
click to toggle source
# File lib/nucop/cli.rb, line 252 def enabled_cops YAML.load(`bundle exec rubocop --parallel --show-cops`) # rubocop:disable Security/YAMLLoad .select { |_, config| config["Enabled"] } .map(&:first) end
enforced_cops()
click to toggle source
# File lib/nucop/cli.rb, line 160 def enforced_cops @_enforced_cops ||= YAML.load_file(options[:enforced_cops_file]) end
files_changed_since(commit_spec)
click to toggle source
# File lib/nucop/cli.rb, line 200 def files_changed_since(commit_spec) `git diff #{commit_spec} HEAD --name-only` .split("\n") .select { |e| e.end_with?(".rb") } end
multi_line_to_single_line(str)
click to toggle source
# File lib/nucop/cli.rb, line 187 def multi_line_to_single_line(str) str.split(/\n+/).join(" ") end
options()
click to toggle source
Override Thor's options method to include Nucop's options
Calls superclass method
# File lib/nucop/cli.rb, line 259 def options return @_options if defined?(@_options) original_options = super @_options = Thor::CoreExt::HashWithIndifferentAccess.new( configuration_options.merge(original_options) ) end
pass_through_flag(options, option)
click to toggle source
# File lib/nucop/cli.rb, line 191 def pass_through_flag(options, option) pass_through_option(options, option, true) end
pass_through_option(options, option, is_flag_option = false)
click to toggle source
# File lib/nucop/cli.rb, line 195 def pass_through_option(options, option, is_flag_option = false) return nil unless options[option] "--#{option} #{options[option] if is_flag_option}" end
print_cops_being_run(only_option)
click to toggle source
# File lib/nucop/cli.rb, line 178 def print_cops_being_run(only_option) if only_option enforced_cops_count = Helpers::CopCounter.count(enabled_cops, only_option.split(",")) puts "Running with a force of #{enforced_cops_count} cops. See '#{options[:enforced_cops_file]}' for more details." else puts "Running all cops (specify using the 'only' option)" end end
print_errors_and_exit(std_error, message = "An error has occurred")
click to toggle source
# File lib/nucop/cli.rb, line 171 def print_errors_and_exit(std_error, message = "An error has occurred") warn message puts std_error puts "Exiting" exit 1 end
regenerate_rubocop_todos()
click to toggle source
# File lib/nucop/cli.rb, line 206 def regenerate_rubocop_todos puts "Regenerating '#{options[:rubocop_todo_file]}'. Please be patient..." rubocop_options = [ "--auto-gen-config", "--config #{options[:rubocop_todo_config_file]}", "--exclude-limit #{options[:'exclude-limit']}", "--require rubocop-rspec", "--require rubocop-performance", "--require rubocop-rails" ] rubocop_command = "DISABLE_SPRING=1 bundle exec rubocop #{rubocop_options.join(' ')}" system(rubocop_command) # RuboCop wants to inherit from our todos (options[:rubocop_todo_file]) in our backlog configuration file (options[:rubocop_todo_config_file]) # However, that means the next time we try to update our backlog, it will NOT include the violations recorded as todo # For now, we ignore any changes in our backlog config system("git checkout #{options[:rubocop_todo_config_file]}") end
update_enforced_cops()
click to toggle source
# File lib/nucop/cli.rb, line 228 def update_enforced_cops puts "Updating enforced cops list..." current_enforced_cops = Helpers::CopSet.new(enforced_cops) cops_without_violations.each do |cop| current_enforced_cops.add_cop(cop) end if current_enforced_cops.cop_added? File.open(options[:enforced_cops_file], "w+") do |f| f.write(current_enforced_cops.to_a.sort.to_yaml) end puts "Updated '#{options[:enforced_cops_file]}'!" else puts "No new cops are clear of violations" end end