right_git 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.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.0
1
+ 1.0.1
@@ -47,39 +47,75 @@ module RightGit::Shell
47
47
  :raise_on_failure => true,
48
48
  :set_env_vars => nil,
49
49
  :clear_env_vars => nil,
50
- :logger => default_logger
50
+ :logger => default_logger,
51
+ :timeout => nil,
51
52
  }.merge(options)
52
53
  outstream = options[:outstream]
53
54
 
54
55
  logger = options[:logger]
55
56
 
56
- # build execution block.
57
+ # build initial popener.
57
58
  exitstatus = nil
58
- executioner = lambda do
59
- logger.info("+ #{cmd}")
60
- ::IO.popen("#{cmd} 2>&1", 'r') do |output|
61
- output.sync = true
62
- done = false
63
- while !done
64
- begin
65
- data = output.readline
59
+ popener = lambda do |output|
60
+ output.sync = true
61
+ loop do
62
+ # note stdout remains selectable after process dies.
63
+ if (::IO.select([output], nil, nil, 0.1) rescue nil)
64
+ if data = output.gets
66
65
  if outstream
67
66
  outstream << data
68
67
  else
69
- logger.info(data.strip)
68
+ data = data.strip
69
+ logger.info(data) unless data.empty?
70
70
  end
71
- rescue ::EOFError
72
- done = true
71
+ else
72
+ break
73
73
  end
74
74
  end
75
75
  end
76
+ end
77
+
78
+ # timeout optionally wraps popener. the timeout must happen inside of the
79
+ # IO.popen block or else it has no good effect.
80
+ if timeout = options[:timeout]
81
+ popener = lambda do |p|
82
+ lambda do |o|
83
+ ::Timeout.timeout(timeout) { p.call(o) }
84
+ end
85
+ end.call(popener)
86
+ end
87
+
88
+ # build initial executioner in terms of popener.
89
+ executioner = lambda do
90
+ logger.info("+ #{cmd}")
91
+ error_msg = nil
92
+ ::IO.popen("#{cmd} 2>&1", 'r') do |output|
93
+ begin
94
+ popener.call(output)
95
+ rescue ::EOFError
96
+ # done
97
+ rescue ::Timeout::Error
98
+ # kill still-running process or else popen's ensure will hang.
99
+ ::Process.kill('KILL', output.pid)
100
+
101
+ # intentionally not reading last data as that could still block
102
+ # due to a child of created process inheriting stdout.
103
+ error_msg = "Execution timed out after #{options[:timeout]} seconds."
104
+ end
105
+ end
106
+
107
+ # note that a killed process may exit 0 under Windows.
76
108
  exitstatus = $?.exitstatus
77
- if (!$?.success? && options[:raise_on_failure])
78
- raise ShellError, "Execution failed with exitstatus #{exitstatus}"
109
+ if 0 == exitstatus && error_msg
110
+ exitstatus = 1
111
+ end
112
+ if (exitstatus != 0 && options[:raise_on_failure])
113
+ error_msg ||= "Execution failed with exitstatus #{exitstatus}"
114
+ raise ShellError, error_msg
79
115
  end
80
116
  end
81
117
 
82
- # configure and invoke.
118
+ # configure executioner (by options) and then invoke executioner.
83
119
  configure_executioner(executioner, options).call
84
120
 
85
121
  return exitstatus
@@ -48,6 +48,7 @@ module RightGit::Shell
48
48
  # @option options :raise_on_failure [TrueClass|FalseClass] if true, wil raise a RuntimeError if the command does not end successfully (default), false to ignore errors
49
49
  # @option options :set_env_vars [Hash] environment variables to set during execution (default = none set)
50
50
  # @option options :clear_env_vars [Hash] environment variables to clear during execution (default = none cleared but see :clean_bundler_env)
51
+ # @option options :timeout [Numeric] to kill spawned process when time (in seconds) expires
51
52
  #
52
53
  # @return [Integer] exitstatus of the command
53
54
  #
data/right_git.gemspec CHANGED
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: right_git 1.0.0 ruby lib
5
+ # stub: right_git 1.0.1 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "right_git"
9
- s.version = "1.0.0"
9
+ s.version = "1.0.1"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib"]
13
13
  s.authors = ["Tony Spataro", "Scott Messier"]
14
- s.date = "2014-08-13"
14
+ s.date = "2014-08-20"
15
15
  s.description = "An assortment of git-related classes created by RightScale."
16
16
  s.email = "support@rightscale.com"
17
17
  s.extra_rdoc_files = [
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: right_git
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2014-08-13 00:00:00.000000000 Z
13
+ date: 2014-08-22 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: right_support
@@ -149,7 +149,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
149
149
  version: '0'
150
150
  segments:
151
151
  - 0
152
- hash: -725937737083672839
152
+ hash: 3982530629756792101
153
153
  required_rubygems_version: !ruby/object:Gem::Requirement
154
154
  none: false
155
155
  requirements:
@@ -158,7 +158,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
158
158
  version: '0'
159
159
  requirements: []
160
160
  rubyforge_project:
161
- rubygems_version: 1.8.23
161
+ rubygems_version: 1.8.26
162
162
  signing_key:
163
163
  specification_version: 3
164
164
  summary: Reusable Git repository management code.