lib/gamefic/shell.rb in gamefic-1.1.0 vs lib/gamefic/shell.rb in gamefic-1.2.0

- old
+ new

@@ -1,25 +1,75 @@ +require 'thor' +require 'gamefic/engine/tty' +require 'zip' +require 'tmpdir' +require 'yaml' + module Gamefic + class Shell < Thor + map %w[--version -v] => :version - class Shell - autoload :Command, 'gamefic/shell/command' + desc "--version, -v", "Print the version" + def version + puts "gamefic #{Gamefic::VERSION}" + end - def initialize - @commands = {} + desc 'play FILE_NAME', 'Execute a compiled (.gfic) game' + option :verbose, type: :boolean, aliases: :v, desc: "Don't suppress Ruby exceptions" + def play(file) + Dir.mktmpdir 'gamefic_' do |dir| + puts 'Loading...' + decompress file, dir + run_game(dir) + end + rescue StandardError => e + puts "'#{file}' does not appear to be a valid Gamefic file." + show_exception(e) if options[:verbose] end + + desc 'info FILE_NAME', 'Print information about a (.gfic) game' + option :verbose, type: :boolean, aliases: :v, desc: "Don't suppress Ruby exceptions" + def info(file) + Dir.mktmpdir 'gamefic_' do |dir| + decompress file, dir + metadata = YAML.load_file File.join(dir, 'metadata.yaml') + metadata.each { |k, v| + puts "#{k}: #{v}" + } + end + rescue StandardError, Zip::Error => e + puts "'#{file}' does not appear to be a valid Gamefic file." + show_exception(e) if options[:verbose] + end - def register cmd, cls - @commands[cmd] = cls + # Custom error message for invalid command or filename + def method_missing(symbol, *args) + raise UndefinedCommandError, "Could not find command or file named \"#{symbol}\"." end - def execute - command = ARGV[0] - cls = @commands[command] - if cls.nil? - Gamefic::Shell::Command::Play.new.run(['play'] + ARGV) - else - cls.new.run ARGV + private + + def show_exception(exception) + puts exception.inspect + puts exception.backtrace.join("\n") + end + + def decompress(zipfile, destination) + Zip::File.open(zipfile) do |z| + z.each do |entry| + FileUtils.mkdir_p File.join(destination, File.dirname(entry.name)) + full_path = File.join(destination, entry.name) + entry.extract full_path unless File.exist?(full_path) + end end end + + def run_game(directory) + story = Plot.new(Source::File.new(File.join(directory, 'scripts'))) + story.script 'main' + story.metadata = YAML.load_file File.join(directory, 'metadata.yaml') + engine = Tty::Engine.new story + puts "\n" + engine.run + end end - end