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
|
+
|