Skip to content

Commit 6b218a5

Browse files
Merge pull request #2196 from ember-cli/switch-to-pnpm
Switch to pnpm + vitest (away from yarn @ 1 and jest)
2 parents 77b8725 + a251916 commit 6b218a5

File tree

18 files changed

+8479
-7822
lines changed

18 files changed

+8479
-7822
lines changed

.github/workflows/ci.yml

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,28 +10,39 @@ on:
1010
branches: [ master ]
1111

1212
jobs:
13-
build:
13+
self-lint:
14+
runs-on: ubuntu-latest
15+
steps:
16+
- uses: actions/checkout@v4
17+
- uses: pnpm/action-setup@v4
18+
with:
19+
run_install: false
20+
- uses: actions/setup-node@v4
21+
with:
22+
node-version: 22.x
23+
cache: 'pnpm'
24+
25+
- run: pnpm install
26+
- run: pnpm lint
1427

28+
build:
1529
runs-on: ${{ matrix.os }}-latest
1630

1731
strategy:
1832
matrix:
1933
os: [ ubuntu, windows ]
20-
node-version: [18.x, 20.x, 21.x]
34+
node-version: [18.x, 20.x, 22.x]
2135

2236
steps:
2337
- uses: actions/checkout@v4
24-
38+
- uses: pnpm/action-setup@v4
39+
with:
40+
run_install: false
2541
- name: Use Node.js ${{ matrix.node-version }}
2642
uses: actions/setup-node@v4
2743
with:
2844
node-version: ${{ matrix.node-version }}
29-
cache: 'yarn'
30-
31-
- run: yarn install --frozen-lockfile --non-interactive
32-
33-
- run: yarn lint
34-
35-
- run: yarn update && git diff --exit-code
45+
cache: 'pnpm'
3646

37-
- run: yarn test:coverage --runInBand
47+
- run: pnpm install
48+
- run: pnpm test:coverage

.npmrc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# npm / pnpm settings here
2+
3+
# as a library, we want to make sure we explicitly handle peers,
4+
# and not rely on hidden behavior of package-managers.
5+
auto-install-peers=false
6+
strict-peer-dependents=true
7+
dedupe-peer-dependents=true
8+
prefer-workspaces-packages=true
9+
resolve-peers-from-workspace-root=false

README.md

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,6 @@
1515

1616
### 1. Install plugin
1717

