gofer 0.2.5 → 0.2.6

Sign up to get free protection for your applications and to get access to all the features.
data/lib/gofer/host.rb CHANGED
@@ -2,38 +2,41 @@ require 'tempfile'
2
2
 
3
3
  module Gofer
4
4
  class HostError < Exception # :nodoc:
5
- def initialize host, message
5
+ attr_reader :host, :response
6
+ def initialize host, response, message
7
+ @host = host
8
+ @response = response
6
9
  super "#{host.hostname}: #{message}"
7
10
  end
8
11
  end
9
-
12
+
10
13
  class Host
11
-
14
+
12
15
  attr_reader :hostname
13
16
  attr_accessor :quiet
14
17
 
15
18
  # Create a new Host connection
16
- #
19
+ #
17
20
  # Options:
18
- #
21
+ #
19
22
  # +quiet+:: Don't print stdout output from +run+ commands
20
23
  # All other+opts+ is passed through directly to Net::SSH.start
21
24
  # See http://net-ssh.github.com/ssh/v2/api/index.html for valid arguments.
22
25
  def initialize _hostname, username, opts={}
23
26
  @hostname = _hostname
24
-
27
+
25
28
  # support legacy positional argument use
26
29
  if opts.is_a? String
27
30
  opts = { :keys => [opts]}
28
31
  end
29
-
32
+
30
33
  @quiet = opts.delete(:quiet)
31
-
34
+
32
35
  # support legacy identity_file argument
33
36
  if opts[:identity_file]
34
37
  opts[:keys] = [opts.delete(:identity_file)]
35
38
  end
36
-
39
+
37
40
  @ssh = SshWrapper.new(hostname, username, opts)
38
41
  end
39
42
 
@@ -41,10 +44,10 @@ module Gofer
41
44
  #
42
45
  # Raise an error if +command+ exits with a non-zero status.
43
46
  #
44
- # Print +stdout+ and +stderr+ as they're received.
47
+ # Print +stdout+ and +stderr+ as they're received.
45
48
  #
46
49
  # Return a Gofer::Response object.
47
- #
50
+ #
48
51
  # Options:
49
52
  #
50
53
  # +quiet+:: Don't print +stdout+, can also be set with +quiet=+ on the instance
@@ -54,19 +57,19 @@ module Gofer
54
57
  opts[:quiet] = quiet unless opts.include?(:quiet)
55
58
  response = @ssh.run command, opts
56
59
  if !opts[:capture_exit_status] && response.exit_status != 0
57
- raise HostError.new(self, "Command #{command} failed with exit status #{@ssh.last_exit_status}")
60
+ raise HostError.new(self, response, "Command #{command} failed with exit status #{@ssh.last_exit_status}")
58
61
  end
59
62
  response
60
63
  end
61
-
64
+
62
65
  # Run +commands+ one by one in order.
63
66
  #
64
67
  # Raise an error if a command in +commands+ exits with a non-zero status.
65
68
  #
66
- # Print +stdout+ and +stderr+ as they're received.
69
+ # Print +stdout+ and +stderr+ as they're received.
67
70
  #
68
71
  # Return a Gofer::Response object.
69
- #
72
+ #
70
73
  # Options:
71
74
  #
72
75
  # +quiet+:: Don't print +stdout+, can also be set with +quiet=+ on the instance
@@ -75,11 +78,11 @@ module Gofer
75
78
  # The behaviour of passing +capture_exit_status+ here is undefined.
76
79
  def run_multiple commands, opts={}
77
80
  return if commands.empty?
78
-
81
+
79
82
  responses = commands.map do |command|
80
83
  run command, opts
81
84
  end
82
-
85
+
83
86
  first_response = responses.shift
84
87
  responses.reduce(first_response) do |cursor, response|
85
88
  Response.new(cursor.stdout + response.stdout, cursor.stderr + response.stderr, cursor.output + response.output, 0)
@@ -91,7 +94,7 @@ module Gofer
91
94
  @ssh.run("sh -c '[ -e #{path} ]'").exit_status == 0
92
95
  end
93
96
 
94
- # Return the contents of the file at +path+.
97
+ # Return the contents of the file at +path+.
95
98
  def read path
96
99
  @ssh.read_file path
97
100
  end
@@ -107,20 +110,20 @@ module Gofer
107
110
  if response.exit_status == 0
108
111
  response.stdout.strip.split("\n")
109
112
  else
110
- raise HostError.new(self, "Could not list #{path}, exit status #{response.exit_status}")
113
+ raise HostError.new(self, response, "Could not list #{path}, exit status #{response.exit_status}")
111
114
  end
112
115
  end
113
116
 
