Skip to content

Commit

Permalink
chore(linting): automate tracking of custom Sass functions for stylel…
Browse files Browse the repository at this point in the history
…int (#10313)

**Related Issue:** #10188 

## Summary

This adds a script that tracks all custom Sass functions and updates the
metadata for Stylelint’s
[`function-no-unknown`](https://github.com/stylelint-scss/stylelint-scss/tree/master/src/rules/function-no-unknown)
rule, addressing workflow improvements as discussed in
#10188 (comment).

Our pre-commit hook will run this script if there is a staged Sass file
and will add any changes (if any).

**Note**: this depends on
#10311.

---------

Co-authored-by: Ben Elan <no-reply@benelan.dev>
  • Loading branch information
jcfranco and benelan authored Sep 16, 2024
1 parent 9afbb48 commit 62259d1
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 3 deletions.
20 changes: 18 additions & 2 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env sh
#!/usr/bin/env bash

ensure_types_are_up_to_date() {
types_path="packages/calcite-components/src/components.d.ts"
Expand All @@ -9,6 +9,21 @@ ensure_types_are_up_to_date() {
fi
}

update_stylelint_config_if_sass_file_edited() {
staged_files="$(git diff --cached --name-only --diff-filter=ACM)"

for file in $staged_files; do
if [[ "$file" == *.scss ]]; then
npm run util:update-stylelint-custom-sass-functions
break
fi
done

if [ -n "$(git diff --name-only -- "packages/calcite-components/.stylelintrc.json")" ]; then
git add "packages/calcite-components/.stylelintrc.json"
fi
}

check_ui_icon_name_consistency() {
svg_icon_dir="packages/calcite-ui-icons/icons"

Expand Down Expand Up @@ -43,7 +58,8 @@ check_ui_icon_name_consistency() {
}

lint-staged
ensure_types_are_up_to_date
check_ui_icon_name_consistency
ensure_types_are_up_to_date
update_stylelint_config_if_sass_file_edited

exit 0
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"util:is-next-deployable": "tsx support/isNextDeployable.ts",
"util:push-tags": "git push origin HEAD --follow-tags",
"util:upload-release-assets": "tsx support/uploadReleaseAssets.ts",
"util:update-stylelint-custom-sass-functions": "tsx support/updateStylelintCustomSassFunctions.ts",
"util:remove-prerelease-changelog-entries": "tsx support/removePrereleaseChangelogEntries.ts",
"util:sync-linked-package-versions": "tsx support/syncLinkedPackageVersions.ts"
},
Expand Down
9 changes: 8 additions & 1 deletion packages/calcite-components/.stylelintrc.cjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
// @ts-check

// ⚠️ AUTO-GENERATED CODE - DO NOT EDIT
const customFunctions = [
"get-trailing-text-input-padding",
"scale-duration"
];
// ⚠️ END OF AUTO-GENERATED CODE

const scssPatternRules = [
"scss/at-function-pattern",
"scss/dollar-variable-pattern",
Expand Down Expand Up @@ -50,7 +57,7 @@ const rules = {
"scss/function-no-unknown": [
true,
{
ignoreFunctions: ["get-trailing-text-input-padding", "scale-duration", "theme", "var"],
ignoreFunctions: [...customFunctions, "theme", "var"],
severity: "error",
},
],
Expand Down
63 changes: 63 additions & 0 deletions support/updateStylelintCustomSassFunctions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/**
* This script updates a variable from the stylelint config file with a list of custom Sass functions found in the project.
* This helps stylelint flag unknown functions that may be unintentionally used.
*/

import * as fs from 'fs';
import * as path from 'path';

console.info('Scanning custom functions for Stylelint config update.');

const rootDirectory = path.join(__dirname, '..');

function collectSassFiles(dir: string): string[] {
const sassFiles: string[] = [];

try {
fs.readdirSync(dir, { recursive: true, withFileTypes: true }).forEach(dirent => {
const fullPath = path.join(dir, dirent.name);

if (dirent.isFile() && fullPath.endsWith('.scss')) {
sassFiles.push(fullPath);
}
});
} catch (err) {
console.error(`Error reading directory: ${dir}`, err);
}

return sassFiles;
}

const customFunctionPattern = /@function\s+([a-zA-Z0-9_-]+)/g;
const customFunctions = new Set<string>();
const sassFiles = collectSassFiles(rootDirectory);

sassFiles.forEach(filePath => {
try {
const content = fs.readFileSync(filePath, 'utf8');
let match: RegExpExecArray | null;

while ((match = customFunctionPattern.exec(content)) !== null) {
customFunctions.add(match[1]);
}
} catch (err) {
console.error(`Error reading file: ${filePath}`, err);
}
});

const stylelintConfigPath = path.join(__dirname, "..", "packages", "calcite-components", ".stylelintrc.cjs");

try {
const stylelintConfigContent = fs.readFileSync(stylelintConfigPath, 'utf8');
const customFunctionsPattern = /const customFunctions = \[[\s\S]*?\];/;

const updatedConfigContent = stylelintConfigContent.replace(
customFunctionsPattern,
`const customFunctions = ${JSON.stringify(Array.from(customFunctions).sort(), null, 2)};`
);

fs.writeFileSync(stylelintConfigPath, updatedConfigContent);
console.info('Stylelint configuration updated successfully');
} catch (err) {
console.error(`Error updating Stylelint configuration: ${stylelintConfigPath}`, err);
}

0 comments on commit 62259d1

Please sign in to comment.