Skip to content

Commit 2a3c0e5

Browse files
committed
Add support for --build --verbose invocations
This is super handy for debugging when a `--build` is failing for some reason. The default reporting from `tsc` or `glint` itself isn't always helpful: it tends to bottom out with a *symptom* like "some type is not defined" without any way to get to the root cause of *why* that type is not defined. Having `--verbose` available for a `--build` invocation surfaces additional information, including which `references` are being built or not, and why.
1 parent 84f23ef commit 2a3c0e5

File tree

2 files changed

+184
-0
lines changed

2 files changed

+184
-0
lines changed

packages/core/__tests__/cli/build.test.ts

+177
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ import {
1515
setupCompositeProject,
1616
} from 'glint-monorepo-test-utils';
1717

18+
const TIMESTAMP = /\d{1,2}:\d{2}:\d{2} (AM|PM)/g;
19+
1820
describe('CLI: single-pass build mode typechecking', () => {
1921
describe('simple projects using `--build`', () => {
2022
let project!: Project;
@@ -131,6 +133,89 @@ describe('CLI: single-pass build mode typechecking', () => {
131133
"
132134
`);
133135
});
136+
137+
describe('with `--verbose`', () => {
138+
test('prints verbose output for a valid basic project', async () => {
139+
let code = stripIndent`
140+
import '@glint/environment-ember-template-imports';
141+
import Component from '@glimmer/component';
142+
143+
type ApplicationArgs = {
144+
version: string;
145+
};
146+
147+
export default class Application extends Component<{ Args: ApplicationArgs }> {
148+
private startupTime = new Date().toISOString();
149+
150+
<template>
151+
Welcome to app v{{@version}}.
152+
The current time is {{this.startupTime}}.
153+
</template>
154+
}
155+
`;
156+
157+
project.write(INPUT_SFC, code);
158+
159+
let checkResult = await project.build({ reject: false, flags: ['--verbose'] });
160+
161+
expect(checkResult.exitCode).toBe(0);
162+
expect(checkResult.stdout.replace(TIMESTAMP, '<time stamp>')).toMatchInlineSnapshot(`
163+
"<time stamp> - Projects in this build:
164+
* tsconfig.json
165+
166+
<time stamp> - Project 'tsconfig.json' is out of date because output file 'dist/tsconfig.tsbuildinfo' does not exist
167+
168+
<time stamp> - Building project '/Users/ckrycho/dev/typed-ember/glint/test-packages/ephemeral/d6cdd8c6a1fd6/tsconfig.json'...
169+
"
170+
`);
171+
expect(checkResult.stderr).toEqual('');
172+
});
173+
174+
test('prints verbose output for a project with a basic template type error', async () => {
175+
let code = stripIndent`
176+
import '@glint/environment-ember-template-imports';
177+
import Component from '@glimmer/component';
178+
179+
type ApplicationArgs = {
180+
version: string;
181+
};
182+
183+
const truncate = (length: number, s: string): string =>
184+
s.slice(0, length);
185+
186+
export default class Application extends Component<{ Args: ApplicationArgs }> {
187+
private startupTime = new Date().toISOString();
188+
189+
<template>
190+
Welcome to app v{{@version}}.
191+
The current time is {{truncate this.startupTime 12}}.
192+
</template>
193+
}
194+
`;
195+
196+
project.write(INPUT_SFC, code);
197+
198+
let checkResult = await project.build({ reject: false, flags: ['--verbose'] });
199+
200+
expect(checkResult.exitCode).toBe(1);
201+
expect(checkResult.stdout.replace(TIMESTAMP, '<time stamp>')).toMatchInlineSnapshot(`
202+
"<time stamp> - Projects in this build:
203+
* tsconfig.json
204+
205+
<time stamp> - Project 'tsconfig.json' is out of date because output file 'dist/tsconfig.tsbuildinfo' does not exist
206+
207+
<time stamp> - Building project '/Users/ckrycho/dev/typed-ember/glint/test-packages/ephemeral/c9e994479a9ca/tsconfig.json'...
208+
"
209+
`);
210+
expect(stripAnsi(checkResult.stderr)).toMatchInlineSnapshot(`
211+
"src/index.gts:16:36 - error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
212+
213+
16 The current time is {{truncate this.startupTime 12}}.
214+
~~~~~~~~~~~~~~~~
215+
"
216+
`);
217+
});
218+
});
134219
});
135220

136221
describe('composite projects', () => {
@@ -1067,6 +1152,98 @@ describe('CLI: single-pass build mode typechecking', () => {
10671152
});
10681153
});
10691154
});
1155+
1156+
describe('with `--verbose`', () => {
1157+
test('for a valid composite subproject with a reference', async () => {
1158+
let checkResult = await projects.children.a.build({ reject: false, flags: ['--verbose'] });
1159+
1160+
expect(checkResult.stdout.replace(TIMESTAMP, '<time stamp>')).toMatchInlineSnapshot(`
1161+
"<time stamp> - Projects in this build:
1162+
* ../c/tsconfig.json
1163+
* tsconfig.json
1164+
1165+
<time stamp> - Project '../c/tsconfig.json' is out of date because output file '../c/tsconfig.tsbuildinfo' does not exist
1166+
1167+
<time stamp> - Building project '/Users/ckrycho/dev/typed-ember/glint/test-packages/ephemeral/d75a8393430fd/c/tsconfig.json'...
1168+
1169+
<time stamp> - Project 'tsconfig.json' is out of date because output file 'tsconfig.tsbuildinfo' does not exist
1170+
1171+
<time stamp> - Building project '/Users/ckrycho/dev/typed-ember/glint/test-packages/ephemeral/d75a8393430fd/a/tsconfig.json'...
1172+
"
1173+
`);
1174+
});
1175+
1176+
test('for a project transitively referenced by the root with a template type error, built from the main project', async () => {
1177+
let rootCode = stripIndent`
1178+
import Component from '@glimmer/component';
1179+
import A from '@glint-test/a';
1180+
import B from '@glint-test/b';
1181+
1182+
type ApplicationArgs = {
1183+
version: string;
1184+
};
1185+
1186+
export default class Application extends Component<{ Args: ApplicationArgs }> {
1187+
private startupTime = new Date().toISOString();
1188+
1189+
<template>
1190+
Welcome to app v{{@version}}.
1191+
The current time is {{this.startupTime}}.
1192+
</template>
1193+
}
1194+
`;
1195+
1196+
let aCode = stripIndent`
1197+
import C from '@glint-test/c';
1198+
const A = 'hello ' + C;
1199+
export default A;
1200+
`;
1201+
1202+
let bCode = stripIndent`
1203+
const B = 'ahoy';
1204+
export default B;
1205+
`;
1206+
1207+
let cCode = stripIndent`
1208+
const double = (n: number) => n * 2;
1209+
const useDouble = <template>{{double "hello"}}</template>;
1210+
const C = 'world';
1211+
export default C;
1212+
`;
1213+
1214+
projects.main.write(INPUT_SFC, rootCode);
1215+
projects.children.a.write(INPUT_SFC, aCode);
1216+
projects.children.b.write(INPUT_SFC, bCode);
1217+
projects.children.c.write(INPUT_SFC, cCode);
1218+
1219+
let checkResult = await projects.main.build({ reject: false, flags: ['--verbose'] });
1220+
1221+
expect(checkResult.stdout).toMatchInlineSnapshot(`
1222+
"12:10:54 PM - Projects in this build:
1223+
* ../c/tsconfig.json
1224+
* ../a/tsconfig.json
1225+
* ../b/tsconfig.json
1226+
* tsconfig.json
1227+
1228+
12:10:54 PM - Project '../c/tsconfig.json' is out of date because output file '../c/tsconfig.tsbuildinfo' does not exist
1229+
1230+
12:10:54 PM - Building project '/Users/ckrycho/dev/typed-ember/glint/test-packages/ephemeral/c9e5192458bc8/c/tsconfig.json'...
1231+
1232+
12:10:55 PM - Project '../a/tsconfig.json' can't be built because its dependency '../c' has errors
1233+
1234+
12:10:55 PM - Skipping build of project '/Users/ckrycho/dev/typed-ember/glint/test-packages/ephemeral/c9e5192458bc8/a/tsconfig.json' because its dependency '/Users/ckrycho/dev/typed-ember/glint/test-packages/ephemeral/c9e5192458bc8/c' has errors
1235+
1236+
12:10:55 PM - Project '../b/tsconfig.json' is out of date because output file '../b/tsconfig.tsbuildinfo' does not exist
1237+
1238+
12:10:55 PM - Building project '/Users/ckrycho/dev/typed-ember/glint/test-packages/ephemeral/c9e5192458bc8/b/tsconfig.json'...
1239+
1240+
12:10:55 PM - Project 'tsconfig.json' can't be built because its dependency '../a' was not built
1241+
1242+
12:10:55 PM - Skipping build of project '/Users/ckrycho/dev/typed-ember/glint/test-packages/ephemeral/c9e5192458bc8/main/tsconfig.json' because its dependency '/Users/ckrycho/dev/typed-ember/glint/test-packages/ephemeral/c9e5192458bc8/a' was not built
1243+
"
1244+
`);
1245+
});
1246+
});
10701247
});
10711248
});
10721249

packages/core/src/cli/index.ts

+7
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ const argv = yargs(process.argv.slice(2))
5454
description: `Show what would be built (or deleted, if specified with '--clean'). Same as the TS \`--dry\` flag.`,
5555
type: 'boolean',
5656
})
57+
.option('verbose', {
58+
implies: 'build',
59+
description:
60+
'Prints out verbose logging to explain what’s going on (may be combined with any other flag). Same as the TS `--verbose` flag.',
61+
type: 'boolean',
62+
})
5763
.option('incremental', {
5864
description:
5965
'Save .tsbuildinfo files to allow for incremental compilation of projects. Same as the TS `--incremental` flag.',
@@ -87,6 +93,7 @@ if (argv.build) {
8793
clean: argv.clean,
8894
force: argv.force,
8995
dry: argv.dry,
96+
verbose: argv.verbose,
9097
};
9198

9299
if ('incremental' in argv) {

0 commit comments

Comments
 (0)