scatter 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/bin/scatter +6 -0
 - data/lib/scatter.rb +27 -0
 - data/lib/scatter/cli.rb +64 -0
 - data/lib/scatter/command.rb +31 -0
 - data/lib/scatter/commands/init.rb +17 -0
 - data/lib/scatter/commands/list.rb +27 -0
 - data/lib/scatter/commands/node.rb +22 -0
 - data/lib/scatter/commands/node/add.rb +20 -0
 - data/lib/scatter/commands/node/list.rb +26 -0
 - data/lib/scatter/commands/node/rm.rb +30 -0
 - data/lib/scatter/commands/push.rb +30 -0
 - data/lib/scatter/commands/receive.rb +19 -0
 - data/lib/scatter/commands/remote.rb +20 -0
 - data/lib/scatter/commands/remote/add.rb +18 -0
 - data/lib/scatter/commands/remote/list.rb +13 -0
 - data/lib/scatter/commands/remote/rm.rb +19 -0
 - data/lib/scatter/config.rb +72 -0
 - data/lib/scatter/gemlist.rb +13 -0
 - data/lib/scatter/logger.rb +7 -0
 - data/lib/scatter/node.rb +34 -0
 - data/lib/scatter/remote.rb +33 -0
 - data/lib/scatter/shell.rb +28 -0
 - data/lib/scatter/sub_command.rb +7 -0
 - data/lib/scatter/super_command.rb +28 -0
 - data/lib/scatter/version.rb +5 -0
 - metadata +81 -0
 
    
        data/bin/scatter
    ADDED
    
    
    
        data/lib/scatter.rb
    ADDED
    
    | 
         @@ -0,0 +1,27 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require File.dirname(__FILE__) + '/scatter/cli'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require File.dirname(__FILE__) + '/scatter/command'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require File.dirname(__FILE__) + '/scatter/super_command'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require File.dirname(__FILE__) + '/scatter/sub_command'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require File.dirname(__FILE__) + '/scatter/commands/list'
         
     | 
| 
      
 6 
     | 
    
         
            +
            require File.dirname(__FILE__) + '/scatter/commands/push'
         
     | 
| 
      
 7 
     | 
    
         
            +
            require File.dirname(__FILE__) + '/scatter/commands/receive'
         
     | 
| 
      
 8 
     | 
    
         
            +
            require File.dirname(__FILE__) + '/scatter/commands/remote'
         
     | 
| 
      
 9 
     | 
    
         
            +
            require File.dirname(__FILE__) + '/scatter/commands/remote/add'
         
     | 
| 
      
 10 
     | 
    
         
            +
            require File.dirname(__FILE__) + '/scatter/commands/remote/list'
         
     | 
| 
      
 11 
     | 
    
         
            +
            require File.dirname(__FILE__) + '/scatter/commands/remote/rm'
         
     | 
| 
      
 12 
     | 
    
         
            +
            require File.dirname(__FILE__) + '/scatter/commands/node'
         
     | 
| 
      
 13 
     | 
    
         
            +
            require File.dirname(__FILE__) + '/scatter/commands/node/add'
         
     | 
| 
      
 14 
     | 
    
         
            +
            require File.dirname(__FILE__) + '/scatter/commands/node/list'
         
     | 
| 
      
 15 
     | 
    
         
            +
            require File.dirname(__FILE__) + '/scatter/commands/node/rm'
         
     | 
| 
      
 16 
     | 
    
         
            +
            require File.dirname(__FILE__) + '/scatter/commands/init'
         
     | 
| 
      
 17 
     | 
    
         
            +
            require File.dirname(__FILE__) + '/scatter/config'
         
     | 
| 
      
 18 
     | 
    
         
            +
            require File.dirname(__FILE__) + '/scatter/logger'
         
     | 
| 
      
 19 
     | 
    
         
            +
            require File.dirname(__FILE__) + '/scatter/node'
         
     | 
| 
      
 20 
     | 
    
         
            +
            require File.dirname(__FILE__) + '/scatter/remote'
         
     | 
| 
      
 21 
     | 
    
         
            +
            require File.dirname(__FILE__) + '/scatter/gemlist'
         
     | 
| 
      
 22 
     | 
    
         
            +
            require File.dirname(__FILE__) + '/scatter/shell'
         
     | 
| 
      
 23 
     | 
    
         
            +
            require File.dirname(__FILE__) + '/scatter/version'
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
            module Scatter
         
     | 
| 
      
 26 
     | 
    
         
            +
              class CommandLineError< StandardError; end
         
     | 
| 
      
 27 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/scatter/cli.rb
    ADDED
    
    | 
         @@ -0,0 +1,64 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Scatter
         
     | 
| 
      
 2 
     | 
    
         
            +
              class CLI
         
     | 
| 
      
 3 
     | 
    
         
            +
                def initialize(out)
         
     | 
| 
      
 4 
     | 
    
         
            +
                  @out = out
         
     | 
| 
      
 5 
     | 
    
         
            +
                end
         
     | 
| 
      
 6 
     | 
    
         
            +
                
         
     | 
| 
      
 7 
     | 
    
         
            +
                def run!(args)
         
     | 
| 
      
 8 
     | 
    
         
            +
                  raise CommandLineError, 'No command given' if args.empty?
         
     | 
| 
      
 9 
     | 
    
         
            +
                
         
     | 
| 
      
 10 
     | 
    
         
            +
                  case command_name = args.shift
         
     | 
| 
      
 11 
     | 
    
         
            +
                  when /^-?-?h(elp)?$/
         
     | 
| 
      
 12 
     | 
    
         
            +
                    if args.empty?
         
     | 
| 
      
 13 
     | 
    
         
            +
                      usage
         
     | 
| 
      
 14 
     | 
    
         
            +
                    else
         
     | 
| 
      
 15 
     | 
    
         
            +
                      if args.first == 'commands'
         
     | 
| 
      
 16 
     | 
    
         
            +
                        commands_help
         
     | 
| 
      
 17 
     | 
    
         
            +
                      else
         
     | 
| 
      
 18 
     | 
    
         
            +
                        @out.puts command_class(args.first).help
         
     | 
| 
      
 19 
     | 
    
         
            +
                      end
         
     | 
| 
      
 20 
     | 
    
         
            +
                    end
         
     | 
| 
      
 21 
     | 
    
         
            +
                  when /^-?-?v(ersion)?$/
         
     | 
| 
      
 22 
     | 
    
         
            +
                    @out.puts "scatter version #{Scatter.version}"
         
     | 
| 
      
 23 
     | 
    
         
            +
                  else
         
     | 
| 
      
 24 
     | 
    
         
            +
                    klass = command_class(command_name)
         
     | 
| 
      
 25 
     | 
    
         
            +
                    command = klass.new(@out, *args)
         
     | 
| 
      
 26 
     | 
    
         
            +
                    command.execute!
         
     | 
| 
      
 27 
     | 
    
         
            +
                  end
         
     | 
| 
      
 28 
     | 
    
         
            +
                end
         
     | 
