tango 0.0.2 → 0.0.3
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.lock +1 -1
- data/bin/tango +12 -0
- data/lib/tango/dance.rb +9 -8
- data/lib/tango/dance_card.rb +32 -0
- data/lib/tango/logger.rb +30 -0
- data/lib/tango/noop_logger.rb +15 -0
- data/lib/tango/step_runner.rb +30 -5
- data/lib/tango/version.rb +1 -1
- data/lib/tango.rb +2 -2
- data/spec/dance_card_spec.rb +56 -0
- data/spec/logger_spec.rb +30 -0
- data/spec/step_runner_spec.rb +67 -0
- metadata +19 -9
- data/lib/tango/dance_builder.rb +0 -13
- data/lib/tango/step.rb +0 -14
- data/spec/step_spec.rb +0 -108
data/Gemfile.lock
CHANGED
data/bin/tango
ADDED
data/lib/tango/dance.rb
CHANGED
@@ -1,20 +1,21 @@
|
|
1
1
|
module Tango
|
2
2
|
class Dance
|
3
3
|
|
4
|
-
def initialize(&block)
|
5
|
-
@
|
6
|
-
|
4
|
+
def initialize(dance_card = nil, &block)
|
5
|
+
@dance_card = dance_card
|
6
|
+
@steps = {}
|
7
|
+
instance_eval(&block)
|
7
8
|
end
|
8
9
|
|
9
|
-
def
|
10
|
+
def step(name, &block)
|
10
11
|
raise StepAlreadyDefinedError, "Step #{name} already defined" if @steps.has_key?(name)
|
11
|
-
|
12
|
-
@steps[name] = step
|
12
|
+
@steps[name] = block
|
13
13
|
end
|
14
14
|
|
15
15
|
def run(step_name, *args)
|
16
|
-
|
17
|
-
|
16
|
+
step = @steps[step_name]
|
17
|
+
raise UndefinedStepError, "Step #{step_name} not defined" if step.nil?
|
18
|
+
StepRunner.new(@dance_card || self).instance_exec(*args, &step)
|
18
19
|
end
|
19
20
|
|
20
21
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'tango/logger'
|
2
|
+
require 'tango/noop_logger'
|
3
|
+
|
4
|
+
module Tango
|
5
|
+
class DanceCard
|
6
|
+
|
7
|
+
def self.instance
|
8
|
+
@dance_card ||= DanceCard.new(Logger.new)
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(logger = nil)
|
12
|
+
@logger = logger || NoopLogger.new
|
13
|
+
@dances = {}
|
14
|
+
end
|
15
|
+
|
16
|
+
def dance(name, &block)
|
17
|
+
@dances[name] = Dance.new(self, &block)
|
18
|
+
end
|
19
|
+
|
20
|
+
def run(name, *args)
|
21
|
+
dance_name, step_name = *name.split(":")
|
22
|
+
@logger.enter(name)
|
23
|
+
@dances[dance_name].run(step_name, *args)
|
24
|
+
@logger.leave(name)
|
25
|
+
end
|
26
|
+
|
27
|
+
def log(message)
|
28
|
+
@logger.log(message)
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
data/lib/tango/logger.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
module Tango
|
2
|
+
class Logger
|
3
|
+
|
4
|
+
def initialize(io = STDERR)
|
5
|
+
@io = io
|
6
|
+
@depth = 0
|
7
|
+
end
|
8
|
+
|
9
|
+
def enter(step_name)
|
10
|
+
@io.puts "#{indent}#{step_name} {\n"
|
11
|
+
@depth += 1
|
12
|
+
end
|
13
|
+
|
14
|
+
def log(message)
|
15
|
+
@io.puts "#{indent}#{message}\n"
|
16
|
+
end
|
17
|
+
|
18
|
+
def leave(step_name)
|
19
|
+
@depth -= 1
|
20
|
+
@io.puts "#{indent}} √ #{step_name}\n"
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def indent
|
26
|
+
" " * @depth
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
data/lib/tango/step_runner.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
module Tango
|
2
|
+
# A step's block is instance_execed against one of these. It provides all the
|
3
|
+
# methods accessible from within the step.
|
2
4
|
class StepRunner
|
3
5
|
|
4
|
-
def initialize(
|
5
|
-
@
|
6
|
+
def initialize(context = nil)
|
7
|
+
@context = context
|
6
8
|
end
|
7
9
|
|
8
10
|
def met?(&met_block)
|
@@ -11,14 +13,37 @@ module Tango
|
|
11
13
|
|
12
14
|
def meet(&meet_block)
|
13
15
|
raise MeetWithoutMetError if @met_block.nil?
|
14
|
-
|
16
|
+
if instance_eval(&@met_block)
|
17
|
+
log "already met."
|
18
|
+
else
|
19
|
+
log "not already met."
|
15
20
|
instance_eval(&meet_block)
|
16
|
-
|
21
|
+
if instance_eval(&@met_block)
|
22
|
+
log "met."
|
23
|
+
else
|
24
|
+
raise CouldNotMeetError
|
25
|
+
end
|
17
26
|
end
|
18
27
|
end
|
19
28
|
|
20
29
|
def run(step_name, *args)
|
21
|
-
@
|
30
|
+
@context.run(step_name, *args)
|
31
|
+
end
|
32
|
+
|
33
|
+
def as(username)
|
34
|
+
info = Etc.getpwent(username)
|
35
|
+
uid, gid = Process.euid, Process.egid
|
36
|
+
Process::Sys.seteuid(0) if uid != 0
|
37
|
+
Process::Sys.setegid(info.gid)
|
38
|
+
Process::Sys.seteuid(info.uid)
|
39
|
+
yield
|
40
|
+
ensure
|
41
|
+
Process::Sys.seteuid(uid)
|
42
|
+
Process::Sys.setegid(gid)
|
43
|
+
end
|
44
|
+
|
45
|
+
def log(message)
|
46
|
+
@context.log(message) unless @context.nil?
|
22
47
|
end
|
23
48
|
|
24
49
|
end
|
data/lib/tango/version.rb
CHANGED
data/lib/tango.rb
CHANGED
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'tango'
|
2
|
+
|
3
|
+
module Tango
|
4
|
+
describe DanceCard do
|
5
|
+
|
6
|
+
it "should run a step in a dance by name" do
|
7
|
+
step_run = false
|
8
|
+
card = DanceCard.new
|
9
|
+
card.dance "example dance" do
|
10
|
+
step "example step" do
|
11
|
+
step_run = true
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
card.run "example dance:example step"
|
16
|
+
|
17
|
+
step_run.should be_true
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should pass arguments to a step" do
|
21
|
+
card = DanceCard.new
|
22
|
+
card.dance "example dance" do
|
23
|
+
step "example step" do |a, b|
|
24
|
+
a.should == 1
|
25
|
+
b.should == 2
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
card.run "example dance:example step", 1, 2
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should call a step in another dance by name" do
|
33
|
+
step_run = false
|
34
|
+
|
35
|
+
card = DanceCard.new
|
36
|
+
|
37
|
+
card.dance "foxtrot" do
|
38
|
+
step "foxtrot step" do
|
39
|
+
step_run = true
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
card.dance "flamenco" do
|
44
|
+
step "flamenco step" do
|
45
|
+
run "foxtrot:foxtrot step"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
card.run "flamenco:flamenco step"
|
50
|
+
|
51
|
+
step_run.should be_true
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
data/spec/logger_spec.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'tango'
|
2
|
+
require 'stringio'
|
3
|
+
|
4
|
+
module Tango
|
5
|
+
describe Logger do
|
6
|
+
|
7
|
+
before do
|
8
|
+
@io = StringIO.new
|
9
|
+
@logger = Logger.new(@io)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should output the step name when entering a step" do
|
13
|
+
@logger.enter("example step")
|
14
|
+
@io.string.should == "example step {\n"
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should output a closing brace when leaving a step" do
|
18
|
+
@logger.enter("example step")
|
19
|
+
@logger.leave("example step")
|
20
|
+
@io.string.should == "example step {\n} √ example step\n"
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should indent nested steps" do
|
24
|
+
@logger.enter("outer step")
|
25
|
+
@logger.enter("inner step")
|
26
|
+
@io.string.should == "outer step {\n inner step {\n"
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'tango'
|
2
|
+
|
3
|
+
module Tango
|
4
|
+
describe StepRunner do
|
5
|
+
|
6
|
+
context "with a meet block and a met block" do
|
7
|
+
it "should check the met?, run the meet, then check the met? again" do
|
8
|
+
met_block_calls = 0
|
9
|
+
meet_block_calls = 0
|
10
|
+
|
11
|
+
StepRunner.new.instance_eval do
|
12
|
+
met? do
|
13
|
+
met_block_calls += 1
|
14
|
+
meet_block_calls > 0
|
15
|
+
end
|
16
|
+
meet { meet_block_calls += 1 }
|
17
|
+
end
|
18
|
+
|
19
|
+
met_block_calls.should == 2
|
20
|
+
meet_block_calls.should == 1
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should not run the meet if the met? succeeds the first time" do
|
24
|
+
met_block_calls = 0
|
25
|
+
meet_block_calls = 0
|
26
|
+
|
27
|
+
StepRunner.new.instance_eval do
|
28
|
+
met? do
|
29
|
+
met_block_calls += 1
|
30
|
+
true
|
31
|
+
end
|
32
|
+
meet { meet_block_calls += 1 }
|
33
|
+
end
|
34
|
+
|
35
|
+
met_block_calls.should == 1
|
36
|
+
meet_block_calls.should == 0
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should raise if the met? block fails twice" do
|
40
|
+
met_block_calls = 0
|
41
|
+
meet_block_calls = 0
|
42
|
+
|
43
|
+
expect do
|
44
|
+
StepRunner.new.instance_eval do
|
45
|
+
met? do
|
46
|
+
met_block_calls += 1
|
47
|
+
false
|
48
|
+
end
|
49
|
+
meet { meet_block_calls += 1 }
|
50
|
+
end
|
51
|
+
end.should raise_error(CouldNotMeetError)
|
52
|
+
|
53
|
+
met_block_calls.should == 2
|
54
|
+
meet_block_calls.should == 1
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should raise an error if there's a meet block without a met block" do
|
58
|
+
expect do
|
59
|
+
StepRunner.new.instance_eval do
|
60
|
+
meet { }
|
61
|
+
end
|
62
|
+
end.should raise_error(MeetWithoutMetError)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
metadata
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tango
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
hash: 25
|
4
5
|
prerelease: false
|
5
6
|
segments:
|
6
7
|
- 0
|
7
8
|
- 0
|
8
|
-
-
|
9
|
-
version: 0.0.
|
9
|
+
- 3
|
10
|
+
version: 0.0.3
|
10
11
|
platform: ruby
|
11
12
|
authors:
|
12
13
|
- Pete Yandell
|
@@ -14,7 +15,7 @@ autorequire:
|
|
14
15
|
bindir: bin
|
15
16
|
cert_chain: []
|
16
17
|
|
17
|
-
date: 2011-
|
18
|
+
date: 2011-03-29 00:00:00 +11:00
|
18
19
|
default_executable:
|
19
20
|
dependencies:
|
20
21
|
- !ruby/object:Gem::Dependency
|
@@ -25,6 +26,7 @@ dependencies:
|
|
25
26
|
requirements:
|
26
27
|
- - ">="
|
27
28
|
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
28
30
|
segments:
|
29
31
|
- 0
|
30
32
|
version: "0"
|
@@ -33,8 +35,8 @@ dependencies:
|
|
33
35
|
description: Experiment in deployment tools, taking ideas from babushka and elsewhere.
|
34
36
|
email:
|
35
37
|
- pete@notahat.com
|
36
|
-
executables:
|
37
|
-
|
38
|
+
executables:
|
39
|
+
- tango
|
38
40
|
extensions: []
|
39
41
|
|
40
42
|
extra_rdoc_files: []
|
@@ -45,15 +47,19 @@ files:
|
|
45
47
|
- Gemfile
|
46
48
|
- Gemfile.lock
|
47
49
|
- Rakefile
|
50
|
+
- bin/tango
|
48
51
|
- lib/tango.rb
|
49
52
|
- lib/tango/dance.rb
|
50
|
-
- lib/tango/
|
53
|
+
- lib/tango/dance_card.rb
|
51
54
|
- lib/tango/errors.rb
|
52
|
-
- lib/tango/
|
55
|
+
- lib/tango/logger.rb
|
56
|
+
- lib/tango/noop_logger.rb
|
53
57
|
- lib/tango/step_runner.rb
|
54
58
|
- lib/tango/version.rb
|
59
|
+
- spec/dance_card_spec.rb
|
55
60
|
- spec/dance_spec.rb
|
56
|
-
- spec/
|
61
|
+
- spec/logger_spec.rb
|
62
|
+
- spec/step_runner_spec.rb
|
57
63
|
- tango.gemspec
|
58
64
|
has_rdoc: true
|
59
65
|
homepage: ""
|
@@ -69,6 +75,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
69
75
|
requirements:
|
70
76
|
- - ">="
|
71
77
|
- !ruby/object:Gem::Version
|
78
|
+
hash: 3
|
72
79
|
segments:
|
73
80
|
- 0
|
74
81
|
version: "0"
|
@@ -77,6 +84,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
77
84
|
requirements:
|
78
85
|
- - ">="
|
79
86
|
- !ruby/object:Gem::Version
|
87
|
+
hash: 3
|
80
88
|
segments:
|
81
89
|
- 0
|
82
90
|
version: "0"
|
@@ -88,5 +96,7 @@ signing_key:
|
|
88
96
|
specification_version: 3
|
89
97
|
summary: Experiment in deployment tools.
|
90
98
|
test_files:
|
99
|
+
- spec/dance_card_spec.rb
|
91
100
|
- spec/dance_spec.rb
|
92
|
-
- spec/
|
101
|
+
- spec/logger_spec.rb
|
102
|
+
- spec/step_runner_spec.rb
|
data/lib/tango/dance_builder.rb
DELETED
data/lib/tango/step.rb
DELETED
data/spec/step_spec.rb
DELETED
@@ -1,108 +0,0 @@
|
|
1
|
-
require 'tango'
|
2
|
-
|
3
|
-
module Tango
|
4
|
-
describe Step do
|
5
|
-
|
6
|
-
context "with just a plain block" do
|
7
|
-
it "should run the block" do
|
8
|
-
block_calls = 0
|
9
|
-
step = Step.new do
|
10
|
-
block_calls += 1
|
11
|
-
end
|
12
|
-
|
13
|
-
step.run
|
14
|
-
block_calls.should == 1
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
context "with a meet block and a met block" do
|
19
|
-
it "should check the met?, run the meet, then check the met? again" do
|
20
|
-
met_block_calls = 0
|
21
|
-
meet_block_calls = 0
|
22
|
-
step = Step.new do
|
23
|
-
met? do
|
24
|
-
met_block_calls += 1
|
25
|
-
meet_block_calls > 0
|
26
|
-
end
|
27
|
-
meet { meet_block_calls += 1 }
|
28
|
-
end
|
29
|
-
|
30
|
-
step.run
|
31
|
-
met_block_calls.should == 2
|
32
|
-
meet_block_calls.should == 1
|
33
|
-
end
|
34
|
-
|
35
|
-
it "should not run the meet if the met? succeeds the first time" do
|
36
|
-
met_block_calls = 0
|
37
|
-
meet_block_calls = 0
|
38
|
-
step = Step.new do
|
39
|
-
met? do
|
40
|
-
met_block_calls += 1
|
41
|
-
true
|
42
|
-
end
|
43
|
-
meet { meet_block_calls += 1 }
|
44
|
-
end
|
45
|
-
|
46
|
-
step.run
|
47
|
-
met_block_calls.should == 1
|
48
|
-
meet_block_calls.should == 0
|
49
|
-
end
|
50
|
-
|
51
|
-
it "should raise if the met? block fails twice" do
|
52
|
-
met_block_calls = 0
|
53
|
-
meet_block_calls = 0
|
54
|
-
step = Step.new do
|
55
|
-
met? do
|
56
|
-
met_block_calls += 1
|
57
|
-
false
|
58
|
-
end
|
59
|
-
meet { meet_block_calls += 1 }
|
60
|
-
end
|
61
|
-
|
62
|
-
expect { step.run }.should raise_error(CouldNotMeetError)
|
63
|
-
met_block_calls.should == 2
|
64
|
-
meet_block_calls.should == 1
|
65
|
-
end
|
66
|
-
|
67
|
-
it "should raise an error if there's a meet block without a met block" do
|
68
|
-
step = Step.new do
|
69
|
-
meet { }
|
70
|
-
end
|
71
|
-
|
72
|
-
expect { step.run }.should raise_error(MeetWithoutMetError)
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
context "step arguments" do
|
77
|
-
it "should pass a single argument to the step" do
|
78
|
-
step = Step.new do |a|
|
79
|
-
a.should == 1
|
80
|
-
end
|
81
|
-
|
82
|
-
step.run(1)
|
83
|
-
end
|
84
|
-
|
85
|
-
it "should pass multiple arguments to the step" do
|
86
|
-
step = Step.new do |a, b|
|
87
|
-
a.should == 1
|
88
|
-
b.should == 2
|
89
|
-
end
|
90
|
-
|
91
|
-
step.run(1, 2)
|
92
|
-
end
|
93
|
-
|
94
|
-
it "should capture arguments in the met? and meet blocks" do
|
95
|
-
step = Step.new do |argument|
|
96
|
-
met? do
|
97
|
-
argument.should == 1
|
98
|
-
false
|
99
|
-
end
|
100
|
-
meet { argument.should == 1 }
|
101
|
-
end
|
102
|
-
|
103
|
-
expect { step.run(1) }.should raise_error(CouldNotMeetError)
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
end
|
108
|
-
end
|