taketo 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -66,7 +66,7 @@ Destination resolving works intelligently. Given the following config:
66
66
  end
67
67
  end
68
68
  end
69
-
69
+
70
70
  project :my_project2 do
71
71
  environment :staging do
72
72
  server :s2 do
@@ -76,8 +76,8 @@ Destination resolving works intelligently. Given the following config:
76
76
  end
77
77
  ```
78
78
 
79
- ```taketo my_project:staging``` will ssh to s1 with host = 1.2.3.4
80
- ```taketo my_project2``` will ssh to s2 with host = 2.3.4.5
79
+ ```taketo my_project:staging``` will ssh to s1 with host = 1.2.3.4
80
+ ```taketo my_project2``` will ssh to s2 with host = 2.3.4.5
81
81
  ```taketo mps1``` will ssh to ps1 with host = 3.4.5.6 - note the use of global alias
82
82
 
83
83
  Note that default destination can be specified via ```default_destination``` config option
@@ -105,29 +105,45 @@ You can use shared server configs to reduce duplication:
105
105
 
106
106
  server :s2 do
107
107
  host :s2 do
108
- include_shared_server_config(:my_staging => [], :some_other_shared_config => "qux")
108
+ include_shared_server_config(:my_staging, :some_other_shared_config => "qux")
109
109
  end
110
110
  end
111
111
  end
112
112
  ```
113
113
 
114
- This will give you ```console``` commands available both on s1 and s2
114
+ This will give you ```console``` commands available both on s1 and s2
115
115
 
116
116
  The Changelog:
117
117
  --------------
118
118
 
119
+ ### v0.0.8 (17.11.2012) ###
120
+ * Add per-config, per-project and per-environment default server config support, i.e.
121
+ ```ruby
122
+ default_server_config { env :TERM => 'xterm-256color' } # Global default server config
123
+
124
+ project :p1 do
125
+ default_server_config { env :FOO => 'bar' } # global default server config is merged
126
+ ...
127
+ end
128
+ ```
129
+
130
+ * Shared server configs can be included without redundant empty-array arguments, i.e.
131
+ ```ruby
132
+ include_shared_server_configs(:foo, :bar, :baz => [:arg1, :arg2], :qux => :arg3)
133
+ ```
134
+
119
135
  ### v0.0.7 (08.10.2012) ###
120
136
  * Add ability to include several shared server config at once
121
137
  Use hash as include_shared_server_config parameter to include
122
138
  multiple shared server configs with arguments, like:
123
139
  ```ruby
124
- include_shared_server_config(:foo => :some_arg, :bar => [:arg1, :arg2])
140
+ include_shared_server_configs(:foo => :some_arg, :bar => [:arg1, :arg2])
125
141
  ```
126
142
  or just enumerate them if no arguments needed:
127
143
  ```ruby
128
144
  include_shared_server_configs(:baz, :quux)
129
145
  ```
130
-
146
+
131
147
  NOTE: This change will break your config if you've used parametrized
132
148
  shared server configs before; rewrite them using hash-form
133
149
 
@@ -155,3 +171,14 @@ The Changelog:
155
171
  * Initial release
156
172
  * Support for simplest configs
157
173
 
174
+
175
+ TO-DO:
176
+ ------
177
+
178
+ * Shared server configs without arguments
179
+ * Global server defaults
180
+ * Override default commands per server
181
+ * Define servers outside projects and environments
182
+ * Export SSH config (i.e. for scp)
183
+ * Destination completion
184
+ * Command completion
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.7
1
+ 0.0.8
@@ -1,11 +1,11 @@
1
- Feature:
1
+ Feature:
2
2
  In order to be able to quickly run commands on my servers
3
3
  As a developer
4
4
  I want to have ability to create command shortcuts via config
5
5
  or specify command directly
6
6
 
7
7
  Background:
8
- When I have the following config in "/tmp/taketo_test_cfg.rb"
8
+ When I have the following config
9
9
  """
10
10
  project :slots do
11
11
  environment :staging do
@@ -21,21 +21,21 @@ Feature:
21
21
  """
22
22
 
23
23
  Scenario: Run explicit command
24
- When I successfully run `taketo --config=/tmp/taketo_test_cfg.rb --dry-run --command "TERM=xterm-256color bash"`
24
+ When I run taketo --dry-run --command "TERM=xterm-256color bash"
25
25
  Then the output should contain
26
26
  """
27
27
  ssh -t 1.2.3.4 "cd /var/apps/slots; RAILS_ENV=staging TERM=xterm-256color bash"
28
28
  """
29
29
 
30
30
  Scenario: Run command defined in config
31
- When I successfully run `taketo --config=/tmp/taketo_test_cfg.rb --dry-run --command console slots:staging`
31
+ When I run taketo --dry-run --command console slots:staging
32
32
  Then the output should contain
33
33
  """
34
34
  ssh -t 1.2.3.4 "cd /var/apps/slots; RAILS_ENV=staging rails c"
35
35
  """
36
36
 
37
37
  Scenario: Override default location specified for server
38
- When I successfully run `taketo --config=/tmp/taketo_test_cfg.rb --dry-run --directory /var/www slots:staging`
38
+ When I run taketo --dry-run --directory /var/www slots:staging
39
39
  Then the output should contain
