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 <jaiki...@apache.org> 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>