tango 0.0.4 → 0.0.5
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/.gitignore +1 -0
- data/Gemfile.lock +1 -1
- data/README.md +5 -5
- data/lib/tango/logger.rb +10 -5
- data/lib/tango/namespace.rb +6 -0
- data/lib/tango/shell.rb +57 -0
- data/lib/tango/version.rb +1 -1
- data/spec/shell_spec.rb +51 -0
- metadata +9 -6
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -15,17 +15,17 @@ Example
|
|
15
15
|
|
16
16
|
class Homebrew < Tango::Namespace
|
17
17
|
def installed?(formula)
|
18
|
-
|
18
|
+
shell("brew", "info", formula, :echo => false).output !~ /Not installed/
|
19
19
|
end
|
20
20
|
|
21
21
|
step "bootstrap" do
|
22
|
-
met? {
|
23
|
-
meet {
|
22
|
+
met? { shell("brew info").succeeded? }
|
23
|
+
meet { shell(%{ruby -e "$(curl -fsSL https://gist.github.com/raw/323731/install_homebrew.rb)"}) }
|
24
24
|
end
|
25
25
|
|
26
26
|
step "install" do |formula|
|
27
27
|
met? { installed?(formula) }
|
28
|
-
meet {
|
28
|
+
meet { shell("brew, "install", formula) }
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
@@ -39,7 +39,7 @@ Example
|
|
39
39
|
|
40
40
|
step "install mtr" do
|
41
41
|
met? { Homebrew.installed?("mtr") }
|
42
|
-
meet {
|
42
|
+
meet { shell("brew install --no-gtk mtr") }
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
data/lib/tango/logger.rb
CHANGED
@@ -10,17 +10,21 @@ module Tango
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def enter(step_name)
|
13
|
-
|
13
|
+
log "#{step_name} {"
|
14
14
|
@depth += 1
|
15
15
|
end
|
16
16
|
|
17
|
+
def leave(step_name)
|
18
|
+
@depth -= 1
|
19
|
+
log "} √ #{step_name}"
|
20
|
+
end
|
21
|
+
|
17
22
|
def log(message)
|
18
|
-
@io.puts "#{indent}#{message}
|
23
|
+
@io.puts "#{indent}#{message}"
|
19
24
|
end
|
20
25
|
|
21
|
-
def
|
22
|
-
@
|
23
|
-
@io.puts "#{indent}} √ #{step_name}\n"
|
26
|
+
def log_raw(message)
|
27
|
+
@io.write message
|
24
28
|
end
|
25
29
|
|
26
30
|
private
|
@@ -31,3 +35,4 @@ module Tango
|
|
31
35
|
|
32
36
|
end
|
33
37
|
end
|
38
|
+
|
data/lib/tango/namespace.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
require 'tango/as_user'
|
2
2
|
require 'tango/met_and_meet'
|
3
|
+
require 'tango/shell'
|
3
4
|
|
4
5
|
module Tango
|
5
6
|
class Namespace
|
6
7
|
include AsUser
|
7
8
|
include MetAndMeet
|
9
|
+
include Shell
|
8
10
|
|
9
11
|
def self.step(step_name, &block)
|
10
12
|
define_method(step_name, &block)
|
@@ -27,6 +29,10 @@ module Tango
|
|
27
29
|
self.class.logger.log(message)
|
28
30
|
end
|
29
31
|
|
32
|
+
def log_raw(message)
|
33
|
+
self.class.logger.log_raw(message)
|
34
|
+
end
|
35
|
+
|
30
36
|
def self.method_missing(method, *args)
|
31
37
|
new.send(method, *args)
|
32
38
|
end
|
data/lib/tango/shell.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
|
3
|
+
module Tango
|
4
|
+
module Shell
|
5
|
+
|
6
|
+
def shell(command, *args)
|
7
|
+
options = { :echo => true }
|
8
|
+
options.merge!(args.pop) if args.last.is_a?(Hash)
|
9
|
+
|
10
|
+
log "% #{command} #{args.join(' ')}\n\n" if options[:echo]
|
11
|
+
|
12
|
+
pid, pipe = fork_and_exec(command, *args)
|
13
|
+
output = collect_output(pipe, options[:echo])
|
14
|
+
Process.waitpid(pid)
|
15
|
+
pipe.close
|
16
|
+
|
17
|
+
OpenStruct.new(
|
18
|
+
:output => output,
|
19
|
+
:status => $?.exitstatus,
|
20
|
+
:succeeded? => $?.success?,
|
21
|
+
:failed? => !$?.success?
|
22
|
+
)
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def fork_and_exec(command, *args)
|
28
|
+
read_end, write_end = IO.pipe
|
29
|
+
pid = fork do
|
30
|
+
read_end.close
|
31
|
+
STDOUT.reopen(write_end)
|
32
|
+
STDERR.reopen(write_end)
|
33
|
+
exec(command, *args)
|
34
|
+
end
|
35
|
+
write_end.close
|
36
|
+
|
37
|
+
return pid, read_end
|
38
|
+
end
|
39
|
+
|
40
|
+
def collect_output(pipe, echo = true)
|
41
|
+
output = ""
|
42
|
+
|
43
|
+
begin
|
44
|
+
loop do
|
45
|
+
partial = pipe.readpartial(4096)
|
46
|
+
log_raw(partial) if echo
|
47
|
+
output << partial
|
48
|
+
end
|
49
|
+
rescue EOFError
|
50
|
+
end
|
51
|
+
|
52
|
+
output
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
data/lib/tango/version.rb
CHANGED
data/spec/shell_spec.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'tango'
|
2
|
+
|
3
|
+
module Tango
|
4
|
+
describe Shell do
|
5
|
+
|
6
|
+
before do
|
7
|
+
@stub_class = Class.new do
|
8
|
+
include Tango::Shell
|
9
|
+
def log(message); end
|
10
|
+
def log_raw(message); end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should return the right info for a successful command" do
|
15
|
+
result = @stub_class.new.shell("echo", "Hello, world!")
|
16
|
+
result.output.should == "Hello, world!\n"
|
17
|
+
result.status.should == 0
|
18
|
+
result.succeeded?.should be_true
|
19
|
+
result.failed?.should be_false
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should return the right info for a failing command" do
|
23
|
+
result = @stub_class.new.shell("test", "a", "=", "b")
|
24
|
+
result.status.should == 1
|
25
|
+
result.succeeded?.should be_false
|
26
|
+
result.failed?.should be_true
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should accept commands as a single argument" do
|
30
|
+
result = @stub_class.new.shell("echo Hello, world!")
|
31
|
+
result.output.should == "Hello, world!\n"
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should echo the command and its output" do
|
35
|
+
@stub = @stub_class.new
|
36
|
+
@stub.should_receive(:log).with("% echo Hello, world!\n\n")
|
37
|
+
@stub.should_receive(:log_raw).with("Hello, world!\n")
|
38
|
+
|
39
|
+
@stub.shell("echo", "Hello, world!")
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should allow echo to be turned off" do
|
43
|
+
@stub = @stub_class.new
|
44
|
+
@stub.should_not_receive(:log)
|
45
|
+
@stub.should_not_receive(:log_raw)
|
46
|
+
|
47
|
+
@stub.shell("echo", "Hello, world!", :echo => false).output.should == "Hello, world!\n"
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
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:
|
5
|
-
prerelease:
|
4
|
+
hash: 21
|
5
|
+
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 5
|
10
|
+
version: 0.0.5
|
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-
|
18
|
+
date: 2011-04-01 00:00:00 +11:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -54,10 +54,12 @@ files:
|
|
54
54
|
- lib/tango/logger.rb
|
55
55
|
- lib/tango/met_and_meet.rb
|
56
56
|
- lib/tango/namespace.rb
|
57
|
+
- lib/tango/shell.rb
|
57
58
|
- lib/tango/version.rb
|
58
59
|
- spec/logger_spec.rb
|
59
60
|
- spec/met_and_meet_spec.rb
|
60
61
|
- spec/namespace_spec.rb
|
62
|
+
- spec/shell_spec.rb
|
61
63
|
- tango.gemspec
|
62
64
|
has_rdoc: true
|
63
65
|
homepage: ""
|
@@ -89,7 +91,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
89
91
|
requirements: []
|
90
92
|
|
91
93
|
rubyforge_project: tango
|
92
|
-
rubygems_version: 1.
|
94
|
+
rubygems_version: 1.6.2
|
93
95
|
signing_key:
|
94
96
|
specification_version: 3
|
95
97
|
summary: Experiment in deployment tools.
|
@@ -97,3 +99,4 @@ test_files:
|
|
97
99
|
- spec/logger_spec.rb
|
98
100
|
- spec/met_and_meet_spec.rb
|
99
101
|
- spec/namespace_spec.rb
|
102
|
+
- spec/shell_spec.rb
|