40
40
  """
41
41
  ssh -t 1.2.3.4 "cd /var/www; RAILS_ENV=staging bash"
@@ -4,7 +4,7 @@ Feature: taketo config
4
4
  I want to be able configure taketo
5
5
 
6
6
  Scenario: Shared server configs
7
- When I have the following config in "/tmp/taketo_test_cfg.rb"
7
+ When I have the following config
8
8
  """
9
9
  shared_server_config :sc1 do
10
10
  port 9999 #can contain any server config options
@@ -20,14 +20,14 @@ Feature: taketo config
20
20
  end
21
21
  end
22
22
  """
23
- And I successfully run `taketo slots:staging:s1 --config=/tmp/taketo_test_cfg.rb --dry-run`
23
+ And I run taketo slots:staging:s1 --dry-run
24
24
  Then the output should contain
25
25
  """
26
26
  ssh -t -p 9999 1.2.3.4 "cd /var/qux; RAILS_ENV=staging bash"
27
27
  """
28
28
 
29
29
  Scenario: Shared server configs with arguments
30
- When I have the following config in "/tmp/taketo_test_cfg.rb"
30
+ When I have the following config
31
31
  """
32
32
  shared_server_config :sc_args1 do |port_num|
33
33
  port port_num
@@ -46,14 +46,14 @@ Feature: taketo config
46
46
  end
47
47
  end
48
48
  """
49
- And I successfully run `taketo slots:staging:s1 --config=/tmp/taketo_test_cfg.rb --dry-run`
49
+ And I run taketo slots:staging:s1 --dry-run
50
50
  Then the output should contain
51
51
  """
52
52
  ssh -t -p 9999 1.2.3.4 "cd /var/qux; RAILS_ENV=staging bash"
53
53
  """
54
54
 
55
55
  Scenario: Set environment variables
56
- When I have the following config in "/tmp/taketo_test_cfg.rb"
56
+ When I have the following config
57
57
  """
58
58
  project :slots do
59
59
  environment :staging do
@@ -65,7 +65,7 @@ Feature: taketo config
65
65
  end
66
66
  end
67
67
  """
68
- And I successfully run `taketo --config=/tmp/taketo_test_cfg.rb --dry-run`
68
+ And I run taketo --dry-run
69
69
  Then the output should contain
70
70
  """
71
71
  RAILS_ENV=staging
@@ -74,9 +74,9 @@ Feature: taketo config
74
74
  """
75
75
  FOO=the\ value
76
76
  """
77
-
77
+
78
78
  Scenario: Reopen config scopes
79
- When I have the following config in "/tmp/taketo_test_cfg.rb"
79
+ When I have the following config
80
80
  """
81
81
  project :slots do
82
82
  environment :staging do
@@ -94,11 +94,11 @@ Feature: taketo config
94
94
  end
95
95
  end
96
96
  """
97
- And I successfully run `taketo --config=/tmp/taketo_test_cfg.rb slots:staging --dry-run`
97
+ And I run taketo slots:staging --dry-run
98
98
  Then the output should match /ssh -t 1\.2\.3\.4 "(RAILS_ENV=staging FOO=bar|FOO=bar RAILS_ENV=staging) bash"/
99
99
 
100
100
  Scenario: Unique server alias
101
- When I have the following config in "/tmp/taketo_test_cfg.rb"
101
+ When I have the following config
102
102
  """
103
103
  project :slots do
104
104
  environment :staging do
@@ -112,7 +112,7 @@ Feature: taketo config
112
112
  end
113
113
  end
114
114
  """
115
- And I successfully run `taketo ss2 --config=/tmp/taketo_test_cfg.rb --dry-run`
115
+ And I run taketo ss2 --dry-run
116
116
  Then the output should contain
117
117
  """
118
118
  ssh -t 2.3.4.5 "RAILS_ENV=staging bash"
@@ -4,11 +4,11 @@ Feature:
4
4
  I want to be guided if there are any errors in my configuration
5
5
 
6
6
  Scenario Outline: Config validation
7
- When I have the following config in "/tmp/taketo_test_cfg.rb"
7
+ When I have the following config
8
8
  """
9
9
  <config>
10
10
  """
11
- And I run `taketo --config=/tmp/taketo_test_cfg.rb`
11
+ And I run taketo
12
12
  Then the stderr should contain "<error>"
13
13
 
14
14
  Examples:
@@ -19,18 +19,18 @@ Feature:
19
19
  | project(:foo) { environment(:bar) { server {} }} | Server foo:bar:default: host is not defined |
20
20
 
21
21
  Scenario: Global server alias clash
22
- When I have the following config in "/tmp/taketo_test_cfg.rb"
22
+ When I have the following config
23
23
  """
24
24
  project(:foo) { environment(:bar) {
25
25
  server(:s1) { host '1.2.3.4'; global_alias :a1 }
26
26
  server(:s2) { host '2.3.4.5'; global_alias :a1 }
27
27
  }}
28
28
  """
29
- And I run `taketo --config=/tmp/taketo_test_cfg.rb`
29
+ And I run taketo
30
30
  Then the stderr should contain "Server foo:bar:s2: global alias 'a1' has already been taken by server foo:bar:s1"
31
31
 
32
32
  Scenario: Bad command
33
- When I have the following config in "/tmp/taketo_test_cfg.rb"
33
+ When I have the following config
34
34
  """
35
35
  project(:foo) { environment(:bar) {
36
36
  server(:s1) { host '1.2.3.4'
@@ -38,6 +38,6 @@ Feature:
38
38
  }
39
39
  }}
40
40
  """
41
- And I run `taketo --config=/tmp/taketo_test_cfg.rb`
41
+ And I run taketo
42
42
  Then the stderr should contain "Don't know what to execute on command foo"
43
43
 
@@ -5,7 +5,7 @@ Feature:
5
5
  configurable with simple DSL
6
6
 
7
7
  Scenario: SSH to server
8
- When I have the following config in "/tmp/taketo_test_cfg.rb"
8
+ When I have the following config
9
9
  """
10
10
  project :slots do
11
11
  environment :staging do
@@ -22,14 +22,14 @@ Feature:
22
22
  end
23
23
 
24
24
  """
25
- And I successfully run `taketo --config=/tmp/taketo_test_cfg.rb --dry-run slots:staging:s1`
25
+ And I run taketo --dry-run slots:staging:s1
26
26
  Then the output should contain
27
27
  """
28
28
  ssh -t deployer@1.2.3.4 "cd /var/apps/slots; RAILS_ENV=staging bash"
29
29
  """
30
30
 
31
31
  Scenario: SSH to the only server
32
- When I have the following config in "/tmp/taketo_test_cfg.rb"
32
+ When I have the following config
33
33
  """
34
34
  project :slots do
35
35
  environment :staging do
@@ -40,14 +40,14 @@ Feature:
40
40
  end
41
41
  end
42
42
  """
43
- And I successfully run `taketo --config=/tmp/taketo_test_cfg.rb --dry-run`
43
+ And I run taketo --dry-run
44
44
  Then the output should contain
45
45
  """
46
46
  ssh -t 1.2.3.4 "cd /var/apps/slots; RAILS_ENV=staging bash"
47
47
  """
48
48
 
49
49
  Scenario: Default destination
50
- When I have the following config in "/tmp/taketo_test_cfg.rb"
50
+ When I have the following config
51
51
  """
52
52
  default_destination "slots:staging:s2"
53
53
  project :slots do
@@ -61,14 +61,14 @@ Feature:
61
61
  end
62
62
  end
63
63
  """
64
- And I successfully run `taketo --config=/tmp/taketo_test_cfg.rb --dry-run`
64
+ And I run taketo --dry-run
65
65
  Then the output should contain
66
66
  """
67
67
  ssh -t 2.3.4.5 "RAILS_ENV=staging bash"
68
68
  """
69
69
 
70
70
  Scenario: SSH key file
71
- When I have the following config in "/tmp/taketo_test_cfg.rb"
71
+ When I have the following config
72
72
  """
73
73
  project :slots do
74
74
  environment :staging do
@@ -79,7 +79,7 @@ Feature:
79
79
  end
80
80
  end
81
81
  """
82
- And I successfully run `taketo --config=/tmp/taketo_test_cfg.rb --dry-run`
82
+ And I run taketo --dry-run
83
83
  Then the output should contain
84
84
  """
85
85
  ssh -t -i /home/gor/.ssh/foo\ bar 2.3.4.5 "RAILS_ENV=staging bash"
@@ -0,0 +1,41 @@
1
+ Feature: taketo config's default server config
2
+ In order to reduce duplication
3
+ As a taketo user
4
+ I want to be able set default configs for servers in particular scopes
5
+
6
+ Background:
7
+ When I have the following config
8
+ """
9
+ default_server_config do
10
+ env :FOO => 'bar'
11
+ end
12
+
13
+ project :slots do
14
+ default_server_config do
15
+ location '/mnt/apps'
16
+ end
17
+
18
+ environment :staging do
19
+ server :s1 do
20
+ host "1.2.3.4"
21
+ end
22
+ end
23
+ end
24
+
25
+ project :shoes do
26
+ environment :production do
27
+ server do
28
+ host "2.3.4.5"
29
+ end
30
+ end
31
+ end
32
+ """
33
+
34
+ Scenario: Global default server config
35
+ When I run taketo shoes --dry-run
36
+ Then the output should match /ssh -t 2\.3\.4\.5 "(RAILS_ENV=production FOO=bar|FOO=bar RAILS_ENV=production) bash"/
37
+
38
+ Scenario: Project default server config
39
+ When I run taketo slots --dry-run
40
+ Then the output should match /ssh -t 1\.2\.3\.4 "cd .mnt.apps; (RAILS_ENV=staging FOO=bar|FOO=bar RAILS_ENV=staging) bash"/
41
+
@@ -4,7 +4,7 @@ Feature:
4
4
  I want to see meaningful errors when I accidentally specify bad location
5
5
 
6
6
  Background:
7
- When I have the following config in "/tmp/taketo_test_cfg.rb"
7
+ When I have the following config
8
8
  """
9
9
  default_destination "slots:staging:s2"
10
10
  project :slots do
@@ -20,10 +20,10 @@ Feature:
20
20
  """
21
21
 
22
22
  Scenario: Non-existent location
