# frozen_string_literal: false require 'optparse' require 'fileutils' require 'rbconfig' require_relative '../jruby_art/config' require_relative '../jruby_art/version' require_relative '../jruby_art/java_opts' # processing wrapper module module Processing # Utility class to handle the different commands that the 'k9' command # offers. Able to run, watch, live, create, app, and unpack class Runner WIN_PATTERNS = [ /bccwin/i, /cygwin/i, /djgpp/i, /ming/i, /mswin/i, /wince/i ].freeze attr_reader :options, :argc, :filename, :os def initialize @options = {} end # Start running a jruby_art filename from the passed-in arguments def self.execute runner = new runner.parse_options(ARGV) runner.execute! end # Dispatch central. def execute! show_help if options.empty? show_version if options[:version] run_sketch if options[:run] watch_sketch if options[:watch] live if options[:live] create if options[:create] check if options[:check] install if options[:install] end # Parse the command-line options. def parse_options(args) opt_parser = OptionParser.new do |opts| # Set a banner, displayed at the top # of the help screen. opts.banner = 'Usage: k9 [options] [<filename.rb>]' # Define the options, and what they do options[:version] = false opts.on('-v', '--version', 'JRubyArt Version') do options[:version] = true end options[:install] = false opts.on('-i', '--install', 'Installs jruby-complete and examples') do options[:install] = true end options[:check] = false opts.on('-?', '--check', 'Prints configuration') do options[:check] = true end options[:app] = false opts.on('-a', '--app', 'Export as app NOT IMPLEMENTED YET') do options[:export] = true end options[:watch] = false opts.on('-w', '--watch', 'Watch/run the sketch') do options[:watch] = true end options[:run] = false opts.on('-r', '--run', 'Run the sketch') do options[:run] = true end options[:live] = false opts.on('-l', '--live', 'As above, with pry console bound to $app') do options[:live] = true end options[:create] = false opts.on('-c', '--create', 'Create new outline sketch') do options[:create] = true end # This displays the help screen, all programs are # assumed to have this option. opts.on('-h', '--help', 'Display this screen') do puts opts exit end end @argc = opt_parser.parse(args) @filename = argc.shift end def create require_relative '../jruby_art/creators/sketch_writer' config = Processing::RP_CONFIG.fetch('template', 'bare') SketchWriter.new(filename, argc).create!(config) end # Export as app not implemented def export ensure_exists(filename) puts 'Not implemented yet' end # Just simply run a JRubyArt filename. def run_sketch ensure_exists(filename) spin_up('run.rb', filename, argc) end # Just simply run a JRubyArt filename. def live ensure_exists(filename) spin_up('live.rb', filename, argc) end # Run a filename, keeping an eye on it's file, and reloading # whenever it changes. def watch_sketch ensure_exists(filename) spin_up('watch.rb', filename, argc) end def install require_relative '../jruby_art/installer' JRubyComplete.new(K9_ROOT, host_os).install UnpackSamples.new(K9_ROOT, host_os).install end def check require_relative '../jruby_art/installer' Check.new(K9_ROOT, host_os).install end # Show the standard help/usage message. def show_help puts HELP_MESSAGE end def show_version puts format('JRubyArt version %s', JRubyArt::VERSION) end private # Trade in this Ruby instance for a JRuby instance, loading in a starter # script and passing it some arguments. Unless you set JRUBY: false in # ~/.jruby_art/config.yml, an installed version of jruby is used instead # of our vendored one. Note the use of jruby-complete might make using # other gems in your sketches hard (but not impossible).... def spin_up(starter_script, filename, argc) runner = "#{K9_ROOT}/lib/jruby_art/runners/#{starter_script}" if Processing::RP_CONFIG.fetch('JRUBY', true) opts = JRubyOpts.new(SKETCH_ROOT).opts command = ['jruby', opts, runner, filename, argc].flatten else opts = JavaOpts.new(SKETCH_ROOT).opts command = ['java', opts, '-cp', jruby_complete, 'org.jruby.Main', runner, filename, argc].flatten end begin exec(*command) # exec replaces the Ruby process with the JRuby one. rescue Java::JavaLang::ClassNotFoundException end end # NB: We really do mean to use 'and' not '&&' for flow control purposes def ensure_exists(filename) puts "Couldn't find: #{filename}" and exit unless FileTest.exist?(filename) end def jruby_complete rcomplete = File.join(K9_ROOT, 'lib/ruby/jruby-complete.jar') return [rcomplete] if FileTest.exist?(rcomplete) warn "#{rcomplete} does not exist\nTry running `k9 --install`" exit end def libraries %w(video sound).map { |library| sketchbook_library(library) }.flatten end def sketchbook_library(name) Dir["#{Processing::RP_CONFIG['sketchbook_path']}/libraries/#{name}/library/\*.jar"] end def host_os detect_os = RbConfig::CONFIG['host_os'] case detect_os when /mac|darwin/ then :mac when /linux/ then :linux when /solaris|bsd/ then :unix else WIN_PATTERNS.find { |r| detect_os =~ r } raise "unknown os: #{detect_os.inspect}" if Regexp.last_match.nil? :windows end end end # class Runner end # module Processing