command-runner 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -49,6 +49,16 @@ line.pass
49
49
 
50
50
  but defaults to the best one.
51
51
 
52
+ If you run a command that doesn't exist on the machine...
53
+
54
+ ```Ruby
55
+ line = Command::Runner.new("some-non-existant-command", "")
56
+
57
+ line.pass.no_command? # => true
58
+ ```
59
+
60
+ it'll tell you.
61
+
52
62
  ## Compatibility
53
63
  It works on
54
64
 
@@ -18,6 +18,7 @@ module Command
18
18
 
19
19
  # Run the given command and arguments, in the given environment.
20
20
  #
21
+ # @raise [Errno::ENOENT] if the command doesn't exist.
21
22
  # @param command [String] the command to run.
22
23
  # @param arguments [String] the arguments to pass to the
23
24
  # command.
@@ -31,24 +32,22 @@ module Command
31
32
  start_time = nil
32
33
  end_time = nil
33
34
 
34
- future do
35
- with_modified_env(env) do
36
- start_time = Time.now
37
- output << `#{command} #{arguments}`
38
- end_time = Time.now
39
- end
40
-
41
- Message.new :process_id => $?.pid,
42
- :exit_code => $?.exitstatus,
43
- :finished => true,
44
- :time => (end_time - start_time).abs,
45
- :env => env,
46
- :options => {},
47
- :stdout => output,
48
- :line => [command, arguments].join(' '),
49
- :executed => true,
50
- :status => $?
35
+ with_modified_env(env) do
36
+ start_time = Time.now
37
+ output << `#{command} #{arguments}`
38
+ end_time = Time.now
51
39
  end
40
+
41
+ Message.new :process_id => $?.pid,
42
+ :exit_code => $?.exitstatus,
43
+ :finished => true,
44
+ :time => (end_time - start_time).abs,
45
+ :env => env,
46
+ :options => {},
47
+ :stdout => output,
48
+ :line => [command, arguments].join(' '),
49
+ :executed => true,
50
+ :status => $?
52
51
  end
53
52
 
54
53
  private
@@ -27,6 +27,7 @@ module Command
27
27
  #
28
28
  # @abstract
29
29
  # @note Does nothing.
30
+ # @raise [Errno::ENOENT] if the command doesn't exist.
30
31
  # @param command [String] the command to run.
31
32
  # @param arguments [String] the arguments to pass to the
32
33
  # command.
@@ -5,7 +5,10 @@ module Command
5
5
  # Spawns a process using ruby's Process.spawn.
6
6
  class Spawn < Fake
7
7
 
8
- # (see Fake.available?)
8
+ # Returns whether or not this backend is available on this
9
+ # platform.
10
+ #
11
+ # @return [Boolean]
9
12
  def self.available?
10
13
  Process.respond_to?(:spawn) && !(RUBY_PLATFORM == "java" && RUBY_VERSION =~ /\A1\.9/)
11
14
  end
@@ -17,6 +20,7 @@ module Command
17
20
 
18
21
  # Run the given command and arguments, in the given environment.
19
22
  #
23
+ # @raise [Errno::ENOENT] if the command doesn't exist.
20
24
  # @param (see Fake#call)
21
25
  # @return (see Fake#call)
22
26
  def call(command, arguments, env = {}, options = {})
@@ -24,13 +28,14 @@ module Command
24
28
  stderr_r, stderr_w = IO.pipe
25
29
  stdout_r, stdout_w = IO.pipe
26
30
  stdin_r, stdin_w = IO.pipe
31
+ clean_exceptions = options.delete(:clean_exceptions) || false
27
32
 
33
+ if options[:input]
34
+ stdin_w.write(options.delete(:input))
35
+ end
28
36
  new_options = options.merge(:in => stdin_r,
29
37
  :out => stdout_w, :err => stderr_w)
30
38
 
31
- if new_options[:input]
32
- stdin_w.write(new_options.delete(:input))
33
- end
34
39
  stdin_w.close
35
40
 
36
41
  line = [command, arguments].join(' ')
@@ -56,17 +61,6 @@ module Command
56
61
  :executed => true,
57
62
  :status => status
58
63
  end
59
-
60
- rescue Errno::ENOENT => e
61
- Message.new :exit_code => 127,
62
- :finished => true,
63
- :time => -1,
64
- :env => {},
65
- :options => {},
66
- :stdout => "",
67
- :stderr => e.message,
68
- :line => line,
69
- :executed => false
70
64
  end
71
65
 
72
66
  # Spawn the given process, in the environment with the
@@ -6,5 +6,9 @@ module Command
6
6
  # support it.
7
7
  class NotAvailableBackendError < StandardError; end
8
8
 
