@Override
  public void apply(Project project) {
    checkGradleVersion();
    checkJibVersion();

    JibExtension jibExtension =
        project.getExtensions().create(JIB_EXTENSION_NAME, JibExtension.class, project);

    TaskContainer tasks = project.getTasks();
    TaskProvider<BuildImageTask> buildImageTask =
        tasks.register(
            BUILD_IMAGE_TASK_NAME,
            BuildImageTask.class,
            task -> {
              task.setGroup("Jib");
              task.setDescription("Builds a container image to a registry.");
              task.setJibExtension(jibExtension);
            });

    TaskProvider<BuildDockerTask> buildDockerTask =
        tasks.register(
            BUILD_DOCKER_TASK_NAME,
            BuildDockerTask.class,
            task -> {
              task.setGroup("Jib");
              task.setDescription("Builds a container image to a Docker daemon.");
              task.setJibExtension(jibExtension);
            });

    TaskProvider<BuildTarTask> buildTarTask =
        tasks.register(
            BUILD_TAR_TASK_NAME,
            BuildTarTask.class,
            task -> {
              task.setGroup("Jib");
              task.setDescription("Builds a container image to a tarball.");
              task.setJibExtension(jibExtension);
            });

    tasks
        .register(SKAFFOLD_FILES_TASK_V2_NAME, FilesTaskV2.class)
        .configure(task -> task.setJibExtension(jibExtension));
    tasks
        .register(SKAFFOLD_INIT_TASK_NAME, InitTask.class)
        .configure(task -> task.setJibExtension(jibExtension));
    TaskProvider<SyncMapTask> syncMapTask =
        tasks.register(
            SKAFFOLD_SYNC_MAP_TASK_NAME,
            SyncMapTask.class,
            task -> task.setJibExtension(jibExtension));

    // A check to catch older versions of Jib.  This can be removed once we are certain people
    // are using Jib 1.3.1 or later.
    tasks.register(SKAFFOLD_CHECK_REQUIRED_VERSION_TASK_NAME, CheckJibVersionTask.class);

    project.afterEvaluate(
        projectAfterEvaluation -> {
          TaskProvider<Task> warTask = TaskCommon.getWarTaskProvider(projectAfterEvaluation);
          TaskProvider<Task> bootWarTask =
              TaskCommon.getBootWarTaskProvider(projectAfterEvaluation);
          List<Object> jibDependencies = new ArrayList<>();
          if (warTask != null || bootWarTask != null) {
            // Have all tasks depend on the 'war' and/or 'bootWar' task.
            if (warTask != null) {
              jibDependencies.add(warTask);
            }
            if (bootWarTask != null) {
              jibDependencies.add(bootWarTask);
            }
          } else if ("packaged".equals(jibExtension.getContainerizingMode())) {
            // Have all tasks depend on the 'jar' task.
            TaskProvider<Task> jarTask = projectAfterEvaluation.getTasks().named("jar");
            jibDependencies.add(jarTask);

            if (projectAfterEvaluation.getPlugins().hasPlugin("org.springframework.boot")) {
              Task bootJarTask = projectAfterEvaluation.getTasks().getByName("bootJar");

              if (bootJarTask.getEnabled()) {
                String bootJarPath = bootJarTask.getOutputs().getFiles().getAsPath();
                String jarPath = jarTask.get().getOutputs().getFiles().getAsPath();
                if (bootJarPath.equals(jarPath)) {
                  if (!jarTask.get().getEnabled()) {
                    ((Jar) jarTask.get()).getArchiveClassifier().set("original");
                  } else {
                    throw new GradleException(
                        "Both 'bootJar' and 'jar' tasks are enabled, but they write their jar file "
                            + "into the same location at "
                            + jarPath
                            + ". Did you forget to set 'archiveClassifier' on either task?");
                  }
                }
              }
              jarTask.get().setEnabled(true);
            }
          }

          SourceSet mainSourceSet =
              projectAfterEvaluation
                  .getExtensions()
                  .getByType(SourceSetContainer.class)
                  .getByName(SourceSet.MAIN_SOURCE_SET_NAME);
          jibDependencies.add(mainSourceSet.getRuntimeClasspath());
          jibDependencies.add(
              projectAfterEvaluation
                  .getConfigurations()
                  .getByName(jibExtension.getConfigurationName().get()));

          Set<TaskProvider<?>> jibTaskProviders =
              ImmutableSet.of(buildImageTask, buildDockerTask, buildTarTask, syncMapTask);
          jibTaskProviders.forEach(
              provider ->
                  provider.configure(task -> jibDependencies.forEach(dep -> task.dependsOn(dep))));
        });
  }
@Test
  public void testCheckJibVersionInvoked() {
    Project project = createProject();
    System.setProperty(JibPlugin.REQUIRED_VERSION_PROPERTY_NAME, "10000.0"); // not here yet

    Exception exception =
        assertThrows(
            GradleException.class,
            () -> project.getPluginManager().apply("com.google.cloud.tools.jib"));
    // Gradle tests aren't run from a jar and so don't have an identifiable plugin version
    assertThat(exception)
        .hasMessageThat()
        .isEqualTo("Failed to apply plugin 'com.google.cloud.tools.jib'.");
    assertThat(exception.getCause())
        .hasMessageThat()
        .isEqualTo("Could not determine Jib plugin version");
  }