Skip to content

Commit

Permalink
feat: Add basic reporter (#78)
Browse files Browse the repository at this point in the history
Add basic reporter for non-TTY environments like CI
  • Loading branch information
jhnns authored Oct 4, 2018
1 parent 96bdc02 commit 59885d3
Show file tree
Hide file tree
Showing 6 changed files with 420 additions and 1 deletion.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ Specify how updated versions should be saved to the `package.json`:
Choose a reporter for the console output:

- `dense` *(default*): See screenshot
- `basic`: Uses `console.log` for output, no need for a TTY (e.g when running on CI)
- `none`: No console output

### `--test` `-t`
Expand Down
212 changes: 212 additions & 0 deletions src/reporters/basic.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
import ansiEscapes from "ansi-escapes";
import chalk from "chalk";
import unicons from "unicons";
import {
filterSuccessfulUpdates,
filterFailedUpdates,
} from "../tasks/util/filterUpdateResults";
import Message from "./util/Message";
import Indicator, {
INDICATOR_NEUTRAL,
INDICATOR_PENDING,
INDICATOR_OK,
INDICATOR_FAIL,
} from "./util/Indicator";
import customConfigToLines from "./util/customConfigToLines";
import pluralize from "./util/pluralize";
import handleError from "./util/handleError";
import msToString from "./util/msToString";

function updatingLine(updateTask) {
return [
new Indicator(INDICATOR_PENDING),
chalk.bold(updateTask.name),
chalk.grey("updating"),
updateTask.rollbackTo,
chalk.grey(unicons.arrowRight),
updateTask.updateTo + chalk.grey("..."),
].join(" ");
}

function testingLine(updateTask) {
return [
new Indicator(INDICATOR_PENDING),
chalk.bold(updateTask.name),
chalk.grey("testing..."),
].join(" ");
}

function rollbackLine(updateTask) {
return [
new Indicator(INDICATOR_FAIL),
chalk.bold.red(updateTask.name),
chalk.grey("rolling back"),
updateTask.updateTo,
chalk.grey(unicons.arrowRight),
updateTask.rollbackTo + chalk.grey("..."),
].join(" ");
}

function successLine(updateTask) {
return [
new Indicator(INDICATOR_OK),
chalk.bold(updateTask.name),
updateTask.updateTo,
chalk.grey("success"),
].join(" ");
}

function failLine(updateTask) {
return [
new Indicator(INDICATOR_FAIL),
chalk.bold.red(updateTask.name),
updateTask.updateTo,
chalk.grey("failed"),
].join(" ");
}

function excludedLine(excluded) {
return [
new Indicator(INDICATOR_NEUTRAL),
chalk.bold(excluded.name),
chalk.grey(excluded.reason),
].join(" ");
}

function cmdToLines(description, cmd) {
const lines = Array.isArray(description) === true ?
description :
[description];

return lines.concat([chalk.grey(`> ${cmd} `)]);
}

function writeLinesToConsole(lines) {
if (lines.length === 0) {
return;
}
console.log(ansiEscapes.eraseDown + lines.join("\n"));
}

export default function basic(updtr, reporterConfig) {
const startTime = Date.now();
let excludedModules;

updtr.on("start", ({config}) => {
writeLinesToConsole(customConfigToLines(config));
});
updtr.on("init/install-missing", ({cmd}) => {
writeLinesToConsole(
cmdToLines(
"Installing missing dependencies" + chalk.grey("..."),
cmd
)
);
});
updtr.on("init/collect", ({cmd}) => {
writeLinesToConsole(
cmdToLines("Looking for outdated modules" + chalk.grey("..."), cmd)
);
});
updtr.on("init/end", ({updateTasks, excluded}) => {
excludedModules = excluded;
if (updateTasks.length === 0 && excluded.length === 0) {
writeLinesToConsole(["Everything " + chalk.bold("up-to-date")]);
} else if (updateTasks.length === 0) {
writeLinesToConsole([
chalk.bold("No updates available") +
" for the given modules and version range",
]);
} else {
writeLinesToConsole([
new Message("Found " + chalk.bold("%s update%s") + ".", [
updateTasks.length,
pluralize(updateTasks.length),
]),
"",
]);
}
});
updtr.on("batch-update/updating", event => {
writeLinesToConsole(
cmdToLines(event.updateTasks.map(updatingLine), event.cmd)
);
});
updtr.on("batch-update/testing", event => {
writeLinesToConsole(
cmdToLines(event.updateTasks.map(testingLine), event.cmd)
);
});
updtr.on("batch-update/rollback", event => {
writeLinesToConsole(
cmdToLines(event.updateTasks.map(rollbackLine), event.cmd)
);
});
updtr.on("batch-update/result", event => {
if (event.success === true) {
writeLinesToConsole(
event.updateTasks.map(event.success ? successLine : failLine)
);
}
// Not showing the test stdout here when there was an error because
// we will proceed with the sequential update.
});
updtr.on("sequential-update/updating", event => {
writeLinesToConsole(cmdToLines(updatingLine(event), event.cmd));
});
updtr.on("sequential-update/testing", event => {
writeLinesToConsole(cmdToLines(testingLine(event), event.cmd));
});
updtr.on("sequential-update/rollback", event => {
writeLinesToConsole(cmdToLines(rollbackLine(event), event.cmd));
});
updtr.on("sequential-update/result", event => {
writeLinesToConsole([(event.success ? successLine : failLine)(event)]);
if (reporterConfig.testStdout === true && event.success === false) {
writeLinesToConsole([event.stdout]);
}
});
updtr.on("end", ({results}) => {
const duration = msToString(Date.now() - startTime);
const successful = filterSuccessfulUpdates(results);
const failed = filterFailedUpdates(results);

writeLinesToConsole([""]);

if (successful.length > 0) {
writeLinesToConsole([
new Message(chalk.bold("%s successful") + " update%s.", [
successful.length,
pluralize(successful.length),
]),
]);
}
if (failed.length > 0) {
writeLinesToConsole([
new Message(chalk.bold("%s failed") + " update%s.", [
failed.length,
pluralize(failed.length),
]),
]);
}
if (excludedModules.length > 0) {
const list = excludedModules.map(excludedLine);

if (successful.length > 0 || failed.length > 0) {
writeLinesToConsole([""]);
}
writeLinesToConsole(
[
new Message(chalk.bold("%s skipped") + " module%s:", [
excludedModules.length,
pluralize(excludedModules.length),
]),
"",
].concat(list)
);
}

writeLinesToConsole(["", new Message("Finished after %s.", [duration])]);
});
updtr.on("error", err => void handleError(err));
}
3 changes: 2 additions & 1 deletion src/reporters/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import basic from "./basic";
import dense from "./dense";
import none from "./none";

// The first property here is the default reporter
const reporters = {dense, none};
const reporters = {dense, basic, none};

export default reporters;
132 changes: 132 additions & 0 deletions test/reporters/__snapshots__/basic.test.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`basic() batch-update fail and show test stdout should print the expected lines: batch-update fail and show test stdout 1`] = `
"Installing missing dependencies...
> npm install 
Looking for outdated modules...
> npm outdated 
Found 4 updates.
- module updating 0.0.0 → 0.0.1...
- module updating 0.0.0 → 0.1.0...
- module updating 0.0.0 → 1.0.0...
- module updating 0.0.0 → 0.0.1...
> npm install 
- module testing...
- module testing...
- module testing...
- module testing...
> npm test 
- module rolling back 0.0.1 → 0.0.0...
- module rolling back 0.1.0 → 0.0.0...
- module rolling back 1.0.0 → 0.0.0...
- module rolling back 0.0.1 → 0.0.0...
> npm install 

2 successful updates.
1 failed update.

Finished after 1.0s."
`;

