diff --git a/lib/cli.js b/lib/cli.js index 99689481..ead662b7 100755 --- a/lib/cli.js +++ b/lib/cli.js @@ -12,7 +12,6 @@ import rootCheck from 'root-check'; import meow from 'meow'; import list from 'cli-list'; import {bootstrap} from 'global-agent'; -import Tabtab from './completion/tabtab.cjs'; import pkg from './utils/project-package.js'; import Router from './router.js'; import * as routes from './routes/index.js'; @@ -71,14 +70,7 @@ async function pre() { } if (cmd === 'completion') { - // eslint-disable-next-line new-cap - const tabtab = new Tabtab.Commands.default({ - name: 'yo', - completer: 'yo-complete', - cache: false, - }); - - return tabtab.install(); + throw new Error('Tabtab completion is no longer supported. See https://github.com/yeoman/yo/issues/886'); } // Easteregg diff --git a/lib/completion/completer.js b/lib/completion/completer.js deleted file mode 100644 index e1d1d96d..00000000 --- a/lib/completion/completer.js +++ /dev/null @@ -1,106 +0,0 @@ -import path from 'node:path'; -import {execFile} from 'node:child_process'; -import parseHelp from 'parse-help'; -import {getDirname} from '../utils/node-shims.js'; - -/** - * The Completer is in charge of handling `yo-complete` behavior. - * @constructor - * @param {Environment} env A yeoman environment instance - */ -class Completer { - constructor(env) { - this.env = env; - } - - /** - * Completion event done - * - * @param {String} data Environment object as parsed by tabtab - * @param {Function} done Callback to invoke with completion results - */ - complete(data, done) { - if (data.last !== 'yo' && !data.last.startsWith('-')) { - return this.generator(data, done); - } - - this.env.lookup().catch(done).then(() => { - const meta = this.env.getGeneratorsMeta(); - const results = Object.keys(meta).map(this.item('yo'), this); - done(null, results); - }); - } - - /** - * Generator completion event done - * - * @param {String} data Environment object as parsed by tabtab - * @param {Function} done Callback to invoke with completion results - */ - generator(data, done) { - const {last} = data; - const binary = path.resolve(getDirname(import.meta.url), '../cli.js'); - - execFile('node', [binary, last, '--help'], (error, out) => { - if (error) { - done(error); - return; - } - - const results = this.parseHelp(last, out); - done(null, results); - }); - } - - /** - * Helper to format completion results into { name, description } objects - * - * @param {String} data Environment object as parsed by tabtab - * @param {Function} done Callback to invoke with completion results - */ - item(desc, prefix = '') { - return item => { - const name = typeof item === 'string' ? item : item.name; - desc = typeof item !== 'string' && item.description ? item.description : desc; - desc = desc.replaceAll(/^#?\s*/g, ''); - desc = desc.replaceAll(':', '->'); - desc = desc.replaceAll('\'', ' '); - - return { - name: prefix + name, - description: desc, - }; - }; - } - - /** - * Parse-help wrapper. Invokes parse-help with stdout result, returning the - * list of completion items for flags / alias. - * - * @param {String} last Last word in COMP_LINE (completed line in command line) - * @param {String} out Help output - */ - parseHelp(last, out) { - const help = parseHelp(out); - const alias = []; - - let results = Object.keys(help.flags).map(key => { - const flag = help.flags[key]; - - if (flag.alias) { - alias.push({...flag, name: flag.alias}); - } - - flag.name = key; - - return flag; - }).map(this.item(last, '--'), this); - - results = [...results, ...alias.map(this.item(last.replace(':', '_'), '-'), this)]; - results = results.filter(r => r.name !== '--help' && r.name !== '-h'); - - return results; - } -} - -export default Completer; diff --git a/lib/completion/index.cjs b/lib/completion/index.cjs deleted file mode 100755 index 7ade6c6b..00000000 --- a/lib/completion/index.cjs +++ /dev/null @@ -1,22 +0,0 @@ -#! /usr/bin/env node -const tabtab = require('./tabtab.cjs')({ - name: 'yo', - cache: !require('node:process').env.YO_TEST, -}); - -(async () => { - const {createEnv} = await import('yeoman-environment'); - const {default: Completer} = await import('./completer.js'); - const completer = new Completer(createEnv()); - - tabtab.completer = completer; - - // Lookup installed generator in yeoman environment, - // respond completion results with each generator - tabtab.on('yo', completer.complete.bind(completer)); - - // Register complete command - tabtab.start(); -})(); - -module.exports = tabtab; diff --git a/lib/completion/tabtab.cjs b/lib/completion/tabtab.cjs deleted file mode 100644 index 395598c2..00000000 --- a/lib/completion/tabtab.cjs +++ /dev/null @@ -1,3 +0,0 @@ -const tabtab = require('tabtab'); - -module.exports = tabtab; diff --git a/lib/usage.txt b/lib/usage.txt index cdf61e30..6dd0aad4 100644 --- a/lib/usage.txt +++ b/lib/usage.txt @@ -21,12 +21,6 @@ Run local generators: $ yo ./path/to/some/generator -Completion: - - To enable shell completion for the yo command, try running - - $ yo completion - Troubleshooting: For any issues, try running diff --git a/package-lock.json b/package-lock.json index d5b626eb..16fbfc4b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,7 +30,6 @@ "root-check": "^2.0.0", "sort-on": "^6.1.1", "string-length": "^6.0.0", - "tabtab": "^1.3.2", "titleize": "^4.0.0", "update-notifier": "^7.3.1", "yeoman-character": "^2.0.0", @@ -39,8 +38,7 @@ "yosay": "^3.0.0" }, "bin": { - "yo": "lib/cli.js", - "yo-complete": "lib/completion/index.cjs" + "yo": "lib/cli.js" }, "devDependencies": { "c8": "^10.1.3", @@ -3968,12 +3966,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/ansi": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/ansi/-/ansi-0.3.1.tgz", - "integrity": "sha512-iFY7JCgHbepc0b82yLaw4IMortylNb6wG4kL+4R0C3iv6i+RHGHux/yUX5BTiRvSX/shMnngjR1YyNMnXEFh5A==", - "license": "MIT" - }, "node_modules/ansi-align": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", @@ -4089,17 +4081,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/are-we-there-yet": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", - "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", - "deprecated": "This package is no longer supported.", - "license": "ISC", - "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, "node_modules/argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -4778,12 +4759,6 @@ "node-int64": "^0.4.0" } }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "license": "MIT" - }, "node_modules/builtin-modules": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-5.0.0.tgz", @@ -5349,15 +5324,6 @@ "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -5442,21 +5408,6 @@ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "license": "MIT" }, - "node_modules/concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "engines": [ - "node >= 0.8" - ], - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, "node_modules/config-chain": { "version": "1.1.13", "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", @@ -5525,12 +5476,6 @@ "url": "https://opencollective.com/core-js" } }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "license": "MIT" - }, "node_modules/cosmiconfig": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", @@ -5867,12 +5812,6 @@ "node": ">=0.4.0" } }, - "node_modules/delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", - "license": "MIT" - }, "node_modules/detect-node": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", @@ -7331,15 +7270,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/exit-hook": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", - "integrity": "sha512-MsG3prOVw1WtLXAZbM3KiYtooKR1LvxHh3VHsVtIy0uiUu8usxgB/94DP2HxtD/661lLdB6yzQ09lGJSQr6nkg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/expect": { "version": "30.1.2", "resolved": "https://registry.npmjs.org/expect/-/expect-30.1.2.tgz", @@ -7368,19 +7298,9 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true, "license": "MIT" }, - "node_modules/external-editor": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-1.1.1.tgz", - "integrity": "sha512-0XYlP43jzxMgJjugDJ85Z0UDPnowkUbfFztNvsSGC9sJVIk97MZbGEb9WAhIVH0UgNxoLj/9ZQgB4CHJyz2GGQ==", - "license": "MIT", - "dependencies": { - "extend": "^3.0.0", - "spawn-sync": "^1.0.15", - "tmp": "^0.0.29" - } - }, "node_modules/extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", @@ -7941,20 +7861,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/gauge": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-1.2.7.tgz", - "integrity": "sha512-fVbU2wRE91yDvKUnrIaQlHKAWKY5e08PmztCrwuH5YVQ+Z/p3d0ny2T48o6uvAAXHIUnfaQdHkmxYbQft1eHVA==", - "deprecated": "This package is no longer supported.", - "license": "ISC", - "dependencies": { - "ansi": "^0.3.0", - "has-unicode": "^2.0.0", - "lodash.pad": "^4.1.0", - "lodash.padend": "^4.1.0", - "lodash.padstart": "^4.1.0" - } - }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -8334,27 +8240,6 @@ "node": ">=6" } }, - "node_modules/has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-ansi/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/has-bigints": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", @@ -8434,12 +8319,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", - "license": "ISC" - }, "node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", @@ -8703,6 +8582,7 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, "license": "ISC" }, "node_modules/ini": { @@ -9440,12 +9320,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "license": "MIT" - }, "node_modules/isbinaryfile": { "version": "5.0.6", "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-5.0.6.tgz", @@ -10241,24 +10115,6 @@ "dev": true, "license": "MIT" }, - "node_modules/lodash.pad": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/lodash.pad/-/lodash.pad-4.5.1.tgz", - "integrity": "sha512-mvUHifnLqM+03YNzeTBS1/Gr6JRFjd3rRx88FHWUvamVaT9k2O/kXha3yBSOwB9/DTQrSTLJNHvLBBt2FdX7Mg==", - "license": "MIT" - }, - "node_modules/lodash.padend": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/lodash.padend/-/lodash.padend-4.6.1.tgz", - "integrity": "sha512-sOQs2aqGpbl27tmCS1QNZA09Uqp01ZzWfDUoD+xzTii0E7dSQfRKcRetFwa+uXaxaqL+TKm7CgD2JdKP7aZBSw==", - "license": "MIT" - }, - "node_modules/lodash.padstart": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/lodash.padstart/-/lodash.padstart-4.6.1.tgz", - "integrity": "sha512-sW73O6S8+Tg66eY56DBk85aQzzUJDtpoXFBgELMd5P/SotAguo+1kYO6RuYgXxA4HJH3LFTFPASX6ET6bjfriw==", - "license": "MIT" - }, "node_modules/log-driver": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", @@ -10758,18 +10614,6 @@ "node": ">= 18" } }, - "node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "license": "MIT", - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, "node_modules/mocha": { "version": "11.7.2", "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.7.2.tgz", @@ -11360,27 +11204,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/npmlog": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-2.0.4.tgz", - "integrity": "sha512-DaL6RTb8Qh4tMe2ttPT1qWccETy2Vi5/8p+htMpLBeXJTr2CAqnF5WQtSP2eFpvaNbhLZ5uilDb98mRm4Q+lZQ==", - "deprecated": "This package is no longer supported.", - "license": "ISC", - "dependencies": { - "ansi": "~0.3.1", - "are-we-there-yet": "~1.1.2", - "gauge": "~1.2.5" - } - }, - "node_modules/number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", @@ -11405,6 +11228,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -11787,23 +11611,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/os-shim": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/os-shim/-/os-shim-0.1.3.tgz", - "integrity": "sha512-jd0cvB8qQ5uVt0lvCIexBaROw1KyKm5sbulg2fWOHjETisuCzWyt+eTZKEMs8v6HwzoGs8xik26jg7eCM6pS+A==", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/outvariant": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/outvariant/-/outvariant-1.4.3.tgz", @@ -12335,27 +12142,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", - "license": "MIT", - "dependencies": { - "pinkie": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/pirates": { "version": "4.0.7", "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", @@ -12518,12 +12304,6 @@ "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "license": "MIT" - }, "node_modules/proggy": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/proggy/-/proggy-3.0.0.tgz", @@ -12781,27 +12561,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/readable-stream/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "license": "MIT" - }, "node_modules/readdirp": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", @@ -13166,12 +12925,6 @@ "queue-microtask": "^1.2.2" } }, - "node_modules/rx": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz", - "integrity": "sha512-CiaiuN6gapkdl+cZUr67W6I8jquN4lkak3vtIsIWCl4XIPP8ffsoyN6/+PuGXnQy8Cu8W2y9Xxh31Rq4M6wUug==", - "license": "Apache-2.0" - }, "node_modules/rxjs": { "version": "7.8.2", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", @@ -13616,17 +13369,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/spawn-sync": { - "version": "1.0.15", - "resolved": "https://registry.npmjs.org/spawn-sync/-/spawn-sync-1.0.15.tgz", - "integrity": "sha512-9DWBgrgYZzNghseho0JOuh+5fg9u6QWhAWa51QC7+U5rCheZ/j1DrEZnyE0RBBRqZ9uEXGPgSSM0nky6burpVw==", - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "concat-stream": "^1.4.7", - "os-shim": "^0.1.2" - } - }, "node_modules/spdx-correct": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", @@ -13781,21 +13523,6 @@ "dev": true, "license": "MIT" }, - "node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/string_decoder/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "license": "MIT" - }, "node_modules/string-length": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/string-length/-/string-length-6.0.0.tgz", @@ -14216,227 +13943,6 @@ "url": "https://opencollective.com/synckit" } }, - "node_modules/tabtab": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/tabtab/-/tabtab-1.3.2.tgz", - "integrity": "sha512-qHWOJ5g7lrpftZMyPv3ZaYZs7PuUTKWEP/TakZHfpq66bSwH25SQXn5616CCh6Hf/1iPcgQJQHGcJkzQuATabQ==", - "license": "MIT", - "dependencies": { - "debug": "^2.2.0", - "inquirer": "^1.0.2", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", - "npmlog": "^2.0.3", - "object-assign": "^4.1.0" - }, - "bin": { - "tabtab": "bin/tabtab" - } - }, - "node_modules/tabtab/node_modules/ansi-escapes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", - "integrity": "sha512-wiXutNjDUlNEDWHcYH3jtZUhd3c4/VojassD8zHdHCY13xbZy2XbW+NKQwA0tWGBVzDA9qEzYwfoSsWmviidhw==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/tabtab/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/tabtab/node_modules/ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/tabtab/node_modules/chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/tabtab/node_modules/cli-cursor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", - "integrity": "sha512-25tABq090YNKkF6JH7lcwO0zFJTRke4Jcq9iX2nr/Sz0Cjjv4gckmwlW6Ty/aoyFd6z3ysR2hMGC2GFugmBo6A==", - "license": "MIT", - "dependencies": { - "restore-cursor": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/tabtab/node_modules/cli-width": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", - "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", - "license": "ISC" - }, - "node_modules/tabtab/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/tabtab/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/tabtab/node_modules/figures": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", - "integrity": "sha512-UxKlfCRuCBxSXU4C6t9scbDyWZ4VlaFFdojKtzJuSkuOBQ5CNFum+zZXFwHjo+CxBC1t6zlYPgHIgFjL8ggoEQ==", - "license": "MIT", - "dependencies": { - "escape-string-regexp": "^1.0.5", - "object-assign": "^4.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/tabtab/node_modules/inquirer": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-1.2.3.tgz", - "integrity": "sha512-diSnpgfv/Ozq6QKuV2mUcwZ+D24b03J3W6EVxzvtkCWJTPrH2gKLsqgSW0vzRMZZFhFdhnvzka0RUJxIm7AOxQ==", - "license": "MIT", - "dependencies": { - "ansi-escapes": "^1.1.0", - "chalk": "^1.0.0", - "cli-cursor": "^1.0.1", - "cli-width": "^2.0.0", - "external-editor": "^1.1.0", - "figures": "^1.3.5", - "lodash": "^4.3.0", - "mute-stream": "0.0.6", - "pinkie-promise": "^2.0.0", - "run-async": "^2.2.0", - "rx": "^4.1.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.0", - "through": "^2.3.6" - } - }, - "node_modules/tabtab/node_modules/is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==", - "license": "MIT", - "dependencies": { - "number-is-nan": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/tabtab/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" - }, - "node_modules/tabtab/node_modules/mute-stream": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.6.tgz", - "integrity": "sha512-m0kBTDLF/0lgzCsPVmJSKM5xkLNX7ZAB0Q+n2DP37JMIRPVC2R4c3BdO6x++bXFKftbhvSfKgwxAexME+BRDRw==", - "license": "ISC" - }, - "node_modules/tabtab/node_modules/onetime": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", - "integrity": "sha512-GZ+g4jayMqzCRMgB2sol7GiCLjKfS1PINkjmx8spcKce1LiVqcbQreXwqs2YAFXC6R03VIG28ZS31t8M866v6A==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/tabtab/node_modules/restore-cursor": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", - "integrity": "sha512-reSjH4HuiFlxlaBaFCiS6O76ZGG2ygKoSlCsipKdaZuKSPx/+bt9mULkn4l0asVzbEfQQmXRg6Wp6gv6m0wElw==", - "license": "MIT", - "dependencies": { - "exit-hook": "^1.0.0", - "onetime": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/tabtab/node_modules/run-async": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/tabtab/node_modules/string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==", - "license": "MIT", - "dependencies": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/tabtab/node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/tabtab/node_modules/supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/tapable": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.3.tgz", @@ -14530,12 +14036,6 @@ "url": "https://bevry.me/fund" } }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "license": "MIT" - }, "node_modules/time-span": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/time-span/-/time-span-5.1.0.tgz", @@ -14579,18 +14079,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/tmp": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.29.tgz", - "integrity": "sha512-89PTqMWGDva+GqClOqBV9s3SMh7MA3Mq0pJUdAoHuF65YoE7O0LermaZkVfT5/Ngfo18H4eYiyG7zKOtnEbxsw==", - "license": "MIT", - "dependencies": { - "os-tmpdir": "~1.0.1" - }, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", @@ -14909,12 +14397,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "license": "MIT" - }, "node_modules/typescript": { "version": "5.9.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz", diff --git a/package.json b/package.json index 33226d68..373cf2af 100644 --- a/package.json +++ b/package.json @@ -26,8 +26,7 @@ "type": "module", "main": "lib", "bin": { - "yo": "lib/cli.js", - "yo-complete": "lib/completion/index.cjs" + "yo": "lib/cli.js" }, "files": [ "lib" @@ -63,7 +62,6 @@ "root-check": "^2.0.0", "sort-on": "^6.1.1", "string-length": "^6.0.0", - "tabtab": "^1.3.2", "titleize": "^4.0.0", "update-notifier": "^7.3.1", "yeoman-character": "^2.0.0", @@ -83,15 +81,5 @@ }, "engines": { "node": "^20.17.0 || >=22.9.0" - }, - "tabtab": { - "yo": [ - "-f", - "--force", - "--version", - "--no-color", - "--generators", - "--local-only" - ] } } diff --git a/test/completion.js b/test/completion.js deleted file mode 100644 index bcce2bb4..00000000 --- a/test/completion.js +++ /dev/null @@ -1,165 +0,0 @@ -import path from 'node:path'; -import assert from 'node:assert'; -import events from 'node:events'; -import {execFileSync} from 'node:child_process'; -import os from 'node:os'; -import _ from 'lodash'; -import Completer from '../lib/completion/completer.js'; -import completion from '../lib/completion/index.cjs'; -import {getDirname} from '../lib/utils/node-shims.js'; - -const __dirname = getDirname(import.meta.url); - -const help = ` - Usage: - yo backbone:app [options] [] - - Options: - -h, --help # Print the generator's options and usage - --skip-cache # Do not remember prompt answers Default: false - --skip-install # Do not automatically install dependencies Default: false - --appPath # Name of application directory Default: app - --requirejs # Support requirejs Default: false - --template-framework # Choose template framework. lodash/handlebars/mustache Default: lodash - --test-framework # Choose test framework. mocha/jasmine Default: mocha - - Arguments: - app_name Type: String Required: false`; - -describe('Completion', () => { - before(async function () { - const {createEnv} = await import('yeoman-environment'); - this.env = createEnv(); - }); - - describe('Test completion STDOUT output', () => { - (os.platform() === 'win32' ? it.skip : it)( - 'Returns the completion candidates for both options and installed generators', - () => { - const yocomplete = path.join(__dirname, '../lib/completion/index.cjs'); - const yo = path.join(__dirname, '../lib/cli'); - - let cmd - = 'export cmd="yo" && YO_TEST=true DEBUG="tabtab*" COMP_POINT="4" COMP_LINE="yo" COMP_CWORD="yo"'; - cmd += `node ${yocomplete} completion -- ${yo} $cmd`; - - const result = execFileSync(cmd, {encoding: 'utf8', shell: true}); - assert.ok(/-f/.test(result)); - assert.ok(/--force/.test(result)); - assert.ok(/--version/.test(result)); - assert.ok(/--no-color/.test(result)); - assert.ok(/--generators/.test(result)); - assert.ok(/--local-only/.test(result)); - }, - ); - }); - - describe('Completion', () => { - it('Creates tabtab instance', () => { - assert.ok(completion instanceof events); - }); - }); - - describe('Completer', () => { - beforeEach(function () { - // Mock / Monkey patch env.getGeneratorsMeta() here, since we pass the - // instance directly to completer. - this.getGeneratorsMeta = this.env.getGeneratorsMeta; - - this.env.getGeneratorsMeta = () => ({ - 'dummy:app': { - resolved: '/home/user/.nvm/versions/node/v6.1.0/lib/node_modules/generator-dummy/app/index.js', - namespace: 'dummy:app', - }, - 'dummy:yo': { - resolved: '/home/user/.nvm/versions/node/v6.1.0/lib/node_modules/generator-dummy/yo/index.js', - namespace: 'dummy:yo', - }, - }); - - this.completer = new Completer(this.env); - }); - - afterEach(function () { - this.env.getGeneratorsMeta = this.getGeneratorsMeta; - }); - - describe('#parseHelp', () => { - it('Returns completion items based on help output', function () { - const results = this.completer.parseHelp('backbone:app', help); - const first = results[0]; - - assert.strictEqual(results.length, 6); - assert.deepStrictEqual(first, { - name: '--skip-cache', - description: 'Do not remember prompt answers Default-> false', - }); - }); - }); - - describe('#item', () => { - it('Format results into { name, description }', function () { - const list = ['foo', 'bar']; - const results = list.map(this.completer.item('yo!', '--')); - assert.deepStrictEqual(results, [{ - name: '--foo', - description: 'yo!', - }, { - name: '--bar', - description: 'yo!', - }]); - }); - - it('Escapes certain characters before consumption by shell scripts', function () { - const list = ['foo']; - - const desc = '# yo I\'m a very subtle description, with chars that likely will break your Shell: yeah I\'m mean'; - const expected = 'yo I m a very subtle description, with chars that likely will break your Shell-> yeah I m mean'; - const results = list.map(this.completer.item(desc, '-')); - - assert.strictEqual(results[0].description, expected); - }); - }); - - describe('#generator', () => { - it('Returns completion candidates from generator help output', function (done) { - // Here we test against yo --help (could use dummy:yo --help) - this.completer.complete({last: ''}, (error, results) => { - if (error) { - done(error); - return; - } - - /* eslint no-multi-spaces: 0 */ - assert.deepStrictEqual(results, [ - {name: '--force', description: 'Overwrite files that already exist'}, - {name: '--version', description: 'Print version'}, - {name: '--no-color', description: 'Disable colors'}, - {name: '--generators', description: 'Print available generators'}, - {name: '--local-only', description: 'Disable lookup of globally-installed generators'}, - {name: '-f', description: 'Overwrite files that already exist'}, - ]); - - done(); - }); - }); - }); - - describe('#complete', () => { - it('Returns the list of user installed generators as completion candidates', function (done) { - this.completer.complete({last: 'yo'}, (error, results) => { - if (error) { - done(error); - return; - } - - const dummy = _.find(results, result => result.name === 'dummy:yo'); - assert.strictEqual(dummy.name, 'dummy:yo'); - assert.strictEqual(dummy.description, 'yo'); - - done(); - }); - }); - }); - }); -});