#!/usr/bin/env ruby require 'pathname' @root = Pathname(__FILE__).dirname.parent.expand_path %w{json thor angry_hash}.each do |lib| root = @root+'vendor'+lib $: << (root+'lib') end require 'thor' $:.unshift @root+'lib' require 'angry_mob' class MobCLI < Thor default_task 'riot' desc 'riot', 'riot the mob' method_option :nodename , :type => :string, :required => true method_option :json_file, :type => :string, :required => true method_option :act , :type => :string, :required => true method_option :hooks , :type => :string method_option :debug , :type => :boolean, :default => false method_option :dry_run , :type => :boolean, :default => false method_option :allow_missing_act, :type => :boolean, :default => false method_option :mobs, :type => :array, :default => [] attr_reader :config def riot begin @config = AngryHash[ options ] load_hooks(config.hooks) @hooks.pre ui = AngryMob::UI.new(:debug => config.debug?) attributes = build_attributes @hooks.attrs( attributes ) AngryMob::Mob.ui = ui # XXX not threadsafe, but what is? mob_loader = AngryMob::MobLoader.new config.mobs.each {|mob_path| mob_loader.add_mob(mob_path)} mob = mob_loader.to_mob mob.riot!( config.nodename, attributes ) rescue $stdout.flush $stderr.flush puts "\nerror [#{$!.class}] #{$!}" $!.backtrace.each {|b| puts " #{b}"} exit(1) end end protected def build_attributes attributes = load_attributes attributes.acts = [ config.act ] if config.allow_missing_act? attributes.raise_on_missing_act = false end attributes.dry_run = config.dry_run? attributes end def load_attributes return AngryHash.new unless config.json_file? if config.json_file.to_s[/^https?:/] require 'net/http' require 'uri' json = Net::HTTP.get(URI.parse(config.json_file)) else json = Pathname(config.json_file.tapp("loading attributes from")).expand_path.read end require 'json/pure' attributes = JSON.parse( json ) AngryHash[attributes || {}] end def load_hooks(file) @hooks = MobHooks.new( self, file ) end end class MobHooks attr_reader :cli def initialize(cli,file=nil) @cli = cli if file @building = true instance_eval( Pathname(file).read ) @building = false end end def pre(&block) if building? pre_blocks << block else pre_blocks.each {|b| b.call} end end def attrs( *args, &block ) if building? attr_blocks << block else attr_blocks.each {|b| b.call(*args)} end end protected def building?; @building end def pre_blocks ; @pre_blocks ||= [] end def attr_blocks; @attr_blocks ||= [] end end MobCLI.start