Repository: ember-cli/ember-cli
Pull request #9988 (2022-08-04 17:14:02)

[BUGFIX] - Address npm-run-all and Yarn 3 conflict & Removed warning
## Details
* There is an ongoing [issue with `npm-run-all`, Yarn 2+, and Glob Matching ](https://github.com/mysticatea/npm-run-all/issues/200)
  * The general fix for it is instead of `npm-run-all lint:*` we would put `npm-run-all 'lint:*'`
  * The `-n` is for printing the name of the task. For Yarn 2+ users, without this flag, you would not know which subtasks are running from stdout
* Disabled warning for users using Yarn 2+ and linking it with the node-modules folder instead of the new plug n' play mechanism

## Testing
* Ran `yarn test:all` and it succeeded. 
```
  1592 passing (22m)
  13 pending
```
* Tested my changes to a blueprint and verified that the `npm-run-all` command still works as expected for Yarn 1 and Yarn 2+ versions

bertdeblock: FYI, this PR seems to undo the fix implemented over in https://github.com/ember-cli/ember-cli/pull/9500.
Do these scripts still work on windows?
christianarty: @bertdeblock 
>FYI, this PR seems to undo the fix implemented over in https://github.com/ember-cli/ember-cli/pull/9500.
Do these scripts still work on windows?

Yea Upon further research, I have found that the single-quotes will not be interpreted the same on Mac and Windows. See here: https://github.com/mysticatea/npm-run-all/issues/45

I will throw in a fix for that in my latest revision. 

> Somewhat related: I also created https://github.com/ember-cli/ember-cli/issues/9966 a while ago.

I like `concurrently`, however, I think there could be issues with migrating to it from what i know (please let me know if im wrong)
1. Concurrently allows for parallization of npm scripts, however there is not a clear way to run scripts sequentially. By default, `npm-run-all` runs scripts sequentially cross platform (i.e npm run script-1 && npm run script-2)
2. Additionally, how will this effect those using blueprints that build on `npm-run-all`. Would that be part of a larger change?

I don't think we are opposed to it, but i think that would be encompassed in a separate pr rather than this one. @rwjblue  do you have any comments about using `concurrently` instead of `npm-run-all`
bertdeblock: @christianarty Thanks for the update. Yeah, I thought I'd just mention the `concurrently` issue just in case, but agreed, not in scope for this PR.
rwjblue: FWIW, I definitely agree that we should look into migrating to `concurrently` (or something else) since `npm-run-all` isn't being actively maintained.

Patch:
diff --git a/blueprints/app/files/package.json b/blueprints/app/files/package.json
index fabb9a701..5cbe4847b 100644
--- a/blueprints/app/files/package.json
+++ b/blueprints/app/files/package.json
@@ -12,14 +12,14 @@
   },
   "scripts": {
     "build": "ember build --environment=production",
-    "lint": "npm-run-all --aggregate-output --continue-on-error --parallel \"lint:!(fix)\"",
-    "lint:fix": "npm-run-all --aggregate-output --continue-on-error --parallel lint:*:fix",
+    "lint": "npm-run-all --print-name --aggregate-output --continue-on-error --parallel \"lint:!(fix)\"",
+    "lint:fix": "npm-run-all --print-name --aggregate-output --continue-on-error --parallel \"lint:*:fix\"",
     "lint:hbs": "ember-template-lint .",
     "lint:hbs:fix": "ember-template-lint . --fix",
     "lint:js": "eslint . --cache",
     "lint:js:fix": "eslint . --fix",
     "start": "ember serve",
-    "test": "npm-run-all lint test:*",
+    "test": "npm-run-all --print-name \"lint\" \"test:*\"",
     "test:ember": "ember test"
   },
   "devDependencies": {
diff --git a/lib/tasks/npm-task.js b/lib/tasks/npm-task.js
index 2e2ac8066..e32e05812 100644
--- a/lib/tasks/npm-task.js
+++ b/lib/tasks/npm-task.js
@@ -63,7 +63,11 @@ class NpmTask extends Task {
 
       if (semver.gte(version, '2.0.0')) {
         logger.warn('yarn --version: %s', version);
-        this.ui.writeWarnLine(`Yarn v2 is not fully supported. Proceeding with yarn: ${version}`);
+        let yarnConfig = await this.yarn(['config', 'get', 'nodeLinker']);
+        let nodeLinker = yarnConfig.stdout.trim();
+        if (nodeLinker !== 'node-modules') {
+          this.ui.writeWarnLine(`Yarn v2 is not fully supported. Proceeding with yarn: ${version}`);
+        }
       } else {
         logger.info('yarn --version: %s', version);
       }


Test patch:
diff --git a/tests/fixtures/addon/defaults-travis/package.json b/tests/fixtures/addon/defaults-travis/package.json
index 20fc917e7..f40fc1520 100644
--- a/tests/fixtures/addon/defaults-travis/package.json
+++ b/tests/fixtures/addon/defaults-travis/package.json
@@ -14,14 +14,14 @@
   },
   "scripts": {
     "build": "ember build --environment=production",
-    "lint": "npm-run-all --aggregate-output --continue-on-error --parallel \"lint:!(fix)\"",
-    "lint:fix": "npm-run-all --aggregate-output --continue-on-error --parallel lint:*:fix",
+    "lint": "npm-run-all --print-name --aggregate-output --continue-on-error --parallel \"lint:!(fix)\"",
+    "lint:fix": "npm-run-all --print-name --aggregate-output --continue-on-error --parallel \"lint:*:fix\"",
     "lint:hbs": "ember-template-lint .",
     "lint:hbs:fix": "ember-template-lint . --fix",
     "lint:js": "eslint . --cache",
     "lint:js:fix": "eslint . --fix",
     "start": "ember serve",
-    "test": "npm-run-all lint test:*",
+    "test": "npm-run-all --print-name \"lint\" \"test:*\"",
     "test:ember": "ember test",
     "test:ember-compatibility": "ember try:each"
   },
diff --git a/tests/fixtures/addon/defaults/package.json b/tests/fixtures/addon/defaults/package.json
index b7d6c594a..6e80fe759 100644
--- a/tests/fixtures/addon/defaults/package.json
+++ b/tests/fixtures/addon/defaults/package.json
@@ -14,14 +14,14 @@
   },
   "scripts": {
     "build": "ember build --environment=production",
-    "lint": "npm-run-all --aggregate-output --continue-on-error --parallel \"lint:!(fix)\"",
-    "lint:fix": "npm-run-all --aggregate-output --continue-on-error --parallel lint:*:fix",
+    "lint": "npm-run-all --print-name --aggregate-output --continue-on-error --parallel \"lint:!(fix)\"",
+    "lint:fix": "npm-run-all --print-name --aggregate-output --continue-on-error --parallel \"lint:*:fix\"",
     "lint:hbs": "ember-template-lint .",
     "lint:hbs:fix": "ember-template-lint . --fix",
     "lint:js": "eslint . --cache",
     "lint:js:fix": "eslint . --fix",
     "start": "ember serve",
-    "test": "npm-run-all lint test:*",
+    "test": "npm-run-all --print-name \"lint\" \"test:*\"",
     "test:ember": "ember test",
     "test:ember-compatibility": "ember try:each"
   },
