Skip to content
This repository has been archived by the owner on Oct 3, 2024. It is now read-only.

Move from a compile-all to a compile-entry-point pattern #463

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"LICENSE"
],
"scripts": {
"build": "rimraf lib && tsc -d -p tsconfig.json",
"build": "rimraf lib && tsc -d -p src",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since I added a tsconfig.json file under src, I target the src project here. Later on, would we want to build the test suite, we can add a tsconfig.json under tests and target the tests project to build the test suite. This way, entry point can be different between the main and the tests projects.

"test": "jest",
"ruling": "ts-node --files ruling/index.ts",
"precommit": "pretty-quick --staged",
Expand Down
122 changes: 75 additions & 47 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,66 +19,94 @@
*/
import type { TSESLint } from '@typescript-eslint/utils';
import type { FlatConfig } from '@typescript-eslint/utils/ts-eslint';
import * as cognitiveComplexity from './rules/cognitive-complexity';
import * as elseifWithoutElse from './rules/elseif-without-else';
import * as maxSwitchCases from './rules/max-switch-cases';
import * as noAllDuplicatedBranches from './rules/no-all-duplicated-branches';
import * as noCollapsibleIf from './rules/no-collapsible-if';
import * as noCollectionSizeMischeck from './rules/no-collection-size-mischeck';
import * as noDuplicateString from './rules/no-duplicate-string';
import * as noDuplicatedBranches from './rules/no-duplicated-branches';
import * as noElementOverwrite from './rules/no-element-overwrite';
import * as noEmptyCollection from './rules/no-empty-collection';
import * as noExtraArguments from './rules/no-extra-arguments';
import * as noGratuitousExpressions from './rules/no-gratuitous-expressions';
import * as noIdenticalConditions from './rules/no-identical-conditions';
import * as noIdenticalExpressions from './rules/no-identical-expressions';
import * as noIdenticalFunctions from './rules/no-identical-functions';
import * as noIgnoredReturn from './rules/no-ignored-return';
import * as noInvertedBooleanCheck from './rules/no-inverted-boolean-check';
import * as noNestedSwitch from './rules/no-nested-switch';
import * as noNestedTemplateLiterals from './rules/no-nested-template-literals';
import * as noOneIterationLoop from './rules/no-one-iteration-loop';
import * as noRedundantBoolean from './rules/no-redundant-boolean';
import * as noRedundantJump from './rules/no-redundant-jump';
import * as noSameLineConditional from './rules/no-same-line-conditional';
import * as noSmallSwitch from './rules/no-small-switch';
import * as noUnusedCollection from './rules/no-unused-collection';
import * as noUseOfEmptyReturnValue from './rules/no-use-of-empty-return-value';
import * as noUselessCatch from './rules/no-useless-catch';
import * as nonExistentOperator from './rules/non-existent-operator';
import * as preferImmediateReturn from './rules/prefer-immediate-return';
import * as preferObjectLiteral from './rules/prefer-object-literal';
import * as preferSingleBooleanReturn from './rules/prefer-single-boolean-return';
import * as preferWhile from './rules/prefer-while';

const sonarjsRules: string[] = [
'cognitive-complexity',
'elseif-without-else',
'max-switch-cases',
'no-all-duplicated-branches',
'no-collapsible-if',
'no-collection-size-mischeck',
'no-duplicate-string',
'no-duplicated-branches',
'no-element-overwrite',
'no-empty-collection',
'no-extra-arguments',
'no-gratuitous-expressions',
'no-identical-conditions',
'no-identical-expressions',
'no-identical-functions',
'no-ignored-return',
'no-inverted-boolean-check',
'no-nested-switch',
'no-nested-template-literals',
'no-one-iteration-loop',
'no-redundant-boolean',
'no-redundant-jump',
'no-same-line-conditional',
'no-small-switch',
'no-unused-collection',
'no-use-of-empty-return-value',
'no-useless-catch',
'non-existent-operator',
'prefer-immediate-return',
'prefer-object-literal',
'prefer-single-boolean-return',
'prefer-while',
];

const sonarjsRuleModules: { [key: string]: any } = {};
const rules: Record<string, TSESLint.RuleModule<string, Array<unknown>>> = {
'cognitive-complexity': cognitiveComplexity,
'elseif-without-else': elseifWithoutElse,
'max-switch-cases': maxSwitchCases,
'no-all-duplicated-branches': noAllDuplicatedBranches,
'no-collapsible-if': noCollapsibleIf,
'no-collection-size-mischeck': noCollectionSizeMischeck,
'no-duplicate-string': noDuplicateString,
'no-duplicated-branches': noDuplicatedBranches,
'no-element-overwrite': noElementOverwrite,
'no-empty-collection': noEmptyCollection,
'no-extra-arguments': noExtraArguments,
'no-gratuitous-expressions': noGratuitousExpressions,
'no-identical-conditions': noIdenticalConditions,
'no-identical-expressions': noIdenticalExpressions,
'no-identical-functions': noIdenticalFunctions,
'no-ignored-return': noIgnoredReturn,
'no-inverted-boolean-check': noInvertedBooleanCheck,
'no-nested-switch': noNestedSwitch,
'no-nested-template-literals': noNestedTemplateLiterals,
'no-one-iteration-loop': noOneIterationLoop,
'no-redundant-boolean': noRedundantBoolean,
'no-redundant-jump': noRedundantJump,
'no-same-line-conditional': noSameLineConditional,
'no-small-switch': noSmallSwitch,
'no-unused-collection': noUnusedCollection,
'no-use-of-empty-return-value': noUseOfEmptyReturnValue,
'no-useless-catch': noUselessCatch,
'non-existent-operator': nonExistentOperator,
'prefer-immediate-return': preferImmediateReturn,
'prefer-object-literal': preferObjectLiteral,
'prefer-single-boolean-return': preferSingleBooleanReturn,
'prefer-while': preferWhile,
};

const plugin = {
configs: {},
rules: {},
};

const recommendedLegacyConfig: TSESLint.Linter.Config = { plugins: ['sonarjs'], rules: {} };
const recommendedLegacyConfig: TSESLint.Linter.ConfigType = { plugins: ['sonarjs'], rules: {} };
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TSESLint.Linter.Configbeing deprecated, I replaced it with the legit type.

const recommendedConfig: FlatConfig.Config = {
plugins: {
sonarjs: plugin,
},
rules: {},
};

sonarjsRules.forEach(rule => {
sonarjsRuleModules[rule] = require(`./rules/${rule}`);
const {
meta: {
docs: { recommended },
},
} = sonarjsRuleModules[rule];
recommendedConfig.rules![`sonarjs/${rule}`] = recommended === undefined ? 'off' : 'error';
});
for (const key in rules) {
const rule = rules[key];
const recommended = rule.meta.docs?.recommended;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that, in this case, not destructuring is more readable than destructuring. Feel free to request a change if you think the destructured syntax of the original code is clearer:

const {
    meta: {
      docs: { recommended },
    },
  } = rule;


recommendedConfig.rules![`sonarjs/${key}`] = recommended === undefined ? 'off' : 'error';
}

recommendedLegacyConfig.rules = recommendedConfig.rules;

const configs = {
Expand All @@ -87,4 +115,4 @@ const configs = {
};
plugin.configs = configs;

export { sonarjsRuleModules as rules, configs };
export { rules, configs };
7 changes: 7 additions & 0 deletions src/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"sourceMap": false
},
"include": ["index.ts"]
}
2 changes: 1 addition & 1 deletion tests/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ it('should document all rules', () => {
existingRules.forEach(rule => {
expect(README.includes(rule)).toBe(true);
expect(fs.existsSync(`${root}/docs/rules/${rule}.md`)).toBe(true);
expect(rules[rule].meta.docs.url).toBe(
expect(rules[rule].meta.docs!.url).toBe(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that the exported rules is typed, I had to honor the fact that docs can be undefined.

`https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/${rule}.md`,
);
});
Expand Down
3 changes: 1 addition & 2 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,5 @@
"outDir": "lib",
"sourceMap": true,
"moduleResolution": "nodenext"
},
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no need to declare the included files since we now rely on an entry point declared on each project (aka tsconfig.json).

"include": ["src/**/*.ts"]
}
}