Skip to content

Commit

Permalink
Skip up-to-date checks during force build (#43666)
Browse files Browse the repository at this point in the history
* Skip up-to-date checks during force build

Save work by not checking timestamps or parsing the buildinfo file.
Retain correctness checks (like input file existence).

Suppress project status, which was confusing anyway.

* Print a message to indicate that --force is causing the rebuild

* Don't bother updating buildInfoChecked

* Add missing force check
  • Loading branch information
amcasey committed Apr 19, 2021
1 parent e0d5516 commit c671fe1
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 38 deletions.
4 changes: 4 additions & 0 deletions src/compiler/diagnosticMessages.json
Expand Up @@ -5041,6 +5041,10 @@
"code": 6387,
"reportsDeprecated": true
},
"Project '{0}' is being forcibly rebuilt": {
"category": "Message",
"code": 6388
},

"The expected type comes from property '{0}' which is declared here on type '{1}'": {
"category": "Message",
Expand Down
84 changes: 49 additions & 35 deletions src/compiler/tsbuildPublic.ts
Expand Up @@ -1350,6 +1350,7 @@ namespace ts {
}

function getUpToDateStatusWorker(state: SolutionBuilderState, project: ParsedCommandLine, resolvedPath: ResolvedConfigFilePath): UpToDateStatus {
const force = !!state.options.force;
let newestInputFileName: string = undefined!;
let newestInputFileTime = minimumDate;
const { host } = state;
Expand All @@ -1362,10 +1363,12 @@ namespace ts {
};
}

const inputTime = getModifiedTime(host, inputFile); host.getModifiedTime(inputFile);
if (inputTime > newestInputFileTime) {
newestInputFileName = inputFile;
newestInputFileTime = inputTime;
if (!force) {
const inputTime = getModifiedTime(host, inputFile); host.getModifiedTime(inputFile);
if (inputTime > newestInputFileTime) {
newestInputFileName = inputFile;
newestInputFileTime = inputTime;
}
}
}

Expand All @@ -1387,39 +1390,41 @@ namespace ts {
let missingOutputFileName: string | undefined;
let newestDeclarationFileContentChangedTime = minimumDate;
let isOutOfDateWithInputs = false;
for (const output of outputs) {
// Output is missing; can stop checking
// Don't immediately return because we can still be upstream-blocked, which is a higher-priority status
if (!host.fileExists(output)) {
missingOutputFileName = output;
break;
}
if (!force) {
for (const output of outputs) {
// Output is missing; can stop checking
// Don't immediately return because we can still be upstream-blocked, which is a higher-priority status
if (!host.fileExists(output)) {
missingOutputFileName = output;
break;
}

const outputTime = getModifiedTime(host, output);
if (outputTime < oldestOutputFileTime) {
oldestOutputFileTime = outputTime;
oldestOutputFileName = output;
}
const outputTime = getModifiedTime(host, output);
if (outputTime < oldestOutputFileTime) {
oldestOutputFileTime = outputTime;
oldestOutputFileName = output;
}

// If an output is older than the newest input, we can stop checking
// Don't immediately return because we can still be upstream-blocked, which is a higher-priority status
if (outputTime < newestInputFileTime) {
isOutOfDateWithInputs = true;
break;
}
// If an output is older than the newest input, we can stop checking
// Don't immediately return because we can still be upstream-blocked, which is a higher-priority status
if (outputTime < newestInputFileTime) {
isOutOfDateWithInputs = true;
break;
}

if (outputTime > newestOutputFileTime) {
newestOutputFileTime = outputTime;
newestOutputFileName = output;
}
if (outputTime > newestOutputFileTime) {
newestOutputFileTime = outputTime;
newestOutputFileName = output;
}

// Keep track of when the most recent time a .d.ts file was changed.
// In addition to file timestamps, we also keep track of when a .d.ts file
// had its file touched but not had its contents changed - this allows us
// to skip a downstream typecheck
if (isDeclarationFile(output)) {
const outputModifiedTime = getModifiedTime(host, output);
newestDeclarationFileContentChangedTime = newer(newestDeclarationFileContentChangedTime, outputModifiedTime);
// Keep track of when the most recent time a .d.ts file was changed.
// In addition to file timestamps, we also keep track of when a .d.ts file
// had its file touched but not had its contents changed - this allows us
// to skip a downstream typecheck
if (isDeclarationFile(output)) {
const outputModifiedTime = getModifiedTime(host, output);
newestDeclarationFileContentChangedTime = newer(newestDeclarationFileContentChangedTime, outputModifiedTime);
}
}
}

Expand Down Expand Up @@ -1459,7 +1464,8 @@ namespace ts {
}

// Check oldest output file name only if there is no missing output file name
if (!missingOutputFileName) {
// (a check we will have skipped if this is a forced build)
if (!force && !missingOutputFileName) {
// If the upstream project's newest file is older than our oldest output, we
// can't be out of date because of it
if (refStatus.newestInputFileTime && refStatus.newestInputFileTime <= oldestOutputFileTime) {
Expand Down Expand Up @@ -1509,7 +1515,7 @@ namespace ts {
if (extendedConfigStatus) return extendedConfigStatus;
}

if (!state.buildInfoChecked.has(resolvedPath)) {
if (!force && !state.buildInfoChecked.has(resolvedPath)) {
state.buildInfoChecked.set(resolvedPath, true);
const buildInfoPath = getTsBuildInfoEmitOutputFilePath(project.options);
if (buildInfoPath) {
Expand Down Expand Up @@ -2005,6 +2011,14 @@ namespace ts {
}

function reportUpToDateStatus(state: SolutionBuilderState, configFileName: string, status: UpToDateStatus) {
if (state.options.force && (status.type === UpToDateStatusType.UpToDate || status.type === UpToDateStatusType.UpToDateWithUpstreamTypes)) {
return reportStatus(
state,
Diagnostics.Project_0_is_being_forcibly_rebuilt,
relName(state, configFileName)
);
}

switch (status.type) {
case UpToDateStatusType.OutOfDateWithSelf:
return reportStatus(
Expand Down
Expand Up @@ -8,15 +8,15 @@ Output::
* src/logic/tsconfig.json
* src/tests/tsconfig.json

[[90m12:16:00 AM[0m] Project 'src/core/tsconfig.json' is up to date because newest input 'src/core/anotherModule.ts' is older than oldest output 'src/core/anotherModule.js'
[[90m12:16:00 AM[0m] Project 'src/core/tsconfig.json' is being forcibly rebuilt

[12:16:00 AM] Building project '/src/core/tsconfig.json'...

[[90m12:16:00 AM[0m] Project 'src/logic/tsconfig.json' is up to date with .d.ts files from its dependencies
[[90m12:16:00 AM[0m] Project 'src/logic/tsconfig.json' is being forcibly rebuilt

[12:16:00 AM] Building project '/src/logic/tsconfig.json'...

[[90m12:16:00 AM[0m] Project 'src/tests/tsconfig.json' is up to date with .d.ts files from its dependencies
[[90m12:16:00 AM[0m] Project 'src/tests/tsconfig.json' is being forcibly rebuilt

[12:16:00 AM] Building project '/src/tests/tsconfig.json'...

Expand Down

0 comments on commit c671fe1

Please sign in to comment.