blob: d04207f89539a4f86a7025d19abf1dc6b1331272 [file] [log] [blame]
/*
* Copyright 2012-present Facebook, Inc.
*
* 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.facebook.buck.util;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Charsets;
import com.google.common.base.Objects;
import com.google.common.collect.Lists;
import com.google.common.io.Closeables;
import com.google.common.io.Files;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
public final class MoreFiles {
private final static Logger logger = Logger.getLogger(MoreFiles.class.getName());
/** Utility class: do not instantiate. */
private MoreFiles() {}
public static void rmdir(String path, ProcessExecutor processExecutor) throws IOException {
// Unfortunately, Guava's Files.deleteRecursively() method is deprecated.
// This is what the deprecation message suggested to do instead.
// Unfortunately, it is not cross-platform.
Process process = Runtime.getRuntime().exec(new String[] {"rm", "-rf", path});
processExecutor.execute(process);
}
/**
* Writes the specified lines to the specified file, encoded as UTF-8.
*/
public static void writeLinesToFile(Iterable<String> lines, String pathToFile)
throws IOException {
BufferedWriter writer = null;
try {
writer = new BufferedWriter(
new OutputStreamWriter(
new FileOutputStream(pathToFile),
Charsets.UTF_8));
for (String line : lines) {
writer.write(line);
writer.newLine();
}
} finally {
Closeables.close(writer, false /* swallowIOException */);
}
}
/**
* Checks whether the lines in the specified file (encoded as UTF-8) match those in the specified
* Iterable.
*/
@SuppressWarnings("resource") // Closeables.close(...)
public static boolean isMatchingFileContents(Iterable<String> lines, File file)
throws IOException {
boolean matching = true;
BufferedReader reader = null;
Iterator<String> iter = lines.iterator();
try {
reader = Files.newReader(file, Charsets.UTF_8);
while (iter.hasNext()) {
String line = reader.readLine();
if (!Objects.equal(iter.next(), line)) {
matching = false;
break;
}
}
if (matching) {
// At this point, the Iterator has been exhausted, and all lines read so far match what is in
// the Iterator. However, if the reader still contains more lines, then the two are not equal.
matching = reader.readLine() == null;
}
} finally {
Closeables.close(reader, false /* swallowIOException */);
}
if (!matching && logger.isLoggable(Level.INFO)) {
logger.info(String.format("DIFF %s", file.getPath()));
for (String diffLine : diffFileContents(lines, file)) {
logger.info(String.format("DIFF %s", diffLine));
}
}
return matching;
}
/**
* Log a simplistic diff between lines and the contents of file.
*/
@VisibleForTesting
static List<String> diffFileContents(Iterable<String> lines, File file) throws IOException {
List<String> diffLines = Lists.newArrayList();
BufferedReader reader = null;
Iterator<String> iter = lines.iterator();
try {
reader = Files.newReader(file, Charsets.UTF_8);
while (iter.hasNext()) {
String lineA = reader.readLine();
String lineB = iter.next();
if (!Objects.equal(lineA, lineB)) {
diffLines.add(String.format("| %s | %s |", lineA == null ? "" : lineA, lineB));
}
}
String lineA;
while ((lineA = reader.readLine()) != null) {
diffLines.add(String.format("| %s | |", lineA));
}
} finally {
Closeables.close(reader, false /* swallowIOException */);
}
return diffLines;
}
}