Skip to content

Commit 00c5a53

Browse files
authored
fix(cdk/schematics): errors when attempting to read some files (#19783)
In some cases the schematics fail to read a file which results in an error, because we weren't guarding against it properly. We had the correct types in place, but the tsconfig didn't have `strictNullChecks` enabled which prevented the compiler from reporting the errors. Fixes #19779.
1 parent abc94c4 commit 00c5a53

File tree

6 files changed

+42
-36
lines changed

6 files changed

+42
-36
lines changed

src/cdk/schematics/update-tool/component-resource-collector.ts

+21-15
Original file line numberDiff line numberDiff line change
@@ -133,13 +133,11 @@ export class ComponentResourceCollector {
133133
property.initializer.elements.forEach(el => {
134134
if (ts.isStringLiteralLike(el)) {
135135
const stylesheetPath = this._fileSystem.resolve(sourceFileDirPath, el.text);
136+
const stylesheet = this.resolveExternalStylesheet(stylesheetPath, node);
136137

137-
// In case the stylesheet does not exist in the file system, skip it gracefully.
138-
if (!this._fileSystem.exists(stylesheetPath)) {
139-
return;
138+
if (stylesheet) {
139+
this.resolvedStylesheets.push(stylesheet);
140140
}
141-
142-
this.resolvedStylesheets.push(this.resolveExternalStylesheet(stylesheetPath, node));
143141
}
144142
});
145143
}
@@ -155,24 +153,32 @@ export class ComponentResourceCollector {
155153
}
156154

157155
const fileContent = this._fileSystem.read(templatePath);
158-
const lineStartsMap = computeLineStartsMap(fileContent);
159156

160-
this.resolvedTemplates.push({
161-
filePath: templatePath,
162-
container: node,
163-
content: fileContent,
164-
inline: false,
165-
start: 0,
166-
getCharacterAndLineOfPosition: pos => getLineAndCharacterFromPosition(lineStartsMap, pos),
167-
});
157+
if (fileContent) {
158+
const lineStartsMap = computeLineStartsMap(fileContent);
159+
160+
this.resolvedTemplates.push({
161+
filePath: templatePath,
162+
container: node,
163+
content: fileContent,
164+
inline: false,
165+
start: 0,
166+
getCharacterAndLineOfPosition: p => getLineAndCharacterFromPosition(lineStartsMap, p),
167+
});
168+
}
168169
}
169170
});
170171
}
171172

172173
/** Resolves an external stylesheet by reading its content and computing line mappings. */
173174
resolveExternalStylesheet(filePath: WorkspacePath, container: ts.ClassDeclaration|null):
174-
ResolvedResource {
175+
ResolvedResource|null {
175176
const fileContent = this._fileSystem.read(filePath);
177+
178+
if (!fileContent) {
179+
return null;
180+
}
181+
176182
const lineStartsMap = computeLineStartsMap(fileContent);
177183

178184
return {

src/cdk/schematics/update-tool/file-system.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,11 @@ export abstract class FileSystem<T = WorkspacePath> {
5252
/** Applies all changes which have been recorded in update recorders. */
5353
abstract commitEdits(): void;
5454
/** Creates a new file with the given content. */
55-
abstract create(filePath: T, content: string);
55+
abstract create(filePath: T, content: string): void;
5656
/** Overwrites an existing file with the given content. */
57-
abstract overwrite(filePath: T, content: string);
57+
abstract overwrite(filePath: T, content: string): void;
5858
/** Deletes the given file. */
59-
abstract delete(filePath: T);
59+
abstract delete(filePath: T): void;
6060
/**
6161
* Resolves given paths to a resolved path in the file system. For example, the devkit
6262
* tree considers the actual workspace directory as file system root.

src/cdk/schematics/update-tool/index.ts

+11-9
Original file line numberDiff line numberDiff line change
@@ -102,15 +102,17 @@ export class UpdateProject<Context> {
102102
// specified in any Angular component. Therefore we allow for additional stylesheets
103103
// being specified. We visit them in each migration unless they have been already
104104
// discovered before as actual component resource.
105-
additionalStylesheetPaths.forEach(filePath => {
106-
const resolvedPath = this._fileSystem.resolve(filePath);
107-
const stylesheet = resourceCollector.resolveExternalStylesheet(resolvedPath, null);
108-
// Do not visit stylesheets which have been referenced from a component.
109-
if (!this._analyzedFiles.has(resolvedPath)) {
110-
migrations.forEach(r => r.visitStylesheet(stylesheet));
111-
this._analyzedFiles.add(resolvedPath);
112-
}
113-
});
105+
if (additionalStylesheetPaths) {
106+
additionalStylesheetPaths.forEach(filePath => {
107+
const resolvedPath = this._fileSystem.resolve(filePath);
108+
const stylesheet = resourceCollector.resolveExternalStylesheet(resolvedPath, null);
109+
// Do not visit stylesheets which have been referenced from a component.
110+
if (!this._analyzedFiles.has(resolvedPath) && stylesheet) {
111+
migrations.forEach(r => r.visitStylesheet(stylesheet));
112+
this._analyzedFiles.add(resolvedPath);
113+
}
114+
});
115+
}
114116

115117
// Call the "postAnalysis" method for each migration.
116118
migrations.forEach(r => r.postAnalysis());

src/cdk/schematics/update-tool/target-version.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export enum TargetVersion {
2222
* based on the "TargetVersion" enum.
2323
*/
2424
export function getAllVersionNames(): string[] {
25-
return Object.keys(TargetVersion)
26-
.filter(enumValue => typeof TargetVersion[enumValue] === 'string');
25+
return Object.keys(TargetVersion).filter(enumValue => {
26+
return typeof (TargetVersion as Record<string, string|undefined>)[enumValue] === 'string';
27+
});
2728
}

src/cdk/schematics/update-tool/tsconfig.json

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"compilerOptions": {
3+
"strict": true,
34
"lib": ["es2015"],
45
"types": ["node", "glob"]
56
}

src/cdk/schematics/update-tool/version-changes.ts

+3-7
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,11 @@ export type ValueOfChanges<T> = T extends VersionChanges<infer X>? X : null;
2929
*/
3030
export function getChangesForTarget<T>(target: TargetVersion, data: VersionChanges<T>): T[] {
3131
if (!data) {
32-
throw new Error(
33-
`No data could be found for target version: ${TargetVersion[target]}`);
32+
const version = (TargetVersion as Record<string, string>)[target];
33+
throw new Error(`No data could be found for target version: ${version}`);
3434
}
3535

36-
if (!data[target]) {
37-
return [];
38-
}
39-
40-
return data[target]!.reduce((result, prData) => result.concat(prData.changes), [] as T[]);
36+
return (data[target] || []).reduce((result, prData) => result.concat(prData.changes), [] as T[]);
4137
}
4238

4339
/**

0 commit comments

Comments
 (0)