Skip to content

Commit 9af6fc9

Browse files
authored
fix: support disabling of color output when not in TTY (#557)
* fix: support disabling of color output when not in TTY * chore: color build steps * test: override process tty
1 parent c3c5c3b commit 9af6fc9

File tree

9 files changed

+78
-25
lines changed

9 files changed

+78
-25
lines changed

.travis.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ jobs:
1111
- npm test -- --ci --coverage
1212
- npm run coveralls
1313
- name: build
14-
script: make build
14+
script: npm run build
1515
- stage: commitlint
1616
script: npm run commitlint
1717
if: commit_message !~ /^chore\(deps/
1818
- stage: deploy
19-
script: make build && npm run release
19+
script: npm run build && npm run release
2020
if: branch = master

Makefile

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,6 @@ typescript:
2020
@git reset master --soft && git add --all && git commit -m "chore: typescript"
2121
@echo "typescript: branch created, merge to master to complete coversion"
2222

23-
clean:
24-
rm -rf ./lib
25-
rm -rf ./built
26-
27-
build: clean
28-
npm run build-types
29-
npm run build
30-
3123
ifndef VERBOSE
3224
.SILENT:
3325
endif

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
"types": "index.d.ts",
2727
"scripts": {
2828
"lint": "eslint ./src ./tests --ext .js,.ts",
29+
"clean": "rm -rf ./lib && rm -rf ./build",
2930
"commitlint": "commitlint-travis",
3031
"build": "webpack --mode=production",
3132
"build-watch": "webpack --mode=development --watch",

src/constants.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,26 @@
11
import { Stage } from "./types";
2-
3-
const stageMessage = (m: TemplateStringsArray) => (m ? `\n${String(m)}` : "");
2+
import { style, styles } from "./terminal";
43

54
export const defaultStageMessages: Record<
65
Stage,
76
{ enter?: string; exit?: string }
87
> = {
98
buildEnd: {
10-
enter: stageMessage`🌇 Build exiting 🌇`,
9+
enter: "👋 build exiting",
1110
},
1211
buildError: {
13-
enter: stageMessage`🚒 Build failed 🚒`,
12+
enter: style("🚒 build failed", styles.colors.red, true),
1413
},
1514
buildStart: {
16-
enter: stageMessage`🌅 Build starting 🌅`,
15+
enter: style("🚀 build starting", styles.colors.blue, true),
1716
},
1817
compileEnd: {
19-
enter: stageMessage`⌛ Code compiled ⌛`,
18+
enter: style("⌛ code compiled", styles.colors.green, true),
2019
},
2120
compileStart: {
22-
enter: stageMessage`⏳ Code compiling ⏳`,
21+
enter: style("⏳ code compiling", styles.colors.blue, true),
2322
},
2423
interrupt: {
25-
enter: stageMessage`🚧 Build interrupted 🚧`,
24+
enter: style("🚧 build interrupted", styles.colors.yellow, true),
2625
},
2726
};

src/index.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { Compiler } from "webpack";
33
import { logger } from "./logger";
44
import { defaultStageMessages } from "./constants";
55
import { Options, Stage, StageListeners } from "./types";
6+
import { stageMessage } from "./terminal";
67

78
const defaultListeners: Partial<StageListeners> = {
89
buildError: (e: Error) => {
@@ -44,9 +45,11 @@ export class WebpackCompilerPlugin {
4445
? listener
4546
: defaultListeners[stage];
4647
validOptions.listeners[stage] = async (...args) => {
47-
enterMessage && logger.info(enterMessage);
48+
enterMessage &&
49+
logger.info(stageMessage(options.name, enterMessage));
4850
validListener && validListener(...args);
49-
exitMessage && logger.info(exitMessage);
51+
exitMessage &&
52+
logger.info(stageMessage(options.name, exitMessage));
5053
};
5154
}
5255
return validOptions;

src/terminal.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
const supportsColor = () =>
2+
process.stdout.isTTY &&
3+
!(process.env.ANSI_COLORS_DISABLED || process.env.NO_COLOR);
4+
5+
export const style = (
6+
text: string,
7+
[a, b]: [number, number],
8+
force?: boolean,
9+
) => (supportsColor() || force ? `\x1b[${a}m${text}\x1b[${b}m` : text);
10+
11+
export const styles: Record<string, Record<string, [number, number]>> = {
12+
attrs: {
13+
bold: [1, 22],
14+
},
15+
colors: {
16+
blue: [34, 39],
17+
green: [32, 39],
18+
red: [31, 39],
19+
yellow: [33, 39],
20+
},
21+
};
22+
23+
export const stageMessage = (name: string, message: string) =>
24+
`\n${style(`${name}:`, styles.attrs.bold)} ${message}`;

tests/__snapshots__/index.test.ts.snap

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ exports[`default listeners loads with default buildError listener: console log 1
1212
Array [
1313
Array [
1414
"
15-
🚒 Build failed 🚒",
15+
[1mwebpack-compiler-plugin:[22m [31m🚒 build failed[39m",
1616
],
1717
]
1818
`;
@@ -31,7 +31,7 @@ exports[`default listeners loads with default interrupt listener: console log 1`
3131
Array [
3232
Array [
3333
"
34-
🚧 Build interrupted 🚧",
34+
[1mwebpack-compiler-plugin:[22m [33m🚧 build interrupted[39m",
3535
],
3636
]
3737
`;
@@ -54,7 +54,7 @@ exports[`stage messages uses default state messages buildStart 1`] = `
5454
Array [
5555
Array [
5656
"
57-
🌅 Build starting 🌅",
57+
webpack-compiler-plugin: [34m🚀 build starting[39m",
5858
],
5959
]
6060
`;
@@ -63,7 +63,7 @@ exports[`stage messages uses default state messages compileEnd 1`] = `
6363
Array [
6464
Array [
6565
"
66-
⌛ Code compiled",
66+
webpack-compiler-plugin: [32m⌛ code compiled[39m",
6767
],
6868
]
6969
`;
@@ -72,7 +72,7 @@ exports[`stage messages uses default state messages compileStart 1`] = `
7272
Array [
7373
Array [
7474
"
75-
⏳ Code compiling",
75+
webpack-compiler-plugin: [34m⏳ code compiling[39m",
7676
],
7777
]
7878
`;

tests/index.test.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,14 @@ afterEach(() => {
4242
afterAll(jest.restoreAllMocks);
4343

4444
describe("default listeners", () => {
45+
const isTTY = process.stdout.isTTY;
46+
beforeAll(() => {
47+
process.stdout.isTTY = true;
48+
});
49+
afterAll(() => {
50+
process.stdout.isTTY = isTTY;
51+
});
52+
4553
it.each([
4654
["interrupt", ["SIGINT"]],
4755
["buildError", ["uncaughtException", new Error("Uncaught Error")]],
@@ -87,6 +95,13 @@ describe("apply listeners", () => {
8795
});
8896

8997
describe("stage messages", () => {
98+
beforeAll(() => {
99+
process.env.NO_COLOR = "true";
100+
});
101+
afterAll(() => {
102+
delete process.env.NO_COLOR;
103+
});
104+
90105
it.each([
91106
["buildStart", mockCompiler.hooks.afterPlugins.tap],
92107
["compileEnd", mockCompiler.hooks.done.tap],

webpack.config.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
import { execSync } from "child_process";
12
import * as path from "path";
23
import { Configuration } from "webpack";
34
import * as CopyPlugin from "copy-webpack-plugin";
5+
import { WebpackCompilerPlugin } from "./src";
46

57
const outputPath = path.resolve(__dirname, "lib");
68
const configuration: Configuration = {
@@ -31,6 +33,20 @@ const configuration: Configuration = {
3133
path: outputPath,
3234
},
3335
plugins: [
36+
new WebpackCompilerPlugin({
37+
name: "compiler",
38+
listeners: {
39+
buildStart: () => execSync("npm run clean"),
40+
compileStart: () => execSync("npm run build-types"),
41+
},
42+
stageMessages: {
43+
buildStart: { enter: "clean ouput path" },
44+
compileStart: {
45+
enter: "building types: started",
46+
exit: "building types: finished",
47+
},
48+
},
49+
}),
3450
new CopyPlugin({
3551
patterns: [
3652
"package.json",
@@ -45,6 +61,9 @@ const configuration: Configuration = {
4561
modules: [path.resolve("./src"), path.resolve("./node_modules")],
4662
},
4763
target: "node",
64+
watchOptions: {
65+
ignored: ["./node_modules/**", "./tests/**", "./built/**", outputPath],
66+
},
4867
};
4968

5069
export default configuration;

0 commit comments

Comments
 (0)