tango 0.0.9 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- tango (0.0.9)
4
+ tango (0.1.0)
5
5
 
6
6
  GEM
7
7
  remote: http://rubygems.org/
data/README.md CHANGED
@@ -31,10 +31,8 @@ Example Runner
31
31
  shell("dpkg-query", "--status", package, :echo => false).output !~ /not.installed|deinstall/
32
32
  end
33
33
 
34
- step "install" do |package|
34
+ step :install do |package|
35
35
  met? { installed?(package) }
36
- # Need to figure out how to make this non-interactive. See:
37
- # http://ubuntuforums.org/showthread.php?t=1218525
38
36
  meet { shell("apt-get", "install", "-y", package) }
39
37
  end
40
38
  end
@@ -44,7 +42,7 @@ Example Runner
44
42
  shell("gem", "query", "--installed", "--name-matches", gem, :echo => false).output =~ /true/
45
43
  end
46
44
 
47
- step "install" do |gem|
45
+ step :install do |gem|
48
46
  met? { installed?(gem) }
49
47
  meet { shell("gem", "install", gem) }
50
48
  end
@@ -56,7 +54,7 @@ Example Runner
56
54
  @gem = GemInstaller.new
57
55
  end
58
56
 
59
- step "install" do
57
+ step :install do
60
58
  @apt.install "build-essential"
61
59
 
62
60
  @apt.install "mysql-server"
@@ -71,23 +69,25 @@ Example Runner
71
69
  Running the Example
72
70
  -------------------
73
71
 
74
- tango example_installer.rb ExampleInstaller.install
72
+ sudo tango example_installer.rb ExampleInstaller.install
75
73
 
76
74
  Useful Helper Methods
77
75
  ---------------------
78
76
 
79
77
  ### Running Shell Commands
80
78
 
81
- step "install something" do
79
+ step :install_something do
82
80
  result = shell("apt-get", "install", "something")
83
81
  if result.succeeded?
84
82
  write("/tmp/something-install.log", result.output)
85
83
  end
86
84
  end
87
85
 
86
+ Use shell! to raise an exception if the command exits with non-zero status.
87
+
88
88
  ### Writing Config Files
89
89
 
90
- step "configure foo" do
90
+ step :configure_foo do
91
91
  @log_directory = "/var/log/foo.log"
92
92
  write "/etc/foo.conf", <<-EOF
93
93
  # Config file for foo
@@ -95,27 +95,44 @@ Useful Helper Methods
95
95
  end
96
96
  end
97
97
 
98
+ ### Fetching a Remote URL
99
+
100
+ step :install do
101
+ cd "/tmp" do
102
+ fetch "http://example.com/something.tar.gz"
103
+ end
104
+ end
105
+
106
+ Chainable Helper Methods
107
+ ------------------------
108
+
109
+ You can use these together like this:
110
+
111
+ in_directory("/tmp").with_umask(0022) do
112
+ ...
113
+ end
114
+
98
115
  ### Changing the Working Directory
99
116
 
100
- step "migrate" do
101
- cd "/rails_apps/blog" do
117
+ step :migrate do
118
+ in_directory "/rails_apps/blog" do
102
119
  shell "rake db:migrate"
103
120
  end
104
121
  end
105
122
 
106
- ### Running As Another User
123
+ ### Changing the umask
107
124
 
108
- step "..." do
109
- as "fred" do
110
- FileUtils.touch("/home/fred/fred_woz_ere")
125
+ step :install do
126
+ with_umask 0077 do
127
+ shell "make install"
111
128
  end
112
129
  end
113
130
 
114
- ### Fetching a Remote URL
131
+ ### Running As Another User
115
132
 
116
- step "..." do
117
- cd "/tmp" do
118
- fetch "http://example.com/something.tar.gz"
133
+ step :install do
134
+ as_user "fred" do
135
+ FileUtils.touch("/home/fred/fred_woz_ere")
119
136
  end
120
137
  end
121
138
 
@@ -1,2 +1,3 @@
1
+ require 'tango/contexts'
1
2
  require 'tango/logger'
2
3
  require 'tango/runner'
