diff --git a/lib/strong_ruby/runner.rb b/lib/strong_ruby/runner.rb index 10dd83e..afd4a93 100644 --- a/lib/strong_ruby/runner.rb +++ b/lib/strong_ruby/runner.rb @@ -1,7 +1,120 @@ +require 'optparse' +require 'find' + +require 'strong_ruby/version' + module StrongRuby # Parent class for runner tools. class Runner def self.run(options) + new.execute(options) + end + + attr_reader :errors, :warnings, :aborting + + def initialize + @option_parser = OptionParser.new { |opts| setup_option_parsing(opts) } + @files = [] + @errors = [] + @warnings = [] + @list_files = false + @aborting = false + end + + def execute(options) + parse_options(options) + prepare_checker + + process_files + end + + private + + def runner_name + raise NotImplementedError, "implement #{self.class}##{__callee__}" + end + + # rubocop:disable MethodLength + def setup_option_parsing(opts) + opts.banner = "Usage: #{runner_name} [options] FILE|DIRECTORY..." + + opts.on_tail '-h', '--help', 'Display this help message and exit' do + puts opts.help + puts <<-HELP + + If you specify a DIRECTORY, then all *.srb files are fetched + from it recursively and appended to the file list. + HELP + exit + end + + opts.on_tail '-V', '--version', 'Output version information and exit' do + puts "#{runner_name} #{VERSION}" + exit + end + + opts.on_tail '-L', '--list-files', 'List target files' do + @list_files = true + end + end + + def parse_options(options) + @option_parser.parse!(options) + + # The rest of the method performs file retrieval. TODO RuboCop-ify. + options << Dir.pwd if options.empty? + + options.each do |file_or_dir| + if File.directory?(file_or_dir) + Find.find(file_or_dir) do |path| + @files << path if path.end_with? '.srb' + end + else + @files << file_or_dir + end + end + + return unless @files.empty? + + $stderr.puts 'No StrongRuby files found' + exit 1 + end + # rubocop:enable MethodLength + + def prepare_checker + # TODO + end + + def process_files + if @list_files + list_files(@files) + else + inspect_files(@files) + end + end + + def list_files(paths) + paths.each do |path| + # NOTE Inlined from Rubocop::PathUtil.relative_path + base_dir = Dir.pwd + if path.start_with?(base_dir) + path_name = path[(base_dir.length + 1)..-1] + else + path_name = Pathname.new(File.expand_path(path)) + path_name.relative_path_from(Pathname.new(base_dir)).to_s + end + puts path_name + end + end + + def inspect_files(paths) + paths.each do |_path| + # TODO + end + end + + def process(_buffer) + raise NotImplementedError, "implement #{self.class}##{__callee__}" end end end diff --git a/lib/strong_ruby/runner/strong_ruby.rb b/lib/strong_ruby/runner/strong_ruby.rb index 7eaba43..66f1159 100644 --- a/lib/strong_ruby/runner/strong_ruby.rb +++ b/lib/strong_ruby/runner/strong_ruby.rb @@ -1,6 +1,24 @@ require 'strong_ruby/runner' module StrongRuby + # StrongRuby gradual typechecker. class Runner::StrongRuby < StrongRuby::Runner + def initialize + super + end + + private + + def runner_name + 'strongruby' + end + + def setup_option_parsing(opts) + super + end + + def process(buffer) + # TODO + end end end diff --git a/lib/strong_ruby/runner/strong_ruby_c.rb b/lib/strong_ruby/runner/strong_ruby_c.rb index 3e889cf..7814c10 100644 --- a/lib/strong_ruby/runner/strong_ruby_c.rb +++ b/lib/strong_ruby/runner/strong_ruby_c.rb @@ -1,6 +1,24 @@ require 'strong_ruby/runner' module StrongRuby + # StrongRuby to Ruby transpiler. class Runner::StrongRubyC < StrongRuby::Runner + def initialize + super + end + + private + + def runner_name + 'strongrubyc' + end + + def setup_option_parsing(opts) + super + end + + def process(buffer) + # TODO + end end end diff --git a/strongruby.gemspec b/strongruby.gemspec index dd7f424..5d9587a 100644 --- a/strongruby.gemspec +++ b/strongruby.gemspec @@ -16,4 +16,6 @@ Gem::Specification.new do |spec| spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.test_files = spec.files.grep(%r{^test/}) spec.require_paths = ['lib'] + + spec.add_runtime_dependency 'rubocop', '~> 0.40' end