replace-in-file
Advanced tools
Comparing version
@@ -27,3 +27,3 @@ #!/usr/bin/env node | ||
//Extract settings | ||
const {from, to, files, isRegex, verbose} = options; | ||
const {from, to, files, isRegex, verbose, quiet} = options; | ||
@@ -48,8 +48,12 @@ //Single star globs already get expanded in the command line | ||
//Log | ||
console.log(`Replacing '${from}' with '${to}'`); | ||
if (!quiet) { | ||
console.log(`Replacing '${from}' with '${to}'`); | ||
} | ||
//Replace | ||
try { | ||
const changes = replace.sync(options); | ||
successHandler(changes, verbose); | ||
const results = replace.sync(options); | ||
if (!quiet) { | ||
successHandler(results, verbose); | ||
} | ||
} | ||
@@ -56,0 +60,0 @@ catch (error) { |
@@ -11,6 +11,7 @@ 'use strict'; | ||
*/ | ||
module.exports = function getPathsAsync( | ||
patterns, ignore, disableGlobs, allowEmptyPaths, cfg | ||
) { | ||
module.exports = function getPathsAsync(patterns, config) { | ||
//Extract relevant config | ||
const {ignore, disableGlobs, allowEmptyPaths, glob: cfg} = config; | ||
//Not using globs? | ||
@@ -17,0 +18,0 @@ if (disableGlobs) { |
@@ -11,4 +11,7 @@ 'use strict'; | ||
*/ | ||
module.exports = function getPathsSync(patterns, ignore, disableGlobs, cfg) { | ||
module.exports = function getPathsSync(patterns, config) { | ||
//Extract relevant config | ||
const {ignore, disableGlobs, glob: globConfig, cwd} = config; | ||
//Not using globs? | ||
@@ -20,10 +23,22 @@ if (disableGlobs) { | ||
//Prepare glob config | ||
cfg = Object.assign({ignore}, cfg, {nodir: true}); | ||
const cfg = Object.assign({ignore}, globConfig, {nodir: true}); | ||
//Append CWD configuration if given (#56) | ||
//istanbul ignore if | ||
if (cwd) { | ||
cfg.cwd = cwd; | ||
} | ||
//Get paths | ||
const paths = patterns | ||
.map(pattern => glob.sync(pattern, cfg)); | ||
const paths = patterns.map(pattern => glob.sync(pattern, cfg)); | ||
const flattened = [].concat.apply([], paths); | ||
//Prefix each path with CWD if given (#56) | ||
//istanbul ignore if | ||
if (cwd) { | ||
return flattened.map(path => `${cwd}${path}`); | ||
} | ||
//Return flattened | ||
return [].concat.apply([], paths); | ||
return flattened; | ||
}; |
@@ -19,3 +19,3 @@ 'use strict'; | ||
*/ | ||
module.exports = function makeReplacements(contents, from, to, file) { | ||
module.exports = function makeReplacements(contents, from, to, file, count) { | ||
@@ -27,9 +27,16 @@ //Turn into array | ||
//Check if replace value is an array | ||
//Check if replace value is an array and prepare result | ||
const isArray = Array.isArray(to); | ||
const result = {file}; | ||
//Counting? Initialize number of matches | ||
if (count) { | ||
result.numMatches = 0; | ||
result.numReplacements = 0; | ||
} | ||
//Make replacements | ||
from.forEach((item, i) => { | ||
const newContents = from.reduce((contents, item, i) => { | ||
//Call function if given, passing the filename | ||
//Call function if given, passing in the filename | ||
if (typeof item === 'function') { | ||
@@ -42,3 +49,3 @@ item = item(file); | ||
if (replacement === null) { | ||
return; | ||
return contents; | ||
} | ||
@@ -52,8 +59,21 @@ | ||
//Count matches | ||
if (count) { | ||
const matches = contents.match(item); | ||
if (matches) { | ||
const replacements = matches.filter(match => match !== replacement); | ||
result.numMatches += matches.length; | ||
result.numReplacements += replacements.length; | ||
} | ||
} | ||
//Make replacement | ||
contents = contents.replace(item, replacement); | ||
}); | ||
return contents.replace(item, replacement); | ||
}, contents); | ||
//Return modified contents | ||
return contents; | ||
//Check if changed | ||
result.hasChanged = (newContents !== contents); | ||
//Return result and new contents | ||
return [result, newContents]; | ||
}; |
@@ -11,6 +11,9 @@ 'use strict'; | ||
allowEmptyPaths: false, | ||
countMatches: false, | ||
isRegex: false, | ||
verbose: false, | ||
quiet: false, | ||
dry: false, | ||
glob: {}, | ||
cwd: null, | ||
}; | ||
@@ -32,3 +35,3 @@ | ||
//Extract data | ||
const {files, from, to, ignore, encoding, glob} = config; | ||
const {files, from, to, ignore, encoding} = config; | ||
@@ -45,5 +48,2 @@ //Validate values | ||
} | ||
if (typeof glob !== 'object') { | ||
throw new Error('Invalid glob config'); | ||
} | ||
@@ -50,0 +50,0 @@ //Ensure arrays |
@@ -12,5 +12,10 @@ 'use strict'; | ||
*/ | ||
module.exports = function replaceAsync(file, from, to, enc, dry) { | ||
module.exports = function replaceAsync(file, from, to, config) { | ||
//Extract relevant config | ||
const {encoding, dry, countMatches} = config; | ||
//Wrap in promise | ||
return new Promise((resolve, reject) => { | ||
fs.readFile(file, enc, (error, contents) => { | ||
fs.readFile(file, encoding, (error, contents) => { | ||
//istanbul ignore if | ||
@@ -21,15 +26,14 @@ if (error) { | ||
//Replace contents and check if anything changed | ||
let newContents = makeReplacements(contents, from, to, file); | ||
if (newContents === contents) { | ||
return resolve({file, hasChanged: false}); | ||
} | ||
//Make replacements | ||
const [result, newContents] = makeReplacements( | ||
contents, from, to, file, countMatches | ||
); | ||
//Dry run, resolve | ||
if (dry) { | ||
return resolve({file, hasChanged: true}); | ||
//Not changed or dry run? | ||
if (!result.hasChanged || dry) { | ||
return resolve(result); | ||
} | ||
//Write to file | ||
fs.writeFile(file, newContents, enc, error => { | ||
fs.writeFile(file, newContents, encoding, error => { | ||
//istanbul ignore if | ||
@@ -39,3 +43,3 @@ if (error) { | ||
} | ||
resolve({file, hasChanged: true}); | ||
resolve(result); | ||
}); | ||
@@ -42,0 +46,0 @@ }); |
@@ -12,21 +12,20 @@ 'use strict'; | ||
*/ | ||
module.exports = function replaceSync(file, from, to, enc, dry) { | ||
module.exports = function replaceSync(file, from, to, config) { | ||
//Read contents | ||
const contents = fs.readFileSync(file, enc); | ||
//Extract relevant config and read file contents | ||
const {encoding, dry, countMatches} = config; | ||
const contents = fs.readFileSync(file, encoding); | ||
//Replace contents and check if anything changed | ||
const newContents = makeReplacements(contents, from, to, file); | ||
if (newContents === contents) { | ||
return false; | ||
} | ||
const [result, newContents] = makeReplacements( | ||
contents, from, to, file, countMatches | ||
); | ||
//Dry run? | ||
if (dry) { | ||
return true; | ||
//Contents changed and not a dry run? Write to file | ||
if (result.hasChanged && !dry) { | ||
fs.writeFileSync(file, newContents, encoding); | ||
} | ||
//Write to file | ||
fs.writeFileSync(file, newContents, enc); | ||
return true; | ||
//Return result | ||
return result; | ||
}; |
@@ -11,7 +11,9 @@ 'use strict'; | ||
*/ | ||
module.exports = function successHandler(changes, verbose = false) { | ||
if (changes.length > 0) { | ||
console.log(chalk.green(changes.length, 'file(s) were changed')); | ||
module.exports = function successHandler(results, verbose) { | ||
const changed = results.filter(result => result.hasChanged); | ||
const numChanges = changed.length; | ||
if (numChanges > 0) { | ||
console.log(chalk.green(`${numChanges} file(s) were changed`)); | ||
if (verbose) { | ||
changes.forEach(file => console.log(chalk.grey('-', file))); | ||
changed.forEach(result => console.log(chalk.grey('-', result.file))); | ||
} | ||
@@ -18,0 +20,0 @@ } |
@@ -30,6 +30,3 @@ 'use strict'; | ||
//Get config | ||
const { | ||
files, from, to, encoding, ignore, allowEmptyPaths, disableGlobs, | ||
dry, verbose, glob, | ||
} = config; | ||
const {files, from, to, dry, verbose} = config; | ||
@@ -43,22 +40,15 @@ //Dry run? | ||
//Find paths | ||
return getPathsAsync(files, ignore, disableGlobs, allowEmptyPaths, glob) | ||
return getPathsAsync(files, config) | ||
//Make replacements | ||
.then(paths => Promise.all(paths.map(file => { | ||
return replaceAsync(file, from, to, encoding, dry); | ||
}))) | ||
.then(paths => Promise.all( | ||
paths.map(file => replaceAsync(file, from, to, config)) | ||
)) | ||
//Convert results to array of changed files | ||
//Success handler | ||
.then(results => { | ||
return results | ||
.filter(result => result.hasChanged) | ||
.map(result => result.file); | ||
}) | ||
//Success handler | ||
.then(changedFiles => { | ||
if (cb) { | ||
cb(null, changedFiles); | ||
cb(null, results); | ||
} | ||
return changedFiles; | ||
return results; | ||
}) | ||
@@ -86,7 +76,4 @@ | ||
//Get config, paths, and initialize changed files | ||
const { | ||
files, from, to, encoding, ignore, disableGlobs, dry, verbose, glob, | ||
} = config; | ||
const paths = getPathsSync(files, ignore, disableGlobs, glob); | ||
const changedFiles = []; | ||
const {files, from, to, dry, verbose} = config; | ||
const paths = getPathsSync(files, config); | ||
@@ -96,14 +83,7 @@ //Dry run? | ||
if (dry && verbose) { | ||
console.log(chalk.yellow('Dry run, not making any changes')); | ||
console.log(chalk.yellow('Dry run, not making actual changes')); | ||
} | ||
//Process synchronously | ||
paths.forEach(path => { | ||
if (replaceSync(path, from, to, encoding, dry)) { | ||
changedFiles.push(path); | ||
} | ||
}); | ||
//Return changed files | ||
return changedFiles; | ||
//Process synchronously and return results | ||
return paths.map(path => replaceSync(path, from, to, config)); | ||
}; | ||
@@ -110,0 +90,0 @@ |
@@ -71,11 +71,2 @@ 'use strict'; | ||
it('should throw an error when invalid `glob` config defined', () => { | ||
return expect(replace({ | ||
files: 'test1', | ||
from: /re\splace/g, | ||
to: 'test', | ||
glob: 'invalid', | ||
})).to.eventually.be.rejectedWith(Error); | ||
}); | ||
it('should replace contents in a single file with regex', done => { | ||
@@ -240,3 +231,3 @@ replace({ | ||
it('should return a changed files array', done => { | ||
it('should return a results array', done => { | ||
replace({ | ||
@@ -246,4 +237,6 @@ files: 'test1', | ||
to: 'b', | ||
}).then(changedFiles => { | ||
expect(changedFiles).to.be.instanceof(Array); | ||
}).then(results => { | ||
expect(results).to.be.instanceof(Array); | ||
expect(results).to.have.length(1); | ||
expect(results[0].file).to.equal('test1'); | ||
done(); | ||
@@ -253,3 +246,3 @@ }); | ||
it('should return in files if something was replaced', done => { | ||
it('should mark if something was replaced', done => { | ||
replace({ | ||
@@ -259,5 +252,4 @@ files: 'test1', | ||
to: 'b', | ||
}).then(changedFiles => { | ||
expect(changedFiles).to.have.length(1); | ||
expect(changedFiles[0]).to.equal('test1'); | ||
}).then(results => { | ||
expect(results[0].hasChanged).to.equal(true); | ||
done(); | ||
@@ -267,3 +259,3 @@ }); | ||
it('should not return in files if nothing replaced', done => { | ||
it('should not mark if nothing was replaced', done => { | ||
replace({ | ||
@@ -273,4 +265,4 @@ files: 'test1', | ||
to: 'b', | ||
}).then(changedFiles => { | ||
expect(changedFiles).to.have.length(0); | ||
}).then(results => { | ||
expect(results[0].hasChanged).to.equal(false); | ||
done(); | ||
@@ -280,3 +272,3 @@ }); | ||
it('should return changed files for multiple files', done => { | ||
it('should return correct results for multiple files', done => { | ||
replace({ | ||
@@ -286,6 +278,10 @@ files: ['test1', 'test2', 'test3'], | ||
to: 'b', | ||
}).then(changedFiles => { | ||
expect(changedFiles).to.have.length(2); | ||
expect(changedFiles).to.contain('test1'); | ||
expect(changedFiles).to.contain('test2'); | ||
}).then(results => { | ||
expect(results).to.have.length(3); | ||
expect(results[0].file).to.equal('test1'); | ||
expect(results[0].hasChanged).to.equal(true); | ||
expect(results[1].file).to.equal('test2'); | ||
expect(results[1].hasChanged).to.equal(true); | ||
expect(results[2].file).to.equal('test3'); | ||
expect(results[2].hasChanged).to.equal(false); | ||
done(); | ||
@@ -358,6 +354,10 @@ }); | ||
dry: true, | ||
}).then(changedFiles => { | ||
expect(changedFiles).to.have.length(2); | ||
expect(changedFiles).to.contain('test1'); | ||
expect(changedFiles).to.contain('test2'); | ||
}).then(results => { | ||
expect(results).to.have.length(3); | ||
expect(results[0].file).to.equal('test1'); | ||
expect(results[0].hasChanged).to.equal(true); | ||
expect(results[1].file).to.equal('test2'); | ||
expect(results[1].hasChanged).to.equal(true); | ||
expect(results[2].file).to.equal('test3'); | ||
expect(results[2].hasChanged).to.equal(false); | ||
done(); | ||
@@ -395,2 +395,37 @@ }); | ||
}); | ||
it('should count matches if specified in config', done => { | ||
replace({ | ||
files: 'test1', | ||
from: [/re/g, /place/g], | ||
to: 'test', | ||
countMatches: true, | ||
}).then(results => { | ||
expect(results[0].numMatches).to.equal(2); | ||
done(); | ||
}); | ||
}); | ||
it('should not count matches if not specified in config', done => { | ||
replace({ | ||
files: 'test1', | ||
from: [/re/g, /place/g], | ||
to: 'test', | ||
}).then(results => { | ||
expect(results[0].numMatches).to.be.undefined; | ||
done(); | ||
}); | ||
}); | ||
it('should return 0 matches if match not found', done => { | ||
replace({ | ||
files: 'test1', | ||
from: 'nope', | ||
to: 'test', | ||
countMatches: true, | ||
}).then(results => { | ||
expect(results[0].numMatches).to.equal(0); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
@@ -603,3 +638,3 @@ | ||
it('should return a changed files array', done => { | ||
it('should return a results array', done => { | ||
replace({ | ||
@@ -609,4 +644,6 @@ files: 'test1', | ||
to: 'b', | ||
}, (error, changedFiles) => { | ||
expect(changedFiles).to.be.instanceof(Array); | ||
}, (error, results) => { | ||
expect(results).to.be.instanceof(Array); | ||
expect(results).to.have.length(1); | ||
expect(results[0].file).to.equal('test1'); | ||
done(); | ||
@@ -616,3 +653,3 @@ }); | ||
it('should return in files if something was replaced', done => { | ||
it('should mark if something was replaced', done => { | ||
replace({ | ||
@@ -622,5 +659,4 @@ files: 'test1', | ||
to: 'b', | ||
}, (error, changedFiles) => { | ||
expect(changedFiles).to.have.length(1); | ||
expect(changedFiles[0]).to.equal('test1'); | ||
}, (error, results) => { | ||
expect(results[0].hasChanged).to.equal(true); | ||
done(); | ||
@@ -630,3 +666,3 @@ }); | ||
it('should not return in files if nothing replaced', done => { | ||
it('should not mark if nothing was replaced', done => { | ||
replace({ | ||
@@ -636,4 +672,4 @@ files: 'test1', | ||
to: 'b', | ||
}, (error, changedFiles) => { | ||
expect(changedFiles).to.have.length(0); | ||
}, (error, results) => { | ||
expect(results[0].hasChanged).to.equal(false); | ||
done(); | ||
@@ -643,3 +679,3 @@ }); | ||
it('should return changed files for multiple files', done => { | ||
it('should return correct results for multiple files', done => { | ||
replace({ | ||
@@ -649,6 +685,10 @@ files: ['test1', 'test2', 'test3'], | ||
to: 'b', | ||
}, (error, changedFiles) => { | ||
expect(changedFiles).to.have.length(2); | ||
expect(changedFiles).to.contain('test1'); | ||
expect(changedFiles).to.contain('test2'); | ||
}, (error, results) => { | ||
expect(results).to.have.length(3); | ||
expect(results[0].file).to.equal('test1'); | ||
expect(results[0].hasChanged).to.equal(true); | ||
expect(results[1].file).to.equal('test2'); | ||
expect(results[1].hasChanged).to.equal(true); | ||
expect(results[2].file).to.equal('test3'); | ||
expect(results[2].hasChanged).to.equal(false); | ||
done(); | ||
@@ -714,2 +754,37 @@ }); | ||
}); | ||
it('should count matches if specified in config', done => { | ||
replace({ | ||
files: 'test1', | ||
from: [/re/g, /place/g], | ||
to: 'test', | ||
countMatches: true, | ||
}, (error, results) => { | ||
expect(results[0].numMatches).to.equal(2); | ||
done(); | ||
}); | ||
}); | ||
it('should not count matches if not specified in config', done => { | ||
replace({ | ||
files: 'test1', | ||
from: [/re/g, /place/g], | ||
to: 'test', | ||
}, (error, results) => { | ||
expect(results[0].numMatches).to.be.undefined; | ||
done(); | ||
}); | ||
}); | ||
it('should return 0 matches if match not found', done => { | ||
replace({ | ||
files: 'test1', | ||
from: 'nope', | ||
to: 'test', | ||
countMatches: true, | ||
}, (error, results) => { | ||
expect(results[0].numMatches).to.equal(0); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
@@ -884,4 +959,4 @@ | ||
it('should return a changed files array', function() { | ||
const changedFiles = replace.sync({ | ||
it('should return a results array', function() { | ||
const results = replace.sync({ | ||
files: 'test1', | ||
@@ -891,7 +966,9 @@ from: /re\splace/g, | ||
}); | ||
expect(changedFiles).to.be.instanceof(Array); | ||
expect(results).to.be.instanceof(Array); | ||
expect(results).to.have.length(1); | ||
expect(results[0].file).to.equal('test1'); | ||
}); | ||
it('should return in changed files if something was replaced', function() { | ||
const changedFiles = replace.sync({ | ||
it('should mark if something was replaced', function() { | ||
const results = replace.sync({ | ||
files: 'test1', | ||
@@ -901,8 +978,7 @@ from: /re\splace/g, | ||
}); | ||
expect(changedFiles).to.have.length(1); | ||
expect(changedFiles[0]).to.equal('test1'); | ||
expect(results[0].hasChanged).to.equal(true); | ||
}); | ||
it('should not return in changed files if nothing replaced', function() { | ||
const changedFiles = replace.sync({ | ||
it('should not mark if nothing was replaced', function() { | ||
const results = replace.sync({ | ||
files: 'test1', | ||
@@ -912,7 +988,7 @@ from: 'nope', | ||
}); | ||
expect(changedFiles).to.have.length(0); | ||
expect(results[0].hasChanged).to.equal(false); | ||
}); | ||
it('should return changed files for multiple files', function() { | ||
const changedFiles = replace.sync({ | ||
it('should return corret results for multiple files', function() { | ||
const results = replace.sync({ | ||
files: ['test1', 'test2', 'test3'], | ||
@@ -922,5 +998,9 @@ from: /re\splace/g, | ||
}); | ||
expect(changedFiles).to.have.length(2); | ||
expect(changedFiles).to.contain('test1'); | ||
expect(changedFiles).to.contain('test2'); | ||
expect(results).to.have.length(3); | ||
expect(results[0].file).to.equal('test1'); | ||
expect(results[0].hasChanged).to.equal(true); | ||
expect(results[1].file).to.equal('test2'); | ||
expect(results[1].hasChanged).to.equal(true); | ||
expect(results[2].file).to.equal('test3'); | ||
expect(results[2].hasChanged).to.equal(false); | ||
}); | ||
@@ -1030,3 +1110,3 @@ | ||
it('should return changed files for a dry run', () => { | ||
const changedFiles = replace.sync({ | ||
const results = replace.sync({ | ||
files: ['test1', 'test2', 'test3'], | ||
@@ -1037,7 +1117,65 @@ from: /re\splace/g, | ||
}); | ||
expect(changedFiles).to.have.length(2); | ||
expect(changedFiles).to.contain('test1'); | ||
expect(changedFiles).to.contain('test2'); | ||
expect(results).to.have.length(3); | ||
expect(results[0].file).to.equal('test1'); | ||
expect(results[0].hasChanged).to.equal(true); | ||
expect(results[1].file).to.equal('test2'); | ||
expect(results[1].hasChanged).to.equal(true); | ||
expect(results[2].file).to.equal('test3'); | ||
expect(results[2].hasChanged).to.equal(false); | ||
}); | ||
it('should count matches and replacements if specified in config', () => { | ||
const results = replace.sync({ | ||
files: 'test1', | ||
from: [/re/g, /place/g], | ||
to: 'test', | ||
countMatches: true, | ||
}); | ||
expect(results[0].numMatches).to.equal(2); | ||
expect(results[0].numReplacements).to.equal(2); | ||
}); | ||
it('should differentiate between matches and replacements', () => { | ||
const results = replace.sync({ | ||
files: 'test1', | ||
from: [/re/g, /place/g], | ||
to: 're', | ||
countMatches: true, | ||
}); | ||
expect(results[0].numMatches).to.equal(2); | ||
expect(results[0].numReplacements).to.equal(1); | ||
}); | ||
it('should count multiple replacements correctly', () => { | ||
const results = replace.sync({ | ||
files: 'test1', | ||
from: [/re/g, /place/g], | ||
to: 'place', | ||
countMatches: true, | ||
}); | ||
expect(results[0].numMatches).to.equal(3); | ||
expect(results[0].numReplacements).to.equal(1); | ||
}); | ||
it('should not count matches or replacements if not specified in config', () => { | ||
const results = replace.sync({ | ||
files: 'test1', | ||
from: [/re/g, /place/g], | ||
to: 'test', | ||
}); | ||
expect(results[0].numMatches).to.be.undefined; | ||
expect(results[0].numReplacements).to.be.undefined; | ||
}); | ||
it('should return 0 matches and replacements if match not found', () => { | ||
const results = replace.sync({ | ||
files: 'test1', | ||
from: 'nope', | ||
to: 'test', | ||
countMatches: true, | ||
}); | ||
expect(results[0].numMatches).to.equal(0); | ||
expect(results[0].numReplacements).to.equal(0); | ||
}); | ||
}); | ||
}); |
{ | ||
"name": "replace-in-file", | ||
"version": "3.4.4", | ||
"version": "4.0.0", | ||
"description": "A simple utility to quickly replace text in one or more files.", | ||
@@ -41,3 +41,3 @@ "homepage": "https://github.com/adamreisnz/replace-in-file#readme", | ||
"babel-preset-es2015": "^6.24.1", | ||
"bluebird": "^3.5.3", | ||
"bluebird": "^3.5.4", | ||
"chai": "^4.2.0", | ||
@@ -47,3 +47,3 @@ "chai-as-promised": "^7.1.1", | ||
"istanbul": "^1.0.0-alpha.2", | ||
"mocha": "^6.0.2" | ||
"mocha": "^6.1.4" | ||
}, | ||
@@ -50,0 +50,0 @@ "browserify": { |
110
README.md
@@ -19,2 +19,3 @@ # Replace in file | ||
- [Return value](#return-value) | ||
- [Counting matches and replacements](#counting-matches-and-replacements) | ||
- [Advanced usage](#advanced-usage) | ||
@@ -34,3 +35,4 @@ - [Replace a single file or glob](#replace-a-single-file-or-glob) | ||
- [Disable globs](#disable-globs) | ||
- [Specify glob configuration](#glob-configuration) | ||
- [Specify glob configuration](#specify-glob-configuration) | ||
- [Making replacements on network drives](#making-replacements-on-network-drives) | ||
- [Specify character encoding](#specify-character-encoding) | ||
@@ -70,4 +72,4 @@ - [Dry run](#dry-run) | ||
try { | ||
const changes = await replace(options) | ||
console.log('Modified files:', changes.join(', ')); | ||
const results = await replace(options) | ||
console.log('Replacement results:', results); | ||
} | ||
@@ -83,4 +85,4 @@ catch (error) { | ||
replace(options) | ||
.then(changes => { | ||
console.log('Modified files:', changes.join(', ')); | ||
.then(results => { | ||
console.log('Replacement results:', results); | ||
}) | ||
@@ -95,7 +97,7 @@ .catch(error => { | ||
```js | ||
replace(options, (error, changes) => { | ||
replace(options, (error, results) => { | ||
if (error) { | ||
return console.error('Error occurred:', error); | ||
} | ||
console.log('Modified files:', changes.join(', ')); | ||
console.log('Replacement results:', results); | ||
}); | ||
@@ -108,4 +110,4 @@ ``` | ||
try { | ||
const changes = replace.sync(options); | ||
console.log('Modified files:', changes.join(', ')); | ||
const results = replace.sync(options); | ||
console.log('Replacement results:', results); | ||
} | ||
@@ -119,21 +121,83 @@ catch (error) { | ||
The return value of the library is an array of file names of files that were modified (e.g. | ||
had some of the contents replaced). If no replacements were made, the return array will be empty. | ||
The return value of the library is an array of replacement results against each file that was processed. This includes files in which no replacements were made. | ||
Each result contains the following values: | ||
- `file`: The path to the file that was processed | ||
- `hasChanged`: Flag to indicate if the file was changed or not | ||
```js | ||
const changes = replace.sync({ | ||
const results = replace.sync({ | ||
files: 'path/to/files/*.html', | ||
from: 'foo', | ||
from: /foo/g, | ||
to: 'bar', | ||
}); | ||
console.log(changes); | ||
console.log(results); | ||
// [ | ||
// 'path/to/files/file1.html', | ||
// 'path/to/files/file3.html', | ||
// 'path/to/files/file5.html', | ||
// { | ||
// file: 'path/to/files/file1.html', | ||
// hasChanged: true, | ||
// }, | ||
// { | ||
// file: 'path/to/files/file2.html', | ||
// hasChanged: true, | ||
// }, | ||
// { | ||
// file: 'path/to/files/file3.html', | ||
// hasChanged: false, | ||
// }, | ||
// ] | ||
``` | ||
To get an array of changed files, simply map the results as follows: | ||
```js | ||
const changedFiles = results | ||
.filter(result => result.hasChanged) | ||
.map(result => result.file); | ||
``` | ||
### Counting matches and replacements | ||
By setting the `countMatches` configuration flag to `true`, the number of matches and replacements per file will be counted and present in the results array. | ||
- `numMatches`: Indicates the number of times a match was found in the file | ||
- `numReplacements`: Indicates the number of times a replacement was made in the file | ||
Note that the number of matches can be higher than the number of replacements if a match and replacement are the same string. | ||
```js | ||
const results = replace.sync({ | ||
files: 'path/to/files/*.html', | ||
from: /foo/g, | ||
to: 'bar', | ||
countMatches: true, | ||
}); | ||
console.log(results); | ||
// [ | ||
// { | ||
// file: 'path/to/files/file1.html', | ||
// hasChanged: true, | ||
// numMatches: 3, | ||
// numReplacements: 3, | ||
// }, | ||
// { | ||
// file: 'path/to/files/file2.html', | ||
// hasChanged: true, | ||
// numMatches: 1, | ||
// numReplacements: 1, | ||
// }, | ||
// { | ||
// file: 'path/to/files/file3.html', | ||
// hasChanged: false, | ||
// numMatches: 0, | ||
// numReplacements: 0, | ||
// }, | ||
// ] | ||
``` | ||
## Advanced usage | ||
@@ -303,2 +367,5 @@ | ||
### Making replacements on network drives | ||
To make replacements in files on network drives, you may need to specify the UNC path as the `cwd` config option. This will then be passed to glob and prefixed to your paths accordingly. See [#56](https://github.com/adamreisnz/replace-in-file/issues/56) for more details. | ||
### Specify character encoding | ||
@@ -332,2 +399,3 @@ Use a different character encoding for reading/writing files. Defaults to `utf-8`. | ||
[--verbose] | ||
[--quiet] | ||
[--dry] | ||
@@ -343,4 +411,6 @@ ``` | ||
To list the changed files, use the `--verbose` flag. To do a dry run, use `--dry`. | ||
To list the changed files, use the `--verbose` flag. Success output can be suppressed by using the `--quiet` flag. | ||
To do a dry run without making any actual changes, use `--dry`. | ||
A regular expression may be used for the `from` parameter by specifying the `--isRegex` flag. | ||
@@ -356,5 +426,7 @@ | ||
See the [Changelog](CHANGELOG.md) for more information. | ||
## License | ||
(MIT License) | ||
Copyright 2015-2018, [Adam Reis](https://adam.reis.nz), co-founder at [Hello Club](https://helloclub.com/?source=npm) | ||
Copyright 2015-2019, [Adam Reis](https://adam.reis.nz), Co-founder at [Hello Club](https://helloclub.com/?source=npm) |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
27
3.85%1567
10.27%422
20.57%161271
-9.52%