[maven][IDEA-370993] - do not use application-wide maven local repository in non-jps-projects

GitOrigin-RevId: adfe328e2aefc9729e0c33f6c8e8e3e25b29976f
This commit is contained in:
Alexander Bubenchikov
2025-05-09 08:34:59 +00:00
committed by intellij-monorepo-bot
parent 88a72ce857
commit 92a13083bb
34 changed files with 310 additions and 197 deletions
@@ -48,7 +48,7 @@ class JarHttpDownloaderJps(val project: Project, val coroutineScope: CoroutineSc
@JvmStatic
fun getInstance(project: Project): JarHttpDownloaderJps = project.service<JarHttpDownloaderJps>()
private fun collectRelativePathsForJarHttpDownloaderOrLog(library: LibraryEx): CollectResult {
private fun collectRelativePathsForJarHttpDownloaderOrLog(project: Project?, library: LibraryEx): CollectResult {
if (library.getKind() != RepositoryLibraryType.REPOSITORY_LIBRARY_KIND) {
return CollectResult.Failure("Library '${library.name}' is not a repository library")
}
@@ -73,6 +73,7 @@ class JarHttpDownloaderJps(val project: Project, val coroutineScope: CoroutineSc
val possibleMavenLocalRepositoryRoots = listOfNotNull(
// could be overridden, like in tests
JarRepositoryManager.getLocalRepositoryPath().path,
project?.let { JarRepositoryManager.getJPSLocalMavenRepositoryForIdeaProject(it).toString() },
// always returns a canonical path (symlinks resolved), so can be anything even if it was not overridden
PathMacroManager.getInstance(ApplicationManager.getApplication()).expandPath(JarRepositoryManager.MAVEN_REPOSITORY_MACRO),
@@ -134,7 +135,7 @@ class JarHttpDownloaderJps(val project: Project, val coroutineScope: CoroutineSc
@TestOnly
fun whyLibraryCouldNotBeDownloaded(library: LibraryEx): String? {
val result = collectRelativePathsForJarHttpDownloaderOrLog(library)
val result = collectRelativePathsForJarHttpDownloaderOrLog(null, library)
return if (result is CollectResult.Failure) result.reason else null
}
}
@@ -184,7 +185,7 @@ class JarHttpDownloaderJps(val project: Project, val coroutineScope: CoroutineSc
* return null if `library` could not be downloaded by JarHttpDownloader
*/
fun downloadLibraryFilesAsync(library: LibraryEx): Promise<*>? {
val relativePaths = when (val result = collectRelativePathsForJarHttpDownloaderOrLog(library)) {
val relativePaths = when (val result = collectRelativePathsForJarHttpDownloaderOrLog(project, library)) {
is CollectResult.Failure -> {
LOG.debug(result.reason)
return null
@@ -194,7 +195,7 @@ class JarHttpDownloaderJps(val project: Project, val coroutineScope: CoroutineSc
LOG.debug("Downloading library '${library.name}'")
val localRepository = JarRepositoryManager.getLocalRepositoryPath().toPath()
val localRepository = JarRepositoryManager.getJPSLocalMavenRepositoryForIdeaProject(project)
val remoteRepositories = RemoteRepositoriesConfiguration.getInstance(project).repositories
// TODO Needs some tests on cancellation, it's not supported well
@@ -12,6 +12,7 @@ import com.intellij.notification.NotificationType;
import com.intellij.notification.Notifications;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.application.PathMacros;
import com.intellij.openapi.components.PathMacroManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.*;
@@ -79,6 +80,11 @@ import static com.intellij.jarRepository.JarRepositoryAuthenticationDataProvider
public final class JarRepositoryManager {
private static final Logger LOG = Logger.getInstance(JarRepositoryManager.class);
/**
* * @deprecated Do not use it. See description for getLocalRepositoryPath
*/
@ApiStatus.Obsolete
static final String MAVEN_REPOSITORY_MACRO = "$MAVEN_REPOSITORY$";
private static final String DEFAULT_REPOSITORY_PATH = ".m2/repository";
@@ -111,7 +117,9 @@ public final class JarRepositoryManager {
return ourTasksInProgress.get() > 0; // todo: count tasks on per-project basis?
}
public static @Nullable NewLibraryConfiguration chooseLibraryAndDownload(@NotNull Project project, @Nullable String initialFilter, JComponent parentComponent) {
public static @Nullable NewLibraryConfiguration chooseLibraryAndDownload(@NotNull Project project,
@Nullable String initialFilter,
JComponent parentComponent) {
RepositoryAttachDialog dialog = new RepositoryAttachDialog(project, initialFilter, RepositoryAttachDialog.Mode.DOWNLOAD);
if (!dialog.showAndGet()) {
return null;
@@ -132,7 +140,9 @@ public final class JarRepositoryManager {
project, libraryDescriptor, artifactKinds, copyTo, RemoteRepositoriesConfiguration.getInstance(project).getRepositories()
);
if (config == null) {
Messages.showErrorDialog(parentComponent, JavaUiBundle.message("error.message.no.files.were.downloaded.for.0", libraryDescriptor.getMavenId()), CommonBundle.getErrorTitle());
Messages.showErrorDialog(parentComponent,
JavaUiBundle.message("error.message.no.files.were.downloaded.for.0", libraryDescriptor.getMavenId()),
CommonBundle.getErrorTitle());
}
return config;
}
@@ -160,7 +170,8 @@ public final class JarRepositoryManager {
boolean includeTransitiveDependencies,
String copyTo,
Collection<RemoteRepositoryDescription> repositories) {
JpsMavenRepositoryLibraryDescriptor libraryDescriptor = new JpsMavenRepositoryLibraryDescriptor(coord, includeTransitiveDependencies, Collections.emptyList());
JpsMavenRepositoryLibraryDescriptor libraryDescriptor =
new JpsMavenRepositoryLibraryDescriptor(coord, includeTransitiveDependencies, Collections.emptyList());
return resolveAndDownload(
project, libraryDescriptor, ArtifactKind.kindsOf(attachSources, attachJavaDoc, libraryDescriptor.getPackaging()), copyTo, repositories
);
@@ -189,14 +200,40 @@ public final class JarRepositoryManager {
}
/**
* this method is quickfix until we planning to support compilation with JPS, avoid to use it
*/
@ApiStatus.Experimental
public static @NotNull Path getJPSLocalMavenRepositoryForIdeaProject(@NotNull Project project) {
String expanded = PathMacroManager.getInstance(project).expandPath(MAVEN_REPOSITORY_MACRO);
if (!MAVEN_REPOSITORY_MACRO.equals(expanded) && !expanded.isEmpty()) {
slf4jLogger.debug("RepositoryPath: return expanded macros: " + expanded);
return Path.of(expanded);
}
return getLocalRepositoryPath().toPath();
}
/**
* @deprecated Do not use it. See description for getLocalRepositoryPath
*/
@Deprecated
private static volatile File ourLocalRepositoryPath;
/**
* @deprecated Do not use it. There is no such thing like Local repository path without a project.
* Actually, there is no such thing even for idea project, should be per-linked project
* use getJPSLocalMavenRepositoryForIdeaProject
*/
@Deprecated
public static @NotNull File getLocalRepositoryPath() {
File repoPath = ourLocalRepositoryPath;
if (repoPath != null) {
slf4jLogger.debug("RepositoryPath: return cached application-wide repo: " + repoPath );
return repoPath;
}
final String expanded = PathMacroManager.getInstance(ApplicationManager.getApplication()).expandPath(MAVEN_REPOSITORY_MACRO);
if (!MAVEN_REPOSITORY_MACRO.equals(expanded)) {
if (!MAVEN_REPOSITORY_MACRO.equals(expanded) && !expanded.isEmpty()) {
repoPath = new File(expanded);
if (repoPath.exists()) {
try {
@@ -206,17 +243,27 @@ public final class JarRepositoryManager {
}
}
ourLocalRepositoryPath = repoPath;
slf4jLogger.debug("RepositoryPath: return expanded application-wide repo: " + repoPath );
return repoPath;
}
final String userHome = System.getProperty("user.home", null);
repoPath = userHome != null ? new File(userHome, DEFAULT_REPOSITORY_PATH) : new File(DEFAULT_REPOSITORY_PATH);
ourLocalRepositoryPath = repoPath;
return repoPath;
ourLocalRepositoryPath = getDefaultMavenLocalRepositoryPathNoRespectToSettings();
slf4jLogger.debug("RepositoryPath: return default application-wide repo: " + repoPath );
return ourLocalRepositoryPath;
}
private static File getDefaultMavenLocalRepositoryPathNoRespectToSettings() {
final String userHome = System.getProperty("user.home", null);
return userHome != null ? new File(userHome, DEFAULT_REPOSITORY_PATH) : new File(DEFAULT_REPOSITORY_PATH);
}
/**
* @deprecated Do not use it. See description for getLocalRepositoryPath
*/
@TestOnly
@ApiStatus.Internal
@Deprecated
public static void setLocalRepositoryPath(File localRepo) {
ourLocalRepositoryPath = localRepo;
}
@@ -285,12 +332,12 @@ public final class JarRepositoryManager {
*/
@ApiStatus.Internal
public static @NotNull Collection<OrderRoot> loadDependenciesSync(@NotNull Project project,
@NotNull RepositoryLibraryProperties libraryProps,
boolean loadSources,
boolean loadJavadoc,
@Nullable String copyTo,
@Nullable Collection<RemoteRepositoryDescription> repositories,
@NotNull ProgressIndicator progressIndicator) {
@NotNull RepositoryLibraryProperties libraryProps,
boolean loadSources,
boolean loadJavadoc,
@Nullable String copyTo,
@Nullable Collection<RemoteRepositoryDescription> repositories,
@NotNull ProgressIndicator progressIndicator) {
ApplicationManager.getApplication().assertIsNonDispatchThread();
final JpsMavenRepositoryLibraryDescriptor libDescriptor = libraryProps.getRepositoryLibraryDescriptor();
if (libDescriptor.getMavenId() != null) {
@@ -353,13 +400,15 @@ public final class JarRepositoryManager {
@NotNull RepositoryLibraryDescription libraryDescription,
@NotNull List<RemoteRepositoryDescription> repositories) {
List<RemoteRepositoryDescription> repos = selectRemoteRepositories(project, null, repositories).stream().toList();
return submitBackgroundJob(new VersionResolveJob(libraryDescription, repos));
return submitBackgroundJob(new VersionResolveJob(project, libraryDescription, repos));
}
public static @Nullable ArtifactDependencyNode loadDependenciesTree(@NotNull RepositoryLibraryDescription description, @NotNull String version, Project project) {
public static @Nullable ArtifactDependencyNode loadDependenciesTree(@NotNull RepositoryLibraryDescription description,
@NotNull String version,
Project project) {
List<RemoteRepositoryDescription> repositories = RemoteRepositoriesConfiguration.getInstance(project).getRepositories();
return submitModalJob(project, JavaUiBundle.message("jar.repository.manager.dialog.resolving.dependencies.title", 0),
new AetherJob<>(repositories) {
new AetherJob<>(project, repositories) {
@Override
protected String getProgressText() {
return JavaUiBundle.message("jar.repository.manager.progress.text.loading.dependencies",
@@ -491,7 +540,9 @@ public final class JarRepositoryManager {
}
}
private static @Nullable <T> T submitModalJob(@Nullable Project project, @NlsContexts.DialogTitle String title, Function<? super ProgressIndicator, ? extends T> job) {
private static @Nullable <T> T submitModalJob(@Nullable Project project,
@NlsContexts.DialogTitle String title,
Function<? super ProgressIndicator, ? extends T> job) {
Ref<T> result = Ref.create(null);
new Task.Modal(project, title, true) {
@Override
@@ -536,7 +587,9 @@ public final class JarRepositoryManager {
return promise;
}
private static @NotNull Collection<String> lookupVersionsImpl(String groupId, String artifactId, @NotNull ArtifactRepositoryManager manager) throws Exception {
private static @NotNull Collection<String> lookupVersionsImpl(String groupId,
String artifactId,
@NotNull ArtifactRepositoryManager manager) throws Exception {
try {
List<Version> versions = new ArrayList<>(manager.getAvailableVersions(groupId, artifactId, "[0,)", ArtifactKind.ARTIFACT));
ArrayList<String> strings = new ArrayList<>(versions.size());
@@ -551,9 +604,11 @@ public final class JarRepositoryManager {
}
private abstract static class AetherJob<T> implements Function<ProgressIndicator, T> {
@NotNull private final Project myProject;
private final @NotNull Collection<RemoteRepositoryDescription> myRepositories;
AetherJob(@NotNull Collection<RemoteRepositoryDescription> repositories) {
AetherJob(@NotNull Project project, @NotNull Collection<RemoteRepositoryDescription> repositories) {
myProject = project;
myRepositories = repositories;
}
@@ -569,17 +624,18 @@ public final class JarRepositoryManager {
List<RemoteRepository> remotes = createRemoteRepositories(myRepositories);
try {
return perform(indicator, new ArtifactRepositoryManager(getLocalRepositoryPath(), remotes, new ProgressConsumer() {
@Override
public void consume(@NlsContexts.ProgressText String message) {
indicator.setText(message);
}
return perform(indicator, new ArtifactRepositoryManager(getJPSLocalMavenRepositoryForIdeaProject(myProject).toFile(), remotes,
new ProgressConsumer() {
@Override
public void consume(@NlsContexts.ProgressText String message) {
indicator.setText(message);
}
@Override
public boolean isCanceled() {
return indicator.isCanceled();
}
}));
@Override
public boolean isCanceled() {
return indicator.isCanceled();
}
}));
}
catch (ProcessCanceledException e) {
throw e;
@@ -614,16 +670,15 @@ public final class JarRepositoryManager {
@NotNull Set<ArtifactKind> kinds,
@NotNull Collection<RemoteRepositoryDescription> repositories,
@Nullable String copyTo) {
return new LibraryResolveJob(desc, kinds, repositories).andThen(
return new LibraryResolveJob(project, desc, kinds, repositories).andThen(
resolved -> resolved.isEmpty() ? Collections.emptyList() : copyAndRefreshFiles(project, resolved, copyTo));
}
static List<OrderRoot> copyAndRefreshFiles(@NotNull Project project, @NotNull Collection<Artifact> artifacts, @Nullable String copyTo) {
final List<OrderRoot> result = new ArrayList<>();
final VirtualFileManager manager = VirtualFileManager.getInstance();
String targetRepository = PathMacroManager.getInstance(project).expandPath(MAVEN_REPOSITORY_MACRO);
String localRepositoryPath = getLocalRepositoryPath().getPath();
EelDescriptor targetRepositoryDescriptor = EelProviderUtil.getEelDescriptor(Path.of(targetRepository));
String repositoryPath = getJPSLocalMavenRepositoryForIdeaProject(project).toString();
EelDescriptor targetRepositoryDescriptor = EelProviderUtil.getEelDescriptor(Path.of(repositoryPath));
for (Artifact each : artifacts) {
long ms = System.currentTimeMillis();
try {
@@ -637,8 +692,8 @@ public final class JarRepositoryManager {
}
else if (!targetRepositoryDescriptor.equals(EelProviderUtil.getEelDescriptor(Path.of(each.getFile().getPath())))) {
// if .m2 is located remotely, then we need to copy the files to the remote location
String suffix = repoFile.getAbsolutePath().substring(localRepositoryPath.length());
String actualPath = targetRepository + suffix;
String suffix = repoFile.getAbsolutePath().substring(repositoryPath.length());
String actualPath = repositoryPath + suffix;
toFile = new File(actualPath);
if (repoFile.exists()) {
FileUtil.copy(repoFile, toFile);
@@ -673,10 +728,11 @@ public final class JarRepositoryManager {
private final @NotNull JpsMavenRepositoryLibraryDescriptor myDesc;
private final @NotNull Set<ArtifactKind> myKinds;
LibraryResolveJob(@NotNull JpsMavenRepositoryLibraryDescriptor desc,
LibraryResolveJob(@NotNull Project project,
@NotNull JpsMavenRepositoryLibraryDescriptor desc,
@NotNull Set<ArtifactKind> kinds,
@NotNull Collection<RemoteRepositoryDescription> repositories) {
super(repositories);
super(project, repositories);
myDesc = desc;
myKinds = kinds;
}
@@ -688,7 +744,8 @@ public final class JarRepositoryManager {
@Override
protected String getProgressText() {
return JavaUiBundle.message("jar.repository.manager.library.resolve.progress.text", RepositoryLibraryDescription.findDescription(myDesc).getDisplayName());
return JavaUiBundle.message("jar.repository.manager.library.resolve.progress.text",
RepositoryLibraryDescription.findDescription(myDesc).getDisplayName());
}
@Override
@@ -727,8 +784,8 @@ public final class JarRepositoryManager {
throw e;
}
catch (Exception e) {
slf4jLogger.debug("LibraryResolveJob({}) #{} failed in {}ms", myDesc.getMavenId(), Thread.currentThread().getId(),
Duration.between(startTime, Instant.now()).toMillis(), e);
slf4jLogger.warn("LibraryResolveJob({}) #{} failed in {}ms", myDesc.getMavenId(), Thread.currentThread().getId(),
Duration.between(startTime, Instant.now()).toMillis(), e);
final String resolvedVersion = resolveVersion(manager, version);
if (Objects.equals(version, resolvedVersion)) { // no changes
@@ -771,8 +828,10 @@ public final class JarRepositoryManager {
private static class VersionResolveJob extends AetherJob<Collection<String>> {
private final @NotNull RepositoryLibraryDescription myDescription;
VersionResolveJob(@NotNull RepositoryLibraryDescription repositoryLibraryDescription, @NotNull List<RemoteRepositoryDescription> repositories) {
super(repositories);
VersionResolveJob(@NotNull Project project,
@NotNull RepositoryLibraryDescription repositoryLibraryDescription,
@NotNull List<RemoteRepositoryDescription> repositories) {
super(project, repositories);
myDescription = repositoryLibraryDescription;
}
@@ -786,11 +845,14 @@ public final class JarRepositoryManager {
protected Collection<String> perform(ProgressIndicator progress, @NotNull ArtifactRepositoryManager manager) throws Exception {
var startTime = Instant.now();
slf4jLogger.debug("VersionResolveJob({}:{}) #{} started", myDescription.getGroupId(), myDescription.getArtifactId(), Thread.currentThread().getId());
slf4jLogger.debug("VersionResolveJob({}:{}) #{} started", myDescription.getGroupId(), myDescription.getArtifactId(),
Thread.currentThread().getId());
try {
return lookupVersionsImpl(myDescription.getGroupId(), myDescription.getArtifactId(), manager);
} finally {
slf4jLogger.debug("VersionResolveJob({}:{}) #{} finished in {}ms", myDescription.getGroupId(), myDescription.getArtifactId(), Thread.currentThread().getId(), Duration.between(startTime, Instant.now()).toMillis());
}
finally {
slf4jLogger.debug("VersionResolveJob({}:{}) #{} finished in {}ms", myDescription.getGroupId(), myDescription.getArtifactId(),
Thread.currentThread().getId(), Duration.between(startTime, Instant.now()).toMillis());
}
}
@@ -2,13 +2,13 @@
<library name="smallSampleLibRelease" type="repository">
<properties jar-repository-id="repositoryReleases" maven-id="org.example.repository.library.utils.test:smallSampleLib:1.0">
<verification>
<artifact url="file://$REPOSITORY_LIBRARY_UTILS_TEST_LOCAL_MAVEN_REPOSITORY$/org/example/repository/library/utils/test/smallSampleLib/1.0/smallSampleLib-1.0.jar">
<artifact url="file://$MAVEN_REPOSITORY$/org/example/repository/library/utils/test/smallSampleLib/1.0/smallSampleLib-1.0.jar">
<sha256sum>f0aaca850dd5e399541a9614da99dd194c122e9252b35dafeb088b77b8baf6b1</sha256sum>
</artifact>
</verification>
</properties>
<CLASSES>
<root url="jar://$REPOSITORY_LIBRARY_UTILS_TEST_LOCAL_MAVEN_REPOSITORY$/org/example/repository/library/utils/test/smallSampleLib/1.0/smallSampleLib-1.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/example/repository/library/utils/test/smallSampleLib/1.0/smallSampleLib-1.0.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
@@ -2,7 +2,7 @@
<library name="smallSampleLibSnapshot" type="repository">
<properties jar-repository-id="repositorySnapshots" maven-id="org.example.repository.library.utils.test:smallSampleLib:1.0-SNAPSHOT" />
<CLASSES>
<root url="jar://$REPOSITORY_LIBRARY_UTILS_TEST_LOCAL_MAVEN_REPOSITORY$/org/example/repository/library/utils/test/smallSampleLib/1.0-SNAPSHOT/smallSampleLib-1.0-SNAPSHOT.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/example/repository/library/utils/test/smallSampleLib/1.0-SNAPSHOT/smallSampleLib-1.0-SNAPSHOT.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
@@ -13,13 +13,13 @@
<library name="smallSampleTestLibModuleLevel" type="repository">
<properties jar-repository-id="repositoryReleases" maven-id="org.example.repository.library.utils.test:smallSampleLib:1.0">
<verification>
<artifact url="file://$REPOSITORY_LIBRARY_UTILS_TEST_LOCAL_MAVEN_REPOSITORY$/org/example/repository/library/utils/test/smallSampleLib/1.0/smallSampleLib-1.0.jar">
<artifact url="file://$MAVEN_REPOSITORY$/org/example/repository/library/utils/test/smallSampleLib/1.0/smallSampleLib-1.0.jar">
<sha256sum>f0aaca850dd5e399541a9614da99dd194c122e9252b35dafeb088b77b8baf6b1</sha256sum>
</artifact>
</verification>
</properties>
<CLASSES>
<root url="jar://$REPOSITORY_LIBRARY_UTILS_TEST_LOCAL_MAVEN_REPOSITORY$/org/example/repository/library/utils/test/smallSampleLib/1.0/smallSampleLib-1.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/example/repository/library/utils/test/smallSampleLib/1.0/smallSampleLib-1.0.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
@@ -2,13 +2,13 @@
<library name="smallSampleLibRelease" type="repository">
<properties maven-id="org.example.repository.library.utils.test:smallSampleLib:1.0">
<verification>
<artifact url="file://$REPOSITORY_LIBRARY_UTILS_TEST_LOCAL_MAVEN_REPOSITORY$/org/example/repository/library/utils/test/smallSampleLib/1.0/smallSampleLib-1.0.jar">
<artifact url="file://$MAVEN_REPOSITORY$/org/example/repository/library/utils/test/smallSampleLib/1.0/smallSampleLib-1.0.jar">
<sha256sum>badchecksum</sha256sum>
</artifact>
</verification>
</properties>
<CLASSES>
<root url="jar://$REPOSITORY_LIBRARY_UTILS_TEST_LOCAL_MAVEN_REPOSITORY$/org/example/repository/library/utils/test/smallSampleLib/1.0/smallSampleLib-1.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/example/repository/library/utils/test/smallSampleLib/1.0/smallSampleLib-1.0.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
@@ -2,7 +2,7 @@
<library name="smallSampleLibSnapshot" type="repository">
<properties maven-id="org.example.repository.library.utils.test:smallSampleLib:1.0-SNAPSHOT" />
<CLASSES>
<root url="jar://$REPOSITORY_LIBRARY_UTILS_TEST_LOCAL_MAVEN_REPOSITORY$/org/example/repository/library/utils/test/smallSampleLib/1.0-SNAPSHOT/smallSampleLib-1.0-SNAPSHOT.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/example/repository/library/utils/test/smallSampleLib/1.0-SNAPSHOT/smallSampleLib-1.0-SNAPSHOT.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
@@ -13,13 +13,13 @@
<library name="smallSampleTestLibModuleLevel" type="repository">
<properties maven-id="org.example.repository.library.utils.test:smallSampleLib:1.0">
<verification>
<artifact url="file://$REPOSITORY_LIBRARY_UTILS_TEST_LOCAL_MAVEN_REPOSITORY$/org/example/repository/library/utils/test/smallSampleLib/1.0/smallSampleLib-1.0.jar">
<artifact url="file://$MAVEN_REPOSITORY$/org/example/repository/library/utils/test/smallSampleLib/1.0/smallSampleLib-1.0.jar">
<sha256sum>badchecksumhere</sha256sum>
</artifact>
</verification>
</properties>
<CLASSES>
<root url="jar://$REPOSITORY_LIBRARY_UTILS_TEST_LOCAL_MAVEN_REPOSITORY$/org/example/repository/library/utils/test/smallSampleLib/1.0/smallSampleLib-1.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/example/repository/library/utils/test/smallSampleLib/1.0/smallSampleLib-1.0.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
@@ -2,7 +2,7 @@
<library name="smallSampleLibRelease" type="repository">
<properties maven-id="org.example.repository.library.utils.test:smallSampleLib:1.0" />
<CLASSES>
<root url="jar://$REPOSITORY_LIBRARY_UTILS_TEST_LOCAL_MAVEN_REPOSITORY$/org/example/repository/library/utils/test/smallSampleLib/1.0/smallSampleLib-1.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/example/repository/library/utils/test/smallSampleLib/1.0/smallSampleLib-1.0.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
@@ -2,7 +2,7 @@
<library name="smallSampleLibSnapshot" type="repository">
<properties maven-id="org.example.repository.library.utils.test:smallSampleLib:1.0-SNAPSHOT" />
<CLASSES>
<root url="jar://$REPOSITORY_LIBRARY_UTILS_TEST_LOCAL_MAVEN_REPOSITORY$/org/example/repository/library/utils/test/smallSampleLib/1.0-SNAPSHOT/smallSampleLib-1.0-SNAPSHOT.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/example/repository/library/utils/test/smallSampleLib/1.0-SNAPSHOT/smallSampleLib-1.0-SNAPSHOT.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
@@ -13,7 +13,7 @@
<library name="smallSampleTestLibModuleLevel" type="repository">
<properties maven-id="org.example.repository.library.utils.test:smallSampleLib:1.0" />
<CLASSES>
<root url="jar://$REPOSITORY_LIBRARY_UTILS_TEST_LOCAL_MAVEN_REPOSITORY$/org/example/repository/library/utils/test/smallSampleLib/1.0/smallSampleLib-1.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/example/repository/library/utils/test/smallSampleLib/1.0/smallSampleLib-1.0.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
@@ -2,13 +2,13 @@
<library name="smallSampleLibRelease" type="repository">
<properties maven-id="org.example.repository.library.utils.test:smallSampleLib:1.0">
<verification>
<artifact url="file://$REPOSITORY_LIBRARY_UTILS_TEST_LOCAL_MAVEN_REPOSITORY$/org/example/repository/library/utils/test/smallSampleLib/1.0/smallSampleLib-1.0.jar">
<artifact url="file://$MAVEN_REPOSITORY$/org/example/repository/library/utils/test/smallSampleLib/1.0/smallSampleLib-1.0.jar">
<sha256sum>f0aaca850dd5e399541a9614da99dd194c122e9252b35dafeb088b77b8baf6b1</sha256sum>
</artifact>
</verification>
</properties>
<CLASSES>
<root url="jar://$REPOSITORY_LIBRARY_UTILS_TEST_LOCAL_MAVEN_REPOSITORY$/org/example/repository/library/utils/test/smallSampleLib/1.0/smallSampleLib-1.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/example/repository/library/utils/test/smallSampleLib/1.0/smallSampleLib-1.0.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
@@ -2,7 +2,7 @@
<library name="smallSampleLibSnapshot" type="repository">
<properties maven-id="org.example.repository.library.utils.test:smallSampleLib:1.0-SNAPSHOT" />
<CLASSES>
<root url="jar://$REPOSITORY_LIBRARY_UTILS_TEST_LOCAL_MAVEN_REPOSITORY$/org/example/repository/library/utils/test/smallSampleLib/1.0-SNAPSHOT/smallSampleLib-1.0-SNAPSHOT.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/example/repository/library/utils/test/smallSampleLib/1.0-SNAPSHOT/smallSampleLib-1.0-SNAPSHOT.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
@@ -13,13 +13,13 @@
<library name="smallSampleTestLibModuleLevel" type="repository">
<properties maven-id="org.example.repository.library.utils.test:smallSampleLib:1.0">
<verification>
<artifact url="file://$REPOSITORY_LIBRARY_UTILS_TEST_LOCAL_MAVEN_REPOSITORY$/org/example/repository/library/utils/test/smallSampleLib/1.0/smallSampleLib-1.0.jar">
<artifact url="file://$MAVEN_REPOSITORY$/org/example/repository/library/utils/test/smallSampleLib/1.0/smallSampleLib-1.0.jar">
<sha256sum>f0aaca850dd5e399541a9614da99dd194c122e9252b35dafeb088b77b8baf6b1</sha256sum>
</artifact>
</verification>
</properties>
<CLASSES>
<root url="jar://$REPOSITORY_LIBRARY_UTILS_TEST_LOCAL_MAVEN_REPOSITORY$/org/example/repository/library/utils/test/smallSampleLib/1.0/smallSampleLib-1.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/example/repository/library/utils/test/smallSampleLib/1.0/smallSampleLib-1.0.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
@@ -2,17 +2,17 @@
<library name="apache.commons.math3" type="repository">
<properties include-transitive-deps="false" maven-id="org.apache.commons:commons-math3:3.6">
<verification>
<artifact url="file://$REPOSITORY_LIBRARY_UTILS_TEST_LOCAL_MAVEN_REPOSITORY$/org/apache/commons/commons-math3/3.6/commons-math3-3.6.jar">
<artifact url="file://$MAVEN_REPOSITORY$/org/apache/commons/commons-math3/3.6/commons-math3-3.6.jar">
<sha256sum>79b0baf88d2bc643f652f413e52702d81ac40a9b782d7f00fc431739e8d1c28a</sha256sum>
</artifact>
</verification>
</properties>
<CLASSES>
<root url="jar://$REPOSITORY_LIBRARY_UTILS_TEST_LOCAL_MAVEN_REPOSITORY$/org/apache/commons/commons-math3/3.6/commons-math3-3.6.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/apache/commons/commons-math3/3.6/commons-math3-3.6.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$REPOSITORY_LIBRARY_UTILS_TEST_LOCAL_MAVEN_REPOSITORY$/org/apache/commons/commons-math3/3.6/commons-math3-3.6-sources.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/apache/commons/commons-math3/3.6/commons-math3-3.6-sources.jar!/" />
</SOURCES>
</library>
</component>
@@ -2,17 +2,17 @@
<library name="apache.commons.math3.bad.checksum" type="repository">
<properties include-transitive-deps="false" maven-id="org.apache.commons:commons-math3:3.6">
<verification>
<artifact url="file://$REPOSITORY_LIBRARY_UTILS_TEST_LOCAL_MAVEN_REPOSITORY$/org/apache/commons/commons-math3/3.6/commons-math3-3.6.jar">
<artifact url="file://$MAVEN_REPOSITORY$/org/apache/commons/commons-math3/3.6/commons-math3-3.6.jar">
<sha256sum>000000000000000000000000000000000000000000000000000000000000028a</sha256sum>
</artifact>
</verification>
</properties>
<CLASSES>
<root url="jar://$REPOSITORY_LIBRARY_UTILS_TEST_LOCAL_MAVEN_REPOSITORY$/org/apache/commons/commons-math3/3.6/commons-math3-3.6.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/apache/commons/commons-math3/3.6/commons-math3-3.6.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$REPOSITORY_LIBRARY_UTILS_TEST_LOCAL_MAVEN_REPOSITORY$/org/apache/commons/commons-math3/3.6/commons-math3-3.6-sources.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/apache/commons/commons-math3/3.6/commons-math3-3.6-sources.jar!/" />
</SOURCES>
</library>
</component>
@@ -2,7 +2,7 @@
<library name="smallSampleLibRelease" type="repository">
<properties jar-repository-id="repositoryReleases" maven-id="org.example.repository.library.utils.test:smallSampleLib:1.0" />
<CLASSES>
<root url="jar://$REPOSITORY_LIBRARY_UTILS_TEST_LOCAL_MAVEN_REPOSITORY$/org/example/repository/library/utils/test/smallSampleLib/1.0/smallSampleLib-1.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/example/repository/library/utils/test/smallSampleLib/1.0/smallSampleLib-1.0.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
@@ -2,7 +2,7 @@
<library name="smallSampleLibSnapshot" type="repository">
<properties jar-repository-id="repositorySnapshots" maven-id="org.example.repository.library.utils.test:smallSampleLib:1.0-SNAPSHOT" />
<CLASSES>
<root url="jar://$REPOSITORY_LIBRARY_UTILS_TEST_LOCAL_MAVEN_REPOSITORY$/org/example/repository/library/utils/test/smallSampleLib/1.0-SNAPSHOT/smallSampleLib-1.0-SNAPSHOT.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/example/repository/library/utils/test/smallSampleLib/1.0-SNAPSHOT/smallSampleLib-1.0-SNAPSHOT.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
@@ -13,7 +13,7 @@
<library name="smallSampleTestLibModuleLevel" type="repository">
<properties jar-repository-id="repositoryReleases" maven-id="org.example.repository.library.utils.test:smallSampleLib:1.0" />
<CLASSES>
<root url="jar://$REPOSITORY_LIBRARY_UTILS_TEST_LOCAL_MAVEN_REPOSITORY$/org/example/repository/library/utils/test/smallSampleLib/1.0/smallSampleLib-1.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/example/repository/library/utils/test/smallSampleLib/1.0/smallSampleLib-1.0.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
@@ -48,6 +48,7 @@ class JarHttpDownloaderJpsTest {
@Suppress("SpellCheckingInspection")
private val authPassword = "passw0rd"
@RegisterExtension
@JvmField
internal val serverExtension = TestHttpServerExtension { server ->
@@ -84,9 +85,11 @@ class JarHttpDownloaderJpsTest {
pathMacros.setMacro(TEST_REMOTE_REPOSITORIES_ROOT_MACRO, null)
}
JarRepositoryManager.setLocalRepositoryPath(m2DirectoryPath.toFile())
val repo = PathMacros.getInstance().getValue("MAVEN_REPOSITORY")
PathMacros.getInstance().setMacro("MAVEN_REPOSITORY", m2DirectoryPath.toString())
Disposer.register(disposable) {
JarRepositoryManager.setLocalRepositoryPath(null)
PathMacros.getInstance().setMacro("MAVEN_REPOSITORY", repo)
}
assertTrue(JarHttpDownloader.forceHttps, "default forceHttps must be true")
@@ -1,13 +1,18 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.jarRepository
import com.intellij.idea.TestFor
import com.intellij.openapi.application.PathMacros
import com.intellij.openapi.components.PathMacroManager
import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.AnnotationOrderRootType
import com.intellij.openapi.roots.OrderRootType
import com.intellij.openapi.roots.libraries.ui.OrderRoot
import com.intellij.openapi.util.io.FileUtil
import com.intellij.testFramework.UsefulTestCase
import com.intellij.testFramework.fixtures.IdeaProjectTestFixture
import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory
import com.intellij.testFramework.replaceService
import com.intellij.testFramework.runInEdtAndGet
import com.intellij.testFramework.runInEdtAndWait
import com.intellij.util.ui.UIUtil
@@ -18,6 +23,8 @@ import org.junit.Test
import java.io.File
import java.util.concurrent.TimeUnit
import java.util.concurrent.TimeoutException
import kotlin.io.path.absolutePathString
import kotlin.io.path.createTempDirectory
class JarRepositoryManagerTest : UsefulTestCase() {
@@ -26,6 +33,7 @@ class JarRepositoryManagerTest : UsefulTestCase() {
private lateinit var myMavenRepo: File
private lateinit var myTestLocalMvnCache: File
private lateinit var myTestRepo: RemoteRepositoryDescription
private var myOldTestRepo: String? = null
override fun setUp() {
super.setUp()
@@ -36,11 +44,13 @@ class JarRepositoryManagerTest : UsefulTestCase() {
myMavenRepo = FileUtil.createTempDirectory("maven", "repo")
myTestLocalMvnCache = FileUtil.createTempDirectory("maven", "cache")
myTestRepo = RemoteRepositoryDescription("id", "name", myMavenRepo.toURI().toURL().toString())
JarRepositoryManager.setLocalRepositoryPath(myTestLocalMvnCache)
myOldTestRepo = PathMacros.getInstance().getValue("MAVEN_REPOSITORY")
PathMacros.getInstance().setMacro("MAVEN_REPOSITORY", myTestLocalMvnCache.absolutePath)
}
override fun tearDown() {
try {
PathMacros.getInstance().setMacro("MAVEN_REPOSITORY", myOldTestRepo)
runInEdtAndWait {
myFixture.tearDown()
}
@@ -88,7 +98,8 @@ class JarRepositoryManagerTest : UsefulTestCase() {
assertEquals(AnnotationOrderRootType.getInstance(), root.type)
}
@Test fun `test resolving latest annotations artifact`() {
@Test
fun `test resolving latest annotations artifact`() {
val expectedName = MavenRepoFixture(myMavenRepo).run {
addAnnotationsArtifact(version = "1.0")
addAnnotationsArtifact(version = "1.0-an1")
@@ -109,7 +120,8 @@ class JarRepositoryManagerTest : UsefulTestCase() {
assertTrue("File name [${root.file.name}] should contain '$expectedName'", root.file.name.contains(expectedName))
}
@Test fun `test fallback to previous major annotations version`() {
@Test
fun `test fallback to previous major annotations version`() {
val expectedName = MavenRepoFixture(myMavenRepo).run {
addAnnotationsArtifact(version = "1.0")
addAnnotationsArtifact(version = "2.0")
@@ -132,7 +144,8 @@ class JarRepositoryManagerTest : UsefulTestCase() {
}
@Test fun `test selection for interval`() {
@Test
fun `test selection for interval`() {
val expectedName = MavenRepoFixture(myMavenRepo).run {
addAnnotationsArtifact(version = "1.0")
addAnnotationsArtifact(version = "2.0")
@@ -155,7 +168,8 @@ class JarRepositoryManagerTest : UsefulTestCase() {
assertTrue("File name [${root.file.name} should contain '$expectedName'", root.file.name.contains(expectedName))
}
@Test fun `test selection for snapshot`() {
@Test
fun `test selection for snapshot`() {
MavenRepoFixture(myMavenRepo).apply {
addAnnotationsArtifact(version = "1-SNAPSHOT-an1")
generateMavenMetadata("myGroup", "myArtifact")
@@ -171,7 +185,8 @@ class JarRepositoryManagerTest : UsefulTestCase() {
assertEquals(AnnotationOrderRootType.getInstance(), root.type)
}
@Test fun `test remote repositories selection uses project repos by default`() {
@Test
fun `test remote repositories selection uses project repos by default`() {
RemoteRepositoriesConfiguration.getInstance(myProject).repositories = listOf(
RemoteRepositoryDescription("repo1", "repo1", "https://example.com/repo1"),
RemoteRepositoryDescription("repo2", "repo2", "https://example.com/repo2"),
@@ -185,22 +200,24 @@ class JarRepositoryManagerTest : UsefulTestCase() {
val actualWhenEmptyListPassed = JarRepositoryManager.selectRemoteRepositories(myProject, descriptor, emptyList())
assertEquals(expected, actualWhenEmptyListPassed)
}
@Test fun `test remote repositories selection repo from desc has second priority`() {
@Test
fun `test remote repositories selection repo from desc has second priority`() {
val repo1 = RemoteRepositoryDescription("repo1", "repo1", "https://example.com/repo1")
val repo2 = RemoteRepositoryDescription("repo2", "repo2", "https://example.com/repo2")
RemoteRepositoriesConfiguration.getInstance(myProject).repositories = listOf(repo1, repo2)
val descriptor = createDescriptorWithJarRepoId(repo1.id)
val expected = listOf(repo1)
val actualWhenNullPassed = JarRepositoryManager.selectRemoteRepositories(myProject, descriptor, null)
val actualWhenEmptyListPassed = JarRepositoryManager.selectRemoteRepositories(myProject, descriptor, emptyList())
assertEquals(expected, actualWhenNullPassed)
assertEquals(expected, actualWhenEmptyListPassed)
}
@Test fun `test remote repositories selection explicitly set repos have max priority`() {
}
@Test
fun `test remote repositories selection explicitly set repos have max priority`() {
val repo1 = RemoteRepositoryDescription("repo1", "repo1", "https://example.com/repo1")
val repo2 = RemoteRepositoryDescription("repo2", "repo2", "https://example.com/repo2")
@@ -210,10 +227,11 @@ class JarRepositoryManagerTest : UsefulTestCase() {
val actual = JarRepositoryManager.selectRemoteRepositories(myProject, descriptor, expected)
assertEquals(expected, actual)
}
private fun createDescriptorWithJarRepoId(jarRepoId: String?) = JpsMavenRepositoryLibraryDescriptor("id", false, emptyList(),
emptyList(),
jarRepoId)
private fun getResultingRoots(promise: Promise<MutableList<OrderRoot>>): List<OrderRoot>? {
var result: List<OrderRoot>? = null
(1..5).forEach {
@@ -227,4 +245,39 @@ class JarRepositoryManagerTest : UsefulTestCase() {
}
return result
}
@TestFor(issues = ["IDEA-370993"])
//remove when IDEA-372163 is ready
@Test
fun testShouldResolveToProjectAwareMavenRepoIfSet() {
val myLocalProjectRepo = createTempDirectory()
myProject.replaceService(PathMacroManager::class.java, object : PathMacroManager(null) {
override fun expandPath(text: String?): String? {
return if (text == JarRepositoryManager.MAVEN_REPOSITORY_MACRO) myLocalProjectRepo.absolutePathString()
else text
}
}, testRootDisposable)
MavenRepoFixture(myMavenRepo).apply {
addLibraryArtifact(group = "myGroup", artifact = "myArtifact", version = "1.0")
generateMavenMetadata("group", "artifact")
}
RemoteRepositoriesConfiguration.getInstance(myProject).repositories = listOf(
RemoteRepositoryDescription("id", "name", myMavenRepo.toURI().toURL().toString())
)
val description = JpsMavenRepositoryLibraryDescriptor("myGroup", "myArtifact", "1.0")
val promise = JarRepositoryManager.loadDependenciesAsync(myProject, description, setOf(ArtifactKind.ARTIFACT),
listOf(myTestRepo), null)
val result = getResultingRoots(promise)
assertEquals(1, result!!.size)
val root = result?.get(0)!!
assertEquals(OrderRootType.CLASSES, root.type)
assertTrue("files should be downloaded into project defined repo",
root.file.toString().startsWith("jar://$myLocalProjectRepo"))
}
}
@@ -2,6 +2,7 @@
package com.intellij.jarRepository
import com.intellij.openapi.Disposable
import com.intellij.openapi.application.PathMacros
import com.intellij.openapi.application.runWriteActionAndWait
import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.impl.libraries.LibraryEx
@@ -25,6 +26,7 @@ abstract class LibraryTest : UsefulTestCase() {
protected lateinit var myMavenRepoDescription: RemoteRepositoryDescription
private lateinit var myFixture: IdeaProjectTestFixture
private var myOldTestRepo: String? = null
override fun setUp() {
super.setUp()
@@ -35,11 +37,13 @@ abstract class LibraryTest : UsefulTestCase() {
myMavenRepo = FileUtil.createTempDirectory("maven", "repo")
myMavenLocalCache = FileUtil.createTempDirectory("maven", "cache")
myMavenRepoDescription = RemoteRepositoryDescription("id", "name", myMavenRepo.toURI().toURL().toString())
JarRepositoryManager.setLocalRepositoryPath(myMavenLocalCache)
myOldTestRepo = PathMacros.getInstance().getValue("MAVEN_REPOSITORY")
PathMacros.getInstance().setMacro("MAVEN_REPOSITORY", myMavenLocalCache.absolutePath)
}
override fun tearDown() {
RunAll(
{ PathMacros.getInstance().setMacro("MAVEN_REPOSITORY", myOldTestRepo) },
{ myFixture.tearDown() },
{ super.tearDown() },
).run()
@@ -3,6 +3,7 @@ package com.intellij.jarRepository
import com.intellij.java.library.getMavenCoordinates
import com.intellij.openapi.Disposable
import com.intellij.openapi.application.PathMacros
import com.intellij.openapi.application.runWriteActionAndWait
import com.intellij.openapi.roots.OrderRootType
import com.intellij.openapi.roots.impl.libraries.LibraryEx
@@ -52,7 +53,13 @@ class RepositoryLibraryTest {
@BeforeEach
fun setUp() {
JarRepositoryManager.setLocalRepositoryPath(localMavenCache.root)
val repo = PathMacros.getInstance().getValue("MAVEN_REPOSITORY")
PathMacros.getInstance().setMacro("MAVEN_REPOSITORY", localMavenCache.root.absolutePath)
Disposer.register(disposable) {
PathMacros.getInstance().setMacro("MAVEN_REPOSITORY", repo)
}
MavenRepoFixture(mavenRepo.root).apply {
addLibraryArtifact(group = GROUP_NAME, artifact = ARTIFACT_NAME, version = "1.0")
@@ -108,7 +115,7 @@ class RepositoryLibraryTest {
val roots = RepositoryUtils.loadDependenciesToLibrary(projectRule.project, library as LibraryEx, false, false, null)
.blockingGet(1, TimeUnit.MINUTES)!!
assertTrue(jar.exists())
assertTrue(jar.exists(), "$jar should exist")
assertEquals(1, roots.size)
assertEquals(OrderRootType.CLASSES, roots[0].type)
assertEquals(VfsUtil.getUrlForLibraryRoot(jar), roots[0].file.url)
@@ -130,8 +137,7 @@ class RepositoryLibraryTest {
val modelVersionBefore = workspaceVersion()
RepositoryUtils.loadDependenciesToLibrary(projectRule.project, library as LibraryEx, false, false, null)
.blockingGet(1, TimeUnit.MINUTES)!!
assertTrue(jar.exists())
assertTrue(jar.exists(), "$jar should exist")
assertEquals(listOf(OrderRootType.CLASSES to jarUrl), getLibraryRoots(library).toList())
assertTrue(workspaceVersion() == modelVersionBefore)
}
@@ -29,7 +29,7 @@ class RepositoryLibraryUtilsTest {
/**
* See .idea/libraries/ in testData
*/
private const val TEST_MAVEN_LOCAL_REPOSITORY_MACRO = "REPOSITORY_LIBRARY_UTILS_TEST_LOCAL_MAVEN_REPOSITORY"
var mavenRepositoryOld: String? = null
/**
* See .idea/jarRepositories.xml in testData
*/
@@ -49,17 +49,15 @@ class RepositoryLibraryUtilsTest {
@JvmStatic
fun beforeAll() {
val pathMacros: PathMacros = PathMacros.getInstance()
pathMacros.setMacro(TEST_MAVEN_LOCAL_REPOSITORY_MACRO, m2DirectoryPath.toString())
JarRepositoryManager.setLocalRepositoryPath(m2DirectoryPath.toFile())
mavenRepositoryOld = pathMacros.getValue("MAVEN_REPOSITORY")
pathMacros.setMacro("MAVEN_REPOSITORY", m2DirectoryPath.toString())
}
@AfterClass
@JvmStatic
fun afterAll() {
val pathMacros: PathMacros = PathMacros.getInstance()
pathMacros.setMacro(TEST_MAVEN_LOCAL_REPOSITORY_MACRO, null)
pathMacros.setMacro(TEST_REMOTE_REPOSITORIES_ROOT_MACRO, null)
JarRepositoryManager.setLocalRepositoryPath(null)
pathMacros.setMacro("MAVEN_REPOSITORY", mavenRepositoryOld)
}
}
@@ -2,8 +2,10 @@
package org.jetbrains.idea.maven.utils.library;
import com.intellij.jarRepository.*;
import com.intellij.openapi.application.PathMacros;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.io.IoTestUtil;
import com.intellij.testFramework.ServiceContainerUtil;
@@ -45,6 +45,9 @@ open class PathMacrosImpl @JvmOverloads constructor(private val loadContributors
private val LOG = logger<PathMacrosImpl>()
const val IGNORED_MACRO_ELEMENT = "ignoredMacro"
@Deprecated("to be removed")
@ApiStatus.ScheduledForRemoval
const val MAVEN_REPOSITORY = "MAVEN_REPOSITORY"
@Suppress("ReplaceJavaStaticMethodWithKotlinAnalog")
@@ -154,7 +154,9 @@ private fun ApiVersion.toMavenArtifactVersion(project: Project): String? {
object : Task.Modal(project, KotlinProjectConfigurationBundle.message("fetching.available.maven.versions.title"), true) {
override fun run(indicator: ProgressIndicator) {
val repositoryLibraryProperties = LibraryJarDescriptor.RUNTIME_JDK8_JAR.repositoryLibraryProperties
val version: Version? = ArtifactRepositoryManager(JarRepositoryManager.getLocalRepositoryPath()).getAvailableVersions(
val version: Version? = ArtifactRepositoryManager(
JarRepositoryManager.getJPSLocalMavenRepositoryForIdeaProject(project).toFile()
).getAvailableVersions(
repositoryLibraryProperties.groupId,
repositoryLibraryProperties.artifactId,
"[${apiVersion.versionString},)",
@@ -173,7 +175,8 @@ fun askUpdateRuntime(module: Module, requiredVersion: ApiVersion): Boolean {
fun updateLibraries(project: Project, upToMavenVersion: String, libraries: Collection<Library>) {
if (project.modules.any { module -> module.buildSystemType != BuildSystemType.JPS }) {
val message = KotlinProjectConfigurationBundle.message("automatic.library.version.update.for.maven.and.gradle.projects.is.currently.unsupported.please.update.your.build.scripts.manually")
val message =
KotlinProjectConfigurationBundle.message("automatic.library.version.update.for.maven.and.gradle.projects.is.currently.unsupported.please.update.your.build.scripts.manually")
val title = KotlinProjectConfigurationBundle.message("update.kotlin.runtime.library")
Messages.showMessageDialog(project, message, title, Messages.getErrorIcon())
return
@@ -4,13 +4,13 @@ package org.jetbrains.idea.maven.utils
import com.intellij.compiler.server.BuildProcessParametersProvider
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Pair
import org.jetbrains.idea.maven.project.MavenSettingsCache
import java.nio.file.Path
class MavenBuildProcessParameterProvider(private val project: Project) : BuildProcessParametersProvider() {
override fun getPathParameters(): List<Pair<String, Path>> {
val projectFilePath = project.projectFilePath ?: return emptyList()
val pathMacro = MavenPathMacroContributor.getPathToMavenHome(projectFilePath)
return listOf(Pair.create("-Dide.compiler.maven.path.to.home=", Path.of(pathMacro)))
val pathMacro = MavenSettingsCache.getInstance(project).getEffectiveUserLocalRepo()
return listOf(Pair.create("-Dide.compiler.maven.path.to.home=", pathMacro))
}
}
@@ -1,27 +0,0 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.idea.maven.utils
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.NlsContexts
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.vcs.FilePath
import com.intellij.openapi.vcs.changes.IgnoredBeanFactory
import com.intellij.openapi.vcs.changes.IgnoredFileDescriptor
import com.intellij.openapi.vcs.changes.IgnoredFileProvider
import com.intellij.project.stateStore
import org.jetbrains.idea.maven.project.MavenProjectBundle
import org.jetbrains.idea.maven.utils.MavenSerializedRepositoryManager.Companion.MAVEN_REPOSITORY_MANAGER_STORAGE
class MavenIgnoreFileProvider : IgnoredFileProvider {
override fun isIgnoredFile(project: Project, filePath: FilePath): Boolean {
return filePath.name == MAVEN_REPOSITORY_MANAGER_STORAGE && filePath.parentPath?.path == project.basePath
}
override fun getIgnoredFiles(project: Project): Set<IgnoredFileDescriptor> {
return setOf(IgnoredBeanFactory.ignoreFile(FileUtil.toSystemIndependentName(project.stateStore.projectFilePath.parent.resolve(MAVEN_REPOSITORY_MANAGER_STORAGE).toString()), project))
}
override fun getIgnoredGroupDescription(): @NlsContexts.DetailedDescription String {
return MavenProjectBundle.message("maven.ignored.projects.settings")
}
}
@@ -2,21 +2,9 @@
package org.jetbrains.idea.maven.utils;
import com.intellij.application.options.PathMacrosImpl;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.PathMacroContributor;
import com.intellij.openapi.components.PathMacroManager;
import com.intellij.openapi.components.impl.ProjectWidePathMacroContributor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.platform.eel.EelDescriptor;
import com.intellij.platform.eel.provider.EelProviderUtil;
import com.intellij.platform.eel.provider.LocalEelDescriptor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.SystemIndependent;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Map;
/**
@@ -24,7 +12,7 @@ import java.util.Map;
* On one hand, we have an application-wide macros in `path.macros.xml`. The data from these macros is inapplicable to non-local projects,
* such as WSL and Docker based. Here we decide the location by project.
*/
final class MavenPathMacroContributor implements ProjectWidePathMacroContributor, PathMacroContributor {
final class MavenPathMacroContributor implements PathMacroContributor {
@Override
public void registerPathMacros(@NotNull Map<String, String> macros, @NotNull Map<String, String> legacyMacros) {
@@ -38,42 +26,4 @@ final class MavenPathMacroContributor implements ProjectWidePathMacroContributor
macros.put(PathMacrosImpl.MAVEN_REPOSITORY, System.getProperty(MavenUtil.MAVEN_REPO_LOCAL));
}
}
@Override
public @NotNull Map<@NotNull String, @NotNull String> getProjectPathMacros(@NotNull @SystemIndependent String projectFilePath) {
return Map.of(PathMacrosImpl.MAVEN_REPOSITORY, getPathToMavenHome(projectFilePath));
}
static @NotNull String getPathToMavenHome(@NotNull @SystemIndependent String projectFilePath) {
Path projectFile = Path.of(projectFilePath);
EelDescriptor descriptor = EelProviderUtil.getEelDescriptor(projectFile);
String serializedPath = getBySerializedProjectPath(descriptor, projectFilePath, projectFile);
if (serializedPath != null) {
return serializedPath;
}
return MavenUtil.resolveDefaultLocalRepository(projectFile).toAbsolutePath().toString();
}
private static @Nullable String getBySerializedProjectPath(@NotNull EelDescriptor descriptor,
@NotNull String projectFilePath,
Path projectFile) {
if (descriptor.equals(LocalEelDescriptor.INSTANCE) &&
!Files.exists(projectFile.getParent().resolve(MavenSerializedRepositoryManager.MAVEN_REPOSITORY_MANAGER_STORAGE))) {
// we use the globally defined path macro only if the project has not overridden the setting of its maven home
return PathMacroManager.getInstance(ApplicationManager.getApplication()).expandPath("$" + PathMacrosImpl.MAVEN_REPOSITORY + "$");
}
ProjectManager projectManager = ProjectManager.getInstanceIfCreated();
if (projectManager == null) {
return null;
}
Project[] projects = projectManager.getOpenProjects();
for (Project project : projects) {
if (projectFilePath.equals(project.getProjectFilePath())) {
return project.getService(MavenSerializedRepositoryManager.class).getMavenHomePath().toString();
}
}
return null;
}
}
@@ -0,0 +1,57 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.idea.maven.utils;
import com.intellij.application.options.PathMacrosImpl;
import com.intellij.openapi.components.impl.ProjectWidePathMacroContributor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.platform.eel.EelDescriptor;
import com.intellij.platform.eel.provider.EelProviderUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.SystemIndependent;
import java.nio.file.Path;
import java.util.Collections;
import java.util.Map;
/**
* Maven home path depends on an environment where the project is located.
* On one hand, we have an application-wide macros in `path.macros.xml`. The data from these macros is inapplicable to non-local projects,
* such as WSL and Docker based. Here we decide the location by project.
*/
final class MavenProjectPathMacroContributor implements ProjectWidePathMacroContributor {
@Override
public @NotNull Map<@NotNull String, @NotNull String> getProjectPathMacros(@NotNull @SystemIndependent String projectFilePath) {
//noinspection deprecation
return Map.of(PathMacrosImpl.MAVEN_REPOSITORY, getPathToDefaultMavenLocalRepositoryOnSpecificEnv(projectFilePath));
}
static @NotNull String getPathToDefaultMavenLocalRepositoryOnSpecificEnv(@NotNull @SystemIndependent String projectFilePath) {
Path projectFile = Path.of(projectFilePath);
String serializedPath = getBySerializedProjectPath(projectFilePath);
if (serializedPath != null) {
return serializedPath;
}
return MavenUtil.resolveDefaultLocalRepository(projectFile).toAbsolutePath().toString();
}
private static @Nullable String getBySerializedProjectPath(@NotNull String projectFilePath){
ProjectManager projectManager = ProjectManager.getInstanceIfCreated();
if (projectManager == null) {
return null;
}
Project[] projects = projectManager.getOpenProjects();
for (Project project : projects) {
if (projectFilePath.equals(project.getProjectFilePath())) {
MavenSerializedRepositoryManager manager = project.getService(MavenSerializedRepositoryManager.class);
if (manager.isOverriden()) return manager.getMavenHomePath().toString();
}
}
return null;
}
}
@@ -7,24 +7,18 @@ import com.intellij.platform.eel.path.EelPath
import com.intellij.platform.eel.provider.asEelPath
import com.intellij.platform.eel.provider.asNioPathOrNull
import com.intellij.platform.eel.provider.getEelDescriptor
import org.jetbrains.annotations.ApiStatus
import java.nio.file.Path
/**
* This class contains a per-project storage of maven home directory.
* This class contains a per-project storage of maven home directory for maven macros.
* This location cannot be defined globally, as we might have several projects belonging to different environments (e.g., different docker containers)
*/
@Service(Service.Level.PROJECT)
@State(
name = "MavenRepositoryManager",
storages = [Storage(MavenSerializedRepositoryManager.MAVEN_REPOSITORY_MANAGER_STORAGE, usePathMacroManager = false)],
storages = [Storage(StoragePathMacros.WORKSPACE_FILE, usePathMacroManager = false)],
)
class MavenSerializedRepositoryManager(private val project: Project) : PersistentStateComponent<MavenSerializedRepositoryManager.State> {
companion object {
@ApiStatus.Internal
const val MAVEN_REPOSITORY_MANAGER_STORAGE: String = "mavenHomeManager.xml"
}
private var myState: State = State()
private var path: Path? = null
@@ -45,6 +39,10 @@ class MavenSerializedRepositoryManager(private val project: Project) : Persisten
var mavenHomePath: String? by string()
}
fun isOverriden(): Boolean {
return path == null
}
fun getMavenHomePath(): Path {
val currentPath = path
if (currentPath != null) {
@@ -49,6 +49,7 @@ import com.intellij.platform.eel.EelApi
import com.intellij.platform.eel.EelPlatform
import com.intellij.platform.eel.LocalEelApi
import com.intellij.platform.eel.fs.getPath
import com.intellij.platform.eel.provider.LocalEelDescriptor
import com.intellij.platform.eel.provider.asNioPath
import com.intellij.platform.eel.provider.getEelDescriptor
import com.intellij.platform.eel.provider.localEel
@@ -1135,7 +1136,7 @@ object MavenUtil {
return Path.of(forcedM2Home)
}
val api = if (path == null) localEel else path.getEelApiBlocking()
val api = if (path == null|| path.getEelDescriptor() is LocalEelDescriptor) localEel else path.getEelApiBlocking()
val result: Path = api.resolveM2Dir().resolve(REPOSITORY_DIR)
try {
@@ -79,8 +79,7 @@
<postStartupActivity implementation="org.jetbrains.idea.maven.project.MavenProjectsManagerProjectActivity"/>
<pathMacroContributor implementation="org.jetbrains.idea.maven.utils.MavenPathMacroContributor"/>
<projectPathMacroContributor implementation="org.jetbrains.idea.maven.utils.MavenPathMacroContributor"/>
<ignoredFileProvider implementation="org.jetbrains.idea.maven.utils.MavenIgnoreFileProvider"/>
<projectPathMacroContributor implementation="org.jetbrains.idea.maven.utils.MavenProjectPathMacroContributor"/>
<buildProcess.parametersProvider implementation="org.jetbrains.idea.maven.utils.MavenBuildProcessParameterProvider"/>
<customJavadocTagProvider implementation="org.jetbrains.idea.maven.javadoc.MojoClassAnnotationTagProvider"/>
<fileType name="MavenConfig" implementationClass="org.jetbrains.idea.maven.config.MavenConfigFileType"