Skip to content

Commit 7d9579e

Browse files
author
jon-freed
committed
feat: add comment support to flags-dir files
- Support full-line comments starting with # or // in non-JSON files - Preserve existing JSON file behavior (no comment processing) - Filter lines that contain only whitespace + comment markers - Maintain exact whitespace for non-comment lines - Add comprehensive test coverage for comment filtering scenarios
1 parent 399bc9e commit 7d9579e

File tree

2 files changed

+102
-2
lines changed

2 files changed

+102
-2
lines changed

src/hooks/preparse.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,24 @@ const hook: Hook.Preparse = async function ({ argv, options, context }) {
9696
}
9797
const crlf = contents.search('\r\n') !== -1;
9898

99-
const values =
100-
ext === '.json' ? [JSON.stringify(JSON.parse(contents))] : contents?.trim().split(crlf ? '\r\n' : '\n');
99+
let values: string[];
100+
101+
if (ext === '.json') {
102+
// JSON files: parse and re-stringify (existing behavior)
103+
values = [JSON.stringify(JSON.parse(contents))];
104+
} else {
105+
// Non-JSON files: split by lines and filter full-line comments
106+
const lines = contents?.trim().split(crlf ? '\r\n' : '\n') || [];
107+
values = lines.filter((line) => {
108+
const trimmed = line.trim();
109+
// Filter out lines that are only whitespace + comment (full-line comments)
110+
if (trimmed.startsWith('#') || trimmed.startsWith('//')) {
111+
return false;
112+
}
113+
// Keep all other lines unchanged, including empty lines
114+
return true;
115+
});
116+
}
101117

102118
return [name, values] satisfies [string, string[]];
103119
})

test/hooks/preparse.test.ts

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,4 +326,88 @@ describe('preparse hook test', () => {
326326
]);
327327
});
328328
});
329+
330+
describe('comment filtering', () => {
331+
it('should filter full-line comments starting with #', async () => {
332+
const argv = [...baseArgs];
333+
const flags = {
334+
...baseFlags,
335+
str: Flags.string(),
336+
};
337+
makeStubs([{ name: 'str', content: '# This is a comment\nactual-value\n# Another comment' }]);
338+
const results = await config.runHook('preparse', { argv, options: { flags } });
339+
expect(results.successes[0]).to.be.ok;
340+
expect(results.successes[0].result).to.deep.equal([...baseArgs, '--str', 'actual-value']);
341+
});
342+
343+
it('should filter full-line comments starting with //', async () => {
344+
const argv = [...baseArgs];
345+
const flags = {
346+
...baseFlags,
347+
str: Flags.string(),
348+
};
349+
makeStubs([{ name: 'str', content: '// This is a comment\nactual-value\n// Another comment' }]);
350+
const results = await config.runHook('preparse', { argv, options: { flags } });
351+
expect(results.successes[0]).to.be.ok;
352+
expect(results.successes[0].result).to.deep.equal([...baseArgs, '--str', 'actual-value']);
353+
});
354+
355+
it('should filter comments with leading whitespace', async () => {
356+
const argv = [...baseArgs];
357+
const flags = {
358+
...baseFlags,
359+
str: Flags.string(),
360+
};
361+
makeStubs([{ name: 'str', content: ' # Indented hash comment\nactual-value\n\t// Tab-indented slash comment' }]);
362+
const results = await config.runHook('preparse', { argv, options: { flags } });
363+
expect(results.successes[0]).to.be.ok;
364+
expect(results.successes[0].result).to.deep.equal([...baseArgs, '--str', 'actual-value']);
365+
});
366+
367+
it('should preserve lines that contain comments but are not full-line comments', async () => {
368+
const argv = [...baseArgs];
369+
const flags = {
370+
...baseFlags,
371+
str: Flags.string(),
372+
};
373+
makeStubs([{ name: 'str', content: 'value-with#hash\nvalue-with//slashes' }]);
374+
const results = await config.runHook('preparse', { argv, options: { flags } });
375+
expect(results.successes[0]).to.be.ok;
376+
expect(results.successes[0].result).to.deep.equal([
377+
...baseArgs,
378+
'--str',
379+
'value-with#hash',
380+
'--str',
381+
'value-with//slashes',
382+
]);
383+
});
384+
385+
it('should not filter comments in .json files', async () => {
386+
const argv = [...baseArgs];
387+
const flags = {
388+
...baseFlags,
389+
str: Flags.string(),
390+
};
391+
const jsonContent = {
392+
comment: '# This should not be filtered',
393+
slashes: '// This should not be filtered either',
394+
};
395+
makeStubs([{ name: 'str.json', content: JSON.stringify(jsonContent, null, 2) }]);
396+
const results = await config.runHook('preparse', { argv, options: { flags } });
397+
expect(results.successes[0]).to.be.ok;
398+
expect(results.successes[0].result).to.deep.equal([...baseArgs, '--str', JSON.stringify(jsonContent)]);
399+
});
400+
401+
it('should preserve whitespace in non-comment lines', async () => {
402+
const argv = [...baseArgs];
403+
const flags = {
404+
...baseFlags,
405+
str: Flags.string(),
406+
};
407+
makeStubs([{ name: 'str', content: '# Comment\n value with spaces \n// Another comment' }]);
408+
const results = await config.runHook('preparse', { argv, options: { flags } });
409+
expect(results.successes[0]).to.be.ok;
410+
expect(results.successes[0].result).to.deep.equal([...baseArgs, '--str', ' value with spaces ']);
411+
});
412+
});
329413
});

0 commit comments

Comments
 (0)