diff --git a/tests/fixtures/addon/yarn/package.json b/tests/fixtures/addon/yarn/package.json
index 899adb247..1d368f839 100644
--- a/tests/fixtures/addon/yarn/package.json
+++ b/tests/fixtures/addon/yarn/package.json
@@ -14,14 +14,14 @@
   },
   "scripts": {
     "build": "ember build --environment=production",
-    "lint": "npm-run-all --aggregate-output --continue-on-error --parallel \"lint:!(fix)\"",
-    "lint:fix": "npm-run-all --aggregate-output --continue-on-error --parallel lint:*:fix",
+    "lint": "npm-run-all --print-name --aggregate-output --continue-on-error --parallel \"lint:!(fix)\"",
+    "lint:fix": "npm-run-all --print-name --aggregate-output --continue-on-error --parallel \"lint:*:fix\"",
     "lint:hbs": "ember-template-lint .",
     "lint:hbs:fix": "ember-template-lint . --fix",
     "lint:js": "eslint . --cache",
     "lint:js:fix": "eslint . --fix",
     "start": "ember serve",
-    "test": "npm-run-all lint test:*",
+    "test": "npm-run-all --print-name \"lint\" \"test:*\"",
     "test:ember": "ember test",
     "test:ember-compatibility": "ember try:each"
   },
