Skip to content

Commit

Permalink
Merge pull request #15229 from ckeditor/ck/15142
Browse files Browse the repository at this point in the history
Internal: Added support for the `--verify-only` flag in the `yarn run clean-up-svg-icons` script that checks if all SVG files are optimized.

Internal: Added SVG files validator on CI. Closes #15142.
  • Loading branch information
pomek authored Oct 25, 2023
2 parents 73f49bf + 2f4737e commit e08784c
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 25 deletions.
6 changes: 5 additions & 1 deletion .circleci/template.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ commands:
echo "Running full flow due to nightly build, despite detecting '[short flow]'."
exit 0
fi
if [[ "$COMMIT_MESSAGE" == *"[short flow]" ]]; then
echo "Skipping, because the commit message contains '[short flow]'."
circleci step halt
Expand Down Expand Up @@ -105,6 +105,10 @@ jobs:
when: always
name: Validate icons specified in "ckeditor5-metadata.json" files
command: node scripts/ci/validate-metadata-icons.js
- run:
when: always
name: Check if all SVG files are optimized
command: yarn run clean-up-svg-icons --verify-only
- run:
when: always
name: Validate manual test directories
Expand Down
114 changes: 90 additions & 24 deletions scripts/clean-up-svg-icons.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,37 @@
// Cleans up and optimizes SVG files using the SVGO utility. The configuration file is located in svgo.config.json.
//
// Usage:
// yarn run clean-up-svg-icons <path/to/icons>
// yarn run clean-up-svg-icons [<option>...] [<path>...]
//
// yarn run clean-up-svg-icons <path/to/icons> <another/path/to/icons>
//
// The <path/to/icons> can be either a direct path to a SVG file, or a path to a directory. Glob patterns in path are supported.
// The <path> can be either a direct path to a SVG file, or a path to a directory. Glob patterns in path are supported.
// Multiple arguments (paths) in one call are supported.
//
// To optimize the entire project run:
// yarn run clean-up-svg-icons
// Options:
// --verify-only
// If set, the script does not modify any SVG file, but it checks whether all files are already optimized.
// If any file is not optimized, the script ends with an error code.
//
// Examples:
// To optimize the entire project, run:
// yarn run clean-up-svg-icons
//
// To optimize single file, run:
// yarn run clean-up-svg-icons <path/to/icon>
//
// To optimize single directory, run:
// yarn run clean-up-svg-icons <path/to/directory>
//
// To optimize multiple directories, run:
// yarn run clean-up-svg-icons <path/to/directory> <another/path/to/directory>
//
// To check if single file is already optimized, run:
// yarn run clean-up-svg-icons --verify-only <path/to/icon>

'use strict';

const chalk = require( 'chalk' );
const upath = require( 'upath' );
const fs = require( 'fs-extra' );
const minimist = require( 'minimist' );
const { globSync } = require( 'glob' );
const { execSync } = require( 'child_process' );
Expand All @@ -38,33 +55,82 @@ const EXCLUDED_ICONS = [
// A pattern to match all the icons.
const ALL_ICONS_PATTERN = 'packages/**/theme/icons';

const globPattern = parseArguments( process.argv.slice( 2 ) )
.map( pathToIcon => pathToIcon.endsWith( '.svg' ) ? pathToIcon : pathToIcon + '/*.svg' );
const { paths, verifyOnly } = parseArguments( process.argv.slice( 2 ) );

const globPattern = paths.map( pathToIcon => {
return pathToIcon.endsWith( '.svg' ) ? pathToIcon : pathToIcon + '/*.svg';
} );

let statusCode = 0;

globSync( globPattern )
.map( upath.toUnix )
.filter( pathToIcon => {
const iconName = upath.basename( pathToIcon );
const isExcluded = EXCLUDED_ICONS.includes( iconName );
.filter( filterExcludedIcons )
.forEach( processIcon );

if ( verifyOnly && statusCode ) {
console.log( chalk.red.bold( '\nSome SVG files are not optimized.' ) );
console.log( chalk.red(
'Execute "yarn run clean-up-svg-icons" to optimize them or add them to exceptions in "scripts/clean-up-svg-icons.js" file.\n'
) );

process.exit( statusCode );
}

function parseArguments( args ) {
const config = {
boolean: [
'verify-only'
],

if ( isExcluded ) {
console.log( chalk.yellow( `The "${ pathToIcon }" icon is excluded.` ) );
default: {
'verify-only': false
}
};

return !isExcluded;
} )
.forEach( pathToIcon => {
console.log( chalk.green( `Processing "${ pathToIcon }" icon...` ) );
const {
'verify-only': verifyOnly,
_: paths
} = minimist( args, config );

execSync( `svgo --config=./scripts/svgo.config.js -i ${ pathToIcon }` );
} );
return {
verifyOnly,
paths: paths.length > 0 ? paths : [ ALL_ICONS_PATTERN ]
};
}

function parseArguments( args ) {
const paths = minimist( args )._;
function filterExcludedIcons( pathToIcon ) {
const iconName = upath.basename( pathToIcon );
const isExcluded = EXCLUDED_ICONS.includes( iconName );

if ( paths.length > 0 ) {
return paths;
if ( isExcluded ) {
console.log( chalk.yellow( `The "${ pathToIcon }" icon is excluded.` ) );
}

return [ ALL_ICONS_PATTERN ];
return !isExcluded;
}

function processIcon( pathToIcon ) {
console.log( chalk.green( `Processing "${ pathToIcon }" icon...` ) );

const svgoOptions = [
'--config=./scripts/svgo.config.js',
`-i ${ pathToIcon }`
];

if ( verifyOnly ) {
svgoOptions.push( '-o -' );
}

const result = execSync( `svgo ${ svgoOptions.join( ' ' ) }`, { encoding: 'utf-8' } ).trim();

if ( verifyOnly ) {
const iconFile = fs.readFileSync( pathToIcon, 'utf-8' ).trim();

if ( result !== iconFile ) {
statusCode = 1;

console.log( chalk.red( `Icon "${ pathToIcon }" is not optimized.` ) );
}
}
}

0 comments on commit e08784c

Please sign in to comment.