scatter 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|