Skip to content

Commit

Permalink
chore(lint): Add linting rule for experimental features
Browse files Browse the repository at this point in the history
  • Loading branch information
akash1810 committed Aug 12, 2022
1 parent a5e7d6e commit 69bbde8
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 4 deletions.
9 changes: 9 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ module.exports = {
"@typescript-eslint/no-inferrable-types": 0,
"import/no-namespace": 2,
"custom-rules/valid-constructors": 2,
"custom-rules/experimental-classes": 0,
},
root: true,
ignorePatterns: ["**/*.js", "node_modules"],
Expand All @@ -25,5 +26,13 @@ module.exports = {
"custom-rules/valid-constructors": 0,
},
},

// This rule is applied within `overrides` as it only applies to the `experimental` directory, and the rule's test.
{
files: ["src/experimental/**", "tools/eslint/rules/experimental-classes.test.ts"],
rules: {
"custom-rules/experimental-classes": 2,
},
},
],
};
4 changes: 2 additions & 2 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ module.exports = {
},
setupFilesAfterEnv: ["./jest.setup.js"],

// ignore this file as it's used to demonstrate custom lint rule and Jest flags unused declarations
testPathIgnorePatterns: ["<rootDir>/tools/eslint/rules/valid-constructors.test.ts"],
// ignore these files as they're used to demonstrate custom lint rules and Jest flags unused declarations
testPathIgnorePatterns: ["<rootDir>/tools/eslint/rules/*.test.ts"],

/*
Ignore `lib` to prevent a 'duplicate manual mock found" warning
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"format": "prettier --write \"src/**/*.ts\"",
"watch": "tsc -w",
"test": "jest --detectOpenHandles --runInBand",
"test:custom-lint-rule": "eslint tools/eslint/rules/valid-constructors.test.ts",
"test:custom-lint-rule": "eslint tools/eslint/rules/*.test.ts",
"test:dev": "jest --detectOpenHandles --runInBand --watch",
"prepare": "tsc",
"prepack": "cp -r src/bin/commands/new-project/template lib/bin/commands/new-project/template",
Expand Down
1 change: 1 addition & 0 deletions tools/eslint/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
module.exports = {
rules: {
"valid-constructors": require("./rules/valid-constructors"),
"experimental-classes": require("./rules/experimental-classes"),
},
};
48 changes: 48 additions & 0 deletions tools/eslint/rules/experimental-classes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
RULES:
1. Un-exported classes don't get linted
2. Class name must end with 'Experimental'
The rule is applied to the `experimental` directory. See `.eslintrc.js`.
See ../../../docs/architecture-decision-records/005-x01-package-structure.md
*/

const NO_LINT_ERRORS = null;

module.exports = {
meta: {
type: "suggestion",
docs: {
description: "Signal (potential) un-stability to consumers",
category: "Best Practices",
url: "https://github.com/guardian/cdk/blob/main/docs/architecture-decision-records/005-x01-package-structure.md",
},
schema: [],
},

create(context) {
return {
ClassDeclaration(node) {
const isExported = node.parent.type === "ExportNamedDeclaration";

if (!isExported) {
return NO_LINT_ERRORS;
}

const className = node.id.name;
const isClassNameExperimental = className.endsWith("Experimental");

if (isClassNameExperimental) {
return NO_LINT_ERRORS;
}

return context.report({
node,
message: `Exported classes should end with 'Experimental' to signal its (potential) un-stability. Rename ${className} to ${className}Experimental.`,
loc: node.loc,
});
},
};
},
};
17 changes: 17 additions & 0 deletions tools/eslint/rules/experimental-classes.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* This robot is supposed to do helpful things.
*
* @experimental This robot should be helpful, but it might also take over the world...
*/
export class HelpfulRobotExperimental {
private constructor(task: string) {
console.log(task);
}
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars -- testing file
class TheRobot {
private constructor(name: string) {
console.log(name);
}
}
2 changes: 1 addition & 1 deletion tsconfig.eslint.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"extends": "./tsconfig.json",
"include": [
"src/**/*",
"tools/eslint/rules/valid-constructors.test.ts"
"tools/eslint/rules/*.test.ts"
],
"exclude": [
"node_modules"
Expand Down

0 comments on commit 69bbde8

Please sign in to comment.