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
pull/72527/head
Ashley Harrison 2 years ago committed by GitHub
parent 50bd27b665
commit ae4810f854
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      package.json
  2. 4
      packages/grafana-eslint-rules/README.md
  3. 2
      packages/grafana-eslint-rules/index.cjs
  4. 51
      packages/grafana-eslint-rules/rules/theme-token-usage.cjs
  5. 8
      scripts/ci-frontend-metrics.sh

@ -40,6 +40,7 @@
"storybook": "yarn workspace @grafana/ui storybook --ci",
"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: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",
"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",

@ -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.
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 themeTokenUsage = require('./rules/theme-token-usage.cjs');
module.exports = {
rules: {
'no-aria-label-selectors': noAriaLabelSelectors,
'theme-token-usage': themeTokenUsage,
},
};

@ -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}\","
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: {
$THEME_TOKEN_USAGE
$BETTERER_STATS
\"grafana.ci-code.strictErrors\": \"${ERROR_COUNT}\",
\"grafana.ci-code.accessibilityErrors\": \"${ACCESSIBILITY_ERRORS}\",

Loading…
Cancel
Save