18-
```shell
19-
yarn add --dev eslint-plugin-ember
20-
```
21-
22-
Or
23-
2418
```shell
2519
npm install --save-dev eslint-plugin-ember
2620
```
@@ -178,7 +172,7 @@ rules in templates can be disabled with eslint directives with mustache or html
178172
![gjs logo](/docs/svgs/gjs.svg) Set in the `recommended-gjs` [configuration](https://github.com/ember-cli/eslint-plugin-ember#-configurations).\
179173
![gts logo](/docs/svgs/gts.svg) Set in the `recommended-gts` [configuration](https://github.com/ember-cli/eslint-plugin-ember#-configurations).\
180174
🔧 Automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/user-guide/command-line-interface#--fix).\
181-
💡 Manually fixable by [editor suggestions](https://eslint.org/docs/developer-guide/working-with-rules#providing-suggestions).
175+
💡 Manually fixable by [editor suggestions](https://eslint.org/docs/latest/use/core-concepts#rule-suggestions).
182176

183177
### Components
184178

@@ -354,10 +348,10 @@ If you have any suggestions, ideas, or problems, feel free to [create an issue](
354348
- `lib/rules/new-rule.js` (implementation, see [no-proxies](lib/rules/no-proxies.js) for an example)
355349
- `docs/rules/new-rule.md` (documentation, start from the template -- [raw](https://raw.githubusercontent.com/ember-cli/eslint-plugin-ember/master/docs/rules/_TEMPLATE_.md), [rendered](docs/rules/_TEMPLATE_.md))
356350
- `tests/lib/rules/new-rule.js` (tests, see [no-proxies](tests/lib/rules/no-proxies.js) for an example)
357-
- Run `yarn update` to automatically update the README and other files (and re-run this if you change the rule name or description)
351+
- Run `pnpm update` to automatically update the README and other files (and re-run this if you change the rule name or description)
358352
- Make sure your changes will pass [CI](./.github/workflows/ci.yml) by running:
359-
- `yarn test`
360-
- `yarn lint` (`yarn lint:js --fix` can fix many errors)
353+
- `pnpm test`
354+
- `pnpm lint` (`pnpm lint:js --fix` can fix many errors)
361355
- Create a PR and link the created issue in the description
362356

363357
Note that new rules should not immediately be added to the [recommended](./lib/recommended-rules.js) configuration, as we only consider such breaking changes during major version updates.

RELEASE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@
88

99
4. `export EDITOR="vim"` to choose an editor for editing the changelog
1010

11-
5. `yarn release` (uses [@release-it-plugins/lerna-changelog](https://github.com/release-it-plugins/lerna-changelog) to handle versioning, the changelog, publishing to GitHub and NPM, etc)
11+
5. `pnpm release` (uses [@release-it-plugins/lerna-changelog](https://github.com/release-it-plugins/lerna-changelog) to handle versioning, the changelog, publishing to GitHub and NPM, etc)

docs/rules/no-unused-services.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# ember/no-unused-services
22

3-
💡 This rule is manually fixable by [editor suggestions](https://eslint.org/docs/developer-guide/working-with-rules#providing-suggestions).
3+
💡 This rule is manually fixable by [editor suggestions](https://eslint.org/docs/latest/use/core-concepts#rule-suggestions).
44

55
<!-- end auto-generated rule header -->
66

docs/rules/route-path-style.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# ember/route-path-style
22

3-
💡 This rule is manually fixable by [editor suggestions](https://eslint.org/docs/developer-guide/working-with-rules#providing-suggestions).
3+
💡 This rule is manually fixable by [editor suggestions](https://eslint.org/docs/latest/use/core-concepts#rule-suggestions).
44

55
<!-- end auto-generated rule header -->
66

eslint.config.js

Lines changed: 22 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ const js = require('@eslint/js');
55
const babelEslintParser = require('@babel/eslint-parser');
66
const eslintPluginEslintPluginAll = require('eslint-plugin-eslint-plugin/configs/all');
77
const eslintPluginFilenames = require('eslint-plugin-filenames');
8-
const eslintPluginJest = require('eslint-plugin-jest');
98
const eslintPluginMarkdown = require('eslint-plugin-markdown');
109
const eslintPluginN = require('eslint-plugin-n');
1110
const eslintPluginPrettierRecommended = require('eslint-plugin-prettier/recommended');
@@ -33,23 +32,10 @@ module.exports = [
3332
eslintPluginN.configs['flat/recommended'],
3433
eslintPluginUnicorn.configs['flat/recommended'],
3534

36-
{
37-
ignores: [
38-
'coverage/',
39-
'node_modules/',
40-
'lib/recommended-rules.js',
41-
'lib/recommended-rules-gjs.js',
42-
'lib/recommended-rules-gts.js',
43-
'tests/__snapshots__/',
44-
45-
// # Contains <template> in js markdown
46-
'docs/rules/no-empty-glimmer-component-classes.md',
47-
'docs/rules/template-no-let-reference.md',
48-
],
49-
},
5035
{
5136
languageOptions: {
5237
parser: babelEslintParser,
38+
sourceType: 'script',
5339
parserOptions: {
5440
ecmaVersion: 2022,
5541
sourceType: 'script',
@@ -153,6 +139,8 @@ module.exports = [
153139
'import/no-webpack-loader-syntax': 'error',
154140
'import/unambiguous': 'error',
155141

142+
'n/no-unsupported-features/node-builtins': 'off',
143+
156144
// Unicorn rules:
157145
'unicorn/no-array-callback-reference': 'off',
158146
'unicorn/no-array-method-this-argument': 'off',
@@ -168,29 +156,7 @@ module.exports = [
168156
{
169157
// Test files:
170158
files: ['**/*.js', '**/*.js.snap'],
171-
plugins: { jest: eslintPluginJest },
172-
rules: {
173-
...eslintPluginJest.configs.recommended.rules,
174-
...eslintPluginJest.configs.style.rules,
175-
176-
// Optional jest rules:
177-
'jest/consistent-test-it': 'error',
178-
'jest/no-duplicate-hooks': 'error',
179-
'jest/no-hooks': 'error',
180-
'jest/no-if': 'error',
181-
'jest/no-large-snapshots': 'error',
182-
'jest/no-restricted-matchers': 'error',
183-
'jest/no-test-return-statement': 'error',
184-
'jest/prefer-called-with': 'error',
185-
'jest/prefer-hooks-on-top': 'error',
186-
'jest/prefer-lowercase-title': 'error',
187-
'jest/prefer-spy-on': 'error',
188-
'jest/prefer-strict-equal': 'error',
189-
'jest/prefer-todo': 'error',
190-
'jest/require-to-throw-message': 'error',
191-
'jest/require-top-level-describe': 'error',
192-
'jest/valid-title': 'error',
193-
},
159+
plugins: {},
194160
languageOptions: {
195161
globals: {
196162
...globals.jest,
@@ -206,6 +172,7 @@ module.exports = [
206172
// Markdown code samples in documentation:
207173
files: ['**/*.md/*.js'],
208174
languageOptions: {
175+
sourceType: 'module',
209176
parserOptions: {
210177
sourceType: 'module',
211178
ecmaFeatures: { legacyDecorators: true },
@@ -216,10 +183,6 @@ module.exports = [
216183
'filenames/match-regex': 'off',
217184
'import/no-unresolved': 'off',
218185
'import/unambiguous': 'off',
219-
'jest/expect-expect': 'off',
220-
'jest/no-done-callback': 'off',
221-
'jest/no-test-callback': 'off',
222-
'jest/require-top-level-describe': 'off',
223186
'n/no-extraneous-import': 'off',
224187
'n/no-missing-import': 'off',
225188
'n/no-missing-require': 'off',
@@ -259,6 +222,23 @@ module.exports = [
259222
'import/no-named-as-default-member': 'off',
260223
'import/no-unresalved': 'off',
261224
'import/no-missing-import': 'off',
225+
226+
// vite config format does not match regex
227+
'filenames/match-regex': 'off',
262228
},
263229
},
230+
{
231+
ignores: [
232+
'coverage/',
233+
'node_modules/',
234+
'lib/recommended-rules.js',
235+
'lib/recommended-rules-gjs.js',
236+
'lib/recommended-rules-gts.js',
237+
'tests/__snapshots__/',
238+
239+
// # Contains <template> in js markdown
240+
'docs/rules/no-empty-glimmer-component-classes.md',
241+
'docs/rules/template-no-let-reference.md',
242+
],
243+
},
264244
];

lib/rules/no-get.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ module.exports = {
224224
);
225225
}
226226

227-
let currentProxyObject = null;
227+
const proxyObjects = [];
228228
let currentClassWithUnknownPropertyMethod = null;
229229

230230
let importedGetName;
@@ -251,17 +251,17 @@ module.exports = {
251251
},
252252

253253
'CallExpression:exit'(node) {
254-
if (currentProxyObject === node) {
255-
currentProxyObject = null;
254+
if (proxyObjects.at(-1) === node) {
255+
proxyObjects.pop();
256256
}
257257
if (currentClassWithUnknownPropertyMethod === node) {
258258
currentClassWithUnknownPropertyMethod = null;
259259
}
260260
},
261261

262262
'ClassDeclaration:exit'(node) {
263-
if (currentProxyObject === node) {
264-
currentProxyObject = null;
263+
if (proxyObjects.at(-1) === node) {
264+
proxyObjects.pop();
265265
}
266266
if (currentClassWithUnknownPropertyMethod === node) {
267267
currentClassWithUnknownPropertyMethod = null;
@@ -270,7 +270,7 @@ module.exports = {
270270

271271
ClassDeclaration(node) {
272272
if (emberUtils.isEmberProxy(context, node)) {
273-
currentProxyObject = node; // Keep track of being inside a proxy object.
273+
proxyObjects.push(node); // Keep track of being inside a proxy object.
274274
}
275275
if (emberUtils.isEmberObjectImplementingUnknownProperty(node, scopeManager)) {
276276
currentClassWithUnknownPropertyMethod = node; // Keep track of being inside an object implementing `unknownProperty`.
@@ -284,12 +284,12 @@ module.exports = {
284284
// **************************
285285

286286
if (emberUtils.isEmberProxy(context, node)) {
287-
currentProxyObject = node; // Keep track of being inside a proxy object.
287+
proxyObjects.push(node); // Keep track of being inside a proxy object.
288288
}
289289
if (emberUtils.isEmberObjectImplementingUnknownProperty(node, scopeManager)) {
290290
currentClassWithUnknownPropertyMethod = node;
291291
}
292-
if (currentProxyObject || currentClassWithUnknownPropertyMethod) {
292+
if (proxyObjects.at(-1) || currentClassWithUnknownPropertyMethod) {
293293
// Proxy objects and objects implementing `unknownProperty()`
294294
// still require using `get()`, so ignore any code inside them.
295295
return;

package.json

Lines changed: 17 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -40,40 +40,24 @@
4040
"changelog": "lerna-changelog",
4141
"lint": "npm-run-all --continue-on-error --aggregate-output --parallel \"lint:!(fix)\"",
4242
"lint:docs": "markdownlint \"**/*.md\"",
43-
"lint:docs:fix": "npm-run-all \"lint:docs -- --fix\"",
44-
"lint:eslint-docs": "npm-run-all \"update:eslint-docs -- --check\"",
43+
"lint:docs:fix": "pnpm lint:docs --fix",
44+
"lint:eslint-docs": "pnpm update:eslint-docs --check",
4545
"lint:eslint-docs:fix": "npm-run-all \"update:eslint-docs\"",
4646
"lint:fix": "npm-run-all \"lint:*:fix\"",
47-
"lint:js": "eslint --cache .",
48-
"lint:js:fix": "npm-run-all \"lint:js -- --fix\"",
47+
"lint:js": "eslint .",
48+
"lint:js:fix": "pnpm lint:js --fix",
4949
"lint:package-json": "npmPkgJsonLint .",
5050
"lint:package-json-sorting": "sort-package-json --check",
5151
"lint:package-json-sorting:fix": "sort-package-json package.json",
5252
"lint:remote": "eslint-remote-tester",
5353
"release": "release-it",
54-
"start": "yarn run test:watch",
55-
"test": "jest",
56-
"test:coverage": "jest --coverage",
57-
"test:watch": "jest --watchAll",
54+
"start": "pnpm test:watch",
55+
"test": "vitest run",
56+
"test:coverage": "vitest --coverage",
57+
"test:watch": "vitest",
5858
"update": "node ./scripts/update-rules.js && node ./scripts/list-jquery-methods.js && npm-run-all update:eslint-docs",
5959
"update:eslint-docs": "eslint-doc-generator"
6060
},
61-
"jest": {
62-
"coverageThreshold": {
63-
"global": {
64-
"branches": 95,
65-
"functions": 98.95,
66-
"lines": 98,
67-
"statements": 98
68-
}
69-
},
70-
"testMatch": [
71-
"**/tests/**/*.js"
72-
],
73-
"testPathIgnorePatterns": [
74-
"<rootDir>/tests/helpers/"
75-
]
76-
},
7761
"dependencies": {
7862
"@ember-data/rfc395-data": "^0.0.4",
7963
"css-tree": "^2.3.1",
@@ -87,6 +71,7 @@
8771
"snake-case": "^3.0.3"
8872
},
8973
"devDependencies": {
74+
"@babel/core": "^7.25.9",
9075
"@babel/eslint-parser": "^7.22.15",
9176
"@babel/plugin-proposal-class-properties": "^7.18.6",
9277
"@babel/plugin-proposal-decorators": "^7.23.2",
@@ -95,21 +80,20 @@
9580
"@release-it-plugins/lerna-changelog": "^6.0.0",
9681
"@types/eslint": "^8.44.6",
9782
"@typescript-eslint/parser": "^7.0.1",
83+
"@vitest/coverage-v8": "^2.1.3",
9884
"eslint": "^8.55.0",
9985
"eslint-config-prettier": "^9.0.0",
10086
"eslint-doc-generator": "^1.5.3",
10187
"eslint-plugin-eslint-comments": "^3.2.0",
10288
"eslint-plugin-eslint-plugin": "^5.1.1",
10389
"eslint-plugin-filenames": "^1.3.2",
10490
"eslint-plugin-import": "^2.29.0",
105-
"eslint-plugin-jest": "^27.8.0",
10691
"eslint-plugin-markdown": "^3.0.1",
107-
"eslint-plugin-n": "^16.2.0",
92+
"eslint-plugin-n": "^17.11.1",
10893
"eslint-plugin-prettier": "^5.0.1",
10994
"eslint-plugin-unicorn": "^51.0.0",
11095
"eslint-remote-tester": "^3.0.1",
11196
"globals": "^14.0.0",
112-
"jest": "^29.7.0",
11397
"jquery": "^3.7.1",
11498
"jsdom": "^24.0.0",
11599
"markdownlint-cli": "^0.39.0",
@@ -119,7 +103,9 @@
119103
"release-it": "^17.0.0",
120104
"sort-package-json": "^2.6.0",
121105
"typescript": "^5.2.2",
122-
"typescript-eslint": "^8.7.0"
106+
"typescript-eslint": "^8.7.0",
107+
"vite": "^5.4.9",
108+
"vitest": "^2.1.3"
123109
},
124110
"peerDependencies": {
125111
"@typescript-eslint/parser": "*",
@@ -130,12 +116,13 @@
130116
"optional": true
131117
}
132118
},
119+
"packageManager": "[email protected]",
133120
"engines": {
134121
"node": "18.* || 20.* || >= 21"
135122
},
136123
"volta": {
137-
"node": "21.5.0",
138-
"yarn": "1.22.21"
124+
"node": "22.10.0",
125+
"pnpm": "9.12.2"
139126
},
140127
"publishConfig": {
141128
"registry": "https://registry.npmjs.org"

0 commit comments

Comments
 (0)