9
+ # Raised when a command that was passed is not available on this
10
+ # platform.
11
+ class NoCommandError < StandardError; end
12
+
9
13
  end
10
14
  end
@@ -5,6 +5,15 @@ module Command
5
5
  # its exit code, process id, and even time it took to run.
6
6
  class Message
7
7
 
8
+ # For when a message is created for a NoCommandError.
9
+ #
10
+ # @param line [String] the line that was executed, but gave a
11
+ # +Errno::ENOENT+ error.
12
+ # @ return [Message]
13
+ def self.error(line)
14
+ Message.new(:line => line, :exit_code => 127)
15
+ end
16
+
8
17
  # Initialize the message with the given data about the process.
9
18
  #
10
19
  # @param data [Hash] the data about the process.
@@ -58,6 +67,14 @@ module Command
58
67
  exit_code != 0
59
68
  end
60
69
 
70
+ # Whether or not the command existed; or, if the exit code
71
+ # is 127.
72
+ #
73
+ # @return [Boolean]
74
+ def no_command?
75
+ exit_code == 127
76
+ end
77
+
61
78
  # @!attribute [r] exit_code
62
79
  # The code the process exited with.
63
80
  #
@@ -3,7 +3,7 @@ module Command
3
3
  class Runner
4
4
 
5
5
  # The current version of Runner.
6
- VERSION = "0.2.1"
6
+ VERSION = "0.3.0".freeze
7
7
 
8
8
  end
9
9
  end
@@ -52,6 +52,8 @@ module Command
52
52
  # The options the messenger was initialized with.
53
53
  #
54
54
  # @return [Hash]
55
+ # @!parse
56
+ # attr_reader :options
55
57
  def options
56
58
  @options.dup.freeze
57
59
  end
@@ -59,7 +61,7 @@ module Command
59
61
  # Gets the backend to be used by the messenger. If it is not defined
60
62
  # on the instance, it'll get the class default.
61
63
  #
62
- # @see Messenger.backend
64
+ # @see Runner.backend
63
65
  # @return [#call] a backend to use.
64
66
  def backend
65
67
  @backend || self.class.backend
@@ -83,8 +85,34 @@ module Command
83
85
 
84
86
  # Runs the command and arguments with the given interpolations;
85
87
  # defaults to no interpolations.
88
+ #
89
+ # @note This method may not raise a {NoCommandError} and instead
90
+ # return a {Message} with the error code +127+, even if the
91
+ # command doesn't exist.
92
+ # @raise [NoCommandError] on no command.
93
+ # @param interops [Hash<Symbol, Object>] the interpolations to
94
+ # make.
95
+ # @param options [Hash<Symbol, Object>] the options for the
96
+ # backend.
97
+ # @return [Message]
98
+ def pass!(interops = {}, options = {})
99
+ backend.call(*[contents(interops), options.delete(:env) || {}, options].flatten)
100
+
101
+ rescue Errno::ENOENT
102
+ raise NoCommandError, @command
103
+ end
104
+
105
+ # Runs the command and arguments with the given interpolations;
106
+ # defaults to no interpolations. Calls {#pass!}, but does not
107
+ # raise an error.
108
+ #
109
+ # @param (see #pass!)
110
+ # @return (see #pass!)
86
111
  def pass(interops = {}, options = {})
87
- backend.call(*[contents(interops), options.delete(:env) || {}, options].flatten)
112
+ pass! interops, options
113
+
114
+ rescue NoCommandError
115
+ Message.error(:line => contents(interops))
88
116
  end
89
117
 
90
118
  # The command line being run by the runner. Interpolates the
@@ -10,12 +10,7 @@ describe Command::Runner::Backends::Backticks do
10
10
  value.should be_executed
11
11
  end
12
12
 
13
- it "doesn't block" do
14
- start_time = Time.now
15
- value = subject.call("sleep", "0.5")
16
- end_time = Time.now
17
-
18
- (end_time - start_time).should be_within((1.0/100)).of(0)
19
- value.time.should be_within(0.1).of(0.5)
13
+ it "gives the correct time" do
14
+ subject.call("sleep", "0.5").time.should be_within(0.1).of(0.5)
20
15
  end
21
16
  end
@@ -57,4 +57,15 @@ describe Command::Runner do
57
57
  Command::Runner.best_backend.should be_instance_of Command::Runner::Backends::PosixSpawn
58
58
  end
59
59
  end
60
+
61
+ context "running bad commands" do
62
+ let(:command) { "some-non-existant-command" }
63
+ let(:arguments) { "" }
64
+
65
+ it "raises exceptions on non-existant commands" do
66
+ subject.backend = Command::Runner::Backends::Backticks.new
67
+
68
+ subject.pass.should be_no_command
69
+ end
70
+ end
60
71
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: command-runner
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors: