taketo 0.0.10 → 0.1.0
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/Gemfile +1 -1
- data/Gemfile.lock +14 -30
- data/README.md +4 -0
- data/Rakefile +4 -8
- data/VERSION +1 -1
- data/bin/taketo +5 -5
- data/lib/taketo/config_printer_visitor.rb +6 -22
- data/lib/taketo/config_traverser.rb +4 -33
- data/lib/taketo/config_validator.rb +1 -1
- data/lib/taketo/config_visitor.rb +15 -1
- data/lib/taketo/constructs/base_construct.rb +30 -6
- data/lib/taketo/constructs/config.rb +5 -0
- data/lib/taketo/constructs/environment.rb +6 -3
- data/lib/taketo/constructs/project.rb +3 -3
- data/lib/taketo/constructs/server.rb +3 -4
- data/lib/taketo/constructs.rb +6 -1
- data/lib/taketo/destination_resolver.rb +37 -52
- data/lib/taketo/dsl.rb +6 -3
- data/lib/taketo/printer.rb +29 -0
- data/lib/taketo/ssh_config_generator_visitor.rb +8 -22
- data/spec/acceptance/command_spec.rb +20 -0
- data/spec/acceptance/config_dsl_spec.rb +277 -0
- data/spec/acceptance/config_validation_spec.rb +109 -0
- data/spec/acceptance/connect_to_server_spec.rb +60 -0
- data/spec/acceptance/error_handling_spec.rb +31 -0
- data/spec/acceptance/generate_ssh_config_spec.rb +44 -0
- data/spec/acceptance/help_spec.rb +74 -0
- data/spec/acceptance/location_spec.rb +21 -0
- data/spec/acceptance_spec_helper.rb +71 -0
- data/spec/lib/taketo/config_traverser_spec.rb +20 -33
- data/spec/lib/taketo/config_validator_spec.rb +4 -4
- data/spec/lib/taketo/config_visitor_spec.rb +0 -4
- data/spec/lib/taketo/constructs/base_construct_spec.rb +37 -5
- data/spec/lib/taketo/constructs/environment_spec.rb +1 -1
- data/spec/lib/taketo/constructs/project_spec.rb +0 -6
- data/spec/lib/taketo/constructs/server_spec.rb +1 -3
- data/spec/lib/taketo/destination_resolver_spec.rb +21 -54
- data/spec/lib/taketo/dsl_spec.rb +46 -44
- data/spec/spec_helper.rb +1 -1
- data/spec/support/helpers/construct_spec_helper.rb +29 -0
- metadata +94 -82
- data/features/commands.feature +0 -36
- data/features/config.feature +0 -177
- data/features/config_validation.feature +0 -43
- data/features/connect_to_server.feature +0 -87
- data/features/default_server_config.feature +0 -41
- data/features/error_handling.feature +0 -29
- data/features/generate_ssh_config.feature +0 -44
- data/features/help.feature +0 -76
- data/features/step_definitions/main_steps.rb +0 -16
- data/features/support/env.rb +0 -14
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,44 +1,28 @@
|
|
1
1
|
GEM
|
2
2
|
remote: http://rubygems.org/
|
3
3
|
specs:
|
4
|
-
aruba (0.4.11)
|
5
|
-
childprocess (>= 0.2.3)
|
6
|
-
cucumber (>= 1.1.1)
|
7
|
-
ffi (>= 1.0.11)
|
8
|
-
rspec (>= 2.7.0)
|
9
|
-
builder (3.0.0)
|
10
|
-
childprocess (0.3.2)
|
11
|
-
ffi (~> 1.0.6)
|
12
|
-
cucumber (1.2.1)
|
13
|
-
builder (>= 2.1.2)
|
14
|
-
diff-lcs (>= 1.1.3)
|
15
|
-
gherkin (~> 2.11.0)
|
16
|
-
json (>= 1.4.6)
|
17
4
|
diff-lcs (1.1.3)
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
rspec-mocks (~> 2.11.0)
|
28
|
-
rspec-core (2.11.1)
|
29
|
-
rspec-expectations (2.11.3)
|
5
|
+
multi_json (1.3.7)
|
6
|
+
open4 (1.3.0)
|
7
|
+
rake (0.9.5)
|
8
|
+
rspec (2.12.0)
|
9
|
+
rspec-core (~> 2.12.0)
|
10
|
+
rspec-expectations (~> 2.12.0)
|
11
|
+
rspec-mocks (~> 2.12.0)
|
12
|
+
rspec-core (2.12.0)
|
13
|
+
rspec-expectations (2.12.0)
|
30
14
|
diff-lcs (~> 1.1.3)
|
31
|
-
rspec-mocks (2.
|
32
|
-
simplecov (0.
|
15
|
+
rspec-mocks (2.12.0)
|
16
|
+
simplecov (0.7.1)
|
33
17
|
multi_json (~> 1.0)
|
34
|
-
simplecov-html (~> 0.
|
35
|
-
simplecov-html (0.
|
18
|
+
simplecov-html (~> 0.7.1)
|
19
|
+
simplecov-html (0.7.1)
|
36
20
|
|
37
21
|
PLATFORMS
|
38
22
|
ruby
|
39
23
|
|
40
24
|
DEPENDENCIES
|
41
|
-
|
25
|
+
open4 (~> 1.3)
|
42
26
|
rake (~> 0.9)
|
43
27
|
rspec (~> 2.11)
|
44
28
|
simplecov (~> 0.6)
|
data/README.md
CHANGED
@@ -144,6 +144,10 @@ An SSH config file can be generated from taketo config. To do so, run ```taketo
|
|
144
144
|
The Changelog:
|
145
145
|
--------------
|
146
146
|
|
147
|
+
### v0.1.0 (04.12.2012) ###
|
148
|
+
* Servers can now be outside projects and environments (userful for standalone servers)
|
149
|
+
* SSH config is being generated both for hostnames and global aliases
|
150
|
+
|
147
151
|
### v0.0.10 (17.11.2012) ###
|
148
152
|
* Add ability to generate ssh config
|
149
153
|
|
data/Rakefile
CHANGED
@@ -12,22 +12,18 @@ end
|
|
12
12
|
|
13
13
|
require 'rake'
|
14
14
|
require 'rspec/core/rake_task'
|
15
|
-
require 'cucumber'
|
16
|
-
require 'cucumber/rake/task'
|
17
15
|
|
18
16
|
RSpec::Core::RakeTask.new do |t|
|
19
17
|
t.pattern = 'spec/lib/**/*_spec.rb'
|
20
18
|
end
|
21
19
|
|
22
|
-
RSpec::Core::RakeTask.new do |t|
|
20
|
+
RSpec::Core::RakeTask.new(:integration_spec) do |t|
|
23
21
|
t.pattern = 'spec/integration/**/*_spec.rb'
|
24
|
-
t.name = :integration_spec
|
25
22
|
end
|
26
23
|
|
27
|
-
|
28
|
-
t.
|
29
|
-
t.fork = false
|
24
|
+
RSpec::Core::RakeTask.new(:acceptance_spec) do |t|
|
25
|
+
t.pattern = 'spec/acceptance/**/*_spec.rb'
|
30
26
|
end
|
31
27
|
|
32
|
-
task :default => [:spec, :
|
28
|
+
task :default => [:spec, :acceptance_spec]
|
33
29
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0
|
1
|
+
0.1.0
|
data/bin/taketo
CHANGED
@@ -1,9 +1,5 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
if ENV["TAKETO_DEV"]
|
4
|
-
$:.unshift(File.expand_path('../../lib', __FILE__))
|
5
|
-
end
|
6
|
-
|
7
3
|
require 'rubygems'
|
8
4
|
|
9
5
|
require 'taketo'
|
@@ -121,6 +117,10 @@ rescue SystemExit
|
|
121
117
|
# Do nothing
|
122
118
|
rescue Exception => e
|
123
119
|
STDERR.puts "An error occurred: #{e.message}"
|
124
|
-
|
120
|
+
if options && options[:debug]
|
121
|
+
STDERR.puts e.backtrace
|
122
|
+
raise
|
123
|
+
end
|
124
|
+
exit 1
|
125
125
|
end
|
126
126
|
|
@@ -1,16 +1,14 @@
|
|
1
1
|
require 'taketo/config_visitor'
|
2
|
+
require 'taketo/printer'
|
2
3
|
|
3
4
|
module Taketo
|
4
5
|
class ConfigPrinterVisitor < ConfigVisitor
|
5
|
-
|
6
|
-
@indent_level = 0
|
7
|
-
@result = ""
|
8
|
-
end
|
6
|
+
include Printer
|
9
7
|
|
10
8
|
visit Config do |config|
|
11
9
|
indent(0) do
|
12
10
|
if config.has_projects?
|
13
|
-
|
11
|
+
put_optional "Default destination:", config.default_destination
|
14
12
|
else
|
15
13
|
put "There are no projects yet..."
|
16
14
|
end
|
@@ -37,9 +35,9 @@ module Taketo
|
|
37
35
|
put "Server: #{server.name}"
|
38
36
|
indent do
|
39
37
|
put "Host: #{server.host}"
|
40
|
-
|
41
|
-
|
42
|
-
|
38
|
+
put_optional "Port:", server.port
|
39
|
+
put_optional "User:", server.username
|
40
|
+
put_optional "Default location:", server.default_location
|
43
41
|
put "Default command: #{server.default_command}"
|
44
42
|
put "Environment: " + server.environment_variables.map { |n, v| "#{n}=#{v}" }.join(" ")
|
45
43
|
put "Commands:" if server.has_commands?
|
@@ -50,20 +48,6 @@ module Taketo
|
|
50
48
|
visit Command do |command|
|
51
49
|
indent(4) { put command.name.to_s + (" - " + command.description if command.description).to_s }
|
52
50
|
end
|
53
|
-
|
54
|
-
def result
|
55
|
-
@result.chomp
|
56
|
-
end
|
57
|
-
|
58
|
-
def indent(level = nil)
|
59
|
-
@first_indent ||= level || @indent_level
|
60
|
-
level ? @indent_level = level - @first_indent : @indent_level += 1
|
61
|
-
yield
|
62
|
-
end
|
63
|
-
|
64
|
-
def put(str = nil)
|
65
|
-
@result += (" " * @indent_level + str.to_s).rstrip.chomp + "\n"
|
66
|
-
end
|
67
51
|
end
|
68
52
|
end
|
69
53
|
|
@@ -3,53 +3,24 @@ require 'forwardable'
|
|
3
3
|
|
4
4
|
module Taketo
|
5
5
|
class ConfigTraverser
|
6
|
-
LEVELS = { :config => 1, :project => 2, :environment => 3, :server => 4, :command => 5 }.freeze
|
7
|
-
PLURALS = { :config => :configs, :project => :projects, :environment => :environments, :server => :servers, :command => :commands }.freeze
|
8
|
-
|
9
|
-
class NodeWithPath < SimpleDelegator
|
10
|
-
extend Forwardable
|
11
|
-
def_delegators :__getobj__, :class, :ancestors, :== # avoid ancestry tree troubles
|
12
|
-
|
13
|
-
attr_reader :path
|
14
|
-
|
15
|
-
def initialize(node, path_string)
|
16
|
-
super(node)
|
17
|
-
@path = path_string.freeze
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
6
|
def initialize(root)
|
22
7
|
@root = root
|
23
8
|
end
|
24
9
|
|
25
10
|
def visit_depth_first(visitor)
|
26
|
-
|
27
|
-
path_stack = [wrap_node_with_path(parents, @root)]
|
11
|
+
path_stack = [@root]
|
28
12
|
|
29
13
|
while path_stack.any?
|
30
14
|
node = path_stack.pop
|
31
15
|
visitor.visit(node)
|
32
16
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
node.nodes(PLURALS[next_level_node_type]).reverse_each do |n|
|
37
|
-
n = wrap_node_with_path(parents, n)
|
38
|
-
path_stack.push(n)
|
17
|
+
node.class.node_types.each do |node_type|
|
18
|
+
node.nodes(node_type).reverse_each do |n|
|
19
|
+
path_stack.push(n)
|
39
20
|
end
|
40
21
|
end
|
41
22
|
end
|
42
23
|
end
|
43
|
-
|
44
|
-
private
|
45
|
-
|
46
|
-
def wrap_node_with_path(parents, node)
|
47
|
-
NodeWithPath.new(node, path(parents, node))
|
48
|
-
end
|
49
|
-
|
50
|
-
def path(parents, node)
|
51
|
-
parents.map(&:name).reject(&:nil?).concat([node.name]).join(":")
|
52
|
-
end
|
53
24
|
end
|
54
25
|
end
|
55
26
|
|
@@ -10,7 +10,7 @@ module Taketo
|
|
10
10
|
end
|
11
11
|
|
12
12
|
visit Config do |c|
|
13
|
-
raise ConfigError, "There are no
|
13
|
+
raise ConfigError, "There are no servers. Add some to your config (~/.taketo.rc.rb by default)" unless c.has_servers?
|
14
14
|
end
|
15
15
|
|
16
16
|
visit Project do |p|
|
@@ -21,8 +21,22 @@ module Taketo
|
|
21
21
|
next unless respond_to?(method_name)
|
22
22
|
return send(method_name, obj)
|
23
23
|
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def SimpleCollector(*types)
|
28
|
+
Class.new(ConfigVisitor) do
|
29
|
+
attr_reader :result
|
24
30
|
|
25
|
-
|
31
|
+
def initialize
|
32
|
+
@result = []
|
33
|
+
end
|
34
|
+
|
35
|
+
types.each do |t|
|
36
|
+
visit t do |n|
|
37
|
+
@result << n
|
38
|
+
end
|
39
|
+
end
|
26
40
|
end
|
27
41
|
end
|
28
42
|
end
|
@@ -4,14 +4,17 @@ require 'taketo/associated_nodes'
|
|
4
4
|
module Taketo
|
5
5
|
module Constructs
|
6
6
|
class BaseConstruct
|
7
|
-
|
8
7
|
include AssociatedNodes
|
9
|
-
|
8
|
+
|
9
|
+
attr_accessor :parent
|
10
|
+
attr_reader :name
|
11
|
+
attr_writer :default_server_config
|
10
12
|
|
11
13
|
def initialize(name)
|
12
14
|
super
|
13
15
|
@name = name
|
14
16
|
@default_server_config = proc {}
|
17
|
+
@parent = NullConstruct
|
15
18
|
end
|
16
19
|
|
17
20
|
def node_type
|
@@ -22,19 +25,40 @@ module Taketo
|
|
22
25
|
##
|
23
26
|
# Override in subclasses if needed
|
24
27
|
def parent=(parent)
|
25
|
-
@
|
28
|
+
@parent = parent
|
26
29
|
end
|
27
30
|
|
28
|
-
def
|
29
|
-
|
30
|
-
|
31
|
+
def parents
|
32
|
+
result = []
|
33
|
+
p = parent
|
34
|
+
while p != NullConstruct
|
35
|
+
result << p
|
36
|
+
p = p.parent
|
37
|
+
end
|
38
|
+
result
|
39
|
+
end
|
40
|
+
|
41
|
+
def path
|
42
|
+
parents.reverse_each.map(&:name).concat([self.name]).reject(&:nil?).join(":")
|
43
|
+
end
|
44
|
+
|
45
|
+
def default_server_config
|
46
|
+
parent_default_server_config = parent.default_server_config
|
47
|
+
own_default_server_config = @default_server_config
|
48
|
+
proc { instance_eval(&parent_default_server_config); instance_eval(&own_default_server_config)}
|
31
49
|
end
|
32
50
|
|
33
51
|
def qualified_name
|
34
52
|
"#{node_type} #{self.name}"
|
35
53
|
end
|
54
|
+
end
|
36
55
|
|
56
|
+
class NullConstructClass
|
57
|
+
def default_server_config; proc {}; end
|
37
58
|
end
|
59
|
+
|
60
|
+
NullConstruct = NullConstructClass.new
|
61
|
+
|
38
62
|
end
|
39
63
|
end
|
40
64
|
|
@@ -5,12 +5,17 @@ module Taketo
|
|
5
5
|
module Constructs
|
6
6
|
class Config < BaseConstruct
|
7
7
|
has_nodes :projects, :project
|
8
|
+
has_nodes :servers, :server
|
8
9
|
|
9
10
|
attr_accessor :default_destination
|
10
11
|
|
11
12
|
def initialize(*args)
|
12
13
|
super(nil)
|
13
14
|
end
|
15
|
+
|
16
|
+
def has_servers?
|
17
|
+
has_nodes?(:servers) || projects.any?(&:has_servers?)
|
18
|
+
end
|
14
19
|
end
|
15
20
|
end
|
16
21
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'taketo/constructs/base_construct'
|
2
|
+
require 'taketo/constructs/project'
|
2
3
|
require 'taketo/support'
|
3
4
|
|
4
5
|
module Taketo
|
@@ -6,14 +7,16 @@ module Taketo
|
|
6
7
|
class Environment < BaseConstruct
|
7
8
|
has_nodes :servers, :server
|
8
9
|
|
9
|
-
attr_accessor :project
|
10
|
-
|
11
10
|
def initialize(name)
|
12
11
|
super(name)
|
13
12
|
end
|
14
13
|
|
15
14
|
def project_name
|
16
|
-
|
15
|
+
if parent.is_a?(Project)
|
16
|
+
parent.name
|
17
|
+
else
|
18
|
+
""
|
19
|
+
end
|
17
20
|
end
|
18
21
|
end
|
19
22
|
end
|
@@ -5,10 +5,10 @@ module Taketo
|
|
5
5
|
module Constructs
|
6
6
|
class Project < BaseConstruct
|
7
7
|
has_nodes :environments, :environment
|
8
|
+
has_nodes :servers, :server
|
8
9
|
|
9
|
-
def
|
10
|
-
|
11
|
-
super
|
10
|
+
def has_servers?
|
11
|
+
has_nodes?(:servers) || environments.any?(&:has_servers?)
|
12
12
|
end
|
13
13
|
end
|
14
14
|
end
|
@@ -6,7 +6,7 @@ module Taketo
|
|
6
6
|
module Constructs
|
7
7
|
class Server < BaseConstruct
|
8
8
|
attr_reader :environment_variables
|
9
|
-
attr_accessor :host, :port, :username, :default_location, :default_command, :
|
9
|
+
attr_accessor :host, :port, :username, :default_location, :default_command, :global_alias, :identity_file
|
10
10
|
|
11
11
|
has_nodes :commands, :command
|
12
12
|
|
@@ -19,10 +19,9 @@ module Taketo
|
|
19
19
|
@environment_variables.merge!(env_variables)
|
20
20
|
end
|
21
21
|
|
22
|
-
def parent=(
|
23
|
-
env(:RAILS_ENV => environment.name.to_s)
|
24
|
-
@environment = environment
|
22
|
+
def parent=(parent)
|
25
23
|
super
|
24
|
+
env(:RAILS_ENV => parent.name.to_s) if parent.is_a?(Environment)
|
26
25
|
end
|
27
26
|
|
28
27
|
def default_command
|
data/lib/taketo/constructs.rb
CHANGED
@@ -3,4 +3,9 @@ module Taketo
|
|
3
3
|
end
|
4
4
|
end
|
5
5
|
|
6
|
-
|
6
|
+
require 'taketo/constructs/base_construct'
|
7
|
+
require 'taketo/constructs/config'
|
8
|
+
require 'taketo/constructs/project'
|
9
|
+
require 'taketo/constructs/environment'
|
10
|
+
require 'taketo/constructs/server'
|
11
|
+
require 'taketo/constructs/command'
|
@@ -1,81 +1,66 @@
|
|
1
|
+
require 'taketo/config_visitor'
|
2
|
+
require 'taketo/config_traverser'
|
3
|
+
|
1
4
|
module Taketo
|
2
5
|
class AmbiguousDestinationError < StandardError; end
|
3
6
|
class NonExistentDestinationError < StandardError; end
|
4
7
|
|
5
8
|
class DestinationResolver
|
6
|
-
class Path
|
7
|
-
PATH = [[:project, :projects], [:environment, :environments], [:server, :servers]].freeze
|
8
|
-
|
9
|
-
class PathNode < Struct.new(:name, :singular, :plural); end
|
10
|
-
|
11
|
-
def initialize(names)
|
12
|
-
names = names.split(":").map(&:to_sym)
|
13
|
-
@path = PATH.each_with_index.map { |n, i| PathNode.new(names[i], *n) }
|
14
|
-
end
|
15
|
-
|
16
|
-
def specified
|
17
|
-
@path.reject { |n| n.name.nil? }
|
18
|
-
end
|
19
|
-
|
20
|
-
def unspecified
|
21
|
-
@path - specified
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
9
|
def initialize(config, path)
|
26
10
|
@config = config
|
27
11
|
if String(path).empty? && !String(config.default_destination).empty?
|
28
12
|
path = config.default_destination
|
29
13
|
end
|
30
|
-
@
|
31
|
-
@
|
14
|
+
@path = path
|
15
|
+
@traverser = ConfigTraverser.new(@config)
|
32
16
|
end
|
33
17
|
|
34
|
-
def
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
handling_failure do
|
40
|
-
return node if remaining_path.empty?
|
41
|
-
next_in_path = remaining_path.shift
|
42
|
-
node = node.find(next_in_path.singular, next_in_path.name)
|
43
|
-
get_node(node, remaining_path)
|
18
|
+
def servers
|
19
|
+
@servers ||= begin
|
20
|
+
collector = SimpleCollector(Taketo::Constructs::Server).new
|
21
|
+
@traverser.visit_depth_first(collector)
|
22
|
+
collector.result
|
44
23
|
end
|
45
24
|
end
|
46
25
|
|
47
|
-
|
26
|
+
def resolve
|
27
|
+
resolve_by_global_alias || resolve_by_path
|
28
|
+
end
|
48
29
|
|
49
30
|
def resolve_by_global_alias
|
50
|
-
|
51
|
-
|
31
|
+
unless @path.to_s.empty?
|
32
|
+
servers.select(&:global_alias).detect { |s| s.global_alias == @path.to_sym }
|
33
|
+
end
|
52
34
|
end
|
53
35
|
|
54
36
|
def resolve_by_path
|
55
|
-
|
56
|
-
|
37
|
+
matching_servers = servers.select { |s| s.path =~ /^#@path/ }
|
38
|
+
disambiguate(matching_servers)
|
57
39
|
end
|
58
40
|
|
59
|
-
def
|
60
|
-
|
61
|
-
|
62
|
-
nested_nodes = node.nodes(next_in_path.plural)
|
63
|
-
if nested_nodes.one?
|
64
|
-
node = nested_nodes.first
|
65
|
-
get_only_server(node, remaining_path)
|
66
|
-
else
|
67
|
-
raise AmbiguousDestinationError, "There are multiple #{next_in_path.plural} for #{node.node_type} #{node.name}: #{nested_nodes.map(&:name).join(", ")}"
|
68
|
-
end
|
41
|
+
def get_node
|
42
|
+
matching_nodes = nodes.select { |n| n.path == @path }
|
43
|
+
disambiguate(matching_nodes)
|
69
44
|
end
|
70
45
|
|
71
|
-
def
|
72
|
-
|
73
|
-
|
74
|
-
|
46
|
+
def nodes
|
47
|
+
@nodes ||= begin
|
48
|
+
collector = SimpleCollector(Taketo::Constructs::BaseConstruct).new
|
49
|
+
@traverser.visit_depth_first(collector)
|
50
|
+
collector.result
|
51
|
+
end
|
75
52
|
end
|
76
53
|
|
77
|
-
def
|
78
|
-
|
54
|
+
def disambiguate(results)
|
55
|
+
case results.length
|
56
|
+
when 0
|
57
|
+
raise NonExistentDestinationError, "Can't find server for path #@path"
|
58
|
+
when 1
|
59
|
+
results.first
|
60
|
+
else
|
61
|
+
raise AmbiguousDestinationError,
|
62
|
+
"There are multiple possible destinations: #{results.map(&:path).join(", ")}"
|
63
|
+
end
|
79
64
|
end
|
80
65
|
end
|
81
66
|
end
|
data/lib/taketo/dsl.rb
CHANGED
@@ -6,9 +6,12 @@ module Taketo
|
|
6
6
|
class ConfigError < StandardError; end
|
7
7
|
|
8
8
|
class << self
|
9
|
-
def define_scope(scope,
|
9
|
+
def define_scope(scope, *args, &block)
|
10
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
11
|
+
parent_scopes = args
|
12
|
+
|
10
13
|
define_method scope do |*args, &blk|
|
11
|
-
ensure_nesting_allowed!(scope,
|
14
|
+
ensure_nesting_allowed!(scope, parent_scopes)
|
12
15
|
name = args.shift || options[:default_name] or raise(ArgumentError, "Name not specified")
|
13
16
|
|
14
17
|
scope_object = current_scope_object.find(scope, name) { @factory.create(scope, name) }
|
@@ -54,7 +57,7 @@ module Taketo
|
|
54
57
|
define_scope :project, :config
|
55
58
|
define_scope :environment, :project
|
56
59
|
|
57
|
-
define_scope :server, :environment, :default_name => :default do |s|
|
60
|
+
define_scope :server, :environment, :project, :config, :default_name => :default do |s|
|
58
61
|
instance_eval(&s.default_server_config)
|
59
62
|
end
|
60
63
|
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Taketo
|
2
|
+
module Printer
|
3
|
+
def initialize
|
4
|
+
@indent_level = 0
|
5
|
+
@print_result = ""
|
6
|
+
end
|
7
|
+
|
8
|
+
def result
|
9
|
+
@print_result.chomp
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def indent(level = nil)
|
15
|
+
@first_indent ||= level || @indent_level
|
16
|
+
level ? @indent_level = level - @first_indent : @indent_level += 1
|
17
|
+
yield
|
18
|
+
end
|
19
|
+
|
20
|
+
def put(str = nil)
|
21
|
+
@print_result += (" " * @indent_level + str.to_s).rstrip.chomp + "\n"
|
22
|
+
end
|
23
|
+
|
24
|
+
def put_optional(str, value)
|
25
|
+
put "#{str} #{value}" if value
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
@@ -1,36 +1,22 @@
|
|
1
1
|
require 'taketo/config_visitor'
|
2
|
+
require 'taketo/printer'
|
2
3
|
|
3
4
|
module Taketo
|
4
5
|
class SSHConfigGeneratorVisitor < ConfigVisitor
|
5
|
-
|
6
|
-
@result = ""
|
7
|
-
end
|
6
|
+
include Printer
|
8
7
|
|
9
8
|
visit Server do |server|
|
10
|
-
|
9
|
+
put_server(server, server.global_alias) unless server.global_alias.to_s.empty?
|
10
|
+
put_server(server, server.host)
|
11
|
+
end
|
12
|
+
|
13
|
+
def put_server(server, host)
|
14
|
+
put "Host #{host}"
|
11
15
|
put "Hostname #{server.host}"
|
12
16
|
put_optional "Port", server.port
|
13
17
|
put_optional "User", server.username
|
14
18
|
put_optional "IdentityFile", server.identity_file
|
15
19
|
put
|
16
20
|
end
|
17
|
-
|
18
|
-
visit Object do |_|
|
19
|
-
# catch all
|
20
|
-
end
|
21
|
-
|
22
|
-
def result
|
23
|
-
@result.chomp
|
24
|
-
end
|
25
|
-
|
26
|
-
private
|
27
|
-
|
28
|
-
def put(str = "")
|
29
|
-
@result += str + "\n"
|
30
|
-
end
|
31
|
-
|
32
|
-
def put_optional(str, value)
|
33
|
-
put "#{str} #{value}" if value
|
34
|
-
end
|
35
21
|
end
|
36
22
|
end
|