Merge pull request #1605 from alexkuz/patch-1

Configurable stats colors
This commit is contained in:
Tobias Koppers 2015-11-14 15:42:31 +01:00
commit a3837b779a
11 changed files with 197 additions and 154 deletions

View File

@ -312,45 +312,34 @@ Stats.prototype.toString = function toString(options) {
Stats.jsonToString = function jsonToString(obj, useColors) {
var buf = [];
function normal(str) {
buf.push(str);
}
var defaultColors = {
bold: "\u001b[1m",
yellow: "\u001b[1m\u001b[33m",
red: "\u001b[1m\u001b[31m",
green: "\u001b[1m\u001b[32m",
cyan: "\u001b[1m\u001b[36m",
magenta: "\u001b[1m\u001b[35m"
};
function bold(str) {
if(useColors) buf.push("\u001b[1m");
buf.push(str);
if(useColors) buf.push("\u001b[22m");
var colors = Object.keys(defaultColors).reduce(function(obj, color) {
obj[color] = function(str) {
if(useColors) {
buf.push(
(useColors === true || useColors[color] === undefined) ?
defaultColors[color] : useColors[color]
);
}
function yellow(str) {
if(useColors) buf.push("\u001b[1m\u001b[33m");
buf.push(str);
if(useColors) buf.push("\u001b[39m\u001b[22m");
if(useColors) {
buf.push("\u001b[39m\u001b[22m");
}
function red(str) {
if(useColors) buf.push("\u001b[1m\u001b[31m");
};
return obj;
}, {
normal: function(str) {
buf.push(str);
if(useColors) buf.push("\u001b[39m\u001b[22m");
}
function green(str) {
if(useColors) buf.push("\u001b[1m\u001b[32m");
buf.push(str);
if(useColors) buf.push("\u001b[39m\u001b[22m");
}
function cyan(str) {
if(useColors) buf.push("\u001b[1m\u001b[36m");
buf.push(str);
if(useColors) buf.push("\u001b[39m\u001b[22m");
}
function magenta(str) {
if(useColors) buf.push("\u001b[1m\u001b[35m");
buf.push(str);
if(useColors) buf.push("\u001b[39m\u001b[22m");
}
});
function coloredTime(time) {
var times = [800, 400, 200, 100];
@ -358,15 +347,15 @@ Stats.jsonToString = function jsonToString(obj, useColors) {
times = [obj.time / 2, obj.time / 4, obj.time / 8, obj.time / 16];
}
if(time < times[3])
normal(time + "ms");
colors.normal(time + "ms");
else if(time < times[2])
bold(time + "ms");
colors.bold(time + "ms");
else if(time < times[1])
green(time + "ms");
colors.green(time + "ms");
else if(time < times[0])
yellow(time + "ms");
colors.yellow(time + "ms");
else
red(time + "ms");
colors.red(time + "ms");
}
function newline() {
@ -389,17 +378,17 @@ Stats.jsonToString = function jsonToString(obj, useColors) {
}
for(var row = 0; row < rows; row++) {
for(var col = 0; col < cols; col++) {
var format = row === 0 ? bold : formats[col];
var format = row === 0 ? colors.bold : formats[col];
var value = array[row][col] + "";
var l = value.length;
if(align[col] === "l")
format(value);
for(; l < colSizes[col] && col !== cols - 1; l++)
normal(" ");
colors.normal(" ");
if(align[col] === "r")
format(value);
if(col + 1 < cols)
normal(splitter || " ");
colors.normal(splitter || " ");
}
newline();
}
@ -416,24 +405,24 @@ Stats.jsonToString = function jsonToString(obj, useColors) {
}
if(obj.hash) {
normal("Hash: ");
bold(obj.hash);
colors.normal("Hash: ");
colors.bold(obj.hash);
newline();
}
if(obj.version) {
normal("Version: webpack ");
bold(obj.version);
colors.normal("Version: webpack ");
colors.bold(obj.version);
newline();
}
if(typeof obj.time === "number") {
normal("Time: ");
bold(obj.time);
normal("ms");
colors.normal("Time: ");
colors.bold(obj.time);
colors.normal("ms");
newline();
}
if(obj.publicPath) {
normal("PublicPath: ");
bold(obj.publicPath);
colors.normal("PublicPath: ");
colors.bold(obj.publicPath);
newline();
}
if(obj.assets && obj.assets.length > 0) {
@ -449,7 +438,7 @@ Stats.jsonToString = function jsonToString(obj, useColors) {
asset.chunkNames.join(", ")
]);
});
table(t, [green, normal, bold, green, normal], "rrrll");
table(t, [colors.green, colors.normal, colors.bold, colors.green, colors.normal], "rrrll");
}
var modulesByIdentifier = {};
if(obj.modules) {
@ -468,39 +457,39 @@ Stats.jsonToString = function jsonToString(obj, useColors) {
function processProfile(module) {
if(module.profile) {
normal(" ");
colors.normal(" ");
var sum = 0,
allowSum = true;
var path = [];
var current = module;
while(current.issuer) {
if(!modulesByIdentifier["$" + current.issuer]) {
normal(" ... ->");
colors.normal(" ... ->");
allowSum = false;
break;
}
path.unshift(current = modulesByIdentifier["$" + current.issuer]);
}
path.forEach(function(module) {
normal(" [");
normal(module.id);
normal("] ");
colors.normal(" [");
colors.normal(module.id);
colors.normal("] ");
if(module.profile) {
var time = (module.profile.factory || 0) + (module.profile.building || 0);
coloredTime(time);
sum += time;
normal(" ");
colors.normal(" ");
}
normal("->");
colors.normal("->");
});
Object.keys(module.profile).forEach(function(key) {
normal(" " + key + ":");
colors.normal(" " + key + ":");
var time = module.profile[key];
coloredTime(time);
sum += time;
});
if(allowSum) {
normal(" = ");
colors.normal(" = ");
coloredTime(sum);
}
newline();
@ -508,82 +497,82 @@ Stats.jsonToString = function jsonToString(obj, useColors) {
}
function processModuleAttributes(module) {
normal(" ");
normal(formatSize(module.size));
colors.normal(" ");
colors.normal(formatSize(module.size));
if(module.chunks) {
module.chunks.forEach(function(chunk) {
normal(" {");
yellow(chunk);
normal("}");
colors.normal(" {");
colors.yellow(chunk);
colors.normal("}");
});
}
if(!module.cacheable) {
red(" [not cacheable]");
colors.red(" [not cacheable]");
}
if(module.optional) {
yellow(" [optional]");
colors.yellow(" [optional]");
}
if(module.built) {
green(" [built]");
colors.green(" [built]");
}
if(module.prefetched) {
magenta(" [prefetched]");
colors.magenta(" [prefetched]");
}
if(module.failed)
red(" [failed]");
colors.red(" [failed]");
if(module.warnings)
yellow(" [" + module.warnings + " warning" + (module.warnings === 1 ? "" : "s") + "]");
colors.yellow(" [" + module.warnings + " warning" + (module.warnings === 1 ? "" : "s") + "]");
if(module.errors)
red(" [" + module.errors + " error" + (module.errors === 1 ? "" : "s") + "]");
colors.red(" [" + module.errors + " error" + (module.errors === 1 ? "" : "s") + "]");
}
if(obj.chunks) {
obj.chunks.forEach(function(chunk) {
normal("chunk ");
if(chunk.id < 1000) normal(" ");
if(chunk.id < 100) normal(" ");
if(chunk.id < 10) normal(" ");
normal("{");
yellow(chunk.id);
normal("} ");
green(chunk.files.join(", "));
colors.normal("chunk ");
if(chunk.id < 1000) colors.normal(" ");
if(chunk.id < 100) colors.normal(" ");
if(chunk.id < 10) colors.normal(" ");
colors.normal("{");
colors.yellow(chunk.id);
colors.normal("} ");
colors.green(chunk.files.join(", "));
if(chunk.names && chunk.names.length > 0) {
normal(" (");
normal(chunk.names.join(", "));
normal(")");
colors.normal(" (");
colors.normal(chunk.names.join(", "));
colors.normal(")");
}
normal(" ");
normal(formatSize(chunk.size));
colors.normal(" ");
colors.normal(formatSize(chunk.size));
chunk.parents.forEach(function(id) {
normal(" {");
yellow(id);
normal("}");
colors.normal(" {");
colors.yellow(id);
colors.normal("}");
});
if(chunk.rendered) {
green(" [rendered]");
colors.green(" [rendered]");
}
newline();
if(chunk.origins) {
chunk.origins.forEach(function(origin) {
normal(" > ");
colors.normal(" > ");
if(origin.reasons && origin.reasons.length) {
yellow(origin.reasons.join(" "));
normal(" ");
colors.yellow(origin.reasons.join(" "));
colors.normal(" ");
}
if(origin.name) {
normal(origin.name);
normal(" ");
colors.normal(origin.name);
colors.normal(" ");
}
if(origin.module) {
normal("[");
normal(origin.moduleId);
normal("] ");
colors.normal("[");
colors.normal(origin.moduleId);
colors.normal("] ");
var module = modulesByIdentifier["$" + origin.module];
if(module) {
bold(module.name);
normal(" ");
colors.bold(module.name);
colors.normal(" ");
}
if(origin.loc) {
normal(origin.loc);
colors.normal(origin.loc);
}
}
newline();
@ -591,30 +580,30 @@ Stats.jsonToString = function jsonToString(obj, useColors) {
}
if(chunk.modules) {
chunk.modules.forEach(function(module) {
normal(" ");
if(module.id < 1000) normal(" ");
if(module.id < 100) normal(" ");
if(module.id < 10) normal(" ");
normal("[");
normal(module.id);
normal("] ");
bold(module.name);
colors.normal(" ");
if(module.id < 1000) colors.normal(" ");
if(module.id < 100) colors.normal(" ");
if(module.id < 10) colors.normal(" ");
colors.normal("[");
colors.normal(module.id);
colors.normal("] ");
colors.bold(module.name);
processModuleAttributes(module);
newline();
if(module.reasons) {
module.reasons.forEach(function(reason) {
normal(" ");
normal(reason.type);
normal(" ");
cyan(reason.userRequest);
if(reason.templateModules) cyan(reason.templateModules.join(" "));
normal(" [");
normal(reason.moduleId);
normal("] ");
magenta(reason.module);
colors.normal(" ");
colors.normal(reason.type);
colors.normal(" ");
colors.cyan(reason.userRequest);
if(reason.templateModules) colors.cyan(reason.templateModules.join(" "));
colors.normal(" [");
colors.normal(reason.moduleId);
colors.normal("] ");
colors.magenta(reason.module);
if(reason.loc) {
normal(" ");
normal(reason.loc);
colors.normal(" ");
colors.normal(reason.loc);
}
newline();
});
@ -622,7 +611,7 @@ Stats.jsonToString = function jsonToString(obj, useColors) {
processProfile(module);
});
if(chunk.filteredModules > 0) {
normal(" + " + chunk.filteredModules + " hidden modules");
colors.normal(" + " + chunk.filteredModules + " hidden modules");
newline();
}
}
@ -630,29 +619,29 @@ Stats.jsonToString = function jsonToString(obj, useColors) {
}
if(obj.modules) {
obj.modules.forEach(function(module) {
if(module.id < 1000) normal(" ");
if(module.id < 100) normal(" ");
if(module.id < 10) normal(" ");
normal("[");
normal(module.id);
normal("] ");
bold(module.name || module.identifier);
if(module.id < 1000) colors.normal(" ");
if(module.id < 100) colors.normal(" ");
if(module.id < 10) colors.normal(" ");
colors.normal("[");
colors.normal(module.id);
colors.normal("] ");
colors.bold(module.name || module.identifier);
processModuleAttributes(module);
newline();
if(module.reasons) {
module.reasons.forEach(function(reason) {
normal(" ");
normal(reason.type);
normal(" ");
cyan(reason.userRequest);
if(reason.templateModules) cyan(reason.templateModules.join(" "));
normal(" [");
normal(reason.moduleId);
normal("] ");
magenta(reason.module);
colors.normal(" ");
colors.normal(reason.type);
colors.normal(" ");
colors.cyan(reason.userRequest);
if(reason.templateModules) colors.cyan(reason.templateModules.join(" "));
colors.normal(" [");
colors.normal(reason.moduleId);
colors.normal("] ");
colors.magenta(reason.module);
if(reason.loc) {
normal(" ");
normal(reason.loc);
colors.normal(" ");
colors.normal(reason.loc);
}
newline();
});
@ -660,32 +649,32 @@ Stats.jsonToString = function jsonToString(obj, useColors) {
processProfile(module);
});
if(obj.filteredModules > 0) {
normal(" + " + obj.filteredModules + " hidden modules");
colors.normal(" + " + obj.filteredModules + " hidden modules");
newline();
}
}
if(obj._showWarnings && obj.warnings) {
obj.warnings.forEach(function(warning) {
newline();
yellow("WARNING in " + warning);
colors.yellow("WARNING in " + warning);
newline();
});
}
if(obj._showErrors && obj.errors) {
obj.errors.forEach(function(error) {
newline();
red("ERROR in " + error);
colors.red("ERROR in " + error);
newline();
});
}
if(obj.children) {
obj.children.forEach(function(child) {
if(child.name) {
normal("Child ");
bold(child.name);
normal(":");
colors.normal("Child ");
colors.bold(child.name);
colors.normal(":");
} else {
normal("Child");
colors.normal("Child");
}
newline();
buf.push(" ");
@ -694,7 +683,7 @@ Stats.jsonToString = function jsonToString(obj, useColors) {
});
}
if(obj.needAdditionalPass) {
yellow("Compilation needs an additional pass and will compile again.");
colors.yellow("Compilation needs an additional pass and will compile again.");
}
while(buf[buf.length - 1] === "\n") buf.pop();

View File

@ -63,17 +63,32 @@ describe("Stats", function() {
var toStringOptions = {
colors: false
};
var hasColorSetting = false;
if(typeof options.stats !== "undefined") {
toStringOptions = options.stats;
hasColorSetting = typeof options.stats.colors !== "undefined";
}
var actual = stats.toString(toStringOptions);
(typeof actual).should.be.eql("string");
actual =
actual.replace(/\u001b\[[0-9;]*m/g, "")
if(!hasColorSetting) {
actual = actual
.replace(/\u001b\[[0-9;]*m/g, "")
.replace(/[0-9]+(\s?ms)/g, "X$1");
} else {
actual = actual
.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>")
.replace(/[0-9]+(<\/CLR>)?(\s?ms)/g, "X$1$2");
}
actual = actual
.replace(/\r\n?/g, "\n")
.replace(/[\t ]*Version:.+\n/g, "")
.replace(/[0-9]+(\s?ms)/g, "X$1")
.replace(path.join(base, testName), "Xdir/" + testName);
var expected = fs.readFileSync(path.join(base, testName, "expected.txt"), "utf-8").replace(/\r/g, "");
if(actual !== expected) {

View File

@ -0,0 +1,6 @@
Hash: 976ca41fdcf0493c675a
Time: Xms
Asset Size Chunks Chunk Names
main.js 1.53 kB 0 [emitted] main
chunk {0} main.js (main) 0 bytes [rendered]
[0] (webpack)/test/statsCases/color-disabled/index.js 0 bytes {0} [built]

View File

View File

@ -0,0 +1,6 @@
module.exports = {
entry: "./index",
stats: {
colors: false
}
};

View File

@ -0,0 +1,6 @@
Hash: <CLR=BOLD>976ca41fdcf0493c675a</CLR>
Time: <CLR=BOLD>X</CLR>ms
<CLR=BOLD>Asset</CLR> <CLR=BOLD>Size</CLR> <CLR=BOLD>Chunks</CLR> <CLR=39,BOLD><CLR=22> <CLR=BOLD>Chunk Names</CLR>
<CLR=32>main.js</CLR> 1.53 kB <CLR=BOLD>0</CLR> <CLR=32>[emitted]</CLR> main
chunk {<CLR=33>0</CLR>} <CLR=32>main.js</CLR> (main) 0 bytes<CLR=32> [rendered]</CLR>
[0] <CLR=BOLD>(webpack)/test/statsCases/color-enabled-custom/index.js</CLR> 0 bytes {<CLR=33>0</CLR>}<CLR=32> [built]</CLR>

View File

@ -0,0 +1,9 @@
module.exports = {
entry: "./index",
stats: {
colors: {
yellow: '\u001b[33m',
green: '\u001b[32m'
}
}
};

View File

@ -0,0 +1,6 @@
Hash: <CLR=BOLD>976ca41fdcf0493c675a</CLR>
Time: <CLR=BOLD>X</CLR>ms
<CLR=BOLD>Asset</CLR> <CLR=BOLD>Size</CLR> <CLR=BOLD>Chunks</CLR> <CLR=39,BOLD><CLR=22> <CLR=BOLD>Chunk Names</CLR>
<CLR=32,BOLD>main.js</CLR> 1.53 kB <CLR=BOLD>0</CLR> <CLR=32,BOLD>[emitted]</CLR> main
chunk {<CLR=33,BOLD>0</CLR>} <CLR=32,BOLD>main.js</CLR> (main) 0 bytes<CLR=32,BOLD> [rendered]</CLR>
[0] <CLR=BOLD>(webpack)/test/statsCases/color-enabled/index.js</CLR> 0 bytes {<CLR=33,BOLD>0</CLR>}<CLR=32,BOLD> [built]</CLR>

View File

View File

@ -0,0 +1,6 @@
module.exports = {
entry: "./index",
stats: {
colors: true
}
};