Skip to content

Commit d94c3aa

Browse files
CxResadamreisnz
authored andcommitted
Callback for from (#46)
* Callback for `from` Added a callback for `from`, which takes file as an argument. Allows the user to tailor the search string according to the filename. * Minor Changes to Callback for `from` Additional comments to explain the callback forms. Reversed minor version bump. * Changes to documentation for `to` callback Reverted to original `to` callback example. Added a separate example example for using the `file` argument.
1 parent 015571a commit d94c3aa

File tree

3 files changed

+81
-1
lines changed

3 files changed

+81
-1
lines changed

README.md

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ A simple utility to quickly replace text in one or more files or globs. Works sy
2323
- [Replace all occurrences](#replace-all-occurrences)
2424
- [Multiple values with the same replacement](#multiple-values-with-the-same-replacement)
2525
- [Multiple values with different replacements](#multiple-values-with-different-replacements)
26+
- [Using callbacks for `from`](#using-callbacks-for-from)
2627
- [Using callbacks for `to`](#using-callbacks-for-to)
2728
- [Ignore a single file or glob](#ignore-a-single-file-or-glob)
2829
- [Ignore multiple files or globs](#ignore-multiple-files-or-globs)
@@ -191,8 +192,19 @@ const options = {
191192
};
192193
```
193194

195+
### Using callbacks for `from`
196+
You can also specify a callback that returns a string or a regular expression. The callback receives the name of the file in which the replacement is being performed, thereby allowing the user to tailor the search string. The following example uses a callback to produce a search string dependent on the filename:
197+
198+
```js
199+
const options = {
200+
files: 'path/to/file',
201+
from: (file) => RegExp(`${foo('SomePattern[A-Za-z-]+', file)}`, g);,
202+
to: 'bar',
203+
};
204+
```
205+
194206
### Using callbacks for `to`
195-
As the `to` parameter is passed straight to the native [String replace method](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace), you can also specify a callback. The following example uses a callback to convert matching strings to lowercase:
207+
As the `to` parameter is passed to the native [String replace method](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace), you can also specify a callback. The following example uses a callback to convert matching strings to lowercase:
196208

197209
```js
198210
const options = {
@@ -202,6 +214,19 @@ const options = {
202214
};
203215
```
204216

217+
This callback provides for an extra argument above the String replace method, which is the name of the file in which the replacement is being performed. The following example replaces the matched string with the filename:
218+
219+
```js
220+
const options = {
221+
files: 'path/to/file',
222+
from: /SomePattern[A-Za-z-]+/g,
223+
to: (...args) => {
224+
const file = args.pop();
225+
return file;
226+
},
227+
};
228+
```
229+
205230
### Ignore a single file or glob
206231

207232
```js

lib/helpers/make-replacements.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ module.exports = function makeReplacements(contents, from, to, file) {
2828

2929
//Make replacements
3030
from.forEach((item, i) => {
31+
//`from` callback is called with a filename argument
32+
//and returns string or regexp
33+
if (typeof item === 'function') {
34+
item = item(file);
35+
}
3136

3237
//Get replacement value
3338
let replacement = getReplacement(to, isArray, i);
@@ -36,6 +41,7 @@ module.exports = function makeReplacements(contents, from, to, file) {
3641
}
3742
if (typeof replacement === 'function') {
3843
const original = replacement;
44+
//`to` callback is called with an additional filename argument
3945
replacement = (...args) => original(...args, file);
4046
}
4147

lib/replace-in-file.spec.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,23 @@ describe('Replace in file', () => {
8282
});
8383
});
8484

85+
it('should pass file as an arg to a "from" function', done => {
86+
replace({
87+
files: 'test1',
88+
from: (file) => {
89+
expect(file).to.equal('test1');
90+
return /re\splace/g;
91+
},
92+
to: 'b'
93+
}).then(() => {
94+
const test1 = fs.readFileSync('test1', 'utf8');
95+
const test2 = fs.readFileSync('test2', 'utf8');
96+
expect(test1).to.equal('a b c');
97+
expect(test2).to.equal(testData);
98+
done();
99+
});
100+
});
101+
85102
it('should pass the match as first arg and file as last arg to a replacer function replace contents in a single file with regex', done => {
86103
replace({
87104
files: 'test1',
@@ -392,6 +409,23 @@ describe('Replace in file', () => {
392409
});
393410
});
394411

412+
it('should pass file as an arg to a "from" function', done => {
413+
replace({
414+
files: 'test1',
415+
from: (file) => {
416+
expect(file).to.equal('test1');
417+
return /re\splace/g;
418+
},
419+
to: 'b'
420+
}, () => {
421+
const test1 = fs.readFileSync('test1', 'utf8');
422+
const test2 = fs.readFileSync('test2', 'utf8');
423+
expect(test1).to.equal('a b c');
424+
expect(test2).to.equal(testData);
425+
done();
426+
});
427+
});
428+
395429
it('should pass the match as first arg and file as last arg to a replacer function replace contents in a single file with regex', done => {
396430
replace({
397431
files: 'test1',
@@ -708,6 +742,21 @@ describe('Replace in file', () => {
708742
expect(test2).to.equal(testData);
709743
});
710744

745+
it('should pass file as an arg to a "from" function', function() {
746+
replace.sync({
747+
files: 'test1',
748+
from: (file) => {
749+
expect(file).to.equal('test1');
750+
return /re\splace/g;
751+
},
752+
to: 'b'
753+
});
754+
const test1 = fs.readFileSync('test1', 'utf8');
755+
const test2 = fs.readFileSync('test2', 'utf8');
756+
expect(test1).to.equal('a b c');
757+
expect(test2).to.equal(testData);
758+
});
759+
711760
it('should pass the match as first arg and file as last arg to a replacer function replace contents in a single file with regex', function() {
712761
replace.sync({
713762
files: 'test1',

0 commit comments

Comments
 (0)