Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Angular CLI 12.2.0 fails "ng add" with "Command aborted." without confirmation prompt #21512

Closed
1 of 15 tasks
daiplusplus opened this issue Aug 5, 2021 · 10 comments · Fixed by #21513
Closed
1 of 15 tasks
Labels
area: angular/cli freq1: low Only reported by a handful of users who observe it rarely severity1: confusing type: bug/fix
Milestone

Comments

@daiplusplus
Copy link

daiplusplus commented Aug 5, 2021

🐞 Bug report

Command (mark with an x)

  • new
  • build
  • serve
  • test
  • e2e
  • generate
  • add
  • update
  • lint
  • extract-i18n
  • run
  • config
  • help
  • version
  • doc

Is this a regression?

Did this behavior use to work in the previous version?

Yes

Yes, the previous version in which this bug was not present was: ....

v11 (I haven't used other v12.x versions)

Description and 🔬 Minimal Reproduction

  • Running ng add always fails with "Command abort.ed" unless I add --skip-confirmation.
  • Additionally, there is no difference in output with or without --verbose.

For example:

$ cd ~

$ mkdir test

$ cd test

$ npm install -g @angular/cli
# etc

$ ng add @angular-eslint/schematics@12.2.0
- Determining package manager...
i Using package manager: npm
- Loading package information from registry...
√ Package information loaded.
Command aborted.

$ ng add @angular-eslint/schematics --skip-confirmation
- Determining package manager...
i Using package manager: npm
- Searching for compatible package version...
√ Found compatible package version: @angular-eslint/schematics@12.3.1.
- Loading package information from registry...
√ Package information loaded.
- Installing package...
√ Package successfully installed.

    All @angular-eslint dependencies have been successfully installed 🎉

    Please see https://github.com/angular-eslint/angular-eslint for how to add ESLint configuration to your project.


    We detected that you have a single project in your workspace and no existing linter wired up, so we are configuring ESLint for you automatically.

    Please see https://github.com/angular-eslint/angular-eslint for more information.

CREATE .eslintrc.json (984 bytes)
UPDATE package.json (1445 bytes)
UPDATE angular.json (3333 bytes)
- Installing packages (npm)...
√ Packages installed successfully.

🌍 Your Environment


$ node --version
v14.17.4

$ npm --version
7.20.3

$ ng version

     _                      _                 ____ _     ___
    / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
   / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
  / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
 /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                |___/


Angular CLI: 12.2.0
Node: 14.17.4
Package Manager: npm 7.20.3
OS: win32 x64

Angular: 12.2.0
... animations, cli, common, compiler, compiler-cli, core, forms
... platform-browser, platform-browser-dynamic, router

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1202.0
@angular-devkit/build-angular   12.2.0
@angular-devkit/core            12.2.0
@angular-devkit/schematics      12.2.0
@schematics/angular             12.2.0
rxjs                            6.6.7
typescript                      4.3.5

Anything else relevant?

  • Windows 10 x64
  • Using git-bash as my shell in a mintty window.

I fiddled with add-impl.js to see why it wasn't prompting and I think the problem is add-impl.js has if( !tty_1.isTTY ) { but prompt.js has if (!tty_1.isTTY()) {, so is isTTY a function or a getter-property?

@daiplusplus
Copy link
Author

daiplusplus commented Aug 5, 2021

@alan-agius4 The isTTY() change you just made doesn't work for me because when I run it with my additions below, I get typeof process.stdout.isTTY is 'undefined', even though I'm running ng add directly from a terminal window without any redirection (so isTTY should be true, right?)

From Node's docs:

https://nodejs.org/api/tty.html#tty_tty

$ node -p -e "Boolean(process.stdout.isTTY)"
true
$ node -p -e "Boolean(process.stdout.isTTY)" | cat
false

When I run the same commands locally I get the same results:

Screenshot proof:

image

This the code I added in add-impl.js right before the if (!options.skipConfirmation) { line:

    this.logger.error( options.skipConfirmation ? 'options.skipConfirmation == true' : 'options.skipConfirmation == false' );
    this.logger.error( typeof tty_1.isTTY );
    this.logger.error( 'tty_1.isTTY ==' + ( tty_1.isTTY ? 'isTTY' : 'is NOT TTY' ) );
    this.logger.error( 'tty_1.isTTY() ==' + ( tty_1.isTTY() ? 'isTTY' : 'is NOT TTY' ) );
    this.logger.error( 'process.stdout.isTTY type == ' + ( typeof process.stdout.isTTY ) );
    this.logger.error( 'process.stdout.isTTY == ' + ( process.stdout.isTTY ) );

    if (!options.skipConfirmation) {

Gives me this output:

options.skipConfirmation == false
function
tty_1.isTTY ==isTTY
tty_1.isTTY() ==is NOT TTY
process.stdout.isTTY type == undefined
process.stdout.isTTY == undefined

So why is process.stdout.isTTY undefined when in tty.js but not normally?

@daiplusplus
Copy link
Author

daiplusplus commented Aug 5, 2021

After some more digging, when I try to get stdout.isTTY from anywhere before add-impl.js runs, such as in init.js or even in ng itself, I get errors.

Here's my code (in C:\Users\me\AppData\Roaming\npm\node_modules\@angular\cli\bin\ng):

process.stdout.write("------------------------\n");
console.trace( "ng: Stack trace\n" );
process.stderr.write("Writing to stderr\n");
process.stdout.write("Writing to stdout\n");
process.stdout.write("typeof stdout.isTTY === '" + typeof process.stdout.isTTY + "'\n");
try { process.stdout.write( process.stdout.isTTY ); }
catch( err ) { process.stdout.write( "Couldn't get isTTY: " + err ); }
process.stdout.write("\n");
process.stdout.write("------------------------\n");

Gives me this output:

$ ng add @angular-eslint/schematics
------------------------
Trace: ng: Stack trrace
    at Object.<anonymous> (C:\Users\me\AppData\Roaming\npm\node_modules\@angular\cli\bin\ng:5:13)
    at Module._compile (internal/modules/cjs/loader.js:1072:14)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1101:10)
    at Module.load (internal/modules/cjs/loader.js:937:32)
    at Function.Module._load (internal/modules/cjs/loader.js:778:12)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:76:12)
    at internal/main/run_main_module.js:17:47
Writing to stderr
Writing to stdout
typeof stdout.isTTY === 'undefined'
Couldn't get isTTY: TypeError [ERR_INVALID_ARG_TYPE]: The "chunk" argument must be of type string or an instance of Buffer or Uint8Array. Received undefined

And yet, running node -p -e "process.stdout.isTTY" directly still works just fine:

$ node -p -e "process.stdout.isTTY"
true

any ideas?

@alan-agius4
Copy link
Collaborator

That is interesting, not sure how to debug this from my end since I don’t have a Windows machine.

In the past we did see a number of TTY issues with GitBash and typically they were never actionable form our end. In most cases these were address by Node.JS as far as I can tell.

@daiplusplus
Copy link
Author

@alan-agius4 I just realised that the error is because stdout.write does not accept a bool parameter - but it's also reporting isTTY is undefined, so I've got my errors crossed - but it's still broken. I'll update this comment in a short while.

@daiplusplus
Copy link
Author

daiplusplus commented Aug 5, 2021

  • cmd.exe, when running node.exe myscript.js has process.stdout.isTTY === true.
  • cmd.exe, when running ng add foobar to indirectly run my hacked ng.js script has process.stdout.isTTY === true.
  • bash , when running node.exe myscript.js has process.stdout.isTTY === true.
  • bash, when running ng add foobar to indirectly run my hacked ng.js script has process.stdout.isTTY === undefined.

So that's narrowing it down...

UPDATE: So apparently the culprit is the ng bash script (at C:\Users\me\AppData\Roaming\npm\ng) which runs node via exec, and apparently doing exec node is what causes process.stdout.isTTY to be undefined

@daiplusplus
Copy link
Author

daiplusplus commented Aug 5, 2021

@alan-agius4

Correct, running node node_modules/@angular/cli/lib/init.js add foobar directly from git-bash has stdout.isTTY === true.

Running node node_modules/@angular/cli/lib/init.js add @angular-eslint/schematics@12.2.0 succeeds and it asks me for a confirmation prompt.

Can't we replace exec node with just node in the ng bash script, perhaps?


Update: I changed my ng bash script from this:

#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")

case `uname` in
    *CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
esac

if [ -x "$basedir/node" ]; then
  exec "$basedir/node"  "$basedir/node_modules/@angular/cli/bin/ng" "$@"
else 
  exec node  "$basedir/node_modules/@angular/cli/bin/ng" "$@"
fi

to

#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")

case `uname` in
    *CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
esac

if [ -x "$basedir/node" ]; then
  node  "$basedir/node_modules/@angular/cli/bin/ng" "$@"
else 
  node  "$basedir/node_modules/@angular/cli/bin/ng" "$@"
fi

And yet process.stdout.isTTY === undefined still, curious...

Perhaps as an immediate workaround, add a warning output to init.js if typeof isTTY !== 'boolean' ?

@daiplusplus
Copy link
Author

daiplusplus commented Aug 5, 2021

I've raised a bug with NodeJS here: nodejs/node#39673

UPDATE: So while the root cause is that isTTY is undefined in NodeJS when bash-on-Windows indirectly, which is another example of "the winpty problem" described here: https://stackoverflow.com/questions/45890339/stdout-is-not-a-tty-using-bash-for-node-tape-tap-spec

As a quality-of-life improvement, I suggest the ng shell-script print a warning if winpty isn't available, and if so, run the child node process via winpty, thoughts?

@alan-agius4
Copy link
Collaborator

alan-agius4 commented Aug 5, 2021

@Jehoel, the mentioned shell script is actually generated by NPM and not Angular.
Hence we have no controller of its contents.

alan-agius4 added a commit that referenced this issue Aug 6, 2021
…sing `--skip-confirmation` during `ng add`

Closes #21512
alan-agius4 added a commit that referenced this issue Aug 6, 2021
…sing `--skip-confirmation` during `ng add`

Closes #21512

(cherry picked from commit c0f1b5e)
@diegoatnqn
Copy link

diegoatnqn commented Aug 12, 2021

All ng add commands are not working for me either.
My version:

Angular CLI: 12.0.5
Node: 16.5.0
Package Manager: npm 7.20.0
OS: win32 x64
Angular: 12.0.5
... animations, cli, common, compiler, compiler-cli, core, forms
... platform-browser, platform-browser-dynamic, router

Package Version

@angular-devkit/architect 0.1200.5
@angular-devkit/build-angular 12.0.5
@angular-devkit/core 12.0.5
@angular-devkit/schematics 12.0.5
@angular/cdk 12.1.3
@angular/material 12.1.3
@schematics/angular 12.0.5
rxjs 6.6.7
typescript 4.2.4

@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 12, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area: angular/cli freq1: low Only reported by a handful of users who observe it rarely severity1: confusing type: bug/fix
Projects
None yet
3 participants