23
- And I run `taketo slots:staging:qqq --config=/tmp/taketo_test_cfg.rb --dry-run`
23
+ And I run taketo slots:staging:qqq --dry-run
24
24
  Then the stderr should contain "server qqq not found for environment staging"
25
25
 
26
26
  Scenario: Ambiguous location
27
- And I run `taketo slots:staging --config=/tmp/taketo_test_cfg.rb --dry-run`
27
+ And I run taketo slots:staging --dry-run
28
28
  Then the stderr should contain "There are multiple servers for environment staging: s1, s2"
29
29
 
@@ -4,7 +4,7 @@ Feature:
4
4
  I want to view what's set up in config quickly
5
5
 
6
6
  Background:
7
- When I have the following config in "/tmp/taketo_test_cfg.rb"
7
+ When I have the following config
8
8
  """
9
9
  project :foo do
10
10
  environment :bar do
@@ -34,7 +34,7 @@ Feature:
34
34
  """
35
35
 
36
36
  Scenario: View full config
37
- When I run `taketo --config=/tmp/taketo_test_cfg.rb --view`
37
+ When I run taketo --view
38
38
  Then the output should contain exactly:
39
39
  """
40
40
 
@@ -55,11 +55,11 @@ Feature:
55
55
  Environment: RAILS_ENV=qux
56
56
  console
57
57
  killall - Kill ALL humans
58
-
58
+
59
59
  """
60
60
 
61
61
  Scenario: View particular server
62
- When I run `taketo --config=/tmp/taketo_test_cfg.rb --view foo:bar:default`
62
+ When I run taketo --view foo:bar:default
63
63
  Then the output should contain exactly:
64
64
  """
65
65
  Server: default
@@ -1,10 +1,16 @@
1
- When /^I have the following config in "(.*?)"$/ do |path, config|
2
- @config_path = path
3
- File.open(path, "w") do |f|
1
+ DEFAULT_TEST_CONFIG_PATH = "/tmp/taketo_test_cfg.rb".freeze
2
+
3
+ When /^I have the following config$/ do |config|
4
+ @config_path = DEFAULT_TEST_CONFIG_PATH
5
+ File.open(@config_path, "w") do |f|
4
6
  f.write(config)
5
7
  end
6
8
  end
7
9
 
10
+ When /^I run taketo\s?(.*)$/ do |arguments|
11
+ step "I run `taketo --config=/tmp/taketo_test_cfg.rb #{arguments}`"
12
+ end
13
+
8
14
  Then /^the output should contain$/ do |expected|
9
15
  assert_partial_output(expected, all_output)
10
16
  end
@@ -6,11 +6,12 @@ module Taketo
6
6
  class BaseConstruct
7
7
 
8
8
  include AssociatedNodes
9
- attr_reader :name
9
+ attr_reader :name, :default_server_config
10
10
 
11
11
  def initialize(name)
12
12
  super
13
13
  @name = name
14
+ @default_server_config = proc {}
14
15
  end
15
16
 
16
17
  def node_type
@@ -18,6 +19,17 @@ module Taketo
18
19
  demodulized.gsub(/([a-z])([A-Z])/, '\\1_\\2').downcase.to_sym
19
20
  end
20
21
 
22
+ ##
23
+ # Override in subclasses if needed
24
+ def parent=(parent)
25
+ @default_server_config = parent.default_server_config
26
+ end
27
+
28
+ def default_server_config=(config)
29
+ default = @default_server_config
30
+ @default_server_config = proc { instance_eval(&default); instance_eval(&config) }
31
+ end
32
+
21
33
  def qualified_name
22
34
  "#{node_type} #{self.name}"
23
35
  end
@@ -15,11 +15,6 @@ module Taketo
15
15
  def project_name
16
16
  @project.name if defined? @project
17
17
  end
18
-
19
- def append_server(server)
20
- server.environment = self
21
- super
22
- end
23
18
  end
24
19
  end
25
20
  end
@@ -19,9 +19,10 @@ module Taketo
19
19
  @environment_variables.merge!(env_variables)
20
20
  end
21
21
 
22
- def environment=(environment)
22
+ def parent=(environment)
23
23
  env(:RAILS_ENV => environment.name.to_s)
24
24
  @environment = environment
25
+ super
25
26
  end
26
27
 
27
28
  def default_command
data/lib/taketo/dsl.rb CHANGED
@@ -2,30 +2,27 @@ require 'taketo/constructs_factory'
2
2
 
3
3
  module Taketo
4
4
  class DSL
5
- class ScopeError < StandardError; end
5
+ class ScopeError < StandardError; end
6
6
  class ConfigError < StandardError; end
7
7
 
8
8
  class << self
9
- def define_scope(scope, parent_scope, options = {})
10
- define_method scope do |*args, &block|
11
- unless current_scope?(parent_scope)
12
- raise ScopeError,
13
- "#{scope} can't be defined in #{current_scope} scope"
14
- end
9
+ def define_scope(scope, parent_scope, options = {}, &block)
10
+ define_method scope do |*args, &blk|
11
+ ensure_nesting_allowed!(scope, parent_scope)
15
12
  name = args.shift || options[:default_name] or raise(ArgumentError, "Name not specified")
13
+
16
14
  scope_object = current_scope_object.find(scope, name) { @factory.create(scope, name) }
15
+
17
16
  in_scope(scope, scope_object) do
18
- block.call
17
+ instance_exec(current_scope_object, &block) if block
18
+ blk.call
19
19
  end
20
20
  end
21
21
  end
22
22
 
23
- def define_method_in_scope(name, parent_scope, &block)
23
+ def define_method_in_scope(name, *parent_scopes, &block)
24
24
  define_method name do |*args, &blk|
25
- unless current_scope?(parent_scope)
26
- raise ScopeError,
27
- "#{name} can't be defined in #{current_scope} scope"
28
- end
25
+ ensure_nesting_allowed!(name, parent_scopes)
29
26
  args.push blk if blk
30
27
  instance_exec(*args, &block)
31
28
  end
@@ -56,7 +53,11 @@ module Taketo
56
53
 
57
54
  define_scope :project, :config
58
55
  define_scope :environment, :project
59
- define_scope :server, :environment, :default_name => :default
56
+
57
+ define_scope :server, :environment, :default_name => :default do |s|
58
+ instance_eval(&s.default_server_config)
59
+ end
60
+
60
61
  define_scope :command, :server
61
62
 
62
63
  define_method_in_scope(:default_destination, :config) { |destination| current_scope_object.default_destination = destination }
@@ -70,20 +71,17 @@ module Taketo
70
71
  define_method_in_scope(:execute, :command) { |command| current_scope_object.command = command }
71
72
  define_method_in_scope(:desc, :command) { |description| current_scope_object.description = description }
72
73
 
74
+ define_method_in_scope(:default_server_config, :config, :project, :environment) do |blk|
75
+ current_scope_object.default_server_config = blk
76
+ end
77
+
73
78
  define_method_in_scope(:shared_server_config, :config) do |name, blk|
74
79
  @shared_server_configs.store(name.to_sym, blk)
75
80
  end
76
81
 
77
82
  define_method_in_scope(:include_shared_server_config, :server) do |*args|
78
- if args.first.is_a?(Hash)
79
- configs_and_arguments = args.shift
80
- configs_and_arguments.each do |config_name, arguments|
81
- instance_exec(*arguments, &shared_server_configs[config_name])
82
- end
83
- else
84
- args.each do |config_name|
85
- instance_exec(&shared_server_configs[config_name])
86
- end
83
+ extract_config_names_and_arguments(args).each do |config_name, arguments|
84
+ instance_exec(*arguments, &shared_server_configs[config_name])
87
85
  end
88
86
  end
89
87
  alias :include_shared_server_configs :include_shared_server_config
@@ -106,12 +104,26 @@ module Taketo
106
104
  def in_scope(scope, new_scope_object)
107
105
  parent_scope_object, @current_scope_object = @current_scope_object, new_scope_object
108
106
  @scope.push(scope)
109
- yield
110
107
  parent_scope_object.send("append_#{scope}", current_scope_object)
108
+ current_scope_object.parent = parent_scope_object
109
+ yield
111
110
  @scope.pop
112
111
  @current_scope_object = parent_scope_object
113
112
  end
114
113
 
114
+ def ensure_nesting_allowed!(scope, parent_scopes)
115
+ if Array(parent_scopes).none? { |s| current_scope?(s) }
116
+ raise ScopeError, "#{scope} can't be defined in #{current_scope} scope"
117
+ end
118
+ end
119
+
120
+ def extract_config_names_and_arguments(args)
121
+ hashes, names = args.partition { |arg| arg.is_a? Hash }
122
+ configs_from_hashes = hashes.inject({}, &:merge)
123
+ configs_from_names = Hash[names.map { |config_name| [config_name.to_sym, []] }]
124
+ configs_from_hashes.merge(configs_from_names)
125
+ end
126
+
115
127
  end
116
128
  end
117
129
 
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
  require 'taketo/dsl'
3
3
 
4
4
  describe "Taketo DSL" do
5
- it "should parse config and instantiate objects" do
5
+ it "parses config and instantiate objects" do
6
6
  factory = Taketo::ConstructsFactory.new
7
7
  config = Taketo::DSL.new(factory).configure do
8
8
  shared_server_config(:commands) do
@@ -44,7 +44,7 @@ describe "Taketo DSL" do
44
44
 
45
45
  project.environments.length.should == 2
46
46
  staging = project.environments[:staging]
47
-
47
+
48
48
  staging.servers.length.should == 1
49
49
  staging_server = staging.servers[:default]
50
50
  staging_server.name.should == :default
@@ -7,7 +7,7 @@ describe "ConfigValidator" do
7
7
  let(:traverser) { stub(:ConfigTraverser) }
8
8
 
9
9
  describe "#validate!" do
10
- it "should visit all nodes with an instance of ConfigValidator::ConfigValidatorVisitor" do
10
+ it "visits all nodes with an instance of ConfigValidator::ConfigValidatorVisitor" do
11
11
  validator = ConfigValidator.new(traverser)
12
12
  traverser.should_receive(:visit_depth_first).with(an_instance_of(ConfigValidator::ConfigValidatorVisitor))
13
13
  validator.validate!
@@ -18,7 +18,7 @@ end
18
18
  describe "ConfigValidator::ConfigValidatorVisitor" do
19
19
  subject(:visitor) { ConfigValidator::ConfigValidatorVisitor.new }
20
20
 
21
- it "should require config to have projects" do
21
+ it "requires config to have projects" do
22
22
  config = stub(:Config, :has_projects? => false)
23
23
  error_message = /no projects/
24
24
  expect { visitor.visit_config(config) }.to raise_error ConfigError, error_message
@@ -27,7 +27,7 @@ describe "ConfigValidator::ConfigValidatorVisitor" do
27
27
  expect { visitor.visit_config(config) }.not_to raise_error ConfigError, error_message
28
28
  end
29
29
 
30
- it "should require projects to have environments" do
30
+ it "requires projects to have environments" do
31
31
  project = stub(:Project, :has_environments? => false, :path => "my_project")
32
32
  error_message = /my_project: no environments/
33
33
  expect { visitor.visit_project(project) }.to raise_error ConfigError, error_message
@@ -36,7 +36,7 @@ describe "ConfigValidator::ConfigValidatorVisitor" do
36
36
  expect { visitor.visit_project(project) }.not_to raise_error ConfigError, error_message
37
37
  end
38
38
 
39
- it "should require environments to have servers" do
39
+ it "requires environments to have servers" do
40
40
  environment = stub(:Environment, :has_servers? => false, :path => "my_project:my_environment")
41
41
  error_message = /my_project:my_environment: no servers/
42
42
  expect { visitor.visit_environment(environment) }.to raise_error ConfigError, error_message
@@ -45,7 +45,7 @@ describe "ConfigValidator::ConfigValidatorVisitor" do
45
45
  expect { visitor.visit_environment(environment) }.not_to raise_error ConfigError, error_message
46
46
  end
47
47
 
48
- it "should require servers to have host" do
48
+ it "requires servers to have host" do
49
49
  server = stub(:Server, :host => '', :path => "my_project:my_environment:my_server", :global_alias => nil)
50
50
  error_message = /my_project:my_environment:my_server: host is not defined/
51
51
  expect { visitor.visit_server(server) }.to raise_error ConfigError, error_message
@@ -54,7 +54,7 @@ describe "ConfigValidator::ConfigValidatorVisitor" do
54
54
  expect { visitor.visit_server(server) }.not_to raise_error ConfigError, error_message
55
55
  end
56
56
 
57
- it "should require servers to have unique global server aliases" do
57
+ it "requires servers to have unique global server aliases" do
58
58
  server1 = stub(:Server, :host => 'the-host1', :path => "my_project:my_environment:my_server", :global_alias => 'foo')
59
59
  server2 = stub(:Server, :host => 'the-host2', :path => "my_project:my_environment2:my_server3", :global_alias => 'foo')
60
60
  error_message = /my_project:my_environment2:my_server3: global alias 'foo' has already been taken.*my_project:my_environment:my_server/
@@ -63,7 +63,7 @@ describe "ConfigValidator::ConfigValidatorVisitor" do
63
63
  expect { @visitor.visit_server(server2) }.to raise_error ConfigError, error_message
64
64
  end
65
65
 
66
- it "should require commands to have command specified" do
66
+ it "requires commands to have command specified" do
67
67
  command = stub(:Command, :command => '', :name => 'qux')
68
68
  error_message = /execute/
69
69
  expect { visitor.visit_command(command) }.to raise_error ConfigError, error_message
@@ -16,6 +16,36 @@ describe "BaseConstruct" do
16
16
  expect(construct.qualified_name).to eq('test_base_construct my_node')
17
17
  end
18
18
 
19
+ specify "#parent= sets default server config to parent's default server config" do
20
+ parent_default_server_config = proc {}
21
+ construct.parent = stub(:default_server_config => parent_default_server_config)
22
+ expect(construct.default_server_config).to eq(parent_default_server_config)
23
+ end
24
+
25
+ describe "#default_server_config=" do
26
+ let(:default_server_config) { proc { call_from_self } }
27
+ let(:context) { stub }
28
+
29
+ it "sets default server config" do
30
+ construct.default_server_config = default_server_config
31
+ context.should_receive(:call_from_self)
32
+ context.instance_eval(&construct.default_server_config)
33
+ end
34
+
35
+ it "merges given config to parent's default server config" do
36
+ construct.parent = stub(:default_server_config => proc { call_from_parent })
37
+ construct.default_server_config = default_server_config
38
+
39
+ context.should_receive(:call_from_parent).ordered
40
+ context.should_receive(:call_from_self).ordered
41
+ context.instance_eval(&construct.default_server_config)
42
+ end
43
+ end
44
+
45
+ it "has an empty proc as an initial default server config" do
46
+ expect(construct.default_server_config.call).to eq(nil)
47
+ end
48
+
19
49
  end
20
50
 
21
51
 
@@ -13,16 +13,10 @@ describe "Environment" do
13
13
 
14
14
  it_behaves_like "a construct with nodes", :servers, :server
15
15
 
16
- specify "#append_server sets environment attribute on a server to self" do
17
- server = mock(:Server, :name => :foo)
18
- server.should_receive(:environment=).with(environment)
19
- environment.append_server(server)
20
- end
21
-
22
16
  specify "#project_name returns project name" do
23
17
  environment.project = stub(:Project, :name => "TheProject")
24
18
  expect(environment.project_name).to eq("TheProject")
25
- end
19
+ end
26
20
  end
27
21
 
28
22
 
@@ -10,7 +10,7 @@ describe "Project" do
10
10
  it "has name" do
11
11
  expect(project.name).to eq(:foo)
12
12
  end
13
-
13
+
14
14
  specify "#append_environment sets project attribute on an environment to self" do
15
15
  environment = mock(:Environment, :name => :bar)
16
16
  environment.should_receive(:project=).with(project)
@@ -30,14 +30,14 @@ describe "Server" do
30
30
  expect(server.default_command).to eq(:qux)
31
31
  end
32
32
 
33
- describe "#environment=" do
34
- let(:environment) { environment = stub(:Environment, :name => :the_environment) }
33
+ describe "#parent=" do
34
+ let(:environment) { environment = stub(:Environment, :name => :the_environment, :default_server_config => proc {}) }
35
35
 
36
36
  it { should have_accessor(:environment, environment) }
37
37
 
38
38
  it "sets RAILS_ENV environment variable" do
39
39
  server.environment_variables.should == {}
40
- server.environment = environment
40
+ server.parent = environment
41
41
  expect(server.environment_variables[:RAILS_ENV]).to eq(environment.name.to_s)
42
42
  end
43
43
  end
@@ -8,11 +8,15 @@ describe "DSL" do
8
8
  extend DSLSpec
9
9
  include DSLSpec
10
10
 
11
- shared_examples "a scoped construct" do |name, parent_scope_name, with_block|
12
- parent_scope = scopes[parent_scope_name]
13
- it { should be_appropriate_construct(name, :foo).with_block(with_block).under(parent_scope) }
11
+ shared_examples "a scoped construct" do |name, parents, with_block|
12
+ parents = Array(parents)
13
+
14
+ parents.each do |parent_scope_name|
15
+ parent_scope = scopes[parent_scope_name]
16
+ it { should be_appropriate_construct(name, :foo).with_block(with_block).under(parent_scope) }
17
+ end
14
18
 
15
- scopes.except(parent_scope_name).each do |inappropriate_scope|
19
+ scopes.except(*parents).each do |inappropriate_scope|
16
20
  it { should_not be_appropriate_construct(name, :foo).with_block(with_block).under(inappropriate_scope) }
17
21
  end
18
22
  end
@@ -52,16 +56,26 @@ describe "DSL" do
52
56
  c.send(scope_name, :bar) {} # c.project(:bar) {}
53
57
  end # end
54
58
  end # end
59
+
60
+ 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
61
+ dsl(parent_scope, factory.create(parent_scope_name)) do |c| # dsl([:config], factory.create(:config)) do |c|
62
+ stub_find_or_create_scope_object(c, scope_name, :bar) # stub_find_or_create_scope_object(c, :project, :bar)
63
+ factory.send(scope_name).should_receive(:parent=).with(c.current_scope_object) # factory.project.should_receive(:parent=).with(c.current_scope_object)
64
+ c.send(scope_name, :bar) {} # c.project(:bar) {}
65
+ end # end
66
+ end #
55
67
  end
56
68
 
57
- shared_examples "a scoped method" do |attribute_name, parent_scope_name, parent_scope_method, example_value|
58
- it_behaves_like "a scoped construct", attribute_name, parent_scope_name, false
69
+ shared_examples "a scoped method" do |attribute_name, parent_scope_names, parent_scope_method, example_value|
70
+ it_behaves_like "a scoped construct", attribute_name, parent_scope_names, false
59
71
 
60
- it "calls #{parent_scope_method} on current #{parent_scope_name}" do # it "calls default_location= on current server" do
61
- dsl(scopes[parent_scope_name], factory.create(parent_scope_name, :foo)) do |c| # dsl([:config, :project, :environment, :server], factory.create(:server, :foo)) do |c|
62
- factory.send(parent_scope_name).should_receive(parent_scope_method).with(example_value) # factory.server.should_receive(:default_location=).with('/var/app/')
63
- c.send(attribute_name, example_value) # c.location "/var/app"
64
- end # end
72
+ Array(parent_scope_names).each do |parent_scope_name|
73
+ it "calls #{parent_scope_method} on current #{parent_scope_name}" do # it "calls default_location= on current server" do
74
+ dsl(scopes[parent_scope_name], factory.create(parent_scope_name, :foo)) do |c| # dsl([:config, :project, :environment, :server], factory.create(:server, :foo)) do |c|
75
+ factory.send(parent_scope_name).should_receive(parent_scope_method).with(example_value) # factory.server.should_receive(:default_location=).with('/var/app/')
76
+ c.send(attribute_name, example_value) # c.location "/var/app"
77
+ end # end
78
+ end
65
79
  end
66
80
  end
67
81
 
@@ -69,6 +83,18 @@ describe "DSL" do
69
83
  it_behaves_like "a scoped method", :default_destination, :config, :default_destination=, "foo:bar:baz"
70
84
  end
71
85
 
86
+ describe "#default_server_config" do
87
+ it_behaves_like "a scoped construct", :default_server_config, [:config, :project, :environment]
88
+
89
+ it "stores a block" do
90
+ dsl(scopes[:config], factory.create(:config)) do |c|
91
+ cfg = proc { any_method_call_here }
92
+ factory.config.should_receive(:default_server_config=).with(cfg)
93
+ c.default_server_config(&cfg)
94
+ end
95
+ end
96
+ end
97
+
72
98
  describe "#shared_server_config" do
73
99
  it_behaves_like "a scoped construct", :shared_server_config, :config
74
100
 
@@ -84,14 +110,14 @@ describe "DSL" do
84
110
  describe "#include_shared_server_config" do
85
111
  it "executes the block on dsl object in server scope for given shared config names" do
86
112
  dsl(scopes[:server], factory.create(:server)) do |c|
87
- c.stub(:shared_server_configs => { :foo => proc { any_method_call_here }, :bar => proc { second_method_call_here } })
88
- c.should_receive(:any_method_call_here)
89
- c.should_receive(:second_method_call_here)
113
+ c.stub(:shared_server_configs => { :foo => proc { call_from_foo }, :bar => proc { call_from_bar } })
114
+ c.should_receive(:call_from_foo)
115
+ c.should_receive(:call_from_bar)
90
116
  c.include_shared_server_config(:foo, :bar)
91
117
  end
92
118
  end
93
119
 
94
- context "when the only argument is hash where shared config names are keys" do
120
+ context "when the argument is hash where shared config names are keys" do
95
121
  context "when hash values are arrays" do
96
122
  it "includes config corresponding to hash key and passes exploded arguments" do
97
123
  dsl(scopes[:server], factory.create(:server)) do |c|
@@ -113,6 +139,17 @@ describe "DSL" do
113
139
  end
114
140
  end
115
141
 
142
+ context "whne there are symbol arguments (names of shared configs) and a hash" do
143
+ it "includes config corresponding to symbol arguments and hash keys" do
144
+ dsl(scopes[:server], factory.create(:server)) do |c|
145
+ c.stub(:shared_server_configs => { :foo => proc { call_from_foo }, :bar => proc { |qux| call_from_bar(qux) } })
146
+ c.should_receive(:call_from_foo)
147
+ c.should_receive(:call_from_bar).with(123)
148
+ c.include_shared_server_config(:foo, :bar => 123)
149
+ end
150
+ end
151
+ end
152
+
116
153
  it "raises ConfigError if non-existent config included" do
117
154
  dsl(scopes[:server], factory.create(:server)) do |c|
118
155
  expect { c.include_shared_server_config(:foo) }.to raise_error(Taketo::DSL::ConfigError, "Shared server config 'foo' is not defined!")
@@ -131,6 +168,20 @@ describe "DSL" do
131
168
  describe "#server" do
132
169
  it_behaves_like "a scope", :server, :environment
133
170
 
171
+ it "evaluates default_server_config" do
172
+ dsl(scopes[:environment], factory.create(:environment, :foo)) do |c|
173
+ stub_find_or_create_scope_object(c, :server, :bar)
174
+
175
+ default_server_config = proc { some_setup }
176
+ factory.server.stub(:default_server_config => default_server_config)
177
+
178
+ c.should_receive(:some_setup)
179
+
180
+ c.server(:bar) do
181
+ end
182
+ end
183
+ end
184
+
134
185
  it "has name optional" do
135
186
  dsl(scopes[:environment], factory.create(:environment, :foo)) do |c|
136
187
  stub_find_or_create_scope_object(c, :server, :default)
@@ -7,23 +7,23 @@ module DSLSpec
7
7
  end
8
8
 
9
9
  def create_config(*args)
10
- @config ||= RSpec::Mocks::Mock.new(:Config).as_null_object
10
+ @config ||= RSpec::Mocks::Mock.new(:Config, :default_server_config => proc {}).as_null_object
11
11
  end
12
12
 
13
13
  def create_project(name = :foo)
14
- @project ||= RSpec::Mocks::Mock.new(:Project, :name => name).as_null_object
14
+ @project ||= RSpec::Mocks::Mock.new(:Project, :name => name, :default_server_config => proc {}).as_null_object
15
15
  end
16
16
 
17
17
  def create_environment(name = :foo)
18
- @environment ||= RSpec::Mocks::Mock.new(:Environment, :name => name).as_null_object
18
+ @environment ||= RSpec::Mocks::Mock.new(:Environment, :name => name, :default_server_config => proc {}).as_null_object
19
19
  end
20
20
 
21
21
  def create_server(name = :foo)
22
- @server ||= RSpec::Mocks::Mock.new(:Server, :name => name).as_null_object
22
+ @server ||= RSpec::Mocks::Mock.new(:Server, :name => name, :default_server_config => proc {}).as_null_object
23
23
  end
24
24
 
25
25
  def create_command(name = :the_cmd)
26
- @command ||= RSpec::Mocks::Mock.new(:Command, :name => name).as_null_object
26
+ @command ||= RSpec::Mocks::Mock.new(:Command, :name => name, :default_server_config => proc {}).as_null_object
27
27
  end
28
28
  end
29
29
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: taketo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.8
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-10-08 00:00:00.000000000 Z
12
+ date: 2012-11-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
@@ -138,6 +138,7 @@ files:
138
138
  - features/config.feature
139
139
  - features/config_validation.feature
140
140
  - features/connect_to_server.feature
141
+ - features/default_server_config.feature
141
142
  - features/error_handling.feature
142
143
  - features/help.feature
143
144
  - features/step_definitions/main_steps.rb