Skip to content

Commit 60e7b82

Browse files
committed
Add verbose option
1 parent 153dc27 commit 60e7b82

File tree

7 files changed

+103
-10
lines changed

7 files changed

+103
-10
lines changed

README.md

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ A simple utility to quickly replace text in one or more files or globs. Works sy
2929
- [Allow empty/invalid paths](#allow-emptyinvalid-paths)
3030
- [Disable globs](#disable-globs)
3131
- [Specify character encoding](#specify-character-encoding)
32+
- [Dry run](#dry-run)
3233
- [CLI usage](#cli-usage)
3334
- [Version information](#version-information)
3435
- [License](#license)
@@ -249,6 +250,15 @@ const options = {
249250
};
250251
```
251252

253+
### Dry run
254+
To do a dry run without actually making replacements, for testing purposes. Defaults to `false`.
255+
256+
```js
257+
const options = {
258+
dry: true,
259+
};
260+
```
261+
252262
## CLI usage
253263

254264
```sh
@@ -259,6 +269,7 @@ replace-in-file from to some/file.js,some/**/glob.js
259269
[--disableGlobs]
260270
[--isRegex]
261271
[--verbose]
272+
[--dry]
262273
```
263274

264275
Multiple files or globs can be replaced by providing a comma separated list.
@@ -268,7 +279,7 @@ The flags `--disableGlobs`, `--ignore` and `--encoding` are supported in the CLI
268279
The setting `allowEmptyPaths` is not supported in the CLI as the replacement is
269280
synchronous, and this setting is only relevant for asynchronous replacement.
270281

271-
To list the changed files, use the `--verbose` flag.
282+
To list the changed files, use the `--verbose` flag. To do a dry run, use `--dry`.
272283

273284
A regular expression may be used for the `from` parameter by specifying the `--isRegex` flag.
274285

@@ -278,9 +289,9 @@ information in a configuration file. You can provide a path to a configuration f
278289
Node’s built in `path.resolve()`, so you can pass in an absolute or relative path.
279290

280291
## Version information
281-
From version 3.0.0 onwards, replace in file requires Node 6 or higher. If you need support for Node 4 or 5, use version 2.x.x.
292+
From version 3.0.0 onwards, replace in file requires Node 6 or higher. If you need support for Node 4 or 5, please use version 2.x.x.
282293

283294
## License
284295
(MIT License)
285296

286-
Copyright 2015-2017, [Adam Reis](https://adam.reis.nz)
297+
Copyright 2015-2018, [Adam Reis](https://adam.reis.nz)

lib/helpers/combine-config.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ module.exports = function combineConfig(config, argv) {
1313
//Extract options from config
1414
let {
1515
from, to, files, ignore, encoding, verbose,
16-
allowEmptyPaths, disableGlobs, isRegex,
16+
allowEmptyPaths, disableGlobs, isRegex, dry,
1717
} = config;
1818

1919
//Get from/to parameters from CLI args if not defined in options
@@ -45,10 +45,13 @@ module.exports = function combineConfig(config, argv) {
4545
if (typeof verbose === 'undefined') {
4646
verbose = !!argv.verbose;
4747
}
48+
if (typeof dry === 'undefined') {
49+
dry = !!argv.dry;
50+
}
4851

4952
//Return through parser to validate
5053
return parseConfig({
5154
from, to, files, ignore, encoding, verbose,
52-
allowEmptyPaths, disableGlobs, isRegex,
55+
allowEmptyPaths, disableGlobs, isRegex, dry,
5356
});
5457
};

lib/helpers/parse-config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const defaults = {
1010
allowEmptyPaths: false,
1111
isRegex: false,
1212
verbose: false,
13+
dry: false,
1314
};
1415

1516
/**

lib/helpers/replace-async.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const makeReplacements = require('./make-replacements');
99
/**
1010
* Helper to replace in a single file (async)
1111
*/
12-
module.exports = function replaceAsync(file, from, to, enc) {
12+
module.exports = function replaceAsync(file, from, to, enc, dry) {
1313
return new Promise((resolve, reject) => {
1414
fs.readFile(file, enc, (error, contents) => {
1515
//istanbul ignore if
@@ -23,6 +23,11 @@ module.exports = function replaceAsync(file, from, to, enc) {
2323
return resolve({file, hasChanged: false});
2424
}
2525

26+
//Dry run, resolve
27+
if (dry) {
28+
return resolve({file, hasChanged: true});
29+
}
30+
2631
//Write to file
2732
fs.writeFile(file, newContents, enc, error => {
2833
//istanbul ignore if

lib/helpers/replace-sync.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const makeReplacements = require('./make-replacements');
99
/**
1010
* Helper to replace in a single file (sync)
1111
*/
12-
module.exports = function replaceSync(file, from, to, enc) {
12+
module.exports = function replaceSync(file, from, to, enc, dry) {
1313

1414
//Read contents
1515
const contents = fs.readFileSync(file, enc);
@@ -20,6 +20,11 @@ module.exports = function replaceSync(file, from, to, enc) {
2020
return false;
2121
}
2222

23+
//Dry run?
24+
if (dry) {
25+
return true;
26+
}
27+
2328
//Write to file
2429
fs.writeFileSync(file, newContents, enc);
2530
return true;

lib/replace-in-file.js

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
/**
44
* Dependencies
55
*/
6+
const chalk = require('chalk');
67
const parseConfig = require('./helpers/parse-config');
78
const getPathsSync = require('./helpers/get-paths-sync');
89
const getPathsAsync = require('./helpers/get-paths-async');
@@ -28,14 +29,20 @@ function replaceInFile(config, cb) {
2829
//Get config
2930
const {
3031
files, from, to, encoding, ignore, allowEmptyPaths, disableGlobs,
32+
dry, verbose,
3133
} = config;
3234

35+
//Dry run?
36+
if (dry && verbose) {
37+
console.log(chalk.yellow('Dry run, not making actual changes'));
38+
}
39+
3340
//Find paths
3441
return getPathsAsync(files, ignore, disableGlobs, allowEmptyPaths)
3542

3643
//Make replacements
3744
.then(paths => Promise.all(paths.map(file => {
38-
return replaceAsync(file, from, to, encoding);
45+
return replaceAsync(file, from, to, encoding, dry);
3946
})))
4047

4148
//Convert results to array of changed files
@@ -73,13 +80,20 @@ replaceInFile.sync = function(config) {
7380
config = parseConfig(config);
7481

7582
//Get config, paths, and initialize changed files
76-
const {files, from, to, encoding, ignore, disableGlobs} = config;
83+
const {
84+
files, from, to, encoding, ignore, disableGlobs, dry, verbose,
85+
} = config;
7786
const paths = getPathsSync(files, ignore, disableGlobs);
7887
const changedFiles = [];
7988

89+
//Dry run?
90+
if (dry && verbose) {
91+
console.log(chalk.yellow('Dry run, not making any changes'));
92+
}
93+
8094
//Process synchronously
8195
paths.forEach(path => {
82-
if (replaceSync(path, from, to, encoding)) {
96+
if (replaceSync(path, from, to, encoding, dry)) {
8397
changedFiles.push(path);
8498
}
8599
});

lib/replace-in-file.spec.js

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,35 @@ describe('Replace in file', () => {
298298
done();
299299
});
300300
});
301+
302+
it('should not replace in a dry run', done => {
303+
replace({
304+
files: ['test1', 'test2'],
305+
from: /re\splace/g,
306+
to: 'b',
307+
dry: true,
308+
}).then(() => {
309+
const test1 = fs.readFileSync('test1', 'utf8');
310+
const test2 = fs.readFileSync('test2', 'utf8');
311+
expect(test1).to.equal('a re place c');
312+
expect(test2).to.equal('a re place c');
313+
done();
314+
});
315+
});
316+
317+
it('should return changed files for a dry run', done => {
318+
replace({
319+
files: ['test1', 'test2', 'test3'],
320+
from: /re\splace/g,
321+
to: 'b',
322+
dry: true,
323+
}).then(changedFiles => {
324+
expect(changedFiles).to.have.length(2);
325+
expect(changedFiles).to.contain('test1');
326+
expect(changedFiles).to.contain('test2');
327+
done();
328+
});
329+
});
301330
});
302331

303332
/**
@@ -871,5 +900,30 @@ describe('Replace in file', () => {
871900
expect(test1).to.equal('a b c');
872901
expect(test2).to.equal('a b c');
873902
});
903+
904+
it('should not replace in a dry run', () => {
905+
replace.sync({
906+
files: ['test1', 'test2'],
907+
from: /re\splace/g,
908+
to: 'b',
909+
dry: true,
910+
});
911+
const test1 = fs.readFileSync('test1', 'utf8');
912+
const test2 = fs.readFileSync('test2', 'utf8');
913+
expect(test1).to.equal('a re place c');
914+
expect(test2).to.equal('a re place c');
915+
});
916+
917+
it('should return changed files for a dry run', () => {
918+
const changedFiles = replace.sync({
919+
files: ['test1', 'test2', 'test3'],
920+
from: /re\splace/g,
921+
to: 'b',
922+
dry: true,
923+
});
924+
expect(changedFiles).to.have.length(2);
925+
expect(changedFiles).to.contain('test1');
926+
expect(changedFiles).to.contain('test2');
927+
});
874928
});
875929
});

0 commit comments

Comments
 (0)