From 7f48e63695f0532d7d07465b59e260570d9b61c7 Mon Sep 17 00:00:00 2001 From: Nehuen Prados Date: Sat, 27 Jan 2024 21:33:43 -0300 Subject: [PATCH 1/3] Fix Bug #1946 Optimize a large number of vectors sequentially instead of parallel to avoid the simultaneously opened file limit --- lib/svgo/coa.js | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/lib/svgo/coa.js b/lib/svgo/coa.js index 4b434fe5c..3fa48a851 100644 --- a/lib/svgo/coa.js +++ b/lib/svgo/coa.js @@ -303,20 +303,27 @@ function optimizeFolder(config, dir, output) { function processDirectory(config, dir, files, output) { // take only *.svg files, recursively if necessary var svgFilesDescriptions = getFilesDescriptions(config, dir, files, output); - - return svgFilesDescriptions.length - ? Promise.all( - svgFilesDescriptions.map((fileDescription) => - optimizeFile( - config, - fileDescription.inputPath, - fileDescription.outputPath, - ), - ), - ) - : Promise.reject( - new Error(`No SVG files have been found in '${dir}' directory.`), - ); + + if ( svgFilesDescriptions.length == 0 ) { + return Promise.reject(new Error('No SVG files have been found in "' + dir + '" directory.')); + } + + var semaphore = Promise.resolve([ ]); + + svgFilesDescriptions.reduce(function(semaphore, fileDescription) { + return semaphore.then(function(results) { + return optimizeFile( + config, + fileDescription.inputPath, + fileDescription.outputPath, + ).then(function(result) { + results.push(result); + return results; + }); + }); + }, semaphore); + + return semaphore; } /** From 2f0b079c77abb9253716bf52f81145dd1e665f03 Mon Sep 17 00:00:00 2001 From: Nehuen Prados Date: Wed, 31 Jan 2024 17:37:41 -0300 Subject: [PATCH 2/3] Update coa.js like suggeted comments --- lib/svgo/coa.js | 55 ++++++++++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/lib/svgo/coa.js b/lib/svgo/coa.js index 3fa48a851..c61fb9e46 100644 --- a/lib/svgo/coa.js +++ b/lib/svgo/coa.js @@ -1,14 +1,13 @@ -import fs from 'fs'; -import path from 'path'; -import colors from 'picocolors'; -import { fileURLToPath } from 'url'; -import { encodeSVGDatauri, decodeSVGDatauri } from './tools.js'; -import { loadConfig, optimize } from '../svgo-node.js'; -import { builtin } from '../builtin.js'; - -const __dirname = path.dirname(fileURLToPath(import.meta.url)); -const pkgPath = path.join(__dirname, '../../package.json'); -const PKG = JSON.parse(fs.readFileSync(pkgPath, 'utf-8')); +'use strict'; + +const fs = require('fs'); +const os = require('os'); +const path = require('path'); +const colors = require('picocolors'); +const { loadConfig, optimize } = require('../svgo-node.js'); +const { builtin } = require('../builtin.js'); +const PKG = require('../../package.json'); +const { encodeSVGDatauri, decodeSVGDatauri } = require('./tools.js'); const regSVGFile = /\.svg$/i; @@ -17,7 +16,7 @@ const regSVGFile = /\.svg$/i; * * @param {string} path */ -export function checkIsDir(path) { +function checkIsDir(path) { try { return fs.lstatSync(path).isDirectory(); } catch (e) { @@ -25,7 +24,7 @@ export function checkIsDir(path) { } } -export default function makeProgram(program) { +module.exports = function makeProgram(program) { program .name(PKG.name) .description(PKG.description, { @@ -79,7 +78,7 @@ export default function makeProgram(program) { // used by picocolors internally .option('--no-color', 'Output plain text without color') .action(action); -} +}; async function action(args, opts, command) { var input = opts.input || args; @@ -300,30 +299,32 @@ function optimizeFolder(config, dir, output) { * @param {string} output output directory * @return {Promise} */ -function processDirectory(config, dir, files, output) { +async function processDirectory(config, dir, files, output) { // take only *.svg files, recursively if necessary var svgFilesDescriptions = getFilesDescriptions(config, dir, files, output); if ( svgFilesDescriptions.length == 0 ) { - return Promise.reject(new Error('No SVG files have been found in "' + dir + '" directory.')); + throw 'No SVG files have been found in "' + dir + '" directory.'; } - var semaphore = Promise.resolve([ ]); - - svgFilesDescriptions.reduce(function(semaphore, fileDescription) { - return semaphore.then(function(results) { + let results = [ ], + cpus = os.cpus().length; + + while ( svgFilesDescriptions.length > 0 ) { + let _svgFilesDescriptions = svgFilesDescriptions.splice(0, cpus); + + _svgFilesDescriptions = _svgFilesDescriptions.map(function(fileDescription) { return optimizeFile( config, fileDescription.inputPath, fileDescription.outputPath, - ).then(function(result) { - results.push(result); - return results; - }); + ); }); - }, semaphore); + + results = results.concat(await Promise.all(_svgFilesDescriptions)); + } - return semaphore; + return results; } /** @@ -533,3 +534,5 @@ function showAvailablePlugins() { .join('\n'); console.log('Currently available plugins:\n' + list); } + +module.exports.checkIsDir = checkIsDir; From a44b12569bfa39551d607f3ae95e7b98d28585a1 Mon Sep 17 00:00:00 2001 From: Nehuen Prados Date: Wed, 31 Jan 2024 17:44:41 -0300 Subject: [PATCH 3/3] Revert changes over import --- lib/svgo/coa.js | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/lib/svgo/coa.js b/lib/svgo/coa.js index c61fb9e46..37a44ae56 100644 --- a/lib/svgo/coa.js +++ b/lib/svgo/coa.js @@ -1,13 +1,15 @@ -'use strict'; - -const fs = require('fs'); -const os = require('os'); -const path = require('path'); -const colors = require('picocolors'); -const { loadConfig, optimize } = require('../svgo-node.js'); -const { builtin } = require('../builtin.js'); -const PKG = require('../../package.json'); -const { encodeSVGDatauri, decodeSVGDatauri } = require('./tools.js'); +import fs from 'fs'; +import os from 'os'; +import path from 'path'; +import colors from 'picocolors'; +import { fileURLToPath } from 'url'; +import { encodeSVGDatauri, decodeSVGDatauri } from './tools.js'; +import { loadConfig, optimize } from '../svgo-node.js'; +import { builtin } from '../builtin.js'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const pkgPath = path.join(__dirname, '../../package.json'); +const PKG = JSON.parse(fs.readFileSync(pkgPath, 'utf-8')); const regSVGFile = /\.svg$/i; @@ -16,7 +18,7 @@ const regSVGFile = /\.svg$/i; * * @param {string} path */ -function checkIsDir(path) { +export function checkIsDir(path) { try { return fs.lstatSync(path).isDirectory(); } catch (e) { @@ -24,7 +26,7 @@ function checkIsDir(path) { } } -module.exports = function makeProgram(program) { +export default function makeProgram(program) { program .name(PKG.name) .description(PKG.description, { @@ -78,7 +80,7 @@ module.exports = function makeProgram(program) { // used by picocolors internally .option('--no-color', 'Output plain text without color') .action(action); -}; +} async function action(args, opts, command) { var input = opts.input || args; @@ -534,5 +536,3 @@ function showAvailablePlugins() { .join('\n'); console.log('Currently available plugins:\n' + list); } - -module.exports.checkIsDir = checkIsDir;