nutshell 1.0.0 → 1.0.1

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.
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