nutshell 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
File without changes
@@ -1,3 +1,9 @@
1
+ === 1.0.1 / 2012-07-18
2
+
3
+ * Bugfixes:
4
+
5
+ * Update homepage
6
+
1
7
  === 1.0.0 / 2010-09-28
2
8
 
3
9
  * 1 major enhancement
data/README.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  = Nutshell
2
2
 
3
- * http://github.com/yaksnrainbows/nutshell
3
+ * http://yaks.me/nutshell
4
4
 
5
5
  == DESCRIPTION:
6
6
 
@@ -43,7 +43,7 @@ A light weight ssh client that wraps the ssh and rsync commands.
43
43
 
44
44
  * highline gem
45
45
 
46
- * Unix based OS
46
+ * Unix based OS with ssh and rsync
47
47
 
48
48
  == INSTALL:
49
49
 
@@ -53,7 +53,7 @@ A light weight ssh client that wraps the ssh and rsync commands.
53
53
 
54
54
  (The MIT License)
55
55
 
56
- Copyright (c) 2010 FIX
56
+ Copyright (c) 2010 Jeremie Castagna
57
57
 
58
58
  Permission is hereby granted, free of charge, to any person obtaining
59
59
  a copy of this software and associated documentation files (the
data/Rakefile CHANGED
@@ -39,6 +39,7 @@ Hoe.spec 'nutshell' do |p|
39
39
  developer('Jeremie Castagna', 'yaksnrainbows@gmail.com')
40
40
  self.extra_deps << ['open4', '>= 1.0.1']
41
41
  self.extra_deps << ['highline', '>= 1.5.1']
42
+ self.extra_deps << ['ruby-termios', '>= 0.9.6']
42
43
  end
43
44
 
44
45
  # vim: syntax=Ruby
@@ -1,6 +1,7 @@
1
1
  require 'rubygems'
2
2
  require 'open4'
3
3
  require 'highline'
4
+ require 'termios'
4
5
 
5
6
  require 'fileutils'
6
7
  require 'tmpdir'
@@ -8,7 +9,7 @@ require 'tmpdir'
8
9
 
9
10
  module Nutshell
10
11
 
11
- VERSION = "1.0.0"
12
+ VERSION = "1.0.1"
12
13
 
13
14
  ##
14
15
  # Temp directory used by various nutshell classes
@@ -21,22 +22,48 @@ module Nutshell
21
22
  class CmdError < Exception; end
22
23
  class ConnectionError < Exception; end
23
24
 
25
+ DEFAULT_CONFIG = {
26
+ :timeout => 300,
27
+ :interactive => true,
28
+ :tty_state_freq => 0.1
29
+ }
30
+
31
+ ##
32
+ # Set the config.
24
33
 
25
34
  def self.config
26
- @config ||= {}
35
+ @config ||= DEFAULT_CONFIG.dup
27
36
  end
28
37
 
29
38
 
39
+ ##
40
+ # How long to wait with no data coming in before timing out.
41
+ # Reads config[:timeout].
42
+
30
43
  def self.timeout
31
44
  config[:timeout]
32
45
  end
33
46
 
34
47
 
48
+ ##
49
+ # Defines if process should fail when user interaction is required.
50
+ # Defaults to true. Reads config[:interactive].
51
+
35
52
  def self.interactive?
36
53
  config[:interactive]
37
54
  end
38
55
 
39
56
 
57
+ ##
58
+ # How often to check the state of the tty in seconds.
59
+ # Used for detecting prompts.
60
+ # Defaults to 0.1. Reads config[:tty_state_freq].
61
+
62
+ def self.tty_state_freq
63
+ config[:tty_state_freq]
64
+ end
65
+
66
+
40
67
  require 'nutshell/shell'
41
68
  require 'nutshell/remote_shell'
42
69
  end
@@ -60,7 +60,7 @@ module Nutshell
60
60
 
61
61
  @user ||= options[:user]
62
62
 
63
- @rsync_flags = ["-azP"]
63
+ @rsync_flags = ["-azrP"]
64
64
  @rsync_flags.concat [*options[:rsync_flags]] if options[:rsync_flags]
65
65
 
66
66
  @ssh_flags = [
@@ -107,7 +107,7 @@ module Nutshell
107
107
  raise TimeoutError if timed_out?(start_time, LOGIN_TIMEOUT)
108
108
  end
109
109
 
110
- unless connected?
110
+ unless ready && connected?
111
111
  disconnect
112
112
  host_info = [@user, @host].compact.join("@")
113
113
  raise ConnectionError, "Can't connect to #{host_info}"
@@ -165,7 +165,7 @@ module Nutshell
165
165
  # Checks if the given file exists
166
166
 
167
167
  def file? filepath
168
- syscall "test -f #{filepath}"
168
+ self.system "test -f #{filepath}"
169
169
  end
170
170
 
171
171
 
@@ -10,8 +10,22 @@ module Nutshell
10
10
  LOCAL_USER = `whoami`.chomp
11
11
  LOCAL_HOST = `hostname`.chomp
12
12
 
13
- SUDO_FAILED = /^Sorry, try again./
14
- SUDO_PROMPT = /^Password:/
13
+
14
+ class << self
15
+ # The message to match in stderr to determine logging in has failed.
16
+ # Defaults to:
17
+ # /^Sorry, try again./
18
+ attr_accessor :sudo_failed_matcher
19
+
20
+ # The message to match in stderr to determine a password is required.
21
+ # Defaults to:
22
+ # /^Password:/
23
+ attr_accessor :sudo_prompt_matcher
24
+ end
25
+
26
+ self.sudo_failed_matcher = /^Sorry, try again./
27
+ self.sudo_prompt_matcher = /^Password:/
28
+
15
29
 
16
30
  attr_reader :user, :host, :password, :input, :output, :mutex
17
31
  attr_accessor :env, :sudo, :timeout
@@ -69,6 +83,14 @@ module Nutshell
69
83
  end
70
84
 
71
85
 
86
+ ##
87
+ # Prompt the user to make a choice.
88
+
89
+ def choose(&block)
90
+ sync{ @input.choose(&block) }
91
+ end
92
+
93
+
72
94
  ##
73
95
  # Close the output IO. (Required by the Logger class)
74
96
 
@@ -206,7 +228,7 @@ module Nutshell
206
228
  # Build an sh -c command
207
229
 
208
230
  def sh_cmd cmd
209
- ["sh", "-c", quote_cmd(cmd)]
231
+ ["sh", "-i", "-c", quote_cmd(cmd)]
210
232
  end
211
233
 
212
234
 
@@ -258,7 +280,7 @@ module Nutshell
258
280
  ##
259
281
  # Returns true if command was run successfully, otherwise returns false.
260
282
 
261
- def syscall cmd, options=nil
283
+ def system cmd, options=nil
262
284
  call(cmd, options) && true rescue false
263
285
  end
264
286
 
@@ -339,6 +361,8 @@ module Nutshell
339
361
  inn.sync = true
340
362
  log_methods = {out => :debug, err => :error}
341
363
 
364
+ status = nil
365
+
342
366
  result, status = process_streams(pid, out, err) do |stream, data|
343
367
  stream_name = :out if stream == out
344
368
  stream_name = :err if stream == err
@@ -352,9 +376,7 @@ module Nutshell
352
376
 
353
377
 
354
378
  if password_required?(stream_name, data) then
355
-
356
379
  kill_process(pid) unless Nutshell.interactive?
357
-
358
380
  send_password_to_stream(inn, data)
359
381
  end
360
382
  end
@@ -379,12 +401,12 @@ module Nutshell
379
401
 
380
402
 
381
403
  def password_required? stream_name, data
382
- stream_name == :err && data =~ SUDO_PROMPT
404
+ stream_name == :err && data =~ Shell.sudo_prompt_matcher
383
405
  end
384
406
 
385
407
 
386
408
  def send_password_to_stream inn, data
387
- prompt_for_password if data =~ SUDO_FAILED
409
+ prompt_for_password if data =~ Shell.sudo_failed_matcher
388
410
  inn.puts @password || prompt_for_password
389
411
  end
390
412
 
@@ -80,7 +80,7 @@ def assert_rsync from, to, ds=@remote_shell, sudo=false
80
80
  "--rsync-path='#{ path }' "
81
81
  end
82
82
 
83
- rsync_cmd = "rsync -azP #{rsync_path}-e \"ssh #{ds.ssh_flags.join(' ')}\""
83
+ rsync_cmd = "rsync -azrP #{rsync_path}-e \"ssh #{ds.ssh_flags.join(' ')}\""
84
84
 
85
85
  error_msg = "No such command in remote_shell log [#{ds.host}]\n#{rsync_cmd}"
86
86
  error_msg << "#{from.inspect} #{to.inspect}"
@@ -24,13 +24,13 @@ class TestShell < Test::Unit::TestCase
24
24
 
25
25
  def test_ask
26
26
  @shell.ask "input something!"
27
- assert 1, @shell.input.method_call_count(:ask)
27
+ assert_equal 1, @shell.input.method_call_count(:ask)
28
28
  end
29
29
 
30
30
 
31
31
  def test_close
32
32
  @shell.close
33
- assert 1, @shell.output.method_call_count(:close)
33
+ assert_equal 1, @shell.output.method_call_count(:close)
34
34
  end
35
35
 
36
36
 
metadata CHANGED
@@ -1,76 +1,106 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: nutshell
3
- version: !ruby/object:Gem::Version
4
- prerelease: false
5
- segments:
6
- - 1
7
- - 0
8
- - 0
9
- version: 1.0.0
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.1
5
+ prerelease:
10
6
  platform: ruby
11
- authors:
7
+ authors:
12
8
  - Jeremie Castagna
13
9
  autorequire:
14
10
  bindir: bin
15
11
  cert_chain: []
16
-
17
- date: 2010-09-28 00:00:00 -07:00
18
- default_executable:
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
12
+ date: 2012-07-18 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
21
15
  name: open4
22
- prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
24
- requirements:
25
- - - ">="
26
- - !ruby/object:Gem::Version
27
- segments:
28
- - 1
29
- - 0
30
- - 1
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
31
21
  version: 1.0.1
32
22
  type: :runtime
33
- version_requirements: *id001
34
- - !ruby/object:Gem::Dependency
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: 1.0.1
30
+ - !ruby/object:Gem::Dependency
35
31
  name: highline
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: 1.5.1
38
+ type: :runtime
36
39
  prerelease: false
37
- requirement: &id002 !ruby/object:Gem::Requirement
38
- requirements:
39
- - - ">="
40
- - !ruby/object:Gem::Version
41
- segments:
42
- - 1
43
- - 5
44
- - 1
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
45
  version: 1.5.1
46
+ - !ruby/object:Gem::Dependency
47
+ name: ruby-termios
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: 0.9.6
46
54
  type: :runtime
47
- version_requirements: *id002
48
- - !ruby/object:Gem::Dependency
49
- name: hoe
50
55
  prerelease: false
51
- requirement: &id003 !ruby/object:Gem::Requirement
52
- requirements:
53
- - - ">="
54
- - !ruby/object:Gem::Version
55
- segments:
56
- - 2
57
- - 3
58
- - 3
59
- version: 2.3.3
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: 0.9.6
62
+ - !ruby/object:Gem::Dependency
63
+ name: rdoc
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: '3.10'
60
70
  type: :development
61
- version_requirements: *id003
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: '3.10'
78
+ - !ruby/object:Gem::Dependency
79
+ name: hoe
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ~>
84
+ - !ruby/object:Gem::Version
85
+ version: '3.0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ version: '3.0'
62
94
  description: A light weight ssh client that wraps the ssh and rsync commands.
63
- email:
95
+ email:
64
96
  - yaksnrainbows@gmail.com
65
97
  executables: []
66
-
67
98
  extensions: []
68
-
69
- extra_rdoc_files:
99
+ extra_rdoc_files:
70
100
  - History.txt
71
101
  - Manifest.txt
72
102
  - README.txt
73
- files:
103
+ files:
74
104
  - History.txt
75
105
  - Manifest.txt
76
106
  - README.txt
@@ -83,38 +113,34 @@ files:
83
113
  - test/test_helper.rb
84
114
  - test/test_remote_shell.rb
85
115
  - test/test_shell.rb
86
- has_rdoc: true
87
- homepage: http://github.com/yaksnrainbows/nutshell
116
+ - .gemtest
117
+ homepage: http://yaks.me/nutshell
88
118
  licenses: []
89
-
90
119
  post_install_message:
91
- rdoc_options:
120
+ rdoc_options:
92
121
  - --main
93
122
  - README.txt
94
- require_paths:
123
+ require_paths:
95
124
  - lib
96
- required_ruby_version: !ruby/object:Gem::Requirement
97
- requirements:
98
- - - ">="
99
- - !ruby/object:Gem::Version
100
- segments:
101
- - 0
102
- version: "0"
103
- required_rubygems_version: !ruby/object:Gem::Requirement
104
- requirements:
105
- - - ">="
106
- - !ruby/object:Gem::Version
107
- segments:
108
- - 0
109
- version: "0"
125
+ required_ruby_version: !ruby/object:Gem::Requirement
126
+ none: false
127
+ requirements:
128
+ - - ! '>='
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
131
+ required_rubygems_version: !ruby/object:Gem::Requirement
132
+ none: false
133
+ requirements:
134
+ - - ! '>='
135
+ - !ruby/object:Gem::Version
136
+ version: '0'
110
137
  requirements: []
111
-
112
138
  rubyforge_project: nutshell
113
- rubygems_version: 1.3.6
139
+ rubygems_version: 1.8.23
114
140
  signing_key:
115
141
  specification_version: 3
116
142
  summary: A light weight ssh client that wraps the ssh and rsync commands.
117
- test_files:
143
+ test_files:
118
144
  - test/test_helper.rb
119
145
  - test/test_remote_shell.rb
120
146
  - test/test_shell.rb