114
- # Upload the file or directory at +from+ to +to+.
115
- def upload from, to
116
- @ssh.upload from, to, :recursive => File.directory?(from)
117
+ # Upload the file or directory at +from+ to +to+.
118
+ def upload from, to, opts = {}
119
+ @ssh.upload from, to, {:recursive => File.directory?(from)}.merge(opts)
117
120
  end
118
121
 
119
122
  # Download the file or directory at +from+ to +to+
120
- def download from, to
121
- @ssh.download from, to, :recursive => directory?(from)
123
+ def download from, to, opts = {}
124
+ @ssh.download from, to, {:recursive => directory?(from)}.merge(opts)
122
125
  end
123
-
126
+
124
127
  # Write +data+ to a file at +to+
125
128
  def write data, to
126
129
  Tempfile.open "gofer_write" do |file|
data/lib/gofer/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Gofer # :nodoc:
2
- VERSION = "0.2.5"
3
- end
2
+ VERSION = "0.2.6"
3
+ end
@@ -2,21 +2,21 @@ require 'spec_helper'
2
2
  require 'tempfile'
3
3
 
4
4
  describe Gofer do
5
-
5
+
6
6
  HOSTNAME = ENV['TEST_HOST'] || 'localhost'
7
7
  USERNAME = ENV['TEST_USER'] || ENV['USER']
8
8
  IDENTITY_FILE = ENV['TEST_IDENTITY_FILE'] || '~/.ssh/id_rsa'
9
9
 
10
10
  def raw_ssh command
11
11
  out = `ssh -o PasswordAuthentication=no -ni #{IDENTITY_FILE} #{USERNAME}@#{HOSTNAME} #{command}`
12
- raise "Command #{command} failed" unless $? == 0
12
+ raise "Command #{command} failed" unless $? == 0
13
13
  out
14
14
  end
15
15
 
16
16
  def in_tmpdir path
17
17
  File.join(@tmpdir, path)
18
18
  end
19
-
19
+
20
20
  def with_local_tmpdir template
21
21
  f = Tempfile.new template
22
22
  path = f.path
@@ -28,7 +28,7 @@ describe Gofer do
28
28
  FileUtils.rm_rf path unless ENV['KEEPTMPDIR']
29
29
  end
30
30
  end
31
-
31
+
32
32
  before :all do
33
33
  @host = Gofer::Host.new(HOSTNAME, USERNAME, :keys => [IDENTITY_FILE], :quiet => true)
34
34
  @tmpdir = raw_ssh("mktemp -d /tmp/gofertest.XXXXX").chomp
@@ -41,17 +41,17 @@ describe Gofer do
41
41
  raw_ssh "rm -rf #{@tmpdir}" if @tmpdir && @tmpdir =~ %r{gofertest}
42
42
  end
43
43
  end
44
-
44
+
45
45
  describe :new do
46
46
  it "should support the legacy positional argument" do
47
47
  Gofer::Host.new(HOSTNAME, USERNAME, IDENTITY_FILE).run("echo hello", :quiet => true).should == "hello\n"
48
48
  end
49
-
49
+
50
50
  it "should support the legacy identity_file key" do
51
51
  Gofer::Host.new(HOSTNAME, USERNAME, :identity_file => IDENTITY_FILE).run("echo hello", :quiet => true).should == "hello\n"
52
52
  end
53
53
  end
54
-
54
+
55
55
  describe :hostname do
56
56
  it "should be the hostname of the host we're connecting to" do
57
57
  @host.hostname.should == HOSTNAME
@@ -62,32 +62,38 @@ describe Gofer do
62
62
  it "and capture stdout in @response.stdout" do
63
63
  @response.stdout.should == "stdout\n"
64
64
  end
65
-
65
+
66
66
  it "and capture stderr in @response.stderr" do
67
67
  @response.stderr.should == "stderr\n"
68
68
  end
69
-
69
+
70
70
  it "and combine captured stdout / stderr in @response.output" do
71
71
  @response.output.should == "stdout\nstderr\n"
72
72
  end
73
-
73
+
74
74
  it "and @response by itself should be the captured stdout" do
75
75
  @response.should == "stdout\n"
76
76
  end
77
77
  end
78
-
78
+
79
79
  describe :run do
80
-
80
+
81
81
  describe "with a stdout and stderr responses" do
82
- before :all do
82
+ before :all do
83
83
  @response = @host.run "echo stdout; echo stderr 1>&2", :quiet_stderr => true
84
84
  end
85
-
85
+
86
86
  it_should_behave_like "an output capturer"
87
87
  end
88
88
 
89
89
  it "should error if a command returns a non-zero response" do
90
- lambda {@host.run "false"}.should raise_error /failed with exit status/
90
+ lambda {@host.run "false"}.should raise_error(/failed with exit status/)
91
+ begin
92
+ @host.run "false"
93
+ rescue Gofer::HostError => e
94
+ e.response.should be_a Gofer::Response
95
+ e.host.should be_a Gofer::Host
96
+ end
91
97
  end