| 
      
 29 
     | 
    
         
            +
                
         
     | 
| 
      
 30 
     | 
    
         
            +
                def run(args)
         
     | 
| 
      
 31 
     | 
    
         
            +
                  run!(args)
         
     | 
| 
      
 32 
     | 
    
         
            +
                rescue CommandLineError => e
         
     | 
| 
      
 33 
     | 
    
         
            +
                  @out.puts "Error: #{e.message}"
         
     | 
| 
      
 34 
     | 
    
         
            +
                  usage
         
     | 
| 
      
 35 
     | 
    
         
            +
                end
         
     | 
| 
      
 36 
     | 
    
         
            +
              
         
     | 
| 
      
 37 
     | 
    
         
            +
              protected
         
     | 
| 
      
 38 
     | 
    
         
            +
                def usage
         
     | 
| 
      
 39 
     | 
    
         
            +
                  @out.puts "Usage: scatter command [options ...]"
         
     | 
| 
      
 40 
     | 
    
         
            +
                  @out.puts "For information about the commands use: scatter help commands"
         
     | 
| 
      
 41 
     | 
    
         
            +
                end
         
     | 
| 
      
 42 
     | 
    
         
            +
                
         
     | 
| 
      
 43 
     | 
    
         
            +
                def commands_help
         
     | 
| 
      
 44 
     | 
    
         
            +
                  @out.puts "To get help for a command, use: scatter help <command_name>"
         
     | 
| 
      
 45 
     | 
    
         
            +
                  @out.puts
         
     | 
| 
      
 46 
     | 
    
         
            +
                  hash = Scatter::Command.command_classes.inject({}) do |hash, cmd|
         
     | 
| 
      
 47 
     | 
    
         
            +
                    next hash if cmd.abstract
         
     | 
| 
      
 48 
     | 
    
         
            +
                    command_name = cmd.name.split('::').last.downcase
         
     | 
| 
      
 49 
     | 
    
         
            +
                    hash[command_name] = cmd.short_help
         
     | 
| 
      
 50 
     | 
    
         
            +
                    hash
         
     | 
| 
      
 51 
     | 
    
         
            +
                  end
         
     | 
| 
      
 52 
     | 
    
         
            +
                  
         
     | 
| 
      
 53 
     | 
    
         
            +
                  hash.sort.each do |command, help|
         
     | 
| 
      
 54 
     | 
    
         
            +
                    @out.puts "#{command} - #{help}"
         
     | 
| 
      
 55 
     | 
    
         
            +
                  end
         
     | 
| 
      
 56 
     | 
    
         
            +
                end
         
     | 
| 
      
 57 
     | 
    
         
            +
              
         
     | 
| 
      
 58 
     | 
    
         
            +
                def command_class(command_name)
         
     | 
| 
      
 59 
     | 
    
         
            +
                  eval("Scatter::Commands::#{command_name.capitalize}")
         
     | 
| 
      
 60 
     | 
    
         
            +
                rescue
         
     | 
| 
      
 61 
     | 
    
         
            +
                  raise CommandLineError, "Unknown command #{command_name}"
         
     | 
| 
      
 62 
     | 
    
         
            +
                end
         
     | 
| 
      
 63 
     | 
    
         
            +
              end
         
     | 
| 
      
 64 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,31 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Scatter
         
     | 
| 
      
 2 
     | 
    
         
            +
              class Command
         
     | 
| 
      
 3 
     | 
    
         
            +
                def initialize(out)
         
     | 
| 
      
 4 
     | 
    
         
            +
                  @out = out
         
     | 
| 
      
 5 
     | 
    
         
            +
                end
         
     | 
| 
      
 6 
     | 
    
         
            +
                
         
     | 
| 
      
 7 
     | 
    
         
            +
                class << self
         
     | 
| 
      
 8 
     | 
    
         
            +
                  attr_reader :short_help
         
     | 
| 
      
 9 
     | 
    
         
            +
                  attr_reader :command_classes
         
     | 
| 
      
 10 
     | 
    
         
            +
                  attr_accessor :abstract
         
     | 
| 
      
 11 
     | 
    
         
            +
                  
         
     | 
| 
      
 12 
     | 
    
         
            +
                  def usage(short_help, long_help = nil)
         
     | 
| 
      
 13 
     | 
    
         
            +
                    @short_help, @help = short_help, long_help || short_help
         
     | 
| 
      
 14 
     | 
    
         
            +
                  end
         
     | 
| 
      
 15 
     | 
    
         
            +
                  
         
     | 
| 
      
 16 
     | 
    
         
            +
                  def help
         
     | 
| 
      
 17 
     | 
    
         
            +
                    lines = @help.split("\n")
         
     | 
| 
      
 18 
     | 
    
         
            +
                    indent = lines.collect { |l| l[/^(\s*)/, 1].size }.min
         
     | 
| 
      
 19 
     | 
    
         
            +
                    lines.collect { |l| l[indent..-1] }.join("\n")
         
     | 
| 
      
 20 
     | 
    
         
            +
                  end
         
     | 
| 
      
 21 
     | 
    
         
            +
                  
         
     | 
| 
      
 22 
     | 
    
         
            +
                  def inherited(sub)
         
     | 
| 
      
 23 
     | 
    
         
            +
                    (@command_classes ||= []) << sub
         
     | 
| 
      
 24 
     | 
    
         
            +
                  end
         
     | 
| 
      
 25 
     | 
    
         
            +
                  
         
     | 
| 
      
 26 
     | 
    
         
            +
                  def command_name
         
     | 
| 
      
 27 
     | 
    
         
            +
                    name.split('::').last.downcase
         
     | 
| 
      
 28 
     | 
    
         
            +
                  end
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
              end
         
     | 
| 
      
 31 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,17 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'fileutils'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Scatter
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Commands
         
     | 
| 
      
 5 
     | 
    
         
            +
                class Init < Scatter::Command
         
     | 
| 
      
 6 
     | 
    
         
            +
                  usage "Initialize scatter configuration", <<-end
         
     | 
| 
      
 7 
     | 
    
         
            +
                    Initializes your machine to use scatter. You need to run this command only once.
         
     | 
| 
      
 8 
     | 
    
         
            +
                    However, it should not break anything if you run it again.
         
     | 
| 
      
 9 
     | 
    
         
            +
                  end
         
     | 
| 
      
 10 
     | 
    
         
            +
                  
         
     | 
| 
      
 11 
     | 
    
         
            +
                  def execute!
         
     | 
| 
      
 12 
     | 
    
         
            +
                    FileUtils.mkdir_p File.dirname(Scatter::Config.file_name)
         
     | 
| 
      
 13 
     | 
    
         
            +
                    Scatter::Config.save!
         
     | 
| 
      
 14 
     | 
    
         
            +
                  end
         
     | 
| 
      
 15 
     | 
    
         
            +
                end
         
     | 
| 
      
 16 
     | 
    
         
            +
              end
         
     | 
