diff --git a/README.md b/README.md index ad968c8..ed9a3e6 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,17 @@ const options = { //Character encoding for reading/writing files (defaults to utf-8) encoding: 'utf8', + + //Single file or glob to ignore + ignore: 'path/to/ignored/file', + + //Multiple files or globs to ignore + ignore: [ + 'path/to/ignored/file', + 'path/to/other/ignored_file', + 'path/to/ignored_files/*.html', + 'another/**/*.ignore', + ] }; ``` @@ -122,7 +133,7 @@ const changedFiles = replace.sync({ ### CLI usage ```sh -replace-in-file from to some/file.js,some/**/glob.js [--isRegex] +replace-in-file from to some/file.js,some/**/glob.js --ignore=ignore/files.js,ignore/**/glob.js [--isRegex] ``` The flags `allowEmptyPaths` and `encoding` are supported in the CLI. diff --git a/bin/cli.js b/bin/cli.js index e7320cf..46bef0e 100755 --- a/bin/cli.js +++ b/bin/cli.js @@ -16,7 +16,7 @@ if (argv._.length < 3 && !argv.config) { } //Prepare vars -let from, to, files; +let from, to, files, ignore; //If config is set, load config file if (argv.config) { @@ -41,6 +41,12 @@ if (argv.config) { config.files = [config.files]; } files = config.files; + + //Set ignore param + if (typeof config.ignore === 'string') { + config.ignore = [config.ignore]; + } + ignore = config.ignore; } //Get from/to parameters from CLI args if not defined in config file @@ -85,11 +91,16 @@ if (argv.isRegex) { } } +//Get ignored files from ignore flag +if (!ignore && typeof argv.ignore !== 'undefined') { + ignore = argv.ignore; +} + //Log console.log(`Replacing '${from}' with '${to}'`); //Create options -const options = {files, from, to}; +const options = {files, from, to, ignore}; if (typeof argv.encoding !== 'undefined') { options.encoding = argv.encoding; } diff --git a/lib/replace-in-file.js b/lib/replace-in-file.js index f2e7efc..2e88af1 100644 --- a/lib/replace-in-file.js +++ b/lib/replace-in-file.js @@ -13,6 +13,7 @@ const chalk = require('chalk'); const defaults = { allowEmptyPaths: false, encoding: 'utf-8', + ignore: [] }; /** @@ -155,9 +156,9 @@ function replaceAsync(file, from, to, enc) { /** * Promise wrapper for glob */ -function globPromise(pattern, allowEmptyPaths) { +function globPromise(pattern, ignore, allowEmptyPaths) { return new Promise((resolve, reject) => { - glob(pattern, {nodir: true}, (error, files) => { + glob(pattern, {ignore: ignore, nodir: true}, (error, files) => { //istanbul ignore if: hard to make glob error if (error) { @@ -192,17 +193,19 @@ function replaceInFile(config, cb) { } //Get config and globs - // const {files, from, to, allowEmptyPaths, encoding} = config; + // const {files, from, to, allowEmptyPaths, encoding, ignore} = config; const files = config.files; const from = config.from; const to = config.to; const encoding = config.encoding; const allowEmptyPaths = config.allowEmptyPaths; + const ignore = config.ignore; const globs = Array.isArray(files) ? files : [files]; + const ignoreGlobs = Array.isArray(ignore) ? ignore : [ignore]; //Find files return Promise - .all(globs.map(pattern => globPromise(pattern, allowEmptyPaths))) + .all(globs.map(pattern => globPromise(pattern, ignoreGlobs, allowEmptyPaths))) //Flatten array .then(files => [].concat.apply([], files)) @@ -247,18 +250,20 @@ replaceInFile.sync = function(config) { config = parseConfig(config); //Get config and globs - // const {files, from, to, encoding} = config; + // const {files, from, to, encoding, ignore} = config; const files = config.files; const from = config.from; const to = config.to; const encoding = config.encoding; + const ignore = config.ignore; const globs = Array.isArray(files) ? files : [files]; + const ignoreGlobs = Array.isArray(ignore) ? ignore : [ignore]; const changedFiles = []; //Process synchronously globs.forEach(pattern => { glob - .sync(pattern, {nodir: true}) + .sync(pattern, {ignore: ignoreGlobs, nodir: true}) .forEach(file => { if (replaceSync(file, from, to, encoding)) { changedFiles.push(file); diff --git a/lib/replace-in-file.spec.js b/lib/replace-in-file.spec.js index 35f16c2..19ac518 100644 --- a/lib/replace-in-file.spec.js +++ b/lib/replace-in-file.spec.js @@ -122,6 +122,21 @@ describe('Replace in file', () => { }); }); + it('should expand globs while excluding ignored files', done => { + replace({ + files: 'test*', + ignore: 'test1', + from: /re\splace/g, + to: 'b', + }).then(() => { + const test1 = fs.readFileSync('test1', 'utf8'); + const test2 = fs.readFileSync('test2', 'utf8'); + expect(test1).to.equal('a re place c'); + expect(test2).to.equal('a b c'); + done(); + }); + }); + it('should replace substrings', done => { replace({ files: 'test1', @@ -352,6 +367,21 @@ describe('Replace in file', () => { }); }); + it('should expand globs while excluding ignored files', done => { + replace({ + files: 'test*', + ignore: 'test1', + from: /re\splace/g, + to: 'b', + }, () => { + const test1 = fs.readFileSync('test1', 'utf8'); + const test2 = fs.readFileSync('test2', 'utf8'); + expect(test1).to.equal('a re place c'); + expect(test2).to.equal('a b c'); + done(); + }); + }); + it('should not return an error on success', done => { replace({ files: 'test1',