@@ -0,0 +1,4 @@
1
+ require 'tango/contexts/chain'
2
+ require 'tango/contexts/directory'
3
+ require 'tango/contexts/helpers'
4
+ require 'tango/contexts/umask'
@@ -0,0 +1,36 @@
1
+ require 'tango/contexts/helpers'
2
+
3
+ module Tango
4
+ module Contexts
5
+ class Chain
6
+
7
+ include Helpers
8
+
9
+ def initialize
10
+ @contexts = []
11
+ end
12
+
13
+ def in_context(context, &block)
14
+ @contexts << context
15
+ if block_given?
16
+ call_in_contexts(&block)
17
+ else
18
+ self
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def call_in_contexts
25
+ @contexts.each {|context| context.enter }
26
+ begin
27
+ yield
28
+ ensure
29
+ @contexts.reverse.each {|context| context.leave }
30
+ end
31
+ end
32
+
33
+ end
34
+ end
35
+ end
36
+
@@ -0,0 +1,20 @@
1
+ module Tango
2
+ module Contexts
3
+ class Directory
4
+
5
+ def initialize(directory)
6
+ @directory = directory
7
+ end
8
+
9
+ def enter
10
+ @old_directory = Dir.getwd
11
+ Dir.chdir(@directory)
12
+ end
13
+
14
+ def leave
15
+ Dir.chdir(@old_directory)
16
+ end
17
+
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,19 @@
1
+ module Tango
2
+ module Contexts
3
+ module Helpers
4
+
5
+ def in_context(context, &block)
6
+ Chain.new.in_context(context, &block)
7
+ end
8
+
9
+ def in_directory(directory, &block)
10
+ in_context(Directory.new(directory), &block)
11
+ end
12
+
13
+ def with_umask(umask, &block)
14
+ in_context(Umask.new(umask), &block)
15
+ end
16
+
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ module Tango
2
+ module Contexts
3
+ class Umask
4
+
5
+ def initialize(umask)
6
+ @umask = umask
7
+ end
8
+
9
+ def enter
10
+ @old_umask = File.umask(@umask)
11
+ end
12
+
13
+ def leave
14
+ File.umask(@old_umask)
15
+ end
16
+
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,24 @@
1
+ module Tango
2
+ module Contexts
3
+ class User
4
+
5
+ def initialize(username)
6
+ @username = username
7
+ end
8
+
9
+ def enter
10
+ @uid, @gid = Process.euid, Process.egid
11
+ Process::Sys.seteuid(0) if @uid != 0
12
+ info = Etc.getpwnam(@username)
13
+ Process::Sys.setegid(info.gid)
14
+ Process::Sys.seteuid(info.uid)
15
+ end
16
+
17
+ def leave
18
+ Process::Sys.seteuid(@uid)
19
+ Process::Sys.setegid(@gid)
20
+ end
21
+
22
+ end
23
+ end
24
+ end
@@ -1,20 +1,18 @@
1
- require 'tango/as_user'
2
1
  require 'tango/config_files'
2
+ require 'tango/contexts/helpers'
3
3
  require 'tango/delegate'
4
4
  require 'tango/fetch'
5
5
  require 'tango/met_and_meet'
6
6
  require 'tango/shell'
7
- require 'tango/working_directory'
8
7
 
9
8
  module Tango
10
9
  class Runner
11
- include AsUser
12
10
  include ConfigFiles
11
+ include Contexts::Helpers
13
12
  include Delegate
14
13
  include Fetch
15
14
  include MetAndMeet
16
15
  include Shell
17
- include WorkingDirectory
18
16
 
19
17
  def self.step(step_name, &block)
20
18
  define_method(step_name) do |*args|
@@ -1,3 +1,3 @@
1
1
  module Tango
2
- VERSION = "0.0.9"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -0,0 +1,78 @@
1
+ require 'tango'
2
+
3
+ module Tango::Contexts
4
+ describe Chain do
5
+
6
+ before do
7
+ @context_class = Class.new do
8
+ def in_context?
9
+ @in_context
10
+ end
11
+
12
+ def initialize
13
+ @in_context = false
14
+ end
15
+
16
+ def enter
17
+ @in_context = true
18
+ end
19
+
20
+ def leave
21
+ @in_context = false
22
+ end
23
+ end
24
+
25
+ @context = @context_class.new
26
+ end
27
+
28
+ it "should run a block" do
29
+ block_run = false
30
+ Chain.new.in_context(@context) { block_run = true }
31
+ block_run.should be_true
32
+ end
33
+
34
+ it "should return the return value of the block" do
35
+ result = Chain.new.in_context(@context) { "I woz ere." }
36
+ result.should == "I woz ere."
37
+ end
38
+
39
+ it "should run the context's enter method before the block" do
40
+ Chain.new.in_context(@context) do
41
+ @context.should be_in_context
42
+ end
43
+ end
44
+
45
+ it "should run the context's leave method after leaving the block" do
46
+ Chain.new.in_context(@context) { }
47
+ @context.should_not be_in_context
48
+ end
49
+
50
+ it "should run the context's leave method on an exception" do
51
+ expect {
52
+ Chain.new.in_context(@context) { raise "Uh oh" }
53
+ }.should raise_error("Uh oh")
54
+ @context.should_not be_in_context
55
+ end
56
+
57
+ describe "when chaining contexts" do
58
+ before do
59
+ @a = @context_class.new
60
+ @b = @context_class.new
61
+ end
62
+
63
+ it "should run the enter method of each context" do
64
+ Chain.new.in_context(@a).in_context(@b) do
65
+ @a.should be_in_context
66
+ @b.should be_in_context
67
+ end
68
+ end
69
+
70
+ it "should run the leave method of each context" do
71
+ Chain.new.in_context(@a).in_context(@b) { }
72
+ @a.should_not be_in_context
73
+ @b.should_not be_in_context
74
+ end
75
+ end
76
+
77
+ end
78
+ end
@@ -0,0 +1,37 @@
1
+ require 'tango'
2
+
3
+ module Tango::Contexts
4
+ describe Directory do
5
+
6
+ before do
7
+ stub_class = Class.new do
8
+ include Helpers
9
+ end
10
+ @stub = stub_class.new
11
+
12
+ # Make doubly sure we reset the working directory after each test.
13
+ @original_directory = Dir.getwd
14
+ end
15
+
16
+ after do
17
+ Dir.chdir(@original_directory)
18
+ end
19
+
20
+ it "should change the working directory" do
21
+ directory = Dir.getwd + "/lib"
22
+ @stub.in_directory(directory) do
23
+ Dir.getwd.should == directory
24
+ end
25
+ end
26
+
27
+ it "should restore the original working directory" do
28
+ old_directory = Dir.getwd
29
+ directory = Dir.getwd + "/lib"
30
+ @stub.in_directory(directory) { }
31
+ Dir.getwd.should == old_directory
32
+ end
33
+
34
+ end
35
+ end
36
+
37
+
@@ -0,0 +1,33 @@
1
+ require 'tango'
2
+
3
+ module Tango::Contexts
4
+ describe Umask do
5
+
6
+ before do
7
+ stub_class = Class.new do
8
+ include Helpers
9
+ end
10
+ @stub = stub_class.new
11
+
12
+ # Make double sure we reset the umask after each test.
13
+ @original_umask = File.umask
14
+ end
15
+
16
+ after do
17
+ File.umask(@original_umask)
18
+ end
19
+
20
+ it "should change the umask" do
21
+ @stub.with_umask(0777) do
22
+ File.umask.should == 0777
23
+ end
24
+ end
25
+
26
+ it "should restore the original umask" do
27
+ old_umask = File.umask
28
+ @stub.with_umask(0777) { }
29
+ File.umask.should == old_umask
30
+ end
31
+
32
+ end
33
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tango
3
3
  version: !ruby/object:Gem::Version
4
- hash: 13
4
+ hash: 27
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
+ - 1
8
9
  - 0
9
- - 9
10
- version: 0.0.9
10
+ version: 0.1.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Pete Yandell
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-04-13 00:00:00 +10:00
18
+ date: 2011-04-14 00:00:00 +10:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -51,8 +51,13 @@ files:
51
51
  - Rakefile
52
52
  - bin/tango
53
53
  - lib/tango.rb
54
- - lib/tango/as_user.rb
55
54
  - lib/tango/config_files.rb