| 
      
 17 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,27 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Scatter
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Commands
         
     | 
| 
      
 3 
     | 
    
         
            +
                class List < Scatter::Command
         
     | 
| 
      
 4 
     | 
    
         
            +
                  usage "List all gems installed on node", <<-end
         
     | 
| 
      
 5 
     | 
    
         
            +
                    List all gems on a node. The node can be specified by name or by fully qualified
         
     | 
| 
      
 6 
     | 
    
         
            +
                    node name. Examples:
         
     | 
| 
      
 7 
     | 
    
         
            +
                    
         
     | 
| 
      
 8 
     | 
    
         
            +
                      scatter list nodename
         
     | 
| 
      
 9 
     | 
    
         
            +
                      scatter list remote/nodename
         
     | 
| 
      
 10 
     | 
    
         
            +
                  end
         
     | 
| 
      
 11 
     | 
    
         
            +
                  
         
     | 
| 
      
 12 
     | 
    
         
            +
                  def initialize(out, node_name)
         
     | 
| 
      
 13 
     | 
    
         
            +
                    super(out)
         
     | 
| 
      
 14 
     | 
    
         
            +
                    @node_name = node_name
         
     | 
| 
      
 15 
     | 
    
         
            +
                  end
         
     | 
| 
      
 16 
     | 
    
         
            +
                  
         
     | 
| 
      
 17 
     | 
    
         
            +
                  def execute!
         
     | 
| 
      
 18 
     | 
    
         
            +
                    gemlist = node.list
         
     | 
| 
      
 19 
     | 
    
         
            +
                    @out.puts gemlist.gem_output
         
     | 
| 
      
 20 
     | 
    
         
            +
                  end
         
     | 
| 
      
 21 
     | 
    
         
            +
                  
         
     | 
| 
      
 22 
     | 
    
         
            +
                  def node
         
     | 
| 
      
 23 
     | 
    
         
            +
                    @node ||= Scatter::Config.find_node(@node_name)
         
     | 
| 
      
 24 
     | 
    
         
            +
                  end
         
     | 
| 
      
 25 
     | 
    
         
            +
                end
         
     | 
| 
      
 26 
     | 
    
         
            +
              end
         
     | 
| 
      
 27 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,22 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Scatter
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Commands
         
     | 
| 
      
 3 
     | 
    
         
            +
                class Node < Scatter::SuperCommand
         
     | 
| 
      
 4 
     | 
    
         
            +
                  usage "List, add or remove nodes", <<-end
         
     | 
| 
      
 5 
     | 
    
         
            +
                    List, add or remove nodes from remote.
         
     | 
| 
      
 6 
     | 
    
         
            +
                    To list nodes use the following syntax:
         
     | 
| 
      
 7 
     | 
    
         
            +
                    
         
     | 
| 
      
 8 
     | 
    
         
            +
                      scatter node list <remote_name>
         
     | 
| 
      
 9 
     | 
    
         
            +
                    
         
     | 
| 
      
 10 
     | 
    
         
            +
                    To add a node to a remote, use
         
     | 
| 
      
 11 
     | 
    
         
            +
                    
         
     | 
| 
      
 12 
     | 
    
         
            +
                      scatter node add <remote_name> <node_name> <username>@<hostname>
         
     | 
| 
      
 13 
     | 
    
         
            +
                    
         
     | 
| 
      
 14 
     | 
    
         
            +
                    To remove a node, use either of
         
     | 
| 
      
 15 
     | 
    
         
            +
                    
         
     | 
| 
      
 16 
     | 
    
         
            +
                      scatter node rm <node_name>
         
     | 
| 
      
 17 
     | 
    
         
            +
                      scatter node rm <remote_name>/<node_name>
         
     | 
| 
      
 18 
     | 
    
         
            +
                      scatter node rm <remote_name> <node_name>
         
     | 
| 
      
 19 
     | 
    
         
            +
                  end
         
     | 
| 
      
 20 
     | 
    
         
            +
                end
         
     | 
| 
      
 21 
     | 
    
         
            +
              end
         
     | 
| 
      
 22 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,20 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Scatter
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Commands
         
     | 
| 
      
 3 
     | 
    
         
            +
                class Node
         
     | 
| 
      
 4 
     | 
    
         
            +
                  class Add < Scatter::SubCommand
         
     | 
| 
      
 5 
     | 
    
         
            +
                    def initialize(out, remote_name, node, credentials)
         
     | 
| 
      
 6 
     | 
    
         
            +
                      super(out)
         
     | 
| 
      
 7 
     | 
    
         
            +
                      @remote_name, @node, @credentials = remote_name, node, credentials
         
     | 
| 
      
 8 
     | 
    
         
            +
                    end
         
     | 
| 
      
 9 
     | 
    
         
            +
                    
         
     | 
| 
      
 10 
     | 
    
         
            +
                    def execute!
         
     | 
| 
      
 11 
     | 
    
         
            +
                      remote = Scatter::Config.find_remote(@remote_name)
         
     | 
| 
      
 12 
     | 
    
         
            +
                      raise CommandLineError, "Unknown remote #{@remote_name}" unless remote
         
     | 
| 
      
 13 
     | 
    
         
            +
                      raise CommandLineError, "Remote #{@remote_name} already has node #{@node}" if remote.find_node(@node)
         
     | 
| 
      
 14 
     | 
    
         
            +
                      remote.nodes << Scatter::Node.new(remote, @node, *(@credentials.split('@')))
         
     | 
| 
      
 15 
     | 
    
         
            +
                      Scatter::Config.save!
         
     | 
| 
      
 16 
     | 
    
         
            +
                    end
         
     | 
| 
      
 17 
     | 
    
         
            +
                  end
         
     | 
| 
      
 18 
     | 
    
         
            +
                end
         
     | 
| 
      
 19 
     | 
    
         
            +
              end
         
     | 
| 
      
 20 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,26 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Scatter
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Commands
         
     | 
| 
      
 3 
     | 
    
         
            +
                class Node
         
     | 
| 
      
 4 
     | 
    
         
            +
                  class List < Scatter::SubCommand
         
     | 
| 
      
 5 
     | 
    
         
            +
                    def initialize(out, name = nil)
         
     | 
| 
      
 6 
     | 
    
         
            +
                      super(out)
         
     | 
| 
      
 7 
     | 
    
         
            +
                      @name = name
         
     | 
| 
      
 8 
     | 
    
         
            +
                    end
         
     | 
| 
      
 9 
     | 
    
         
            +
                    
         
     | 
| 
      
 10 
     | 
    
         
            +
                    def execute!
         
     | 
| 
      
 11 
     | 
    
         
            +
                      nodes = if @name
         
     | 
| 
      
 12 
     | 
    
         
            +
                        remote = Scatter::Config.find_remote(@name)
         
     | 
| 
      
 13 
     | 
    
         
            +
                        raise CommandLineError, "Unknown remote #{@name}" unless remote
         
     | 
| 
      
 14 
     | 
    
         
            +
                        remote.nodes
         
     | 