diff --git a/tests/fixtures/app/defaults/package.json b/tests/fixtures/app/defaults/package.json
index caa6c6e19..6c0fd598b 100644
--- a/tests/fixtures/app/defaults/package.json
+++ b/tests/fixtures/app/defaults/package.json
@@ -12,14 +12,14 @@
   },
   "scripts": {
     "build": "ember build --environment=production",
-    "lint": "npm-run-all --aggregate-output --continue-on-error --parallel \"lint:!(fix)\"",
-    "lint:fix": "npm-run-all --aggregate-output --continue-on-error --parallel lint:*:fix",
+    "lint": "npm-run-all --print-name --aggregate-output --continue-on-error --parallel \"lint:!(fix)\"",
+    "lint:fix": "npm-run-all --print-name --aggregate-output --continue-on-error --parallel \"lint:*:fix\"",
     "lint:hbs": "ember-template-lint .",
     "lint:hbs:fix": "ember-template-lint . --fix",
     "lint:js": "eslint . --cache",
     "lint:js:fix": "eslint . --fix",
     "start": "ember serve",
-    "test": "npm-run-all lint test:*",
+    "test": "npm-run-all --print-name \"lint\" \"test:*\"",
     "test:ember": "ember test"
   },
   "devDependencies": {
diff --git a/tests/fixtures/app/embroider-no-welcome/package.json b/tests/fixtures/app/embroider-no-welcome/package.json
index cabc88cf8..7923702bf 100644
--- a/tests/fixtures/app/embroider-no-welcome/package.json
+++ b/tests/fixtures/app/embroider-no-welcome/package.json
@@ -12,14 +12,14 @@
   },
   "scripts": {
     "build": "ember build --environment=production",
-    "lint": "npm-run-all --aggregate-output --continue-on-error --parallel \"lint:!(fix)\"",
-    "lint:fix": "npm-run-all --aggregate-output --continue-on-error --parallel lint:*:fix",
+    "lint": "npm-run-all --print-name --aggregate-output --continue-on-error --parallel \"lint:!(fix)\"",
+    "lint:fix": "npm-run-all --print-name --aggregate-output --continue-on-error --parallel \"lint:*:fix\"",
     "lint:hbs": "ember-template-lint .",
     "lint:hbs:fix": "ember-template-lint . --fix",
     "lint:js": "eslint . --cache",
     "lint:js:fix": "eslint . --fix",
     "start": "ember serve",
-    "test": "npm-run-all lint test:*",
+    "test": "npm-run-all --print-name \"lint\" \"test:*\"",
     "test:ember": "ember test"
   },
   "devDependencies": {
diff --git a/tests/fixtures/app/embroider-yarn/package.json b/tests/fixtures/app/embroider-yarn/package.json
index 56b125586..d55b6edd4 100644
--- a/tests/fixtures/app/embroider-yarn/package.json
+++ b/tests/fixtures/app/embroider-yarn/package.json
@@ -12,14 +12,14 @@
   },
   "scripts": {
     "build": "ember build --environment=production",
-    "lint": "npm-run-all --aggregate-output --continue-on-error --parallel \"lint:!(fix)\"",
-    "lint:fix": "npm-run-all --aggregate-output --continue-on-error --parallel lint:*:fix",
+    "lint": "npm-run-all --print-name --aggregate-output --continue-on-error --parallel \"lint:!(fix)\"",
+    "lint:fix": "npm-run-all --print-name --aggregate-output --continue-on-error --parallel \"lint:*:fix\"",
     "lint:hbs": "ember-template-lint .",
     "lint:hbs:fix": "ember-template-lint . --fix",
     "lint:js": "eslint . --cache",
     "lint:js:fix": "eslint . --fix",
     "start": "ember serve",
-    "test": "npm-run-all lint test:*",
+    "test": "npm-run-all --print-name \"lint\" \"test:*\"",
     "test:ember": "ember test"
   },
   "devDependencies": {
diff --git a/tests/fixtures/app/embroider/package.json b/tests/fixtures/app/embroider/package.json
index 56b125586..d55b6edd4 100644
--- a/tests/fixtures/app/embroider/package.json
+++ b/tests/fixtures/app/embroider/package.json
@@ -12,14 +12,14 @@
   },
   "scripts": {
     "build": "ember build --environment=production",
-    "lint": "npm-run-all --aggregate-output --continue-on-error --parallel \"lint:!(fix)\"",
-    "lint:fix": "npm-run-all --aggregate-output --continue-on-error --parallel lint:*:fix",
+    "lint": "npm-run-all --print-name --aggregate-output --continue-on-error --parallel \"lint:!(fix)\"",
+    "lint:fix": "npm-run-all --print-name --aggregate-output --continue-on-error --parallel \"lint:*:fix\"",
     "lint:hbs": "ember-template-lint .",
     "lint:hbs:fix": "ember-template-lint . --fix",
     "lint:js": "eslint . --cache",
     "lint:js:fix": "eslint . --fix",
     "start": "ember serve",
-    "test": "npm-run-all lint test:*",
+    "test": "npm-run-all --print-name \"lint\" \"test:*\"",
     "test:ember": "ember test"
   },
   "devDependencies": {
diff --git a/tests/fixtures/app/nested-project/actual-project/package.json b/tests/fixtures/app/nested-project/actual-project/package.json
index afb65b37f..00c2bba18 100644
--- a/tests/fixtures/app/nested-project/actual-project/package.json
+++ b/tests/fixtures/app/nested-project/actual-project/package.json
@@ -12,14 +12,14 @@
   },
   "scripts": {
     "build": "ember build --environment=production",
-    "lint": "npm-run-all --aggregate-output --continue-on-error --parallel \"lint:!(fix)\"",
-    "lint:fix": "npm-run-all --aggregate-output --continue-on-error --parallel lint:*:fix",
+    "lint": "npm-run-all --print-name --aggregate-output --continue-on-error --parallel \"lint:!(fix)\"",
+    "lint:fix": "npm-run-all --print-name --aggregate-output --continue-on-error --parallel \"lint:*:fix\"",
     "lint:hbs": "ember-template-lint .",
     "lint:hbs:fix": "ember-template-lint . --fix",
     "lint:js": "eslint . --cache",
     "lint:js:fix": "eslint . --fix",
     "start": "ember serve",
-    "test": "npm-run-all lint test:*",
+    "test": "npm-run-all --print-name \"lint\" \"test:*\"",
     "test:ember": "ember test"
   },
   "devDependencies": {
diff --git a/tests/fixtures/app/npm-travis/package.json b/tests/fixtures/app/npm-travis/package.json
index d1ac95589..ffd7705f2 100644
--- a/tests/fixtures/app/npm-travis/package.json
+++ b/tests/fixtures/app/npm-travis/package.json
@@ -12,14 +12,14 @@
   },
   "scripts": {
     "build": "ember build --environment=production",
-    "lint": "npm-run-all --aggregate-output --continue-on-error --parallel \"lint:!(fix)\"",
-    "lint:fix": "npm-run-all --aggregate-output --continue-on-error --parallel lint:*:fix",
+    "lint": "npm-run-all --print-name --aggregate-output --continue-on-error --parallel \"lint:!(fix)\"",
+    "lint:fix": "npm-run-all --print-name --aggregate-output --continue-on-error --parallel \"lint:*:fix\"",
     "lint:hbs": "ember-template-lint .",
     "lint:hbs:fix": "ember-template-lint . --fix",
     "lint:js": "eslint . --cache",
     "lint:js:fix": "eslint . --fix",
     "start": "ember serve",
-    "test": "npm-run-all lint test:*",
+    "test": "npm-run-all --print-name \"lint\" \"test:*\"",
     "test:ember": "ember test"
   },
   "devDependencies": {
diff --git a/tests/fixtures/app/npm/package.json b/tests/fixtures/app/npm/package.json
index 8a9a19ef7..e738a0519 100644
--- a/tests/fixtures/app/npm/package.json
+++ b/tests/fixtures/app/npm/package.json
@@ -12,14 +12,14 @@
   },
   "scripts": {
     "build": "ember build --environment=production",
-    "lint": "npm-run-all --aggregate-output --continue-on-error --parallel \"lint:!(fix)\"",
-    "lint:fix": "npm-run-all --aggregate-output --continue-on-error --parallel lint:*:fix",
+    "lint": "npm-run-all --print-name --aggregate-output --continue-on-error --parallel \"lint:!(fix)\"",
+    "lint:fix": "npm-run-all --print-name --aggregate-output --continue-on-error --parallel \"lint:*:fix\"",
     "lint:hbs": "ember-template-lint .",
     "lint:hbs:fix": "ember-template-lint . --fix",
     "lint:js": "eslint . --cache",
     "lint:js:fix": "eslint . --fix",
     "start": "ember serve",
-    "test": "npm-run-all lint test:*",
+    "test": "npm-run-all --print-name \"lint\" \"test:*\"",
     "test:ember": "ember test"
   },
   "devDependencies": {
diff --git a/tests/fixtures/app/with-blueprint-override-lint-fail/package.json b/tests/fixtures/app/with-blueprint-override-lint-fail/package.json
index 487014bb8..6ad880bd2 100644
--- a/tests/fixtures/app/with-blueprint-override-lint-fail/package.json
+++ b/tests/fixtures/app/with-blueprint-override-lint-fail/package.json
@@ -12,14 +12,14 @@
   },
   "scripts": {
     "build": "ember build --environment=production",
-    "lint": "npm-run-all --aggregate-output --continue-on-error --parallel \"lint:!(fix)\"",
-    "lint:fix": "npm-run-all --aggregate-output --continue-on-error --parallel lint:*:fix",
+    "lint": "npm-run-all --print-name --aggregate-output --continue-on-error --parallel \"lint:!(fix)\"",
+    "lint:fix": "npm-run-all --print-name --aggregate-output --continue-on-error --parallel \"lint:*:fix\"",
     "lint:hbs": "ember-template-lint .",
     "lint:hbs:fix": "ember-template-lint . --fix",
     "lint:js": "eslint . --cache",
     "lint:js:fix": "eslint . --fix",
     "start": "ember serve",
-    "test": "npm-run-all lint test:*",
+    "test": "npm-run-all --print-name \"lint\" \"test:*\"",
     "test:ember": "ember test"
   },
   "devDependencies": {
diff --git a/tests/fixtures/app/yarn-travis/package.json b/tests/fixtures/app/yarn-travis/package.json
index 279b8bc3b..3f775a7be 100644
--- a/tests/fixtures/app/yarn-travis/package.json
+++ b/tests/fixtures/app/yarn-travis/package.json
@@ -12,14 +12,14 @@
   },
   "scripts": {
     "build": "ember build --environment=production",
-    "lint": "npm-run-all --aggregate-output --continue-on-error --parallel \"lint:!(fix)\"",
-    "lint:fix": "npm-run-all --aggregate-output --continue-on-error --parallel lint:*:fix",
+    "lint": "npm-run-all --print-name --aggregate-output --continue-on-error --parallel \"lint:!(fix)\"",
+    "lint:fix": "npm-run-all --print-name --aggregate-output --continue-on-error --parallel \"lint:*:fix\"",
     "lint:hbs": "ember-template-lint .",
     "lint:hbs:fix": "ember-template-lint . --fix",
     "lint:js": "eslint . --cache",
     "lint:js:fix": "eslint . --fix",
     "start": "ember serve",
-    "test": "npm-run-all lint test:*",
+    "test": "npm-run-all --print-name \"lint\" \"test:*\"",
     "test:ember": "ember test"
   },
   "devDependencies": {
diff --git a/tests/fixtures/app/yarn/package.json b/tests/fixtures/app/yarn/package.json
index caa6c6e19..6c0fd598b 100644
--- a/tests/fixtures/app/yarn/package.json
+++ b/tests/fixtures/app/yarn/package.json
@@ -12,14 +12,14 @@
   },
   "scripts": {
     "build": "ember build --environment=production",
-    "lint": "npm-run-all --aggregate-output --continue-on-error --parallel \"lint:!(fix)\"",
-    "lint:fix": "npm-run-all --aggregate-output --continue-on-error --parallel lint:*:fix",
+    "lint": "npm-run-all --print-name --aggregate-output --continue-on-error --parallel \"lint:!(fix)\"",
+    "lint:fix": "npm-run-all --print-name --aggregate-output --continue-on-error --parallel \"lint:*:fix\"",
     "lint:hbs": "ember-template-lint .",
     "lint:hbs:fix": "ember-template-lint . --fix",
     "lint:js": "eslint . --cache",
     "lint:js:fix": "eslint . --fix",
     "start": "ember serve",
-    "test": "npm-run-all lint test:*",
+    "test": "npm-run-all --print-name \"lint\" \"test:*\"",
     "test:ember": "ember test"
   },
   "devDependencies": {
diff --git a/tests/unit/tasks/npm-task-test.js b/tests/unit/tasks/npm-task-test.js
index 761df9ba5..0ea26f5f0 100644
--- a/tests/unit/tasks/npm-task-test.js
+++ b/tests/unit/tasks/npm-task-test.js
@@ -88,9 +88,18 @@ describe('NpmTask', function () {
       expect(ui.errors).to.be.empty;
     });
 
-    it('resolves with warning when yarn >=2.0.0 is found', async function () {
-      td.when(task.yarn(['--version'])).thenResolve({ stdout: '2.0.0' });
+    it('resolves when yarn >=2.0.0 is found and using node_modules', async function () {
+      td.when(task.yarn(['--version'])).thenResolve({ stdout: '3.2.2' });
+      td.when(task.yarn(['config', 'get', 'nodeLinker'])).thenResolve({ stdout: 'node-modules' });
 
+      await task.checkYarn();
+      expect(ui.output).to.be.empty;
+      expect(ui.errors).to.be.empty;
+    });
+
+    it('resolves with warning when yarn >=2.0.0 is found and not using node_modules', async function () {
+      td.when(task.yarn(['--version'])).thenResolve({ stdout: '2.0.0' });
+      td.when(task.yarn(['config', 'get', 'nodeLinker'])).thenResolve({ stdout: 'pnp' });
       await task.checkYarn();
       expect(ui.output).to.contain('WARNING');
       expect(ui.errors).to.be.empty;