// Copyright 2014 The Bazel Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package com.google.devtools.build.lib.unix; import com.google.devtools.build.lib.shell.AbnormalTerminationException; import com.google.devtools.build.lib.shell.Command; import com.google.devtools.build.lib.shell.CommandException; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; /** * Provides utility methods for working with directories in a Unix environment. */ public final class Directories { /** * Deletes a file or directory and all contents recursively, like {@code rm -rf file}. * * <p>If the file argument is a symbolic link, the link will be deleted but not the target of the * link. If the argument is a directory, symbolic links within the directory will not be followed. * If the argument does not exist, throws a FileNotFoundException. * * @param file the file or directory to delete * @throws FileNotFoundException if the file or directory does not exist * @throws IOException if an I/O error occurs */ public static void deleteRecursively(File file) throws IOException { deleteRecursivelyImpl(file, true); } /** * Deletes a file or directory and all contents recursively, like {@code rm -rf file}, if it * exists. * * <p>If the file argument is a symbolic link, the link will be deleted but not the target of the * link. If the argument is a directory, symbolic links within the directory will not be followed. * * @param file the file or directory to delete * @return {@code true} if the file or directory was deleted by this method; {@code false} if the * file or directory could not be deleted because it did not exist * @throws IOException if an I/O error occurs */ public static boolean deleteRecursivelyIfExists(File file) throws IOException { return deleteRecursivelyImpl(file, false); } private static boolean deleteRecursivelyImpl(File file, boolean failIfFileDoesNotExist) throws IOException { if (!file.exists()) { if (failIfFileDoesNotExist) { throw new FileNotFoundException(file.getPath()); } else { return false; } } String filePath = file.getPath(); if (!filePath.isEmpty() && filePath.charAt(0) == '-') { filePath = "./" + filePath; } try { new Command(new String[] {"/bin/rm", "-rf", filePath}).execute(); } catch (AbnormalTerminationException e) { String message = e.getResult().getTerminationStatus() + ": " + new String(e.getResult().getStderr()); throw new IOException(message, e); } catch (CommandException e) { throw new IOException(e); } return true; } private Directories() {} }