| 
      
 15 
     | 
    
         
            +
                      else
         
     | 
| 
      
 16 
     | 
    
         
            +
                        Scatter::Config.nodes
         
     | 
| 
      
 17 
     | 
    
         
            +
                      end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                      nodes.each do |node|
         
     | 
| 
      
 20 
     | 
    
         
            +
                        @out.puts "#{node.remote.name}/#{node.name}"
         
     | 
| 
      
 21 
     | 
    
         
            +
                      end
         
     | 
| 
      
 22 
     | 
    
         
            +
                    end
         
     | 
| 
      
 23 
     | 
    
         
            +
                  end
         
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
              end
         
     | 
| 
      
 26 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,30 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Scatter
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Commands
         
     | 
| 
      
 3 
     | 
    
         
            +
                class Node
         
     | 
| 
      
 4 
     | 
    
         
            +
                  class Rm < Scatter::SubCommand
         
     | 
| 
      
 5 
     | 
    
         
            +
                    def initialize(out, remote, node = nil)
         
     | 
| 
      
 6 
     | 
    
         
            +
                      super(out)
         
     | 
| 
      
 7 
     | 
    
         
            +
                      @remote, @node = remote, node
         
     | 
| 
      
 8 
     | 
    
         
            +
                    end
         
     | 
| 
      
 9 
     | 
    
         
            +
                    
         
     | 
| 
      
 10 
     | 
    
         
            +
                    def execute!
         
     | 
| 
      
 11 
     | 
    
         
            +
                      node = if @node
         
     | 
| 
      
 12 
     | 
    
         
            +
                        remote = Scatter::Config.find_remote(@remote)
         
     | 
| 
      
 13 
     | 
    
         
            +
                        raise CommandLineError, "Unknown remote #{@remote}" unless remote
         
     | 
| 
      
 14 
     | 
    
         
            +
                        remote.find_node(@node)
         
     | 
| 
      
 15 
     | 
    
         
            +
                      else
         
     | 
| 
      
 16 
     | 
    
         
            +
                        Scatter::Config.find_destination(@remote)
         
     | 
| 
      
 17 
     | 
    
         
            +
                      end
         
     | 
| 
      
 18 
     | 
    
         
            +
                      
         
     | 
| 
      
 19 
     | 
    
         
            +
                      unless node
         
     | 
| 
      
 20 
     | 
    
         
            +
                        dest = [@remote, @node].compact.join('/')
         
     | 
| 
      
 21 
     | 
    
         
            +
                        raise CommandLineError, "Unknown node #{dest}"
         
     | 
| 
      
 22 
     | 
    
         
            +
                      end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                      node.remote.nodes.delete(node)
         
     | 
| 
      
 25 
     | 
    
         
            +
                      Scatter::Config.save!
         
     | 
| 
      
 26 
     | 
    
         
            +
                    end
         
     | 
| 
      
 27 
     | 
    
         
            +
                  end
         
     | 
| 
      
 28 
     | 
    
         
            +
                end
         
     | 
| 
      
 29 
     | 
    
         
            +
              end
         
     | 
| 
      
 30 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,30 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Scatter
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Commands
         
     | 
| 
      
 3 
     | 
    
         
            +
                class Push < Scatter::Command
         
     | 
| 
      
 4 
     | 
    
         
            +
                  usage "Push gem to remote or node", <<-end
         
     | 
| 
      
 5 
     | 
    
         
            +
                    Pushes a gem to a remote or node. Use the remote name, node name or fully
         
     | 
| 
      
 6 
     | 
    
         
            +
                    qualified node name to specify the target. Examples:
         
     | 
| 
      
 7 
     | 
    
         
            +
                    
         
     | 
| 
      
 8 
     | 
    
         
            +
                      # to push to node my_node
         
     | 
| 
      
 9 
     | 
    
         
            +
                      scatter push my_gem.gem my_node
         
     | 
| 
      
 10 
     | 
    
         
            +
                      scatter push my_gem.gem my_remote/my_node
         
     | 
| 
      
 11 
     | 
    
         
            +
                      
         
     | 
| 
      
 12 
     | 
    
         
            +
                      # to push to remote my_remote
         
     | 
| 
      
 13 
     | 
    
         
            +
                      scatter push my_gem.gem my_remote
         
     | 
| 
      
 14 
     | 
    
         
            +
                  end
         
     | 
| 
      
 15 
     | 
    
         
            +
                  
         
     | 
| 
      
 16 
     | 
    
         
            +
                  def initialize(out, gemfile, destination)
         
     | 
| 
      
 17 
     | 
    
         
            +
                    super(out)
         
     | 
| 
      
 18 
     | 
    
         
            +
                    @gemfile, @destination = gemfile, destination
         
     | 
| 
      
 19 
     | 
    
         
            +
                  end
         
     | 
| 
      
 20 
     | 
    
         
            +
                  
         
     | 
| 
      
 21 
     | 
    
         
            +
                  def execute!
         
     | 
| 
      
 22 
     | 
    
         
            +
                    dest.push(@gemfile)
         
     | 
| 
      
 23 
     | 
    
         
            +
                  end
         
     | 
| 
      
 24 
     | 
    
         
            +
                  
         
     | 
| 
      
 25 
     | 
    
         
            +
                  def dest
         
     | 
| 
      
 26 
     | 
    
         
            +
                    @dest ||= Scatter::Config.find_destination(@destination)
         
     | 
| 
      
 27 
     | 
    
         
            +
                  end
         
     | 
| 
      
 28 
     | 
    
         
            +
                end
         
     | 
| 
      
 29 
     | 
    
         
            +
              end
         
     | 
| 
      
 30 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,19 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Scatter
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Commands
         
     | 
| 
      
 3 
     | 
    
         
            +
                class Receive < Scatter::Command
         
     | 
| 
      
 4 
     | 
    
         
            +
                  usage "Inform scatter that gem was received; calls post receive hook"
         
     | 
| 
      
 5 
     | 
    
         
            +
                  
         
     | 
| 
      
 6 
     | 
    
         
            +
                  def initialize(out, gemfile)
         
     | 
| 
      
 7 
     | 
    
         
            +
                    super(out)
         
     | 
| 
      
 8 
     | 
    
         
            +
                    @gemfile = gemfile
         
     | 
| 
      
 9 
     | 
    
         
            +
                  end
         
     | 
| 
      
 10 
     | 
    
         
            +
                  
         
     | 
| 
      
 11 
     | 
    
         
            +
                  def execute!
         
     | 
| 
      
 12 
     | 
    
         
            +
                    if File.executable?("#{ENV['HOME']}/.scatter/post-receive")
         
     | 
| 
      
 13 
     | 
    
         
            +
                      Scatter::Logger.log("Executing post receive hook")
         
     | 
| 
      
 14 
     | 
    
         
            +
                      Scatter::Shell.execute "#{ENV['HOME']}/.scatter/post-receive #{@gemfile}"
         
     | 
