@VisibleForTesting
  List<Future<PreparedLayer>> obtainBaseImageLayers(
      Image baseImage,
      boolean layersRequiredLocally,
      Map<DescriptorDigest, Future<PreparedLayer>> preparedLayersCache,
      ProgressEventDispatcher.Factory progressDispatcherFactory)
      throws InterruptedException, ExecutionException {
    List<Future<PreparedLayer>> preparedLayers = new ArrayList<>();

    try (ProgressEventDispatcher progressDispatcher =
        progressDispatcherFactory.create(
            "launching base image layer pullers", baseImage.getLayers().size())) {
      for (Layer layer : baseImage.getLayers()) {
        DescriptorDigest digest = layer.getBlobDescriptor().getDigest();
        Future<PreparedLayer> preparedLayer = preparedLayersCache.get(digest);

        if (preparedLayer != null) {
          progressDispatcher.dispatchProgress(1);
        } else { // If we haven't obtained this layer yet, launcher a puller.
          preparedLayer =
              executorService.submit(
                  layersRequiredLocally
                      ? ObtainBaseImageLayerStep.forForcedDownload(
                          buildContext,
                          progressDispatcher.newChildProducer(),
                          layer,
                          results.baseImagesAndRegistryClient.get().registryClient)
                      : ObtainBaseImageLayerStep.forSelectiveDownload(
                          buildContext,
                          progressDispatcher.newChildProducer(),
                          layer,
                          results.baseImagesAndRegistryClient.get().registryClient,
                          results.targetRegistryClient.get()));
          preparedLayersCache.put(digest, preparedLayer);
        }
        preparedLayers.add(preparedLayer);
      }
      return preparedLayers;
    }
  }
Run all steps and return a BuildResult after a build is completed.

@return a {@link BuildResult} with build metadata
@throws ExecutionException if an error occurred during asynchronous execution of steps
@throws InterruptedException if the build was interrupted while waiting for results
jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/StepsRunner.java