Skip to content
Open
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
20 changes: 18 additions & 2 deletions src/hooks/preparse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,24 @@ const hook: Hook.Preparse = async function ({ argv, options, context }) {
}
const crlf = contents.search('\r\n') !== -1;

const values =
ext === '.json' ? [JSON.stringify(JSON.parse(contents))] : contents?.trim().split(crlf ? '\r\n' : '\n');
let values: string[];

if (ext === '.json') {
// JSON files: parse and re-stringify (existing behavior)
values = [JSON.stringify(JSON.parse(contents))];
} else {
// Non-JSON files: split by lines and filter full-line comments
const lines = contents?.trim().split(crlf ? '\r\n' : '\n') || [];
values = lines.filter((line) => {
const trimmed = line.trim();
// Filter out lines that are only whitespace + comment (full-line comments)
if (trimmed.startsWith('#') || trimmed.startsWith('//')) {
return false;
}
// Keep all other lines unchanged, including empty lines
return true;
});
}

return [name, values] satisfies [string, string[]];
})
Expand Down
84 changes: 84 additions & 0 deletions test/hooks/preparse.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -326,4 +326,88 @@ describe('preparse hook test', () => {
]);
});
});

describe('comment filtering', () => {
it('should filter full-line comments starting with #', async () => {
const argv = [...baseArgs];
const flags = {
...baseFlags,
str: Flags.string(),
};
makeStubs([{ name: 'str', content: '# This is a comment\nactual-value\n# Another comment' }]);
const results = await config.runHook('preparse', { argv, options: { flags } });
expect(results.successes[0]).to.be.ok;
expect(results.successes[0].result).to.deep.equal([...baseArgs, '--str', 'actual-value']);
});

it('should filter full-line comments starting with //', async () => {
const argv = [...baseArgs];
const flags = {
...baseFlags,
str: Flags.string(),
};
makeStubs([{ name: 'str', content: '// This is a comment\nactual-value\n// Another comment' }]);
const results = await config.runHook('preparse', { argv, options: { flags } });
expect(results.successes[0]).to.be.ok;
expect(results.successes[0].result).to.deep.equal([...baseArgs, '--str', 'actual-value']);
});

it('should filter comments with leading whitespace', async () => {
const argv = [...baseArgs];
const flags = {
...baseFlags,
str: Flags.string(),
};
makeStubs([{ name: 'str', content: ' # Indented hash comment\nactual-value\n\t// Tab-indented slash comment' }]);
const results = await config.runHook('preparse', { argv, options: { flags } });
expect(results.successes[0]).to.be.ok;
expect(results.successes[0].result).to.deep.equal([...baseArgs, '--str', 'actual-value']);
});

it('should preserve lines that contain comments but are not full-line comments', async () => {
const argv = [...baseArgs];
const flags = {
...baseFlags,
str: Flags.string(),
};
makeStubs([{ name: 'str', content: 'value-with#hash\nvalue-with//slashes' }]);
const results = await config.runHook('preparse', { argv, options: { flags } });
expect(results.successes[0]).to.be.ok;
expect(results.successes[0].result).to.deep.equal([
...baseArgs,
'--str',
'value-with#hash',
'--str',
'value-with//slashes',
]);
});

it('should not filter comments in .json files', async () => {
const argv = [...baseArgs];
const flags = {
...baseFlags,
str: Flags.string(),
};
const jsonContent = {
comment: '# This should not be filtered',
slashes: '// This should not be filtered either',
};
makeStubs([{ name: 'str.json', content: JSON.stringify(jsonContent, null, 2) }]);
const results = await config.runHook('preparse', { argv, options: { flags } });
expect(results.successes[0]).to.be.ok;
expect(results.successes[0].result).to.deep.equal([...baseArgs, '--str', JSON.stringify(jsonContent)]);
});

it('should preserve whitespace in non-comment lines', async () => {
const argv = [...baseArgs];
const flags = {
...baseFlags,
str: Flags.string(),
};
makeStubs([{ name: 'str', content: '# Comment\n value with spaces \n// Another comment' }]);
const results = await config.runHook('preparse', { argv, options: { flags } });
expect(results.successes[0]).to.be.ok;
expect(results.successes[0].result).to.deep.equal([...baseArgs, '--str', ' value with spaces ']);
});
});
});