| 
      
 15 
     | 
    
         
            +
                    end
         
     | 
| 
      
 16 
     | 
    
         
            +
                  end
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
              end
         
     | 
| 
      
 19 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,20 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Scatter
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Commands
         
     | 
| 
      
 3 
     | 
    
         
            +
                class Remote < Scatter::SuperCommand
         
     | 
| 
      
 4 
     | 
    
         
            +
                  usage "List, add or remove remotes", <<-end
         
     | 
| 
      
 5 
     | 
    
         
            +
                    List, add or remove remotes.
         
     | 
| 
      
 6 
     | 
    
         
            +
                    To list remotes use the following syntax:
         
     | 
| 
      
 7 
     | 
    
         
            +
                    
         
     | 
| 
      
 8 
     | 
    
         
            +
                      scatter remote list
         
     | 
| 
      
 9 
     | 
    
         
            +
                    
         
     | 
| 
      
 10 
     | 
    
         
            +
                    To add a remote, use
         
     | 
| 
      
 11 
     | 
    
         
            +
                    
         
     | 
| 
      
 12 
     | 
    
         
            +
                      scatter remote add <remote_name>
         
     | 
| 
      
 13 
     | 
    
         
            +
                    
         
     | 
| 
      
 14 
     | 
    
         
            +
                    To remove a remote, use
         
     | 
| 
      
 15 
     | 
    
         
            +
                    
         
     | 
| 
      
 16 
     | 
    
         
            +
                      scatter remote rm <remote_name>
         
     | 
| 
      
 17 
     | 
    
         
            +
                  end
         
     | 
| 
      
 18 
     | 
    
         
            +
                end
         
     | 
| 
      
 19 
     | 
    
         
            +
              end
         
     | 
| 
      
 20 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,18 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Scatter
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Commands
         
     | 
| 
      
 3 
     | 
    
         
            +
                class Remote
         
     | 
| 
      
 4 
     | 
    
         
            +
                  class Add < Scatter::SubCommand
         
     | 
| 
      
 5 
     | 
    
         
            +
                    def initialize(out, name)
         
     | 
| 
      
 6 
     | 
    
         
            +
                      super(out)
         
     | 
| 
      
 7 
     | 
    
         
            +
                      @name = name
         
     | 
| 
      
 8 
     | 
    
         
            +
                    end
         
     | 
| 
      
 9 
     | 
    
         
            +
                    
         
     | 
| 
      
 10 
     | 
    
         
            +
                    def execute!
         
     | 
| 
      
 11 
     | 
    
         
            +
                      raise CommandLineError, "Remote #{@name} already exists" if Scatter::Config.find_remote(@name)
         
     | 
| 
      
 12 
     | 
    
         
            +
                      Scatter::Config.remotes << Scatter::Remote.new(@name)
         
     | 
| 
      
 13 
     | 
    
         
            +
                      Scatter::Config.save!
         
     | 
| 
      
 14 
     | 
    
         
            +
                    end
         
     | 
| 
      
 15 
     | 
    
         
            +
                  end
         
     | 
| 
      
 16 
     | 
    
         
            +
                end
         
     | 
| 
      
 17 
     | 
    
         
            +
              end
         
     | 
| 
      
 18 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,19 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Scatter
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Commands
         
     | 
| 
      
 3 
     | 
    
         
            +
                class Remote
         
     | 
| 
      
 4 
     | 
    
         
            +
                  class Rm < Scatter::SubCommand
         
     | 
| 
      
 5 
     | 
    
         
            +
                    def initialize(out, name)
         
     | 
| 
      
 6 
     | 
    
         
            +
                      super(out)
         
     | 
| 
      
 7 
     | 
    
         
            +
                      @name = name
         
     | 
| 
      
 8 
     | 
    
         
            +
                    end
         
     | 
| 
      
 9 
     | 
    
         
            +
                    
         
     | 
| 
      
 10 
     | 
    
         
            +
                    def execute!
         
     | 
| 
      
 11 
     | 
    
         
            +
                      remote = Scatter::Config.find_remote(@name)
         
     | 
| 
      
 12 
     | 
    
         
            +
                      raise CommandLineError, "Remote #{@name} does not exist" unless remote
         
     | 
| 
      
 13 
     | 
    
         
            +
                      Scatter::Config.remotes.delete(remote)
         
     | 
| 
      
 14 
     | 
    
         
            +
                      Scatter::Config.save!
         
     | 
| 
      
 15 
     | 
    
         
            +
                    end
         
     | 
| 
      
 16 
     | 
    
         
            +
                  end
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
              end
         
     | 
| 
      
 19 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,72 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Scatter
         
     | 
| 
      
 2 
     | 
    
         
            +
              class Config
         
     | 
| 
      
 3 
     | 
    
         
            +
                class << self
         
     | 
| 
      
 4 
     | 
    
         
            +
                  def instance
         
     | 
| 
      
 5 
     | 
    
         
            +
                    @instance ||= new
         
     | 
| 
      
 6 
     | 
    
         
            +
                  end
         
     | 
| 
      
 7 
     | 
    
         
            +
                  
         
     | 
| 
      
 8 
     | 
    
         
            +
                  def clear
         
     | 
| 
      
 9 
     | 
    
         
            +
                    @instance = nil
         
     | 
| 
      
 10 
     | 
    
         
            +
                  end
         
     | 
| 
      
 11 
     | 
    
         
            +
                  
         
     | 
| 
      
 12 
     | 
    
         
            +
                  def reload
         
     | 
| 
      
 13 
     | 
    
         
            +
                    @instance = new(@instance.file_name)
         
     | 
| 
      
 14 
     | 
    
         
            +
                  end
         
     | 
| 
      
 15 
     | 
    
         
            +
                  
         
     | 
| 
      
 16 
     | 
    
         
            +
                  def method_missing(method, *args)
         
     | 
| 
      
 17 
     | 
    
         
            +
                    if instance.respond_to?(method)
         
     | 
| 
      
 18 
     | 
    
         
            +
                      instance.send(method, *args)
         
     | 
| 
      
 19 
     | 
    
         
            +
                    else
         
     | 
| 
      
 20 
     | 
    
         
            +
                      super
         
     | 
| 
      
 21 
     | 
    
         
            +
                    end
         
     | 
| 
      
 22 
     | 
    
         
            +
                  end
         
     | 
| 
      
 23 
     | 
    
         
            +
                end
         
     | 
| 
      
 24 
     | 
    
         
            +
                
         
     | 
| 
      
 25 
     | 
    
         
            +
                attr_accessor :file_name
         
     | 
| 
      
 26 
     | 
    
         
            +
                
         
     | 
| 
      
 27 
     | 
    
         
            +
                def initialize(file_name = nil)
         
     | 
| 
      
 28 
     | 
    
         
            +
                  self.file_name = file_name || "#{ENV['HOME']}/.scatter/config"
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                def remotes
         
     | 
| 
      
 32 
     | 
    
         
            +
                  load!
         
     | 
