Repository: GoogleContainerTools/jib
File: jib-core/src/main/java/com/google/cloud/tools/jib/docker/CliDockerClient.java (Java)

Code before:

    /**
     * Return a list of diff ids of the layers in the image.
     *
     * @return a list of diff ids
     * @throws DigestException if a digest is invalid
     */
    @Override
    public List<DescriptorDigest> getDiffIds() throws DigestException {
      List<DescriptorDigest> processedDiffIds = new ArrayList<>(rootFs.layers.size());
      for (String diffId : rootFs.layers) {
        processedDiffIds.add(DescriptorDigest.fromDigest(diffId.trim()));
      }
      return processedDiffIds;
    }
  }

  /** Default path to the docker executable. */
  public static final Path DEFAULT_DOCKER_CLIENT = Paths.get("docker");

  /**
   * Checks if Docker is installed on the user's system by running the `docker` command.
   *
   * @return {@code true} if Docker is installed on the user's system and accessible
   */
  public static boolean isDefaultDockerInstalled() {
    try {
      new ProcessBuilder(DEFAULT_DOCKER_CLIENT.toString()).start();
      return true;
    } catch (IOException ex) {
      return false;
    }
  }

  /**
   * Checks if Docker is installed by verifying if the executable passed in exists.
   *
   * @param dockerExecutable path to the executable to verify
   * @return {@code true} if executable exists on the system
   */
  public static boolean isDockerInstalled(Path dockerExecutable) {
    return Files.exists(dockerExecutable);
  }

  /**
   * Gets a function that takes a {@code docker} subcommand and gives back a {@link ProcessBuilder}
   * for that {@code docker} command.
   *
   * @param dockerExecutable path to {@code docker}
   * @return the default {@link ProcessBuilder} factory for running a {@code docker} subcommand
   */

Review comment (suggestion):
Some background of this change: Checking for existence of the default docker command when it is on PATH has been a little tricky. There can be several places where docker could be installed on a system and this also differs from OS to OS. For checking whether the path passed through `jib.dockerClient.executable` is installed correctly, however, we no longer run executable itself.

Code after:
     * Return a list of diff ids of the layers in the image.
     *
     * @return a list of diff ids
     * @throws DigestException if a digest is invalid
     */
    @Override
    public List<DescriptorDigest> getDiffIds() throws DigestException {
      List<DescriptorDigest> processedDiffIds = new ArrayList<>(rootFs.layers.size());
      for (String diffId : rootFs.layers) {
        processedDiffIds.add(DescriptorDigest.fromDigest(diffId.trim()));
      }
      return processedDiffIds;
    }
  }

  /** Default path to the docker executable. */
  public static final Path DEFAULT_DOCKER_CLIENT = Paths.get("docker");

  /**
   * Checks if Docker is installed on the user's system by running the `docker` command.
   *
   * @return {@code true} if Docker is installed on the user's system and accessible
   */
  public static boolean isDefaultDockerInstalled() {
    try {
      new ProcessBuilder(DEFAULT_DOCKER_CLIENT.toString()).start();
      return true;
    } catch (IOException ex) {
      return false;
    }
  }

  /**
   * Checks if Docker is installed on the user's system and by verifying if the executable path
   * provided has the appropriate permissions.
   *
   * @param dockerExecutable path to the executable to test running
   * @return {@code true} if Docker is installed on the user's system and accessible
   */
  public static boolean isDockerInstalled(Path dockerExecutable) {
    return Files.exists(dockerExecutable);
  }

  /**
   * Gets a function that takes a {@code docker} subcommand and gives back a {@link ProcessBuilder}
   * for that {@code docker} command.
   *
   * @param dockerExecutable path to {@code docker}
   * @return the default {@link ProcessBuilder} factory for running a {@code docker} subcommand
   */
  @VisibleForTesting