diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/util/io/CaseSensitivityDetectionTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/util/io/CaseSensitivityDetectionTest.java index c58a7bc4b632..d20311bbd346 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/util/io/CaseSensitivityDetectionTest.java +++ b/platform/platform-tests/testSrc/com/intellij/openapi/util/io/CaseSensitivityDetectionTest.java @@ -5,13 +5,17 @@ import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.io.FileAttributes.CaseSensitivity; import com.intellij.testFramework.rules.TempDirectory; import com.intellij.util.io.SuperUserStatus; +import com.intellij.util.system.OS; import org.junit.Rule; import org.junit.Test; -import java.io.File; import java.io.IOException; +import java.nio.file.FileAlreadyExistsException; +import java.nio.file.Files; +import java.nio.file.Path; import static com.intellij.openapi.util.io.IoTestUtil.*; +import static org.assertj.core.api.Assertions.assertThatCode; import static org.junit.Assert.*; import static org.junit.Assume.assumeTrue; @@ -20,32 +24,29 @@ import static org.junit.Assume.assumeTrue; public class CaseSensitivityDetectionTest { @Rule public TempDirectory tempDir = new TempDirectory(); - @Test - public void windowsFSRootsMustHaveDefaultSensitivity() { + @Test public void windowsFSRootsMustHaveDefaultSensitivity() { assumeWindows(); - String systemDrive = System.getenv("SystemDrive"); // typically, "C:" + var systemDrive = System.getenv("SystemDrive"); // typically, "C:" assertNotNull(systemDrive); - File root = new File(systemDrive + '\\'); - CaseSensitivity rootCs = FileSystemUtil.readParentCaseSensitivity(root); + var root = Path.of(systemDrive + '\\'); + var rootCs = FileSystemUtil.readParentCaseSensitivity(root.toFile()); assertEquals(systemDrive, CaseSensitivity.INSENSITIVE, rootCs); - String systemRoot = System.getenv("SystemRoot"); // typically, "C:\Windows" + var systemRoot = System.getenv("SystemRoot"); // typically, "C:\Windows" assertNotNull(systemRoot); - File child = new File(systemRoot); - assertEquals(root, child.getParentFile()); - assertEquals(systemRoot, rootCs, FileSystemUtil.readParentCaseSensitivity(child)); + var child = Path.of(systemRoot); + assertEquals(root, child.getParent()); + assertEquals(systemRoot, rootCs, FileSystemUtil.readParentCaseSensitivity(child.toFile())); } - @Test - public void wslRootsMustBeCaseSensitive() { - String name = assumeWorkingWslDistribution(); - String root = "\\\\wsl$\\" + name; - assertEquals(root, CaseSensitivity.SENSITIVE, FileSystemUtil.readParentCaseSensitivity(new File(root))); + @Test public void wslRootsMustBeCaseSensitive() { + var name = assumeWorkingWslDistribution(); + var root = Path.of("\\\\wsl$\\" + name); + assertEquals(root.toString(), CaseSensitivity.SENSITIVE, FileSystemUtil.readParentCaseSensitivity(root.toFile())); } - @Test - public void caseSensitivityChangesUnderWindowsMustBeReReadCorrectly() throws IOException { + @Test public void caseSensitivityChangesUnderWindowsMustBeReReadCorrectly() throws IOException { assumeWindows(); assumeWslPresence(); assumeTrue("'fsutil.exe' needs elevated privileges to work", SuperUserStatus.isSuperUser()); @@ -59,85 +60,78 @@ public class CaseSensitivityDetectionTest { assertEquals(CaseSensitivity.INSENSITIVE, FileSystemUtil.readParentCaseSensitivity(file)); } - @Test - public void macOsBasics() { + @Test public void macOsBasics() { assumeMacOS(); - File root = new File("/"); - CaseSensitivity rootCs = FileSystemUtil.readParentCaseSensitivity(root); + var root = Path.of("/"); + var rootCs = FileSystemUtil.readParentCaseSensitivity(root.toFile()); assertNotEquals(CaseSensitivity.UNKNOWN, rootCs); - File child = new File("/Users"); - assertEquals(root, child.getParentFile()); - assertEquals(rootCs, FileSystemUtil.readParentCaseSensitivity(child)); + var child = Path.of("/Users"); + assertEquals(root, child.getParent()); + assertEquals(rootCs, FileSystemUtil.readParentCaseSensitivity(child.toFile())); } - @Test - public void linuxBasics() { + @Test public void linuxBasics() { assumeLinux(); - File root = new File("/"); - CaseSensitivity rootCs = FileSystemUtil.readParentCaseSensitivity(root); + var root = Path.of("/"); + var rootCs = FileSystemUtil.readParentCaseSensitivity(root.toFile()); assertEquals(CaseSensitivity.SENSITIVE, rootCs); - File child = new File("/home"); - assertEquals(rootCs, FileSystemUtil.readParentCaseSensitivity(child)); + var child = Path.of("/home"); + assertEquals(rootCs, FileSystemUtil.readParentCaseSensitivity(child.toFile())); } - @Test - public void caseSensitivityIsReadSanely() throws IOException { - File file = tempDir.newFile("dir/x.txt"); - CaseSensitivity sensitivity = FileSystemUtil.readParentCaseSensitivity(file); + @Test public void caseSensitivityIsReadSanely() throws IOException { + var file = tempDir.newFileNio("dir/x.txt"); + var sensitivity = FileSystemUtil.readParentCaseSensitivity(file.toFile()); if (sensitivity == CaseSensitivity.SENSITIVE) { - assertTrue(new File(file.getParentFile(), "X.txt").createNewFile()); + Files.createFile(file.resolveSibling("X.txt")); } else if (sensitivity == CaseSensitivity.INSENSITIVE) { - assertFalse(new File(file.getParentFile(), "X.txt").createNewFile()); + assertThatCode(() -> Files.createFile(file.resolveSibling("X.txt"))) + .doesNotThrowAnyExceptionExcept(FileAlreadyExistsException.class); } else { fail("invalid sensitivity: " + sensitivity); } } - @Test - public void caseSensitivityOfNonExistingDirMustBeUnknown() { - File file = new File(tempDir.getRoot(), "dir/child.txt"); - assertFalse(file.exists()); - assertEquals(CaseSensitivity.UNKNOWN, FileSystemUtil.readParentCaseSensitivity(file)); + @Test public void caseSensitivityOfNonExistingDirMustBeUnknown() { + var file = tempDir.getRootPath().resolve("dir/child.txt"); + assertFalse(Files.exists(file.getParent())); + assertEquals(CaseSensitivity.UNKNOWN, FileSystemUtil.readCaseSensitivityByNativeAPI(file.toFile())); + assertEquals(CaseSensitivity.UNKNOWN, FileSystemUtil.readCaseSensitivityByJavaIO(file.toFile())); } - @Test - public void nativeApiWorksInSimpleCases() { - File file = tempDir.newFile("dir/0"); - assertFalse(FileSystemUtil.isCaseToggleable(file.getName())); + @Test public void nativeApiWorksInSimpleCases() { + var file = tempDir.newFileNio("dir/0"); + assertFalse(FileSystemUtil.isCaseToggleable(file.getFileName().toString())); - CaseSensitivity expected = SystemInfo.isWindows || SystemInfo.isMac ? CaseSensitivity.INSENSITIVE : CaseSensitivity.SENSITIVE; - assertEquals(expected, FileSystemUtil.readParentCaseSensitivity(file)); + var expected = OS.CURRENT == OS.Windows || OS.CURRENT == OS.macOS ? CaseSensitivity.INSENSITIVE : CaseSensitivity.SENSITIVE; + assertEquals(expected, FileSystemUtil.readParentCaseSensitivity(file.toFile())); } - @Test - public void nativeApiWorksWithNonLatinPaths() { - String uni = SystemInfo.isWindows ? getUnicodeName(System.getProperty("sun.jnu.encoding")) : getUnicodeName(); + @Test public void nativeApiWorksWithNonLatinPaths() { + var uni = OS.CURRENT == OS.Windows ? getUnicodeName(System.getProperty("sun.jnu.encoding")) : getUnicodeName(); assumeTrue(uni != null); - File file = tempDir.newFile(uni + "/0"); - CaseSensitivity expected = SystemInfo.isWindows || SystemInfo.isMac ? CaseSensitivity.INSENSITIVE : CaseSensitivity.SENSITIVE; - assertEquals(expected, FileSystemUtil.readParentCaseSensitivity(file)); + var file = tempDir.newFileNio(uni + "/0"); + var expected = OS.CURRENT == OS.Windows || OS.CURRENT == OS.macOS ? CaseSensitivity.INSENSITIVE : CaseSensitivity.SENSITIVE; + assertEquals(expected, FileSystemUtil.readParentCaseSensitivity(file.toFile())); } - @Test - public void caseSensitivityNativeWrappersMustWorkAtLeastInSimpleCases() { - CaseSensitivity defaultCS = SystemInfo.isFileSystemCaseSensitive ? CaseSensitivity.SENSITIVE : CaseSensitivity.INSENSITIVE; - assertEquals(defaultCS, FileSystemUtil.readCaseSensitivityByNativeAPI(tempDir.newFile("dir0/child.txt"))); - assertEquals(defaultCS, FileSystemUtil.readCaseSensitivityByNativeAPI(tempDir.newFile("dir0/0"))); // there's a toggleable "child.txt" in this dir already - assertEquals(defaultCS, FileSystemUtil.readCaseSensitivityByNativeAPI(tempDir.newFile("dir1/0"))); + @Test public void caseSensitivityNativeWrappersMustWorkAtLeastInSimpleCases() { + var defaultCS = SystemInfo.isFileSystemCaseSensitive ? CaseSensitivity.SENSITIVE : CaseSensitivity.INSENSITIVE; + assertEquals(defaultCS, FileSystemUtil.readCaseSensitivityByNativeAPI(tempDir.newFileNio("dir0/child.txt").toFile())); + assertEquals(defaultCS, FileSystemUtil.readCaseSensitivityByNativeAPI(tempDir.newFileNio("dir0/0").toFile())); // there's a toggleable "child.txt" in this dir already + assertEquals(defaultCS, FileSystemUtil.readCaseSensitivityByNativeAPI(tempDir.newFileNio("dir1/0").toFile())); } - @Test - public void caseSensitivityMustBeDeducibleByPureJavaIOAtLeastInSimpleCases() { - CaseSensitivity defaultCS = SystemInfo.isFileSystemCaseSensitive ? CaseSensitivity.SENSITIVE : CaseSensitivity.INSENSITIVE; - assertEquals(defaultCS, FileSystemUtil.readParentCaseSensitivityByJavaIO(tempDir.newFile("dir0/child.txt"))); - assertEquals(defaultCS, FileSystemUtil.readParentCaseSensitivityByJavaIO(tempDir.newFile("dir0/0"))); // there's a toggleable "child.txt" in this dir already - assertEquals(defaultCS, FileSystemUtil.readParentCaseSensitivityByJavaIO(tempDir.newDirectory("dir0/Ubuntu"))); - //assertEquals(defaultCS, FileSystemUtil.readParentCaseSensitivityByJavaIO(tempDir.newFile("dir1/0"))); + @Test public void caseSensitivityMustBeDeducibleByPureJavaIOAtLeastInSimpleCases() { + var defaultCS = SystemInfo.isFileSystemCaseSensitive ? CaseSensitivity.SENSITIVE : CaseSensitivity.INSENSITIVE; + assertEquals(defaultCS, FileSystemUtil.readCaseSensitivityByJavaIO(tempDir.newFileNio("dir0/child.txt").toFile())); + assertEquals(defaultCS, FileSystemUtil.readCaseSensitivityByJavaIO(tempDir.newFileNio("dir0/0").toFile())); // there's a toggleable "child.txt" in this dir already + assertEquals(defaultCS, FileSystemUtil.readCaseSensitivityByJavaIO(tempDir.newDirectoryPath("dir0/Ubuntu").toFile())); } } diff --git a/platform/util/src/com/intellij/openapi/util/io/FileSystemUtil.java b/platform/util/src/com/intellij/openapi/util/io/FileSystemUtil.java index e2ca5bf5a8dc..24098155c41a 100644 --- a/platform/util/src/com/intellij/openapi/util/io/FileSystemUtil.java +++ b/platform/util/src/com/intellij/openapi/util/io/FileSystemUtil.java @@ -3,7 +3,7 @@ package com.intellij.openapi.util.io; import com.intellij.jna.JnaLoader; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.util.SystemInfo; +import com.intellij.util.system.OS; import com.sun.jna.*; import com.sun.jna.platform.win32.Kernel32; import com.sun.jna.platform.win32.WinBase; @@ -44,7 +44,7 @@ public final class FileSystemUtil { } private static String normalizePath(@NotNull String path) { - if (SystemInfo.isWindows && path.length() == 2 && path.charAt(1) == ':') { + if (OS.CURRENT == OS.Windows && path.length() == 2 && path.charAt(1) == ':') { path += '\\'; } return path; @@ -141,12 +141,12 @@ public final class FileSystemUtil { FileAttributes.CaseSensitivity detected = readCaseSensitivityByNativeAPI(anyChild); if (detected.isKnown()) return detected; // native queries failed, fallback to the Java I/O: - return readParentCaseSensitivityByJavaIO(anyChild); + return readCaseSensitivityByJavaIO(anyChild); } @VisibleForTesting @ApiStatus.Internal - public static @NotNull FileAttributes.CaseSensitivity readParentCaseSensitivityByJavaIO(@NotNull java.io.File anyChild) { + public static @NotNull FileAttributes.CaseSensitivity readCaseSensitivityByJavaIO(@NotNull java.io.File anyChild) { // try to query this path by different-case strings and deduce case sensitivity from the answers java.io.File parent = anyChild.getParentFile(); if (parent == null) { @@ -238,21 +238,20 @@ public final class FileSystemUtil { @VisibleForTesting @ApiStatus.Internal public static @NotNull FileAttributes.CaseSensitivity readCaseSensitivityByNativeAPI(@NotNull java.io.File anyChild) { - FileAttributes.CaseSensitivity detected = com.intellij.openapi.util.io.FileAttributes.CaseSensitivity.UNKNOWN; if (JnaLoader.isLoaded()) { java.io.File parent = anyChild.getParentFile(); String path = (parent != null ? parent : anyChild).getAbsolutePath(); - if (SystemInfo.isWin10OrNewer && WINDOWS_CS_API_AVAILABLE) { - detected = OSAgnosticPathUtil.isAbsoluteDosPath(path) ? getNtfsCaseSensitivity(path) : com.intellij.openapi.util.io.FileAttributes.CaseSensitivity.UNKNOWN; + if (OS.CURRENT == OS.Windows && OS.CURRENT.isAtLeast(10, 0) && WINDOWS_CS_API_AVAILABLE && OSAgnosticPathUtil.isAbsoluteDosPath(path)) { + return getNtfsCaseSensitivity(path); } - else if (SystemInfo.isMac && MAC_CS_API_AVAILABLE) { - detected = getMacOsCaseSensitivity(path); + else if (OS.CURRENT == OS.macOS && MAC_CS_API_AVAILABLE) { + return getMacOsCaseSensitivity(path); } - else if (SystemInfo.isLinux && LINUX_CS_API_AVAILABLE) { - detected = getLinuxCaseSensitivity(path); + else if (OS.CURRENT == OS.Linux && LINUX_CS_API_AVAILABLE) { + return getLinuxCaseSensitivity(path); } } - return detected; + return FileAttributes.CaseSensitivity.UNKNOWN; } private static String toggleCase(String name) {