Skip to content

Commit

Permalink
feat(eslint-plugin): yarnrc version harmonize
Browse files Browse the repository at this point in the history
  • Loading branch information
kpanot committed Dec 7, 2023
1 parent 48b523c commit c06f091
Show file tree
Hide file tree
Showing 17 changed files with 537 additions and 268 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ generated-doc/
/.vscode
/tools/github-actions/*/packaged-action/
/**/src/**/package.json
!/.yarnrc.yml
19 changes: 19 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ module.exports = {
'jest/no-jasmine-globals': 'off'
}
},

{
'parser': require.resolve('jsonc-eslint-parser'),
'files': [
Expand All @@ -49,6 +50,24 @@ module.exports = {
'checkObsoleteDependencies': false
}]
}
},

{
'parser': require.resolve('yaml-eslint-parser'),
'files': [
'**/*.y{a,}ml'
]
},
{
'files': [
'**/.yarnrc.yml'
],
'plugins': [
'@o3r'
],
'rules': {
'@o3r/yarnrc-package-extensions-harmonize': ['error']
}
}
],
'env': {
Expand Down
6 changes: 4 additions & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,17 @@
"eslint.validate": [
"javascript",
"typescript",
"json"
"json",
"yaml"
],
"eslint.probe": [
"javascript",
"typescript",
"typescriptreact",
"html",
"markdown",
"json"
"json",
"yaml"
],
"typescript.enablePromptUseWorkspaceTsdk": true,
"nxConsole.generatorAllowlist": [
Expand Down
22 changes: 11 additions & 11 deletions .yarnrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,17 @@ nodeLinker: pnp
packageExtensions:
"@design-factory/design-factory@*":
peerDependencies:
"@angular/router": ^17.0.0
"@angular/router": ~17.0.4
"@nx/angular@^17.1.1":
dependencies:
"@angular-devkit/build-angular": ^17.0.0
"@angular-devkit/core": ^17.0.0
"@angular-devkit/schematics": ^17.0.0
"@angular/compiler": ^17.0.0
"@angular/compiler-cli": ^17.0.0
"@schematics/angular": ^17.0.0
"@types/node": ^17.0.23
esbuild: ^0.17.5
"@angular-devkit/build-angular": ~17.0.3
"@angular-devkit/core": ~17.0.3
"@angular-devkit/schematics": ~17.0.3
"@angular/compiler": ~17.0.4
"@angular/compiler-cli": ~17.0.4
"@schematics/angular": ~17.0.3
"@types/node": ^18.0.0
esbuild: ~0.19.0
eslint: ^8.42.0
nx: ^17.1.1
rxjs: ^7.8.1
Expand Down Expand Up @@ -47,12 +47,12 @@ packageExtensions:
typescript: ~5.2.2
"@nx/webpack@^17.1.1":
dependencies:
"@types/node": ^17.0.23
"@types/node": ^18.0.0
nx: ^17.1.1
typescript: ~5.2.2
postcss-loader@^7.2.4:
dependencies:
"@types/node": ^17.0.23
"@types/node": ^18.0.0
probot@*:
dependencies:
body-parser: ^1.20.2
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,11 @@ Example of a ESLint configuration:
"plugins": [
"@o3r"
],
"files": [
"**/package.json"
],
"extends": [
"@o3r:recommended-json"
"@o3r:json-recommended"
]
}
```
Expand Down
103 changes: 103 additions & 0 deletions docs/linter/eslint-plugin/rules/yarnrc-package-extensions-harmonize.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# Verify that the yarn package extensions versions

This rule checks the `.yarnrc.yml` file to ensure that each version defined in the `packageExtensions` are aligned with the one used in the `package.json` files of the project.

## Prerequisite

The linter is dedicated to YAML files and requires the setup of the [yaml-eslint-parser](https://www.npmjs.com/package/yaml-eslint-parser).

Example of a ESLint configuration:

```json
{
"parser": "yaml-eslint-parser",
"plugins": [
"@o3r"
],

"files": [
"**/.yarnrc.yml"
],
"extends": [
"@o3r:yarn-recommended"
]
}
```

## Options

### dependencyTypesInPackages

List of dependency types to check in the package.json

**Default**: ['optionalDependencies', 'dependencies', 'devDependencies', 'peerDependencies', 'generatorDependencies']*

**Usage**:

```json
{
"@o3r/yarnrc-package-extensions-harmonize": [
"error",
{
"dependencyTypesInPackages": ["dependencies", "peerDependencies"]
}
]
}
```

### ignoredDependencies

List of dependencies to ignore.

**Default**: *[]*

**Usage**:

```json
{
"@o3r/yarnrc-package-extensions-harmonize": [
"error",
{
"ignoredDependencies": ["rxjs", "@angular/*"]
}
]
}
```

### excludePackages

List of package name to ignore when determining the dependencies versions.

**Default**: *[]*

**Usage**:

```json
{
"@o3r/yarnrc-package-extensions-harmonize": [
"error",
{
"excludePackages": ["@o3r/core"]
}
]
}
```

### yarnrcDependencyTypes

List of package extension types to check in the yarnrc.

**Default**: *['peerDependencies', 'dependencies']*

**Usage**:

```json
{
"@o3r/yarnrc-package-extensions-harmonize": [
"error",
{
"yarnrcDependencyTypes": ["dependencies"]
}
]
}
```
8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"build:storybook": "yarn doc:generate:json && yarn ng run storybook:extract-style && build-storybook",
"clear": "rimraf -g './{packages,tools,apps}/{@*/,}{amaterasu/,}*/{dist,build,dist-*}/'",
"set:version": "yarn o3r-set-version --placeholder 0.0.0-placeholder --include '{apps,packages}/**/dist/package.json'",
"harmonize:version": "eslint '**/package.json*' --quiet --fix",
"harmonize:version": "eslint '**/package.json*' '.yarnrc.yml' --quiet --fix",
"doc:packages": "yarn nx run-many --target=documentation --parallel $(yarn get:cpus-number)",
"doc:root": "yarn prepare-doc-root-menu-template && yarn update-doc-summary ./docs && yarn compodoc",
"doc:generate": "rimraf ./generated-doc && yarn doc:root && yarn doc:packages && yarn doc-links --docs ./docs --generated-doc ./generated-doc",
Expand All @@ -49,6 +49,9 @@
"**/package.json": [
"eslint --quiet --fix"
],
"**/.yarnrc.yml": [
"eslint --quiet --fix"
],
"*": [
"editorconfig-checker -exclude \".*[\\\\/]templates[\\\\/].*\" -ignore-defaults --verbose"
]
Expand Down Expand Up @@ -237,7 +240,8 @@
"typescript": "~5.2.2",
"uuid": "^9.0.0",
"webpack": "~5.89.0",
"winston": "^3.8.2"
"winston": "^3.8.2",
"yaml-eslint-parser": "^1.2.2"
},
"engines": {
"npm": "please-use-yarn",
Expand Down
9 changes: 7 additions & 2 deletions packages/@o3r/eslint-plugin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@
},
"jsonc-eslint-parser": {
"optional": true
},
"yaml-eslint-parser": {
"optional": true
}
},
"peerDependencies": {
Expand All @@ -41,7 +44,8 @@
"@typescript-eslint/eslint-plugin": "^6.11.0",
"@typescript-eslint/parser": "^6.11.0",
"eslint": "^8.22.0",
"jsonc-eslint-parser": "~2.4.0"
"jsonc-eslint-parser": "~2.4.0",
"yaml-eslint-parser": "^1.2.2"
},
"devDependencies": {
"@angular-devkit/core": "~17.0.3",
Expand Down Expand Up @@ -74,7 +78,8 @@
"rimraf": "^5.0.1",
"ts-jest": "~29.1.1",
"type-fest": "^3.12.0",
"typescript": "~5.2.2"
"typescript": "~5.2.2",
"yaml-eslint-parser": "^1.2.2"
},
"schematics": "./collection.json"
}
12 changes: 10 additions & 2 deletions packages/@o3r/eslint-plugin/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
/* eslint-disable @typescript-eslint/naming-convention */
import noFolderImportForModule from './rules/typescript/no-folder-import-for-module/no-folder-import-for-module';
import o3rWidgetTags from './rules/typescript/o3r-widget-tags/o3r-widget-tags';
import matchingConfigurationName from './rules/typescript/matching-configuration-name/matching-configuration-name';
import noInnerHTML from './rules/template/no-inner-html/no-inner-html';
import templateAsyncNumberLimitation from './rules/template/template-async-number-limitation/template-async-number-limitation';
import jsonDependencyVersionsHarmonize from './rules/json/json-dependency-versions-harmonize/json-dependency-versions-harmonize';
import matchingConfigurationName from './rules/typescript/matching-configuration-name/matching-configuration-name';
import yarnrcPackageExtensionHarmonize from './rules/yaml/yarnrc-package-extensions-harmonize/yarnrc-package-extensions-harmonize';

module.exports = {
rules: {
Expand All @@ -13,7 +14,8 @@ module.exports = {
'template-async-number-limitation': templateAsyncNumberLimitation,
'o3r-widget-tags': o3rWidgetTags,
'json-dependency-versions-harmonize': jsonDependencyVersionsHarmonize,
'matching-configuration-name': matchingConfigurationName
'matching-configuration-name': matchingConfigurationName,
'yarnrc-package-extensions-harmonize': yarnrcPackageExtensionHarmonize
},
configs: {
'@o3r/no-folder-import-for-module': 'error',
Expand All @@ -40,6 +42,12 @@ module.exports = {
rules: {
'@o3r/json-dependency-versions-harmonize': 'error'
}
},

'yarn-recommended': {
rules: {
'@o3r/yarnrc-package-extensions-harmonize': 'error'
}
}
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export default createRule<[Options, ...any], 'versionUpdate' | 'error', any>({
dependencyTypes: {
type: 'array',
description: 'List of dependency types to update',
default: defaultOptions[0].dependencyTypes,
items: {
type: 'string'
}
Expand Down
2 changes: 1 addition & 1 deletion packages/@o3r/eslint-plugin/src/rules/json/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ interface JsoncParserServices extends ParserServices {
* @param parserServices Parser services object
*/
export function isJsoncParserServices(parserServices: any): parserServices is JsoncParserServices {
return !!parserServices;
return !!parserServices && typeof parserServices.isJSON !== undefined;
}

/**
Expand Down
49 changes: 49 additions & 0 deletions packages/@o3r/eslint-plugin/src/rules/yaml/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { ParserServices, TSESLint } from '@typescript-eslint/experimental-utils';

/** Basic interface for the Parser Services object provided by yaml-eslint-parser */
interface YamlParserServices extends ParserServices {
isYAML: boolean;
}

/**
* Determine if yaml-eslint-parser is used
* @param parserServices Parser services object
*/
export function isYamlParserServices(parserServices: any): parserServices is YamlParserServices {
return !!parserServices && parserServices.isYAML;
}

/**
* Retrieve the yaml parser services object or throw if the invalid parser is used
* @param context Rule context
*/
export function getYamlParserServices(context: Readonly<TSESLint.RuleContext<string, readonly unknown[]>>) {
const parserService = context.parserServices;
if (!isYamlParserServices(parserService)) {
/*
* The user needs to have configured "parser" in their eslint config and set it
* to yaml-eslint-parser
*/
throw new Error(
'You have used a rule which requires \'yaml-eslint-parser\' to be used as the \'parser\' in your ESLint config.'
);
}
return parserService;
}

/**
* Utility for rule authors to ensure that their rule is correctly being used with yaml-eslint-parser
* If yaml-eslint-parser is not the configured parser when the function is invoked it will throw
* @param context
*/
export function ensureJsoncParser(context: Readonly<TSESLint.RuleContext<string, readonly unknown[]>>): void {
if (!(context.parserServices)) {
/*
* The user needs to have configured "parser" in their eslint config and set it
* to yaml-eslint-parser
*/
throw new Error(
'You have used a rule which requires \'yaml-eslint-parser\' to be used as the \'parser\' in your ESLint config.'
);
}
}
Loading

0 comments on commit c06f091

Please sign in to comment.