Skip to content

Commit

Permalink
feat(@angular/cli): don't prompt to set up autocompletion for `ng upd…
Browse files Browse the repository at this point in the history
…ate` and `ng completion` commands

`ng update` is most likely called when upgrading a project to the next version and users should be more concerned about their project than their personal terminal setup.

`ng completion` is unconditionally setting up autocompletion, while `ng completion script` is getting the shell script for autocompletion setup. As a result, both of these don't benefit from a prompt and should be safe to skip it.
  • Loading branch information
dgp1130 committed May 3, 2022
1 parent 2e15df9 commit fb06228
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 3 deletions.
5 changes: 4 additions & 1 deletion packages/angular/cli/src/command-builder/command-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,10 @@ export abstract class CommandModule<T extends {} = {}> implements CommandModuleI
}

// Set up autocompletion if appropriate.
const autocompletionExitCode = await considerSettingUpAutocompletion(this.context.logger);
const autocompletionExitCode = await considerSettingUpAutocompletion(
this.commandName,
this.context.logger,
);
if (autocompletionExitCode !== undefined) {
process.exitCode = autocompletionExitCode;

Expand Down
13 changes: 11 additions & 2 deletions packages/angular/cli/src/utilities/completion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,12 @@ interface CompletionConfig {
* @returns an exit code if the program should terminate, undefined otherwise.
*/
export async function considerSettingUpAutocompletion(
command: string,
logger: logging.Logger,
): Promise<number | undefined> {
// Check if we should prompt the user to setup autocompletion.
const completionConfig = await getCompletionConfig();
if (!(await shouldPromptForAutocompletionSetup(completionConfig))) {
if (!(await shouldPromptForAutocompletionSetup(command, completionConfig))) {
return undefined; // Already set up or prompted previously, nothing to do.
}

Expand Down Expand Up @@ -106,12 +107,20 @@ async function setCompletionConfig(config: CompletionConfig): Promise<void> {
await wksp.save();
}

async function shouldPromptForAutocompletionSetup(config?: CompletionConfig): Promise<boolean> {
async function shouldPromptForAutocompletionSetup(
command: string,
config?: CompletionConfig,
): Promise<boolean> {
// Force whether or not to prompt for autocomplete to give an easy path for e2e testing to skip.
if (forceAutocomplete !== undefined) {
return forceAutocomplete;
}

// Don't prompt on `ng update` or `ng completion`.
if (command === 'update' || command === 'completion') {
return false;
}

// Non-interactive and continuous integration systems don't care about autocompletion.
if (!isTTY()) {
return false;
Expand Down
25 changes: 25 additions & 0 deletions tests/legacy-cli/e2e/tests/misc/completion-prompt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,31 @@ export default async function () {
}
});

// Does *not* prompt for `ng update` commands.
await mockHome(async (home) => {
// Use `ng update --help` so it's actually a no-op and we don't need to setup a project.
const { stdout } = await execWithEnv('ng', ['update', '--help'], {
...DEFAULT_ENV,
HOME: home,
});

if (AUTOCOMPLETION_PROMPT.test(stdout)) {
throw new Error('`ng update` command incorrectly prompted for autocompletion setup.');
}
});

// Does *not* prompt for `ng completion` commands.
await mockHome(async (home) => {
const { stdout } = await execWithEnv('ng', ['completion'], {
...DEFAULT_ENV,
HOME: home,
});

if (AUTOCOMPLETION_PROMPT.test(stdout)) {
throw new Error('`ng completion` command incorrectly prompted for autocompletion setup.');
}
});

// Does *not* prompt user for CI executions.
{
const { stdout } = await execWithEnv('ng', ['version'], {
Expand Down

0 comments on commit fb06228

Please sign in to comment.