Skip to content

Commit

Permalink
New: Add a 'did you mean?' note when failing to find a task (#94)
Browse files Browse the repository at this point in the history
  • Loading branch information
orta authored Aug 16, 2020
1 parent 6537453 commit 89c9675
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 2 deletions.
29 changes: 28 additions & 1 deletion lib/helpers/normalizeArgs.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ var assert = require('assert');

var map = require('arr-map');
var flatten = require('arr-flatten');
var levenshtein = require('fast-levenshtein');

function normalizeArgs(registry, args) {
function getFunction(task) {
Expand All @@ -12,7 +13,14 @@ function normalizeArgs(registry, args) {
}

var fn = registry.get(task);
assert(fn, 'Task never defined: ' + task);
if (!fn) {
var similar = similarTasks(registry, task);
if (similar.length > 0) {
assert(false, 'Task never defined: ' + task + ' - did you mean? ' + similar.join(', '));
} else {
assert(false, 'Task never defined: ' + task);
}
}
return fn;
}

Expand All @@ -22,4 +30,23 @@ function normalizeArgs(registry, args) {
return map(flattenArgs, getFunction);
}

function similarTasks(registry, queryTask) {
if (typeof queryTask !== 'string') {
return [];
}

var tasks = registry.tasks();
var similarTasks = [];
for (var task in tasks) {
if (tasks.hasOwnProperty(task)) {
var distance = levenshtein.get(task, queryTask);
var allowedDistance = Math.floor(0.4 * task.length) + 1;
if (distance < allowedDistance) {
similarTasks.push(task);
}
}
}
return similarTasks;
}

module.exports = normalizeArgs;
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@
"last-run": "^1.1.0",
"object.defaults": "^1.0.0",
"object.reduce": "^1.0.0",
"undertaker-registry": "^1.0.0"
"undertaker-registry": "^1.0.0",
"fast-levenshtein": "^1.0.0"
},
"devDependencies": {
"async-once": "^1.0.0",
Expand Down
12 changes: 12 additions & 0 deletions test/registry.js
Original file line number Diff line number Diff line change
Expand Up @@ -194,4 +194,16 @@ describe('registry', function() {
taker.series('test')();
});

it('should fail and offer tasks which are close in name', function(done) {
var taker = new Undertaker(new CommonRegistry());
var customRegistry = new DefaultRegistry();
taker.registry(customRegistry);

function fail() {
taker.series('clear');
}

expect(fail).toThrow(/Task never defined: clear - did you mean\? clean/);
done();
});
});

0 comments on commit 89c9675

Please sign in to comment.