Report file not found error about the project and watch config file even if not present

This commit is contained in:
Sheetal Nandi 2018-09-11 15:59:24 -07:00
parent 8a7550f82f
commit bdf1c782b2
2 changed files with 75 additions and 27 deletions

View File

@ -483,11 +483,11 @@ namespace ts {
function startWatching() {
const graph = getGlobalDependencyGraph();
for (const resolved of graph.buildQueue) {
// Watch this file
watchConfigFile(resolved);
const cfg = parseConfigFile(resolved);
if (cfg) {
// Watch this file
watchConfigFile(resolved);
// Update watchers for wildcard directories
watchWildCardDirectories(resolved, cfg);
@ -879,7 +879,11 @@ namespace ts {
// TODO:: handle this in better way later
const proj = parseConfigFile(resolved);
if (!proj) return; // ?
if (!proj) {
reportParseConfigFileDiagnostic(resolved);
return;
}
if (reloadLevel === ConfigFileProgramReloadLevel.Full) {
watchConfigFile(resolved);
watchWildCardDirectories(resolved, proj);
@ -954,6 +958,11 @@ namespace ts {
}
}
function reportParseConfigFileDiagnostic(proj: ResolvedConfigFileName) {
host.reportDiagnostic(configFileCache.getValue(proj) as Diagnostic);
storeErrorSummary(proj, 1);
}
function buildSingleProject(proj: ResolvedConfigFileName): BuildResultFlags {
if (options.dry) {
reportStatus(Diagnostics.A_non_dry_build_would_build_project_0, proj);
@ -969,8 +978,7 @@ namespace ts {
if (!configFile) {
// Failed to read the config file
resultFlags |= BuildResultFlags.ConfigFileErrors;
host.reportDiagnostic(configFileCache.getValue(proj) as Diagnostic);
storeErrorSummary(proj, 1);
reportParseConfigFileDiagnostic(proj);
projectStatus.setValue(proj, { type: UpToDateStatusType.Unbuildable, reason: "Config file errors" });
return resultFlags;
}
@ -995,10 +1003,7 @@ namespace ts {
...program.getSyntacticDiagnostics()];
if (syntaxDiagnostics.length) {
resultFlags |= BuildResultFlags.SyntaxErrors;
for (const diag of syntaxDiagnostics) {
host.reportDiagnostic(diag);
}
storeErrors(proj, syntaxDiagnostics);
reportErrors(proj, syntaxDiagnostics);
projectStatus.setValue(proj, { type: UpToDateStatusType.Unbuildable, reason: "Syntactic errors" });
return resultFlags;
}
@ -1008,10 +1013,7 @@ namespace ts {
const declDiagnostics = program.getDeclarationDiagnostics();
if (declDiagnostics.length) {
resultFlags |= BuildResultFlags.DeclarationEmitErrors;
for (const diag of declDiagnostics) {
host.reportDiagnostic(diag);
}
storeErrors(proj, declDiagnostics);
reportErrors(proj, declDiagnostics);
projectStatus.setValue(proj, { type: UpToDateStatusType.Unbuildable, reason: "Declaration file errors" });
return resultFlags;
}
@ -1021,10 +1023,7 @@ namespace ts {
const semanticDiagnostics = program.getSemanticDiagnostics();
if (semanticDiagnostics.length) {
resultFlags |= BuildResultFlags.TypeErrors;
for (const diag of semanticDiagnostics) {
host.reportDiagnostic(diag);
}
storeErrors(proj, semanticDiagnostics);
reportErrors(proj, semanticDiagnostics);
projectStatus.setValue(proj, { type: UpToDateStatusType.Unbuildable, reason: "Semantic errors" });
return resultFlags;
}
@ -1091,6 +1090,7 @@ namespace ts {
const parsed = parseConfigFile(proj);
if (parsed === undefined) {
// File has gone missing; fine to ignore here
reportParseConfigFileDiagnostic(proj);
continue;
}
const outputs = getAllProjectOutputs(parsed);
@ -1133,6 +1133,7 @@ namespace ts {
for (const next of graph.buildQueue) {
const proj = parseConfigFile(next);
if (proj === undefined) {
reportParseConfigFileDiagnostic(next);
anyFailed = true;
break;
}
@ -1144,7 +1145,7 @@ namespace ts {
const projName = proj.options.configFilePath!;
if (status.type === UpToDateStatusType.UpToDate && !options.force) {
reportErrors(errors);
reportErrors(next, errors);
// Up to date, skip
if (defaultOptions.dry) {
// In a dry build, inform the user of this fact
@ -1154,20 +1155,20 @@ namespace ts {
}
if (status.type === UpToDateStatusType.UpToDateWithUpstreamTypes && !options.force) {
reportErrors(errors);
reportErrors(next, errors);
// Fake build
updateOutputTimestamps(proj);
continue;
}
if (status.type === UpToDateStatusType.UpstreamBlocked) {
reportErrors(errors);
reportErrors(next, errors);
if (options.verbose) reportStatus(Diagnostics.Skipping_build_of_project_0_because_its_dependency_1_has_errors, projName, status.upstreamProjectName);
continue;
}
if (status.type === UpToDateStatusType.ContainerOnly) {
reportErrors(errors);
reportErrors(next, errors);
// Do nothing
continue;
}
@ -1179,8 +1180,9 @@ namespace ts {
return anyFailed ? ExitStatus.DiagnosticsPresent_OutputsSkipped : ExitStatus.Success;
}
function reportErrors(errors: Diagnostic[]) {
errors.forEach((err) => host.reportDiagnostic(err));
function reportErrors(proj: ResolvedConfigFileName, errors: ReadonlyArray<Diagnostic>) {
errors.forEach(err => host.reportDiagnostic(err));
storeErrors(proj, errors);
}
/**

View File

@ -98,9 +98,7 @@ namespace ts.tscWatch {
function createSolutionInWatchMode() {
const host = createWatchedSystem(allFiles, { currentDirectory: projectsLocation });
createSolutionBuilderWithWatch(host, [`${project}/${SubProject.tests}`]);
checkWatchedFiles(host, testProjectExpectedWatchedFiles);
checkWatchedDirectories(host, emptyArray, /*recursive*/ false);
checkWatchedDirectories(host, [projectPath(SubProject.core), projectPath(SubProject.logic)], /*recursive*/ true);
verifyWatches(host);
checkOutputErrorsInitial(host, emptyArray);
const outputFileStamps = getOutputFileStamps(host);
for (const stamp of outputFileStamps) {
@ -108,6 +106,13 @@ namespace ts.tscWatch {
}
return host;
}
function verifyWatches(host: WatchedSystem) {
checkWatchedFiles(host, testProjectExpectedWatchedFiles);
checkWatchedDirectories(host, emptyArray, /*recursive*/ false);
checkWatchedDirectories(host, [projectPath(SubProject.core), projectPath(SubProject.logic)], /*recursive*/ true);
}
it("creates solution in watch mode", () => {
createSolutionInWatchMode();
});
@ -197,6 +202,47 @@ export class someClass2 { }`);
});
it("watches config files that are not present", () => {
const allFiles = [libFile, ...core, logic[1], ...tests];
const host = createWatchedSystem(allFiles, { currentDirectory: projectsLocation });
createSolutionBuilderWithWatch(host, [`${project}/${SubProject.tests}`]);
checkWatchedFiles(host, [core[0], core[1], core[2], logic[0], ...tests].map(f => f.path));
checkWatchedDirectories(host, emptyArray, /*recursive*/ false);
checkWatchedDirectories(host, [projectPath(SubProject.core)], /*recursive*/ true);
checkOutputErrorsInitial(host, [
createCompilerDiagnostic(Diagnostics.File_0_not_found, logic[0].path)
]);
for (const f of [
...getOutputFileNames(SubProject.core, "anotherModule"),
...getOutputFileNames(SubProject.core, "index")
]) {
assert.isTrue(host.fileExists(f), `${f} expected to be present`);
}
for (const f of [
...getOutputFileNames(SubProject.logic, "index"),
...getOutputFileNames(SubProject.tests, "index")
]) {
assert.isFalse(host.fileExists(f), `${f} expected to be absent`);
}
// Create tsconfig file for logic and see that build succeeds
const initial = getOutputFileStamps(host);
host.writeFile(logic[0].path, logic[0].content);
host.checkTimeoutQueueLengthAndRun(1); // Builds logic
const changedLogic = getOutputFileStamps(host);
verifyChangedFiles(changedLogic, initial, [
...getOutputFileNames(SubProject.logic, "index")
]);
host.checkTimeoutQueueLengthAndRun(1); // Builds tests
const changedTests = getOutputFileStamps(host);
verifyChangedFiles(changedTests, changedLogic, [
...getOutputFileNames(SubProject.tests, "index")
]);
host.checkTimeoutQueueLength(0);
checkOutputErrorsIncremental(host, emptyArray);
verifyWatches(host);
});
// TODO: write tests reporting errors but that will have more involved work since file
});
}