Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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',
]
};
```

Expand Down Expand Up @@ -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.
Expand Down
15 changes: 13 additions & 2 deletions bin/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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
Expand Down Expand Up @@ -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;
}
Expand Down
17 changes: 11 additions & 6 deletions lib/replace-in-file.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const chalk = require('chalk');
const defaults = {
allowEmptyPaths: false,
encoding: 'utf-8',
ignore: []
};

/**
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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);
Expand Down
30 changes: 30 additions & 0 deletions lib/replace-in-file.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down Expand Up @@ -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',
Expand Down