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
@@ -1,62 +1,49 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require 'support/helpers/construct_spec_helper'
|
2
3
|
require 'taketo/config_traverser'
|
3
4
|
|
4
|
-
# config 1
|
5
|
-
# / \
|
6
|
-
# project 1 2
|
5
|
+
# config 1--
|
6
|
+
# / \ \
|
7
|
+
# project 1 2 server_3
|
7
8
|
# / \
|
8
9
|
# environment 1 2
|
9
10
|
# /|\
|
10
11
|
# server 1 2 3
|
11
12
|
|
12
13
|
describe Taketo::ConfigTraverser do
|
13
|
-
|
14
|
-
let(:server_2) { stub(:Server2, :node_type => :server, :name => :server_2).as_null_object }
|
15
|
-
let(:server_3) { stub(:Server3, :node_type => :server, :name => :server_3).as_null_object }
|
14
|
+
include ConstructsFixtures
|
16
15
|
|
17
|
-
let(:
|
18
|
-
let(:
|
16
|
+
let(:server_1) { server(:Server1) }
|
17
|
+
let(:server_2) { server(:Server2) }
|
18
|
+
let(:server_3) { server(:Server3) }
|
19
19
|
|
20
|
-
let(:
|
21
|
-
let(:
|
20
|
+
let(:environment_1) { environment(:Environment1) }
|
21
|
+
let(:environment_2) { environment(:Environment2, :servers => [server_1, server_2]) }
|
22
22
|
|
23
|
-
let(:
|
23
|
+
let(:project_1) { project(:Project1, :environments => [environment_1, environment_2]) }
|
24
|
+
let(:project_2) { project(:Project2) }
|
24
25
|
|
25
|
-
let(:
|
26
|
-
|
27
|
-
before do
|
28
|
-
config.stub(:has_nodes?).with(:projects).and_return(true)
|
29
|
-
config.stub(:nodes).with(:projects).and_return([project_1, project_2])
|
30
|
-
|
31
|
-
project_1.stub(:has_nodes?).with(:environments).and_return(true)
|
32
|
-
project_1.stub(:nodes).with(:environments).and_return([environment_1, environment_2])
|
33
|
-
|
34
|
-
project_2.stub(:has_nodes?).with(:environments).and_return(false)
|
35
|
-
project_2.should_not_receive(:nodes)
|
26
|
+
let(:config) { create_config(:projects => [project_1, project_2], :servers => server_3) }
|
36
27
|
|
37
|
-
|
38
|
-
environment_1.should_not_receive(:nodes)
|
39
|
-
|
40
|
-
environment_2.stub(:has_nodes?).with(:servers).and_return(true)
|
41
|
-
environment_2.stub(:nodes).and_return([server_1, server_2, server_3])
|
42
|
-
end
|
28
|
+
let(:traverser) { described_class.new(config) }
|
43
29
|
|
44
30
|
class PrintingVisitor
|
31
|
+
attr_reader :result
|
32
|
+
|
45
33
|
def initialize
|
46
34
|
@result = []
|
47
35
|
end
|
48
36
|
|
49
|
-
def visit(
|
37
|
+
def visit(node)
|
38
|
+
@result << node.name
|
50
39
|
end
|
51
40
|
end
|
52
41
|
|
53
42
|
describe "#visit_depth_first" do
|
54
43
|
it "traverses in depth with visitor" do
|
55
|
-
visitor =
|
56
|
-
[config, project_1, environment_1, environment_2, server_1, server_2, server_3, project_2].each do |node|
|
57
|
-
visitor.should_receive(:visit).with(node).ordered
|
58
|
-
end
|
44
|
+
visitor = PrintingVisitor.new
|
59
45
|
traverser.visit_depth_first(visitor)
|
46
|
+
visitor.result.should == [config, server_3, project_1, environment_1, environment_2, server_1, server_2, project_2].map(&:name)
|
60
47
|
end
|
61
48
|
end
|
62
49
|
end
|
@@ -18,12 +18,12 @@ end
|
|
18
18
|
describe "ConfigValidator::ConfigValidatorVisitor" do
|
19
19
|
subject(:visitor) { ConfigValidator::ConfigValidatorVisitor.new }
|
20
20
|
|
21
|
-
it "requires config to have
|
22
|
-
config = stub(:Config, :
|
23
|
-
error_message = /no
|
21
|
+
it "requires config to have servers" do
|
22
|
+
config = stub(:Config, :has_servers? => false)
|
23
|
+
error_message = /no servers/
|
24
24
|
expect { visitor.visit_config(config) }.to raise_error ConfigError, error_message
|
25
25
|
|
26
|
-
config.stub(:
|
26
|
+
config.stub(:has_servers? => true)
|
27
27
|
expect { visitor.visit_config(config) }.not_to raise_error ConfigError, error_message
|
28
28
|
end
|
29
29
|
|
@@ -16,15 +16,47 @@ describe "BaseConstruct" do
|
|
16
16
|
expect(construct.qualified_name).to eq('test_base_construct my_node')
|
17
17
|
end
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
19
|
+
describe "#parent=" do
|
20
|
+
it "stores parent" do
|
21
|
+
parent = stub
|
22
|
+
construct.parent = parent
|
23
|
+
construct.parent.should == parent
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
shared_context "parents" do
|
28
|
+
let(:grand_parent) { TestBaseConstruct.new(:grand_parent) }
|
29
|
+
let(:parent) { TestBaseConstruct.new(:parent) }
|
30
|
+
|
31
|
+
before(:each) do
|
32
|
+
parent.parent = grand_parent
|
33
|
+
construct.parent = parent
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "#parents" do
|
38
|
+
include_context "parents"
|
39
|
+
|
40
|
+
it "returns parent nodes up until NullConstruct" do
|
41
|
+
expect(construct.parents).to eq([parent, grand_parent])
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
specify "#parents returns an empty array if there are no parents" do
|
46
|
+
expect(construct.parents).to eq([])
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "#path" do
|
50
|
+
include_context "parents"
|
51
|
+
|
52
|
+
it "returns names of parents separated by :" do
|
53
|
+
expect(construct.path).to eq("grand_parent:parent:my_node")
|
54
|
+
end
|
23
55
|
end
|
24
56
|
|
25
57
|
describe "#default_server_config=" do
|
26
58
|
let(:default_server_config) { proc { call_from_self } }
|
27
|
-
let(:context) { stub }
|
59
|
+
let(:context) { stub(:Context) }
|
28
60
|
|
29
61
|
it "sets default server config" do
|
30
62
|
construct.default_server_config = default_server_config
|
@@ -14,7 +14,7 @@ describe "Environment" do
|
|
14
14
|
it_behaves_like "a construct with nodes", :servers, :server
|
15
15
|
|
16
16
|
specify "#project_name returns project name" do
|
17
|
-
environment.
|
17
|
+
environment.parent = Taketo::Constructs::Project.new("TheProject")
|
18
18
|
expect(environment.project_name).to eq("TheProject")
|
19
19
|
end
|
20
20
|
end
|
@@ -11,12 +11,6 @@ describe "Project" do
|
|
11
11
|
expect(project.name).to eq(:foo)
|
12
12
|
end
|
13
13
|
|
14
|
-
specify "#append_environment sets project attribute on an environment to self" do
|
15
|
-
environment = mock(:Environment, :name => :bar)
|
16
|
-
environment.should_receive(:project=).with(project)
|
17
|
-
project.append_environment(environment)
|
18
|
-
end
|
19
|
-
|
20
14
|
it_behaves_like "a construct with nodes", :environments, :environment
|
21
15
|
end
|
22
16
|
|
@@ -48,9 +48,7 @@ describe "Server" do
|
|
48
48
|
end
|
49
49
|
|
50
50
|
describe "#parent=" do
|
51
|
-
let(:environment) { environment =
|
52
|
-
|
53
|
-
it { should have_accessor(:environment, environment) }
|
51
|
+
let(:environment) { environment = Taketo::Constructs::Environment.new(:the_environment) }
|
54
52
|
|
55
53
|
it "sets RAILS_ENV environment variable" do
|
56
54
|
server.environment_variables.should == {}
|
@@ -1,53 +1,31 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require 'support/helpers/construct_spec_helper'
|
2
3
|
require 'taketo/destination_resolver'
|
3
4
|
require 'taketo/support/named_nodes_collection'
|
4
5
|
|
5
6
|
include Taketo
|
6
7
|
|
7
8
|
describe "DestinationResolver" do
|
8
|
-
|
9
|
-
attr_reader :name, :node_type
|
10
|
-
def initialize(node_type, name, *nodes)
|
11
|
-
@node_type, @name, @nodes = node_type, name, nodes
|
12
|
-
end
|
13
|
-
|
14
|
-
def find(type, name)
|
15
|
-
@nodes.detect { |s| s.name == name } or raise KeyError, name.to_s
|
16
|
-
end
|
17
|
-
|
18
|
-
def nodes(type)
|
19
|
-
@nodes
|
20
|
-
end
|
21
|
-
|
22
|
-
def global_alias
|
23
|
-
:the_alias if name == :s1 && node_type == :server
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
[:project, :environment, :server].each do |node_type|
|
28
|
-
define_method node_type do |name, *nodes|
|
29
|
-
TestNode.new(node_type, name, *nodes)
|
30
|
-
end
|
31
|
-
end
|
9
|
+
include ConstructsFixtures
|
32
10
|
|
33
|
-
let(:server1) { server(:s1) }
|
34
|
-
let(:environment1) { environment(:bar, server1) }
|
35
|
-
let(:project1) { project(:foo, environment1) }
|
11
|
+
let(:server1) { s = server(:s1); s.global_alias = :the_alias; s }
|
12
|
+
let(:environment1) { environment(:bar, :servers => server1) }
|
13
|
+
let(:project1) { project(:foo, :environments => environment1) }
|
36
14
|
|
37
15
|
let(:server2) { server(:s2) }
|
38
|
-
let(:environment2) { environment(:qux, server2) }
|
39
|
-
let(:project2) { project(:baz, environment2) }
|
16
|
+
let(:environment2) { environment(:qux, :servers => server2) }
|
17
|
+
let(:project2) { project(:baz, :environments => environment2) }
|
40
18
|
|
41
19
|
let(:server3) { server(:s3) }
|
42
20
|
let(:server4) { server(:s4) }
|
43
|
-
let(:environment3) { environment(:corge, server3, server4) }
|
44
|
-
let(:project3) {
|
21
|
+
let(:environment3) { environment(:corge, :servers => [server3, server4]) }
|
22
|
+
let(:project3) { project(:quux, :environments => environment3) }
|
45
23
|
|
46
|
-
let(:environment4) { environment(:garply, server(:s5), server(:s6)) }
|
47
|
-
let(:environment5) { environment(:waldo, server(:s7)) }
|
48
|
-
let(:project4) { project(:grault, environment4, environment5) }
|
24
|
+
let(:environment4) { environment(:garply, :servers => [server(:s5), server(:s6)]) }
|
25
|
+
let(:environment5) { environment(:waldo, :servers => server(:s7)) }
|
26
|
+
let(:project4) { project(:grault, :environments => [environment4, environment5]) }
|
49
27
|
|
50
|
-
let(:config) {
|
28
|
+
let(:config) { create_config(:projects => [project1, project2, project3, project4]) }
|
51
29
|
|
52
30
|
context "when project, environment and server specified" do
|
53
31
|
it "returns server if it exists" do
|
@@ -114,43 +92,38 @@ describe "DestinationResolver" do
|
|
114
92
|
context "when there's one environment" do
|
115
93
|
context "when there's one server" do
|
116
94
|
it "executes command without asking project/environment/server" do
|
117
|
-
config =
|
118
|
-
config.stub(:default_destination => nil)
|
95
|
+
config = create_config(:projects => project1)
|
119
96
|
expect(resolver(config, "").resolve).to eq(server1)
|
120
97
|
end
|
121
98
|
end
|
122
99
|
|
123
100
|
context "when there are multiple servers" do
|
124
101
|
it "asks for server" do
|
125
|
-
config =
|
126
|
-
config.
|
127
|
-
expect { resolver(config, "").resolve }.to raise_error AmbiguousDestinationError, /server/i
|
102
|
+
config = create_config(:projects => project3)
|
103
|
+
expect { resolver(config, "").resolve }.to raise_error AmbiguousDestinationError, /s3.*s4/i
|
128
104
|
end
|
129
105
|
end
|
130
106
|
end
|
131
107
|
|
132
108
|
context "when there are multiple environments" do
|
133
109
|
it "asks for environment" do
|
134
|
-
config =
|
135
|
-
config.
|
136
|
-
expect { resolver(config, "").resolve }.to raise_error AmbiguousDestinationError, /environment/i
|
110
|
+
config = create_config(:projects => project4)
|
111
|
+
expect { resolver(config, "").resolve }.to raise_error AmbiguousDestinationError, /garply:s5.*garply:s6.*waldo:s7/i
|
137
112
|
end
|
138
113
|
end
|
139
114
|
end
|
140
115
|
|
141
116
|
context "when there are multiple projects" do
|
142
117
|
it "asks for project" do
|
143
|
-
config =
|
144
|
-
config.
|
145
|
-
|
146
|
-
expect { resolver(config, "").resolve }.to raise_error AmbiguousDestinationError, /projects/i
|
118
|
+
config = create_config(:projects => [project3, project4])
|
119
|
+
expect { resolver(config, "").resolve }.to raise_error AmbiguousDestinationError, /corge:s3.*corge:s4.*garply:s5.*garply:s6.*waldo:s7/i
|
147
120
|
end
|
148
121
|
end
|
149
122
|
end
|
150
123
|
|
151
124
|
context "when there is default destination" do
|
152
125
|
it "resolves by default destination" do
|
153
|
-
config.
|
126
|
+
config.default_destination = "foo:bar:s1"
|
154
127
|
expect(resolver(config, "").resolve).to eq(server1)
|
155
128
|
end
|
156
129
|
end
|
@@ -176,12 +149,10 @@ describe "DestinationResolver" do
|
|
176
149
|
end
|
177
150
|
|
178
151
|
it "returns the config if path has is empty and there's no default destination" do
|
179
|
-
config.stub(:default_destination => nil)
|
180
152
|
expect(resolver(config, "").get_node).to eq(config)
|
181
153
|
end
|
182
154
|
|
183
155
|
it "raises NonExistentDestinationError when path is not correct" do
|
184
|
-
config.should_receive(:find).with(:project, :i).and_raise(KeyError)
|
185
156
|
expect { resolver(config, "i").get_node }.to raise_error(NonExistentDestinationError)
|
186
157
|
end
|
187
158
|
end
|
@@ -190,9 +161,5 @@ describe "DestinationResolver" do
|
|
190
161
|
DestinationResolver.new(*args)
|
191
162
|
end
|
192
163
|
|
193
|
-
def list(*items)
|
194
|
-
Taketo::Support::NamedNodesCollection.new(items)
|
195
|
-
end
|
196
|
-
|
197
164
|
end
|
198
165
|
|
data/spec/lib/taketo/dsl_spec.rb
CHANGED
@@ -21,49 +21,51 @@ describe "DSL" do
|
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
-
shared_examples "a scope" do |scope_name,
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
24
|
+
shared_examples "a scope" do |scope_name, parent_scope_names|
|
25
|
+
it_behaves_like "a scoped construct", scope_name, Array(parent_scope_names), true
|
26
|
+
|
27
|
+
Array(parent_scope_names).each do |parent_scope_name|
|
28
|
+
parent_scope = scopes[parent_scope_name]
|
29
|
+
|
30
|
+
it { should enclose_scope(scope_name).under(parent_scope) }
|
31
|
+
|
32
|
+
it "creates a #{scope_name} and set it as current scope object" do # it "creates project and set it as current scope object"
|
33
|
+
dsl(parent_scope, factory.create(parent_scope_name)) do |c| # dsl([:config], factory.create(:config)) do |c|
|
34
|
+
stub_find_or_create_scope_object(c, scope_name, :bar) # stub_find_or_create_scope_object(c, :project, :bar)
|
35
|
+
c.send(scope_name, :bar) do # c.project(:bar) do
|
36
|
+
expect(c.current_scope_object).not_to be_nil # expect(c.current_scope_object).not_to be_nil
|
37
|
+
expect(c.current_scope_object).to eq(factory.send(scope_name)) # expect(c.current_scope_object).to eq(factory.project)
|
38
|
+
end # end
|
39
|
+
end # end
|
40
|
+
end # end
|
41
|
+
|
42
|
+
it "does not leak #{scope_name} as current scope object" do # it "does not leak project as current scope object"
|
43
|
+
dsl(parent_scope, factory.create(parent_scope_name)) do |c| # dsl([:config], factory.create(:config)) do |c|
|
44
|
+
stub_find_or_create_scope_object(c, scope_name, :bar) # stub_find_or_create_scope_object(c, :project, :bar)
|
45
|
+
c.send(scope_name, :bar) do # c.project(:bar) do
|
46
|
+
expect(c.current_scope_object).to eq(factory.send(scope_name)) # expect(c.current_scope_object).to eq(factory.project)
|
47
|
+
end # end
|
48
|
+
expect(c.current_scope_object).not_to eq(factory.send(scope_name)) # expect(c.current_scope_object).not_to eq(factory.project)
|
49
|
+
end # end
|
50
|
+
end # end
|
51
|
+
|
52
|
+
it "adds a #{scope_name} to the #{parent_scope_name}'s #{scope_name}s collection" do # it "adds a project to the config's projects collection" do
|
53
|
+
dsl(parent_scope, factory.create(parent_scope_name)) do |c| # dsl([:config], factory.create(:config)) do |c|
|
54
|
+
stub_find_or_create_scope_object(c, scope_name, :bar) # stub_find_or_create_scope_object(c, :project, :bar)
|
55
|
+
c.current_scope_object.should_receive("append_#{scope_name}"). # c.current_scope_object.should_receive(:append_project).
|
56
|
+
with(factory.send(scope_name)) # with(factory.project)
|
57
|
+
c.send(scope_name, :bar) {} # c.project(:bar) {}
|
58
|
+
end # end
|
59
|
+
end # end
|
60
|
+
|
61
|
+
it "sets #{scope_name}'s parent to the #{parent_scope_name} scope object" do # it "sets project's parent to the config scope object" do
|
62
|
+
dsl(parent_scope, factory.create(parent_scope_name)) do |c| # dsl([:config], factory.create(:config)) do |c|
|
63
|
+
stub_find_or_create_scope_object(c, scope_name, :bar) # stub_find_or_create_scope_object(c, :project, :bar)
|
64
|
+
factory.send(scope_name).should_receive(:parent=).with(c.current_scope_object) # factory.project.should_receive(:parent=).with(c.current_scope_object)
|
65
|
+
c.send(scope_name, :bar) {} # c.project(:bar) {}
|
66
|
+
end # end
|
67
|
+
end #
|
68
|
+
end
|
67
69
|
end
|
68
70
|
|
69
71
|
shared_examples "a scoped method" do |attribute_name, parent_scope_names, parent_scope_method, example_value|
|
@@ -166,7 +168,7 @@ describe "DSL" do
|
|
166
168
|
end
|
167
169
|
|
168
170
|
describe "#server" do
|
169
|
-
it_behaves_like "a scope", :server, :environment
|
171
|
+
it_behaves_like "a scope", :server, [:environment, :config, :project]
|
170
172
|
|
171
173
|
it "evaluates default_server_config" do
|
172
174
|
dsl(scopes[:environment], factory.create(:environment, :foo)) do |c|
|
data/spec/spec_helper.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'taketo/constructs'
|
2
|
+
|
1
3
|
shared_examples "a construct with nodes" do |name_plural, name_singular|
|
2
4
|
specify "#append_#{name_singular} adds a #{name_singular} to " + # specify "#append_server adds a server to " +
|
3
5
|
"the #{name_plural} collection" do # "the servers collection" do
|
@@ -13,3 +15,30 @@ shared_examples "a construct with nodes" do |name_plural, name_singular|
|
|
13
15
|
end # end
|
14
16
|
end
|
15
17
|
|
18
|
+
module ConstructsFixtures
|
19
|
+
include Taketo::Constructs
|
20
|
+
|
21
|
+
[Project, Environment, Server].each do |node_type|
|
22
|
+
define_method node_type.name.downcase.gsub(/\w*::/, '') do |name, *args|
|
23
|
+
n = node_type.new(name)
|
24
|
+
add_nodes(n, args.first || {})
|
25
|
+
n
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def create_config(nodes_by_types = {})
|
30
|
+
c = Taketo::Constructs::Config.new
|
31
|
+
add_nodes(c, nodes_by_types)
|
32
|
+
c
|
33
|
+
end
|
34
|
+
|
35
|
+
def add_nodes(node, nodes_by_types)
|
36
|
+
nodes_by_types.each do |child_type, children_of_type|
|
37
|
+
Array(children_of_type).each do |c|
|
38
|
+
node.nodes(child_type) << c
|
39
|
+
c.parent = node
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|