Skip to content

Commit f911bf0

Browse files
botandrose-machineseanpdoyle
authored andcommitted
Improve command failure reporting
* Remove `#silence_build` method from `#exec.` * Tell the user what happened when a command fails. * Print both the command and error message for easier debugging. * Capture both STDOUT and STDERR in #exec. Commands may output important debugging information via either channel. Use `Open3.capture2e` instead of `Kernel.system`. It appears to be impossible to capture both `STDERR` and `STDOUT` simultaneously with the latter.
1 parent 87c65e3 commit f911bf0

File tree

4 files changed

+76
-18
lines changed

4 files changed

+76
-18
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
master
22
------
33

4+
* Improve command failure reporting. [#324]
45
* Use latest EmberCLI-generated asset files. [#316]
56
* Delete previous build output on application boot instead of on process exit.
67
[#308]
78

9+
[#324]: https://github.com/thoughtbot/ember-cli-rails/pull/324
810
[#316]: https://github.com/thoughtbot/ember-cli-rails/pull/316
911
[#308]: https://github.com/thoughtbot/ember-cli-rails/pull/308
1012

lib/ember_cli/runner.rb

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
require "open3"
2+
3+
module EmberCli
4+
class Runner
5+
def initialize(env: {}, out:, err:, options: {})
6+
@env = env
7+
@out = out
8+
@err = err
9+
@options = options
10+
end
11+
12+
def run!(command)
13+
output, status = Open3.capture2e(@env, command, @options)
14+
15+
@out.write(output)
16+
17+
unless status.success?
18+
@err.write <<-MSG.strip_heredoc
19+
ERROR: Failed command: `#{command}`
20+
OUTPUT:
21+
#{output}
22+
MSG
23+
24+
exit 1
25+
end
26+
27+
true
28+
end
29+
end
30+
end

lib/ember_cli/shell.rb

+10-18
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
require "ember_cli/command"
2+
require "ember_cli/runner"
23

34
module EmberCli
45
class Shell
@@ -13,7 +14,7 @@ def initialize(paths:, env: {}, options: {})
1314
end
1415

1516
def compile
16-
silence_build { exec ember.build }
17+
exec ember.build
1718
end
1819

1920
def build_and_watch
@@ -50,18 +51,17 @@ def test
5051
attr_reader :ember, :env, :options, :paths
5152

5253
def spawn(command)
53-
Kernel.spawn(env, command, process_options) || exit(1)
54+
Kernel.spawn(env, command, chdir: paths.root.to_s, out: paths.log.to_s) ||
55+
exit(1)
5456
end
5557

5658
def exec(command)
57-
Kernel.system(env, command, process_options) || exit(1)
58-
end
59-
60-
def process_options
61-
{
62-
chdir: paths.root.to_s,
63-
out: paths.log.to_s,
64-
}
59+
Runner.new(
60+
options: { chdir: paths.root.to_s },
61+
out: paths.log,
62+
err: $stderr,
63+
env: env,
64+
).run!(command)
6565
end
6666

6767
def running?
@@ -77,13 +77,5 @@ def lock_buildfile
7777
def detach
7878
Process.detach pid
7979
end
80-
81-
def silence_build(&block)
82-
if ENV.fetch("EMBER_CLI_RAILS_VERBOSE") { EmberCli.env.production? }
83-
yield
84-
else
85-
silence_stream(STDOUT, &block)
86-
end
87-
end
8880
end
8981
end

spec/lib/ember_cli/runner_spec.rb

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
require "ember_cli/runner"
2+
3+
describe EmberCli::Runner do
4+
describe "#run!" do
5+
context "when the command fails" do
6+
it "writes STDERR and STDOUT to `err`" do
7+
out = StringIO.new
8+
err = StringIO.new
9+
runner = EmberCli::Runner.new(err: err, out: out)
10+
11+
expect { runner.run!("echo 'out'; echo 'err' > /dev/stderr; exit 1") }.
12+
to raise_error(SystemExit)
13+
14+
[err, out].each(&:rewind)
15+
16+
expect(err.read).to match(/out\nerr/)
17+
expect(out.read).to eq("out\nerr\n")
18+
end
19+
end
20+
21+
it "executes the command" do
22+
out = StringIO.new
23+
err = StringIO.new
24+
runner = EmberCli::Runner.new(err: err, out: out)
25+
26+
runner.run!("echo 'out'")
27+
28+
[err, out].each(&:rewind)
29+
30+
expect(err.read).to be_empty
31+
expect(out.read).to eq("out\n")
32+
end
33+
end
34+
end

0 commit comments

Comments
 (0)