Skip to content

Commit 0b61ab6

Browse files
justin808claude
andcommitted
Add changelog entry and tests for stderr log output
- Add changelog entry for PR #869 documenting the bug fix - Add tests verifying [Shakapacker] log messages go to stderr, not stdout - Tests ensure stdout remains clean when using --json flag for valid JSON output Co-Authored-By: Claude Opus 4.5 <[email protected]>
1 parent a905f6d commit 0b61ab6

File tree

2 files changed

+59
-0
lines changed

2 files changed

+59
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ Changes since the last non-beta release.
1414
### Fixed
1515

1616
- **Fixed NODE_ENV=test causing DefinePlugin warnings**. [PR #870](https://github.com/shakacode/shakapacker/pull/870) by [justin808](https://github.com/justin808). When RAILS_ENV=test, Shakapacker now sets NODE_ENV=development instead of NODE_ENV=test. This prevents webpack/rspack DefinePlugin conflicts since these bundlers only recognize "development" and "production" as valid NODE_ENV values.
17+
- **Fixed `--json` flag output being corrupted by log messages**. [PR #869](https://github.com/shakacode/shakapacker/pull/869) by [justin808](https://github.com/justin808). `[Shakapacker]` log messages are now written to stderr instead of stdout, allowing `bin/shakapacker --profile --json` to produce valid JSON output that can be piped to tools like `webpack-bundle-analyzer`. Resolves [#868](https://github.com/shakacode/shakapacker/issues/868).
1718

1819
## [v9.5.0] - January 7, 2026
1920

spec/shakapacker/webpack_runner_spec.rb

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,8 +206,66 @@
206206
end
207207
end
208208

209+
describe "stdout/stderr separation for JSON output" do
210+
it "does not write [Shakapacker] log messages to stdout" do
211+
Dir.chdir(test_app_path) do
212+
klass = Shakapacker::WebpackRunner
213+
instance = klass.new(["--json"])
214+
215+
allow(klass).to receive(:new).and_return(instance)
216+
allow(Shakapacker::Utils::Manager).to receive(:error_unless_package_manager_is_obvious!)
217+
218+
allow(instance).to receive(:system) do |*args|
219+
system("true")
220+
true
221+
end
222+
223+
stdout_output, stderr_output = capture_stdout_and_stderr { klass.run(["--json"]) }
224+
225+
# Stdout should NOT contain [Shakapacker] log messages
226+
expect(stdout_output).not_to match(/\[Shakapacker\]/)
227+
228+
# Stderr SHOULD contain [Shakapacker] log messages
229+
expect(stderr_output).to match(/\[Shakapacker\]/)
230+
end
231+
end
232+
233+
it "keeps stdout clean for valid JSON output when using --json flag" do
234+
Dir.chdir(test_app_path) do
235+
klass = Shakapacker::WebpackRunner
236+
instance = klass.new(["--profile", "--json"])
237+
238+
allow(klass).to receive(:new).and_return(instance)
239+
allow(Shakapacker::Utils::Manager).to receive(:error_unless_package_manager_is_obvious!)
240+
241+
allow(instance).to receive(:system) do |*args|
242+
system("true")
243+
true
244+
end
245+
246+
stdout_output, = capture_stdout_and_stderr { klass.run(["--profile", "--json"]) }
247+
248+
# Stdout should be empty (no log messages polluting it)
249+
# The actual JSON would come from webpack itself, not shakapacker
250+
expect(stdout_output).to be_empty
251+
end
252+
end
253+
end
254+
209255
private
210256

257+
def capture_stdout_and_stderr
258+
old_stdout = $stdout
259+
old_stderr = $stderr
260+
$stdout = StringIO.new
261+
$stderr = StringIO.new
262+
yield
263+
[$stdout.string, $stderr.string]
264+
ensure
265+
$stdout = old_stdout
266+
$stderr = old_stderr
267+
end
268+
211269
def capture_stderr
212270
old_stderr = $stderr
213271
$stderr = StringIO.new

0 commit comments

Comments
 (0)