Class: Mattock::CommandLine
- Inherits:
-
Object
- Object
- Mattock::CommandLine
show all
- Defined in:
- lib/mattock/command-line.rb,
lib/mattock/testing/record-commands.rb,
lib/mattock/testing/mock-command-line.rb,
lib/mattock/command-line/command-run-result.rb
Defined Under Namespace
Classes: CommandRunResult
Constant Summary
collapse
- @@commands =
[]
Class Attribute Summary collapse
Instance Attribute Summary collapse
Class Method Summary
collapse
Instance Method Summary
collapse
-
#background ⇒ Object
Run a command in parallel with the parent process - will kill it if it outlasts us.
-
#collect_result(pid, host_stdout, host_stderr) ⇒ Object
-
#command ⇒ Object
-
#complete(pid, out, err) ⇒ Object
-
#copy_stream_to(from, to) ⇒ Object
-
#execute ⇒ Object
If I wasn’t worried about writing my own limited shell, I’d say e.g.
-
#initialize(executable, *options) {|_self| ... } ⇒ CommandLine
constructor
A new instance of CommandLine.
-
#kill_process(pid) ⇒ Object
-
#must_succeed! ⇒ Object
-
#options_composition ⇒ Object
-
#original_execute ⇒ Object
If I wasn’t worried about writing my own limited shell, I’d say e.g.
-
#redirect_from(path, stream) ⇒ Object
-
#redirect_stderr(path) ⇒ Object
-
#redirect_stdin(path) ⇒ Object
-
#redirect_stdout(path) ⇒ Object
-
#redirect_to(stream, path) ⇒ Object
-
#replace_us ⇒ Object
-
#run ⇒ Object
-
#set_env(name, value) ⇒ Object
-
#spawn_process ⇒ Object
-
#spin_off ⇒ Object
Run a command in the background.
-
#string_format ⇒ Object
-
#succeeds? ⇒ Boolean
-
#verbose ⇒ Object
Constructor Details
#initialize(executable, *options) {|_self| ... } ⇒ CommandLine
Returns a new instance of CommandLine.
25
26
27
28
29
30
31
|
# File 'lib/mattock/command-line.rb', line 25
def initialize(executable, *options)
@executable = executable
@options = options
@redirections = []
@env = {}
yield self if block_given?
end
|
Class Attribute Details
.command_recording_path ⇒ Object
Returns the value of attribute command_recording_path.
15
16
17
|
# File 'lib/mattock/testing/record-commands.rb', line 15
def command_recording_path
@command_recording_path
end
|
Instance Attribute Details
#env ⇒ Object
Also known as:
command_environment
Returns the value of attribute env.
33
34
35
|
# File 'lib/mattock/command-line.rb', line 33
def env
@env
end
|
#executable ⇒ Object
Returns the value of attribute executable.
33
34
35
|
# File 'lib/mattock/command-line.rb', line 33
def executable
@executable
end
|
#name ⇒ Object
Returns the value of attribute name.
33
34
35
|
# File 'lib/mattock/command-line.rb', line 33
def name
@name
end
|
#options ⇒ Object
Returns the value of attribute options.
33
34
35
|
# File 'lib/mattock/command-line.rb', line 33
def options
@options
end
|
#redirections ⇒ Object
Returns the value of attribute redirections.
34
35
36
|
# File 'lib/mattock/command-line.rb', line 34
def redirections
@redirections
end
|
Class Method Details
.define_chain_op(opname, klass) ⇒ Object
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
# File 'lib/mattock/command-line.rb', line 5
def self.define_chain_op(opname, klass)
define_method(opname) do |other|
unless CommandLine === other
other = CommandLine.new(*[*other])
end
chain = nil
if klass === self
chain = self
else
chain = klass.new
chain.add(self)
end
chain.add(other)
end
end
|
.define_op(opname) ⇒ Object
.emit_recording ⇒ Object
21
22
23
24
25
26
27
28
29
30
31
|
# File 'lib/mattock/testing/record-commands.rb', line 21
def emit_recording
io = $stderr
if command_recording_path
io = File.open(command_recording_path, "w")
else
io.puts "Set MATTOCK_CMDREC to write to a path"
end
@@commands.each do |pair|
io.puts "[/#{pair[0]}/, #{[pair[1].exit_code, pair[1].streams].inspect}]"
end
end
|
.execute(*args) ⇒ Object
28
29
30
|
# File 'lib/mattock/testing/mock-command-line.rb', line 28
def self.execute(*args)
fail "Command line executed in specs without 'expect_command' or 'expect_some_commands'"
end
|
Instance Method Details
#background ⇒ Object
Run a command in parallel with the parent process - will kill it if it outlasts us
129
130
131
132
133
134
135
136
|
# File 'lib/mattock/command-line.rb', line 129
def background
pid, out, err = spawn_process
Process.detach(pid)
at_exit do
kill_process(pid)
end
return pid, out, err
end
|
#collect_result(pid, host_stdout, host_stderr) ⇒ Object
106
107
108
109
110
111
|
# File 'lib/mattock/command-line.rb', line 106
def collect_result(pid, host_stdout, host_stderr)
result = CommandRunResult.new(pid, self)
result.streams = {1 => host_stdout, 2 => host_stderr}
result.wait
return result
end
|
#command ⇒ Object
51
52
53
|
# File 'lib/mattock/command-line.rb', line 51
def command
([executable] + options_composition + @redirections).join(" ")
end
|
#complete(pid, out, err) ⇒ Object
142
143
144
145
|
# File 'lib/mattock/command-line.rb', line 142
def complete(pid, out, err)
kill_process(pid)
collect_result(pid, out, err)
end
|
#copy_stream_to(from, to) ⇒ Object
73
74
75
|
# File 'lib/mattock/command-line.rb', line 73
def copy_stream_to(from, to)
@redirections << "#{from}>&#{to}"
end
|
#execute ⇒ Object
If I wasn’t worried about writing my own limited shell, I’d say e.g. Pipeline would be an explicit chain of pipes… which is probably as originally intended :/
116
117
118
|
# File 'lib/mattock/command-line.rb', line 116
def execute
collect_result(*spawn_process)
end
|
#kill_process(pid) ⇒ Object
138
139
140
|
# File 'lib/mattock/command-line.rb', line 138
def kill_process(pid)
Process.kill("INT", pid)
end
|
#must_succeed! ⇒ Object
161
162
163
|
# File 'lib/mattock/command-line.rb', line 161
def must_succeed!
run.must_succeed!
end
|
#options_composition ⇒ Object
61
62
63
|
# File 'lib/mattock/command-line.rb', line 61
def options_composition
options
end
|
#original_execute ⇒ Object
If I wasn’t worried about writing my own limited shell, I’d say e.g. Pipeline would be an explicit chain of pipes… which is probably as originally intended :/
6
7
8
|
# File 'lib/mattock/testing/record-commands.rb', line 6
def execute
collect_result(*spawn_process)
end
|
#redirect_from(path, stream) ⇒ Object
69
70
71
|
# File 'lib/mattock/command-line.rb', line 69
def redirect_from(path, stream)
@redirections << "#{stream}<#{path}"
end
|
#redirect_stderr(path) ⇒ Object
81
82
83
|
# File 'lib/mattock/command-line.rb', line 81
def redirect_stderr(path)
redirect_to(2, path)
end
|
#redirect_stdin(path) ⇒ Object
85
86
87
|
# File 'lib/mattock/command-line.rb', line 85
def redirect_stdin(path)
redirect_from(path, 0)
end
|
#redirect_stdout(path) ⇒ Object
77
78
79
|
# File 'lib/mattock/command-line.rb', line 77
def redirect_stdout(path)
redirect_to(1, path)
end
|
#redirect_to(stream, path) ⇒ Object
65
66
67
|
# File 'lib/mattock/command-line.rb', line 65
def redirect_to(stream, path)
@redirections << "#{stream}>#{path}"
end
|
#replace_us ⇒ Object
89
90
91
92
93
|
# File 'lib/mattock/command-line.rb', line 89
def replace_us
puts "Ceding execution to: "
puts string_format
Process.exec(command_environment, command)
end
|
#run ⇒ Object
147
148
149
150
151
152
153
154
155
|
# File 'lib/mattock/command-line.rb', line 147
def run
print string_format + " "
result = execute
puts "=> #{result.exit_code}"
puts result.format_streams if verbose
return result
ensure
puts if verbose
end
|
#set_env(name, value) ⇒ Object
38
39
40
41
|
# File 'lib/mattock/command-line.rb', line 38
def set_env(name, value)
command_environment[name] = value
return self
end
|
#spawn_process ⇒ Object
95
96
97
98
99
100
101
102
103
104
|
# File 'lib/mattock/command-line.rb', line 95
def spawn_process
host_stdout, cmd_stdout = IO.pipe
host_stderr, cmd_stderr = IO.pipe
pid = Process.spawn(command_environment, command, :out => cmd_stdout, :err => cmd_stderr)
cmd_stdout.close
cmd_stderr.close
return pid, host_stdout, host_stderr
end
|
#spin_off ⇒ Object
Run a command in the background. The command can survive the caller
121
122
123
124
125
|
# File 'lib/mattock/command-line.rb', line 121
def spin_off
pid, out, err = spawn_process
Process.detach(pid)
return pid, out, err
end
|
55
56
57
58
59
|
# File 'lib/mattock/command-line.rb', line 55
def string_format
(command_environment.map do |key, value|
[key, value].join("=")
end + [command]).join(" ")
end
|
#succeeds? ⇒ Boolean
157
158
159
|
# File 'lib/mattock/command-line.rb', line 157
def succeeds?
run.succeeded?
end
|
#verbose ⇒ Object
43
44
45
|
# File 'lib/mattock/command-line.rb', line 43
def verbose
::Rake.verbose && ::Rake.verbose != ::Rake::FileUtilsExt::DEFAULT
end
|