IJPL-175157 Changing version of a Maven library in JPS project download JARs to the wrong location

GitOrigin-RevId: 4b911dc871a0565926218b00a9bb8cfdf26e34fd
This commit is contained in:
Leonid Shalupov
2025-01-15 19:13:35 +00:00
committed by intellij-monorepo-bot
parent 4fc1a679c1
commit 8f7935d584
3 changed files with 79 additions and 3 deletions
@@ -216,7 +216,8 @@ public final class JarRepositoryManager {
}
@TestOnly
static void setLocalRepositoryPath(File localRepo) {
@ApiStatus.Internal
public static void setLocalRepositoryPath(File localRepo) {
ourLocalRepositoryPath = localRepo;
}
@@ -18,7 +18,6 @@ import com.intellij.openapi.roots.ui.configuration.libraryEditor.LibraryEditor;
import com.intellij.openapi.roots.ui.configuration.libraryEditor.NewLibraryEditor;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.JarFileSystem;
import com.intellij.openapi.vfs.StandardFileSystems;
import com.intellij.openapi.vfs.VfsUtilCore;
@@ -31,6 +30,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.concurrency.AsyncPromise;
import org.jetbrains.concurrency.Promise;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;
@@ -83,11 +83,36 @@ public final class RepositoryUtils {
String firstPath = getOnDiskParentPath(urls[0]);
for (String root : urls) {
if (!StringUtil.equals(firstPath, getOnDiskParentPath(root))) {
if (!FileUtil.pathsEqual(firstPath, getOnDiskParentPath(root))) {
return null;
}
}
if (urls.length == 1) {
// IJPL-175157 Only one file in the library, so we can't decide on storage root without looking into cache location
// It's worse with symlinks where we may have a non-canonical path in `firstPath`
// and canonical path in JarRepositoryManager.getLocalRepositoryPath
var localRepositoryPath = JarRepositoryManager.getLocalRepositoryPath();
// happy case, no symlinks, so canonical localRepositoryPath is the same is firstPath
if (FileUtil.startsWith(firstPath, localRepositoryPath.getPath())) {
return null;
}
// non-happy case, symlinks, let's try to get as much canonical as we can.
// covered by tests
try {
var canonicalFirstPath = new File(firstPath).getCanonicalPath();
var canonicalLocalRepositoryPath = localRepositoryPath.getCanonicalPath();
if (FileUtil.startsWith(canonicalFirstPath, canonicalLocalRepositoryPath)) {
return null;
}
}
catch (IOException ignored) {
// IOError, can't decide
}
}
return firstPath;
}
@@ -5,10 +5,12 @@ import com.intellij.jarRepository.*;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.io.IoTestUtil;
import com.intellij.testFramework.ServiceContainerUtil;
import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.model.library.JpsMavenRepositoryLibraryDescriptor;
import org.jetbrains.jps.util.JpsPathUtil;
import java.io.IOException;
import java.nio.file.Files;
@@ -138,6 +140,54 @@ public class RepositoryUtilsTest extends LibraryTest {
);
}
public void testGetStorageRootWithSymlinks() throws IOException {
IoTestUtil.assumeSymLinkCreationIsSupported();
var temp = Files.createTempDirectory("storage-root").toRealPath();
var dir = temp.resolve("dir");
var dir2 = temp.resolve("dir2");
var symlinkToDir = temp.resolve("symlink");
Files.createDirectory(dir);
Files.createSymbolicLink(symlinkToDir, dir);
var oldLocalRepositoryPath = JarRepositoryManager.getLocalRepositoryPath();
JarRepositoryManager.setLocalRepositoryPath(dir.toFile());
try {
// IJPL-175157 one url, should return null since it's under local repository, request symlinks resolve
assertNull(
RepositoryUtils.getStorageRoot(
new String[]{
JpsPathUtil.pathToUrl(symlinkToDir.toString()) + "/com/fasterxml/jackson/jr/jackson-jr-objects/2.17.2/jackson-jr-objects-2.17.2.jar",
}
)
);
// IJPL-175157 one url, should return null since it's under local repository
assertNull(
RepositoryUtils.getStorageRoot(
new String[]{
JpsPathUtil.pathToUrl(dir.toString()) + "/com/fasterxml/jackson/jr/jackson-jr-objects/2.17.2/jackson-jr-objects-2.17.2.jar",
}
)
);
// Another directory; should return it
assertEquals(
FileUtil.toSystemDependentName(dir2 + "/com/fasterxml/jackson/jr/jackson-jr-objects/2.17.2"),
RepositoryUtils.getStorageRoot(
new String[]{
JpsPathUtil.pathToUrl(dir2.toString()) + "/com/fasterxml/jackson/jr/jackson-jr-objects/2.17.2/jackson-jr-objects-2.17.2.jar",
}
)
);
} finally {
JarRepositoryManager.setLocalRepositoryPath(oldLocalRepositoryPath);
FileUtil.deleteRecursively(temp);
}
}
private static String fileContent(Path path) {
try {
return Files.readAllLines(path).get(0);