Skip to content

Commit 89c9675

Browse files
authoredAug 16, 2020
New: Add a 'did you mean?' note when failing to find a task (#94)
1 parent 6537453 commit 89c9675

File tree

3 files changed

+42
-2
lines changed

3 files changed

+42
-2
lines changed
 

‎lib/helpers/normalizeArgs.js

+28-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ var assert = require('assert');
44

55
var map = require('arr-map');
66
var flatten = require('arr-flatten');
7+
var levenshtein = require('fast-levenshtein');
78

89
function normalizeArgs(registry, args) {
910
function getFunction(task) {
@@ -12,7 +13,14 @@ function normalizeArgs(registry, args) {
1213
}
1314

1415
var fn = registry.get(task);
15-
assert(fn, 'Task never defined: ' + task);
16+
if (!fn) {
17+
var similar = similarTasks(registry, task);
18+
if (similar.length > 0) {
19+
assert(false, 'Task never defined: ' + task + ' - did you mean? ' + similar.join(', '));
20+
} else {
21+
assert(false, 'Task never defined: ' + task);
22+
}
23+
}
1624
return fn;
1725
}
1826

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

33+
function similarTasks(registry, queryTask) {
34+
if (typeof queryTask !== 'string') {
35+
return [];
36+
}
37+
38+
var tasks = registry.tasks();
39+
var similarTasks = [];
40+
for (var task in tasks) {
41+
if (tasks.hasOwnProperty(task)) {
42+
var distance = levenshtein.get(task, queryTask);
43+
var allowedDistance = Math.floor(0.4 * task.length) + 1;
44+
if (distance < allowedDistance) {
45+
similarTasks.push(task);
46+
}
47+
}
48+
}
49+
return similarTasks;
50+
}
51+
2552
module.exports = normalizeArgs;

‎package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@
3434
"last-run": "^1.1.0",
3535
"object.defaults": "^1.0.0",
3636
"object.reduce": "^1.0.0",
37-
"undertaker-registry": "^1.0.0"
37+
"undertaker-registry": "^1.0.0",
38+
"fast-levenshtein": "^1.0.0"
3839
},
3940
"devDependencies": {
4041
"async-once": "^1.0.0",

‎test/registry.js

+12
Original file line numberDiff line numberDiff line change
@@ -194,4 +194,16 @@ describe('registry', function() {
194194
taker.series('test')();
195195
});
196196

197+
it('should fail and offer tasks which are close in name', function(done) {
198+
var taker = new Undertaker(new CommonRegistry());
199+
var customRegistry = new DefaultRegistry();
200+
taker.registry(customRegistry);
201+
202+
function fail() {
203+
taker.series('clear');
204+
}
205+
206+
expect(fail).toThrow(/Task never defined: clear - did you mean\? clean/);
207+
done();
208+
});
197209
});

0 commit comments

Comments
 (0)