92
98
 
93
99
  it "should capture a non-zero exit status if asked" do
@@ -95,7 +101,7 @@ describe Gofer do
95
101
  response.exit_status.should == 1
96
102
  end
97
103
  end
98
-
104
+
99
105
  describe :run_multiple do
100
106
  describe "with stdout and stderr responses" do
101
107
  before :all do
@@ -103,12 +109,12 @@ describe Gofer do
103
109
  end
104
110
  it_should_behave_like "an output capturer"
105
111
  end
106
-
112
+
107
113
  it "should error if a command returns a non-zero response" do
108
114
  lambda {@host.run_multiple ["echo", "false"]}.should raise_error /failed with exit status/
109
115
  end
110
116
  end
111
-
117
+
112
118
  describe :exist? do
113
119
  it "should return true if a path or file exists" do
114
120
  raw_ssh "touch #{in_tmpdir 'exists'}"
@@ -137,7 +143,7 @@ describe Gofer do
137
143
  @host.read(@tmpdir + '/hello.txt').should == "hello\n"
138
144
  end
139
145
  end
140
-
146
+
141
147
  describe :ls do
142
148
  it "should list the contents of a directory" do
143
149
  raw_ssh "mkdir #{@tmpdir}/lstmp && touch #{@tmpdir}/lstmp/f"
@@ -165,7 +171,7 @@ describe Gofer do
165
171
  end
166
172
  end
167
173
  end
168
-
174
+
169
175
  describe :write do
170
176
  it "should write a file to the remote server" do
171
177
  @host.write("some data\n", in_tmpdir('written'))
@@ -190,7 +196,7 @@ describe Gofer do
190
196
  with_local_tmpdir 'download_dir' do |path|
191
197
  download_dir = in_tmpdir 'download_dir'
192
198
  raw_ssh "mkdir #{download_dir} && echo 'sup' > #{download_dir}/hey"
193
-
199
+
194
200
  @host.download(download_dir, path)
195
201
  File.open(path + '/download_dir/hey').read.should == "sup\n"
196
202
  end
metadata CHANGED
@@ -1,8 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gofer
3
3
  version: !ruby/object:Gem::Version
4
+ hash: 27
4
5
  prerelease:
5
- version: 0.2.5
6
+ segments:
7
+ - 0
8
+ - 2
9
+ - 6
10
+ version: 0.2.6
6
11
  platform: ruby
7
12
  authors:
8
13
  - Michael Pearson
@@ -10,7 +15,7 @@ autorequire:
10
15
  bindir: bin
11
16
  cert_chain: []
12
17
 
13
- date: 2011-06-02 00:00:00 Z
18
+ date: 2012-08-29 00:00:00 Z
14
19
  dependencies:
15
20
  - !ruby/object:Gem::Dependency
16
21
  name: net-ssh
@@ -20,6 +25,11 @@ dependencies:
20
25
  requirements:
21
26
  - - ">="
22
27
  - !ruby/object:Gem::Version
28
+ hash: 33
29
+ segments:
30
+ - 2
31
+ - 0
32
+ - 23
23
33
  version: 2.0.23
24
34
  type: :runtime
25
35
  version_requirements: *id001
@@ -31,12 +41,19 @@ dependencies:
31
41
  requirements:
32
42
  - - ">="
33
43
  - !ruby/object:Gem::Version
44
+ hash: 31
45
+ segments:
46
+ - 1
47
+ - 0
48
+ - 4
34
49
  version: 1.0.4
35
50
  type: :runtime
36
51
  version_requirements: *id002
37
- description: "\n\
38
- Gofer provides a flexible and reliable model for performing tasks on remote\n\
39
- server using Net::SSH\n"
52
+ description: |
53
+
54
+ Gofer provides a flexible and reliable model for performing tasks on remote
55
+ server using Net::SSH
56
+
40
57
  email:
41
58
  - mipearson@gmail.com
42
59
  executables: []
@@ -72,17 +89,23 @@ required_ruby_version: !ruby/object:Gem::Requirement
72
89
  requirements:
73
90
  - - ">="
74
91
  - !ruby/object:Gem::Version
92
+ hash: 3
93
+ segments:
94
+ - 0
75
95
  version: "0"
76
96
  required_rubygems_version: !ruby/object:Gem::Requirement
77
97
  none: false
78
98
  requirements:
79
99
  - - ">="
80
100
  - !ruby/object:Gem::Version
101
+ hash: 3
102
+ segments:
103
+ - 0
81
104
  version: "0"
82
105
  requirements: []
83
106
 
84
107
  rubyforge_project:
85
- rubygems_version: 1.8.3
108
+ rubygems_version: 1.8.17
86
109
  signing_key:
87
110
  specification_version: 3
88
111
  summary: run commands on remote servers using SSH