Skip to content

Commit

Permalink
[New] add --help, --version; accept a path to another directory; …
Browse files Browse the repository at this point in the history
…nicer error messages
  • Loading branch information
ljharb committed Jun 20, 2024
1 parent 5c481c1 commit 69371ff
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 8 deletions.
50 changes: 48 additions & 2 deletions nvmrc.mjs
Original file line number Diff line number Diff line change
@@ -1,9 +1,55 @@
#! /usr/bin/env node

import { readFile } from 'fs/promises';
import { join } from 'path';
import { existsSync } from 'fs';
import { join, sep } from 'path';
import { parseArgs } from 'util';

const contentsP = readFile(join(process.cwd(), '.nvmrc'));
const {
values: {
help,
version,
},
positionals,
} = parseArgs({
allowPositionals: true,
options: {
help: { type: 'boolean' },
version: { type: 'boolean' },
},
});

const cwd = process.cwd();

if (help) {
console.log(`nvmrc
command-line tool to validate a \`.nvmrc\` file
Positionals:
<dir> a relative path to a directory containing a \`.nvmrc\` file [default: \`${cwd}\`]
Options:
--version Show version number [boolean]
--help Show help [boolean]`);
process.exit(0);
} else if (version) {
console.log(`v${(await import('module')).createRequire(import.meta.url)('./package.json').version}`);
process.exit(0);
} else if (positionals.length > 1) {
console.error(`expected exactly zero or one positional arguments; got ${positionals.length}`);
}

const [dir = cwd] = positionals;

const file = join(dir, '.nvmrc');

if (!existsSync(file)) {
console.error(`\`.nvmrc\` file not found in \`${dir.replace(sep === '/' ? /\/?$/ : /\\?$/, sep)}\``);
process.exit(1);
}

const contentsP = readFile(file);

const contentsStr = `${await contentsP}`;

Expand Down
52 changes: 46 additions & 6 deletions test/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,52 @@ const invalid = readdirSync(join(fixtureDir, 'invalid'));
test('nvmrc', async (t) => {
const bin = join(import.meta.dirname, '../nvmrc.mjs');

t.test('--help', async (st) => {
const { status, stdout, stderr } = spawnSync(`${bin}`, ['--help']);

st.equal(status, 0, 'yields a zero exit code');
st.equal(String(stderr), '', 'yields no stderr');
st.notEqual(String(stdout).replace(/^\s+|\s+$/g, ''), 'trimmed stdout is nonempty');
});

t.test('--version', async (st) => {
const { status, stdout, stderr } = spawnSync(`${bin}`, ['--version']);

st.equal(status, 0, 'yields a zero exit code');
st.equal(String(stderr), '', 'yields no stderr');
st.notEqual(
String(stdout),
`v${(await import('module')).createRequire(import.meta.url)('../package.json').version}`,
'version is as expected',
);
});

t.test('nonexistent file', async (st) => {
const cwd = import.meta.dirname;
const { status, stdout, stderr } = spawnSync(`${bin}`, { cwd });
st.notEqual(status, 0, 'yields a nonzero exit code');
st.equal(String(stdout), '', 'yields no stdout');
st.notEqual(
String(stderr),
'',
'stderr is nonempty',
);
});

t.test('too many files', async (st) => {
const { status, stdout, stderr } = spawnSync(`${bin}`, ['a', 'b']);

st.notEqual(status, 0, 'yields a nonzero exit code');
st.equal(String(stdout), '', 'yields no stdout');
st.notEqual(
String(stderr),
'',
'stderr is nonempty',
);
});

for (const fixture of valid) {
t.test(`fixture ${fixture}`, (st) => {
t.test(`fixture ${fixture}`, async (st) => {
const cwd = join(fixtureDir, 'valid', fixture);

const { status, stdout } = spawnSync(`${bin}`, { cwd });
Expand All @@ -29,13 +73,11 @@ test('nvmrc', async (t) => {
const expected = JSON.parse(`${readFileSync(join(cwd, 'expected.json'))}`);

st.deepEqual(JSON.parse(stripped), expected, `fixture ${fixture} yields expected result`);

st.end();
});
}

for (const fixture of invalid) {
t.test(`fixture ${fixture}`, (st) => {
t.test(`fixture ${fixture}`, async (st) => {
const cwd = join(fixtureDir, 'invalid', fixture);

const { status, stderr } = spawnSync(`${bin}`, { cwd });
Expand All @@ -58,8 +100,6 @@ test('nvmrc', async (t) => {
const expected = JSON.parse(`${readFileSync(join(cwd, 'expected.json'))}`);

st.deepEqual(lines.slice(6), expected, `fixture ${fixture} produces expected warning lines`);

st.end();
});
}
});

0 comments on commit 69371ff

Please sign in to comment.