Fixes #43 - adds debug switch showing compression efficiency and time taken to minify.
authorGoalSmashers <jakub@goalsmashers.com>
Thu, 5 Sep 2013 08:44:34 +0000 (10:44 +0200)
committerGoalSmashers <jakub@goalsmashers.com>
Thu, 5 Sep 2013 09:39:12 +0000 (11:39 +0200)
History.md
README.md
bin/cleancss
test/binary-test.js

index 01b19b4..977f678 100644 (file)
@@ -1,6 +1,7 @@
 1.1.0 / 2013-xx-xx (UNRELEASED)
 ==================
 
+* Fixed issue [#43](https://github.com/GoalSmashers/clean-css/issues/43) - `--debug` switch for minification stats.
 * Fixed issue [#65](https://github.com/GoalSmashers/clean-css/issues/65) - full color name / hex shortening.
 * Fixed issue [#84](https://github.com/GoalSmashers/clean-css/issues/84) - support for `@import` with media queries.
 * Fixed issue [#124](https://github.com/GoalSmashers/clean-css/issues/124) - raise error on broken imports.
index daa393b..e7dd7b5 100644 (file)
--- a/README.md
+++ b/README.md
@@ -33,6 +33,7 @@ cleancss [options] <source-file>
 
 -h, --help                  Output usage information
 -v, --version               Output the version number
+-d, --debug                 Shows debug information (minification time & compression efficiency)
 -e, --remove-empty          Remove empty declarations (e.g. a{})
 -b, --keep-line-breaks      Keep line breaks
 --s0                        Remove all special comments (i.e. /*! special comment */)
index 5554efb..e241cd7 100755 (executable)
@@ -16,6 +16,7 @@ var isWindows = process.platform == 'win32';
 commands
   .version(buildVersion, '-v, --version')
   .usage('[options] <source-file>')
+  .option('-d, --debug', 'Shows debug information (minification time & compression efficiency)')
   .option('-e, --remove-empty', 'Remove empty declarations (e.g. a{})')
   .option('-b, --keep-line-breaks', 'Keep line breaks')
   .option('--s0', 'Remove all special comments (i.e. /*! special comment */)')
@@ -68,6 +69,8 @@ if (commands.root)
   cleanOptions.root = commands.root;
 if (commands.skipImport)
   cleanOptions.processImport = false;
+if (commands.debug)
+  options.debug = true;
 if (commands.args.length > 0) {
   var source = commands.args[0];
   options.source = source;
@@ -76,26 +79,43 @@ if (commands.args.length > 0) {
 
 // ... and do the magic!
 if (options.source) {
-  fs.readFile(options.source, 'utf8', function(error, text) {
+  fs.readFile(options.source, 'utf8', function(error, data) {
     if (error)
       throw error;
-    output(CleanCSS.process(text, cleanOptions));
+    output(minify(data));
   });
 } else {
   var stdin = process.openStdin();
   stdin.setEncoding('utf-8');
-  var text = '';
+  var data = '';
   stdin.on('data', function(chunk) {
-    text += chunk;
+    data += chunk;
   });
   stdin.on('end', function() {
-    output(CleanCSS.process(text, cleanOptions));
+    output(minify(data));
   });
 }
 
-function output(cleaned) {
+function minify(data) {
+  var minified;
+
+  if (options.debug) {
+    var start = process.hrtime();
+    minified = CleanCSS.process(data, cleanOptions);
+    var taken = process.hrtime(start);
+
+    console.error('Minification time: %dms', ~~(taken[0] * 1e3 + taken[1] / 1e6));
+    console.error('Compression efficiency: %d%', ~~((1 - minified.length / data.length) * 100));
+  } else {
+    minified = CleanCSS.process(data, cleanOptions);
+  }
+
+  return minified;
+}
+
+function output(minified) {
   if (options.target)
-    fs.writeFileSync(options.target, cleaned, 'utf8');
+    fs.writeFileSync(options.target, minified, 'utf8');
   else
-    process.stdout.write(cleaned);
+    process.stdout.write(minified);
 };
index e42a822..928eee2 100644 (file)
@@ -85,8 +85,32 @@ exports.commandsSuite = vows.describe('binary commands').addBatch({
     }
   }),
   'empty': pipedContext('a{}', '-e', {
-    'should preserve content': function(error, stdout) {
+    'should preserve content': function(error, stdout, stderr) {
+      assert.equal(stdout, '');
+      assert.equal(stderr, '');
+    }
+  }),
+  'piped with debug info': pipedContext('a{color:#f00}', '-d', {
+    'should output content to stdout and debug info to stderr': function(error, stdout, stderr) {
+      assert.equal(stdout, 'a{color:red}');
+      assert.notEqual(stderr, '');
+      assert.include(stderr, 'Minification time:');
+      assert.include(stderr, 'Compression efficiency:');
+    }
+  }),
+  'to output file with debug info': pipedContext('a{color:#f00}', '-d -o debug.css', {
+    'should output nothing to stdout and debug info to stderr': function(error, stdout, stderr) {
       assert.equal(stdout, '');
+      assert.notEqual(stderr, '');
+      assert.include(stderr, 'Minification time:');
+      assert.include(stderr, 'Compression efficiency:');
+    },
+    'should output content to file': function() {
+      var minimized = readFile('debug.css');
+      assert.equal(minimized, 'a{color:red}');
+    },
+    teardown: function() {
+      deleteFile('debug.css');
     }
   }),
   'no relative to path': binaryContext('./test/data/partials-absolute/base.css', {