command-runner 0.2.1 → 0.3.0

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/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: