diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 6a339e265943b..e6e3c44afcd6f 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -284,7 +284,6 @@ namespace ts { // Write build information if applicable if (!buildInfoPath || targetSourceFile || emitSkipped) return; const program = host.getProgramBuildInfo(); - if (!bundle && !program) return; if (host.isEmitBlocked(buildInfoPath) || compilerOptions.noEmit) { emitSkipped = true; return; diff --git a/src/compiler/tsbuild.ts b/src/compiler/tsbuild.ts index 77de45bee011b..43b1e24a573db 100644 --- a/src/compiler/tsbuild.ts +++ b/src/compiler/tsbuild.ts @@ -1524,7 +1524,7 @@ namespace ts { if (buildInfoPath) { const value = state.readFileWithCache(buildInfoPath); const buildInfo = value && getBuildInfo(value); - if (buildInfo && buildInfo.version !== version) { + if (buildInfo && (buildInfo.bundle || buildInfo.program) && buildInfo.version !== version) { return { type: UpToDateStatusType.TsVersionOutputOfDate, version: buildInfo.version diff --git a/src/harness/fakes.ts b/src/harness/fakes.ts index c3a3bb621ce59..31e64e2c93129 100644 --- a/src/harness/fakes.ts +++ b/src/harness/fakes.ts @@ -418,7 +418,12 @@ namespace fakes { export const version = "FakeTSVersion"; export class SolutionBuilderHost extends CompilerHost implements ts.SolutionBuilderHost { - createProgram = ts.createEmitAndSemanticDiagnosticsBuilderProgram; + createProgram: ts.CreateProgram; + + constructor(sys: System | vfs.FileSystem, options?: ts.CompilerOptions, setParentNodes?: boolean, createProgram?: ts.CreateProgram) { + super(sys, options, setParentNodes); + this.createProgram = createProgram || ts.createEmitAndSemanticDiagnosticsBuilderProgram; + } readFile(path: string) { const value = super.readFile(path); diff --git a/src/testRunner/unittests/tsbuild/sample.ts b/src/testRunner/unittests/tsbuild/sample.ts index 130ebd9b8eb78..25ad761c8f18b 100644 --- a/src/testRunner/unittests/tsbuild/sample.ts +++ b/src/testRunner/unittests/tsbuild/sample.ts @@ -2,9 +2,9 @@ namespace ts { describe("unittests:: tsbuild:: on 'sample1' project", () => { let projFs: vfs.FileSystem; const { time, tick } = getTime(); - const testsOutputs = ["/src/tests/index.js"]; - const logicOutputs = ["/src/logic/index.js", "/src/logic/index.js.map", "/src/logic/index.d.ts"]; - const coreOutputs = ["/src/core/index.js", "/src/core/index.d.ts", "/src/core/index.d.ts.map"]; + const testsOutputs = ["/src/tests/index.js", "/src/tests/index.d.ts", "/src/tests/tsconfig.tsbuildinfo"]; + const logicOutputs = ["/src/logic/index.js", "/src/logic/index.js.map", "/src/logic/index.d.ts", "/src/logic/tsconfig.tsbuildinfo"]; + const coreOutputs = ["/src/core/index.js", "/src/core/index.d.ts", "/src/core/index.d.ts.map", "/src/core/tsconfig.tsbuildinfo"]; const allExpectedOutputs = [...testsOutputs, ...logicOutputs, ...coreOutputs]; before(() => { @@ -272,6 +272,35 @@ namespace ts { ); }); + it("does not rebuild if there is no program and bundle in the ts build info event if version doesnt match ts version", () => { + const fs = projFs.shadow(); + const host = new fakes.SolutionBuilderHost(fs, /*options*/ undefined, /*setParentNodes*/ undefined, createAbstractBuilder); + let builder = createSolutionBuilder(host, ["/src/tests"], { verbose: true }); + builder.build(); + host.assertDiagnosticMessages( + getExpectedDiagnosticForProjectsInBuild("src/core/tsconfig.json", "src/logic/tsconfig.json", "src/tests/tsconfig.json"), + [Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, "src/core/tsconfig.json", "src/core/anotherModule.js"], + [Diagnostics.Building_project_0, "/src/core/tsconfig.json"], + [Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, "src/logic/tsconfig.json", "src/logic/index.js"], + [Diagnostics.Building_project_0, "/src/logic/tsconfig.json"], + [Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, "src/tests/tsconfig.json", "src/tests/index.js"], + [Diagnostics.Building_project_0, "/src/tests/tsconfig.json"] + ); + verifyOutputsPresent(fs, allExpectedOutputs); + + host.clearDiagnostics(); + tick(); + builder = createSolutionBuilder(host, ["/src/tests"], { verbose: true }); + changeCompilerVersion(host); + builder.build(); + host.assertDiagnosticMessages( + getExpectedDiagnosticForProjectsInBuild("src/core/tsconfig.json", "src/logic/tsconfig.json", "src/tests/tsconfig.json"), + [Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, "src/core/tsconfig.json", "src/core/anotherModule.ts", "src/core/anotherModule.js"], + [Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, "src/logic/tsconfig.json", "src/logic/index.ts", "src/logic/index.js"], + [Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, "src/tests/tsconfig.json", "src/tests/index.ts", "src/tests/index.js"] + ); + }); + it("rebuilds from start if --f is passed", () => { const { host, builder } = initializeWithBuild({ force: true }); builder.build();