tango 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -2,3 +2,4 @@ pkg/*
2
2
  *.gem
3
3
  .bundle
4
4
  .DS_Store
5
+ .rvmrc
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- tango (0.0.4)
4
+ tango (0.0.5)
5
5
 
6
6
  GEM
7
7
  remote: http://rubygems.org/
data/README.md CHANGED
@@ -15,17 +15,17 @@ Example
15
15
 
16
16
  class Homebrew < Tango::Namespace
17
17
  def installed?(formula)
18
- `brew info #{formula}` !~ /Not installed/
18
+ shell("brew", "info", formula, :echo => false).output !~ /Not installed/
19
19
  end
20
20
 
21
21
  step "bootstrap" do
22
- met? { system "brew info" }
23
- meet { system %{ruby -e "$(curl -fsSL https://gist.github.com/raw/323731/install_homebrew.rb)"} }
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 { system "brew install #{formula}" }
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 { system "brew install --no-gtk mtr" }
42
+ meet { shell("brew install --no-gtk mtr") }
43
43
  end
44
44
  end
45
45
 
@@ -10,17 +10,21 @@ module Tango
10
10
  end
11
11
 
12
12
  def enter(step_name)
13
- @io.puts "#{indent}#{step_name} {\n"
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}\n"
23
+ @io.puts "#{indent}#{message}"
19
24
  end
20
25
 
21
- def leave(step_name)
22
- @depth -= 1
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
+
@@ -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
@@ -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
+
@@ -1,3 +1,3 @@
1
1
  module Tango
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.5"
3
3
  end
@@ -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: 23
5
- prerelease: false
4
+ hash: 21
5
+ prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 4
10
- version: 0.0.4
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-03-30 00:00:00 +11:00
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.3.7
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