Skip to content

Instantly share code, notes, and snippets.

@philipjfulcher
Created February 27, 2024 20:02
Show Gist options
  • Select an option

  • Save philipjfulcher/dcc63282253a3e0722168f2df717dd50 to your computer and use it in GitHub Desktop.

Select an option

Save philipjfulcher/dcc63282253a3e0722168f2df717dd50 to your computer and use it in GitHub Desktop.
Experimental lint rule example
import {
joinPathFragments,
normalizePath,
NX_VERSION,
ProjectGraphExternalNode,
ProjectGraphProjectNode, readCachedProjectGraph,
workspaceRoot
} from '@nx/devkit';
import { isRelativePath } from 'nx/src/utils/fileutils';
import { ESLintUtils } from '@typescript-eslint/utils';
import { AST_NODE_TYPES, TSESTree } from '@typescript-eslint/utils';
import { basename, dirname, relative } from 'path';
type Options = [
{}
];
export type MessageIds =
| 'dependsOnExperimental' | 'log';
export const RULE_NAME = 'depends-on-experimental';
export const rule = ESLintUtils.RuleCreator(
() => __filename
)<Options, MessageIds>({
name: RULE_NAME,
meta: {
type: "suggestion",
fixable: "code",
docs: {
description: "Enforce that a variable named `foo` can only be assigned a value of 'bar'."
},
schema: [],
messages: {
dependsOnExperimental: `This project depends on an experimental feature`,
log: "{{message}}"
}
},
defaultOptions: [
{}
],
create(
context
) {
const projectGraph = readCachedProjectGraph();
if (!projectGraph) {
return {};
}
function run(
node:
| TSESTree.ImportDeclaration
| TSESTree.ImportExpression
) {
// accept only literals because template literals have no value
if (node.source.type !== AST_NODE_TYPES.Literal) {
return;
}
const imp = node.source.value as string;
// context.report({ node, messageId: 'log', data: {message: imp} });
const targetProject = projectGraph.nodes[imp.replace('@angular-eslint-workspace-rule/','')];
// If source is not part of an nx workspace, return.
if (!targetProject) {
return;
}
if (targetProject.data.tags.includes('lifecycle:experimental')) {
context.report({ node, messageId: 'dependsOnExperimental'});
}
}
return {
ImportDeclaration(node: TSESTree.ImportDeclaration) {
run(node);
},
ImportExpression(node: TSESTree.ImportExpression) {
run(node);
}
};
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment