mirror of
https://github.com/angular/angular-cli.git
synced 2025-05-21 05:52:41 +08:00
BREAKING CHANGE: Removing the `ng init` & `ng update` commands because their current implementation causes more problems than it solves. Once RC is released, we won't need to use those to update anymore as the step will be as simple as installing the latest version of the CLI.
184 lines
5.0 KiB
TypeScript
184 lines
5.0 KiB
TypeScript
import * as fs from 'fs';
|
|
import * as path from 'path';
|
|
|
|
import { oneLine, stripIndent } from 'common-tags';
|
|
|
|
const stringUtils = require('ember-cli-string-utils');
|
|
const Command = require('../ember-cli/lib/models/command');
|
|
const lookupCommand = require('../ember-cli/lib/cli/lookup-command');
|
|
|
|
function extractOptions(opts: any): String {
|
|
const output: String[] = [];
|
|
|
|
for (let index = 0; index < opts.length; index++) {
|
|
const element = opts[index];
|
|
output.push('--' + element.name);
|
|
if (element.aliases) {
|
|
output.push('-' + element.aliases[0]);
|
|
}
|
|
}
|
|
|
|
return output.sort().join(' ');
|
|
}
|
|
|
|
export interface CompletionCommandOptions {
|
|
all?: boolean;
|
|
bash?: boolean;
|
|
zsh?: boolean;
|
|
};
|
|
|
|
const commandsToIgnore = [
|
|
'easter-egg',
|
|
'init',
|
|
'destroy',
|
|
'github-pages-deploy' // errors because there is no base github-pages command
|
|
];
|
|
|
|
const optsNg: String[] = [];
|
|
|
|
const CompletionCommand = Command.extend({
|
|
name: 'completion',
|
|
description: 'Adds autocomplete functionality to `ng` commands and subcommands',
|
|
works: 'everywhere',
|
|
availableOptions: [
|
|
{ name: 'all', type: Boolean, default: true, aliases: ['a'] },
|
|
{ name: 'bash', type: Boolean, default: false, aliases: ['b'] },
|
|
{ name: 'zsh', type: Boolean, default: false, aliases: ['z'] }
|
|
],
|
|
|
|
run: function (commandOptions: CompletionCommandOptions) {
|
|
commandOptions.all = !commandOptions.bash && !commandOptions.zsh;
|
|
|
|
const commandFiles = fs.readdirSync(__dirname)
|
|
.filter(file => file.match(/\.ts$/) && !file.match(/\.run.ts$/))
|
|
.map(file => path.parse(file).name)
|
|
.filter(file => {
|
|
return commandsToIgnore.indexOf(file) < 0;
|
|
})
|
|
.map(file => file.toLowerCase());
|
|
|
|
const commandMap = commandFiles.reduce((acc: any, curr: string) => {
|
|
let classifiedName = stringUtils.classify(curr);
|
|
let defaultImport = require(`./${curr}`).default;
|
|
|
|
acc[classifiedName] = defaultImport;
|
|
|
|
return acc;
|
|
}, {});
|
|
|
|
let caseBlock = '';
|
|
|
|
commandFiles.forEach(cmd => {
|
|
const Command = lookupCommand(commandMap, cmd);
|
|
const com: String[] = [];
|
|
|
|
const command = new Command({
|
|
ui: this.ui,
|
|
project: this.project,
|
|
commands: this.commands,
|
|
tasks: this.tasks
|
|
});
|
|
|
|
optsNg.push(command.name);
|
|
com.push(command.name);
|
|
|
|
if (command.aliases) {
|
|
command.aliases.forEach((element: String) => {
|
|
optsNg.push(element);
|
|
com.push(element);
|
|
});
|
|
}
|
|
|
|
if (command.availableOptions && command.availableOptions[0]) {
|
|
let opts = extractOptions (command.availableOptions);
|
|
caseBlock = caseBlock + ' ' + com.sort().join('|') + ') opts="' + opts + '" ;;\n';
|
|
}
|
|
});
|
|
|
|
caseBlock = 'ng|help) opts="' + optsNg.sort().join(' ') + '" ;;\n' +
|
|
caseBlock +
|
|
' *) opts="" ;;';
|
|
|
|
console.log(stripIndent`
|
|
###-begin-ng-completion###
|
|
#
|
|
|
|
# ng command completion script
|
|
# This command supports 3 cases.
|
|
# 1. (Default case) It prints a common completion initialisation for both Bash and Zsh.
|
|
# It is the result of either calling "ng completion" or "ng completion -a".
|
|
# 2. Produce Bash-only completion: "ng completion -b" or "ng completion --bash".
|
|
# 3. Produce Zsh-only completion: "ng completion -z" or "ng completion --zsh".
|
|
#
|
|
# Installation: ng completion -b >> ~/.bashrc
|
|
# or ng completion -z >> ~/.zshrc
|
|
#`);
|
|
|
|
if (commandOptions.all && !commandOptions.bash) {
|
|
console.log('if test ".$(type -t complete 2>/dev/null || true)" = ".builtin"; then');
|
|
}
|
|
|
|
if (commandOptions.all || commandOptions.bash) {
|
|
console.log(stripIndent`
|
|
_ng_completion() {
|
|
local cword pword opts
|
|
|
|
COMPREPLY=()
|
|
cword=\${COMP_WORDS[COMP_CWORD]}
|
|
pword=\${COMP_WORDS[COMP_CWORD - 1]}
|
|
|
|
case \${pword} in
|
|
${caseBlock}
|
|
esac
|
|
|
|
COMPREPLY=( $(compgen -W '\${opts}' -- $cword) )
|
|
|
|
return 0
|
|
}
|
|
|
|
complete -o default -F _ng_completion ng
|
|
`);
|
|
}
|
|
|
|
if (commandOptions.all) {
|
|
console.log(stripIndent`
|
|
elif test ".$(type -w compctl 2>/dev/null || true)" = ".compctl: builtin" ; then
|
|
`);
|
|
}
|
|
|
|
if (commandOptions.all || commandOptions.zsh) {
|
|
console.log(stripIndent`
|
|
_ng_completion () {
|
|
local words cword opts
|
|
read -Ac words
|
|
read -cn cword
|
|
let cword-=1
|
|
|
|
case $words[cword] in
|
|
${caseBlock}
|
|
esac
|
|
|
|
setopt shwordsplit
|
|
reply=($opts)
|
|
unset shwordsplit
|
|
}
|
|
|
|
compctl -K _ng_completion ng
|
|
`);
|
|
}
|
|
|
|
if (commandOptions.all) {
|
|
console.log(stripIndent`
|
|
else
|
|
echo "Builtin command 'complete' or 'compctl' is redefined; cannot produce completion."
|
|
return 1
|
|
fi`);
|
|
}
|
|
|
|
console.log('###-end-ng-completion###');
|
|
|
|
}
|
|
});
|
|
|
|
export default CompletionCommand;
|