aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java
diff options
context:
space:
mode:
authorGravatar tomlu <tomlu@google.com>2017-12-14 12:37:58 -0500
committerGravatar John Cater <jcater@google.com>2017-12-14 12:40:27 -0500
commit8b3ba50246fed6ff13d70299fb039cc66be465c4 (patch)
treeba0dc049c248529b464fa0af91267dc59a3f29fe /src/main/java
parente6863e2336f3aacac8181394f5edd92cac9471a9 (diff)
Move msys path support into DependencySet, removing it from the general Path system.
This is the only place that should actually need it. PiperOrigin-RevId: 179054861
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/com/google/devtools/build/lib/util/DependencySet.java69
-rw-r--r--src/main/java/com/google/devtools/build/lib/vfs/Path.java5
-rw-r--r--src/main/java/com/google/devtools/build/lib/windows/WindowsFileSystem.java57
3 files changed, 71 insertions, 60 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/util/DependencySet.java b/src/main/java/com/google/devtools/build/lib/util/DependencySet.java
index 358610d14d..e2ce5fb6ce 100644
--- a/src/main/java/com/google/devtools/build/lib/util/DependencySet.java
+++ b/src/main/java/com/google/devtools/build/lib/util/DependencySet.java
@@ -24,6 +24,7 @@ import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.concurrent.atomic.AtomicReference;
/**
* Representation of a set of file dependencies for a given output file. There
@@ -99,10 +100,18 @@ public final class DependencySet {
* Adds a given dependency to this DependencySet instance.
*/
private void addDependency(String dep) {
+ dep = translatePath(dep);
Path depPath = root.getRelative(dep);
dependencies.add(depPath);
}
+ private String translatePath(String path) {
+ if (OS.getCurrent() != OS.WINDOWS) {
+ return path;
+ }
+ return WindowsPath.translateWindowsPath(path);
+ }
+
/**
* Reads a dotd file into this DependencySet instance.
*/
@@ -241,4 +250,64 @@ public final class DependencySet {
public int hashCode() {
return dependencies.hashCode();
}
+
+ private static final class WindowsPath {
+ private static final AtomicReference<String> UNIX_ROOT = new AtomicReference<>(null);
+
+ private static String translateWindowsPath(String path) {
+ int n = path.length();
+ if (n == 0 || path.charAt(0) != '/') {
+ return path;
+ }
+ if (n >= 2 && isAsciiLetter(path.charAt(1)) && (n == 2 || path.charAt(2) == '/')) {
+ StringBuilder sb = new StringBuilder(path.length());
+ sb.append(Character.toUpperCase(path.charAt(1)));
+ sb.append(":/");
+ sb.append(path, 2, path.length());
+ return sb.toString();
+ } else {
+ String unixRoot = getUnixRoot();
+ return unixRoot + path;
+ }
+ }
+
+ private static boolean isAsciiLetter(char c) {
+ return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
+ }
+
+ private static String getUnixRoot() {
+ String value = UNIX_ROOT.get();
+ if (value == null) {
+ String jvmFlag = "bazel.windows_unix_root";
+ value = determineUnixRoot(jvmFlag);
+ if (value == null) {
+ throw new IllegalStateException(
+ String.format(
+ "\"%1$s\" JVM flag is not set. Use the --host_jvm_args flag. "
+ + "For example: "
+ + "\"--host_jvm_args=-D%1$s=c:/tools/msys64\".",
+ jvmFlag));
+ }
+ value = value.replace('\\', '/');
+ if (value.length() > 3 && value.endsWith("/")) {
+ value = value.substring(0, value.length() - 1);
+ }
+ UNIX_ROOT.set(value);
+ }
+ return value;
+ }
+
+ private static String determineUnixRoot(String jvmArgName) {
+ // Get the path from a JVM flag, if specified.
+ String path = System.getProperty(jvmArgName);
+ if (path == null) {
+ return null;
+ }
+ path = path.trim();
+ if (path.isEmpty()) {
+ return null;
+ }
+ return path;
+ }
+ }
}
diff --git a/src/main/java/com/google/devtools/build/lib/vfs/Path.java b/src/main/java/com/google/devtools/build/lib/vfs/Path.java
index 6fe6118b9a..1d3947dcdc 100644
--- a/src/main/java/com/google/devtools/build/lib/vfs/Path.java
+++ b/src/main/java/com/google/devtools/build/lib/vfs/Path.java
@@ -78,11 +78,6 @@ public class Path implements Comparable<Path>, Serializable, SkylarkPrintable {
/**
* Makes the proper invocation of {@link FileSystem#getCachedChildPathInternal}, doing
* filesystem-specific logic if necessary.
- *
- * <p>On Unix filesystems this method merely calls through to {@code
- * FileSystem.getCachedChildPathInternal(parent, child)}, but on Windows this can be used to
- * handle the translatation of absolute Unix paths to absolute Windows paths, e.g. "/c" to "C:/"
- * or "/usr" to "C:/tools/msys64/usr".
*/
Path getCachedChildPathInternal(Path path, String childName);
}
diff --git a/src/main/java/com/google/devtools/build/lib/windows/WindowsFileSystem.java b/src/main/java/com/google/devtools/build/lib/windows/WindowsFileSystem.java
index 21de058e07..af97e27d3d 100644
--- a/src/main/java/com/google/devtools/build/lib/windows/WindowsFileSystem.java
+++ b/src/main/java/com/google/devtools/build/lib/windows/WindowsFileSystem.java
@@ -32,7 +32,6 @@ import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.attribute.DosFileAttributes;
import java.util.Arrays;
-import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.annotation.Nullable;
@@ -106,42 +105,11 @@ public class WindowsFileSystem extends JavaIoFileSystem {
private static Path getCachedChildPathInternalImpl(
Path parent, String child, Function<String, String> resolver) {
if (parent != null && parent.isRootDirectory()) {
- // This is a top-level directory. It's either a drive name ("C:" or "c") or some other
- // Unix path (e.g. "/usr").
- //
- // We need to translate it to an absolute Windows path. The correct way would be looking
- // up /etc/mtab to see if any mount point matches the prefix of the path, and change the
- // prefix to the mounted path. Looking up /etc/mtab each time we create a path however
- // would be too expensive so we use a heuristic instead.
- //
- // If the name looks like a volume name ("C:" or "c") then we treat it as such, otherwise
- // we make it relative to UNIX_ROOT, thus "/usr" becomes "C:/tools/msys64/usr".
- //
- // This heuristic ignores other mount points as well as procfs.
-
- // TODO(laszlocsomor): use GetLogicalDrives to retrieve the list of drives and only apply
- // this heuristic for the valid drives. It's possible that the user has a directory "/a"
- // but no "A:\" drive, so in that case we should prepend the MSYS root.
-
+ // This is a top-level directory. It must be a drive name ("C:" or "c").
if (WindowsPath.isWindowsVolumeName(child)) {
child = WindowsPath.getDriveLetter((WindowsPath) parent, child) + ":";
} else {
- if (UNIX_ROOT.get() == null) {
- String jvmFlag = "bazel.windows_unix_root";
- PathFragment value = determineUnixRoot(jvmFlag);
- if (value == null) {
- throw new IllegalStateException(
- String.format(
- "\"%1$s\" JVM flag is not set. Use the --host_jvm_args flag or export the "
- + "BAZEL_SH environment variable. For example "
- + "\"--host_jvm_args=-D%1$s=c:/tools/msys64\" or "
- + "\"set BAZEL_SH=c:/tools/msys64/usr/bin/bash.exe\". "
- + "parent=(%2$s) name=(%3$s)",
- jvmFlag, parent, child));
- }
- UNIX_ROOT.set(value);
- }
- parent = parent.getRelative(UNIX_ROOT.get());
+ throw new IllegalArgumentException("Cannot create Unix-style paths on Windows.");
}
}
@@ -303,8 +271,6 @@ public class WindowsFileSystem extends JavaIoFileSystem {
return WindowsPathFactory.createForTesting(mockResolver);
}
- private static final AtomicReference<PathFragment> UNIX_ROOT = new AtomicReference<>(null);
-
public static final LinkOption[] NO_OPTIONS = new LinkOption[0];
public static final LinkOption[] NO_FOLLOW = new LinkOption[] {LinkOption.NOFOLLOW_LINKS};
@@ -478,23 +444,4 @@ public class WindowsFileSystem extends JavaIoFileSystem {
return Files.readAttributes(
file.toPath(), DosFileAttributes.class, symlinkOpts(followSymlinks));
}
-
- private static PathFragment determineUnixRoot(String jvmArgName) {
- // Get the path from a JVM flag, if specified.
- String path = System.getProperty(jvmArgName);
- if (path == null) {
- return null;
- }
-
- path = path.trim();
- if (path.isEmpty()) {
- return null;
- }
-
- PathFragment result = PathFragment.create(path);
- if (result.getDriveLetter() == '\0' || !result.isAbsolute()) {
- return null;
- }
- return result;
- }
}