Skip to content

Commit

Permalink
feat: cleanup error print, enforce project name in silent mode
Browse files Browse the repository at this point in the history
  • Loading branch information
3cp committed Jul 15, 2019
1 parent e08ef30 commit 54d1f30
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 22 deletions.
6 changes: 5 additions & 1 deletion bin/makes.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ makes(supplier, {
unattended,
here
}).catch(error => {
console.error(error);
if (error.name === 'SoftError') {
console.error(error.message);
} else {
console.error(error);
}
process.exit(1);
});
6 changes: 6 additions & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const {info} = require('./log');
const fs = require('fs');
const prompts = require('./prompts');
const run = require('./run');
const SoftError = require('./soft-error');
const ansiColors = require('ansi-colors');
const sisteransi = require('sisteransi');

Expand Down Expand Up @@ -36,6 +37,11 @@ async function makes(supplier, {
_runQuestionnaire = runQuestionnaire,
_writeProject = writeProject
} = {}) {
if (unattended && !predefinedProperties.name) {
throw new SoftError('Please provide a project name for silent mode, like\n' +
ansiColors.inverse(` npx makes ${supplier} <project-name> -s ${preselectedFeatures.join(',')}${preselectedFeatures.length ? ' ' : ''}`));
}

let skeletonDirectory = await _skeletonDir(supplier);

const {
Expand Down
17 changes: 9 additions & 8 deletions lib/run-questionnaire.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const {select, text} = require('./prompts');
const applicable = require('./applicable');
const SoftError = require('./soft-error');

function isSame(arr1, arr2) {
if (arr1 === arr2) return true;
Expand Down Expand Up @@ -35,7 +36,7 @@ async function run(questions, {
let {choices, name} = question;

if (!name && !choices) {
throw new Error(`Question needs to supply "choices" for selection, or "name" for text prompt. Invalid question:\n` +
throw new SoftError(`Question needs to supply "choices" for selection, or "name" for text prompt. Invalid question:\n` +
JSON.stringify(question, null, 2) + '\n\n');
}

Expand All @@ -45,7 +46,7 @@ async function run(questions, {
}

if (!name && !Array.isArray(choices)) {
throw new Error(`"choices" for select prompt must be an array. Invalid question:\n` +
throw new SoftError(`"choices" for select prompt must be an array. Invalid question:\n` +
JSON.stringify(question, null, 2) + '\n\n');
}

Expand Down Expand Up @@ -91,7 +92,7 @@ async function run(questions, {
async function textPrompt(question, {predefinedProperties, unattended, _debug}) {
const {name} = question;
if (!name.match(/^[a-zA-Z1-9-]+$/)) {
throw new Error(`Name ${JSON.stringify(name)} is invalid. Only accept letters, numbers, and dash(-).` +
throw new SoftError(`Name ${JSON.stringify(name)} is invalid. Only accept letters, numbers, and dash(-).\n` +
'In question:\n' + JSON.stringify(question, null, 2) + '\n\n');
}

Expand All @@ -110,9 +111,9 @@ async function textPrompt(question, {predefinedProperties, unattended, _debug})
const valid = await question.validate.call(undefined, answer);
// simulate same error in predefined/unattended mode
if (typeof valid === 'string' && valid) {
throw new Error(`Invalid "${name}": ${valid}`);
throw new SoftError(`Invalid "${name}": ${valid}`);
} else if (valid === false) {
throw new Error(`Invalid value in "${name}".`);
throw new SoftError(`Invalid value in "${name}".`);
}
}
return answer;
Expand All @@ -125,17 +126,17 @@ async function selectPrompt(question, pickedFeatures, {preselectedFeatures, unat

choices.forEach(c => {
if (multiple && !c.value) {
throw new Error(`Value ${JSON.stringify(c.value)} is invalid. Need to provide a non-empty string value for every choice in multi-select.\n` +
throw new SoftError(`Value ${JSON.stringify(c.value)} is invalid. Need to provide a non-empty string value for every choice in multi-select.\n` +
'In question:\n' + JSON.stringify(question, null, 2) + '\n\n');
}

if (c.value && (typeof c.value !== 'string' || !c.value.match(/^[a-zA-Z1-9-]*$/))) {
throw new Error(`Value ${JSON.stringify(c.value)} is invalid. Only accept letters, numbers, and dash(-).\n` +
throw new SoftError(`Value ${JSON.stringify(c.value)} is invalid. Only accept letters, numbers, and dash(-).\n` +
'In question:\n' + JSON.stringify(question, null, 2) + '\n\n');
}

if (RESERVED_VALUES.includes(c.value)) {
throw new Error(`Value ${JSON.stringify(c.value)} is rejected, because it's one of reserved strings ${JSON.stringify(RESERVED_VALUES)}.\n` +
throw new SoftError(`Value ${JSON.stringify(c.value)} is rejected, because it's one of reserved strings ${JSON.stringify(RESERVED_VALUES)}.\n` +
'In question:\n' + JSON.stringify(question, null, 2) + '\n\n');
}
});
Expand Down
11 changes: 6 additions & 5 deletions lib/skeleton-dir.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const tar = require('tar-fs');
const {info, warn} = require('./log');
const {folderExists} = require('./file-exists');
const useGitRepo = require('./use-git-repo');
const SoftError = require('./soft-error');
const tmp = require('tmp');
tmp.setGracefulCleanup();

Expand Down Expand Up @@ -44,10 +45,10 @@ function getHash(tarball) {
// remove quotes
resolve(hash.replace(/^("|')|("|')$/g, ''));
} else {
reject(new Error('Unable to get unique file name for ' + tarball));
reject(new SoftError('Unable to get unique file name for ' + tarball));
}
} else {
reject(new Error('Unable to get ' + tarball));
reject(new SoftError('Unable to get ' + tarball));
}
});
req.on('error', reject);
Expand Down Expand Up @@ -76,7 +77,7 @@ module.exports = async function(supplier, {
info('Using local skeleton ' + supplier);
return supplier;
}
throw new Error(`Local folder "${supplier}" does not exist.`);
throw new SoftError(`Local folder "${supplier}" does not exist.`);
}

// for "something" or "github:something"
Expand All @@ -87,7 +88,7 @@ module.exports = async function(supplier, {

const result = await _resolve(supplier);
if (!result) {
throw new Error('Cannot find git repo ' + supplier);
throw new SoftError('Cannot find git repo ' + supplier);
}

info('Using remote skeleton ' + result.shortcut);
Expand Down Expand Up @@ -116,7 +117,7 @@ module.exports = async function(supplier, {
.once('error', reject)
.once('finish', resolve);
} else {
reject(new Error(`${res.statusCode} ${res.statusMessage}`));
reject(new SoftError(`${res.statusCode} ${res.statusMessage}`));
}
}).on('error', reject);
});
Expand Down
9 changes: 9 additions & 0 deletions lib/soft-error.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const c = require('ansi-colors');
class SoftError extends Error {
constructor(message) {
super(c.red(message));
this.name = 'SoftError';
}
}

module.exports = SoftError;
16 changes: 8 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,25 +40,25 @@
},
"homepage": "https://github.com/makesjs/makes#readme",
"devDependencies": {
"ansi-colors": "^3.2.4",
"ava": "^2.1.0",
"ansi-colors": "^4.1.1",
"ava": "^2.2.0",
"cross-spawn": "^6.0.5",
"eslint": "^5.16.0",
"eslint": "^6.0.1",
"gunzip-maybe": "^1.4.1",
"hosted-git-info": "^2.7.1",
"isutf8": "^2.0.4",
"lodash.camelcase": "^4.3.0",
"lodash.mergewith": "^4.6.1",
"lodash.mergewith": "^4.6.2",
"minimist": "^1.2.0",
"mock-fs": "^4.10.1",
"nyc": "^14.1.1",
"rimraf": "^2.6.3",
"rollup": "^1.15.1",
"rollup-plugin-commonjs": "^10.0.0",
"rollup": "^1.16.7",
"rollup-plugin-commonjs": "^10.0.1",
"rollup-plugin-json": "^4.0.0",
"rollup-plugin-node-resolve": "^5.0.1",
"rollup-plugin-node-resolve": "^5.2.0",
"rollup-plugin-replace": "^2.2.0",
"sisteransi": "^1.0.0",
"sisteransi": "^1.0.2",
"standard-changelog": "^2.0.11",
"tar-fs": "^2.0.0",
"tmp": "^0.1.0",
Expand Down
9 changes: 9 additions & 0 deletions test/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,15 @@ test('exports getOpts func', t => {
t.is(typeof makes.getOpts, 'function');
});

test.serial('makes complains missing project name in silent mode', async t => {
mockfs();

await t.throwsAsync(async () => makes('supplier', {
predefinedProperties: {},
unattended: true
}));
});

test.serial('makes checks target folder', async t => {
let captured;

Expand Down

0 comments on commit 54d1f30

Please sign in to comment.