├── .gitignore ├── bin └── grunt-remove-logging ├── example ├── js │ ├── output.js │ └── app.js └── Gruntfile.js ├── test ├── tests.txt └── test.js ├── Gruntfile.js ├── package.json ├── LICENSE-MIT ├── tasks ├── lib │ └── removelogging.js └── grunt-remove-logging.js └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | examples/js/output.js 3 | -------------------------------------------------------------------------------- /bin/grunt-remove-logging: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | require("grunt").npmTasks("grunt-remove-logging").cli(); 3 | -------------------------------------------------------------------------------- /example/js/output.js: -------------------------------------------------------------------------------- 1 | if(true) { 2 | 3 | 4 | 5 | 6 | console.log("except for this one!");/*RemoveLogging:skip*/ 7 | } 8 | -------------------------------------------------------------------------------- /example/js/app.js: -------------------------------------------------------------------------------- 1 | if(true) { 2 | console.log("These"); 3 | console.warn('console'); 4 | console.error('statements'); 5 | console.dir({ will: be, removed: "true" }); 6 | console.log("except for this one!");/*RemoveLogging:skip*/ 7 | } 8 | -------------------------------------------------------------------------------- /example/Gruntfile.js: -------------------------------------------------------------------------------- 1 | /*global module:false*/ 2 | module.exports = function(grunt) { 3 | "use strict"; 4 | 5 | grunt.loadTasks("../tasks"); 6 | 7 | grunt.initConfig({ 8 | removelogging: { 9 | dist: { 10 | src: "js/app.js", 11 | dest: "js/output.js" 12 | } 13 | } 14 | }); 15 | 16 | grunt.registerTask("default", ["removelogging"]); 17 | }; 18 | -------------------------------------------------------------------------------- /test/tests.txt: -------------------------------------------------------------------------------- 1 | console.log("foo"); 2 | console.warn("foo"); console.log("bar"); 3 | console.trace(); 4 | console.error("foo", 'bar', baz); 5 | console.log("foo") 6 | 7 | console.warn('foo'); 8 | console.log(foo); 9 | console.warn([foo]); 10 | console.log("(foo)"); 11 | foo1 console.log(foo); foo2 12 | foo1 console.log(foo);foo2; 13 | 14 | foo1 this.log(foo);bar; 15 | foo2;that.log(bar);foo; 16 | 17 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | 3 | // Project configuration. 4 | grunt.initConfig({ 5 | nodeunit: { 6 | all: ["test/**/*.js"] 7 | }, 8 | watch: { 9 | files: "", 10 | tasks: "default" 11 | }, 12 | jshint: { 13 | all: ["grunt.js", "tasks/**/*.js", "test/**/*.js"], 14 | options: { 15 | curly: true, 16 | eqeqeq: true, 17 | immed: true, 18 | latedef: true, 19 | newcap: true, 20 | noarg: true, 21 | sub: true, 22 | undef: true, 23 | boss: true, 24 | eqnull: true, 25 | node: true, 26 | globals: {} 27 | } 28 | } 29 | }); 30 | 31 | grunt.loadNpmTasks("grunt-contrib-jshint"); 32 | grunt.loadNpmTasks("grunt-contrib-nodeunit"); 33 | 34 | grunt.registerTask("default", ["jshint", "nodeunit"]); 35 | }; 36 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name" : "grunt-remove-logging", 3 | "description" : "Grunt task to remove console logging statements", 4 | "version" : "0.2.1", 5 | "homepage" : "", 6 | "author" : { 7 | "name" : "Eric Hynds", 8 | "email" : "ehynds@gmail.com", 9 | "url" : "http://erichynds.com" 10 | }, 11 | "contributors": { 12 | "name": "Thomas Welton", 13 | "email": "thomaswelton@me.com", 14 | "url": "https://github.com/thomaswelton" 15 | }, 16 | "repository" : { 17 | "type" : "git", 18 | "url" : "git://github.com/ehynds/grunt-remove-logging.git" 19 | }, 20 | "bugs" : { 21 | "url" : "https://github.com/ehynds/grunt-remove-logging/issues" 22 | }, 23 | "main" : "grunt.js", 24 | "bin" : "bin/grunt-remove-logging", 25 | "engines" : { 26 | "node" : "*" 27 | }, 28 | "scripts" : { 29 | "test" : "grunt test" 30 | }, 31 | "devDependencies" : { 32 | "grunt" : "~0.4.2", 33 | "grunt-contrib-jshint": "~0.7.2", 34 | "grunt-contrib-nodeunit": "~0.2.2" 35 | }, 36 | "keywords" : [ 37 | "gruntplugin", "console", "log", "debugging", "remove", "statements" 38 | ] 39 | } 40 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Eric Hynds & contributors 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /tasks/lib/removelogging.js: -------------------------------------------------------------------------------- 1 | exports.init = function(grunt) { 2 | "use strict"; 3 | 4 | var _ = grunt.util._; 5 | 6 | return function(src, opts) { 7 | var counter = 0; 8 | var rConsole; 9 | 10 | // Use console as the default namespace 11 | if(!("namespace" in opts)) { 12 | opts.namespace = [ "console", "window.console" ]; 13 | } 14 | 15 | // Default methods 16 | if(!("methods" in opts) || !_.isArray(opts.methods)) { 17 | opts.methods = "log info warn error assert count clear group groupEnd groupCollapsed trace debug dir dirxml profile profileEnd time timeEnd timeStamp table exception".split(" "); 18 | } 19 | 20 | if(!("verbose" in opts)) { 21 | opts.verbose = true; 22 | } 23 | 24 | rConsole = new RegExp("(" + opts.namespace.join("|") + ")" + ".(?:" + opts.methods.join("|") + ")\\s{0,}\\([^;]*\\)(?!\\s*[;,]?\\s*\\/\\*\\s*RemoveLogging:skip\\s*\\*\\/)\\s{0,};?", "gi"); 25 | 26 | src = src.replace(rConsole, function() { 27 | counter++; 28 | return opts.replaceWith || ""; 29 | }); 30 | 31 | return { 32 | src: src, 33 | count: counter 34 | }; 35 | }; 36 | }; 37 | -------------------------------------------------------------------------------- /tasks/grunt-remove-logging.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Grunt Remove Logging 3 | * https://github.com/ehynds/grunt-remove-logging 4 | * 5 | * Copyright (c) 2013 Eric Hynds 6 | * Licensed under the MIT license. 7 | */ 8 | 9 | module.exports = function(grunt) { 10 | "use strict"; 11 | 12 | var task = require("./lib/removelogging").init(grunt); 13 | 14 | grunt.registerMultiTask("removelogging", "Remove console logging", function() { 15 | var opts = this.options(); 16 | 17 | var statementCount = 0, fileCount = 0; 18 | 19 | var process = function(srcFile) { 20 | var result = task(grunt.file.read(srcFile), opts); 21 | statementCount += result.count; 22 | fileCount++; 23 | if (opts.verbose) { 24 | grunt.log.writeln("Removed " + result.count + " logging statements from " + srcFile); 25 | } 26 | return result; 27 | }; 28 | 29 | this.files.forEach(function(f) { 30 | if(typeof f.dest === "undefined") { 31 | f.src.forEach(function(srcFile) { 32 | var result = process(srcFile); 33 | grunt.file.write(srcFile, result.src); 34 | }); 35 | } else { 36 | var ret = f.src.map(function(srcFile) { 37 | if(grunt.file.isFile(srcFile)){ 38 | return process(srcFile).src; 39 | } else { 40 | grunt.log.error("File not found " + srcFile); 41 | } 42 | }).join(""); 43 | 44 | if(ret) { 45 | grunt.file.write(f.dest, ret); 46 | } 47 | } 48 | }); 49 | 50 | if (!opts.verbose) { 51 | grunt.log.writeln("Checked " + fileCount + " files, removed " + statementCount + " logging statements"); 52 | } 53 | }); 54 | }; 55 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## About 2 | 3 | This task removes all console logging statements from your source code. 4 | 5 | ## Getting Started 6 | 7 | Install this plugin with the command: 8 | 9 | ```js 10 | npm install grunt-remove-logging 11 | ``` 12 | 13 | Next, add this line to your project's grunt file: 14 | 15 | ```js 16 | grunt.loadNpmTasks("grunt-remove-logging"); 17 | ``` 18 | 19 | Lastly, add the configuration settings (see below) to your grunt file. 20 | 21 | ## Documentation 22 | 23 | This task has two required properties, `src` and `dest`. `src` is the path to 24 | your source file and `dest` is the file this task will write to (relative to the 25 | grunt.js file). 26 | 27 | An example configuration looks like this: 28 | 29 | ```js 30 | grunt.initConfig({ 31 | removelogging: { 32 | dist: { 33 | src: "js/application.js", 34 | dest: "js/application-clean.js", 35 | 36 | options: { 37 | // see below for options. this is optional. 38 | } 39 | } 40 | } 41 | }); 42 | ``` 43 | 44 | To run this task against multiple files and **automatically overwrite them** 45 | with the resultant output, omit the `dest` option: 46 | 47 | ```js 48 | grunt.initConfig({ 49 | removelogging: { 50 | dist: { 51 | src: "dist/**/*.js" // Each file will be overwritten with the output! 52 | } 53 | } 54 | }); 55 | ``` 56 | 57 | ### Optional Configuration Properties 58 | 59 | This plugin can be customized by specifying the following options: 60 | 61 | * `replaceWith`: A value to replace logging statements with. This option defaults to an empty string. If you use fancy statements like `console && console.log("foo");`, you may choose to specify a `replaceWith` value like `0;` so that your scripts don't completely break. 62 | * `namespace`: An array of object names that logging methods are attached to. 63 | Defaults to `[ 'console', 'window.console' ]`. If you use a custom logger, like 64 | `MyApp.logger.log(foo)`, you would set this option to `[MyApp.logger]`. 65 | * `methods`: An array of method names to remove. Defaults to [all the methods](http://getfirebug.com/wiki/index.php/Console_API) in the Firebug console API. This option is useful if you want to strip out all `log` methods, but keep `warn` for example. 66 | * `verbose`: Boolean value, whether to show count of logging statements removed for each file. Defaults to true. If false, a single summary line is logged to grunt instead. 67 | 68 | ### Skipping Individual Statements 69 | 70 | You can tell this task to keep specific logging statements by adding the comment directive `/*RemoveLogging:skip*/` after the statement: 71 | 72 | ```js 73 | console.log("foo");/*RemoveLogging:skip*/ 74 | 75 | // or: 76 | 77 | console.log("foo")/*RemoveLogging:skip*/; 78 | 79 | // whitespace is fine too, whatever floats your boat: 80 | 81 | console.log("foo") /* RemoveLogging:skip */; 82 | ``` 83 | -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var grunt = require("grunt"); 4 | var task = require("../tasks/lib/removelogging").init(grunt); 5 | var async = grunt.util.async; 6 | 7 | // each item in the array is a test. 8 | // the convention is: 9 | // [ 10 | // string to test, 11 | // options to pass to the remove_logging helper 12 | // expected result 13 | // ] 14 | var tests = [ 15 | [ 16 | 'console.log(foo); bar; console.warn("bar")', 17 | {}, 18 | " bar; " 19 | ], 20 | [ 21 | 'console.dir({ complex: "objects" }, [ "array" ])', 22 | {}, 23 | "" 24 | ], 25 | [ 26 | 'console.log("foo (inner parens)")', 27 | {}, 28 | "" 29 | ], 30 | [ 31 | 'console.log("foo (inner parens)");foo;console.warn("(lol)")', 32 | {}, 33 | "foo;" 34 | ], 35 | [ 36 | ';if(true){functionCall(function namedFun(){console.log("test", args);})};for(var x=1;x