Skip to content

Commit fb4fded

Browse files
authored
Merge pull request #11 from codemagic-ci-cd/hermes
Reduce Hermes log noise during release-react
2 parents c15087a + 82e83d3 commit fb4fded

2 files changed

Lines changed: 96 additions & 6 deletions

File tree

script/react-native-utils.ts

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import * as fs from "fs";
2-
import * as chalk from "chalk";
32
import * as path from "path";
43
import * as childProcess from "child_process";
54
import { coerce, compare, valid } from "semver";
@@ -12,6 +11,11 @@ export function isValidVersion(version: string): boolean {
1211
return !!valid(version) || /^\d+\.\d+$/.test(version);
1312
}
1413

14+
function formatProcessOutput(label: string, output: string): string {
15+
const trimmedOutput = output.trim();
16+
return trimmedOutput ? `\n${label}:\n${trimmedOutput}` : "";
17+
}
18+
1519
export async function runHermesEmitBinaryCommand(
1620
bundleName: string,
1721
outputFolder: string,
@@ -33,20 +37,21 @@ export async function runHermesEmitBinaryCommand(
3337
hermesArgs.push("-output-source-map");
3438
}
3539

36-
console.log(chalk.cyan("Converting JS bundle to byte code via Hermes, running command:\n"));
3740
const hermesCommand = await getHermesCommand(gradleFile);
3841
const hermesProcess = childProcess.spawn(hermesCommand, hermesArgs);
39-
console.log(`${hermesCommand} ${hermesArgs.join(" ")}`);
42+
const hermesCommandLine = `${hermesCommand} ${hermesArgs.join(" ")}`;
43+
let hermesStdout = "";
44+
let hermesStderr = "";
4045

4146
return new Promise<void>((resolve, reject) => {
4247
let hermesProcessError: Error = null;
4348

4449
hermesProcess.stdout.on("data", (data: Buffer) => {
45-
console.log(data.toString().trim());
50+
hermesStdout += data.toString();
4651
});
4752

4853
hermesProcess.stderr.on("data", (data: Buffer) => {
49-
console.error(data.toString().trim());
54+
hermesStderr += data.toString();
5055
});
5156

5257
hermesProcess.on("error", (err: Error) => {
@@ -60,7 +65,14 @@ export async function runHermesEmitBinaryCommand(
6065
}
6166

6267
if (exitCode !== 0) {
63-
reject(new Error(`"hermes" command failed (exitCode=${exitCode}, signal=${signal}).`));
68+
reject(
69+
new Error(
70+
`"hermes" command failed (exitCode=${exitCode}, signal=${signal}).` +
71+
`\nCommand:\n${hermesCommandLine}` +
72+
formatProcessOutput("Hermes stdout", hermesStdout) +
73+
formatProcessOutput("Hermes stderr", hermesStderr)
74+
)
75+
);
6476
return;
6577
}
6678

test/react-native-utils.ts

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import * as fs from "fs";
77
import * as os from "os";
88
import * as path from "path";
99
import * as sinon from "sinon";
10+
import { EventEmitter } from "events";
1011
import { getAndroidHermesEnabled, getiOSHermesEnabled, runHermesEmitBinaryCommand } from "../script/react-native-utils";
1112

1213
function getHermesOSBin(): string {
@@ -259,6 +260,83 @@ android {
259260
assert.equal(fs.readFileSync(path.join(outputFolder, bundleName), "utf-8"), "compiled hermes bundle");
260261
});
261262

263+
it("keeps Hermes compiler output quiet when compilation succeeds", async (): Promise<void> => {
264+
writeReactNativeProject(projectPath, "0.84.1");
265+
266+
const hermesCompilerPath = path.join(
267+
"node_modules",
268+
"hermes-compiler",
269+
"hermesc",
270+
getHermesOSBin(),
271+
getHermesCompilerExe()
272+
);
273+
writeFile(path.join(projectPath, hermesCompilerPath));
274+
275+
const outputFolder = path.join(projectPath, "CodePush");
276+
const bundleName = "index.android.bundle";
277+
writeFile(path.join(outputFolder, bundleName), "plain js bundle");
278+
279+
const consoleLog = sandbox.stub(console, "log");
280+
const consoleError = sandbox.stub(console, "error");
281+
sandbox.stub(childProcess, "spawn").callsFake((command: string, args: string[]): any => {
282+
const outputIndex = args.indexOf("-out");
283+
fs.writeFileSync(args[outputIndex + 1], "compiled hermes bundle");
284+
285+
const hermesProcess = new EventEmitter() as any;
286+
hermesProcess.stdout = new EventEmitter();
287+
hermesProcess.stderr = new EventEmitter();
288+
289+
setImmediate(() => {
290+
hermesProcess.stdout.emit("data", Buffer.from("verbose stdout\n"));
291+
hermesProcess.stderr.emit("data", Buffer.from("verbose stderr\n"));
292+
hermesProcess.emit("close", 0, null);
293+
});
294+
295+
return hermesProcess;
296+
});
297+
298+
await runHermesEmitBinaryCommand(bundleName, outputFolder, null, [], null);
299+
300+
sinon.assert.notCalled(consoleLog);
301+
sinon.assert.notCalled(consoleError);
302+
});
303+
304+
it("includes buffered Hermes compiler output when compilation fails", async (): Promise<void> => {
305+
writeReactNativeProject(projectPath, "0.84.1");
306+
307+
const hermesCompilerPath = path.join(
308+
"node_modules",
309+
"hermes-compiler",
310+
"hermesc",
311+
getHermesOSBin(),
312+
getHermesCompilerExe()
313+
);
314+
writeFile(path.join(projectPath, hermesCompilerPath));
315+
316+
const outputFolder = path.join(projectPath, "CodePush");
317+
const bundleName = "index.android.bundle";
318+
writeFile(path.join(outputFolder, bundleName), "plain js bundle");
319+
320+
sandbox.stub(childProcess, "spawn").callsFake((): any => {
321+
const hermesProcess = new EventEmitter() as any;
322+
hermesProcess.stdout = new EventEmitter();
323+
hermesProcess.stderr = new EventEmitter();
324+
325+
setImmediate(() => {
326+
hermesProcess.stdout.emit("data", Buffer.from("useful stdout\n"));
327+
hermesProcess.stderr.emit("data", Buffer.from("useful stderr\n"));
328+
hermesProcess.emit("close", 1, null);
329+
});
330+
331+
return hermesProcess;
332+
});
333+
334+
await assert.rejects(
335+
() => runHermesEmitBinaryCommand(bundleName, outputFolder, null, [], null),
336+
/Hermes stdout:\nuseful stdout[\s\S]*Hermes stderr:\nuseful stderr/
337+
);
338+
});
339+
262340
it("uses explicit Gradle hermesCommand before package autodetection", async (): Promise<void> => {
263341
writeReactNativeProject(projectPath, "0.84.1");
264342
const customHermesCommand = path.join("..", "..", "custom-hermes", "%OS-BIN%", getHermesCompilerExe());

0 commit comments

Comments
 (0)