Skip to content

Commit

Permalink
Merge 9ba4046 into a6d2c88
Browse files Browse the repository at this point in the history
  • Loading branch information
dartess committed Nov 13, 2017
2 parents a6d2c88 + 9ba4046 commit 3f3ed5d
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 19 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ bin/svgo-profiling
*.sublime-*
*.log
.DS_Store
.idea
.vscode
71 changes: 54 additions & 17 deletions lib/svgo/coa.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ require('colors');

var FS = require('fs'),
PATH = require('path'),
mkdirp = require('mkdirp'),
promisify = require('util.promisify'),
readdir = promisify(FS.readdir),
readFile = promisify(FS.readFile),
Expand All @@ -14,6 +15,7 @@ var FS = require('fs'),
PKG = require('../../package.json'),
encodeSVGDatauri = require('./tools.js').encodeSVGDatauri,
decodeSVGDatauri = require('./tools.js').decodeSVGDatauri,
checkIsDir = require('./tools.js').checkIsDir,
regSVGFile = /\.svg$/,
noop = () => {},
svgo;
Expand Down Expand Up @@ -120,6 +122,11 @@ module.exports = require('coa').Cmd()
return !isNaN(val) ? val : this.reject("Option '--indent' must be an integer number");
})
.end()
.opt()
.name('recursive').title('Use with \'-f\'. Optimizes *.svg files in folders recursively.')
.short('r').long('recursive')
.flag()
.end()
.opt()
.name('quiet').title('Only output error messages, not regular status messages')
.short('q').long('quiet')
Expand Down Expand Up @@ -198,6 +205,11 @@ module.exports = require('coa').Cmd()
config.quiet = opts.quiet;
}

// --recursive
if (opts.recursive) {
config.recursive = opts.recursive;
}

// --precision
if (opts.precision) {
var precision = Math.min(Math.max(0, parseInt(opts.precision)), 20);
Expand Down Expand Up @@ -358,13 +370,46 @@ function optimizeFolder(config, dir, output) {
* @return {Promise}
*/
function processDirectory(config, dir, files, output) {
// take only *.svg files
var svgFiles = files.filter(name => regSVGFile.test(name));
return svgFiles.length ?
Promise.all(svgFiles.map(name => optimizeFile(config, PATH.resolve(dir, name), PATH.resolve(output, name)))) :
// 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.`));
}

/**
* Get svg files descriptions
* @param {Object} config options
* @param {string} dir input directory
* @param {Array} files list of file names in the directory
* @param {string} output output directory
* @return {Array}
*/
function getFilesDescriptions(config, dir, files, output) {
const filesInThisFolder = files
.filter(name => regSVGFile.test(name))
.map(name => ({
inputPath: PATH.resolve(dir, name),
outputPath: PATH.resolve(output, name),
}));

return config.recursive ?
[
...filesInThisFolder,
...files
.filter(name => checkIsDir(PATH.resolve(dir, name)))
.map(subFolderName => {
const subFolderPath = PATH.resolve(dir, subFolderName);
const subFolderFiles = FS.readdirSync(subFolderPath);
const subFolderOutput = PATH.resolve(output, subFolderName);
return getFilesDescriptions(config, subFolderPath, subFolderFiles, subFolderOutput);
})
.reduce((a, b) => [...a, ...b], [])
] :
filesInThisFolder;
}

/**
* Read SVG file and pass to processing.
* @param {Object} config options
Expand Down Expand Up @@ -423,9 +468,13 @@ function writeOutput(input, output, data) {
console.log(data);
return Promise.resolve();
}

mkdirp.sync(PATH.dirname(output));

return writeFile(output, data, 'utf8').catch(error => checkWriteFileError(input, output, data, error));
}


/**
* Write a time taken by optimization.
* @param {number} time time in milliseconds.
Expand Down Expand Up @@ -483,18 +532,6 @@ function checkWriteFileError(input, output, data, error) {
}
}

/**
* Synchronously check if path is a directory. Tolerant to errors like ENOENT.
* @param {string} path
*/
function checkIsDir(path) {
try {
return FS.lstatSync(path).isDirectory();
} catch(e) {
return false;
}
}

/**
* Show list of available plugins with short description.
*/
Expand All @@ -518,4 +555,4 @@ function printErrorAndExit(error) {
console.error(error);
process.exit(1);
return Promise.reject(error); // for tests
}
}
15 changes: 15 additions & 0 deletions lib/svgo/tools.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
'use strict';

var FS = require('fs');

/**
* Encode plain SVG data string into Data URI string.
*
Expand Down Expand Up @@ -145,3 +147,16 @@ var removeLeadingZero = exports.removeLeadingZero = function(num) {
return strNum;

};


/**
* Synchronously check if path is a directory. Tolerant to errors like ENOENT.
* @param {string} path
*/
exports.checkIsDir = function(path) {
try {
return FS.lstatSync(path).isDirectory();
} catch(e) {
return false;
}
};
18 changes: 16 additions & 2 deletions test/coa/_index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ const fs = require('fs'),
path = require('path'),
svgPath = path.resolve(__dirname, 'test.svg'),
svgFolderPath = path.resolve(__dirname, 'testSvg'),
svgFolderPathRecursively = path.resolve(__dirname, 'testSvgRecursively'),
svgFiles = [path.resolve(__dirname, 'testSvg/test.svg'), path.resolve(__dirname, 'testSvg/test.1.svg')],
tempFolder = 'temp',
fse = require('fs-extra'),
checkIsDir = require('../../lib/svgo/tools.js').checkIsDir,
noop = () => {};

describe('coa', function() {
Expand Down Expand Up @@ -49,8 +51,10 @@ describe('coa', function() {
}

function calcFolderSvgWeight(folderPath) {
return fs.readdirSync(folderPath).reduce((initWeight, fileName) => (
initWeight + (/.svg/.test(fileName) ? fs.statSync(path.join(folderPath, fileName)).size : 0)
return fs.readdirSync(folderPath).reduce((initWeight, name) => (
initWeight +
(/.svg/.test(name) ? fs.statSync(path.join(folderPath, name)).size : 0) +
(checkIsDir(path.join(folderPath, name)) ? calcFolderSvgWeight(path.join(folderPath, name)) : 0)
), 0);
}

Expand Down Expand Up @@ -82,6 +86,16 @@ describe('coa', function() {
}, error => done(error));
});

it('should optimize folder recursively', function(done) {
const initWeight = calcFolderSvgWeight(svgFolderPathRecursively);

svgo({ folder: svgFolderPathRecursively, output: tempFolder, quiet: true, recursive: true }).then(function() {
const optimizedWeight = calcFolderSvgWeight(svgFolderPathRecursively);

done(optimizedWeight > 0 && initWeight <= optimizedWeight ? null : 'Folder was not optimized');
}, error => done(error));
});

it('should optimize file', function(done) {
const initialFileLength = fs.readFileSync(path.resolve(__dirname, 'test.svg')).length;

Expand Down
1 change: 1 addition & 0 deletions test/coa/testSvgRecursively/depth-1/depth-2/test.1.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions test/coa/testSvgRecursively/depth-1/depth-2/test.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions test/coa/testSvgRecursively/test.1.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions test/coa/testSvgRecursively/test.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 3f3ed5d

Please sign in to comment.