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