| 
      
 33 
     | 
    
         
            +
                  @remotes ||= (@config['remotes'] || {}).collect { |name, config| Scatter::Remote.decode_from_config(name, config) }
         
     | 
| 
      
 34 
     | 
    
         
            +
                end
         
     | 
| 
      
 35 
     | 
    
         
            +
                
         
     | 
| 
      
 36 
     | 
    
         
            +
                def nodes
         
     | 
| 
      
 37 
     | 
    
         
            +
                  @nodes ||= remotes.collect { |remote| remote.nodes }.flatten
         
     | 
| 
      
 38 
     | 
    
         
            +
                end
         
     | 
| 
      
 39 
     | 
    
         
            +
                
         
     | 
| 
      
 40 
     | 
    
         
            +
                def load!
         
     | 
| 
      
 41 
     | 
    
         
            +
                  @loaded ||= begin
         
     | 
| 
      
 42 
     | 
    
         
            +
                    @config = YAML.load(File.read(file_name)) rescue {}
         
     | 
| 
      
 43 
     | 
    
         
            +
                    true
         
     | 
| 
      
 44 
     | 
    
         
            +
                  end
         
     | 
| 
      
 45 
     | 
    
         
            +
                end
         
     | 
| 
      
 46 
     | 
    
         
            +
                
         
     | 
| 
      
 47 
     | 
    
         
            +
                def save!
         
     | 
| 
      
 48 
     | 
    
         
            +
                  config = {
         
     | 
| 
      
 49 
     | 
    
         
            +
                    'remotes' => self.remotes.inject({}) { |hash, remote| hash[remote.name] = remote.encode_for_config; hash }
         
     | 
| 
      
 50 
     | 
    
         
            +
                  }
         
     | 
| 
      
 51 
     | 
    
         
            +
                  File.open(file_name, 'w') { |file| file.puts config.to_yaml }
         
     | 
| 
      
 52 
     | 
    
         
            +
                end
         
     | 
| 
      
 53 
     | 
    
         
            +
                
         
     | 
| 
      
 54 
     | 
    
         
            +
                def find_remote(name)
         
     | 
| 
      
 55 
     | 
    
         
            +
                  remotes.find { |remote| remote.name == name }
         
     | 
| 
      
 56 
     | 
    
         
            +
                end
         
     | 
| 
      
 57 
     | 
    
         
            +
                
         
     | 
| 
      
 58 
     | 
    
         
            +
                def find_node(name)
         
     | 
| 
      
 59 
     | 
    
         
            +
                  nodes.find { |node| node.name == name || node.full_name == name }
         
     | 
| 
      
 60 
     | 
    
         
            +
                end
         
     | 
| 
      
 61 
     | 
    
         
            +
                
         
     | 
| 
      
 62 
     | 
    
         
            +
                def find_destination(name)
         
     | 
| 
      
 63 
     | 
    
         
            +
                  if name =~ /\//
         
     | 
| 
      
 64 
     | 
    
         
            +
                    remote, node = *(name.split('/'))
         
     | 
| 
      
 65 
     | 
    
         
            +
                    remote_object = find_remote(remote)
         
     | 
| 
      
 66 
     | 
    
         
            +
                    remote_object.find_node(node) if remote_object
         
     | 
| 
      
 67 
     | 
    
         
            +
                  else
         
     | 
| 
      
 68 
     | 
    
         
            +
                    (remotes + nodes).find { |dest| dest.name == name }
         
     | 
| 
      
 69 
     | 
    
         
            +
                  end
         
     | 
| 
      
 70 
     | 
    
         
            +
                end
         
     | 
| 
      
 71 
     | 
    
         
            +
              end
         
     | 
| 
      
 72 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/scatter/node.rb
    ADDED
    
    | 
         @@ -0,0 +1,34 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Scatter
         
     | 
| 
      
 2 
     | 
    
         
            +
              class Node
         
     | 
| 
      
 3 
     | 
    
         
            +
                attr_reader :remote, :name, :username, :hostname
         
     | 
| 
      
 4 
     | 
    
         
            +
                
         
     | 
| 
      
 5 
     | 
    
         
            +
                def initialize(remote, name, username, hostname)
         
     | 
| 
      
 6 
     | 
    
         
            +
                  @remote, @name, @username, @hostname = remote, name, username, hostname
         
     | 
| 
      
 7 
     | 
    
         
            +
                end
         
     | 
| 
      
 8 
     | 
    
         
            +
                
         
     | 
| 
      
 9 
     | 
    
         
            +
                def full_name
         
     | 
| 
      
 10 
     | 
    
         
            +
                  [remote.name, name].join('/')
         
     | 
| 
      
 11 
     | 
    
         
            +
                end
         
     | 
| 
      
 12 
     | 
    
         
            +
                
         
     | 
| 
      
 13 
     | 
    
         
            +
                def list
         
     | 
| 
      
 14 
     | 
    
         
            +
                  Scatter::Gemlist.parse(Scatter::Shell.capture("ssh #{@username}@#{@hostname} gem list"))
         
     | 
| 
      
 15 
     | 
    
         
            +
                end
         
     | 
| 
      
 16 
     | 
    
         
            +
                
         
     | 
| 
      
 17 
     | 
    
         
            +
                def push(gemfile)
         
     | 
| 
      
 18 
     | 
    
         
            +
                  Scatter::Shell.execute "scp #{gemfile} #{@username}@#{@hostname}:/tmp"
         
     | 
| 
      
 19 
     | 
    
         
            +
                  Scatter::Shell.execute "ssh #{@username}@#{@hostname} sudo gem install /tmp/#{File.basename(gemfile)}"
         
     | 
| 
      
 20 
     | 
    
         
            +
                  Scatter::Shell.execute "ssh #{@username}@#{@hostname} scatter receive /tmp/#{File.basename(gemfile)}"
         
     | 
| 
      
 21 
     | 
    
         
            +
                end
         
     | 
| 
      
 22 
     | 
    
         
            +
                
         
     | 
| 
      
 23 
     | 
    
         
            +
                def self.decode_from_config(remote, name, config)
         
     | 
| 
      
 24 
     | 
    
         
            +
                  new(remote, name, config['username'], config['hostname'])
         
     | 
| 
      
 25 
     | 
    
         
            +
                end
         
     | 
| 
      
 26 
     | 
    
         
            +
                
         
     | 
| 
      
 27 
     | 
    
         
            +
                def encode_for_config
         
     | 
| 
      
 28 
     | 
    
         
            +
                  {
         
     | 
| 
      
 29 
     | 
    
         
            +
                    'username' => @username,
         
     | 
| 
      
 30 
     | 
    
         
            +
                    'hostname' => @hostname
         
     | 
| 
      
 31 
     | 
    
         
            +
                  }
         
     | 
| 
      
 32 
     | 
    
         
            +
                end
         
     | 
| 
      
 33 
     | 
    
         
            +
              end
         
     | 
| 
      
 34 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,33 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Scatter
         
     | 