exports[`basic() batch-update success and show test stdout should print the expected lines: batch-update success and show test stdout 1`] = `
"Installing missing dependencies...
> npm install 
Looking for outdated modules...
> npm outdated 
Found 4 updates.
- module updating 0.0.0 → 0.0.1...
- module updating 0.0.0 → 0.1.0...
- module updating 0.0.0 → 1.0.0...
- module updating 0.0.0 → 0.0.1...
> npm install 
- module testing...
- module testing...
- module testing...
- module testing...
> npm test 
- module 0.0.1 success
- module 0.1.0 success
- module 1.0.0 success
- module 0.0.1 success

3 successful updates.

Finished after 1.0s."
`;

exports[`basic() custom config and only excluded modules should print the expected lines: custom config and only excluded modules 1`] = `
"Running updtr with custom configuration:
- exclude: b, c
Installing missing dependencies...
> npm install 
Looking for outdated modules...
> npm outdated 
No updates available for the given modules and version range

3 skipped modules:
- a git
- b excluded
- c excluded

Finished after 1.0s."
`;

exports[`basic() custom config and sequential-update with mixed success and show test stdout should print the expected lines: custom config and sequential-update with mixed success and show test stdout 1`] = `
"Running updtr with custom configuration:
- exclude: b, c
Installing missing dependencies...
> npm install 
Looking for outdated modules...
> npm outdated 
Found 4 updates.
- module updating 0.0.0 → 0.0.1...
> npm install 
- module testing...
> npm test 
- module 0.0.1 success
- module updating 0.0.0 → 0.1.0...
> npm install 
- module testing...
> npm test 
- module rolling back 0.1.0 → 0.0.0...
> npm install 
- module 0.1.0 failed
This is the test stdout
- module updating 0.0.0 → 1.0.0...
> npm install 
- module testing...
> npm test 
- module 1.0.0 success
- module updating 0.0.0 → 0.0.1...
> npm install 
- module testing...
> npm test 
- module rolling back 0.0.1 → 0.0.0...
> npm install 
- module 0.0.1 failed
This is the test stdout

2 successful updates.
2 failed updates.

Finished after 1.0s."
`;

exports[`basic() no outdated modules should print the expected lines: no outdated modules 1`] = `
"Installing missing dependencies...
> npm install 
Looking for outdated modules...
> npm outdated 
Everything up-to-date


Finished after 1.0s."
`;
1 change: 1 addition & 0 deletions test/reporters/__snapshots__/index.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
exports[`reporters should export all available reporters 1`] = `
Array [
"dense",
"basic",
"none",
]
`;
Loading

0 comments on commit 59885d3

Please sign in to comment.