Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add colors flag to infrastructureLogging #13051

Merged
merged 6 commits into from Apr 6, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions declarations/WebpackOptions.d.ts
Expand Up @@ -1199,6 +1199,10 @@ export interface ExternalsPresets {
* Options for infrastructure level logging.
*/
export interface InfrastructureLogging {
/**
* Enables/Disables colorful output.
*/
colors?: boolean;
/**
* Enable debug logging for specific loggers.
*/
Expand Down
5 changes: 5 additions & 0 deletions lib/config/defaults.js
Expand Up @@ -1079,6 +1079,11 @@ const getResolveLoaderDefaults = ({ cache }) => {
const applyInfrastructureLoggingDefaults = infrastructureLogging => {
D(infrastructureLogging, "level", "info");
D(infrastructureLogging, "debug", false);
D(
infrastructureLogging,
"colors",
process.stderr.isTTY && process.env.TERM !== "dumb"
);
};

exports.applyWebpackOptionsBaseDefaults = applyWebpackOptionsBaseDefaults;
Expand Down
8 changes: 7 additions & 1 deletion lib/node/NodeEnvironmentPlugin.js
Expand Up @@ -24,12 +24,18 @@ class NodeEnvironmentPlugin {
* @returns {void}
*/
apply(compiler) {
const console = nodeConsole(
this.options.infrastructureLogging.colors !== undefined
? this.options.infrastructureLogging.colors
: process.stderr.isTTY && process.env.TERM !== "dumb"
);
delete this.options.infrastructureLogging.colors;
compiler.infrastructureLogger = createConsoleLogger(
Object.assign(
{
level: "info",
debug: false,
console: nodeConsole
console
},
this.options.infrastructureLogging
)
Expand Down
172 changes: 101 additions & 71 deletions lib/node/nodeConsole.js
Expand Up @@ -15,10 +15,10 @@ let hasStatusMessage = false;
let currentIndent = "";
let currentCollapsed = 0;

const indent = (str, prefix, colorPrefix, colorSuffix) => {
const indent = (colors, str, prefix, colorPrefix, colorSuffix) => {
if (str === "") return str;
prefix = currentIndent + prefix;
if (tty) {
if (colors) {
return (
prefix +
colorPrefix +
Expand Down Expand Up @@ -49,86 +49,116 @@ const writeStatusMessage = () => {
hasStatusMessage = true;
};

const writeColored = (prefix, colorPrefix, colorSuffix) => {
const writeColored = (colors, prefix, colorPrefix, colorSuffix) => {
return (...args) => {
if (currentCollapsed > 0) return;
clearStatusMessage();
const str = indent(util.format(...args), prefix, colorPrefix, colorSuffix);
const str = indent(
colors,
util.format(...args),
prefix,
colorPrefix,
colorSuffix
);
process.stderr.write(str + "\n");
writeStatusMessage();
};
};

const writeGroupMessage = writeColored(
"<-> ",
"\u001b[1m\u001b[36m",
"\u001b[39m\u001b[22m"
);
module.exports = colors => {
const writeGroupMessage = writeColored(
colors,
"<-> ",
"\u001b[1m\u001b[36m",
"\u001b[39m\u001b[22m"
);

const writeGroupCollapsedMessage = writeColored(
"<+> ",
"\u001b[1m\u001b[36m",
"\u001b[39m\u001b[22m"
);
const writeGroupCollapsedMessage = writeColored(
colors,
"<+> ",
"\u001b[1m\u001b[36m",
"\u001b[39m\u001b[22m"
);

module.exports = {
log: writeColored(" ", "\u001b[1m", "\u001b[22m"),
debug: writeColored(" ", "", ""),
trace: writeColored(" ", "", ""),
info: writeColored("<i> ", "\u001b[1m\u001b[32m", "\u001b[39m\u001b[22m"),
warn: writeColored("<w> ", "\u001b[1m\u001b[33m", "\u001b[39m\u001b[22m"),
error: writeColored("<e> ", "\u001b[1m\u001b[31m", "\u001b[39m\u001b[22m"),
logTime: writeColored("<t> ", "\u001b[1m\u001b[35m", "\u001b[39m\u001b[22m"),
group: (...args) => {
writeGroupMessage(...args);
if (currentCollapsed > 0) {
return {
log: writeColored(colors, " ", "\u001b[1m", "\u001b[22m"),
debug: writeColored(colors, " ", "", ""),
trace: writeColored(colors, " ", "", ""),
info: writeColored(
colors,
"<i> ",
"\u001b[1m\u001b[32m",
"\u001b[39m\u001b[22m"
),
warn: writeColored(
colors,
"<w> ",
"\u001b[1m\u001b[33m",
"\u001b[39m\u001b[22m"
),
error: writeColored(
colors,
"<e> ",
"\u001b[1m\u001b[31m",
"\u001b[39m\u001b[22m"
),
logTime: writeColored(
colors,
"<t> ",
"\u001b[1m\u001b[35m",
"\u001b[39m\u001b[22m"
),
group: (...args) => {
writeGroupMessage(...args);
if (currentCollapsed > 0) {
currentCollapsed++;
} else {
currentIndent += " ";
}
},
groupCollapsed: (...args) => {
writeGroupCollapsedMessage(...args);
currentCollapsed++;
} else {
currentIndent += " ";
}
},
groupCollapsed: (...args) => {
writeGroupCollapsedMessage(...args);
currentCollapsed++;
},
groupEnd: () => {
if (currentCollapsed > 0) currentCollapsed--;
else if (currentIndent.length >= 2)
currentIndent = currentIndent.slice(0, currentIndent.length - 2);
},
// eslint-disable-next-line node/no-unsupported-features/node-builtins
profile: console.profile && (name => console.profile(name)),
// eslint-disable-next-line node/no-unsupported-features/node-builtins
profileEnd: console.profileEnd && (name => console.profileEnd(name)),
clear:
tty &&
},
groupEnd: () => {
if (currentCollapsed > 0) currentCollapsed--;
else if (currentIndent.length >= 2)
currentIndent = currentIndent.slice(0, currentIndent.length - 2);
},
// eslint-disable-next-line node/no-unsupported-features/node-builtins
console.clear &&
(() => {
clearStatusMessage();
profile: console.profile && (name => console.profile(name)),
// eslint-disable-next-line node/no-unsupported-features/node-builtins
profileEnd: console.profileEnd && (name => console.profileEnd(name)),
clear:
tty &&
// eslint-disable-next-line node/no-unsupported-features/node-builtins
console.clear();
writeStatusMessage();
}),
status: tty
? (name, ...args) => {
args = args.filter(Boolean);
if (name === undefined && args.length === 0) {
clearStatusMessage();
currentStatusMessage = undefined;
} else if (
typeof name === "string" &&
name.startsWith("[webpack.Progress] ")
) {
currentStatusMessage = [name.slice(19), ...args];
writeStatusMessage();
} else if (name === "[webpack.Progress]") {
currentStatusMessage = [...args];
writeStatusMessage();
} else {
currentStatusMessage = [name, ...args];
writeStatusMessage();
}
}
: writeColored("<s> ", "", "")
console.clear &&
(() => {
clearStatusMessage();
// eslint-disable-next-line node/no-unsupported-features/node-builtins
console.clear();
writeStatusMessage();
}),
status: tty
? (name, ...args) => {
args = args.filter(Boolean);
if (name === undefined && args.length === 0) {
clearStatusMessage();
currentStatusMessage = undefined;
} else if (
typeof name === "string" &&
name.startsWith("[webpack.Progress] ")
) {
currentStatusMessage = [name.slice(19), ...args];
writeStatusMessage();
} else if (name === "[webpack.Progress]") {
currentStatusMessage = [...args];
writeStatusMessage();
} else {
currentStatusMessage = [name, ...args];
writeStatusMessage();
}
}
: writeColored(colors, "<s> ", "", "")
};
};
4 changes: 4 additions & 0 deletions schemas/WebpackOptions.json
Expand Up @@ -1211,6 +1211,10 @@
"type": "object",
"additionalProperties": false,
"properties": {
"colors": {
"description": "Enables/Disables colorful output.",
"type": "boolean"
},
"debug": {
"description": "Enable debug logging for specific loggers.",
"anyOf": [
Expand Down
76 changes: 73 additions & 3 deletions test/Compiler.test.js
Expand Up @@ -778,6 +778,12 @@ describe("Compiler", () => {
afterEach(() => {
capture.restore();
});
const escapeAnsi = stringRaw =>
stringRaw
.replace(/\u001b\[1m\u001b\[([0-9;]*)m/g, "<CLR=$1,BOLD>")
.replace(/\u001b\[1m/g, "<CLR=BOLD>")
.replace(/\u001b\[39m\u001b\[22m/g, "</CLR>")
.replace(/\u001b\[([0-9;]*)m/g, "<CLR=$1>");
class MyPlugin {
apply(compiler) {
const logger = compiler.getInfrastructureLogger("MyPlugin");
Expand All @@ -788,7 +794,7 @@ describe("Compiler", () => {
logger.info("Info");
logger.log("Log");
logger.debug("Debug");
logger.groupCollapsed("Collaped group");
logger.groupCollapsed("Collapsed group");
logger.log("Log inside collapsed group");
logger.groupEnd();
logger.groupEnd();
Expand Down Expand Up @@ -817,7 +823,7 @@ describe("Compiler", () => {
<w> [MyPlugin] Warning
<i> [MyPlugin] Info
[MyPlugin] Log
<-> [MyPlugin] Collaped group
<-> [MyPlugin] Collapsed group
[MyPlugin] Log inside collapsed group
<t> [MyPlugin] Time: X ms
"
Expand Down Expand Up @@ -849,7 +855,7 @@ describe("Compiler", () => {
<i> [MyPlugin] Info
[MyPlugin] Log
[MyPlugin] Debug
<-> [MyPlugin] Collaped group
<-> [MyPlugin] Collapsed group
[MyPlugin] Log inside collapsed group
<t> [MyPlugin] Time: X ms
"
Expand All @@ -876,5 +882,69 @@ describe("Compiler", () => {
done();
});
});
it("should log to the console with colors (verbose)", done => {
const compiler = webpack({
context: path.join(__dirname, "fixtures"),
entry: "./a",
output: {
path: "/directory",
filename: "bundle.js"
},
infrastructureLogging: {
level: "verbose",
colors: true
},
plugins: [new MyPlugin()]
});
compiler.outputFileSystem = createFsFromVolume(new Volume());
compiler.run((err, stats) => {
expect(escapeAnsi(capture.toStringRaw()).replace(/[\d.]+ ms/, "X ms"))
.toMatchInlineSnapshot(`
"<-> <CLR=36,BOLD>[MyPlugin] Group</CLR>
<e> <CLR=31,BOLD>[MyPlugin] Error</CLR>
<w> <CLR=33,BOLD>[MyPlugin] Warning</CLR>
<i> <CLR=32,BOLD>[MyPlugin] Info</CLR>
<CLR=BOLD>[MyPlugin] Log<CLR=22>
<-> <CLR=36,BOLD>[MyPlugin] Collapsed group</CLR>
<CLR=BOLD>[MyPlugin] Log inside collapsed group<CLR=22>
<t> <CLR=35,BOLD>[MyPlugin] Time: X ms</CLR>
"
`);
done();
});
});
it("should log to the console with colors (debug mode)", done => {
const compiler = webpack({
context: path.join(__dirname, "fixtures"),
entry: "./a",
output: {
path: "/directory",
filename: "bundle.js"
},
infrastructureLogging: {
level: "error",
debug: /MyPlugin/,
colors: true
},
plugins: [new MyPlugin()]
});
compiler.outputFileSystem = createFsFromVolume(new Volume());
compiler.run((err, stats) => {
expect(escapeAnsi(capture.toStringRaw()).replace(/[\d.]+ ms/, "X ms"))
.toMatchInlineSnapshot(`
"<-> <CLR=36,BOLD>[MyPlugin] Group</CLR>
<e> <CLR=31,BOLD>[MyPlugin] Error</CLR>
<w> <CLR=33,BOLD>[MyPlugin] Warning</CLR>
<i> <CLR=32,BOLD>[MyPlugin] Info</CLR>
<CLR=BOLD>[MyPlugin] Log<CLR=22>
[MyPlugin] Debug
<-> <CLR=36,BOLD>[MyPlugin] Collapsed group</CLR>
<CLR=BOLD>[MyPlugin] Log inside collapsed group<CLR=22>
<t> <CLR=35,BOLD>[MyPlugin] Time: X ms</CLR>
"
`);
done();
});
});
});
});
1 change: 1 addition & 0 deletions test/Defaults.unittest.js
Expand Up @@ -109,6 +109,7 @@ describe("Defaults", () => {
"externalsType": "var",
"ignoreWarnings": undefined,
"infrastructureLogging": Object {
"colors": undefined,
"debug": false,
"level": "info",
},
Expand Down
13 changes: 13 additions & 0 deletions test/__snapshots__/Cli.test.js.snap
Expand Up @@ -751,6 +751,19 @@ Object {
"multiple": false,
"simpleType": "boolean",
},
"infrastructure-logging-colors": Object {
"configs": Array [
Object {
"description": "Enables/Disables colorful output.",
"multiple": false,
"path": "infrastructureLogging.colors",
"type": "boolean",
},
],
"description": "Enables/Disables colorful output.",
"multiple": false,
"simpleType": "boolean",
},
"infrastructure-logging-debug": Object {
"configs": Array [
Object {
Expand Down