Skip to content
Closed
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
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,6 @@ _.oO(What should "sed" have looked like by now?)_
- Let Pattern, replacement, and globs come from a file
- Let pattern and glob be javascript code returning a string as the result
- Auto string search / replace if no regex magic is used (and verify that speed is better)
- Error != warning
- Flag for String-literal (no regex, no special chars, no escape chars) to avoid backslashes or remembering which characters needs to be escaped
- Check if https://github.com/eugeneware/replacestream is good to rely on
- Check if regex engine from spider monkey can be wrapped in something that does not need node
Expand Down
14 changes: 13 additions & 1 deletion src/engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const globs = require('fast-glob');

const now = new Date();

import {outputConfig, step, debug, chat, info, error, die} from './output.ts';
import {outputConfig, step, debug, chat, info, warn, error, die} from './output.ts';

const re = {
euro: /€/g,
Expand Down Expand Up @@ -156,6 +156,18 @@ function handlePipedData(config) {
step('Check Piped Data');

if (config.includeGlob.length) {
if (
!config.replacementJs &&
!config.replacementPipe &&
!config.pipedDataUsed &&
!config.voidPipe &&
config.pipedData &&
config.pipedData !== '\n' &&
config.pipedData !== '\r\n'
Comment on lines +165 to +166

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this? what is the reasoning?

) {
warn('Data is piped in, but no flag tells what to do with it. It is not used.');
}

if (!config.replacementJs && config.pipedData) {
chat('Piped data never used.');
}
Expand Down
10 changes: 9 additions & 1 deletion src/output.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
let font: any = {};
font.red = font.green = font.gray = (str) => str;
font.yellow = font.red = font.green = font.gray = (str) => str;
// check for node version supporting chalk - if so overwrite `font`
//const font = import('chalk');

Expand Down Expand Up @@ -42,6 +42,14 @@ export const error = function (msg, data = '') {
return false;
};

export const warn = function (msg, data = '') {
if (config?.quiet || config?.quietTotal) {
return false;
}
console.error(...[' 🟡', font.yellow(msg), data].filter(Boolean));
return false;
};

export function debug(data) {
if (config.debug) {
console.error(font.gray(JSON.stringify(data, null, 4)));
Expand Down
22 changes: 22 additions & 0 deletions test/cli/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,28 @@ assert "printf x | rexreplace 'foo' 'pipe' my.file -o --replacement-js --voi
assert_failure "printf x | rexreplace 'b' _ my.file -P -R"
assert_failure "printf x | rexreplace 'b' _ my.file -P -T"

# Warn when piped data is not used (#719)
reset
assert "printf notes | rexreplace foo bar my.file 2>&1 1>/dev/null" " 🟡 Data is piped in, but no flag tells what to do with it. It is not used.\nmy.file "
assert "cat my.file" 'barbar'

reset
assert "printf notes | rexreplace foo bar my.file -q 2>&1 1>/dev/null" ''

reset
assert "printf notes | rexreplace foo bar my.file -Q 2>&1 1>/dev/null" ''

reset
assert "printf notes | rexreplace foo bar my.file -P 2>&1 1>/dev/null" 'my.file '

reset
assert "printf '' | rexreplace foo bar my.file 2>&1 1>/dev/null" 'my.file '

reset
assert "printf '\n' | rexreplace foo bar my.file 2>&1 1>/dev/null" 'my.file '






Expand Down
130 changes: 130 additions & 0 deletions test/js/fix/719.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
// https://github.com/mathiasrw/rexreplace/issues/719
// Warn when data is piped in and files are also given, but the piped data is not used.
import {describe, test, expect} from 'bun:test';
import fs from 'fs';
import {rr} from '../helper.js';

const warnMsg = ' 🟡 Data is piped in, but no flag tells what to do with it. It is not used.\n';

describe('#719 warn when piped data is not used', () => {
test('warns when data is piped in and files are given', async () => {
fs.writeFileSync('my.file', 'foobar');
const result = await rr('foo', 'bar', {
includeGlob: ['my.file'],
pipedData: 'notes',
});
expect(result.err).toContain(warnMsg);
expect(result.exit).toBe(null);
expect(fs.readFileSync('my.file', 'utf8')).toBe('barbar');
});

test('warning starts with 🟡 and goes to stderr', async () => {
fs.writeFileSync('my.file', 'foobar');
const result = await rr('foo', 'bar', {
includeGlob: ['my.file'],
pipedData: 'notes',
});
expect(result.err.startsWith(' 🟡')).toBe(true);
expect(result.out).toBe('');
});

test('--quiet hides the warning', async () => {
fs.writeFileSync('my.file', 'foobar');
const result = await rr('foo', 'bar', {
includeGlob: ['my.file'],
pipedData: 'notes',
quiet: true,
});
expect(result.err).toBe('');
expect(fs.readFileSync('my.file', 'utf8')).toBe('barbar');
});

test('--quiet-total hides the warning', async () => {
fs.writeFileSync('my.file', 'foobar');
const result = await rr('foo', 'bar', {
includeGlob: ['my.file'],
pipedData: 'notes',
quietTotal: true,
});
expect(result.err).toBe('');
expect(fs.readFileSync('my.file', 'utf8')).toBe('barbar');
});

test('warning never stops the run, also not with --halt', async () => {
fs.writeFileSync('my.file', 'foobar');
const result = await rr('foo', 'bar', {
includeGlob: ['my.file'],
pipedData: 'notes',
halt: true,
});
expect(result.err).toContain(warnMsg);
expect(result.exit).toBe(null);
expect(fs.readFileSync('my.file', 'utf8')).toBe('barbar');
});

test('--void-pipe suppresses the warning', async () => {
fs.writeFileSync('my.file', 'foobar');
const result = await rr('foo', 'bar', {
includeGlob: ['my.file'],
pipedData: 'notes',
voidPipe: true,
});
expect(result.err).not.toContain(warnMsg);
expect(fs.readFileSync('my.file', 'utf8')).toBe('barbar');
});

test('--replacement-pipe suppresses the warning', async () => {
fs.writeFileSync('my.file', 'foobar');
const result = await rr('foo', '_', {
includeGlob: ['my.file'],
pipedData: 'bar',
replacementPipe: true,
});
expect(result.err).not.toContain(warnMsg);
expect(fs.readFileSync('my.file', 'utf8')).toBe('barbar');
});

test('--replacement-js suppresses the warning', async () => {
fs.writeFileSync('my.file', 'foobar');
const result = await rr('foo', 'pipe', {
includeGlob: ['my.file'],
pipedData: 'bar',
replacementJs: true,
});
expect(result.err).not.toContain(warnMsg);
expect(fs.readFileSync('my.file', 'utf8')).toBe('barbar');
});

test('empty piped data does not trigger a warning', async () => {
fs.writeFileSync('my.file', 'foobar');
const result = await rr('foo', 'bar', {
includeGlob: ['my.file'],
pipedData: '',
});
expect(result.err).not.toContain(warnMsg);
});

test('piped data with only a newline does not trigger a warning', async () => {
fs.writeFileSync('my.file', 'foobar');
const resultN = await rr('foo', 'bar', {
includeGlob: ['my.file'],
pipedData: '\n',
});
expect(resultN.err).not.toContain(warnMsg);

const resultRN = await rr('foo', 'bar', {
includeGlob: ['my.file'],
pipedData: '\r\n',
});
expect(resultRN.err).not.toContain(warnMsg);
});

test('piped data when no files are given does not trigger a warning', async () => {
const result = await rr('foo', 'bar', {
includeGlob: [],
pipedData: 'foobar',
});
expect(result.err).not.toContain(warnMsg);
expect(result.out).toBe('barbar');
});
});