| 
      
 2 
     | 
    
         
            +
              class Remote
         
     | 
| 
      
 3 
     | 
    
         
            +
                attr_reader :name, :nodes
         
     | 
| 
      
 4 
     | 
    
         
            +
                
         
     | 
| 
      
 5 
     | 
    
         
            +
                def initialize(name)
         
     | 
| 
      
 6 
     | 
    
         
            +
                  @name = name
         
     | 
| 
      
 7 
     | 
    
         
            +
                  @nodes = []
         
     | 
| 
      
 8 
     | 
    
         
            +
                end
         
     | 
| 
      
 9 
     | 
    
         
            +
                
         
     | 
| 
      
 10 
     | 
    
         
            +
                def push(gemfile)
         
     | 
| 
      
 11 
     | 
    
         
            +
                  @nodes.each do |node|
         
     | 
| 
      
 12 
     | 
    
         
            +
                    node.push(gemfile)
         
     | 
| 
      
 13 
     | 
    
         
            +
                  end
         
     | 
| 
      
 14 
     | 
    
         
            +
                end
         
     | 
| 
      
 15 
     | 
    
         
            +
                
         
     | 
| 
      
 16 
     | 
    
         
            +
                def find_node(name)
         
     | 
| 
      
 17 
     | 
    
         
            +
                  nodes.find { |node| node.name == name }
         
     | 
| 
      
 18 
     | 
    
         
            +
                end
         
     | 
| 
      
 19 
     | 
    
         
            +
                
         
     | 
| 
      
 20 
     | 
    
         
            +
                def self.decode_from_config(name, config)
         
     | 
| 
      
 21 
     | 
    
         
            +
                  remote = new(name)
         
     | 
| 
      
 22 
     | 
    
         
            +
                  nodes = config['nodes'].collect { |nodename, config| Node.decode_from_config(remote, nodename, config) } rescue []
         
     | 
| 
      
 23 
     | 
    
         
            +
                  remote.nodes.concat(nodes)
         
     | 
| 
      
 24 
     | 
    
         
            +
                  remote
         
     | 
| 
      
 25 
     | 
    
         
            +
                end
         
     | 
| 
      
 26 
     | 
    
         
            +
                
         
     | 
| 
      
 27 
     | 
    
         
            +
                def encode_for_config
         
     | 
| 
      
 28 
     | 
    
         
            +
                  {
         
     | 
| 
      
 29 
     | 
    
         
            +
                    'nodes' => @nodes.inject({}) { |hash, node| hash[node.name] = node.encode_for_config; hash }
         
     | 
| 
      
 30 
     | 
    
         
            +
                  }
         
     | 
| 
      
 31 
     | 
    
         
            +
                end
         
     | 
| 
      
 32 
     | 
    
         
            +
              end
         
     | 
| 
      
 33 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,28 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Scatter
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Shell
         
     | 
| 
      
 3 
     | 
    
         
            +
                extend self
         
     | 
| 
      
 4 
     | 
    
         
            +
                
         
     | 
| 
      
 5 
     | 
    
         
            +
                attr_accessor :dry_run
         
     | 
| 
      
 6 
     | 
    
         
            +
                attr_accessor :command_log
         
     | 
| 
      
 7 
     | 
    
         
            +
                
         
     | 
| 
      
 8 
     | 
    
         
            +
                def execute(command)
         
     | 
| 
      
 9 
     | 
    
         
            +
                  log_command command
         
     | 
| 
      
 10 
     | 
    
         
            +
                  system command unless dry_run
         
     | 
| 
      
 11 
     | 
    
         
            +
                end
         
     | 
| 
      
 12 
     | 
    
         
            +
                
         
     | 
| 
      
 13 
     | 
    
         
            +
                def capture(command)
         
     | 
| 
      
 14 
     | 
    
         
            +
                  log_command command
         
     | 
