Skip to content

What's left to make this work #1

@nedtwigg

Description

@nedtwigg

There are two open questions:

  1. Does gradle let you disable a task during task execution? That's our whole premise, so hopefully the answer to this is yes!

if (isCachedOrUpToDate(horizonTask.get())) {
for (Provider<? extends Task> innerProvider : innerTasks) {
Task innerTask = innerProvider.get();
innerTask.setEnabled(false);
}

  1. How can we implement boolean isCachedOrUpToDate(Task task)?

This is how far we got, by copying out the relevant-looking parts of Gradle's task execution. It definitely doesn't work as written, but it points towards the internal APIs that Gradle uses for this.

private boolean isCachedOrUpToDate(Task task) {
TaskExecutionGraphInternal graph = (TaskExecutionGraphInternal) getProject().getGradle().getTaskGraph();
for (Node node : graph.getScheduledWork()) {
if (node instanceof LocalTaskNode) {
LocalTaskNode localTaskNode = (LocalTaskNode) node;
if (localTaskNode.getTask() == horizonTask) {
return isCachedOrUpToDate(localTaskNode);
}
}
}
return false;
}
private boolean isCachedOrUpToDate(LocalTaskNode localTaskNode) {
ServiceRegistry registry = ((ProjectInternal) getProject()).getServices();
BuildOperationExecutor buildOperationExecutor = registry.get(BuildOperationExecutor.class);
ClassLoaderHierarchyHasher classLoaderHierarchyHasher = registry.get(ClassLoaderHierarchyHasher.class);
ValueSnapshotter valueSnapshotter = registry.get(ValueSnapshotter.class);
OverlappingOutputDetector overlappingOutputDetector = registry.get(OverlappingOutputDetector.class);
BuildCacheController buildCacheController = registry.get(BuildCacheController.class);
boolean buildScansEnabled = false;
DefaultWorkExecutor<ExecutionRequestContext, CachingResult> executor = new DefaultWorkExecutor<>(
new LoadExecutionStateStep<>(
new CaptureStateBeforeExecutionStep(buildOperationExecutor, classLoaderHierarchyHasher, valueSnapshotter, overlappingOutputDetector,
new ResolveCachingStateStep(buildCacheController, buildScansEnabled, new Step<CachingContext, UpToDateResult>() {
@Override
public UpToDateResult execute(CachingContext context) {
return new UpToDateResult() {
@Override
public ImmutableSortedMap<String, ? extends FileCollectionFingerprint> getFinalOutputs() {
throw new UnsupportedOperationException();
}
@Override
public Try<ExecutionOutcome> getOutcome() {
throw new UnsupportedOperationException();
}
@Override
public ImmutableList<String> getExecutionReasons() {
throw new UnsupportedOperationException();
}
@Override
public Optional<OriginMetadata> getReusedOutputOriginMetadata() {
throw new UnsupportedOperationException();
}
};
}
}))));
CachingResult caching = executor.execute(new ExecutionRequestContext() {
@Override
public Optional<String> getRebuildReason() {
throw new UnsupportedOperationException();
}
@Override
public UnitOfWork getWork() {
throw new UnsupportedOperationException();
}
});
ExecutionOutcome outcome = caching.getOutcome().get();
return outcome == ExecutionOutcome.FROM_CACHE || outcome == ExecutionOutcome.UP_TO_DATE;
}

That's as far as we got, and as far as we are likely to get for the foreseeable future. We're happy to merge PRs and add committers here if you don't want to deal with publishing and maintaining, also we're also happy to shut this project down and link to yours if you find a way forward and want to maintain it.

Our intent is to use this issue as the "forum" for solving the two questions above, or for linking out to other solutions that frame the problem differently.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions