Skip to content

Commit 0e2e902

Browse files
committed
implement warning for missing cmkOptions.enabled
1 parent 113b818 commit 0e2e902

8 files changed

Lines changed: 101 additions & 35 deletions

File tree

packages/codegen/e2e-test/index.test.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ test('generates .d.ts', async () => {
3333
"noEmit": true,
3434
"paths": { "@/*": ["./src/*"] },
3535
"rootDirs": [".", "generated"]
36-
}
36+
},
37+
"cmkOptions": { "enabled": true }
3738
}
3839
`,
3940
});
@@ -91,7 +92,7 @@ test('prints version number', () => {
9192
test('reports CSS syntax error', async () => {
9293
const iff = await createIFF({
9394
'src/a.module.css': `badword`,
94-
'tsconfig.json': '{}',
95+
'tsconfig.json': '{ "cmkOptions": { "enabled": true } }',
9596
});
9697
const cmk = spawnSync('node', [binPath, '--pretty'], { cwd: iff.rootDir });
9798
expect(cmk.status).toBe(1);
@@ -138,7 +139,8 @@ test('generates .d.ts with circular import', async () => {
138139
"lib": ["ES2015"],
139140
"noEmit": true,
140141
"rootDirs": [".", "generated"]
141-
}
142+
},
143+
"cmkOptions": { "enabled": true }
142144
}
143145
`,
144146
});

