From 1bad25828463c291cfeae858cba4b2f914962466 Mon Sep 17 00:00:00 2001 From: Fredrik Ekelund Date: Wed, 3 Feb 2016 11:51:33 +0100 Subject: [PATCH] Ability to handle directories as input When passed a folder as input, the program will attempt to recursively create a folder with the name specified in the `-o` option. Or if there is already a folder with the same name as the output location, the program will write each of the input files to that folder. If the input comes from stdin and the output location is a folder, a file named `htmlmin.html` will be saved in that folder. --- README.md | 19 +++++++++++- bin/htmlmin | 82 +++++++++++++++++++++++++++++++++++++++++++--------- package.json | 1 + 3 files changed, 88 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index c1c4347..c81c470 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,24 @@ Command-line interface for [html-minifier](http://kangax.github.io/html-minifier `npm install html-minifier-cli -g` ## Usage +See `htmlmin -h` for full details. +### Examples +Read from `index.html` and write to `index.min.html`: `htmlmin -o index.min.html index.html` -See `htmlmin -h` for more usage. \ No newline at end of file +Read all files from `client/views` and write them to `public/views`: +`htmlmin -o public/views client/views` + +Read from `client/views/index.html` and write it to already existing folder +`public/views`: +`htmlmin -o public/views client/views/index.html` + +### Output +You can pass input either as a path to a file or a folder, or directly from +stdin. When passed a folder as input, the program will attempt to recursively +create a folder with the name specified in the `-o` option. Or if there is +already a folder with the same name as the output location, the program will +write each of the input files to that folder. If the input comes from stdin and +the output location is a folder, a file named `htmlmin.html` will be saved in +that folder. diff --git a/bin/htmlmin b/bin/htmlmin index d87eba3..dc030f2 100755 --- a/bin/htmlmin +++ b/bin/htmlmin @@ -1,14 +1,16 @@ #!/usr/bin/env node var fs = require('fs'); +var path = require('path'); var program = require('commander'); var through2 = require('through2'); var extend = require('xtend'); +var mkdirp = require('mkdirp'); var htmlmin = require('html-minifier'); program - .usage('[options] [file]') - .option('-o, --output ', 'Write output to this file instead of stdout') + .usage('[options] [file|folder]') + .option('-o, --output ', 'Write output to this file or folder instead of stdout') .option('-u, --unsafe', 'Enable unsafe compression options') .parse(process.argv); @@ -44,18 +46,72 @@ var minify = through2(function (chunk, enc, cb) { this.push(content); }); -var src; -if (program.args.length) { - src = fs.createReadStream(program.args[0], { encoding: 'utf8' }); -} else { - src = process.stdin; +function getInput (args, callback) { + if (args.length) { + fs.stat(args[0], function (error, stats) { + if (!stats) { + throw new Error("ENOENT, no such file or directory '" + args[0] + "'"); + } + + if (stats.isDirectory()) { + fs.readdir(args[0], function (error, files) { + var inputStreams = files.filter(function (file) { + return path.extname(file) === '.html'; + }).map(function (file) { + return fs.createReadStream(path.join(args[0], file)); + }); + + callback(undefined, inputStreams); + }); + } else { + callback(undefined, fs.createReadStream(args[0])); + } + }); + } else { + callback(undefined, process.stdin); + } } -var dest; -if (program.output) { - dest = fs.createWriteStream(program.output); -} else { - dest = process.stdout; +function getDest (filePath, outputToDir, callback) { + if (outputToDir && program.output) { + var dest = path.join(program.output, path.basename(filePath)); + + mkdirp(program.output, function (error) { + if (error) + throw error; + + callback(undefined, fs.createWriteStream(dest)); + }); + } else if (program.output) { + callback(undefined, fs.createWriteStream(program.output)); + } else { + callback(undefined, process.stdout); + } } -src.pipe(minify).pipe(dest); \ No newline at end of file +function writeOutput (streams, outputToDir) { + streams.forEach(function (stream) { + var filePath = stream.path || 'htmlmin.html'; + + getDest(filePath, outputToDir, function (error, dest) { + stream.pipe(minify).pipe(dest); + }); + }); +} + +getInput(program.args, function (error, src) { + var inputIsDir = Array.isArray(src); + var outputIsDir, outputToDir; + + src = !inputIsDir ? [src] : src; + + if (program.output) { + fs.stat(program.output, function (error, stats) { + outputIsDir = stats && stats.isDirectory(); + outputToDir = inputIsDir || outputIsDir; + writeOutput(src, outputToDir); + }); + } else { + writeOutput(src); + } +}); diff --git a/package.json b/package.json index c2faf73..28a30e0 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "dependencies": { "commander": "~2.1.0", "html-minifier": "~0.5.5", + "mkdirp": "^0.5.1", "through2": "~0.4.1", "xtend": "~2.1.2" },