Skip to content

Commit 467be59

Browse files
committed
Update
1 parent 1f8b460 commit 467be59

File tree

3 files changed

+47
-34
lines changed

3 files changed

+47
-34
lines changed

maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/EnhancedLocalRepositoryManagerFactory.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,10 @@ public class EnhancedLocalRepositoryManagerFactory implements LocalRepositoryMan
6464
public static final String DEFAULT_TRACKING_FILENAME = "_remote.repositories";
6565

6666
/**
67-
* Configuration for "repository key" function.
67+
* <b>Experimental:</b> Configuration for "repository key" function.
6868
* Note: repository key functions other than "simple" produce repository keys will be <em>way different
6969
* that those produced with previous versions or without this option enabled</em>. Ideally, you may want to
70-
* use empty local repository to populate with new repository key contained metadata,
70+
* use empty local repository to populate with new repository key contained metadata.
7171
*
7272
* @since 2.0.14
7373
* @configurationSource {@link RepositorySystemSession#getConfigProperties()}

maven-resolver-util/src/main/java/org/eclipse/aether/util/repository/RepositoryIdHelper.java

Lines changed: 44 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
*/
1919
package org.eclipse.aether.util.repository;
2020

21+
import java.util.ArrayList;
22+
import java.util.Comparator;
2123
import java.util.Locale;
2224
import java.util.SortedSet;
2325
import java.util.TreeSet;
@@ -59,6 +61,11 @@ public enum RepositoryKeyType {
5961
* Crafts unique repository key using {@link RemoteRepository#getId()} and {@link RemoteRepository#getUrl()}.
6062
*/
6163
ID_URL,
64+
/**
65+
* Crafts normalized unique repository key using {@link RemoteRepository#getId()} and all the remaining properties of
66+
* {@link RemoteRepository} ignoring actual list of mirrors, if any (but mirrors are split).
67+
*/
68+
NGURK,
6269
/**
6370
* Crafts unique repository key using {@link RemoteRepository#getId()} and all the remaining properties of
6471
* {@link RemoteRepository}.
@@ -86,6 +93,8 @@ public static RepositoryKeyFunction getRepositoryKeyFunction(String keyTypeStrin
8693
return RepositoryIdHelper::simpleRepositoryKey;
8794
case ID_URL:
8895
return RepositoryIdHelper::idAndUrlRepositoryKey;
96+
case NGURK:
97+
return RepositoryIdHelper::normalizedGloballyUniqueRepositoryKey;
8998
case GURK:
9099
return RepositoryIdHelper::globallyUniqueRepositoryKey;
91100
default:
@@ -98,7 +107,8 @@ public static RepositoryKeyFunction getRepositoryKeyFunction(String keyTypeStrin
98107
* {@link RemoteRepository#isRepositoryManager()} returns {@code true}, in which case this method creates
99108
* unique identifier based on ID and current configuration of the remote repository and context.
100109
* <p>
101-
* This was the default {@code repositoryKey} method in Maven 3.
110+
* This was the default {@code repositoryKey} method in Maven 3. Is exposed (others key methods are private) as
111+
* it is directly used by "simple" LRM.
102112
*
103113
* @since 2.0.14
104114
**/
@@ -137,43 +147,38 @@ private static String idAndUrlRepositoryKey(RemoteRepository repository, String
137147
return idToPathSegment(repository) + "-" + StringDigestUtil.sha1(seed);
138148
}
139149

150+
/**
151+
* Normalized globally unique {@code repositoryKey} function. This method creates unique identifier based on ID and current
152+
* configuration of the remote repository ignoring mirrors (it records the fact repository is a mirror, but ignores
153+
* mirrored repositories). If {@link RemoteRepository#isRepositoryManager()} returns {@code true}, the passed in
154+
* {@code context} string is factored in as well.
155+
*
156+
* @since 2.0.14
157+
**/
158+
private static String normalizedGloballyUniqueRepositoryKey(RemoteRepository repository, String context) {
159+
String seed = remoteRepositoryDescription(repository, false);
160+
if (repository.isRepositoryManager() && context != null && !context.isEmpty()) {
161+
seed += context;
162+
}
163+
return idToPathSegment(repository) + "-" + StringDigestUtil.sha1(seed);
164+
}
165+
140166
/**
141167
* Globally unique {@code repositoryKey} function. This method creates unique identifier based on ID and current
142168
* configuration of the remote repository. If {@link RemoteRepository#isRepositoryManager()} returns {@code true},
143-
* the passed in {@code context} string is factored in as well. This repository key method returns same results as
144-
* {@link #remoteRepositoryUniqueId(RemoteRepository)} if parameter context is {@code null} or empty string.
169+
* the passed in {@code context} string is factored in as well.
145170
* <p>
146171
* <em>Important:</em> this repository key can be considered "stable" for normal remote repositories (where only
147172
* ID and URL matters). But, for mirror repositories, the key will change if mirror members change.
148-
* TODO: reconsider this?
149173
*
150-
* @see #remoteRepositoryUniqueId(RemoteRepository)
151174
* @since 2.0.14
152175
**/
153176
private static String globallyUniqueRepositoryKey(RemoteRepository repository, String context) {
154-
String description = remoteRepositoryDescription(repository);
177+
String seed = remoteRepositoryDescription(repository, true);
155178
if (repository.isRepositoryManager() && context != null && !context.isEmpty()) {
156-
description += context;
179+
seed += context;
157180
}
158-
return idToPathSegment(repository) + "-" + StringDigestUtil.sha1(description);
159-
}
160-
161-
/**
162-
* Creates unique repository id for given {@link RemoteRepository}.
163-
* For any remote repository it will return string created as {@code $(repository.id)-sha1(repository-aspects)}.
164-
* The key material contains all relevant aspects of remote repository, so repository with same ID even if just
165-
* policy changes (enabled/disabled), will map to different string id. The checksum and update policies are not
166-
* participating in key creation.
167-
* <p>
168-
* This method is costly, so should be invoked sparingly, or cache results if needed.
169-
* <p>
170-
* <em>Important:</em>Do not use this method, or at least <em>do consider when do you want to use it</em>, as it
171-
* totally disconnects repositories used in session. This method may be used under some special circumstances
172-
* (ie reporting), but <em>must not be used within Resolver (and Maven) session for "usual" resolution and
173-
* deployment use cases</em>.
174-
*/
175-
public static String remoteRepositoryUniqueId(RemoteRepository repository) {
176-
return idToPathSegment(repository) + "-" + StringDigestUtil.sha1(remoteRepositoryDescription(repository));
181+
return idToPathSegment(repository) + "-" + StringDigestUtil.sha1(seed);
177182
}
178183

179184
/**
@@ -198,7 +203,7 @@ public static String idToPathSegment(ArtifactRepository repository) {
198203
* <li>{@link RemoteRepository#getIntent()}</li>
199204
* </ul>
200205
*/
201-
public static String remoteRepositoryDescription(RemoteRepository repository) {
206+
private static String remoteRepositoryDescription(RemoteRepository repository, boolean mirrorDetails) {
202207
StringBuilder buffer = new StringBuilder(256);
203208
buffer.append(repository.getId());
204209
buffer.append(" (").append(repository.getUrl());
@@ -218,11 +223,19 @@ public static String remoteRepositoryDescription(RemoteRepository repository) {
218223
buffer.append(", managed");
219224
}
220225
if (!repository.getMirroredRepositories().isEmpty()) {
221-
buffer.append(", mirrorOf(");
222-
for (RemoteRepository mirroredRepo : repository.getMirroredRepositories()) {
223-
buffer.append(remoteRepositoryDescription(mirroredRepo));
226+
if (mirrorDetails) {
227+
// sort them to make it stable ordering
228+
ArrayList<RemoteRepository> mirroredRepositories =
229+
new ArrayList<>(repository.getMirroredRepositories());
230+
mirroredRepositories.sort(Comparator.comparing(RemoteRepository::getId));
231+
buffer.append(", mirrorOf(");
232+
for (RemoteRepository mirroredRepo : mirroredRepositories) {
233+
buffer.append(remoteRepositoryDescription(mirroredRepo, true));
234+
}
235+
buffer.append(")");
236+
} else {
237+
buffer.append(", isMirror");
224238
}
225-
buffer.append(")");
226239
}
227240
if (repository.isBlocked()) {
228241
buffer.append(", blocked");

src/site/markdown/configuration.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ To modify this file, edit the template and regenerate.
7474
| `"aether.lrm.enhanced.localPrefix"` | `String` | The prefix to use for locally installed artifacts. | `"installed"` | 1.8.1 | No | Session Configuration |
7575
| `"aether.lrm.enhanced.releasesPrefix"` | `String` | The prefix to use for release artifacts. | `"releases"` | 1.8.1 | No | Session Configuration |
7676
| `"aether.lrm.enhanced.remotePrefix"` | `String` | The prefix to use for remotely cached artifacts. | `"cached"` | 1.8.1 | No | Session Configuration |
77-
| `"aether.lrm.enhanced.repositoryKeyFunction"` | `String` | Configuration for "repository key" function. Note: repository key functions other than "simple" produce repository keys will be <em>way different that those produced with previous versions or without this option enabled</em>. Ideally, you may want to use empty local repository to populate with new repository key contained metadata, | `"simple"` | 2.0.14 | No | Session Configuration |
77+
| `"aether.lrm.enhanced.repositoryKeyFunction"` | `String` | <b>Experimental:</b> Configuration for "repository key" function. Note: repository key functions other than "simple" produce repository keys will be <em>way different that those produced with previous versions or without this option enabled</em>. Ideally, you may want to use empty local repository to populate with new repository key contained metadata. | `"simple"` | 2.0.14 | No | Session Configuration |
7878
| `"aether.lrm.enhanced.snapshotsPrefix"` | `String` | The prefix to use for snapshot artifacts. | `"snapshots"` | 1.8.1 | No | Session Configuration |
7979
| `"aether.lrm.enhanced.split"` | `Boolean` | Whether LRM should split local and remote artifacts. | `false` | 1.8.1 | No | Session Configuration |
8080
| `"aether.lrm.enhanced.splitLocal"` | `Boolean` | Whether locally installed artifacts should be split by version (release/snapshot). | `false` | 1.8.1 | No | Session Configuration |

0 commit comments

Comments
 (0)