| 
      
 15 
     | 
    
         
            +
                  %x{#{command}} unless dry_run
         
     | 
| 
      
 16 
     | 
    
         
            +
                end
         
     | 
| 
      
 17 
     | 
    
         
            +
                
         
     | 
| 
      
 18 
     | 
    
         
            +
                def clear_log
         
     | 
| 
      
 19 
     | 
    
         
            +
                  self.command_log = []
         
     | 
| 
      
 20 
     | 
    
         
            +
                end
         
     | 
| 
      
 21 
     | 
    
         
            +
                
         
     | 
| 
      
 22 
     | 
    
         
            +
              protected
         
     | 
| 
      
 23 
     | 
    
         
            +
                def log_command(command)
         
     | 
| 
      
 24 
     | 
    
         
            +
                  self.command_log ||= []
         
     | 
| 
      
 25 
     | 
    
         
            +
                  self.command_log << command
         
     | 
| 
      
 26 
     | 
    
         
            +
                end
         
     | 
| 
      
 27 
     | 
    
         
            +
              end
         
     | 
| 
      
 28 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,28 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Scatter
         
     | 
| 
      
 2 
     | 
    
         
            +
              class SuperCommand < Command
         
     | 
| 
      
 3 
     | 
    
         
            +
                self.abstract = true
         
     | 
| 
      
 4 
     | 
    
         
            +
                
         
     | 
| 
      
 5 
     | 
    
         
            +
                # needed?
         
     | 
| 
      
 6 
     | 
    
         
            +
                class << self
         
     | 
| 
      
 7 
     | 
    
         
            +
                  def inherited(sub)
         
     | 
| 
      
 8 
     | 
    
         
            +
                    Command.inherited(sub)
         
     | 
| 
      
 9 
     | 
    
         
            +
                  end
         
     | 
| 
      
 10 
     | 
    
         
            +
                end
         
     | 
| 
      
 11 
     | 
    
         
            +
                
         
     | 
| 
      
 12 
     | 
    
         
            +
                def initialize(out, *args)
         
     | 
| 
      
 13 
     | 
    
         
            +
                  super(out)
         
     | 
| 
      
 14 
     | 
    
         
            +
                  @subcmd = args.shift
         
     | 
| 
      
 15 
     | 
    
         
            +
                  @arguments = args
         
     | 
| 
      
 16 
     | 
    
         
            +
                end
         
     | 
| 
      
 17 
     | 
    
         
            +
                
         
     | 
| 
      
 18 
     | 
    
         
            +
                def execute!
         
     | 
| 
      
 19 
     | 
    
         
            +
                  subcmd_class = eval("#{self.class.name}::#{@subcmd.capitalize}")
         
     | 
| 
      
 20 
     | 
    
         
            +
                  cmd = subcmd_class.new(@out, *@arguments)
         
     | 
| 
      
 21 
     | 
    
         
            +
                  cmd.execute!
         
     | 
| 
      
 22 
     | 
    
         
            +
                rescue ArgumentError
         
     | 
| 
      
 23 
     | 
    
         
            +
                  raise CommandLineError, "Wrong number of mandatory arguments for command #{self.class.command_name} #{@subcmd}"
         
     | 
| 
      
 24 
     | 
    
         
            +
                rescue NameError
         
     | 
| 
      
 25 
     | 
    
         
            +
                  raise CommandLineError, "Unknown subcommand #{@subcmd} for command #{self.class.command_name}"
         
     | 
| 
      
 26 
     | 
    
         
            +
                end
         
     | 
| 
      
 27 
     | 
    
         
            +
              end
         
     | 
| 
      
 28 
     | 
    
         
            +
            end
         
     | 
    
        metadata
    ADDED
    
    | 
         @@ -0,0 +1,81 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            --- !ruby/object:Gem::Specification 
         
     | 
| 
      
 2 
     | 
    
         
            +
            name: scatter
         
     | 
| 
      
 3 
     | 
    
         
            +
            version: !ruby/object:Gem::Version 
         
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.0.1
         
     | 
| 
      
 5 
     | 
    
         
            +
            platform: ruby
         
     | 
| 
      
 6 
     | 
    
         
            +
            authors: 
         
     | 
| 
      
 7 
     | 
    
         
            +
            - imedo GmbH
         
     | 
| 
      
 8 
     | 
    
         
            +
            autorequire: 
         
     | 
| 
      
 9 
     | 
    
         
            +
            bindir: bin
         
     | 
| 
      
 10 
     | 
    
         
            +
            cert_chain: []
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            date: 2010-04-17 00:00:00 +02:00
         
     | 
| 
      
 13 
     | 
    
         
            +
            default_executable: 
         
     | 
| 
      
 14 
     | 
    
         
            +
            dependencies: []
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            description: 
         
     | 
| 
      
 17 
     | 
    
         
            +
            email: entwicker@imedo.de
         
     | 
| 
      
 18 
     | 
    
         
            +
            executables: 
         
     | 
| 
      
 19 
     | 
    
         
            +
            - scatter
         
     | 
| 
      
 20 
     | 
    
         
            +
            extensions: []
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
            extra_rdoc_files: []
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
            files: 
         
     | 
| 
      
 25 
     | 
    
         
            +
            - bin/scatter
         
     | 
| 
      
 26 
     | 
    
         
            +
            - lib/scatter
         
     | 
| 
      
 27 
     | 
    
         
            +
            - lib/scatter/cli.rb
         
     | 
| 
      
 28 
     | 
    
         
            +
            - lib/scatter/command.rb
         
     | 
| 
      
 29 
     | 
    
         
            +
            - lib/scatter/commands
         
     | 
| 
      
 30 
     | 
    
         
            +
            - lib/scatter/commands/init.rb
         
     | 
| 
      
 31 
     | 
    
         
            +
            - lib/scatter/commands/list.rb
         
     | 
| 
      
 32 
     | 
    
         
            +
            - lib/scatter/commands/node
         
     | 
| 
      
 33 
     | 
    
         
            +
            - lib/scatter/commands/node/add.rb
         
     | 
| 
      
 34 
     | 
    
         
            +
            - lib/scatter/commands/node/list.rb
         
     | 
| 
      
 35 
     | 
    
         
            +
            - lib/scatter/commands/node/rm.rb
         
     | 
| 
      
 36 
     | 
    
         
            +
            - lib/scatter/commands/node.rb
         
     | 
| 
      
 37 
     | 
    
         
            +
            - lib/scatter/commands/push.rb
         
     | 
| 
      
 38 
     | 
    
         
            +
            - lib/scatter/commands/receive.rb
         
     | 
| 
      
 39 
     | 
    
         
            +
            - lib/scatter/commands/remote
         
     | 
| 
      
 40 
     | 
    
         
            +
            - lib/scatter/commands/remote/add.rb
         
     | 
| 
      
 41 
     | 
    
         
            +
            - lib/scatter/commands/remote/list.rb
         
     | 
| 
      
 42 
     | 
    
         
            +
            - lib/scatter/commands/remote/rm.rb
         
     | 
| 
      
 43 
     | 
    
         
            +
            - lib/scatter/commands/remote.rb
         
     | 
| 
      
 44 
     | 
    
         
            +
            - lib/scatter/config.rb
         
     | 
| 
      
 45 
     | 
    
         
            +
            - lib/scatter/gemlist.rb
         
     | 
| 
      
 46 
     | 
    
         
            +
            - lib/scatter/logger.rb
         
     | 
| 
      
 47 
     | 
    
         
            +
            - lib/scatter/node.rb
         
     | 
| 
      
 48 
     | 
    
         
            +
            - lib/scatter/remote.rb
         
     | 
| 
      
 49 
     | 
    
         
            +
            - lib/scatter/shell.rb
         
     | 
| 
      
 50 
     | 
    
         
            +
            - lib/scatter/sub_command.rb
         
     | 
| 
      
 51 
     | 
    
         
            +
            - lib/scatter/super_command.rb
         
     | 
| 
      
 52 
     | 
    
         
            +
            - lib/scatter/version.rb
         
     | 
| 
      
 53 
     | 
    
         
            +
            - lib/scatter.rb
         
     | 
| 
      
 54 
     | 
    
         
            +
            has_rdoc: false
         
     | 
| 
      
 55 
     | 
    
         
            +
            homepage: http://www.imedo.de/
         
     | 
| 
      
 56 
     | 
    
         
            +
            post_install_message: 
         
     | 
| 
      
 57 
     | 
    
         
            +
            rdoc_options: []
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
            require_paths: 
         
     | 
| 
      
 60 
     | 
    
         
            +
            - lib
         
     | 
| 
      
 61 
     | 
    
         
            +
            required_ruby_version: !ruby/object:Gem::Requirement 
         
     | 
| 
      
 62 
     | 
    
         
            +
              requirements: 
         
     | 
| 
      
 63 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 64 
     | 
    
         
            +
                - !ruby/object:Gem::Version 
         
     | 
| 
      
 65 
     | 
    
         
            +
                  version: "0"
         
     | 
| 
      
 66 
     | 
    
         
            +
              version: 
         
     | 
| 
      
 67 
     | 
    
         
            +
            required_rubygems_version: !ruby/object:Gem::Requirement 
         
     | 
| 
      
 68 
     | 
    
         
            +
              requirements: 
         
     | 
| 
      
 69 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 70 
     | 
    
         
            +
                - !ruby/object:Gem::Version 
         
     | 
| 
      
 71 
     | 
    
         
            +
                  version: "0"
         
     | 
| 
      
 72 
     | 
    
         
            +
              version: 
         
     | 
| 
      
 73 
     | 
    
         
            +
            requirements: []
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
            rubyforge_project: 
         
     | 
| 
      
 76 
     | 
    
         
            +
            rubygems_version: 1.3.1
         
     | 
| 
      
 77 
     | 
    
         
            +
            signing_key: 
         
     | 
| 
      
 78 
     | 
    
         
            +
            specification_version: 2
         
     | 
| 
      
 79 
     | 
    
         
            +
            summary: Gem deployment tool
         
     | 
| 
      
 80 
     | 
    
         
            +
            test_files: []
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     |