Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md

Large diffs are not rendered by default.

15 changes: 11 additions & 4 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,13 @@ const yargs = require('yargs')
.describe('b', 'Keep a backup file of the original content.')
.alias('b', 'keep-backup')

.boolean('S')
.describe(
'S',
'Do everything but write the files. The names of the files that would be changed are printed as usual, and no backup is made.'
)
.alias('S', 'simulate')

.boolean('m')
.describe(
'm',
Expand Down Expand Up @@ -384,7 +391,7 @@ All variables, except from module, date objects, \`nl\` and \`_\`, has a corresp

Upper Case Free Lower Case Free
a
C c
C
D
F
g
Expand All @@ -403,10 +410,10 @@ Z z


*/
.boolean('S')
.alias('S', 'status-compact')
.boolean('c')
.alias('c', 'status-compact')
.describe(
'S',
'c',
'As the last thing before ending any execution a status report will be printed as one line of JSON. Will print even in combination with `--quiet-total`. Will incude extra info about the inner workings of the engine in combination with the `--verbose` flag.'
)

Expand Down
5 changes: 5 additions & 0 deletions src/engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,11 @@ function doReplacement(_file_rr: string, _config_rr: any, _data_rr: string) {
return;
}

// --simulate does everything but write, so the file is named as if it was changed
if (_config_rr.simulate) {
return updated(_file_rr, _config_rr);
}

// Release the memory while storing files
_data_rr = '';

Expand Down
7 changes: 7 additions & 0 deletions test/cli/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,13 @@ assert "rexreplace 'b' 'x' my.file --content-delimiter '\x4' 2>&1 | grep -c
assert "rexreplace 'b' 'x' my.file --delimiter '\x4' 2>&1 | grep -c 'Invalid escape sequence in --delimiter'" '1'
assert "cat my.file" 'foobar'

# --simulate: the files that would be changed are named, but nothing is written (#710)
reset
assert "rexreplace 'oo' 'x' my.file your.file --simulate" 'my.file'
assert "cat my.file" 'foobar'
assert "rexreplace 'b' 'x' my.file -S" 'my.file'
assert "cat my.file" 'foobar'

# --full-path
reset
assert "rexreplace 'b' 'x' my.file -f" "$(pwd -P)/my.file"
Expand Down
55 changes: 55 additions & 0 deletions test/js/fix/710.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// https://github.com/mathiasrw/rexreplace/issues/710
// There was no way to see which files a command would change without changing them.
import {describe, test, expect} from 'bun:test';
import fs from 'fs';
import {rr, rrStatus} from '../helper.js';

// Note that rr() from the helper sets voidAsync per default, so the async flow is `voidAsync: false`
const flows = [
['the async flow', {voidAsync: false}],
['--void-async', {voidAsync: true}],
];

// Make a.file and c.file with `foo`, and b.file with `bar` (nothing to replace)
function makeFiles() {
fs.writeFileSync('a.file', 'foo');
fs.writeFileSync('b.file', 'bar');
fs.writeFileSync('c.file', 'foo');
return {includeGlob: ['*.file'], simulate: true};
}

const contents = () => ['a.file', 'b.file', 'c.file'].map(name => fs.readFileSync(name, 'utf8'));

describe('#710 --simulate', () => {
test.each(flows)(
'names the files that would be changed, and changes nothing, with %s',
async (name, flags) => {
const result = await rr('o', 'x', {...makeFiles(), ...flags});
expect(result.out.split('\n').sort()).toEqual(['', 'a.file', 'c.file']);
expect(result.err).toBe('');
expect(result.exit).toBe(null);
expect(contents()).toEqual(['foo', 'bar', 'foo']);
expect(fs.readdirSync('.').sort()).toEqual(['a.file', 'b.file', 'c.file']);
}
);

test('makes no backup, also with --keep-backup', async () => {
await rr('o', 'x', {...makeFiles(), keepBackup: true});
expect(fs.readdirSync('.').sort()).toEqual(['a.file', 'b.file', 'c.file']);
});

test('has the files that would be changed in the status report', async () => {
const status = await rrStatus('o', 'x', makeFiles());
expect(status.files).toEqual({
searched: ['a.file', 'b.file', 'c.file'],
updated: ['a.file', 'c.file'],
});
});

test('with --name-all names all files, but only the changed ones are updated', async () => {
const config = {...makeFiles(), nameAll: true};
expect((await rr('o', 'x', config)).out).toBe('a.file\nb.file\nc.file\n');
expect((await rrStatus('o', 'x', config)).files.updated).toEqual(['a.file', 'c.file']);
expect(contents()).toEqual(['foo', 'bar', 'foo']);
});
});
2 changes: 1 addition & 1 deletion test/js/fix/742.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ describe('#742 the CLI', () => {
});
});

test.each(['--status-compact', '-S'])(
test.each(['--status-compact', '-c'])(
'%s prints the status report on one line, with no line break in front',
flag => {
fs.writeFileSync('a.file', 'foo');
Expand Down
Loading