This is an automated email from the ASF dual-hosted git repository.
jaikiran pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ant-ivy.git
The following commit(s) were added to refs/heads/master by this push:
new 8e2bdfb IVY-1616 Properly parse the artifact origin location, if the
location is a file: URI
8e2bdfb is described below
commit 8e2bdfb302f1e3e6e20fc727e1853c5edabdf7d4
Author: Jaikiran Pai <[email protected]>
AuthorDate: Mon Mar 29 13:04:56 2021 +0530
IVY-1616 Properly parse the artifact origin location, if the location is a
file: URI
---
asciidoc/release-notes.adoc | 1 +
.../core/cache/DefaultRepositoryCacheManager.java | 39 ++++++++++++++++++++--
.../org/apache/ivy/core/resolve/ResolveTest.java | 28 ++++++++++++++++
.../repositories/ivysettings-caches-use-origin.xml | 28 ++++++++++++++++
4 files changed, 94 insertions(+), 2 deletions(-)
diff --git a/asciidoc/release-notes.adoc b/asciidoc/release-notes.adoc
index 493b9db..b7cbd82 100644
--- a/asciidoc/release-notes.adoc
+++ b/asciidoc/release-notes.adoc
@@ -48,6 +48,7 @@ For details about the following changes, check our JIRA
install at link:https://
- BREAKING: Removed old fr\jayasoft\ivy\ant\antlib.xml AntLib definition file
(jira:IVY-1612[])
- FIX: ResolveEngine resets dictator resolver to null in the global
configuration (jira:IVY-1618[])
- FIX: ConcurrentModificationException in MessageLoggerHelper.sumupProblems
(jira:IVY-1628[])
+- FIX: useOrigin="true" fails with file-based ibiblio (jira:IVY-1616[])
- IMPROVEMENT: Ivy command now accepts a URL for the -settings option
(jira:IVY-1615[])
diff --git
a/src/java/org/apache/ivy/core/cache/DefaultRepositoryCacheManager.java
b/src/java/org/apache/ivy/core/cache/DefaultRepositoryCacheManager.java
index 3206915..497a536 100644
--- a/src/java/org/apache/ivy/core/cache/DefaultRepositoryCacheManager.java
+++ b/src/java/org/apache/ivy/core/cache/DefaultRepositoryCacheManager.java
@@ -21,6 +21,8 @@ import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
@@ -385,7 +387,7 @@ public class DefaultRepositoryCacheManager implements
RepositoryCacheManager, Iv
public File getArchiveFileInCache(Artifact artifact, ArtifactOrigin
origin) {
File archive = new File(getRepositoryCacheRoot(),
getArchivePathInCache(artifact, origin));
if (!archive.exists() && !ArtifactOrigin.isUnknown(origin) &&
origin.isLocal()) {
- File original = Checks.checkAbsolute(origin.getLocation(), artifact
+ File original =
Checks.checkAbsolute(parseArtifactOriginFilePath(origin), artifact
+ " origin location");
if (original.exists()) {
return original;
@@ -407,7 +409,7 @@ public class DefaultRepositoryCacheManager implements
RepositoryCacheManager, Iv
*/
private File getArchiveFileInCache(Artifact artifact, ArtifactOrigin
origin, boolean useOrigin) {
if (useOrigin && !ArtifactOrigin.isUnknown(origin) &&
origin.isLocal()) {
- return Checks.checkAbsolute(origin.getLocation(), artifact + "
origin location");
+ return Checks.checkAbsolute(parseArtifactOriginFilePath(origin),
artifact + " origin location");
}
return new File(getRepositoryCacheRoot(),
getArchivePathInCache(artifact, origin));
}
@@ -1533,6 +1535,39 @@ public class DefaultRepositoryCacheManager implements
RepositoryCacheManager, Iv
}
/**
+ * If the {@link ArtifactOrigin#getLocation() location of the artifact
origin} is a
+ * {@code file:} scheme URI, then this method parses that URI and returns
back the
+ * path of the file it represents. Else returns back {@link
ArtifactOrigin#getLocation()}
+ * @param origin The artifact origin
+ * @return
+ */
+ private static String parseArtifactOriginFilePath(final ArtifactOrigin
origin) {
+ if (origin == null || origin.getLocation() == null) {
+ return null;
+ }
+ final String location = origin.getLocation();
+ if (!location.startsWith("file:")) {
+ // no need to parse it into a URI, if it's not a "file" scheme URI
+ return location;
+ }
+ final URI uri;
+ try {
+ uri = new URI(location);
+ } catch (URISyntaxException e) {
+ return location;
+ }
+ if (!uri.isAbsolute()) {
+ // no scheme in URI, just return the original location
+ return location;
+ } else if (uri.getScheme().equals("file")) {
+ // return the file path
+ return uri.getPath();
+ }
+ // not a "file" scheme URI, just return back the original location
+ return location;
+ }
+
+ /**
* Resource downloader which makes a copy of the previously existing file
before overriding it.
* <p>
* The backup file can be restored or cleaned up later
diff --git a/test/java/org/apache/ivy/core/resolve/ResolveTest.java
b/test/java/org/apache/ivy/core/resolve/ResolveTest.java
index abeae45..633ca64 100644
--- a/test/java/org/apache/ivy/core/resolve/ResolveTest.java
+++ b/test/java/org/apache/ivy/core/resolve/ResolveTest.java
@@ -6589,6 +6589,34 @@ public class ResolveTest {
}
}
+
+ /**
+ * Tests that when the internal metadata file containing the artifact
origin location
+ * points to {@code file:} URI, then the location is correctly parsed.
+ * See IVY-1616
+ */
+ @Test
+ public void testCacheUseOrigin() throws Exception {
+ final Ivy current = new Ivy();
+ current.configure(new
File("test/repositories/ivysettings-caches-use-origin.xml"));
+ // resolve and download an artifact and let the origin details be
stored in the internal metadata files
+ // in ivy cache
+ ResolveReport report =
current.resolve(ModuleRevisionId.newInstance("org.apache",
+ "test","1.0"),
+ getResolveOptions(new String[] {"*"}).setDownload(true),
false);
+ assertNotNull("Resolve report is null", report);
+ assertFalse("Resolution has errors", report.hasError());
+ // now set the "useOrigin" on caches to true, so that the next
resolution uses the artifact origin
+ // that was saved in previous resolution
+ current.getSettings().setDefaultUseOrigin(true);
+ // trigger the resolution again
+ report = current.resolve(ModuleRevisionId.newInstance("org.apache",
+ "test","1.0"),
+ getResolveOptions(new String[] {"*"}).setDownload(true),
false);
+ assertNotNull("Resolve report is null", report);
+ assertFalse("Resolution has errors", report.hasError());
+ }
+
private void assertJarContains(final File jar, final String jarEntryPath)
throws IOException {
try (final JarFile jarFile = new JarFile(jar)) {
final JarEntry entry = jarFile.getJarEntry(jarEntryPath);
diff --git a/test/repositories/ivysettings-caches-use-origin.xml
b/test/repositories/ivysettings-caches-use-origin.xml
new file mode 100644
index 0000000..3ca9ead
--- /dev/null
+++ b/test/repositories/ivysettings-caches-use-origin.xml
@@ -0,0 +1,28 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<ivysettings>
+ <properties file="${ivy.settings.dir}/ivysettings.properties" />
+ <settings defaultResolver="test"/>
+ <caches defaultCacheDir="${cache.dir}"/>
+ <resolvers>
+ <chain name="test">
+ <ibiblio name="m2-local" m2compatible="true"
useMavenMetadata="true" root="file:${ivy.settings.dir}/m2" />
+ </chain>
+ </resolvers>
+</ivysettings>