Create api for buildNextProject
This commit is contained in:
parent
0a255249f6
commit
71b190af61
4 changed files with 80 additions and 11 deletions
|
@ -260,9 +260,15 @@ namespace ts {
|
|||
export interface SolutionBuilderWithWatchHost<T extends BuilderProgram> extends SolutionBuilderHostBase<T>, WatchHost {
|
||||
}
|
||||
|
||||
export interface SolutionBuilderResult<T> {
|
||||
project: ResolvedConfigFileName;
|
||||
result: T;
|
||||
}
|
||||
|
||||
export interface SolutionBuilder {
|
||||
build(project?: string, cancellationToken?: CancellationToken): ExitStatus;
|
||||
clean(project?: string): ExitStatus;
|
||||
buildNextProject(cancellationToken?: CancellationToken): SolutionBuilderResult<ExitStatus> | undefined;
|
||||
|
||||
// Currently used for testing but can be made public if needed:
|
||||
/*@internal*/ getBuildOrder(): ReadonlyArray<ResolvedConfigFileName>;
|
||||
|
@ -401,6 +407,7 @@ namespace ts {
|
|||
return {
|
||||
build,
|
||||
clean,
|
||||
buildNextProject,
|
||||
getBuildOrder,
|
||||
getUpToDateStatusOfProject,
|
||||
invalidateProject,
|
||||
|
@ -1437,10 +1444,7 @@ namespace ts {
|
|||
return resolvedProject ? createBuildOrder([resolvedProject]) : getBuildOrder();
|
||||
}
|
||||
|
||||
function build(project?: string, cancellationToken?: CancellationToken): ExitStatus {
|
||||
const buildOrder = getBuildOrderFor(project);
|
||||
if (!buildOrder) return ExitStatus.InvalidProject_OutputsSkipped;
|
||||
|
||||
function setupInitialBuild(cancellationToken: CancellationToken | undefined) {
|
||||
// Set initial build if not already built
|
||||
if (allProjectBuildPending) {
|
||||
allProjectBuildPending = false;
|
||||
|
@ -1455,6 +1459,27 @@ namespace ts {
|
|||
cancellationToken.throwIfCancellationRequested();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function buildNextProject(cancellationToken?: CancellationToken): SolutionBuilderResult<ExitStatus> | undefined {
|
||||
setupInitialBuild(cancellationToken);
|
||||
const invalidatedProject = getNextInvalidatedProject(getBuildOrder());
|
||||
if (!invalidatedProject) return undefined;
|
||||
|
||||
buildInvalidatedProject(invalidatedProject, cancellationToken);
|
||||
return {
|
||||
project: invalidatedProject.project,
|
||||
result: diagnostics.has(invalidatedProject.projectPath) ?
|
||||
ExitStatus.DiagnosticsPresent_OutputsSkipped :
|
||||
ExitStatus.Success
|
||||
};
|
||||
}
|
||||
|
||||
function build(project?: string, cancellationToken?: CancellationToken): ExitStatus {
|
||||
const buildOrder = getBuildOrderFor(project);
|
||||
if (!buildOrder) return ExitStatus.InvalidProject_OutputsSkipped;
|
||||
|
||||
setupInitialBuild(cancellationToken);
|
||||
|
||||
let successfulProjects = 0;
|
||||
let errorProjects = 0;
|
||||
|
|
|
@ -2,9 +2,10 @@ namespace ts {
|
|||
describe("unittests:: tsbuild:: on 'sample1' project", () => {
|
||||
let projFs: vfs.FileSystem;
|
||||
const { time, tick } = getTime();
|
||||
const allExpectedOutputs = ["/src/tests/index.js",
|
||||
"/src/core/index.js", "/src/core/index.d.ts", "/src/core/index.d.ts.map",
|
||||
"/src/logic/index.js", "/src/logic/index.js.map", "/src/logic/index.d.ts"];
|
||||
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 allExpectedOutputs = [...testsOutputs, ...logicOutputs, ...coreOutputs];
|
||||
|
||||
before(() => {
|
||||
projFs = loadProjectFromDisk("tests/projects/sample1", time);
|
||||
|
@ -140,8 +141,8 @@ namespace ts {
|
|||
builder.build();
|
||||
const result = builder.clean("/src/logic");
|
||||
host.assertDiagnosticMessages(/*empty*/);
|
||||
verifyOutputsPresent(fs, [allExpectedOutputs[0]]);
|
||||
verifyOutputsAbsent(fs, allExpectedOutputs.slice(1));
|
||||
verifyOutputsPresent(fs, testsOutputs);
|
||||
verifyOutputsAbsent(fs, [...logicOutputs, ...coreOutputs]);
|
||||
assert.equal(result, ExitStatus.Success);
|
||||
});
|
||||
|
||||
|
@ -334,8 +335,8 @@ namespace ts {
|
|||
const builder = createSolutionBuilder(host, ["/src/tests"], {});
|
||||
const result = builder.build("/src/logic");
|
||||
host.assertDiagnosticMessages(/*empty*/);
|
||||
verifyOutputsAbsent(fs, [allExpectedOutputs[0]]);
|
||||
verifyOutputsPresent(fs, allExpectedOutputs.slice(1));
|
||||
verifyOutputsAbsent(fs, testsOutputs);
|
||||
verifyOutputsPresent(fs, [...logicOutputs, ...coreOutputs]);
|
||||
assert.equal(result, ExitStatus.Success);
|
||||
});
|
||||
|
||||
|
@ -348,6 +349,39 @@ namespace ts {
|
|||
verifyOutputsAbsent(fs, allExpectedOutputs);
|
||||
assert.equal(result, ExitStatus.InvalidProject_OutputsSkipped);
|
||||
});
|
||||
|
||||
it("building using buildNextProject", () => {
|
||||
const fs = projFs.shadow();
|
||||
const host = new fakes.SolutionBuilderHost(fs);
|
||||
const builder = createSolutionBuilder(host, ["/src/tests"], {});
|
||||
verifyBuildNextResult({
|
||||
project: "/src/core/tsconfig.json" as ResolvedConfigFileName,
|
||||
result: ExitStatus.Success
|
||||
}, coreOutputs, [...logicOutputs, ...testsOutputs]);
|
||||
|
||||
verifyBuildNextResult({
|
||||
project: "/src/logic/tsconfig.json" as ResolvedConfigFileName,
|
||||
result: ExitStatus.Success
|
||||
}, [...coreOutputs, ...logicOutputs], testsOutputs);
|
||||
|
||||
verifyBuildNextResult({
|
||||
project: "/src/tests/tsconfig.json" as ResolvedConfigFileName,
|
||||
result: ExitStatus.Success
|
||||
}, allExpectedOutputs, emptyArray);
|
||||
|
||||
verifyBuildNextResult(/*expected*/ undefined, allExpectedOutputs, emptyArray);
|
||||
|
||||
function verifyBuildNextResult(
|
||||
expected: SolutionBuilderResult<ExitStatus> | undefined,
|
||||
presentOutputs: readonly string[],
|
||||
absentOutputs: readonly string[]
|
||||
) {
|
||||
const result = builder.buildNextProject();
|
||||
assert.deepEqual(result, expected);
|
||||
verifyOutputsPresent(fs, presentOutputs);
|
||||
verifyOutputsAbsent(fs, absentOutputs);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("downstream-blocked compilations", () => {
|
||||
|
|
|
@ -4594,9 +4594,14 @@ declare namespace ts {
|
|||
}
|
||||
interface SolutionBuilderWithWatchHost<T extends BuilderProgram> extends SolutionBuilderHostBase<T>, WatchHost {
|
||||
}
|
||||
interface SolutionBuilderResult<T> {
|
||||
project: ResolvedConfigFileName;
|
||||
result: T;
|
||||
}
|
||||
interface SolutionBuilder {
|
||||
build(project?: string, cancellationToken?: CancellationToken): ExitStatus;
|
||||
clean(project?: string): ExitStatus;
|
||||
buildNextProject(cancellationToken?: CancellationToken): SolutionBuilderResult<ExitStatus> | undefined;
|
||||
}
|
||||
/**
|
||||
* Create a function that reports watch status by writing to the system and handles the formating of the diagnostic
|
||||
|
|
|
@ -4594,9 +4594,14 @@ declare namespace ts {
|
|||
}
|
||||
interface SolutionBuilderWithWatchHost<T extends BuilderProgram> extends SolutionBuilderHostBase<T>, WatchHost {
|
||||
}
|
||||
interface SolutionBuilderResult<T> {
|
||||
project: ResolvedConfigFileName;
|
||||
result: T;
|
||||
}
|
||||
interface SolutionBuilder {
|
||||
build(project?: string, cancellationToken?: CancellationToken): ExitStatus;
|
||||
clean(project?: string): ExitStatus;
|
||||
buildNextProject(cancellationToken?: CancellationToken): SolutionBuilderResult<ExitStatus> | undefined;
|
||||
}
|
||||
/**
|
||||
* Create a function that reports watch status by writing to the system and handles the formating of the diagnostic
|
||||
|
|
Loading…
Reference in a new issue