mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Chore: Emit theme token usage metrics (#72500)
* create rule to find instances of theme variables * emit theme token usage metrics * move awking into script * make sure theme usage is covering ts and tsx files, remove commented lines
This commit is contained in:
@@ -40,6 +40,7 @@
|
|||||||
"storybook": "yarn workspace @grafana/ui storybook --ci",
|
"storybook": "yarn workspace @grafana/ui storybook --ci",
|
||||||
"storybook:build": "yarn workspace @grafana/ui storybook:build",
|
"storybook:build": "yarn workspace @grafana/ui storybook:build",
|
||||||
"themes:generate": "esbuild --target=es6 ./scripts/cli/generateSassVariableFiles.ts --bundle --platform=node --tsconfig=./scripts/cli/tsconfig.json | node",
|
"themes:generate": "esbuild --target=es6 ./scripts/cli/generateSassVariableFiles.ts --bundle --platform=node --tsconfig=./scripts/cli/tsconfig.json | node",
|
||||||
|
"themes:usage": "eslint . --ext .tsx,.ts --ignore-pattern '*.test.ts*' --ignore-pattern '*.spec.ts*' --cache --rule '{ @grafana/theme-token-usage: \"error\" }'",
|
||||||
"typecheck": "tsc --noEmit && yarn run packages:typecheck",
|
"typecheck": "tsc --noEmit && yarn run packages:typecheck",
|
||||||
"plugins:build-bundled": "find plugins-bundled -name package.json -not -path '*/node_modules/*' -execdir yarn build \\;",
|
"plugins:build-bundled": "find plugins-bundled -name package.json -not -path '*/node_modules/*' -execdir yarn build \\;",
|
||||||
"watch": "yarn start -d watch,start core:start --watchTheme",
|
"watch": "yarn start -d watch,start core:start --watchTheme",
|
||||||
|
|||||||
@@ -11,3 +11,7 @@ Require aria-label JSX properties to not include selectors from the `@grafana/e2
|
|||||||
Previously we hijacked the aria-label property to use as E2E selectors as an attempt to "improve accessibility" while making this easier for testing. However, this lead to many elements having poor, verbose, and unnecessary labels.
|
Previously we hijacked the aria-label property to use as E2E selectors as an attempt to "improve accessibility" while making this easier for testing. However, this lead to many elements having poor, verbose, and unnecessary labels.
|
||||||
|
|
||||||
Now, we prefer using data-testid for E2E selectors.
|
Now, we prefer using data-testid for E2E selectors.
|
||||||
|
|
||||||
|
### `@grafana/theme-token-usage`
|
||||||
|
|
||||||
|
Used to find all instances of `theme` tokens being used in the codebase and emit the counts as metrics. Should **not** be used as an actual lint rule!
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
const noAriaLabelSelectors = require('./rules/no-aria-label-e2e-selectors.cjs');
|
const noAriaLabelSelectors = require('./rules/no-aria-label-e2e-selectors.cjs');
|
||||||
|
const themeTokenUsage = require('./rules/theme-token-usage.cjs');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
rules: {
|
rules: {
|
||||||
'no-aria-label-selectors': noAriaLabelSelectors,
|
'no-aria-label-selectors': noAriaLabelSelectors,
|
||||||
|
'theme-token-usage': themeTokenUsage,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
51
packages/grafana-eslint-rules/rules/theme-token-usage.cjs
Normal file
51
packages/grafana-eslint-rules/rules/theme-token-usage.cjs
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
// @ts-check
|
||||||
|
const { ESLintUtils, AST_NODE_TYPES } = require('@typescript-eslint/utils');
|
||||||
|
|
||||||
|
const createRule = ESLintUtils.RuleCreator((name) => `https://github.com/grafana/grafana#${name}`);
|
||||||
|
|
||||||
|
const themeTokenUsage = createRule({
|
||||||
|
create(context) {
|
||||||
|
return {
|
||||||
|
Identifier: function (node) {
|
||||||
|
if (node.name === 'theme') {
|
||||||
|
const ancestors = context.getAncestors().reverse();
|
||||||
|
const paths = [];
|
||||||
|
let lastAncestor = null;
|
||||||
|
for (const ancestor of ancestors) {
|
||||||
|
if (ancestor.type === AST_NODE_TYPES.MemberExpression && ancestor.property.type === AST_NODE_TYPES.Identifier) {
|
||||||
|
paths.push(ancestor.property.name)
|
||||||
|
lastAncestor = ancestor;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (paths.length > 0 && lastAncestor) {
|
||||||
|
paths.unshift('theme');
|
||||||
|
context.report({
|
||||||
|
node: lastAncestor,
|
||||||
|
messageId: "themeTokenUsed",
|
||||||
|
data: {
|
||||||
|
identifier: paths.join('.')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
name: 'theme-token-usage',
|
||||||
|
meta: {
|
||||||
|
type: 'problem',
|
||||||
|
docs: {
|
||||||
|
description: 'Check for theme token usage',
|
||||||
|
recommended: false,
|
||||||
|
},
|
||||||
|
messages: {
|
||||||
|
themeTokenUsed: '{{ identifier }}',
|
||||||
|
},
|
||||||
|
schema: [],
|
||||||
|
},
|
||||||
|
defaultOptions: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = themeTokenUsage;
|
||||||
@@ -41,7 +41,15 @@ do
|
|||||||
BETTERER_STATS+="\"grafana.ci-code.betterer.${name}\": \"${value}\","
|
BETTERER_STATS+="\"grafana.ci-code.betterer.${name}\": \"${value}\","
|
||||||
done <<< "$(yarn betterer:stats)"
|
done <<< "$(yarn betterer:stats)"
|
||||||
|
|
||||||
|
THEME_TOKEN_USAGE=""
|
||||||
|
while read -r name value
|
||||||
|
do
|
||||||
|
THEME_TOKEN_USAGE+=$'\n '
|
||||||
|
THEME_TOKEN_USAGE+="\"grafana.ci-code.themeUsage.${name}\": \"${value}\","
|
||||||
|
done <<< "$(yarn themes:usage | awk '$4 == "@grafana/theme-token-usage" {print $3}' | awk '{!seen[$0]++}END{for (i in seen) print i, seen[i]}')"
|
||||||
|
|
||||||
echo "Metrics: {
|
echo "Metrics: {
|
||||||
|
$THEME_TOKEN_USAGE
|
||||||
$BETTERER_STATS
|
$BETTERER_STATS
|
||||||
\"grafana.ci-code.strictErrors\": \"${ERROR_COUNT}\",
|
\"grafana.ci-code.strictErrors\": \"${ERROR_COUNT}\",
|
||||||
\"grafana.ci-code.accessibilityErrors\": \"${ACCESSIBILITY_ERRORS}\",
|
\"grafana.ci-code.accessibilityErrors\": \"${ACCESSIBILITY_ERRORS}\",
|
||||||
|
|||||||
Reference in New Issue
Block a user