switchtower 0.10.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -58,7 +58,7 @@ module SwitchTower
58
58
  sftp = @actor.sessions[server].sftp
59
59
  sftp.connect unless sftp.state == :open
60
60
 
61
- sftp.open(@filename, IO::WRONLY | IO::CREAT, @params[:mode] || 0660) do |status, handle|
61
+ sftp.open(@filename, IO::WRONLY | IO::CREAT | IO::TRUNC, @params[:mode] || 0660) do |status, handle|
62
62
  break unless check_status("open #{@filename}", server, status)
63
63
 
64
64
  logger.info "uploading data to #{server}:#{@filename}"
@@ -0,0 +1,26 @@
1
+ module SwitchTower
2
+ # A helper method for converting a comma-delimited string into an array of
3
+ # roles.
4
+ def self.str2roles(string)
5
+ list = string.split(/,/).map { |s| s.strip.to_sym }
6
+ list.empty? ? nil : list
7
+ end
8
+
9
+ # Used by third-party task bundles to identify the switchtower configuration
10
+ # that is loading them. It's return value is not reliable in other contexts.
11
+ # If +require_config+ is not false, an exception will be raised if the current
12
+ # configuration is not set.
13
+ def self.configuration(require_config=false)
14
+ config = Thread.current[:switchtower_configuration]
15
+ if require_config && config.nil?
16
+ raise "Please require this file from within a SwitchTower recipe"
17
+ end
18
+ config
19
+ end
20
+
21
+ # Used internally by SwitchTower to specify the current configuration before
22
+ # loading a third-party task bundle.
23
+ def self.configuration=(config)
24
+ Thread.current[:switchtower_configuration] = config
25
+ end
26
+ end
@@ -18,13 +18,13 @@ module SwitchTower
18
18
  good
19
19
  end
20
20
 
21
- MAJOR = 0
22
- MINOR = 10
21
+ MAJOR = 1
22
+ MINOR = 0
23
23
  TINY = 0
24
24
 
25
25
  STRING = [MAJOR, MINOR, TINY].join(".")
26
26
 
27
- SSH_REQUIRED = [1,0,5]
27
+ SSH_REQUIRED = [1,0,8]
28
28
  SFTP_REQUIRED = [1,1,0]
29
29
  end
30
30
  end
data/test/actor_test.rb CHANGED
@@ -4,6 +4,7 @@ require 'stringio'
4
4
  require 'test/unit'
5
5
  require 'switchtower/actor'
6
6
  require 'switchtower/logger'
7
+ require 'switchtower/configuration'
7
8
 
8
9
  class ActorTest < Test::Unit::TestCase
9
10
 
@@ -83,6 +84,12 @@ class ActorTest < Test::Unit::TestCase
83
84
  end
84
85
  end
85
86
 
87
+ module CustomExtension
88
+ def do_something_extra(a, b, c)
89
+ run "echo '#{a} :: #{b} :: #{c}'"
90
+ end
91
+ end
92
+
86
93
  def setup
87
94
  TestingCommand.reset!
88
95
  @actor = TestActor.new(MockConfiguration.new)
@@ -162,7 +169,7 @@ class ActorTest < Test::Unit::TestCase
162
169
  run "do this"
163
170
  end
164
171
 
165
- assert_equal %w(01.example.com 02.example.com 03.example.com 04.example.com 05.example.com 06.example.com 07.example.com all.example.com), @actor.tasks[:foo].servers(@actor.configuration).sort
172
+ assert_equal %w(01.example.com 02.example.com 03.example.com 04.example.com 05.example.com 06.example.com 07.example.com all.example.com), @actor.tasks[:foo].servers.sort
166
173
  end
167
174
 
168
175
  def test_run_in_task_without_explicit_roles_selects_all_roles
@@ -258,4 +265,30 @@ class ActorTest < Test::Unit::TestCase
258
265
  @actor.foo
259
266
  assert_equal %w(foo after_foo), history
260
267
  end
268
+
269
+ def test_uppercase_variables
270
+ config = SwitchTower::Configuration.new(TestActor)
271
+ config.set :HELLO, "world"
272
+ assert_equal "world", config.actor.instance_eval("HELLO")
273
+ config.set :HELLO, "test"
274
+ assert_equal "test", config.actor.instance_eval("HELLO")
275
+ end
276
+
277
+ def test_connect_when_no_matching_servers
278
+ @actor.define_task :foo, :roles => :db, :only => { :fnoofy => true } do
279
+ run "do this"
280
+ end
281
+
282
+ assert_raises(RuntimeError) { @actor.foo }
283
+ end
284
+
285
+ def test_custom_extension
286
+ assert SwitchTower.plugin(:custom, CustomExtension)
287
+ @actor.define_task :foo, :roles => :db do
288
+ custom.do_something_extra(1, 2, 3)
289
+ end
290
+ assert_nothing_raised { @actor.foo }
291
+ assert TestingCommand.invoked?
292
+ assert SwitchTower.remove_plugin(:custom)
293
+ end
261
294
  end
@@ -125,6 +125,16 @@ class ConfigurationTest < Test::Unit::TestCase
125
125
  assert_equal 1, @config.roles[:web].length
126
126
  end
127
127
 
128
+ def test_load_proc_explicit
129
+ @config.load :proc => Proc.new { set :gateway, "nifty.zoo.test" }
130
+ assert_equal "nifty.zoo.test", @config.gateway
131
+ end
132
+
133
+ def test_load_proc_implicit
134
+ @config.load { set :gateway, "nifty.zoo.test" }
135
+ assert_equal "nifty.zoo.test", @config.gateway
136
+ end
137
+
128
138
  def test_task_without_options
129
139
  block = Proc.new { }
130
140
  @config.task :hello, &block
@@ -209,10 +219,15 @@ class ConfigurationTest < Test::Unit::TestCase
209
219
  end
210
220
 
211
221
  def test_get_proc_variable_sets_original_value_hash
212
- @config.set :proc, Proc.new { "foo" }
222
+ @config.set(:proc) { "foo" }
213
223
  assert_nil @config[:original_value][:proc]
214
224
  assert_equal "foo", @config[:proc]
215
225
  assert_not_nil @config[:original_value][:proc]
216
226
  assert @config[:original_value][:proc].respond_to?(:call)
217
227
  end
228
+
229
+ def test_require
230
+ @config.require "#{File.dirname(__FILE__)}/fixtures/custom"
231
+ assert_equal "foo", @config.gateway
232
+ end
218
233
  end
@@ -0,0 +1,3 @@
1
+ SwitchTower.configuration(:must_exist).load do
2
+ set :gateway, "foo"
3
+ end
data/test/scm/cvs_test.rb CHANGED
@@ -9,10 +9,15 @@ class ScmCvsTest < Test::Unit::TestCase
9
9
  attr_accessor :story
10
10
  attr_reader :last_path
11
11
 
12
- def cvs_log(path)
12
+ def cvs_log(path,branch)
13
13
  @last_path = path
14
14
  story.shift
15
15
  end
16
+
17
+ def cvs_branch(path)
18
+ "deploy-me"
19
+ end
20
+
16
21
  end
17
22
 
18
23
  class MockChannel
@@ -56,7 +61,6 @@ class ScmCvsTest < Test::Unit::TestCase
56
61
  def setup
57
62
  @config = MockConfiguration.new
58
63
  @config[:repository] = ":ext:joetester@rubyforge.org:/hello/world"
59
- @config[:local] = "/hello/world"
60
64
  @config[:cvs] = "/path/to/cvs"
61
65
  @config[:password] = "chocolatebrownies"
62
66
  @config[:now] = Time.utc(2005,8,24,12,0,0)
@@ -144,11 +148,19 @@ MSG
144
148
  end
145
149
 
146
150
  def test_latest_revision
151
+ @config[:local] = "/hello/world"
147
152
  @scm.story = [ @log_msg ]
148
153
  assert_equal "2004-10-12 02:21:02", @scm.latest_revision
149
154
  assert_equal "/hello/world", @scm.last_path
150
155
  end
151
156
 
157
+ def test_latest_with_default_local
158
+ @config[:local] = nil
159
+ @scm.story = [ @log_msg ]
160
+ assert_equal "2004-10-12 02:21:02", @scm.latest_revision
161
+ assert_equal ".", @scm.last_path
162
+ end
163
+
152
164
  def test_checkout
153
165
  @actor.story = []
154
166
  assert_nothing_raised { @scm.checkout(@actor) }
@@ -161,4 +173,14 @@ MSG
161
173
  assert_nothing_raised { @scm.checkout(@actor) }
162
174
  assert_equal ["chocolatebrownies\n"], @actor.channels.last.sent_data
163
175
  end
176
+
177
+ def test_current_branch
178
+ assert_equal "deploy-me", @scm.current_branch
179
+ end
180
+
181
+ def test_default_current_branch
182
+ @config[:branch] = "default-branch"
183
+ @scm = CvsTest.new(@config)
184
+ assert_equal "default-branch", @scm.current_branch
185
+ end
164
186
  end
@@ -84,7 +84,7 @@ MSG
84
84
  @actor.story = []
85
85
  assert_nothing_raised { @scm.checkout(@actor) }
86
86
  assert_nil @actor.channels.last.sent_data
87
- assert_match %r{/path/to/svn}, @actor.command
87
+ assert_match %r{/path/to/svn co\s+-q}, @actor.command
88
88
  end
89
89
 
90
90
  def test_checkout_via_export
@@ -92,7 +92,7 @@ MSG
92
92
  @config[:checkout] = "export"
93
93
  assert_nothing_raised { @scm.checkout(@actor) }
94
94
  assert_nil @actor.channels.last.sent_data
95
- assert_match %r{/path/to/svn export}, @actor.command
95
+ assert_match %r{/path/to/svn export\s+-q}, @actor.command
96
96
  end
97
97
 
98
98
  def test_update
@@ -119,4 +119,19 @@ MSG
119
119
  assert_nothing_raised { @scm.checkout(@actor) }
120
120
  assert_equal ["chocolatebrownies\n"], @actor.channels.last.sent_data
121
121
  end
122
+
123
+ def test_svn_password
124
+ @config[:svn_password] = "butterscotchcandies"
125
+ @actor.story = [[:out, "Password: "]]
126
+ assert_nothing_raised { @scm.checkout(@actor) }
127
+ assert_equal ["butterscotchcandies\n"], @actor.channels.last.sent_data
128
+ end
129
+
130
+ def test_svn_username
131
+ @actor.story = []
132
+ @config[:svn_username] = "turtledove"
133
+ assert_nothing_raised { @scm.checkout(@actor) }
134
+ assert_nil @actor.channels.last.sent_data
135
+ assert_match %r{/path/to/svn co --username turtledove}, @actor.command
136
+ end
122
137
  end
data/test/utils.rb CHANGED
@@ -32,6 +32,14 @@ class MockConfiguration < Hash
32
32
  @logger ||= MockLogger.new
33
33
  end
34
34
 
35
+ def set(variable, value=nil, &block)
36
+ self[variable] = value
37
+ end
38
+
39
+ def respond_to?(sym)
40
+ self.has_key?(sym)
41
+ end
42
+
35
43
  def method_missing(sym, *args)
36
44
  if args.length == 0
37
45
  self[sym]
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.11
3
3
  specification_version: 1
4
4
  name: switchtower
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.10.0
7
- date: 2006-01-02 00:00:00 -07:00
6
+ version: 1.0.0
7
+ date: 2006-02-18 00:00:00 -07:00
8
8
  summary: "SwitchTower is a framework and utility for executing commands in parallel on
9
9
  multiple remote machines, via SSH. The primary goal is to simplify and
10
10
  automate the deployment of web applications."
@@ -38,6 +38,7 @@ files:
38
38
  - lib/switchtower/cli.rb
39
39
  - lib/switchtower/command.rb
40
40
  - lib/switchtower/configuration.rb
41
+ - lib/switchtower/extensions.rb
41
42
  - lib/switchtower/gateway.rb
42
43
  - lib/switchtower/generators
43
44
  - lib/switchtower/logger.rb
@@ -45,6 +46,7 @@ files:
45
46
  - lib/switchtower/scm
46
47
  - lib/switchtower/ssh.rb
47
48
  - lib/switchtower/transfer.rb
49
+ - lib/switchtower/utils.rb
48
50
  - lib/switchtower/version.rb
49
51
  - lib/switchtower/generators/rails
50
52
  - lib/switchtower/generators/rails/deployment
@@ -57,8 +59,11 @@ files:
57
59
  - lib/switchtower/recipes/templates
58
60
  - lib/switchtower/recipes/templates/maintenance.rhtml
59
61
  - lib/switchtower/scm/base.rb
62
+ - lib/switchtower/scm/baz.rb
63
+ - lib/switchtower/scm/bzr.rb
60
64
  - lib/switchtower/scm/cvs.rb
61
65
  - lib/switchtower/scm/darcs.rb
66
+ - lib/switchtower/scm/perforce.rb
62
67
  - lib/switchtower/scm/subversion.rb
63
68
  - examples/sample.rb
64
69
  - test/actor_test.rb
@@ -69,6 +74,7 @@ files:
69
74
  - test/ssh_test.rb
70
75
  - test/utils.rb
71
76
  - test/fixtures/config.rb
77
+ - test/fixtures/custom.rb
72
78
  - test/scm/cvs_test.rb
73
79
  - test/scm/subversion_test.rb
74
80
  test_files: []
@@ -87,7 +93,7 @@ dependencies:
87
93
  -
88
94
  - ">="
89
95
  - !ruby/object:Gem::Version
90
- version: 1.0.5
96
+ version: 1.0.8
91
97
  version:
92
98
  - !ruby/object:Gem::Dependency
93
99
  name: net-sftp