class RubyCrystalCodemod::Command
Constants
- CODE_CHANGE
- CODE_ERROR
- CODE_OK
Attributes
logger[R]
Public Class Methods
new(want_check, exit_code, filename_for_dot_ruby_crystal_codemod, loglevel)
click to toggle source
# File lib/ruby_crystal_codemod/command.rb, line 16 def initialize(want_check, exit_code, filename_for_dot_ruby_crystal_codemod, loglevel) @want_check = want_check @exit_code = exit_code @filename_for_dot_ruby_crystal_codemod = filename_for_dot_ruby_crystal_codemod @dot_file = RubyCrystalCodemod::DotFile.new @squiggly_warning_files = [] @logger = RubyCrystalCodemod::Logger.new(loglevel) @post_processor = PostProcessCrystal.new end
parse_options(argv)
click to toggle source
# File lib/ruby_crystal_codemod/command.rb, line 170 def self.parse_options(argv) exit_code, want_check = true, false filename_for_dot_ruby_crystal_codemod = nil loglevel = :log OptionParser.new do |opts| opts.version = RubyCrystalCodemod::VERSION opts.banner = "Usage: ruby_crystal_codemod files or dirs [options]" opts.on("-c", "--check", "Only check formating changes") do want_check = true end opts.on("--filename=value", "Filename to use to lookup .ruby_crystal_codemod (useful for STDIN formatting)") do |value| filename_for_dot_ruby_crystal_codemod = value end opts.on("-x", "--simple-exit", "Return 1 in the case of failure, else 0") do exit_code = false end opts.on(RubyCrystalCodemod::Logger::LEVELS, "--loglevel[=LEVEL]", "Change the level of logging for the CLI. Options are: error, warn, log (default), debug, silent") do |value| loglevel = value.to_sym end opts.on("-h", "--help", "Show this help") do puts opts exit end end.parse!(argv) [want_check, exit_code, filename_for_dot_ruby_crystal_codemod, loglevel] end
run(argv)
click to toggle source
# File lib/ruby_crystal_codemod/command.rb, line 11 def self.run(argv) want_check, exit_code, filename_for_dot_ruby_crystal_codemod, loglevel = parse_options(argv) new(want_check, exit_code, filename_for_dot_ruby_crystal_codemod, loglevel).run(argv) end
Public Instance Methods
exit_code(status_code)
click to toggle source
# File lib/ruby_crystal_codemod/command.rb, line 26 def exit_code(status_code) if @exit_code status_code else case status_code when CODE_OK, CODE_CHANGE 0 else 1 end end end
format(code, filename, dir)
click to toggle source
# File lib/ruby_crystal_codemod/command.rb, line 157 def format(code, filename, dir) @squiggly_warning = false formatter = RubyCrystalCodemod::Formatter.new(code, filename, dir) options = @dot_file.get_config_in(dir) unless options.nil? formatter.init_settings(options) end formatter.format result = formatter.result result end
format_args(args)
click to toggle source
# File lib/ruby_crystal_codemod/command.rb, line 65 def format_args(args) file_finder = RubyCrystalCodemod::FileFinder.new(args) files = file_finder.to_a changed = false syntax_error = false files_exist = false files.each do |(exists, file)| if exists files_exist = true else logger.warn("Error: file or directory not found: #{file}") next end result = format_file(file) changed |= result == CODE_CHANGE syntax_error |= result == CODE_ERROR end return CODE_ERROR unless files_exist case when syntax_error then CODE_ERROR when changed then CODE_CHANGE else CODE_OK end end
format_file(filename)
click to toggle source
# File lib/ruby_crystal_codemod/command.rb, line 95 def format_file(filename) logger.debug("Formatting: #{filename}") code = File.read(filename) begin result = format(code, filename, @filename_for_dot_ruby_crystal_codemod || File.dirname(filename)) rescue RubyCrystalCodemod::SyntaxError # We ignore syntax errors as these might be template files # with .rb extension logger.warn("Error: #{filename} has syntax errors") return CODE_ERROR end # if code.force_encoding(result.encoding) != result if @want_check logger.warn("Formatting #{filename} produced changes") else crystal_filename = filename.sub(/\.rb$/, ".cr") File.write(crystal_filename, result) logger.log("Format: #{filename} => #{crystal_filename}") end # Run the post-processing step to remove Ruby code and uncomment Crystal. @post_processor.filename = crystal_filename @post_processor.post_process_crystal File.write(crystal_filename, @post_processor.contents) # UPDATE: It's difficult to package/compile the Crystal binary in a Ruby gem. # But it was really easy to port it to Ruby! # post_process_cmd = File.expand_path(File.join(__dir__, "../../util/post_process")) # unless File.exist?(post_process_cmd) # raise "Please run ./bin/compile_post_process to compile the post-processing command " \ # "at: #{post_process_cmd}" # end # stdout, stderr, status = Open3.capture3(post_process_cmd, crystal_filename) # unless status.success? # warn "'./util/post_process' failed with status: #{status.exitstatus}\n\n" \ # "stdout: #{stdout}\n\n" \ # "stderr: #{stderr}" # end # Format the Crystal file with the Crystal code formatter stdout, stderr, status = Open3.capture3("crystal", "tool", "format", crystal_filename) unless status.success? warn "'crystal tool format' failed with status: #{status.exitstatus}\n\n" \ "stdout: #{stdout}\n\n" \ "stderr: #{stderr}" puts "(This probably means that you will have to fix some errors manually.)" end return CODE_CHANGE # end rescue RubyCrystalCodemod::SyntaxError logger.error("Error: the given text in #{filename} is not a valid ruby program (it has syntax errors)") CODE_ERROR rescue => e logger.error("You've found a bug!") logger.error("It happened while trying to format the file #{filename}") logger.error("Please report it to https://github.com/DocSpring/ruby_crystal_codemod/issues with code that triggers it\n") raise e end
format_stdin()
click to toggle source
# File lib/ruby_crystal_codemod/command.rb, line 48 def format_stdin code = STDIN.read result = format(code, nil, @filename_for_dot_ruby_crystal_codemod || Dir.getwd) print(result) if !@want_check code == result ? CODE_OK : CODE_CHANGE rescue RubyCrystalCodemod::SyntaxError logger.error("Error: the given text is not a valid ruby program (it has syntax errors)") CODE_ERROR rescue => e logger.error("You've found a bug!") logger.error("Please report it to https://github.com/DocSpring/ruby_crystal_codemod/issues with code that triggers it\n") raise e end
run(argv)
click to toggle source
# File lib/ruby_crystal_codemod/command.rb, line 39 def run(argv) status_code = if argv.empty? format_stdin else format_args argv end exit exit_code(status_code) end