mirror of https://github.com/apache/ant-ivy
IVY-1580 Resolve any implicit artifacts when one among multiple dependencies of the same module has an explicit artifact/includes declaration
This commit is contained in:
parent
3cdf4752ec
commit
d714d9dffb
|
|
@ -87,6 +87,7 @@ For details about the following changes, check our JIRA install at link:https://
|
|||
- FIX: ModuleDescriptorMemoryCache didn't detect outdated entries when Ivy file was updated in the cache by another process
|
||||
- FIX: Store ArtifactOrigin's location as a URL
|
||||
- FIX: Retrieve task, with symlink enabled, would not create symlinks for artifacts in certain specific cases (jira:IVY-1594[])
|
||||
- FIX: Generated ivy.xml from pom with multiple dependencies with different classifier does not contain the main dependency (jira:IVY-1580[])
|
||||
|
||||
|
||||
- IMPROVEMENT: Throw an IllegalStateException when retrieving the resolutionCacheRoot on the DefaultResolutionCacheManager if the basedir (or IvySettings) is not set (jira:IVY-1482[])
|
||||
|
|
|
|||
|
|
@ -24,10 +24,15 @@ import java.util.HashSet;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.ivy.core.module.descriptor.DefaultIncludeRule;
|
||||
import org.apache.ivy.core.module.descriptor.DependencyArtifactDescriptor;
|
||||
import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
|
||||
import org.apache.ivy.core.module.descriptor.IncludeRule;
|
||||
import org.apache.ivy.core.module.descriptor.WorkspaceModuleDescriptor;
|
||||
import org.apache.ivy.core.module.id.ArtifactId;
|
||||
import org.apache.ivy.core.module.id.ModuleId;
|
||||
import org.apache.ivy.plugins.matcher.ExactPatternMatcher;
|
||||
import org.apache.ivy.plugins.matcher.PatternMatcher;
|
||||
|
||||
/**
|
||||
* Class collecting usage data for an IvyNode.
|
||||
|
|
@ -233,20 +238,40 @@ public class IvyNodeUsage {
|
|||
return dependencyArtifacts;
|
||||
}
|
||||
|
||||
protected Set<IncludeRule> getDependencyIncludesSet(String rootModuleConf) {
|
||||
Collection<Depender> dependersInConf = dependers.get(rootModuleConf);
|
||||
protected Set<IncludeRule> getDependencyIncludesSet(final String rootModuleConf) {
|
||||
final Collection<Depender> dependersInConf = dependers.get(rootModuleConf);
|
||||
if (dependersInConf == null) {
|
||||
return null;
|
||||
}
|
||||
Set<IncludeRule> dependencyIncludes = new HashSet<>();
|
||||
for (Depender depender : dependersInConf) {
|
||||
IncludeRule[] rules = depender.dd.getIncludeRules(depender.dependerConf);
|
||||
if (rules == null || rules.length == 0) {
|
||||
// no include rule in at least one depender -> we must include everything,
|
||||
// and so return no include rule at all
|
||||
return null;
|
||||
final Set<IncludeRule> dependencyIncludes = new HashSet<>();
|
||||
// true if the depedency descriptor of any of the depender *doesn't* have an explicit
|
||||
// "<artifact>" or an "<include>". false otherwise
|
||||
boolean atLeastOneDependerNeedsAllArtifacts = false;
|
||||
// true if the dependency descriptor of any of the depender either has an explicit "<artifact>"
|
||||
// or an "<include>". false otherwise
|
||||
boolean atLeastOneDependerHasSpecificArtifactSelection = false;
|
||||
for (final Depender depender : dependersInConf) {
|
||||
final DependencyArtifactDescriptor dads[] = depender.dd.getDependencyArtifacts(depender.dd.getModuleConfigurations());
|
||||
final boolean declaresArtifacts = dads != null && dads.length > 0;
|
||||
final IncludeRule[] rules = depender.dd.getIncludeRules(depender.dependerConf);
|
||||
final boolean hasIncludeRule = rules != null && rules.length > 0;
|
||||
if (hasIncludeRule) {
|
||||
dependencyIncludes.addAll(Arrays.asList(rules));
|
||||
}
|
||||
dependencyIncludes.addAll(Arrays.asList(rules));
|
||||
if (declaresArtifacts || hasIncludeRule) {
|
||||
atLeastOneDependerHasSpecificArtifactSelection = true;
|
||||
}
|
||||
if (!hasIncludeRule && !declaresArtifacts) {
|
||||
atLeastOneDependerNeedsAllArtifacts = true;
|
||||
}
|
||||
}
|
||||
// so there's at least one depender D1 which has a specific artifact dependency and at the
|
||||
// same time there's a depender D2 which doesn't have any explicit artifact/includes.
|
||||
// so it is expected that an implicit "include all artifacts" is applied so that dependencies
|
||||
// such as D2 get (all) the artifacts that are published by the dependency's module
|
||||
if (atLeastOneDependerHasSpecificArtifactSelection && atLeastOneDependerNeedsAllArtifacts) {
|
||||
// add a "include all artifacts" rule
|
||||
dependencyIncludes.add(includeAllArtifacts());
|
||||
}
|
||||
return dependencyIncludes;
|
||||
}
|
||||
|
|
@ -313,4 +338,13 @@ public class IvyNodeUsage {
|
|||
return false;
|
||||
}
|
||||
|
||||
private static IncludeRule includeAllArtifacts() {
|
||||
final ArtifactId aid = new ArtifactId(
|
||||
new ModuleId(PatternMatcher.ANY_EXPRESSION, PatternMatcher.ANY_EXPRESSION),
|
||||
PatternMatcher.ANY_EXPRESSION, PatternMatcher.ANY_EXPRESSION,
|
||||
PatternMatcher.ANY_EXPRESSION);
|
||||
return new DefaultIncludeRule(aid, ExactPatternMatcher.INSTANCE, null);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6444,6 +6444,85 @@ public class ResolveTest {
|
|||
assertTrue("Missing artifact(s) with classifiers " + classifiers, classifiers.isEmpty());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tests the issue noted in IVY-1580.
|
||||
* <pre>
|
||||
* org.apache:1580:1.0.0 depends on (Maven modules):
|
||||
* -> org.apache:1580-foo-api:1.2.3
|
||||
* -> org.apache:1580-foo-impl:1.2.3 which in turn depends on:
|
||||
* -> org.apache:1580-foo-api:1.2.3 (in compile scope)
|
||||
* -> org.apache:1580-foo-api:1.2.3 (type = test-jar, in test scope)
|
||||
* </pre>
|
||||
* It's expected that the resolution of org.apache:1580:1.0.0, correctly gets both the regular
|
||||
* jar of org.apache:1580-foo-api as well as the test-jar of the same org.apache:1580-foo-api.
|
||||
*
|
||||
* @see <a href="https://issues.apache.org/jira/browse/IVY-1580">IVY-1580</a>
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Test
|
||||
public void testIvy1580() throws Exception {
|
||||
final File ivyXML = new File("test/repositories/1/ivy-1580/ivy-1580.xml");
|
||||
final ResolveReport resolveReport = ivy.resolve(ivyXML.toURI().toURL(),
|
||||
new ResolveOptions().setConfs(new String[]{"*"}));
|
||||
assertFalse("Resolution report has failures", resolveReport.hasError());
|
||||
final String rootModuleConf = "default";
|
||||
// get the "default" conf, resolution report for the org.apache:1580:1.0.0 module (represented by the
|
||||
// ivy-1580.xml module descriptor)
|
||||
final ConfigurationResolveReport confReport = resolveReport.getConfigurationReport(rootModuleConf);
|
||||
assertNotNull(rootModuleConf + " conf resolution report for " +
|
||||
resolveReport.getModuleDescriptor().getModuleRevisionId() + " is null", confReport);
|
||||
|
||||
final ModuleRevisionId apiDependencyId = ModuleRevisionId.newInstance("org.apache", "1580-foo-api", "1.2.3");
|
||||
final IvyNode apiDepNode = confReport.getDependency(apiDependencyId);
|
||||
assertNotNull("Dependency " + apiDependencyId + " not found in conf resolve report", apiDepNode);
|
||||
final Artifact[] apiArtifacts = apiDepNode.getArtifacts(rootModuleConf);
|
||||
assertNotNull("No artifacts available for dependency " + apiDependencyId, apiArtifacts);
|
||||
assertEquals("Unexpected number of artifacts for dependency " + apiDependencyId, 2, apiArtifacts.length);
|
||||
boolean foundTestJarType = false;
|
||||
boolean foundJarType = false;
|
||||
for (final Artifact apiArtifact : apiArtifacts) {
|
||||
assertEquals("Unexpected artifact name", "1580-foo-api", apiArtifact.getName());
|
||||
assertNotNull("Artifact type is null for " + apiArtifact, apiArtifact.getType());
|
||||
ArtifactDownloadReport apiDownloadReport = null;
|
||||
for (final ArtifactDownloadReport artifactDownloadReport : confReport.getAllArtifactsReports()) {
|
||||
if (artifactDownloadReport.getArtifact().equals(apiArtifact)) {
|
||||
apiDownloadReport = artifactDownloadReport;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assertNotNull("No download report found for artifact " + apiArtifact, apiDownloadReport);
|
||||
final File apiJar = apiDownloadReport.getLocalFile();
|
||||
assertNotNull("artifact jar file is null for " + apiArtifact, apiJar);
|
||||
switch (apiArtifact.getType()) {
|
||||
case "test-jar" : {
|
||||
assertFalse("More than 1 test-jar artifact found", foundTestJarType);
|
||||
foundTestJarType = true;
|
||||
assertJarContains(apiJar, "api-test-file.txt");
|
||||
break;
|
||||
}
|
||||
case "jar" : {
|
||||
assertFalse("More than 1 jar artifact found", foundJarType);
|
||||
foundJarType = true;
|
||||
assertJarContains(apiJar, "api-file.txt");
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
fail("unexpected artifact type " + apiArtifact.getType() + " for artifact " + apiArtifact);
|
||||
}
|
||||
}
|
||||
}
|
||||
assertTrue("No test-jar artifact found for dependency " + apiDependencyId, foundTestJarType);
|
||||
assertTrue("No jar artifact found for dependency " + apiDependencyId, foundJarType);
|
||||
|
||||
// just do some basic check on the impl module as well
|
||||
final ModuleRevisionId implDepId = ModuleRevisionId.newInstance("org.apache", "1580-foo-impl", "1.2.3");
|
||||
final IvyNode implDepNode = confReport.getDependency(implDepId);
|
||||
assertNotNull("Dependency " + implDepId + " not found in conf resolve report", implDepNode);
|
||||
|
||||
}
|
||||
|
||||
private void assertJarContains(final File jar, final String jarEntryPath) throws IOException {
|
||||
try (final JarFile jarFile = new JarFile(jar)) {
|
||||
final JarEntry entry = jarFile.getJarEntry(jarEntryPath);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!--
|
||||
~ 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
|
||||
~
|
||||
~ http://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.
|
||||
-->
|
||||
<ivy-module version="2.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="http://ant.apache.org/ivy/schemas/ivy.xsd">
|
||||
<info organisation="org.apache" module="1580" revision="1.0.0"/>
|
||||
<dependencies>
|
||||
<!-- These modules are Maven based artifacts (available in test/repositories/m2/) -->
|
||||
<dependency org="org.apache" name="1580-foo-api" rev="1.2.3" />
|
||||
<dependency org="org.apache" name="1580-foo-impl" rev="1.2.3" />
|
||||
</dependencies>
|
||||
</ivy-module>
|
||||
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ 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
|
||||
~
|
||||
~ http://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.
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.apache</groupId>
|
||||
<artifactId>1580-foo-api</artifactId>
|
||||
<version>1.2.3</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
</project>
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ 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
|
||||
~
|
||||
~ http://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.
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.apache</groupId>
|
||||
<artifactId>1580-foo-api</artifactId>
|
||||
<version>1.2.3</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
</project>
|
||||
Binary file not shown.
|
|
@ -0,0 +1,45 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ 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
|
||||
~
|
||||
~ http://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.
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.apache</groupId>
|
||||
<artifactId>1580-foo-impl</artifactId>
|
||||
<version>1.2.3</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache</groupId>
|
||||
<artifactId>1580-foo-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache</groupId>
|
||||
<artifactId>1580-foo-api</artifactId>
|
||||
<type>test-jar</type>
|
||||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
|
@ -0,0 +1 @@
|
|||
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ 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
|
||||
~
|
||||
~ http://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.
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.apache</groupId>
|
||||
<artifactId>1580-foo-impl</artifactId>
|
||||
<version>1.2.3</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache</groupId>
|
||||
<artifactId>1580-foo-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache</groupId>
|
||||
<artifactId>1580-foo-api</artifactId>
|
||||
<type>test-jar</type>
|
||||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
Loading…
Reference in New Issue