Skip to content

Commit

Permalink
Log levels (#367)
Browse files Browse the repository at this point in the history
  • Loading branch information
jamiebuilds committed Oct 8, 2016
1 parent 89d5256 commit 83cac1b
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 58 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -523,3 +523,9 @@ $ lerna publish --only-explicit-updates
```

Ex: in Babel, `babel-types` is depended upon by all packages in the monorepo (over 100). However, Babel uses `^` for most of it's dependencies so it isn't necessary to bump the versions of all packages if only `babel-types` is updated. This option allows only the packages that have been explicitly updated to make a new version.

#### --loglevel [silent|error|warn|success|info|verbose|silly]

What level of logs to report. On failure, all logs are written to lerna-debug.log in the current working directory.

Any logs of a higher level than the setting are shown. The default is "info".
6 changes: 5 additions & 1 deletion bin/lerna.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/usr/bin/env node

var lerna = require("../lib/index");
var logger = require("../lib/logger");
var chalk = require("chalk");
var meow = require("meow");

Expand Down Expand Up @@ -31,7 +32,8 @@ var cli = meow([
" --force-publish Force publish for the specified packages (comma-separated) or all packages using * (skips the git diff check for changed packages)",
" --yes Skip all confirmation prompts",
" --repo-version Specify repo version to publish",
" --concurrency How many threads to use if lerna parallelises the tasks (defaults to 4)"
" --concurrency How many threads to use if lerna parallelises the tasks (defaults to 4)",
" --loglevel What level of logs to report (defaults to \"info\"). On failure, all logs are written to lerna-debug.log in the current working directory.",
], {
alias: {
independent: "i",
Expand All @@ -42,6 +44,8 @@ var cli = meow([

require("signal-exit").unload();

logger.setLogLevel(cli.flags.loglevel);

var commandName = cli.input[0];
var Command = lerna.__commands__[commandName];

Expand Down
24 changes: 12 additions & 12 deletions src/Command.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,31 +34,31 @@ export default class Command {

runValidations() {
if (this.concurrency < 1) {
this.logger.warning("command must be run with at least one thread.");
this.logger.warn("command must be run with at least one thread.");
this._complete(null, 1);
return;
}

if (!FileSystemUtilities.existsSync(this.repository.packagesLocation)) {
this.logger.warning("`packages/` directory does not exist, have you run `lerna init`?");
this.logger.warn("`packages/` directory does not exist, have you run `lerna init`?");
this._complete(null, 1);
return;
}

if (!FileSystemUtilities.existsSync(this.repository.packageJsonLocation)) {
this.logger.warning("`package.json` does not exist, have you run `lerna init`?");
this.logger.warn("`package.json` does not exist, have you run `lerna init`?");
this._complete(null, 1);
return;
}

if (!FileSystemUtilities.existsSync(this.repository.lernaJsonLocation)) {
this.logger.warning("`lerna.json` does not exist, have you run `lerna init`?");
this.logger.warn("`lerna.json` does not exist, have you run `lerna init`?");
this._complete(null, 1);
return;
}

if (this.flags.independent && !this.repository.isIndependent()) {
this.logger.warning(
this.logger.warn(
"You ran lerna with `--independent` or `-i`, but the repository is not set to independent mode. " +
"To use independent mode you need to set your `lerna.json` \"version\" to \"independent\". " +
"Then you won't need to pass the `--independent` or `-i` flags."
Expand All @@ -71,7 +71,7 @@ export default class Command {
process.env.NODE_ENV !== "test" &&
this.lernaVersion !== this.repository.lernaVersion
) {
this.logger.warning(
this.logger.warn(
`Lerna version mismatch: The current version of lerna is ${this.lernaVersion}, ` +
`but the Lerna version in \`lerna.json\` is ${this.repository.lernaVersion}. ` +
`You can either run \`lerna init\` again or install \`lerna@${this.repository.lernaVersion}\`.`
Expand All @@ -81,19 +81,19 @@ export default class Command {
}

if (FileSystemUtilities.existsSync(this.repository.versionLocation)) {
this.logger.warning("You have a `VERSION` file in your repository, this is leftover from a previous ");
this.logger.warn("You have a `VERSION` file in your repository, this is leftover from a previous ");
this._complete(null, 1);
return;
}

if (process.env.NPM_DIST_TAG !== undefined) {
this.logger.warning("`NPM_DIST_TAG=[tagname] lerna publish` is deprecated, please use `lerna publish --tag [tagname]` instead.");
this.logger.warn("`NPM_DIST_TAG=[tagname] lerna publish` is deprecated, please use `lerna publish --tag [tagname]` instead.");
this._complete(null, 1);
return;
}

if (process.env.FORCE_VERSION !== undefined) {
this.logger.warning("`FORCE_VERSION=[package/*] lerna updated/publish` is deprecated, please use `lerna updated/publish --force-publish [package/*]` instead.");
this.logger.warn("`FORCE_VERSION=[package/*] lerna updated/publish` is deprecated, please use `lerna updated/publish --force-publish [package/*]` instead.");
this._complete(null, 1);
return;
}
Expand Down Expand Up @@ -122,17 +122,17 @@ export default class Command {
const methodName = `${this.constructor.name}.${method}`;

try {
this.logger.debug(`Attempting running ${methodName}`);
this.logger.verbose(`Attempting running ${methodName}`);

this[method]((err, completed) => {
if (err) {
this.logger.error(`Errored while running ${methodName}`, err);
this._complete(err, 1, callback);
} else if (!completed) {
this.logger.debug(`Exited early while running ${methodName}`);
this.logger.verbose(`Exited early while running ${methodName}`);
this._complete(null, 1, callback);
} else {
this.logger.debug(`Successfully ran ${methodName}`);
this.logger.verbose(`Successfully ran ${methodName}`);
next();
}
});
Expand Down
2 changes: 1 addition & 1 deletion src/commands/BootstrapCommand.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ export default class BootstrapCommand extends Command {
// then we've encountered a cycle in the dependency graph. Run a
// single-package batch with the package that has the most dependents.
if (todoPackages.length && !batch.length) {
this.logger.warning(
this.logger.warn(
"Encountered a cycle in the dependency graph. " +
"This may cause instability if dependencies are used during `prepublish`."
);
Expand Down
4 changes: 2 additions & 2 deletions src/commands/PublishCommand.js
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ export default class PublishCommand extends Command {
if (FileSystemUtilities.existsSync(scriptLocation)) {
require(scriptLocation);
} else {
this.logger.debug(`No ${script} script found at ${scriptLocation}`);
this.logger.verbose(`No ${script} script found at ${scriptLocation}`);
}
}

Expand All @@ -349,7 +349,7 @@ export default class PublishCommand extends Command {
let attempts = 0;

const run = (cb) => {
this.logger.debug("Publishing " + pkg.name + "...");
this.logger.verbose("Publishing " + pkg.name + "...");

NpmUtilities.publishTaggedInDir("lerna-temp", pkg.location, (err) => {
err = err && err.stack || err;
Expand Down
61 changes: 37 additions & 24 deletions src/logger.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,39 @@ import pad from "pad";

const cwd = process.cwd();

const DEFAULT_LOGLEVEL = "info";

const LEVELS = [
[ "silly", "magenta" ],
[ "verbose", "blue" ],
[ "info", "white" ],
[ "success", "green" ],
[ "warn", "yellow" ],
[ "error", "red" ],
[ "silent", ],
];

const TYPE_TO_LEVEL = LEVELS
.reduce((map, [type], index) => (map[type] = index, map), {});

class Logger {
constructor() {
this.setLogLevel();
this.logs = [];
}

_log(type, verbose, style, message, error) {
setLogLevel(type) {
this.loglevel = TYPE_TO_LEVEL[type || DEFAULT_LOGLEVEL];
}

_log(type, style, level, message, error) {
this.logs.push({
type,
message,
error
});

if (verbose) {
if (level < this.loglevel) {
return;
}

Expand All @@ -29,34 +49,18 @@ class Logger {
}

progressBar.clear();
if (process.env.NODE_ENV !== "test") {
console.log(message);
}
this._emit(message);
progressBar.restore();
}

debug(message, verbose = true) {
this._log("debug", verbose, chalk.blue, message);
}

info(message, verbose = false) {
this._log("info", verbose, chalk.white, message);
}

success(message, verbose = false) {
this._log("success", verbose, chalk.green, message);
}

warning(message, verbose = false) {
this._log("warning", verbose, chalk.yellow, message);
}

error(message, error, verbose = false) {
this._log("error", verbose, chalk.red, message, error);
_emit(message) {
if (process.env.NODE_ENV !== "test") {
console.log(message);
}
}

newLine() {
this.info("");
this._emit("");
}

logifyAsync(target, property, descriptor) {
Expand Down Expand Up @@ -121,4 +125,13 @@ class Logger {
}
}

LEVELS.forEach(([type, color]) => {
if (!color) return; // "silent"
const style = chalk[color];
const level = TYPE_TO_LEVEL[type];
Logger.prototype[type] = function(message, error) {
this._log(type, style, level, message, error);
};
});

export default new Logger();
18 changes: 0 additions & 18 deletions test/UpdatedCommand.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,7 @@ describe("UpdatedCommand", () => {
let calls = 0;
stub(logger, "info", (message) => {
if (calls === 0) assert.equal(message, "Checking for updated packages...");
if (calls === 1) assert.equal(message, "");
if (calls === 2) assert.equal(message, "- package-2\n- package-3");
if (calls === 3) assert.equal(message, "");
calls++;
});

Expand All @@ -65,9 +63,7 @@ describe("UpdatedCommand", () => {
let calls = 0;
stub(logger, "info", (message) => {
if (calls === 0) assert.equal(message, "Checking for updated packages...");
if (calls === 1) assert.equal(message, "");
if (calls === 2) assert.equal(message, "- package-1\n- package-2\n- package-3\n- package-4");
if (calls === 3) assert.equal(message, "");
calls++;
});

Expand All @@ -90,9 +86,7 @@ describe("UpdatedCommand", () => {
let calls = 0;
stub(logger, "info", (message) => {
if (calls === 0) assert.equal(message, "Checking for updated packages...");
if (calls === 1) assert.equal(message, "");
if (calls === 2) assert.equal(message, "- package-2\n- package-3\n- package-4");
if (calls === 3) assert.equal(message, "");
calls++;
});

Expand Down Expand Up @@ -121,9 +115,7 @@ describe("UpdatedCommand", () => {
let calls = 0;
stub(logger, "info", (message) => {
if (calls === 0) assert.equal(message, "Checking for updated packages...");
if (calls === 1) assert.equal(message, "");
if (calls === 2) assert.equal(message, "- package-3");
if (calls === 3) assert.equal(message, "");
calls++;
});

Expand All @@ -146,9 +138,7 @@ describe("UpdatedCommand", () => {
let calls = 0;
stub(logger, "info", (message) => {
if (calls === 0) assert.equal(message, "Checking for updated packages...");
if (calls === 1) assert.equal(message, "");
if (calls === 2) assert.equal(message, "- package-2");
if (calls === 3) assert.equal(message, "");
calls++;
});

Expand Down Expand Up @@ -181,9 +171,7 @@ describe("UpdatedCommand", () => {
let calls = 0;
stub(logger, "info", (message) => {
if (calls === 0) assert.equal(message, "Checking for updated packages...");
if (calls === 1) assert.equal(message, "");
if (calls === 2) assert.equal(message, "- package-3\n- package-4");
if (calls === 3) assert.equal(message, "");
calls++;
});

Expand All @@ -206,9 +194,7 @@ describe("UpdatedCommand", () => {
let calls = 0;
stub(logger, "info", (message) => {
if (calls === 0) assert.equal(message, "Checking for updated packages...");
if (calls === 1) assert.equal(message, "");
if (calls === 2) assert.equal(message, "- package-1\n- package-2\n- package-3\n- package-4");
if (calls === 3) assert.equal(message, "");
calls++;
});

Expand All @@ -231,9 +217,7 @@ describe("UpdatedCommand", () => {
let calls = 0;
stub(logger, "info", (message) => {
if (calls === 0) assert.equal(message, "Checking for updated packages...");
if (calls === 1) assert.equal(message, "");
if (calls === 2) assert.equal(message, "- package-2\n- package-3\n- package-4");
if (calls === 3) assert.equal(message, "");
calls++;
});

Expand Down Expand Up @@ -262,9 +246,7 @@ describe("UpdatedCommand", () => {
let calls = 0;
stub(logger, "info", (message) => {
if (calls === 0) assert.equal(message, "Checking for updated packages...");
if (calls === 1) assert.equal(message, "");
if (calls === 2) assert.equal(message, "- package-3\n- package-4");
if (calls === 3) assert.equal(message, "");
calls++;
});

Expand Down
28 changes: 28 additions & 0 deletions test/logger.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,37 @@
import assert from "assert";
import stub from "./_stub";

import logger from "../src/logger";

describe("logger", () => {
it("should exist", () => {
assert.ok(logger);
});
describe("log levels", () => {
let called;
beforeEach(() => {
called = false;
stub(logger, "_emit", () => called = true);
});
afterEach(() => logger.setLogLevel());

it("should suppress verbose by default", () => {
logger.verbose("test");
assert.ok(!called);
});
it("should emit verbose if configured", () => {
logger.setLogLevel("verbose");
logger.verbose("test");
assert.ok(called);
});
it("should emit error by default", () => {
logger.error("test");
assert.ok(called);
});
it("should suppress error if silent", () => {
logger.setLogLevel("silent");
logger.error("test");
assert.ok(!called);
});
});
});

0 comments on commit 83cac1b

Please sign in to comment.