Skip to content

Skip up-to-date checks during force build #43666

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/compiler/diagnosticMessages.json
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ Output::
* src/logic/tsconfig.json
* src/tests/tsconfig.json

[12:16:00 AM] 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'
[12:16:00 AM] Project 'src/core/tsconfig.json' is being forcibly rebuilt

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

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

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

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

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

Expand Down