Fixes pre-commit git hook to ensure the optimisation of staged icons (#958)

* testing

* Fixes pre-commit hook

* Removing checkIcons from pre commit hook because it might result in false positives and negatives on an unclean local repository

* Added checkIcons Github action

---------

Co-authored-by: Karsa <karsa@karsa.org>
This commit is contained in:
Karsa
2023-02-28 17:24:17 +01:00
committed by GitHub
parent 2485f6117a
commit 1479a9dbd8
9 changed files with 69 additions and 25 deletions

View File

@@ -1,4 +0,0 @@
#!/bin/sh
pnpm run checkIcons
exit $?

41
.github/actions/check-icons.yml vendored Normal file
View File

@@ -0,0 +1,41 @@
name: "Check icons"
description: "Cross-checks icon and category references in JSON descriptors"
inputs:
name:
description: “Name of the package”
required: true
runs:
using: "composite"
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 16
- uses: pnpm/action-setup@v2.0.1
name: Install pnpm
id: pnpm-install
with:
version: 7
run_install: false
- name: Get pnpm store directory
id: pnpm-cache
run: |
echo "::set-output name=pnpm_cache_dir::$(pnpm store path)"
- uses: actions/cache@v3
name: Setup pnpm cache
with:
path: ${{ steps.pnpm-cache.outputs.pnpm_cache_dir }}
key: ${{ runner.os }}-lucide-preact-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-lucide-preact-pnpm-store-
- name: Install dependencies
run: pnpm install --filter .
- name: Check icons and categories
run: pnpm checkIcons

5
.husky/pre-commit Executable file
View File

@@ -0,0 +1,5 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
pnpm lint-staged
pnpm checkIcons

View File

@@ -20,7 +20,7 @@
"type": "string"
},
"icon": {
"$ref": "#/$defs/types/icon-reference"
"type": "string"
},
"weight": {
"type": "integer"

View File

@@ -24,7 +24,8 @@
"categories2icons": "node scripts/migrateCategoriesToIcons.mjs --presets @babel/env",
"generate:changelog": "node ./scripts/generateChangelog.mjs",
"postinstall": "husky install",
"lint": "eslint --ext .ts,.js,.mjs ./{packages/lucide,scripts}"
"lint": "eslint --ext .ts,.js,.mjs ./{packages/lucide,scripts}",
"prepare": "husky install"
},
"devDependencies": {
"eslint": "^8.26.0",
@@ -40,11 +41,6 @@
"svgo": "^3.0.0",
"svgson": "^5.2.1"
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"icons/*.svg": "node ./scripts/optimizeStagedSvgs.mjs"
},

View File

@@ -7,7 +7,7 @@ const icons = readAllMetadata(ICONS_DIR);
const CATEGORIES_DIR = path.resolve(currentDir, '../categories');
const categories = readAllMetadata(CATEGORIES_DIR);
console.log(`Read all icons`);
console.log('Reading all icons')
const svgFiles = readSvgDirectory(ICONS_DIR);
const iconNames = svgFiles.map(icon => icon.split('.')[0]);
@@ -47,5 +47,6 @@ Object.keys(categories).forEach(categoryName => {
});
if (error) {
throw new Error('At least one error in icon JSONs prevents from committing changes.');
console.error('At least one error in icon JSONs prevents from committing changes.');
process.exit(1);
}

View File

@@ -1,10 +1,11 @@
import fs from 'fs';
import processSvg from './render/processSvg.mjs';
const svgFiles = process.argv.slice(4);
const svgFiles = process.argv.slice(2);
svgFiles.forEach(async (svgFile) => {
console.log('Optimizing staged SVG file:', svgFile)
const content = fs.readFileSync(svgFile);
const svg = await processSvg(content);
const svg = await processSvg(content, svgFile);
fs.writeFileSync(svgFile, svg, 'utf-8');
});

View File

@@ -11,5 +11,5 @@ const svgFiles = readSvgDirectory(ICONS_DIR);
svgFiles.forEach((svgFile) => {
const content = fs.readFileSync(path.join(ICONS_DIR, svgFile));
processSvg(content).then((svg) => writeSvgFile(svgFile, ICONS_DIR, svg));
processSvg(content, svgFile).then((svg) => writeSvgFile(svgFile, ICONS_DIR, svg));
});

View File

@@ -1,6 +1,6 @@
import { optimize } from 'svgo';
import {optimize} from 'svgo';
import prettier from 'prettier';
import { parseSync, stringify } from 'svgson';
import {parseSync, stringify} from 'svgson';
import DEFAULT_ATTRS from './default-attrs.json' assert { type: 'json' };
/**
@@ -8,8 +8,9 @@ import DEFAULT_ATTRS from './default-attrs.json' assert { type: 'json' };
* @param {string} svg - An SVG string.
* @returns {Promise<string>} An optimized svg
*/
async function optimizeSvg(svg) {
async function optimizeSvg(svg, path) {
const result = optimize(svg, {
path,
plugins: [
{
name: 'preset-default',
@@ -17,12 +18,15 @@ async function optimizeSvg(svg) {
overrides: {
convertShapeToPath: false,
mergePaths: false,
removeAttrs: {
attrs: '(fill|stroke.*)',
},
},
},
},
{
name: 'removeAttrs',
params: {
attrs: '(fill|stroke.*)',
}
}
],
});
@@ -47,12 +51,12 @@ function setAttrs(svg) {
* @param {string} svg An SVG string.
* @returns {Promise<string>} An optimized svg
*/
function processSvg(svg) {
function processSvg(svg, path) {
return (
optimizeSvg(svg)
optimizeSvg(svg, path)
.then(setAttrs)
.then((optimizedSvg) =>
prettier.format(optimizedSvg, { parser: 'babel' }),
prettier.format(optimizedSvg, {parser: 'babel'}),
)
// remove semicolon inserted by prettier
// because prettier thinks it's formatting JSX not HTML