mirror of
https://github.com/svg/svgo.git
synced 2025-07-31 07:44:22 +03:00
Fix reporting of config errors (#1342)
Errors are swallowed while resolving.
This commit is contained in:
6
bin/svgo
6
bin/svgo
@ -1,6 +1,10 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
const { red } = require('chalk');
|
||||||
const { program } = require('commander');
|
const { program } = require('commander');
|
||||||
const makeProgram = require('../lib/svgo/coa');
|
const makeProgram = require('../lib/svgo/coa');
|
||||||
makeProgram(program);
|
makeProgram(program);
|
||||||
program.parseAsync(process.argv);
|
program.parseAsync(process.argv).catch(error => {
|
||||||
|
console.error(red(error.stack));
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
|
@ -10,19 +10,26 @@ const {
|
|||||||
|
|
||||||
const importConfig = async configFile => {
|
const importConfig = async configFile => {
|
||||||
try {
|
try {
|
||||||
const config = require(configFile);
|
await fs.promises.access(configFile);
|
||||||
if (config == null || typeof config !== 'object' || Array.isArray(config)) {
|
} catch {
|
||||||
throw Error(`Invalid config file "${configFile}"`);
|
return null;
|
||||||
}
|
|
||||||
return config;
|
|
||||||
} catch (error) {
|
|
||||||
if (error.code === 'MODULE_NOT_FOUND') {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
throw error;
|
|
||||||
}
|
}
|
||||||
|
const config = require(configFile);
|
||||||
|
if (config == null || typeof config !== 'object' || Array.isArray(config)) {
|
||||||
|
throw Error(`Invalid config file "${configFile}"`);
|
||||||
|
}
|
||||||
|
return config;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const isFile = async (file) => {
|
||||||
|
try {
|
||||||
|
const stats = await fs.promises.stat(file);
|
||||||
|
return stats.isFile();
|
||||||
|
} catch {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const loadConfig = async (configFile, cwd = process.cwd()) => {
|
const loadConfig = async (configFile, cwd = process.cwd()) => {
|
||||||
if (configFile != null) {
|
if (configFile != null) {
|
||||||
if (path.isAbsolute(configFile)) {
|
if (path.isAbsolute(configFile)) {
|
||||||
@ -33,13 +40,10 @@ const loadConfig = async (configFile, cwd = process.cwd()) => {
|
|||||||
}
|
}
|
||||||
let dir = cwd;
|
let dir = cwd;
|
||||||
while (true) {
|
while (true) {
|
||||||
try {
|
const file = path.join(dir, "svgo.config.js");
|
||||||
const file = path.join(dir, "svgo.config.js");
|
if (await isFile(file)) {
|
||||||
const stats = await fs.promises.stat(file);
|
return await importConfig(file);
|
||||||
if (stats.isFile()) {
|
}
|
||||||
return await importConfig(file);
|
|
||||||
}
|
|
||||||
} catch {}
|
|
||||||
const parent = path.dirname(dir);
|
const parent = path.dirname(dir);
|
||||||
if (dir === parent) {
|
if (dir === parent) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -9,7 +9,6 @@ const pluginsMap = require('../../plugins/plugins.js');
|
|||||||
const PKG = require('../../package.json');
|
const PKG = require('../../package.json');
|
||||||
const { encodeSVGDatauri, decodeSVGDatauri } = require('./tools.js');
|
const { encodeSVGDatauri, decodeSVGDatauri } = require('./tools.js');
|
||||||
const regSVGFile = /\.svg$/i;
|
const regSVGFile = /\.svg$/i;
|
||||||
const noop = () => {};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Synchronously check if path is a directory. Tolerant to errors like ENOENT.
|
* Synchronously check if path is a directory. Tolerant to errors like ENOENT.
|
||||||
@ -97,18 +96,14 @@ async function action(args, opts) {
|
|||||||
if (typeof process == 'object' && process.versions && process.versions.node && PKG && PKG.engines.node) {
|
if (typeof process == 'object' && process.versions && process.versions.node && PKG && PKG.engines.node) {
|
||||||
var nodeVersion = String(PKG.engines.node).match(/\d*(\.\d+)*/)[0];
|
var nodeVersion = String(PKG.engines.node).match(/\d*(\.\d+)*/)[0];
|
||||||
if (parseFloat(process.versions.node) < parseFloat(nodeVersion)) {
|
if (parseFloat(process.versions.node) < parseFloat(nodeVersion)) {
|
||||||
return printErrorAndExit(`Error: ${PKG.name} requires Node.js version ${nodeVersion} or higher.`);
|
throw Error(`${PKG.name} requires Node.js version ${nodeVersion} or higher.`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// --config
|
// --config
|
||||||
try {
|
const loadedConfig = await loadConfig(opts.config);
|
||||||
const loadedConfig = await loadConfig(opts.config);
|
if (loadedConfig != null) {
|
||||||
if (loadedConfig != null) {
|
config = loadedConfig;
|
||||||
config = loadedConfig;
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
return printErrorAndExit(error.message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// --quiet
|
// --quiet
|
||||||
@ -166,7 +161,7 @@ async function action(args, opts) {
|
|||||||
// --folder
|
// --folder
|
||||||
if (opts.folder) {
|
if (opts.folder) {
|
||||||
var ouputFolder = output && output[0] || opts.folder;
|
var ouputFolder = output && output[0] || opts.folder;
|
||||||
return optimizeFolder(config, opts.folder, ouputFolder).then(noop, printErrorAndExit);
|
await optimizeFolder(config, opts.folder, ouputFolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
// --input
|
// --input
|
||||||
@ -183,8 +178,9 @@ async function action(args, opts) {
|
|||||||
});
|
});
|
||||||
// file
|
// file
|
||||||
} else {
|
} else {
|
||||||
return Promise.all(input.map((file, n) => optimizeFile(config, file, output[n])))
|
await Promise.all(
|
||||||
.then(noop, printErrorAndExit);
|
input.map((file, n) => optimizeFile(config, file, output[n]))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// --string
|
// --string
|
||||||
@ -390,15 +386,4 @@ function showAvailablePlugins() {
|
|||||||
console.log('Currently available plugins:\n' + list);
|
console.log('Currently available plugins:\n' + list);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Write an error and exit.
|
|
||||||
* @param {Error} error
|
|
||||||
* @return {Promise} a promise for running tests
|
|
||||||
*/
|
|
||||||
function printErrorAndExit(error) {
|
|
||||||
console.error(chalk.red(error));
|
|
||||||
process.exit(1);
|
|
||||||
return Promise.reject(error); // for tests
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports.checkIsDir = checkIsDir;
|
module.exports.checkIsDir = checkIsDir;
|
||||||
|
@ -175,22 +175,18 @@ describe('coa', function() {
|
|||||||
if (!fs.existsSync(emptyFolderPath)) {
|
if (!fs.existsSync(emptyFolderPath)) {
|
||||||
fs.mkdirSync(emptyFolderPath);
|
fs.mkdirSync(emptyFolderPath);
|
||||||
}
|
}
|
||||||
replaceConsoleError();
|
|
||||||
try {
|
try {
|
||||||
await runProgram(['--folder', emptyFolderPath, '--quiet']);
|
await runProgram(['--folder', emptyFolderPath, '--quiet']);
|
||||||
} catch {} finally {
|
} catch (error) {
|
||||||
restoreConsoleError();
|
expect(error.message).to.match(/No SVG files/);
|
||||||
expect(output).to.match(/No SVG files/);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should show message when folder does not consists any svg files', async () => {
|
it('should show message when folder does not consists any svg files', async () => {
|
||||||
replaceConsoleError();
|
|
||||||
try {
|
try {
|
||||||
await runProgram(['--folder', path.resolve(__dirname, 'testFolderWithNoSvg'), '--quiet'])
|
await runProgram(['--folder', path.resolve(__dirname, 'testFolderWithNoSvg'), '--quiet'])
|
||||||
} catch {} finally {
|
} catch (error) {
|
||||||
restoreConsoleError();
|
expect(error.message).to.match(/No SVG files have been found/);
|
||||||
expect(output).to.match(/No SVG files have been found/);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -243,6 +243,27 @@ describe('config', function() {
|
|||||||
expect(error.message).to.match(/Invalid config file/);
|
expect(error.message).to.match(/Invalid config file/);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
it('handles config errors properly', async () => {
|
||||||
|
try {
|
||||||
|
await loadConfig(
|
||||||
|
null,
|
||||||
|
path.join(process.cwd(), './test/config/fixtures/invalid/config'),
|
||||||
|
);
|
||||||
|
expect.fail('Config is loaded successfully');
|
||||||
|
} catch (error) {
|
||||||
|
expect(error.message).to.match(/plugins is not defined/);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
it('handles MODULE_NOT_FOUND properly', async () => {
|
||||||
|
try {
|
||||||
|
await loadConfig(
|
||||||
|
path.join(process.cwd(), './test/config/fixtures/module-not-found.js'),
|
||||||
|
);
|
||||||
|
expect.fail('Config is loaded successfully');
|
||||||
|
} catch (error) {
|
||||||
|
expect(error.message).to.match(/Cannot find module 'unknown-module'/);
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
1
test/config/fixtures/invalid/svgo.config.js
Normal file
1
test/config/fixtures/invalid/svgo.config.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
module.exports = { plugins };
|
2
test/config/fixtures/module-not-found.js
Normal file
2
test/config/fixtures/module-not-found.js
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
require('unknown-module');
|
||||||
|
module.exports = {}
|
Reference in New Issue
Block a user