Skip to content

Commit

Permalink
[fx] #197 , remove need for regex flag
Browse files Browse the repository at this point in the history
  • Loading branch information
adamreisnz committed Jul 2, 2024
1 parent 760102a commit dc5e8cd
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 89 deletions.
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down
5 changes: 1 addition & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand All @@ -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.
Expand All @@ -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.

Expand Down
9 changes: 1 addition & 8 deletions bin/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -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}'`)
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -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": {
Expand Down
25 changes: 10 additions & 15 deletions src/helpers/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

/**
Expand Down Expand Up @@ -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'
Expand All @@ -85,7 +84,6 @@ export function parseConfig(config) {
disableGlobs: false,
allowEmptyPaths: false,
countMatches: false,
isRegex: false,
verbose: false,
quiet: false,
dry: false,
Expand All @@ -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
Expand All @@ -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
}
Expand All @@ -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,
})
}
79 changes: 19 additions & 60 deletions src/helpers/config.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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')
})
})

/**
Expand All @@ -114,7 +58,6 @@ describe('helpers/config.js', () => {
ignore: ['ignore-file.txt'],
encoding: 'encoding',
disableGlobs: true,
isRegex: true,
dry: true,
quiet: true,
}
Expand All @@ -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
})
Expand Down Expand Up @@ -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',
Expand All @@ -244,7 +205,6 @@ describe('helpers/config.js', () => {
disableGlobs: true,
allowEmptyPaths: true,
countMatches: true,
isRegex: true,
verbose: true,
quiet: true,
dry: true,
Expand All @@ -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
Expand Down
15 changes: 15 additions & 0 deletions src/replace-in-file.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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', () => {
Expand Down

0 comments on commit dc5e8cd

Please sign in to comment.