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: allow running on multiple packages #956

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ test/.*
coverage/
.nyc_output/
.eslintcache
.idea
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ citgm --help
```

```
Usage: citgm [options] <module>
Usage: citgm [options] <module-1> <module-2> <module-n>

Options:

Expand Down
123 changes: 91 additions & 32 deletions lib/bin/citgm.js
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

most of the code taken from citgm-all and used here, if the feature is acceptable I would extract the multiple run to shared file

Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,22 @@ import { windows, Tester } from '../citgm.js';
import { commonArgs } from '../common-args.js';
import { logger } from '../out.js';
import * as reporter from '../reporter/index.js';
import async from 'async';

let mod;
let mods;

const yargs = commonArgs().usage('citgm [options] <module>').option('sha', {
alias: 'c',
type: 'string',
description: 'Install module from commit-sha, branch or tag'
});
const yargs = commonArgs()
.usage('citgm [options] <module-1> <module-2> <module-n>')
.option('sha', {
alias: 'c',
type: 'string',
description: 'Install module from commit-sha, branch or tag'
});

const app = yargs.argv;

mod = app._[0];
mods = app._;
let modules = [];

const log = logger({
level: app.verbose,
Expand All @@ -32,7 +36,7 @@ if (!app.su) {
log.warn('root', 'Running as root! Use caution!');
}

if (!mod) {
if (!mods.length) {
yargs.showHelp();
process.exit(0);
}
Expand All @@ -56,18 +60,23 @@ if (!windows) {
uidnumber(uid, gid, (err, uid, gid) => {
options.uid = uid;
options.gid = gid;
launch(mod, options);
launch();
});
} else {
launch(mod, options);
launch();
}

const start = new Date();
function launch(mod, options) {
function runCitgm(mod, next) {
const start = new Date();
const runner = new Tester(mod, options);
let bailed = false;

function cleanup() {
bailed = true;
runner.cleanup();
process.removeListener('SIGINT', cleanup);
process.removeListener('SIGHUP', cleanup);
process.removeListener('SIGBREAK', cleanup);
}

process.on('SIGINT', cleanup);
Expand All @@ -84,28 +93,78 @@ function launch(mod, options) {
.on('data', (type, key, message) => {
log[type](key, message);
})
.on('end', (module) => {
module.duration = new Date() - start;
reporter.logger(log, module);

log.info('duration', `test duration: ${module.duration}ms`);
if (app.markdown) {
reporter.markdown(log.bypass, module);
}
if (app.tap) {
const tap = typeof app.tap === 'string' ? app.tap : log.bypass;
reporter.tap(tap, module, app.append);
.on('end', (result) => {
result.duration = new Date() - start;
log.info('duration', `test duration: ${result.duration}ms`);
if (result.error) {
log.error(
`${result.name} done`,
`done - the test suite for ${result.name} version ${result.version} failed`
);
} else {
log.info(
`${result.name} done`,
`done - the test suite for ${result.name} version ${result.version} passed.`
);
}

if (app.junit) {
const junit = typeof app.junit === 'string' ? app.junit : log.bypass;
reporter.junit(junit, module, app.append);
modules.push(result);
if (!bailed) {
process.removeListener('SIGINT', cleanup);
process.removeListener('SIGHUP', cleanup);
process.removeListener('SIGBREAK', cleanup);
}

process.removeListener('SIGINT', cleanup);
process.removeListener('SIGHUP', cleanup);
process.removeListener('SIGBREAK', cleanup);
process.exit(module.error ? 1 : 0);
return next(bailed);
})
.run();
}

function runTask(mod, next) {
runCitgm(mod, next);
}

function launch() {
const collection = mods;

const q = async.queue(runTask, app.parallel || 1);
q.push(collection);
function done(exitCode = 0) {
q.kill();
reporter.logger(log, modules);

if (app.markdown) {
reporter.markdown(log.bypass, modules);
}

if (app.tap) {
// If tap is a string it should be a path to write output to
// If not use `log.bypass` which is currently process.stdout.write
// TODO check that we can write to that path, perhaps require a flag to
// Overwrite
const tap = typeof app.tap === 'string' ? app.tap : log.bypass;
reporter.tap(tap, modules, app.append);
}

if (app.junit) {
const junit = typeof app.junit === 'string' ? app.junit : log.bypass;
reporter.junit(junit, modules, app.append);
}

const hasFailures = reporter.util.hasFailures(modules) ? 1 : 0;
process.exit(hasFailures || exitCode);
}

function abort() {
q.pause();
q.kill();
process.removeListener('SIGINT', abort);
process.removeListener('SIGHUP', abort);
process.removeListener('SIGBREAK', abort);
done(1);
}

q.drain(done);

process.on('SIGINT', abort);
process.on('SIGHUP', abort);
process.on('SIGBREAK', abort);
}
23 changes: 23 additions & 0 deletions test/bin/test-citgm.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,29 @@ test('bin: omg-i-pass /w local module', (t) => {
});
});

test('bin: multiple packages', (t) => {
t.plan(3);
const proc = spawn(citgmPath, ['omg-i-pass', 'omg-i-fail']);
let stdout = '';

proc.on('close', (code) => {
t.ok(code !== 0, 'omg-i-fail should fail with a non-zero exit code');
t.match(
stdout,
/info:\s*starting\s*\|\s*omg-i-pass\s*/,
'stdout should contain omg-i-pass'
);
t.match(
stdout,
/info:\s*starting\s*\|\s*omg-i-fail\s*/,
'stdout should contain omg-i-fail'
);
});
proc.stdout.on('data', (data) => {
stdout += data;
});
});

test('bin: no module /w root check', (t) => {
t.plan(1);
const proc = spawn(citgmPath, ['-s']);
Expand Down
Loading