55
+ - lib/tango/contexts.rb
56
+ - lib/tango/contexts/chain.rb
57
+ - lib/tango/contexts/directory.rb
58
+ - lib/tango/contexts/helpers.rb
59
+ - lib/tango/contexts/umask.rb
60
+ - lib/tango/contexts/user.rb
56
61
  - lib/tango/delegate.rb
57
62
  - lib/tango/fetch.rb
58
63
  - lib/tango/logger.rb
@@ -60,14 +65,16 @@ files:
60
65
  - lib/tango/runner.rb
61
66
  - lib/tango/shell.rb
62
67
  - lib/tango/version.rb
63
- - lib/tango/working_directory.rb
64
68
  - spec/config_files_spec.rb
69
+ - spec/contexts/chain_spec.rb
70
+ - spec/contexts/directory_spec.rb
71
+ - spec/contexts/umask_spec.rb
65
72
  - spec/logger_spec.rb
66
73
  - spec/met_and_meet_spec.rb
67
74
  - spec/runner_spec.rb
68
75
  - spec/shell_spec.rb
69
- - spec/working_directory_spec.rb
70
76
  - tango.gemspec
77
+ - tmp/.gitignore
71
78
  has_rdoc: true
72
79
  homepage: ""
73
80
  licenses: []
@@ -104,8 +111,10 @@ specification_version: 3
104
111
  summary: Experiment in deployment tools.
105
112
  test_files:
106
113
  - spec/config_files_spec.rb
114
+ - spec/contexts/chain_spec.rb
115
+ - spec/contexts/directory_spec.rb
116
+ - spec/contexts/umask_spec.rb
107
117
  - spec/logger_spec.rb
108
118
  - spec/met_and_meet_spec.rb
109
119
  - spec/runner_spec.rb
110
120
  - spec/shell_spec.rb
111
- - spec/working_directory_spec.rb
@@ -1,17 +0,0 @@
1
- module Tango
2
- module AsUser
3
-
4
- def as(username)
5
- info = Etc.getpwent(username)
6
- uid, gid = Process.euid, Process.egid
7
- Process::Sys.seteuid(0) if uid != 0
8
- Process::Sys.setegid(info.gid)
9
- Process::Sys.seteuid(info.uid)
10
- yield
11
- ensure
12
- Process::Sys.seteuid(uid)
13
- Process::Sys.setegid(gid)
14
- end
15
-
16
- end
17
- end
@@ -1,15 +0,0 @@
1
- module Tango
2
- module WorkingDirectory
3
-
4
- def cd(directory)
5
- old_directory = Dir.getwd
6
- begin
7
- Dir.chdir(directory)
8
- yield
9
- ensure
10
- Dir.chdir(old_directory)
11
- end
12
- end
13
-
14
- end
15
- end
@@ -1,57 +0,0 @@
1
- require 'tango'
2
-
3
- module Tango
4
- describe WorkingDirectory do
5
-
6
- before do
7
- stub_class = Class.new do
8
- include WorkingDirectory
9
- end
10
- @stub = stub_class.new
11
-
12
- # Make doubly sure we reset the working directory after each test.
13
- @original_directory = Dir.getwd
14
- end
15
-
16
- after do
17
- Dir.chdir(@original_directory)
18
- end
19
-
20
- it "should run a block" do
21
- block_run = false
22
- @stub.cd("/tmp") { block_run = true }
23
- block_run.should be_true
24
- end
25
-
26
- it "should return the return value of the block" do
27
- result = @stub.cd("/tmp") { "I woz ere." }
28
- result.should == "I woz ere."
29
- end
30
-
31
- it "should change directory" do
32
- directory = Dir.getwd + "/lib"
33
- @stub.cd(directory) do
34
- Dir.getwd.should == directory
35
- end
36
- end
37
-
38
- it "should restore the original working directory" do
39
- old_directory = Dir.getwd
40
- directory = Dir.getwd + "/lib"
41
- @stub.cd(directory) { }
42
- Dir.getwd.should == old_directory
43
- end
44
-
45
- it "should restore the original directory after an exception" do
46
- old_directory = Dir.getwd
47
- directory = Dir.getwd + "/lib"
48
- expect {
49
- @stub.cd(directory) { raise "Uh oh!" }
50
- }.should raise_error
51
- Dir.getwd.should == old_directory
52
- end
53
-
54
- end
55
- end
56
-
57
-