diff --git a/CHANGELOG.md b/CHANGELOG.md index 493af10..0c2275a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,8 +10,11 @@ The package has been converted to an ES module and now requires Node 18 or highe - To use a custom `fs` implementation, you must now specify `fs` config parameter for the async API, and `fsSync` for the sync API. For the asynchronous APIs, the provided `fs` must provide the `readFile` and `writeFile` methods. For the synchronous APIs, the provided `fsSync` must provide the `readFileSync` and `writeFileSync` methods. - If a `cwd` parameter is provided, it will no longer be prefixed to each path using basic string concatenation, but rather uses `path.join()` to ensure correct path concatenation. + ### New features -You can now specify a `getTargetFile` config param to modify the target file for saving the new file contents to. For example: +- The `isRegex` flag is no longer required. +- You can now specify a `getTargetFile` config param to modify the target file for saving the new file contents to. For example: + ```js const options = { diff --git a/README.md b/README.md index 4670edd..8bef86d 100644 --- a/README.md +++ b/README.md @@ -484,7 +484,6 @@ replace-in-file from to some/file.js,some/**/glob.js [--ignore=ignore/files.js,ignore/**/glob.js] [--encoding=utf-8] [--disableGlobs] - [--isRegex] [--verbose] [--quiet] [--dry] @@ -501,7 +500,7 @@ To list the changed files, use the `--verbose` flag. Success output can be suppr 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. +A regular expression may be used for the `from` parameter by passing in a string correctly formatted as a regular expression. The library will automatically detect that it is a regular expression. The `from` and `to` parameters, as well as the files list, can be omitted if you provide this information in a configuration file. @@ -519,8 +518,6 @@ If you are using a configuration file, and you want to use a regular expression } ``` -It is not necessary to use the `--isRegex` flag in this case. - ## A note on using globs with the CLI When using the CLI, the glob pattern is handled by the operating system. But if you specify the glob pattern in the configuration file, the package will use the glob module from the Node modules, and this can lead to different behaviour despite using the same pattern. diff --git a/bin/cli.js b/bin/cli.js index 22ea350..85bc2f6 100755 --- a/bin/cli.js +++ b/bin/cli.js @@ -25,20 +25,13 @@ async function main() { const options = combineConfig(config, argv) //Extract settings - const {from, to, files, isRegex, verbose, quiet} = options + const {from, to, files, verbose, quiet} = options //Single star globs already get expanded in the command line options.files = files.reduce((files, file) => { return files.concat(file.split(',')) }, []) - //If the isRegex flag is passed, convert the from parameter to a RegExp object - if (isRegex && typeof from === 'string') { - const flags = from.replace(/.*\/([gimyus]*)$/, '$1') - const pattern = from.replace(new RegExp(`^/(.*?)/${flags}$`), '$1') - options.from = new RegExp(pattern, flags) - } - //Log if (!quiet) { console.log(`Replacing '${from}' with '${to}'`) diff --git a/package.json b/package.json index 45dc209..2ff2344 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "replace-in-file", "type": "module", - "version": "8.0.2", + "version": "8.0.3", "description": "A simple utility to quickly replace text in one or more files.", "homepage": "https://github.com/adamreisnz/replace-in-file#readme", "author": { diff --git a/src/helpers/config.js b/src/helpers/config.js index d5cf4cc..123eac7 100644 --- a/src/helpers/config.js +++ b/src/helpers/config.js @@ -14,15 +14,7 @@ export async function loadConfig(file) { //Read file const json = await fs.readFile(path.resolve(file), 'utf8') - const config = JSON.parse(json) - - //Since we can't store Regexp in JSON, convert from string if needed - if (config.from && config.from.match(/.*\/([gimyus]*)$/)) { - config.from = new RegExp(config.from) - } - - //Return config - return config + return JSON.parse(json) } /** @@ -73,6 +65,13 @@ export function parseConfig(config) { } } + //Since we can't store Regexp in JSON, convert from string if needed + if (typeof from === 'string' && from.match(/.*\/([gimyus]*)$/)) { + const flags = from.replace(/.*\/([gimyus]*)$/, '$1') + const pattern = from.replace(new RegExp(`^/(.*?)/${flags}$`), '$1') + config.from = new RegExp(pattern, flags) + } + //Use default encoding if invalid if (typeof encoding !== 'string' || encoding === '') { config.encoding = 'utf-8' @@ -85,7 +84,6 @@ export function parseConfig(config) { disableGlobs: false, allowEmptyPaths: false, countMatches: false, - isRegex: false, verbose: false, quiet: false, dry: false, @@ -105,7 +103,7 @@ export function combineConfig(config, argv) { //Extract options from config let { from, to, files, ignore, encoding, verbose, - allowEmptyPaths, disableGlobs, isRegex, dry, quiet, + allowEmptyPaths, disableGlobs, dry, quiet, } = config //Get from/to parameters from CLI args if not defined in options @@ -131,9 +129,6 @@ export function combineConfig(config, argv) { if (typeof disableGlobs === 'undefined') { disableGlobs = !!argv.disableGlobs } - if (typeof isRegex === 'undefined') { - isRegex = !!argv.isRegex - } if (typeof verbose === 'undefined') { verbose = !!argv.verbose } @@ -147,6 +142,6 @@ export function combineConfig(config, argv) { //Return through parser to validate return parseConfig({ from, to, files, ignore, encoding, verbose, - allowEmptyPaths, disableGlobs, isRegex, dry, quiet, + allowEmptyPaths, disableGlobs, dry, quiet, }) } diff --git a/src/helpers/config.spec.js b/src/helpers/config.spec.js index fc92038..2607dc4 100644 --- a/src/helpers/config.spec.js +++ b/src/helpers/config.spec.js @@ -46,62 +46,6 @@ describe('helpers/config.js', () => { //Clean up fs.unlinkSync('config.json') }) - - it('should convert from regex if provided in JSON', async () => { - - //Test config - const config = { - files: ['file.txt'], - from: '/foo/g', - to: 'bar', - } - fs.writeFileSync('config.json', JSON.stringify(config), 'utf8') - - //Load config - const cfg = await loadConfig('config.json') - expect(cfg.from).to.be.an.instanceof(RegExp) - - //Clean up - fs.unlinkSync('config.json') - }) - - it('should not convert from regex if it is a regular string', async () => { - - //Test config - const config = { - files: ['file.txt'], - from: '/foo', - to: 'bar', - } - fs.writeFileSync('config.json', JSON.stringify(config), 'utf8') - - //Load config - const cfg = await loadConfig('config.json') - expect(cfg.from).not.to.be.an.instanceof(RegExp) - expect(cfg.from).to.equal(config.from) - - //Clean up - fs.unlinkSync('config.json') - }) - - it('should ignore the isRegex flag if a regex has already been provided', async () => { - - //Test config - const config = { - files: ['file.txt'], - from: '/foo/g', - to: 'bar', - isRegex: true, - } - fs.writeFileSync('config.json', JSON.stringify(config), 'utf8') - - //Load config - const cfg = await loadConfig('config.json') - expect(cfg.from).to.be.an.instanceof(RegExp) - - //Clean up - fs.unlinkSync('config.json') - }) }) /** @@ -114,7 +58,6 @@ describe('helpers/config.js', () => { ignore: ['ignore-file.txt'], encoding: 'encoding', disableGlobs: true, - isRegex: true, dry: true, quiet: true, } @@ -125,7 +68,6 @@ describe('helpers/config.js', () => { expect(combined.ignore).to.eql(['ignore-file.txt']) expect(combined.encoding).to.equal('encoding') expect(combined.disableGlobs).to.be.true - expect(combined.isRegex).to.be.true expect(combined.dry).to.be.true expect(combined.quiet).to.be.true }) @@ -234,6 +176,25 @@ describe('helpers/config.js', () => { expect(c.encoding).to.equal('utf-8') }) + it('should convert from regex if provided in JSON', async () => { + const parsed = parseConfig({ + files: ['file.txt'], + from: '/foo/g', + to: 'bar', + }) + expect(parsed.from).to.be.an.instanceof(RegExp) + }) + + it('should not convert from regex if it is a regular string', async () => { + const parsed = parseConfig({ + files: ['file.txt'], + from: '/foo', + to: 'bar', + }) + expect(parsed.from).not.to.be.an.instanceof(RegExp) + expect(parsed.from).to.equal('/foo') + }) + it('should overwrite the config defaults', () => { const parsed = parseConfig({ files: 'test1', @@ -244,7 +205,6 @@ describe('helpers/config.js', () => { disableGlobs: true, allowEmptyPaths: true, countMatches: true, - isRegex: true, verbose: true, quiet: true, dry: true, @@ -258,7 +218,6 @@ describe('helpers/config.js', () => { expect(parsed.disableGlobs).to.be.true expect(parsed.allowEmptyPaths).to.be.true expect(parsed.countMatches).to.be.true - expect(parsed.isRegex).to.be.true expect(parsed.verbose).to.be.true expect(parsed.quiet).to.be.true expect(parsed.dry).to.be.true diff --git a/src/replace-in-file.spec.js b/src/replace-in-file.spec.js index f47bc88..a51c25f 100644 --- a/src/replace-in-file.spec.js +++ b/src/replace-in-file.spec.js @@ -826,6 +826,21 @@ describe('Replace in file', () => { expect(test1).to.equal('a re bloop c') }) }) + + //#197 + describe('#197', () => { + before(() => fs.writeFileSync('test197', 'ABC 123\n6666666\nDEF 456', 'utf8')) + after(() => fs.unlinkSync('test197')) + it('should replace contents when a regex string is passed', () => { + replaceInFileSync({ + files: 'test197', + from: '/\\w{3} \\d{3}/g', + to: 'replaced', + }) + const test197 = fs.readFileSync('test197', 'utf8') + expect(test197).to.equal('replaced\n6666666\nreplaced') + }) + }) }) describe('module export', () => {