packages/codegen/src/project.test.ts

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { createIFF } from './test/fixture.js';
1010
describe('createProject', () => {
1111
test('creates project', async () => {
1212
const iff = await createIFF({
13-
'tsconfig.json': '{}',
13+
'tsconfig.json': '{ "cmkOptions": { "enabled": true } }',
1414
});
1515
const project = createProject({ project: iff.rootDir });
1616
expect(project.config.dtsOutDir).toContain('generated');
@@ -23,7 +23,7 @@ describe('createProject', () => {
2323
'throws ReadCSSModuleFileError when a CSS module file cannot be read',
2424
async () => {
2525
const iff = await createIFF({
26-
'tsconfig.json': '{}',
26+
'tsconfig.json': '{ "cmkOptions": { "enabled": true } }',
2727
'src/a.module.css': '.a1 { color: red; }',
2828
});
2929
await chmod(iff.paths['src/a.module.css'], 0o200); // Remove read permission
@@ -50,7 +50,7 @@ test('isWildcardMatchedFile', async () => {
5050
describe('addFile', () => {
5151
test('The diagnostics of the added file are reported, and .d.ts file is emitted', async () => {
5252
const iff = await createIFF({
53-
'tsconfig.json': '{}',
53+
'tsconfig.json': '{ "cmkOptions": { "enabled": true } }',
5454
'src': {},
5555
});
5656
const project = createProject({ project: iff.rootDir });
@@ -90,7 +90,7 @@ describe('addFile', () => {
9090
// - The check stage cache for files that directly import the added file should be invalidated.
9191
// - The check stage cache for files that indirectly import the added file should also be invalidated.
9292
const iff = await createIFF({
93-
'tsconfig.json': '{}',
93+
'tsconfig.json': '{ "cmkOptions": { "enabled": true } }',
9494
'src/b.module.css': '@import "./a.module.css";', // directly
9595
'src/c.module.css': '@value a_1 from "./b.module.css";', // indirectly
9696
});
@@ -134,7 +134,8 @@ describe('addFile', () => {
134134
"paths": {
135135
"@/a.module.css": ["src/a-1.module.css", "src/a-2.module.css"]
136136
}
137-
}
137+
},
138+
"cmkOptions": { "enabled": true }
138139
}
139140
`,
140141
'src/a-2.module.css': '@value a_2: red;',
@@ -165,7 +166,7 @@ describe('addFile', () => {
165166
describe('updateFile', () => {
166167
test('The new diagnostics of the changed file are reported, and new .d.ts file is emitted', async () => {
167168
const iff = await createIFF({
168-
'tsconfig.json': '{}',
169+
'tsconfig.json': '{ "cmkOptions": { "enabled": true } }',
169170
'src/a.module.css': '',
170171
});
171172
const project = createProject({ project: iff.rootDir });
@@ -226,7 +227,7 @@ describe('updateFile', () => {
226227
// - The check stage cache for files that directly import the changed file should be invalidated.
227228
// - The check stage cache for files that indirectly import the changed file should also be invalidated.
228229
const iff = await createIFF({
229-
'tsconfig.json': '{}',
230+
'tsconfig.json': '{ "cmkOptions": { "enabled": true } }',
230231
'src/a.module.css': '',
231232
'src/b.module.css': dedent`
232233
@value a_1 from "./a.module.css";
@@ -268,7 +269,7 @@ describe('updateFile', () => {
268269
describe('removeFile', () => {
269270
test('The diagnostics of the removed file are not reported, and .d.ts file is not emitted', async () => {
270271
const iff = await createIFF({
271-
'tsconfig.json': '{}',
272+
'tsconfig.json': '{ "cmkOptions": { "enabled": true } }',
272273
'src/a.module.css': '.a_1 {',
273274
});
274275
const project = createProject({ project: iff.rootDir });
@@ -308,7 +309,7 @@ describe('removeFile', () => {
308309
// - The check stage cache for files that directly import the changed file should be invalidated.
309310
// - The check stage cache for files that indirectly import the changed file should also be invalidated.
310311
const iff = await createIFF({
311-
'tsconfig.json': '{}',
312+
'tsconfig.json': '{ "cmkOptions": { "enabled": true } }',
312313
'src/a.module.css': '@value a_1: red;',
313314
'src/b.module.css': '@import "./a.module.css";', // directly
314315
'src/c.module.css': '@value a_1 from "./b.module.css";', // indirectly
@@ -353,7 +354,8 @@ describe('removeFile', () => {
353354
"paths": {
354355
"@/a.module.css": ["src/a-1.module.css", "src/a-2.module.css"]
355356
}
356-
}
357+
},
358+
"cmkOptions": { "enabled": true }
357359
}
358360
`,
359361
'src/a-1.module.css': '@value a_1: red;',
@@ -385,16 +387,32 @@ describe('removeFile', () => {
385387
describe('getDiagnostics', () => {
386388
test('returns empty array when no diagnostics', async () => {
387389
const iff = await createIFF({
388-
'tsconfig.json': '{}',
390+
'tsconfig.json': '{ "cmkOptions": { "enabled": true } }',
389391
'src/a.module.css': '.a_1 { color: red; }',
390392
});
391393
const project = createProject({ project: iff.rootDir });
392394
const diagnostics = project.getDiagnostics();
393395
expect(diagnostics).toEqual([]);
394396
});
397+
test('returns warning when enabled is not specified', async () => {
398+
const iff = await createIFF({
399+
'tsconfig.json': '{}',
400+
'src/a.module.css': '.a_1 { color: red; }',
401+
});
402+
const project = createProject({ project: iff.rootDir });
403+
const diagnostics = project.getDiagnostics();
404+
expect(formatDiagnostics(diagnostics, iff.rootDir)).toMatchInlineSnapshot(`
405+
[
406+
{
407+
"category": "warning",
408+
"text": ""cmkOptions.enabled" will be required in a future version of css-modules-kit. Add \`"cmkOptions": { "enabled": true }\` to <rootDir>/tsconfig.json. See https://github.com/mizdra/css-modules-kit/issues/289 for details.",
409+
},
410+
]
411+
`);
412+
});
395413
test('returns project diagnostics', async () => {
396414
const iff = await createIFF({
397-
'tsconfig.json': '{ "cmkOptions": { "dtsOutDir": 1 } }',
415+
'tsconfig.json': '{ "cmkOptions": { "enabled": true, "dtsOutDir": 1 } }',
398416
});
399417
const project = createProject({ project: iff.rootDir });
400418
const diagnostics = project.getDiagnostics();
@@ -413,7 +431,7 @@ describe('getDiagnostics', () => {
413431
});
414432
test('returns syntactic diagnostics', async () => {
415433
const iff = await createIFF({
416-
'tsconfig.json': '{}',
434+
'tsconfig.json': '{ "cmkOptions": { "enabled": true } }',
417435
'src/a.module.css': '.a_1 {',
418436
'src/b.module.css': '.a_2 { color }',
419437
});
@@ -447,7 +465,7 @@ describe('getDiagnostics', () => {
447465

448466
test('returns semantic diagnostics', async () => {
449467
const iff = await createIFF({
450-
'tsconfig.json': '{}',
468+
'tsconfig.json': '{ "cmkOptions": { "enabled": true } }',
451469
'src/a.module.css': `@import './non-existent-1.module.css';`,
452470
'src/b.module.css': `@import './non-existent-2.module.css';`,
453471
});
@@ -480,7 +498,7 @@ describe('getDiagnostics', () => {
480498
});
481499
test('skips semantic diagnostics when project or syntactic diagnostics exist', async () => {
482500
const iff = await createIFF({
483-
'tsconfig.json': '{ "cmkOptions": { "dtsOutDir": 1 } }',
501+
'tsconfig.json': '{ "cmkOptions": { "enabled": true, "dtsOutDir": 1 } }',
484502
'src/a.module.css': '.a_1 {',
485503
'src/b.module.css': `@import './non-existent.module.css';`,
486504
});
@@ -510,7 +528,7 @@ describe('getDiagnostics', () => {
510528
describe('emitDtsFiles', () => {
511529
test('emits .d.ts files', async () => {
512530
const iff = await createIFF({
513-
'tsconfig.json': '{}',
531+
'tsconfig.json': '{ "cmkOptions": { "enabled": true } }',
514532
'src/a.module.css': '.a1 { color: red; }',
515533
'src/b.module.css': '.b1 { color: blue; }',
516534
});
@@ -535,7 +553,7 @@ describe('emitDtsFiles', () => {
535553
});
536554
test('does not emit .d.ts files for files not matched by `pattern`', async () => {
537555
const iff = await createIFF({
538-
'tsconfig.json': '{}',
556+
'tsconfig.json': '{ "cmkOptions": { "enabled": true } }',
539557
'src/a.module.css': '.a1 { color: red; }',
540558
'src/b.css': '.b1 { color: blue; }',
541559
});

packages/codegen/src/project.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,12 @@ export function createProject(args: ProjectArgs): Project {
166166
function getProjectDiagnostics() {
167167
const diagnostics: Diagnostic[] = [];
168168
diagnostics.push(...config.diagnostics);
169+
if (config.enabled === undefined) {
170+
diagnostics.push({
171+
category: 'warning',
172+
text: `"cmkOptions.enabled" will be required in a future version of css-modules-kit. Add \`"cmkOptions": { "enabled": true }\` to ${config.configFileName}. See https://github.com/mizdra/css-modules-kit/issues/289 for details.`,
173+
});
174+
}
169175
if (cssModuleMap.size === 0) {
170176
diagnostics.push({
171177
category: 'error',

packages/codegen/src/runner.test.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ describe('runCMK', () => {
4545
});
4646
test('reports diagnostics if errors are found', async () => {
4747
const iff = await createIFF({
48-
'tsconfig.json': '{}',
48+
'tsconfig.json': '{ "cmkOptions": { "enabled": true } }',
4949
'src/a.module.css': '.a_1 {',
5050
'src/b.module.css': '.b_1 { color: red; }',
5151
});
@@ -69,7 +69,7 @@ describe('runCMK', () => {
6969
});
7070
test('returns false if errors are found', async () => {
7171
const iff = await createIFF({
72-
'tsconfig.json': '{}',
72+
'tsconfig.json': '{ "cmkOptions": { "enabled": true } }',
7373
'src/a.module.css': '.a_1 {',
7474
});
7575
const result1 = await runCMK(fakeParsedArgs({ project: iff.rootDir }), createLoggerSpy());
@@ -80,7 +80,7 @@ describe('runCMK', () => {
8080
});
8181
test('emits .d.ts files even if there are diagnostics', async () => {
8282
const iff = await createIFF({
83-
'tsconfig.json': '{}',
83+
'tsconfig.json': '{ "cmkOptions": { "enabled": true } }',
8484
'src/a.module.css': '.a_1 {',
8585
'src/b.module.css': '.b_1 { color: red; }',
8686
});
@@ -92,7 +92,7 @@ describe('runCMK', () => {
9292
});
9393
test('removes output directory before emitting files when `clean` is true', async () => {
9494
const iff = await createIFF({
95-
'tsconfig.json': '{}',
95+
'tsconfig.json': '{ "cmkOptions": { "enabled": true } }',
9696
'src/a.module.css': '.a_1 { color: red; }',
9797
'generated/src/old.module.css.d.ts': '',
9898
});
@@ -141,7 +141,7 @@ describe('runCMKInWatchMode', () => {
141141
});
142142
test('reports diagnostics if errors are found', async () => {
143143
const iff = await createIFF({
144-
'tsconfig.json': '{}',
144+
'tsconfig.json': '{ "cmkOptions": { "enabled": true } }',
145145
'src/a.module.css': '.a_1 {',
146146
'src/b.module.css': '.b_1 { color: red; }',
147147
});
@@ -165,7 +165,7 @@ describe('runCMKInWatchMode', () => {
165165
});
166166
test('emits .d.ts files even if there are diagnostics', async () => {
167167
const iff = await createIFF({
168-
'tsconfig.json': '{}',
168+
'tsconfig.json': '{ "cmkOptions": { "enabled": true } }',
169169
'src/a.module.css': '.a_1 {',
170170
'src/b.module.css': '.b_1 { color: red; }',
171171
});
@@ -177,7 +177,7 @@ describe('runCMKInWatchMode', () => {
177177
});
178178
test('removes output directory before emitting files when `clean` is true', async () => {
179179
const iff = await createIFF({
180-
'tsconfig.json': '{}',
180+
'tsconfig.json': '{ "cmkOptions": { "enabled": true } }',
181181
'src/a.module.css': '.a_1 { color: red; }',
182182
'generated/src/old.module.css.d.ts': '',
183183
});
@@ -187,7 +187,7 @@ describe('runCMKInWatchMode', () => {
187187
});
188188
test('reports system error occurs during watching', async () => {
189189
const iff = await createIFF({
190-
'tsconfig.json': '{}',
190+
'tsconfig.json': '{ "cmkOptions": { "enabled": true } }',
191191
'src/a.module.css': '.a_1 { color: red; }',
192192
});
193193

@@ -232,7 +232,7 @@ describe('runCMKInWatchMode', () => {
232232
});
233233
test('reports diagnostics and emits files on changes', async () => {
234234
const iff = await createIFF({
235-
'tsconfig.json': '{}',
235+
'tsconfig.json': '{ "cmkOptions": { "enabled": true } }',
236236
'src/a.module.css': '.a_1 { color: red; }',
237237
});
238238
const loggerSpy = createLoggerSpy();
@@ -267,7 +267,7 @@ describe('runCMKInWatchMode', () => {
267267
});
268268
test('batches rapid file changes', async () => {
269269
const iff = await createIFF({
270-
'tsconfig.json': '{}',
270+
'tsconfig.json': '{ "cmkOptions": { "enabled": true } }',
271271
'src': {},
272272
});
273273
const loggerSpy = createLoggerSpy();
@@ -291,7 +291,7 @@ describe('runCMKInWatchMode', () => {
291291
});
292292
test('does not clear screen when preserveWatchOutput is true', async () => {
293293
const iff = await createIFF({
294-
'tsconfig.json': '{}',
294+
'tsconfig.json': '{ "cmkOptions": { "enabled": true } }',
295295
'src/a.module.css': '.a_1 { color: red; }',
296296
});
297297

packages/codegen/src/runner.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ export async function runCMK(args: RunnerArgs, logger: Logger): Promise<boolean>
3232
const diagnostics = project.getDiagnostics();
3333
if (diagnostics.length > 0) {
3434
logger.logDiagnostics(diagnostics);
35-
return false;
35+
const hasErrors = diagnostics.some((d) => d.category === 'error');
36+
return !hasErrors;
3637
}
3738
return true;
3839
}
@@ -138,8 +139,11 @@ export async function runCMKInWatchMode(args: RunnerArgs, logger: Logger): Promi
138139
if (diagnostics.length > 0) {
139140
logger.logDiagnostics(diagnostics);
140141
}
142+
const errorCount = diagnostics.filter((d) => d.category === 'error').length;
143+
const warningCount = diagnostics.filter((d) => d.category === 'warning').length;
144+
const warningPart = warningCount > 0 ? ` and ${warningCount} warning${warningCount === 1 ? '' : 's'}` : '';
141145
logger.logMessage(
142-
`Found ${diagnostics.length} error${diagnostics.length === 1 ? '' : 's'}. Watching for file changes.`,
146+
`Found ${errorCount} error${errorCount === 1 ? '' : 's'}${warningPart}. Watching for file changes.`,
143147
{ time: true },
144148
);
145149
if (args.preserveWatchOutput) {

0 commit comments

Comments
 (0)