Compare commits

...

101 Commits

Author SHA1 Message Date
Stefan Bodewig 6546134471
building SBOMs requires Java 9+ 2026-07-26 18:16:49 +02:00
Stefan Bodewig eb29656412
typo 2026-07-26 18:11:41 +02:00
Stefan Bodewig 8f2556cb9f
pack200 now requires asm which is marked optional in commons-compress 2026-07-19 11:32:30 +02:00
Stefan Bodewig 03e4ac2dcb
remove build-system external references 2026-07-19 10:48:37 +02:00
Stefan Bodewig c362906efe
post release stuff to do 2026-07-15 17:38:01 +02:00
Stefan Bodewig b73fc55a25 Tagging version 2.6.0 of Ivy
-----BEGIN PGP SIGNATURE-----
 
 iIkEABYKADEWIQRqkxYesZkOg0bnuisjc439fEDeQwUCalembRMcYm9kZXdpZ0Bh
 cGFjaGUub3JnAAoJECNzjf18QN5DEZMA/jvWXUr1JjjazdAC84Vls/ASCncIzK6e
 ACOpc/0RITPmAP49B9HwvdCzRb1zGLxPfjfAFQ8iBsfciVb3pCvOd3aPAg==
 =sJGc
 -----END PGP SIGNATURE-----
gpgsig -----BEGIN PGP SIGNATURE-----
 
 iIkEABYKADEWIQRqkxYesZkOg0bnuisjc439fEDeQwUCalen3BMcYm9kZXdpZ0Bh
 cGFjaGUub3JnAAoJECNzjf18QN5DH6gA/2Fjhv5GwqioeQEz6HbdZ+QUB13ibV7O
 fSE/psMi4G3XAP4rrrdD932ZImA6lHlBGvh7WtyINU2Z/6+Q5yxM878RAQ==
 =HXlk
 -----END PGP SIGNATURE-----

Merge tag 'rel/2.6.0'

Tagging version 2.6.0 of Ivy

# -----BEGIN PGP SIGNATURE-----
#
# iIkEABYKADEWIQRqkxYesZkOg0bnuisjc439fEDeQwUCalembRMcYm9kZXdpZ0Bh
# cGFjaGUub3JnAAoJECNzjf18QN5DEZMA/jvWXUr1JjjazdAC84Vls/ASCncIzK6e
# ACOpc/0RITPmAP49B9HwvdCzRb1zGLxPfjfAFQ8iBsfciVb3pCvOd3aPAg==
# =sJGc
# -----END PGP SIGNATURE-----
# gpg: Signatur vom Mi 15 Jul 2026 17:25:33 CEST
# gpg:                mittels EDDSA-Schlüssel 6A93161EB1990E8346E7BA2B23738DFD7C40DE43
# gpg:                Aussteller "bodewig@apache.org"
# gpg: Korrekte Signatur von "Stefan Bodewig <bodewig@apache.org>" [ultimativ]
2026-07-15 17:31:40 +02:00
Stefan Bodewig bead264cc5
add License for jQuery Treeview 2026-07-14 17:43:05 +02:00
Stefan Bodewig 63849b29ba
tweak release instructions 2026-07-12 09:10:00 +02:00
Stefan Bodewig 2927c79ff1
prepare RC1 of Ivy 2.6.0 2026-07-12 07:56:24 +02:00
Maarten Coene 8644f1b12e
Use pattern 2026-07-10 12:53:26 +02:00
Stefan Bodewig 9747ab62d0
record github PR #127 , add @raboof 2026-07-10 11:29:58 +02:00
Stefan Bodewig 9bba2ae9ee
Merge pull request #127 from raboof/fix-deterministic-extra-dependency-attributes
fix: make module attribute string encoding deterministic
2026-07-10 05:52:44 +00:00
Arnout Engelen a888e862eb
fix: make module attribute string encoding deterministic
This value makes it into the `pom.xml`'s `extraDependencyAttributes`
property at least for SBT, and it'd be good to have this be
deterministic: aside from general hygiene, generating them bit-by-bit
reproducibly helps validating no malware was sneaked into the artifacts.
This is also called 'Reproducible Builds' (https://reproducible-builds.org/)
2026-07-09 17:59:13 +02:00
Stefan Bodewig bcc04c828f
set all manifest versions to 2.6.0 2026-07-08 21:22:08 +02:00
Maarten Coene fe36d4522a
Update release-notes.adoc
Updated release notes
2026-07-06 18:34:56 +02:00
Maarten Coene 14dc81daa2
Merge pull request #108 from eric-milles/IVY-1662
IVY-1662: collect updates by conf and check transitive on old dependency
2026-07-06 18:32:16 +02:00
Eric Milles 6edbe1907f
IVY-1662: collect updates by conf and check transitive on old dependency 2026-07-01 09:16:49 -05:00
Maarten Coene 489da1e2fc
Update ibiblio.adoc
IVY-1666: try to be a bit more precise in mentionning Maven Central Repository
2026-06-27 00:06:10 +02:00
Maarten Coene 2470ea152c
Update ibiblio.adoc
Replaced 'ibiblio' with 'Maven Central repository' in the documentation. The type 'ibiblio' is kept as is for backwards compatibility reasons.
2026-06-26 23:59:00 +02:00
Maarten Coene dc35d510d2
fixed build 2026-06-26 14:17:03 +02:00
Maarten Coene 788c011d37
Updated release notes with recent merges 2026-06-25 23:45:04 +02:00
Maarten Coene 05981d1a56
Merge pull request #124 from eric-milles/IVY-1656
IVY-1656: write inherited dependencies first to preserve resolve order
2026-06-25 23:40:15 +02:00
Stefan Bodewig 67df79d90a
cyclonedx -> cdx 2026-06-20 08:31:27 +02:00
Eric Milles c30e37cf8f
check info line 2026-06-18 16:04:10 -05:00
Eric Milles 2f085c9b59
extra blank line 2026-06-18 15:22:36 -05:00
Eric Milles 1cac02ef6f
IVY-1656: write inherited dependencies first to preserve resolve order 2026-06-18 11:39:15 -05:00
Maarten Coene 749dca3c09
Merge pull request #123 from eric-milles/IVY-1410-test
rewrite test case to specify files inline
2026-06-17 21:51:23 +02:00
Eric Milles 4db7f57828
rewrite test case to specify files inline 2026-06-17 14:02:11 -05:00
Maarten Coene ee1a61a0a0
Updated release notes with recent merges 2026-06-17 20:33:52 +02:00
Maarten Coene 648768b130
Merge pull request #111 from eric-milles/IVY-1658
IVY-1658: merge `ivy-module` namespaces
2026-06-17 20:19:22 +02:00
Maarten Coene c33191f88d
Merge pull request #114 from eric-milles/IVY-1653
IVY-1653: `makepom`: write overrides to Maven `dependencyManagement` section
2026-06-17 20:12:07 +02:00
Eric Milles 37ad05cf60
PomModuleDescriptorWriter has indents between 2 and 5 2026-06-16 14:40:34 -05:00
Eric Milles 87319046c2
do not write empty dependencyManagement block 2026-06-16 14:32:52 -05:00
Eric Milles 866fddeb18
dependencyManagement before dependencies when missing form template 2026-06-16 14:14:19 -05:00
Eric Milles c9058c78ae
next line continue 2026-06-16 13:38:16 -05:00
Eric Milles 1bc11cd09c
next line continue 2026-06-16 12:52:59 -05:00
Eric Milles 0ccdad9b8c
IVY-1653: makepom: write overrides to Maven dependencyManagement section 2026-06-16 08:59:18 -05:00
Maarten Coene 3b67d9adc7
Updated release notes 2026-06-16 00:14:58 +02:00
Maarten Coene f72d589709
Merge pull request #120 from eric-milles/IVY-1667
IVY-1667: `makepom`: check output lines for `dependencyManagement` element
2026-06-16 00:06:25 +02:00
Maarten Coene a569ad67b8
Merge pull request #119 from eric-milles/IVY-1665
IVY-1665: `checkdepsupdate`: verify version is greater before reporting on available update
2026-06-16 00:05:08 +02:00
Eric Milles 27b4431886
add test case 2026-06-12 13:52:24 -05:00
Eric Milles 0dc2b2d237
IVY-1667: makepom: check output lines for dependencyManagement element 2026-06-12 13:23:36 -05:00
Eric Milles aebe2c1f0f
IVY-1665: use configured LatestStrategy to compare revisions 2026-06-12 13:06:56 -05:00
Eric Milles fd67cacf14
IVY-1665: use default LatestStrategy to compare revisions 2026-06-12 10:19:54 -05:00
Eric Milles 426102ff4d
IVY-1658: merge `ivy-module` namespaces 2026-06-12 09:43:30 -05:00
Stefan Bodewig 8d34dd1ae4
some things require Java9+ 2026-06-12 09:58:35 +02:00
Stefan Bodewig 2a4e550f93
Ant 1.10 is required to build, now. At least I have used Java11 so far. 2026-06-12 09:11:19 +02:00
Stefan Bodewig 0a9234e2de
didn't I say I'd remove the example SBOMs? 2026-06-12 08:21:34 +02:00
Stefan Bodewig b2cd04d116
Merge pull request #118 from apache/cyclonedx
Cyclonedx
2026-06-12 06:13:49 +00:00
Eric Milles e6a9db4456
IVY-1665: verify version is greater before reporting on available update 2026-06-11 15:45:08 -05:00
Maarten Coene 8ca1d8895e
css styling 2026-06-10 00:34:23 +02:00
Maarten Coene 2506b26c2a
IVY-450: highlight active page in tree 2026-06-10 00:34:01 +02:00
Stefan Bodewig c0601d9258
extract files to build dir instead of /tmp 2026-06-07 15:28:17 +02:00
Stefan Bodewig 0e6d805318
temporary folder containing example SBOMs 2026-06-07 07:28:02 +02:00
Stefan Bodewig c8a49f5cf8
target dependency is not required 2026-06-06 18:36:42 +02:00
Stefan Bodewig 6968b1b39f
create SBOMs for tarballs 2026-06-06 18:32:57 +02:00
Stefan Bodewig edb5269d63
add SBOMs to binary distribution 2026-06-06 17:29:45 +02:00
Stefan Bodewig 4b4576e48a
Merge branch 'master' into cyclonedx 2026-06-06 16:54:58 +02:00
Stefan Bodewig df64393433
skip tests if test server is not reachable 2026-06-06 16:54:04 +02:00
Stefan Bodewig f711904dd2
reminder of what to change for a release 2026-06-06 09:19:32 +02:00
Stefan Bodewig ea9bc07131
bump copyright year 2026-06-06 08:31:15 +02:00
Stefan Bodewig fb454b6788
also sign SBOMs, actuylly the openpgp antlib doesn't semm to work for GnuPG 2.x 2026-06-04 20:49:15 +02:00
Stefan Bodewig 16932bebcf
publish SBOM for ivy.jar 2026-06-04 20:44:13 +02:00
Stefan Bodewig d269dbcb87
RAT doesn't like .asf.yaml 2026-06-04 20:40:31 +02:00
Stefan Bodewig a39071ad7f
looks as if the template hasn't been touched for a while 2026-06-04 14:04:59 +02:00
Stefan Bodewig 13423b96a4
new Ant logo 2026-06-04 13:00:15 +02:00
Maarten Coene e86e69443e
Added missing test files 2026-05-20 15:57:36 +02:00
Maarten Coene a4c22ca869
FIX: the 'ivy:install' task didn't take the 'from' resolver into account when resolving Maven parent modules or source/javadoc artifacts. 2026-05-20 09:09:40 +02:00
Stefan Bodewig 8d21b6d0c4
Merge pull request #117 from apache/infrastructure-ruleset-bot/default-branch-protection
[INFRA] Set up default rulesets for default and release branches
2026-05-16 16:10:27 +00:00
The Apache Software Foundation c2fd0d47f2 Set up default protection ruleset for default and release branches 2026-05-15 13:51:47 -05:00
Stefan Bodewig dcd36eac92
document what I've learned about Ivy files. 2026-02-16 18:20:22 +01:00
Stefan Bodewig 0284d83704
Merge pull request #107 from jbeckers/less-wide-osgi-tables
Less wide osgi tables
2026-02-16 17:18:26 +00:00
Maarten Coene 057528e0f4
Merge pull request #115 from eric-milles/assert-throws
Java 8: use `assertThrows` instead of `ExpectedException` rule
2025-09-11 23:10:38 +02:00
Eric Milles d7036d97be
use `assertThrows` instead of `ExpectedException` rule 2025-09-11 11:32:08 -05:00
Eric Milles 3a865956d8
refactor `IvyDependencyUpdateChecker` 2025-09-08 15:01:00 -05:00
Eric Milles af6502084f
project refresh 2025-09-03 22:45:40 +02:00
Maarten Coene 8fe5d37d6c
IVY-1410: FIX: the 'ivy:deliver' task didn't replace dynamic revision from inherited dependencies. 2025-08-31 23:39:45 +02:00
Maarten Coene aa3c169322
IVY-1664: added support for the override child element 2025-08-31 14:41:54 +02:00
Maarten Coene 934bf19233
IVY-1485, IVY-1661 : reverted old change causing issues with replacing dynamic revisions on deliver when there were multiple configurations. 2025-08-31 12:32:47 +02:00
Maarten Coene 58232c0ef0
Merge pull request #110 from eric-milles/IVY-813
IVY-813: add typedef for nearest conflict manager
2025-08-04 22:59:37 +02:00
Eric Milles 9817b7c03f
IVY-813: add typedef for nearest conflict manager 2025-08-04 10:47:12 -05:00
Maarten Coene 75b554334e
IVY-1660: the ivy:retrieve task failed when the retrieve pattern contained some text in parentheses before the first token 2025-08-01 22:41:32 +02:00
Maarten Coene 889bedb4ef
Mention Java 8 or higher is required now 2025-07-08 22:10:02 +02:00
Joachim Beckers c22c9e3627
Merge branch 'apache:master' into less-wide-osgi-tables 2025-07-06 16:56:26 +02:00
Maarten Coene 7b3ebeb083
Added missing '2.5' version and prepare for '2.6' as well 2025-07-04 00:02:08 +02:00
Joachim Beckers 114d6d819e
Make OSGi tables less wide 2025-07-02 11:17:12 +02:00
Joachim Beckers 9f8a1ecbab
Merge branch 'apache:master' into master 2025-07-02 11:15:00 +02:00
Maarten Coene 318c5c64e8
Merge pull request #105 from jbeckers/inline-mode-no-literal-block
Remove spurious indent for 'Inline mode'
2025-06-28 19:40:30 +02:00
Joachim Beckers b6c823bc8f
Merge pull request #1 from jbeckers/inline-mode-no-literal-block
Remove spurious indent for 'Inline mode'
2025-06-27 21:04:56 +02:00
Joachim Beckers 79e2599a0a
Remove spurious indent for 'Inline mode'
The "Inline mode" paragraph starts with a space, which is an asciidoc construct: https://docs.asciidoctor.org/asciidoc/latest/verbatim/literal-blocks/

Remove the spurious space
2025-06-27 21:03:44 +02:00
Maarten Coene ea70bbe7e3
IVY-813: added a 'nearest' conflict manager 2025-06-08 12:57:50 +02:00
Maarten Coene 60a1ff1b11
Updated OSGI bundle headers for new pack200 code 2025-04-29 23:44:05 +02:00
Maarten Coene ec7b728251
Reorganized code a bit in an attempt to avoid class loading issues while loading ivy settings. 2025-04-29 23:21:51 +02:00
Maarten Coene 05fdc916fb
Also catch errors when trying to instantiate optional classes. 2025-04-24 00:39:32 +02:00
Maarten Coene 5f9e01d7a0
Added the default constructor in an attempt to fix a NoClassDefFoundError 2025-04-23 23:46:50 +02:00
Maarten Coene d77284167b
IMPROVEMENT: use Apache Commons Compress for pack200 handling to avoid issues on Java 14 and later. (IVY-1652) 2025-04-23 23:04:43 +02:00
Maarten Coene 3a8510df01
Use latest Apache Rat Ant Task Library 2025-04-21 23:23:35 +02:00
Maarten Coene 646b1d2fea
Mention to delete your Ivy cache after upgrading. 2025-04-21 23:15:34 +02:00
Maarten Coene 6a8cfd4004
FIX: improved Maven dependencyManagement matching for dependencies with a non-default type or classifier (IVY-1654) 2025-03-25 00:00:19 +01:00
Maarten Coene a9eb9f1680
Prepare for next development iteration 2025-01-29 23:22:06 +01:00
Maarten Coene a26e706dbd
Prepare for next development iteration 2025-01-07 16:42:06 +01:00
114 changed files with 3770 additions and 1774 deletions

14
.asf.yaml Normal file
View File

@ -0,0 +1,14 @@
github:
rulesets:
- name: "Default Branch Protection"
type: branch
branches:
includes:
- "~DEFAULT_BRANCH"
- "release/*"
- "rel/*"
excludes: []
bypass_teams:
- root
restrict_deletion: true
restrict_force_push: true

View File

@ -20,7 +20,7 @@
<classpath>
<classpathentry kind="src" path="src/java"/>
<classpathentry kind="src" path="test/java"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="lib" path="lib/ant.jar"/>
<classpathentry kind="lib" path="lib/ant-testutil.jar"/>
<classpathentry kind="lib" path="lib/commons-codec.jar"/>

View File

@ -20,7 +20,7 @@
<classpath>
<classpathentry kind="src" path="src/java"/>
<classpathentry kind="src" path="test/java"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="con" path="org.apache.ivyde.eclipse.cpcontainer.IVYDE_CONTAINER/?project=ivy&amp;ivyXmlPath=ivy.xml&amp;confs=*&amp;ivySettingsPath=&amp;propertyFiles=version.properties"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View File

@ -1,4 +1,3 @@
#Thu Mar 13 22:45:49 CET 2014
# ***************************************************************
# * Licensed to the Apache Software Foundation (ASF) under one
# * or more contributor license agreements. See the NOTICE file
@ -7,9 +6,9 @@
# * 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
@ -20,15 +19,15 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.7
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.7
org.eclipse.jdt.core.compiler.source=1.8
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0

File diff suppressed because one or more lines are too long

View File

@ -1,23 +0,0 @@
#Sun Sep 03 16:43:34 PDT 2006
# ***************************************************************
# * 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.
# ***************************************************************
acceptedTypes=[inherited]
eclipse.preferences.version=1
ivy_conf_path=file\:///./ivysettings.xml
retreive.pattern=none

33
LICENSE
View File

@ -256,6 +256,39 @@ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
------------------------------------------------------------------------------
License for jQuery Treeview
------------------------------------------------------------------------------
Treeview 1.2 - jQuery plugin to hide and show branches of a tree
Copyright (c) 2006 Jörn Zaefferer, Myles Angell
Dual licensed under the MIT and GPL licenses:
http://www.opensource.org/licenses/mit-license.php
http://www.gnu.org/licenses/gpl.html
MIT Option:
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
“Software”), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
------------------------------------------------------------------------------
License for ganymed ssh library
------------------------------------------------------------------------------

View File

@ -1,7 +1,7 @@
Manifest-Version: 1.0
Main-Class: org.apache.ivy.Main
Automatic-Module-Name: org.apache.ivy
Bundle-Version: 2.4.0
Bundle-Version: 2.6.0
Bundle-Name: Ivy
Bundle-ManifestVersion: 2
Bundle-SymbolicName: org.apache.ivy
@ -15,6 +15,7 @@ Import-Package: com.jcraft.jsch;resolution:=optional,
javax.xml.transform,
javax.xml.transform.sax,
javax.xml.transform.stream,
org.apache.commons.compress.compressors.pack200;resolution:=optional,
org.apache.commons.httpclient;resolution:=optional,
org.apache.commons.httpclient.auth;resolution:=optional,
org.apache.commons.httpclient.methods;resolution:=optional,
@ -44,70 +45,71 @@ Import-Package: com.jcraft.jsch;resolution:=optional,
org.xml.sax,
org.xml.sax.ext,
org.xml.sax.helpers
Export-Package: org.apache.ivy;version="2.0.0",
org.apache.ivy.ant;version="2.0.0",
org.apache.ivy.core;version="2.0.0",
org.apache.ivy.core.cache;version="2.0.0",
org.apache.ivy.core.check;version="2.0.0",
org.apache.ivy.core.deliver;version="2.0.0",
org.apache.ivy.core.event;version="2.0.0",
org.apache.ivy.core.event.download;version="2.0.0",
org.apache.ivy.core.event.publish;version="2.0.0",
org.apache.ivy.core.event.resolve;version="2.0.0",
org.apache.ivy.core.event.retrieve;version="2.0.0",
org.apache.ivy.core.install;version="2.0.0",
org.apache.ivy.core.module.descriptor;version="2.0.0",
org.apache.ivy.core.module.id;version="2.0.0",
org.apache.ivy.core.module.status;version="2.0.0",
org.apache.ivy.core.pack;version="2.4.0",
org.apache.ivy.core.publish;version="2.0.0",
org.apache.ivy.core.report;version="2.0.0",
org.apache.ivy.core.repository;version="2.0.0",
org.apache.ivy.core.resolve;version="2.0.0",
org.apache.ivy.core.retrieve;version="2.0.0",
org.apache.ivy.core.search;version="2.0.0",
org.apache.ivy.core.settings;version="2.0.0",
org.apache.ivy.core.sort;version="2.0.0",
org.apache.ivy.osgi.core;version="2.3.0",
org.apache.ivy.osgi.filter;version="2.3.0",
org.apache.ivy.osgi.obr;version="2.3.0",
org.apache.ivy.osgi.obr.xml;version="2.3.0",
org.apache.ivy.osgi.p2;version="2.3.0",
org.apache.ivy.osgi.repo;version="2.3.0",
org.apache.ivy.osgi.updatesite;version="2.3.0",
org.apache.ivy.osgi.updatesite.xml;version="2.3.0",
org.apache.ivy.osgi.util;version="2.3.0",
org.apache.ivy.plugins;version="2.0.0",
org.apache.ivy.plugins.circular;version="2.0.0",
org.apache.ivy.plugins.conflict;version="2.0.0",
org.apache.ivy.plugins.latest;version="2.0.0",
org.apache.ivy.plugins.lock;version="2.0.0",
org.apache.ivy.plugins.matcher;version="2.0.0",
org.apache.ivy.plugins.namespace;version="2.0.0",
org.apache.ivy.plugins.parser;version="2.0.0",
org.apache.ivy.plugins.parser.m2;version="2.0.0",
org.apache.ivy.plugins.parser.xml;version="2.0.0",
org.apache.ivy.plugins.report;version="2.0.0",
org.apache.ivy.plugins.repository;version="2.0.0",
org.apache.ivy.plugins.repository.file;version="2.0.0",
org.apache.ivy.plugins.repository.jar;version="2.3.0",
org.apache.ivy.plugins.repository.sftp;version="2.0.0",
org.apache.ivy.plugins.repository.ssh;version="2.0.0",
org.apache.ivy.plugins.repository.url;version="2.0.0",
org.apache.ivy.plugins.repository.vfs;version="2.0.0",
org.apache.ivy.plugins.repository.vsftp;version="2.0.0",
org.apache.ivy.plugins.resolver;version="2.0.0",
org.apache.ivy.plugins.resolver.packager;version="2.0.0",
org.apache.ivy.plugins.resolver.util;version="2.0.0",
org.apache.ivy.plugins.signer;version="2.2.0",
org.apache.ivy.plugins.signer.bouncycastle;version="2.2.0",
org.apache.ivy.plugins.trigger;version="2.0.0",
org.apache.ivy.plugins.version;version="2.0.0",
org.apache.ivy.tools.analyser;version="2.0.0",
org.apache.ivy.util;version="2.0.0",
org.apache.ivy.util.cli;version="2.0.0",
org.apache.ivy.util.extendable;version="2.0.0",
org.apache.ivy.util.filter;version="2.0.0",
org.apache.ivy.util.url;version="2.0.0"
Export-Package: org.apache.ivy;version="2.6.0",
org.apache.ivy.ant;version="2.6.0",
org.apache.ivy.core;version="2.6.0",
org.apache.ivy.core.cache;version="2.6.0",
org.apache.ivy.core.check;version="2.6.0",
org.apache.ivy.core.deliver;version="2.6.0",
org.apache.ivy.core.event;version="2.6.0",
org.apache.ivy.core.event.download;version="2.6.0",
org.apache.ivy.core.event.publish;version="2.6.0",
org.apache.ivy.core.event.resolve;version="2.6.0",
org.apache.ivy.core.event.retrieve;version="2.6.0",
org.apache.ivy.core.install;version="2.6.0",
org.apache.ivy.core.module.descriptor;version="2.6.0",
org.apache.ivy.core.module.id;version="2.6.0",
org.apache.ivy.core.module.status;version="2.6.0",
org.apache.ivy.core.pack;version="2.6.0",
org.apache.ivy.core.publish;version="2.6.0",
org.apache.ivy.core.report;version="2.6.0",
org.apache.ivy.core.repository;version="2.6.0",
org.apache.ivy.core.resolve;version="2.6.0",
org.apache.ivy.core.retrieve;version="2.6.0",
org.apache.ivy.core.search;version="2.6.0",
org.apache.ivy.core.settings;version="2.6.0",
org.apache.ivy.core.sort;version="2.6.0",
org.apache.ivy.osgi.core;version="2.6.0",
org.apache.ivy.osgi.filter;version="2.6.0",
org.apache.ivy.osgi.obr;version="2.6.0",
org.apache.ivy.osgi.obr.xml;version="2.6.0",
org.apache.ivy.osgi.p2;version="2.6.0",
org.apache.ivy.osgi.repo;version="2.6.0",
org.apache.ivy.osgi.updatesite;version="2.6.0",
org.apache.ivy.osgi.updatesite.xml;version="2.6.0",
org.apache.ivy.osgi.util;version="2.6.0",
org.apache.ivy.plugins;version="2.6.0",
org.apache.ivy.plugins.circular;version="2.6.0",
org.apache.ivy.plugins.conflict;version="2.6.0",
org.apache.ivy.plugins.latest;version="2.6.0",
org.apache.ivy.plugins.lock;version="2.6.0",
org.apache.ivy.plugins.matcher;version="2.6.0",
org.apache.ivy.plugins.namespace;version="2.6.0",
org.apache.ivy.plugins.pack;version="2.6.0",
org.apache.ivy.plugins.parser;version="2.6.0",
org.apache.ivy.plugins.parser.m2;version="2.6.0",
org.apache.ivy.plugins.parser.xml;version="2.6.0",
org.apache.ivy.plugins.report;version="2.6.0",
org.apache.ivy.plugins.repository;version="2.6.0",
org.apache.ivy.plugins.repository.file;version="2.6.0",
org.apache.ivy.plugins.repository.jar;version="2.6.0",
org.apache.ivy.plugins.repository.sftp;version="2.6.0",
org.apache.ivy.plugins.repository.ssh;version="2.6.0",
org.apache.ivy.plugins.repository.url;version="2.6.0",
org.apache.ivy.plugins.repository.vfs;version="2.6.0",
org.apache.ivy.plugins.repository.vsftp;version="2.6.0",
org.apache.ivy.plugins.resolver;version="2.6.0",
org.apache.ivy.plugins.resolver.packager;version="2.6.0",
org.apache.ivy.plugins.resolver.util;version="2.6.0",
org.apache.ivy.plugins.signer;version="2.6.0",
org.apache.ivy.plugins.signer.bouncycastle;version="2.6.0",
org.apache.ivy.plugins.trigger;version="2.6.0",
org.apache.ivy.plugins.version;version="2.6.0",
org.apache.ivy.tools.analyser;version="2.6.0",
org.apache.ivy.util;version="2.6.0",
org.apache.ivy.util.cli;version="2.6.0",
org.apache.ivy.util.extendable;version="2.6.0",
org.apache.ivy.util.filter;version="2.6.0",
org.apache.ivy.util.url;version="2.6.0"
Bundle-ClassPath: .
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Bundle-RequiredExecutionEnvironment: JavaSE-1.8

2
NOTICE
View File

@ -1,5 +1,5 @@
Apache Ivy (TM)
Copyright 2007-2024 The Apache Software Foundation
Copyright 2007-2026 The Apache Software Foundation
This product includes software developed at
The Apache Software Foundation (http://www.apache.org/).

View File

@ -25,6 +25,8 @@ For Ivy 2.4.0, a minimum of Java 5 is required.
Since Ivy 2.5.0, a minimum of Java 7 is required.
Since Ivy 2.5.1, a minimum of Java 8 is required.
== Apache Ant
Ivy doesn't require a specific version of Ant as long as the Ant being used complies with the JVM compatibility requirements noted above.

View File

@ -28,11 +28,14 @@ All you need is
* a link:https://git-scm.com/downloads[Git] client +
_to check out Ivy sources from Apache Git, not required if you build from sources packaged in a release_
* link:https://ant.apache.org/[Apache Ant] 1.9.0 or greater +
* link:https://ant.apache.org/[Apache Ant] 1.10.0 or greater +
_We recommend the latest version of Ant_
* a link:http://www.oracle.com/technetwork/java/javase/downloads/index.html[JDK] 7 or greater +
_Build instructions have been successfully tested with Oracle JDK 7 and 8_
_Build instructions have been successfully tested with OpenJDK 8 and 11_
Some of the targets used during the release process generate CycloneDX
SBOMs and require Java 9 or greater in order to build.
=== Procedure
@ -42,7 +45,7 @@ You can either get the sources from a release, or get them directly from Git:
[source,shell]
----
git clone git://git.apache.org/ant-ivy.git
git clone https://gitbox.apache.org/repos/asf/ant-ivy.git
----
==== Build

View File

@ -29,7 +29,10 @@ Requirements for making a release are similar to the requirements for building f
On the master, check that files which require update for the release are up to date.
This includes particularly:
`asciidoc/release-notes.adoc`
- `asciidoc/release-notes.adoc`
- `version.properties` (`target.ivy.bundle.version.qualifier` shoud be `final`)
- `ivy.xml` (`status` should be `release`)
==== 2. Check out a clean copy of the branch
@ -92,7 +95,7 @@ Here is a ruby script you can use to sign the files:
require 'find'
Find.find('build/distrib') do |f|
`gpg --armor --output #{f}.asc --detach-sig #{f}` if File.file?(f) && ['.zip', '.gz', '.jar', '.pom'].include?(File.extname(f))
`gpg --armor --output #{f}.asc --detach-sig #{f}` if File.file?(f) && ['.zip', '.gz', '.jar', '.pom', '.xml', '.json'].include?(File.extname(f))
end
----
@ -126,6 +129,8 @@ Having your GPG key ID, its password, your apache ID and the associated password
ant -f build-release.xml upload-nexus
----
NOTE: the openpgp library used doesn't seem to support modern algorithms. The step failed for Stefan using an ECC key. The workaround is to manually sign all artifacts and using Nexus "upload bundle" feature to uplad a zip of all artifacts and signatures.
Once uploaded, log in https://repository.apache.org/ with your preferred web browser (use your Apache ID).
You should find there an __open__ repository with the name of the form `orgapacheant-XXXX`. It should contain the Maven artifacts: the pom, the jar, the sources, the javadocs and the sha and asc files.
@ -283,15 +288,23 @@ Regards,
${me}
----
==== 17. Update this doc
==== 17. Some Housekeeping
- update `doap_Ivy.rdf` in this repository and add the release.
- log in to https://reporter.apache.org/addrelease.html?ant and add the release information
- mark the version as released and a newr elease version to Jira https://issues.apache.org/jira/projects/IVY?selectedItem=com.atlassian.jira.jira-projects-plugin:release-page
- update Ant's homepage and the news page to anounce the release
- After a few days "svn rm" the older release artifacts from https://dist.apache.org/repos/dist/release/ant/ivy
==== 18. Update this doc
If you feel like anything is missing or misleading in this release doc, update it as soon as you encounter the problem.
==== 18. Merge your modifications back to the master if necessary.
==== 19. Merge your modifications back to the master if necessary.
Modifications on the template files do not need to be merged, but if you had troubles during your release you may want to merge your fixes back to the trunk.
==== 19. Prepare next release
==== 20. Prepare next release
In the master branch, update the file version.properties with the version of the next release so that anyone building from the trunk will obtain jar with the correct version number.

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@ -47,6 +47,8 @@ For those familiar with XML schema, the schema used to validate Ivy files can be
</ivy-module>
----
Ivy expects to use the "no namespace" namespace, so you can't use an XML namespace to identify Ivy elements or attributes or use any namespace prefix for Ivy's built-in elements/attributes.
== Dynamic and [[resolved]]resolved Ivy files
A module descriptor (Ivy file) is needed both before and after the publication of each revision of the module. Depending on the case, a module descriptor can be either _dynamic_ or _resolved_.

25
asciidoc/js/menu.js Normal file
View File

@ -0,0 +1,25 @@
/*
* 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.
*
*/
function highlightActiveMenuItem() {
var pageId = document.body.dataset.pageId;
if (pageId) {
var id = CSS.escape('xooki-' + pageId);
document.querySelector('#' + id + ' a')?.classList.add('active-menu-item');
}
}

View File

@ -155,7 +155,11 @@ If there is the OSGi `resolution` parameter specified to `optional`, then the de
a|
[source, xml]
----
<dependency osgi="bundle" org="" name="com.acme.product.plugin" rev="[3.2.1,)" conf="default->default"/>
<dependency osgi="bundle"
org=""
name="com.acme.product.plugin"
rev="[3.2.1,)"
conf="default->default"/>
----
@ -163,7 +167,10 @@ a|
a|
[source, xml]
----
<dependency org="bundle" name="com.acme.product.plugin" rev="[3.2.1,)" conf="optional->default;transitive-optional->transitive-optional"/>
<dependency org="bundle"
name="com.acme.product.plugin"
rev="[3.2.1,)"
conf="optional->default;transitive-optional->transitive-optional"/>
----
@ -188,7 +195,10 @@ As it is an import package, the configuration of the dependency will be the `use
a|
[source, xml]
----
<dependency org="package" name="com.acme.product.plugin.utils" rev="[3.2.1,)" conf="default->default;use_com.acme.product.plugin.utils->use_com.acme.product.plugin.utils"/>
<dependency org="package"
name="com.acme.product.plugin.utils"
rev="[3.2.1,)"
conf="default->default;use_com.acme.product.plugin.utils->use_com.acme.product.plugin.utils"/>
----
@ -196,7 +206,10 @@ a|
a|
[source, xml]
----
<dependency org="package" name="com.acme.product.plugin.utils" rev="[3.2.1,)" conf="optional->default;transitive-optional->transitive-optional;use_com.acme.product.plugin.utils->use_com.acme.product.plugin.utils"/>
<dependency org="package"
name="com.acme.product.plugin.utils"
rev="[3.2.1,)"
conf="optional->default;transitive-optional->transitive-optional;use_com.acme.product.plugin.utils->use_com.acme.product.plugin.utils"/>
----

View File

@ -19,7 +19,7 @@
= Ivy Release Announcement
December 23 2024 - The Apache Ivy project is pleased to announce its 2.5.3 release.
XXXX Date XXXX - The Apache Ivy project is pleased to announce its 2.6.1 release.
== What is Ivy?
Apache Ivy is a tool for managing (recording, tracking, resolving and reporting) project dependencies, characterized by flexibility,
@ -34,18 +34,15 @@ More information about the project can be found on the website link:https://ant.
== Key features in this release
This 2.5.3 release is a bugfix release, no new features have been added.
Key features of this 2.6.1 release are:
== List of Changes in this Release
For details about the following changes, check our JIRA install at link:https://issues.apache.org/jira/browse/IVY[]
*List of changes since Ivy 2.5.2:*
*List of changes since Ivy 2.6.1:*
- FIX: trying to set safe XML features causes SAXExceptions when used with certain XML parsers (jira:IVY-1647[])
- FIX: some unit tests failed on Java 8 (jira:IVY-1648[]) (Thanks to Adrien Piquerez)
- FIX: cached Ivy files were not valid in some scenarios (jira:IVY-1649[], jira:IVY-1650[]) (Thanks to Moritz Baumann)
- DOCUMENTATION: improved to the documentation regarding the use of patterns in the resolvers and retrieve task (jira:IVY-1651[]) (Thanks to Lewis John McGibbney)
Note, if you have resolved dependencies with version of Ivy prior to 2.6.1, you may need to remove your Ivy cache for some fixes to have any effect.
////
Samples :
@ -68,7 +65,7 @@ Here is the list of people who have contributed source code and documentation up
* Gintautas Grigelionis
* Xavier Hanin
* Nicolas Lalev&eacute;e
* Jan Mat&egrave;rne
* Jan Mat&egrave;rne
* Jaikiran Pai
* Jon Schneider
* Gilles Scokart
@ -96,6 +93,7 @@ Here is the list of people who have contributed source code and documentation up
* Mirko Bulovic
* Ed Burcher
* Jamie Burns
* Colin Chambers
* Wei Chen
* Chris Chilvers
* Kristian Cibulskis
@ -106,6 +104,7 @@ Here is the list of people who have contributed source code and documentation up
* Mykhailo Delegan
* Charles Duffy
* Martin Eigenbrodt
* Arnout Engelen
* Alexandr Esaulov
* Stephen Evanchik
* Stephan Feder
@ -139,6 +138,7 @@ Here is the list of people who have contributed source code and documentation up
* Matthias Kilian
* Alexey Kiselev
* Gregory Kisling
* Mark Kittisopikul
* Stepan Koltsov
* Heschi Kreinick
* Sebastian Krueger
@ -152,20 +152,21 @@ Here is the list of people who have contributed source code and documentation up
* Andrey Lomakin
* William Lyvers
* Sakari Maaranen
* David Maplesden
* Glen Marchesani
* Jan Materne
* Markus M. May
* Lewis John McGibbney
* Phil Messenger
* Steve Miller
* Eric Milles
* Abel Muino
* J. Lewis Muir
* Mathias Muller
* Stephen Nesbitt
* Joshua Nichols
* Bernard Niset
* Ales Nosek
* David Maplesden
* Glen Marchesani
* Phil Messenger
* Steve Miller
* Mathias Muller
* Randy Nott
* Peter Oxenham
* Douglas Palmer

View File

@ -17,7 +17,7 @@
under the License.
////
= Ibiblio resolver
= Maven resolver
[]
|=======
@ -27,9 +27,9 @@
|=======
[ivysettings.resolvers.ibiblio]#This resolver usually uses ibiblio to find artifacts.#
[ivysettings.resolvers.ibiblio]#This resolver usually uses the Maven Central Repository to find artifacts.#
(*__since 1.3__*) Using the `m2compatible` attribute, you can benefit from Maven 2 repository compatibility (convert dots in organisation into slashes, search for POMs, use transitive dependencies of POMs). This setting also affects the default place where the resolver looks for its artifacts to point to the Maven 2 repository. So setting this attribute to `true` is sufficient to use Maven 2 ibiblio repository.
(*__since 1.3__*) Using the `m2compatible` attribute, you can benefit from Maven 2 repository compatibility (convert dots in organisation into slashes, search for POMs, use transitive dependencies of POMs). This setting also affects the default place where the resolver looks for its artifacts to point to the Maven 2 repository. So setting this attribute to `true` is sufficient to use the Maven Central repository.
(*__since 1.4__*) When using the `m2compatible` flag, you can disable the use of POMs by setting the usepoms flag to `false`. It is then roughly equivalent to a URL resolver configured like this:
@ -73,7 +73,7 @@ This resolver shares the link:../settings/resolvers{outfilesuffix}#common[common
----
Defines a resolver called `maven2` using the Maven 2 public repository to find module metadata (using Maven 2 POMs) and artifacts.
Defines a resolver called `maven2` using the Maven Central Repository to find module metadata (using Maven 2 POMs) and artifacts.
'''

View File

@ -42,6 +42,9 @@ Here is a list of built-in conflict managers (which do not require anything in t
* strict +
this conflict manager throws an exception (i.e. causes a build failure) whenever a conflict is found.
* nearest (*__since 2.6.0__*) +
this conflict manager selects the nearest version in the dependency graph, i.e. the one which is closest to the root of the dependency graph. This is compatible with the Maven conflict handling.
The two "latest" conflict managers also take into account the force attribute of the dependencies.
In fact, direct dependencies can declare a force attribute (see link:../ivyfile/dependency{outfilesuffix}[dependency]), which indicates that the revision given in the direct dependency should be preferred over indirect dependencies.

View File

@ -26,8 +26,8 @@ body {
margin: 8px auto;
padding: 0;
width: 98%;
color: #000;
background-color: #fff;
color: black;
background-color: white;
border-radius: 5px;
padding-top: 5px;
padding-bottom: 5px;
@ -37,15 +37,16 @@ body, p, td, li, ul, ol {
font-size: small;
}
h1, h2, h3, h4, h5, h6 {
color: #7a9438;font-family: "Trebuchet MS", Geneva, Arial, Helvetica, SunSans-Regular, Verdana, sans-serif;
color: #7a9438;
font-family: "Trebuchet MS", Geneva, Arial, Helvetica, SunSans-Regular, Verdana, sans-serif;
}
h1 {
color: #7a9438;
background-color: #fff;
background-color: white;
background: none;
}
h2 {
color: #fff;
color: white;
background-color: #7a9438;
padding-left: 10px;
font-size: 1.6em;
@ -85,7 +86,7 @@ blockquote {
font-size: 1.2em;
line-height: 1.3em;
font-family: "Trebuchet MS", Geneva, Arial, Helvetica, SunSans-Regular, Verdana, sans-serif;
color: #696969;
color: dimgray;
}
pre {
padding: 0.75em 1.5em;
@ -94,7 +95,7 @@ pre {
border: 1px solid #ddd;
}
code {
background-color: #EEE;
background-color: #eee;
}
dt {
font-weight: bold;
@ -122,27 +123,27 @@ li p {
#navcontainer {
color: white;
margin-left: 20px;
background-color:#7a9438;
background-color: #7a9438;
}
#navcontainer a {
color: white;
text-decoration: none;
}
#nav {
background-color:#7a9438;
background-color: #7a9438;
}
#nav ul {
background-color:#7a9438;
background-color: #7a9438;
border-top: 1px solid #7a9438;
border-right: 1px solid #7a9438;
border-bottom: 1px solid #7a9438;
border-left: 0.75em solid #7a9438;
}
#nav li a {
color: #fff;
color: white;
}
#nav .title {
color: #fff;
color: white;
background: #7a9438;
border-top: 0;
border-right: 0;
@ -150,7 +151,7 @@ li p {
border-left: 0;
}
#nav li li a {
background: #fff;
background: white;
color: #7a9438;
border-top: 0;
border-right: 0;
@ -161,7 +162,7 @@ li p {
background: #9ebf47;
}
#top-menu {
background-color:#7a9438;
background-color: #7a9438;
border-top: 3px solid #9ebf47;
border-bottom: 3px solid #9ebf47;
}
@ -207,12 +208,12 @@ li p {
font-weight: 700;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
color: #000;
color: black;
background-color: #eee;
font-family: "Trebuchet MS", Geneva, Arial, Helvetica, SunSans-Regular, Verdana, sans-serif;
}
#content {
table-layout:fixed;
table-layout: fixed;
}
.block h2 {
margin: 5px 0px 0px 0px;
@ -220,13 +221,15 @@ li p {
font-size: 1.2em;
font-weight: 700;
border-top-left-radius: 5px;
border-top-right-radius: 5px;color: #000;
border-top-right-radius: 5px;
color: black;
background-color: #eee;
}
.block .content {
border-bottom-right-radius: 5px;
border-bottom-left-radius: 5px;
margin-bottom: 10px;background-color: #fff;
margin-bottom: 10px;
background-color: white;
border: 1px solid #eee;
}
#main {
@ -254,20 +257,20 @@ table.tableblock {
margin-bottom: 10px;
}
table.tableblock thead {
background-color: #DEE4CD;
border: 1px solid #7A9437;
background-color: #dee4cd;
border: 1px solid #7a9437;
}
table.tableblock th {
font-family: monospace;
border: 1px solid #7A9437;
border: 1px solid #7a9437;
padding: 5px;
}
table.tableblock tbody {
background-color: #FFFFFF;
border: 1px solid #7A9437;
background-color: white;
border: 1px solid #7a9437;
}
table.tableblock td {
border: 1px dotted #7A9437;
border: 1px dotted #7a9437;
padding: 5px;
}
table.tableblock td p:last-child {
@ -281,27 +284,27 @@ table.tableblock .valign-middle {
}
.note {
padding: 15px;
border-style:solid;
border-width:1px;
border-color: #F0D88D;
background-color: #FCFCCA;
border-style: solid;
border-width: 1px;
border-color: #f0d88d;
background-color: #fcfcca;
margin: 10px;
}
.note .title {
display:none;
display: none;
}
.warning:before {
content: url(../images/warning.svg)
}
.warning {
border-style:solid;
border-width:1px;
border-color: #F0D88D;
background-color: #FCFCCA;
border-style: solid;
border-width: 1px;
border-color: #f0d88d;
background-color: #fcfcca;
margin: 10px;
}
.warning .title {
display:none;
display: none;
}
#treemenu {
padding-left: 10px;
@ -316,6 +319,11 @@ table.tableblock .valign-middle {
padding-left: 22px;
margin-bottom: 3px;
}
.treeview a.active-menu-item {
background-color: #eef4e0;
border-left: 3px solid #7a9438;
padding-left: 4px;
}
.treeview li.submenu {
background: white url(../images/closed.gif) no-repeat left 1px;
}
@ -342,5 +350,5 @@ table.tableblock .valign-middle {
color: #7a9438;
}
#book {
background-color: #FFFFFF;
background-color: white;
}

View File

@ -32,7 +32,7 @@ html lang=(attr :lang, 'en' unless attr? :nolang)
tr
td id="home" width="30%"
a href="http://ant.apache.org/" title="Apache Ant"
img src="./images/ant-project-logo.svg" alt="Apache Ant" border="0" height="80px"/
img src="./images/group-logo.png" alt="Apache Ant" border="0" height="65px"/
td class="product" width="70%" align="right" valign="middle"
img src="./images/logo.png" alt="ivy" border="0"/
div id="title"

View File

@ -25,18 +25,22 @@ html lang=(attr :lang, 'en' unless attr? :nolang)
link rel="stylesheet" type="text/css" href="#{page.relativeRoot}style/style.css"
script src="#{page.relativeRoot}js/jquery.pack.js" type="text/javascript"
script src="#{page.relativeRoot}js/jquery.treeview.js" type="text/javascript"
script src="#{page.relativeRoot}js/menu.js" type="text/javascript"
link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/default.min.css"
script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js" type="text/javascript"
javascript:
$(document).ready(function(){$("#treemenu").Treeview({speed: "fast",store: true});});
$(document).ready(function() {
$("#treemenu").Treeview({speed: "fast",store: true});
highlightActiveMenuItem();
});
hljs.initHighlightingOnLoad();
body
body data-page-id="#{page.id}"
div id="body"
table id="header" summary="Navigation elements." border="0" cellpadding="0" cellspacing="0" width="100%"
tr
td id="home" width="30%"
a href="http://ant.apache.org/" title="Apache Ant"
img src="#{page.relativeRoot}images/ant-project-logo.svg" alt="Apache Ant" border="0" height="80px"/
img src="#{page.relativeRoot}images/group-logo.png" alt="Apache Ant" border="0" height="65px"/
td class="product" width="70%" align="right" valign="middle"
img src="#{page.relativeRoot}images/logo.png" alt="ivy" border="0"/
table id="top-menu" summary="Navigation elements." border="0" cellpadding="0" cellspacing="0" width="100%"

View File

@ -27,7 +27,7 @@ This task generates a resolved descriptor of the current module, based upon the
Moreover, all included configurations' files are included in the Ivy file, and variables are replaced by their values.
Finally, in the resolved Ivy file, dynamic revisions are replaced by the static ones that have been found during the resolve step, so the Ivy file can be used later safely to obtain the same dependencies (providing that a revision uniquely identifies a module, which should be the case for proper Ivy use).
Finally, in the resolved Ivy file, dynamic revisions are replaced by the static ones that have been found during the resolve step, so the Ivy file can be used later safely to obtain the same dependencies (providing that a revision uniquely identifies a module, which should be the case for proper Ivy use). Note that this replacement is done before any conflict resolution happens. This can cause differences between the selected versions in the delivered ivy.xml file and the ones that are actually retrieved. This should not be a problem, because if the delivered ivy.xml is used to resolve the dependencies again, the conflict resolution will select the correct versions, even if not all configurations are resolved. This way, we ensure a reproducible dependency resolution as much as possible.
(*__since 1.3__*) The replacement of dynamic revisions by static ones can be turned off, so that dynamic revisions are kept in the Ivy file. This is an exception to the recommended standard that published module descriptors be fully resolved, so use it with caution.

View File

@ -83,7 +83,8 @@ There is one important difference with the ivy.xml's link:../ivyfile/dependencie
|Element|Description|Cardinality
|link:../ivyfile/dependency{outfilesuffix}[dependency]|declares a dependency to resolve|0..n
|link:../ivyfile/exclude{outfilesuffix}[exclude]|excludes artifacts, modules or whole organizations from the set of dependencies to resolve|0..n
|link:../ivyfile/override{outfilesuffix}[override]|specify an override mediation rule, overriding the revision and/or branch requested for a transitive dependency (*__since 2.0__*)|0..n
|link:../ivyfile/override{outfilesuffix}[override]|specify an override mediation rule, overriding the revision and/or branch requested for a transitive dependency (*__since 2.6__*)|0..n
|link:../ivyfile/conflict{outfilesuffix}[conflict]|specify a a conflict manager for one or several dependencies|0..n
|=======
== Examples

View File

@ -78,7 +78,7 @@ This table gives some statistics about the dependency resolution. Each line corr
[*__since 1.4__*]
The inline mode allows to call a resolve without an Ivy file, by setting directly the module which should be resolved from the repository. It is particularly useful to install released software, like an Ant task for example. When `inline` is set to `true`, the organisation module and revision attributes are used to specify which module should be resolved from the repository.
The inline mode allows to call a resolve without an Ivy file, by setting directly the module which should be resolved from the repository. It is particularly useful to install released software, like an Ant task for example. When `inline` is set to `true`, the organisation module and revision attributes are used to specify which module should be resolved from the repository.
*Remark:* if you want the standard Ivy properties to be set or to reuse the results of an inline resolve by other post-resolve tasks like `retrieve`, `cachepath`, `report`..., you must set the keep attribute to `true`!
@ -148,7 +148,8 @@ There is one important difference with the ivy.xml's link:../ivyfile/dependencie
|Element|Description|Cardinality
|link:../ivyfile/dependency{outfilesuffix}[dependency]|declares a dependency to resolve|0..n
|link:../ivyfile/exclude{outfilesuffix}[exclude]|excludes artifacts, modules or whole organizations from the set of dependencies to resolve|0..n
|link:../ivyfile/override{outfilesuffix}[override]|specify an override mediation rule, overriding the revision and/or branch requested for a transitive dependency (*__since 2.0__*)|0..n
|link:../ivyfile/override{outfilesuffix}[override]|specify an override mediation rule, overriding the revision and/or branch requested for a transitive dependency (*__since 2.6__*)|0..n
|link:../ivyfile/conflict{outfilesuffix}[conflict]|specify a a conflict manager for one or several dependencies|0..n
|=======
== Examples

View File

@ -288,15 +288,15 @@
</exec>
<mkdir dir="${distrib.dir}/dist/${build.version}"/>
<zip destfile="${distrib.dir}/dist/${build.version}/${snapshot.full.name}-src.zip" defaultexcludes="no">
<zipfileset dir="${build.dir}/snapshot-src" prefix="${snapshot.full.name}" defaultexcludes="no" excludes=".git/**"/>
<zipfileset dir="${build.dir}/snapshot-src" prefix="${snapshot.full.name}" defaultexcludes="no" excludes=".git/**" id="dist.sources"/>
</zip>
<tar destfile="${distrib.dir}/dist/${build.version}/${snapshot.full.name}-src.tar.gz"
compression="gzip" longfile="gnu" defaultexcludes="no">
<zipfileset dir="${build.dir}/snapshot-src" prefix="${snapshot.full.name}" defaultexcludes="no" excludes=".git/**"/>
<zipfileset refid="dist.sources"/>
</tar>
</target>
<target name="snapshot-bin-without-dependencies" depends="snapshot-metadata,jar,all-doc">
<target name="snapshot-bin-without-dependencies" depends="snapshot-metadata,jar,jar-sbom,all-doc">
<mkdir dir="${distrib.dir}/dist/${build.version}"/>
<zip destfile="${distrib.dir}/dist/${build.version}/${snapshot.full.name}-bin.zip">
<zipfileset dir="${doc.build.dir}" prefix="${snapshot.full.name}/doc" excludes="**/reports/coverage/**,**/reports/test/**"/>
@ -311,6 +311,7 @@
<zipfileset dir="${basedir}" includes="build-for-bin-distrib.xml" fullpath="${snapshot.full.name}/build.xml"/>
<zipfileset dir="${artifacts.build.dir}/jars" includes="${final.name}" fullpath="${snapshot.full.name}/ivy-${build.version}.jar"/>
<zipfileset dir="${artifacts.build.dir}/jars" includes="ivy-${build.version}.cdx.*" prefix="${snapshot.full.name}"/>
</zip>
<tar destfile="${distrib.dir}/dist/${build.version}/${snapshot.full.name}-bin.tar.gz"
compression="gzip" longfile="gnu">
@ -318,7 +319,7 @@
</tar>
</target>
<target name="snapshot-bin-with-dependencies" depends="snapshot-metadata,jar,all-doc">
<target name="snapshot-bin-with-dependencies" depends="snapshot-metadata,jar,jar-sbom,all-doc">
<mkdir dir="${distrib.dir}/dist/${build.version}"/>
<delete dir="${build.dir}/lib"/>
<ivy:retrieve conf="default" pattern="${build.dir}/lib/[artifact]-[revision].[ext]"/>
@ -334,6 +335,7 @@
<zipfileset dir="${artifacts.build.dir}" includes="ivy.xml" fullpath="${snapshot.full.name}/ivy.xml"/>
<zipfileset dir="${artifacts.build.dir}/jars" includes="${final.name}" fullpath="${snapshot.full.name}/ivy-${build.version}.jar"/>
<zipfileset dir="${artifacts.build.dir}/jars" includes="ivy-${build.version}.cdx.*" prefix="${snapshot.full.name}"/>
<zipfileset dir="${build.dir}/lib" prefix="${snapshot.full.name}/lib" excludes="ant-*.jar,bcpg-*.jar,bcprov*.jar"/>
</zip>
@ -361,6 +363,10 @@
</ivy:makepom>
<copy file="${artifacts.build.dir}/jars/${final.name}"
tofile="${m2.distrib.dir}/ivy-${build.version}.jar"/>
<!-- SBOMs -->
<copy todir="${m2.distrib.dir}">
<fileset dir="${artifacts.build.dir}/jars" includes="ivy-${build.version}.cdx.*"/>
</copy>
<!-- jar javadocs -->
<jar destfile="${m2.distrib.dir}/ivy-${build.version}-javadoc.jar">
<fileset dir="${javadoc.build.dir}"/>
@ -373,12 +379,16 @@
<fileset dir="${m2.distrib.dir}">
<include name="*.pom"/>
<include name="*.jar"/>
<include name="*.cdx.json"/>
<include name="*.cdx.xml"/>
</fileset>
</checksum>
<checksum algorithm="sha-512" fileext=".sha512">
<fileset dir="${m2.distrib.dir}">
<include name="*.pom"/>
<include name="*.jar"/>
<include name="*.cdx.json"/>
<include name="*.cdx.xml"/>
</fileset>
</checksum>
</target>
@ -390,6 +400,8 @@
<include name="*.jar"/>
<include name="*.zip"/>
<include name="*.gz"/>
<include name="*.cdx.json"/>
<include name="*.cdx.xml"/>
</fileset>
</checksum>
<checksum algorithm="sha-512" fileext=".sha512">
@ -398,6 +410,8 @@
<include name="*.jar"/>
<include name="*.zip"/>
<include name="*.gz"/>
<include name="*.cdx.json"/>
<include name="*.cdx.xml"/>
</fileset>
</checksum>
</target>
@ -471,6 +485,8 @@
asciiarmor="true">
<fileset dir="${distrib.dir}">
<include name="**/*.pom"/>
<include name="**/*.cdx.json"/>
<include name="**/*.cdx.xml"/>
<include name="**/*.jar"/>
<include name="**/*.zip"/>
<include name="**/*.gz"/>
@ -480,7 +496,7 @@
<target name="rat" depends="init-ivy">
<property name="rat.failOnError" value="true"/>
<ivy:cachepath organisation="org.apache.rat" module="apache-rat-tasks" revision="0.15"
<ivy:cachepath organisation="org.apache.rat" module="apache-rat-tasks" revision="0.16.1"
inline="true" conf="default" pathid="rat.classpath"
log="download-only"/>
@ -492,6 +508,7 @@
<mkdir dir="${rat.report.dir}"/>
<rat:report xmlns:rat="antlib:org.apache.rat.anttasks" reportFile="${rat.report.dir}/rat-report.txt">
<fileset dir="${basedir}">
<exclude name=".asf.yaml"/>
<exclude name=".classpath"/>
<exclude name="*.iml"/>
<exclude name="ReleaseInstructions"/>
@ -555,6 +572,8 @@
<artifact name="ivy" ext="pom" type="ivy"/>
<artifact name="ivy" ext="jar" type="sources" classifier="sources"/>
<artifact name="ivy" ext="jar" type="javadoc" classifier="javadoc"/>
<artifact name="ivy" ext="cdx.json" type="cyclonedx"/>
<artifact name="ivy" ext="cdx.xml" type="cyclonedx"/>
</ivy2:publish>
</target>
@ -562,7 +581,7 @@
depends="/localivy,clean-ivy-home,clean,clean-lib,snapshot-version,install,clean-examples,test-report"/>
<target name="snapshot"
depends="prepare-snapshot,snapshot-src,snapshot-bin,snapshot-maven2,snapshot-checksums"
depends="prepare-snapshot,snapshot-src,snapshot-bin,snapshot-maven2,sboms,snapshot-checksums"
description="used for nightly and integration builds"/>
<target name="release"
@ -636,4 +655,390 @@
</generate-tagsdoc>
</target>
<target name="define-cyclonedx-components" if="jdk9+">
<ivy:cachepath organisation="org.apache.ant"
module="ant-cyclonedx"
revision="${ant-cyclonedx.version}"
inline="true" conf="default"
pathid="cyclonedx.classpath"
log="download-only"/>
<typedef uri="antlib:org.apache.ant.cyclonedx"
resource="org/apache/ant/cyclonedx/antlib.xml"
classpathref="cyclonedx.classpath"/>
<!-- common definitions for SBOMs -->
<cdx:organization
name="Apache Ant Project Management Committee"
id="ant-pmc"
xmlns:cdx="antlib:org.apache.ant.cyclonedx">
<url url="https://ant.apache.org/"/>
</cdx:organization>
<cdx:license
licenseId="Apache-2.0"
id="apache-2"
xmlns:cdx="antlib:org.apache.ant.cyclonedx">
<url url="https://www.apache.org/licenses/LICENSE-2.0.txt"/>
</cdx:license>
<cdx:externalreferenceset
id="ant-common-refs"
xmlns:cdx="antlib:org.apache.ant.cyclonedx">
<externalReference
type="LICENSE"
url="https://www.apache.org/licenses/LICENSE-2.0.txt"/>
<externalReference
type="SECURITY_CONTACT"
url="https://www.apache.org/security/"/>
</cdx:externalreferenceset>
<cdx:externalreferenceset
id="ivy-ext-refs"
xmlns:cdx="antlib:org.apache.ant.cyclonedx">
<externalReference
type="MAILING_LIST"
url="https://ant.apache.org/ivy/mailing-lists.html"/>
<externalReference
type="VCS"
url="https://gitbox.apache.org/repos/asf/ant-ivy.git"/>
<externalReference
type="ISSUE_TRACKER"
url="http://issues.apache.org/jira/browse/IVY"/>
<externalReference
type="WEBSITE"
url="https://ant.apache.org/ivy/"/>
<externalReference
type="DISTRIBUTION"
url="https://ant.apache.org/ivy/download.cgi"/>
<externalReference
type="SOURCE_DISTRIBUTION"
url="https://ant.apache.org/ivy/download.cgi"/>
<externalReference
type="ADVISORIES"
url="https://ant.apache.org/ivy/security.html"/>
</cdx:externalreferenceset>
<cdx:externalreferenceset
id="ant-ext-refs"
xmlns:cdx="antlib:org.apache.ant.cyclonedx">
<externalReference
type="MAILING_LIST"
url="https://ant.apache.org/mail.html"/>
<externalReference
type="VCS"
url="https://gitbox.apache.org/repos/asf/ant.git"/>
<externalReference
type="ISSUE_TRACKER"
url="https://bz.apache.org/bugzilla/buglist.cgi?product=Ant"/>
<externalReference
type="WEBSITE"
url="https://ant.apache.org/"/>
<externalReference
type="DISTRIBUTION"
url="https://ant.apache.org/bindownload.cgi"/>
<externalReference
type="SOURCE_DISTRIBUTION"
url="https://ant.apache.org/srcdownload.cgi"/>
<externalReference
type="ADVISORIES"
url="https://ant.apache.org/security.html#Apache%20Ant%20Security%20Vulnerabilities"/>
<externalReference
type="DOCUMENTATION"
url="https://ant.apache.org/manual/"/>
</cdx:externalreferenceset>
</target>
<target name="jar-sbom" depends="define-cyclonedx-components,jar" if="jdk9+">
<cdx:componentbom
bomName="ivy-${build.version}.cdx"
outputdirectory="${artifacts.build.dir}/jars"
format="all"
useComponentSupplier="true"
useComponentManufacturer="true"
xmlns:cdx="antlib:org.apache.ant.cyclonedx">
<component
name="ivy"
group="org.apache.ivy"
version="${build.version}"
description="Apache Ivy"
publisher="The Apache Software Foundation"
supplierIsManufacturer="true">
<file file="${artifacts.build.dir}/jars/${final.name}"/>
<supplier refid="ant-pmc"/>
<license refid="apache-2"/>
<externalReferenceSet refid="ant-common-refs"/>
<externalReferenceSet refid="ivy-ext-refs"/>
<dependency componentRef="cdx-ant"/>
<dependency componentRef="cdx-httpclient"/>
<dependency componentRef="cdx-commons-compress"/>
<dependency componentRef="cdx-commons-vfs2"/>
<dependency componentRef="cdx-apache-oro"/>
<dependency componentRef="cdx-jsch"/>
<dependency componentRef="cdx-jsch.agentproxy"/>
<dependency componentRef="cdx-jsch.agentproxy.connector-factory"/>
<dependency componentRef="cdx-jsch.agentproxy.jsch"/>
<dependency componentRef="cdx-bcpg-jdk15on"/>
<dependency componentRef="cdx-bcprov-jdk15on"/>
<dependency componentRef="cdx-commons-codec"/>
</component>
<license refid="apache-2"/>
<additionalComponent
name="ant"
group="org.apache.ant"
version="${apache-ant.version}"
isExternal="true"
id="cdx-ant">
<supplier refid="ant-pmc"/>
<license refid="apache-2"/>
<externalReferenceSet refid="ant-common-refs"/>
<externalReferenceSet refid="ant-ext-refs"/>
<dependency componentRef="cdx-ant-launcher"/>
</additionalComponent>
<additionalComponent
name="ant-launcher"
group="org.apache.ant"
version="${apache-ant.version}"
isExternal="true"
id="cdx-ant-launcher">
<supplier refid="ant-pmc"/>
<license refid="apache-2"/>
<externalReferenceSet refid="ant-common-refs"/>
<externalReferenceSet refid="ant-ext-refs"/>
</additionalComponent>
<additionalComponent
id="cdx-httpclient"
name="httpclient"
group="org.apache.httpcomponents"
version="${httpclient.version}"
xmlns:cdx="antlib:org.apache.ant.cyclonedx">
<license refid="apache-2"/>
<dependency componentRef="cdx-commons-codec"/>
<dependency componentRef="cdx-commons-logging"/>
</additionalComponent>
<additionalComponent
id="cdx-commons-logging"
name="commons-logging"
group="org.apache.commons"
version="1.2"
unknownDependencies="true"
xmlns:cdx="antlib:org.apache.ant.cyclonedx">
<license refid="apache-2"/>
</additionalComponent>
<additionalComponent
id="cdx-commons-compress"
name="commons-compress"
group="org.apache.commons"
version="${commons-compress.version}"
unknownDependencies="true"
xmlns:cdx="antlib:org.apache.ant.cyclonedx">
<license refid="apache-2"/>
</additionalComponent>
<additionalComponent
id="cdx-commons-vfs2"
name="commons-vfs2"
group="org.apache.commons"
version="${commons-vfs2.version}"
unknownDependencies="true"
xmlns:cdx="antlib:org.apache.ant.cyclonedx">
<license refid="apache-2"/>
</additionalComponent>
<additionalComponent
id="cdx-apache-oro"
name="oro"
group="oro"
version="${oro.version}"
unknownDependencies="true"
xmlns:cdx="antlib:org.apache.ant.cyclonedx">
<license refid="apache-2"/>
</additionalComponent>
<additionalComponent
id="cdx-jsch"
name="jsch"
group="com.jcraft"
description="JSch is a pure Java implementation of SSH2"
version="${jsch.version}"
xmlns:cdx="antlib:org.apache.ant.cyclonedx">
<externalReference
type="WEBSITE"
url="http://www.jcraft.com/"/>
<license name="Revised BSD">
<url url="http://www.jcraft.com/jsch/LICENSE.txt"/>
</license>
</additionalComponent>
<additionalComponent
id="cdx-jsch.agentproxy"
name="jsch.agentproxy"
group="com.jcraft"
description="a proxy to ssh-agent and Pageant in Java "
version="${jsch.agentproxy.version}"
xmlns:cdx="antlib:org.apache.ant.cyclonedx">
<externalReference
type="WEBSITE"
url="http://www.jcraft.com/"/>
<license name="Revised BSD">
<url url="http://www.jcraft.com/jsch/LICENSE.txt"/>
</license>
</additionalComponent>
<additionalComponent
id="cdx-jsch.agentproxy.connector-factory"
name="jsch.agentproxy.connector-factory"
group="com.jcraft"
description="a connector factory"
version="${jsch.agentproxy.version}"
unknownDependencies="true"
xmlns:cdx="antlib:org.apache.ant.cyclonedx">
<externalReference
type="WEBSITE"
url="http://www.jcraft.com/"/>
<license name="Revised BSD">
<url url="http://www.jcraft.com/jsch/LICENSE.txt"/>
</license>
</additionalComponent>
<additionalComponent
id="cdx-jsch.agentproxy.jsch"
name="jsch.agentproxy.jsch"
group="com.jcraft"
description="a library to use jsch-agent-proxy with JSch"
version="${jsch.agentproxy.version}"
unknownDependencies="true"
xmlns:cdx="antlib:org.apache.ant.cyclonedx">
<externalReference
type="WEBSITE"
url="http://www.jcraft.com/"/>
<license name="Revised BSD">
<url url="http://www.jcraft.com/jsch/LICENSE.txt"/>
</license>
</additionalComponent>
<additionalComponent
id="cdx-commons-codec"
name="commons-codec"
group="org.apache.commons"
version="${commons-codec.version}"
xmlns:cdx="antlib:org.apache.ant.cyclonedx">
<license refid="apache-2"/>
</additionalComponent>
<additionalComponent
id="cdx-bcpg-jdk15on"
name="bcpg-jdk15on"
group="org.bouncycastle"
version="${bouncycastle.version}"
xmlns:cdx="antlib:org.apache.ant.cyclonedx">
<license name="Bouncy Castle Licence">
<url url="https://www.bouncycastle.org/licence.html"/>
</license>
<dependency componentRef="cdx-bcprov-jdk15on"/>
</additionalComponent>
<additionalComponent
id="cdx-bcprov-jdk15on"
name="bcprov-jdk15on"
group="org.bouncycastle"
version="${bouncycastle.version}"
xmlns:cdx="antlib:org.apache.ant.cyclonedx">
<license name="Bouncy Castle Licence">
<url url="https://www.bouncycastle.org/licence.html"/>
</license>
</additionalComponent>
</cdx:componentbom>
</target>
<target name="prepare-distribution-sboms"
depends="define-cyclonedx-components"
if="jdk9+">
<macrodef name="create-tarball-bom">
<attribute name="binsrc"/>
<attribute name="binarysource"/>
<attribute name="ext"/>
<element name="archiveContent"/>
<element name="moreComponentChildren" optional="true"/>
<sequential
xmlns:cdx="antlib:org.apache.ant.cyclonedx">
<cdx:componentbom
bomName="${snapshot.full.name}-@{binsrc}.@{ext}.cdx"
outputdirectory="${distrib.dir}/dist/${build.version}"
format="all"
useComponentManufacturer="true"
useComponentSupplier="true">
<component
version="${build.version}"
purl="https://archive.apache.org/dist/ant/ivy/${build.version}/${snapshot.full.name}-@{binsrc}.@{ext}"
name="https://archive.apache.org/dist/ant/ivy/${build.version}/${snapshot.full.name}-@{binsrc}.@{ext}"
description="Apache Ivy @{binarysource}"
publisher="The Apache Software Foundation"
type="file"
supplierIsManufacturer="true">
<file file="${distrib.dir}/dist/${build.version}/${snapshot.full.name}-@{binsrc}.@{ext}"/>
<supplier refid="ant-pmc"/>
<license refid="apache-2"/>
<externalReferenceSet refid="ant-common-refs"/>
<externalReferenceSet refid="ivy-ext-refs"/>
<moreComponentChildren/>
</component>
<pureFileComponents>
<archiveContent/>
</pureFileComponents>
<license refid="apache-2"/>
</cdx:componentbom>
</sequential>
</macrodef>
<macrodef name="create-tarball-boms">
<attribute name="binsrc"/>
<attribute name="binarysource"/>
<element name="componentChildren" implicit="true" optional="true"/>
<sequential>
<mkdir dir="${build.dir}/sbom/@{binsrc}"/>
<unzip dest="${build.dir}/sbom/@{binsrc}"
src="${distrib.dir}/dist/${build.version}/${snapshot.full.name}-@{binsrc}.zip"/>
<create-tarball-bom
binsrc="@{binsrc}"
binarysource="@{binarysource}"
ext="tar.gz">
<moreComponentChildren>
<componentChildren/>
</moreComponentChildren>
<archiveContent>
<fileset dir="${build.dir}/sbom/@{binsrc}" defaultexcludes="no"/>
</archiveContent>
</create-tarball-bom>
<create-tarball-bom
binsrc="@{binsrc}"
binarysource="@{binarysource}"
ext="zip">
<moreComponentChildren>
<componentChildren/>
</moreComponentChildren>
<archiveContent>
<fileset dir="${build.dir}/sbom/@{binsrc}" defaultexcludes="no"/>
</archiveContent>
</create-tarball-bom>
<delete dir="${build.dir}/sbom/@{binsrc}"/>
</sequential>
</macrodef>
</target>
<target name="src-tarball-sboms"
depends="snapshot-src,prepare-distribution-sboms"
if="jdk9+">
<create-tarball-boms binsrc="src" binarysource="Source Distribution"/>
</target>
<target name="bin-tarball-sboms"
depends="snapshot-bin,prepare-distribution-sboms"
if="jdk9+">
<create-tarball-boms binsrc="bin"
binarysource="Binary Distribution">
<component>
<sbomLink>
<file file="${artifacts.build.dir}/jars/ivy-${build.version}.cdx.json"/>
</sbomLink>
<file file="${artifacts.build.dir}/jars/${final.name}"/>
</component>
</create-tarball-boms>
<create-tarball-boms binsrc="bin-with-deps"
binarysource="Binary Distribution with Dependencies">
<component>
<sbomLink>
<file file="${artifacts.build.dir}/jars/ivy-${build.version}.cdx.json"/>
</sbomLink>
<file file="${artifacts.build.dir}/jars/${final.name}"/>
</component>
</create-tarball-boms>
</target>
<target name="sboms" depends="src-tarball-sboms,bin-tarball-sboms"/>
</project>

View File

@ -24,6 +24,10 @@
<property name="final.name" value="ivy.jar"/>
<condition property="jdk9+">
<javaversion atleast="9"/>
</condition>
<target name="init-ivy-user-home" unless="ivy.use.local.home">
<condition property="ivy.home" value="${env.IVY_HOME}">
<isset property="env.IVY_HOME"/>
@ -597,7 +601,7 @@
</target>
<target name="init-checkstyle" depends="jar">
<ivy:cachepath organisation="com.puppycrawl.tools" module="checkstyle" revision="6.19"
<ivy:cachepath organisation="com.puppycrawl.tools" module="checkstyle" revision="8.45.1"
inline="true" conf="default" pathid="checkstyle.classpath" log="download-only"/>
<taskdef uri="antlib:com.puppycrawl.tools.checkstyle.ant"
resource="com/puppycrawl/tools/checkstyle/ant/antlib.xml" classpathref="checkstyle.classpath"/>

View File

@ -34,6 +34,13 @@
<download-page rdf:resource="http://ant.apache.org/ivy/download.cgi" />
<programming-language>Java</programming-language>
<category rdf:resource="http://projects.apache.org/category/build-management" />
<release>
<Version>
<name>Apache Ivy 2.6.0</name>
<created>2026-07-15</created>
<revision>2.6.0</revision>
</Version>
</release>
<release>
<Version>
<name>Apache Ivy 2.5.3</name>

19
ivy.xml
View File

@ -21,7 +21,7 @@
xsi:noNamespaceSchemaLocation="http://ant.apache.org/ivy/schemas/ivy.xsd">
<info organisation="org.apache.ivy"
module="ivy"
status="release">
status="integration">
<description homepage="http://ant.apache.org/ivy/">
Apache Ivy is a tool for managing (recording, tracking, resolving and reporting) project dependencies.
</description>
@ -32,6 +32,7 @@
<conf name="oro" extends="core" description="to use optional glob matcher"/>
<conf name="vfs" extends="core" description="core + optional VirtualFileSystem(VFS) support" />
<conf name="sftp" extends="core" description="core + optional SFTP support" />
<conf name="pack200" extends="core" description="core + optional pack200 support" />
<conf name="standalone" extends="core" description="to launch in standalone mode (from command line)"/>
<conf name="ant" extends="core" description="core + ant jar provided as a dependency"/>
<conf name="default" extends="core" description="full ivy with all dependencies"/>
@ -46,8 +47,15 @@
<dependencies>
<dependency org="org.apache.ant" name="ant" rev="${apache-ant.version}" conf="default,ant"/>
<dependency org="org.apache.httpcomponents" name="httpclient" rev="${httpclient.version}" conf="default,httpclient->runtime,master"/>
<dependency org="oro" name="oro" rev="${oro.version}" conf="default,oro"/>
<dependency org="org.apache.commons" name="commons-compress"
rev="${commons-compress.version}"
conf="default,pack200->default,optional">
<exclude org="com.github.luben"/>
<exclude org="org.brotli"/>
<exclude org="org.tukaani"/>
</dependency>
<dependency org="org.apache.commons" name="commons-vfs2" rev="${commons-vfs2.version}" conf="default,vfs"/>
<dependency org="oro" name="oro" rev="${oro.version}" conf="default,oro"/>
<dependency org="com.jcraft" name="jsch" rev="${jsch.version}" conf="default,sftp"/>
<dependency org="com.jcraft" name="jsch.agentproxy" rev="${jsch.agentproxy.version}" conf="default,sftp"/>
<dependency org="com.jcraft" name="jsch.agentproxy.connector-factory" rev="${jsch.agentproxy.version}" conf="default,sftp"/>
@ -55,6 +63,9 @@
<dependency org="org.bouncycastle" name="bcpg-jdk15on" rev="${bouncycastle.version}" conf="default"/>
<dependency org="org.bouncycastle" name="bcprov-jdk15on" rev="${bouncycastle.version}" conf="default"/>
<!-- we manually specify a dependency on commons-codec so that both the httpclient and the pack200 configs resolve to the same version -->
<dependency org="commons-codec" name="commons-codec" rev="${commons-codec.version}" conf="default,httpclient,pack200"/>
<!-- Test dependencies -->
<dependency org="junit" name="junit" rev="${junit.version}" conf="test"/>
<dependency org="org.hamcrest" name="hamcrest-core" rev="${hamcrest.version}" conf="test"/>
@ -67,8 +78,8 @@
<dependency org="xmlunit" name="xmlunit" rev="${xmlunit.version}" conf="test" transitive="false"/>
<!-- Global excludes -->
<exclude org="junit" module="junit" conf="core,default,httpclient,oro,vfs,sftp,standalone,ant"/>
<exclude org="org.hamcrest" module="hamcrest-core" conf="core,default,httpclient,oro,vfs,sftp,standalone,ant"/>
<exclude org="junit" module="junit" conf="core,default,httpclient,oro,vfs,sftp,pack200,standalone,ant"/>
<exclude org="org.hamcrest" module="hamcrest-core" conf="core,default,httpclient,oro,vfs,sftp,standalone,pack200,ant"/>
<!-- Exclude the whole outdated commons-httpclient org -->
<exclude org="commons-httpclient" conf="*"/>
</dependencies>

View File

@ -20,6 +20,7 @@
#This file defines the sources to compile for ivy-optional.jar
org/apache/ivy/Main.java
org/apache/ivy/plugins/matcher/GlobPatternMatcher.java
org/apache/ivy/plugins/pack/Pack200*.java
org/apache/ivy/plugins/repository/sftp/**/*.java
org/apache/ivy/plugins/repository/ssh/**/*.java
org/apache/ivy/plugins/repository/vfs/**/*.java

View File

@ -34,6 +34,7 @@
<module name="JavadocType">
<property name="scope" value="protected"/>
</module>
<!--
<module name="JavadocMethod">
<property name="scope" value="protected"/>
<property name="allowUndeclaredRTE" value="true"/>
@ -41,6 +42,7 @@
<module name="JavadocVariable">
<property name="scope" value="public"/>
</module>
-->
<!-- element naming -->
<module name="PackageName"/>
@ -60,11 +62,13 @@
<module name="UnusedImports"/>
<!-- size limits -->
<!--
<module name="LineLength">
<property name="max" value="100"/>
<property name="ignorePattern" value="^ *\* *[^ ]+$"/>
<property name="tabWidth" value="4"/>
</module>
-->
<module name="MethodLength"/>
<module name="ParameterNumber"/>
@ -106,6 +110,9 @@
<property name="allowUnchecked" value="true"/>
</module>
-->
<module name="OneStatementPerLine">
<property name="treatTryResourcesAsStatement" value="true"/>
</module>
<module name="SimplifyBooleanExpression"/>
<module name="SimplifyBooleanReturn"/>
@ -120,9 +127,8 @@
<module name="ArrayTypeStyle"/>
<!-- <module name="TodoComment"/> -->
<module name="UpperEll"/>
<!-- allow comment suppression of checks -->
<module name="FileContentsHolder"/>
<!--
<module name="FileContentsHolder"/>
<module name="GenericIllegalRegexp">
<property name="format" value="\s+$"/>
<property name="message" value="Line has trailing spaces."/>
@ -135,12 +141,13 @@
<property name="format" value="\s+$"/>
</module>
<!-- <module name="au.com.redhillconsulting.simian.SimianCheck"/> -->
<!--
<module name="SuppressionCommentFilter">
<property name="offCommentFormat" value="CheckStyle\:([\w\|]+) *OFF"/>
<property name="onCommentFormat" value="CheckStyle\:([\w\|]+) *ON"/>
<property name="checkFormat" value="$1"/>
</module>
-->
<module name="SuppressionFilter">
<property name="file" value="${checkstyle.src.dir}/checkstyle-suppress.xml"/>

View File

@ -21,5 +21,5 @@
under the License.
-->
<suppressions>
<suppress checks="MagicNumber" files=".*[\\/]test[\\/]java[\\/].*"/>
<suppress checks="MagicNumber" files="[\\/]test[\\/]java[\\/]|PomModuleDescriptorWriter\.java$"/>
</suppressions>

View File

@ -32,9 +32,9 @@
<name>Apache Ivy</name>
<url>${ivy.pom.url}</url>
<scm>
<connection>scm:svn:https://svn.apache.org/repos/asf/ant/ivy/core/trunk/</connection>
<developerConnection>scm:svn:https://svn.apache.org/repos/asf/ant/ivy/core/trunk</developerConnection>
<url>https://svn.apache.org/repos/asf/ant/ivy/core/trunk</url>
<connection>scm:git:https://gitbox.apache.org/repos/asf/ant-ivy.git</connection>
<developerConnection>scm:git:https://gitbox.apache.org/repos/asf/ant-ivy.git</developerConnection>
<url>https://gitbox.apache.org/repos/asf?p=ant-ivy.git</url>
</scm>
<mailingLists>
<mailingList>
@ -42,14 +42,14 @@
<subscribe>dev-subscribe@ant.apache.org</subscribe>
<unsubscribe>dev-unsubscribe@ant.apache.org</unsubscribe>
<post>dev@ant.apache.org</post>
<archive>https://mail-archives.apache.org/mod_mbox/ant-dev</archive>
<archive>https://lists.apache.org/list.html?dev@ant.apache.org</archive>
</mailingList>
<mailingList>
<name>Ivy Users List</name>
<subscribe>ivy-user-subscribe@ant.apache.org</subscribe>
<unsubscribe>ivy-user-unsubscribe@ant.apache.org</unsubscribe>
<post>ivy-user@ant.apache.org</post>
<archive>https://mail-archives.apache.org/mod_mbox/ant-ivy-user</archive>
<archive>https://lists.apache.org/list.html?ivy-user@ant.apache.org</archive>
</mailingList>
</mailingLists>
<issueManagement>

View File

@ -17,109 +17,160 @@
*/
package org.apache.ivy.ant;
import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import org.apache.ivy.core.module.descriptor.Configuration;
import org.apache.ivy.core.module.descriptor.DefaultModuleDescriptor;
import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
import org.apache.ivy.core.module.id.ModuleRevisionId;
import org.apache.ivy.core.report.ConfigurationResolveReport;
import org.apache.ivy.core.report.ResolveReport;
import org.apache.ivy.core.resolve.IvyNode;
import org.apache.ivy.core.resolve.ResolveOptions;
import org.apache.ivy.plugins.latest.ArtifactInfo;
import org.apache.ivy.plugins.latest.LatestStrategy;
import org.apache.ivy.plugins.resolver.DependencyResolver;
import org.apache.ivy.plugins.resolver.util.HasLatestStrategy;
import org.apache.tools.ant.BuildException;
import static org.apache.ivy.util.StringUtils.splitToArray;
public class IvyDependencyUpdateChecker extends IvyPostResolveTask {
private String revisionToCheck = "latest.integration";
private boolean download = false;
private boolean checkIfChanged = false;
private boolean showTransitive = false;
private String revisionToCheck = "latest.integration";
public boolean isDownload() {
return download;
}
public void setDownload(boolean download) {
this.download = download;
}
public boolean isCheckIfChanged() {
return checkIfChanged;
}
public void setCheckIfChanged(boolean checkIfChanged) {
this.checkIfChanged = checkIfChanged;
}
public boolean isShowTransitive() {
return showTransitive;
}
public void setShowTransitive(boolean showTransitive) {
this.showTransitive = showTransitive;
}
public String getRevisionToCheck() {
return revisionToCheck;
}
public void setRevisionToCheck(String revisionToCheck) {
this.revisionToCheck = revisionToCheck;
}
//--------------------------------------------------------------------------
@Override
public void doExecute() throws BuildException {
prepareAndCheck();
ModuleDescriptor originalModuleDescriptor = getResolvedReport().getModuleDescriptor();
// clone module descriptor
DefaultModuleDescriptor latestModuleDescriptor = new DefaultModuleDescriptor(
originalModuleDescriptor.getModuleRevisionId(),
originalModuleDescriptor.getStatus(), originalModuleDescriptor.getPublicationDate());
// copy configurations
for (Configuration configuration : originalModuleDescriptor.getConfigurations()) {
latestModuleDescriptor.addConfiguration(configuration);
}
// clone dependency and add new one with the requested revisionToCheck
for (DependencyDescriptor dependencyDescriptor : originalModuleDescriptor.getDependencies()) {
ModuleRevisionId upToDateMrid = ModuleRevisionId.newInstance(
dependencyDescriptor.getDependencyRevisionId(), revisionToCheck);
latestModuleDescriptor.addDependency(dependencyDescriptor.clone(upToDateMrid));
}
// resolve
ResolveOptions resolveOptions = new ResolveOptions();
resolveOptions.setCheckIfChanged(checkIfChanged);
resolveOptions.setConfs(splitToArray(getConf()));
resolveOptions.setDownload(isDownload());
resolveOptions.setLog(getLog());
resolveOptions.setConfs(splitToArray(getConf()));
resolveOptions.setCheckIfChanged(checkIfChanged);
ResolveReport latestReport;
try {
latestReport = getIvyInstance().getResolveEngine().resolve(latestModuleDescriptor,
resolveOptions);
ResolveReport latestReport = getIvyInstance().getResolveEngine()
.resolve(createModuleDescriptorForRevisionToCheck(), resolveOptions);
displayDependencyUpdates(getResolvedReport(), latestReport);
if (showTransitive) {
displayNewDependencyOnLatest(getResolvedReport(), latestReport);
displayMissingDependencyOnLatest(getResolvedReport(), latestReport);
}
} catch (ParseException | IOException e) {
} catch (Exception e) {
throw new BuildException("impossible to resolve dependencies:\n\t" + e, e);
}
}
private ModuleDescriptor createModuleDescriptorForRevisionToCheck() {
ModuleDescriptor moduleDescriptor = getResolvedReport().getModuleDescriptor();
// clone module descriptor
DefaultModuleDescriptor latestModuleDescriptor = new DefaultModuleDescriptor(
moduleDescriptor.getModuleRevisionId(), moduleDescriptor.getStatus(), moduleDescriptor.getPublicationDate());
// copy configurations
for (Configuration configuration : moduleDescriptor.getConfigurations()) {
latestModuleDescriptor.addConfiguration(configuration);
}
// clone direct dependencies with the requested revisionToCheck
for (DependencyDescriptor dependencyDescriptor : moduleDescriptor.getDependencies()) {
ModuleRevisionId upToDateMrid = ModuleRevisionId.newInstance(
dependencyDescriptor.getDependencyRevisionId(), revisionToCheck);
latestModuleDescriptor.addDependency(dependencyDescriptor.clone(upToDateMrid));
}
return latestModuleDescriptor;
}
private void displayDependencyUpdates(ResolveReport originalReport, ResolveReport latestReport) {
log("Dependencies updates available :");
boolean dependencyUpdateDetected = false;
for (IvyNode latest : latestReport.getDependencies()) {
for (IvyNode originalDependency : originalReport.getDependencies()) {
if (originalDependency.getModuleId().equals(latest.getModuleId())) {
if (!originalDependency.getResolvedId().getRevision()
.equals(latest.getResolvedId().getRevision())) {
// is this dependency a transitive or a direct dependency?
// (unfortunately .isTransitive() methods do not have the same meaning)
boolean isTransitiveDependency = latest.getDependencyDescriptor(latest
.getRoot()) == null;
if (!isTransitiveDependency || showTransitive) {
log(String.format("\t%s#%s%s\t%s -> %s",
originalDependency.getResolvedId().getOrganisation(),
originalDependency.getResolvedId().getName(),
isTransitiveDependency ? " (transitive)" : "",
originalDependency.getResolvedId().getRevision(),
latest.getResolvedId().getRevision()));
dependencyUpdateDetected = true;
}
}
Set<String> updates = new LinkedHashSet<>();
for (String conf : latestReport.getConfigurations()) {
ConfigurationResolveReport newReport = latestReport.getConfigurationReport(conf);
ConfigurationResolveReport oldReport = originalReport.getConfigurationReport(conf);
// NOTE: getModuleRevisionIds() filters evicted and problem deps
for (ModuleRevisionId latest : newReport.getModuleRevisionIds()) {
Iterable<IvyNode> iter = oldReport.getNodes(latest.getModuleId());
if (iter == null) {
continue;
}
for (IvyNode node : iter) {
ArtifactInfo in1 = toArtifactInfo(latest.getRevision());
ArtifactInfo in2 = toArtifactInfo(node.getResolvedId().getRevision());
ArtifactInfo out = getLatestStrategy(node).findLatest(new ArtifactInfo[]{in1, in2}, null);
boolean revisionGT = (out == in1);
boolean transitive = (node.getDependencyDescriptor(node.getRoot()) == null);
if (revisionGT && (!transitive || showTransitive)) {
String update = String.format("\t%s#%s%s\t%s -> %s",
node.getResolvedId().getOrganisation(),
node.getResolvedId().getName(),
transitive ? " (transitive)" : "",
node.getResolvedId().getRevision(),
latest.getRevision());
updates.add(update);
}
}
}
}
if (!dependencyUpdateDetected) {
log("\tAll dependencies are up to date");
log("Dependencies updates available :");
if (updates.isEmpty()) {
log("All dependencies are up to date");
} else {
updates.forEach(this::log);
}
}
private void displayMissingDependencyOnLatest(ResolveReport originalReport,
ResolveReport latestReport) {
private void displayMissingDependencyOnLatest(ResolveReport originalReport, ResolveReport latestReport) {
List<ModuleRevisionId> listOfMissingDependencyOnLatest = new ArrayList<>();
for (IvyNode originalDependency : originalReport.getDependencies()) {
boolean dependencyFound = false;
@ -141,8 +192,7 @@ public class IvyDependencyUpdateChecker extends IvyPostResolveTask {
}
}
private void displayNewDependencyOnLatest(ResolveReport originalReport,
ResolveReport latestReport) {
private void displayNewDependencyOnLatest(ResolveReport originalReport, ResolveReport latestReport) {
List<ModuleRevisionId> listOfNewDependencyOnLatest = new ArrayList<>();
for (IvyNode latest : latestReport.getDependencies()) {
boolean dependencyFound = false;
@ -163,35 +213,26 @@ public class IvyDependencyUpdateChecker extends IvyPostResolveTask {
}
}
public String getRevisionToCheck() {
return revisionToCheck;
//--------------------------------------------------------------------------
private LatestStrategy getLatestStrategy(IvyNode node) {
DependencyResolver resolver = getSettings().getResolver(node.getResolvedId());
if (resolver instanceof HasLatestStrategy) {
return ((HasLatestStrategy) resolver).getLatestStrategy();
}
return getSettings().getDefaultLatestStrategy();
}
public void setRevisionToCheck(String revisionToCheck) {
this.revisionToCheck = revisionToCheck;
}
public boolean isDownload() {
return download;
}
public void setDownload(boolean download) {
this.download = download;
}
public boolean isShowTransitive() {
return showTransitive;
}
public void setShowTransitive(boolean showTransitive) {
this.showTransitive = showTransitive;
}
public boolean isCheckIfChanged() {
return checkIfChanged;
}
public void setCheckIfChanged(boolean checkIfChanged) {
this.checkIfChanged = checkIfChanged;
private static ArtifactInfo toArtifactInfo(String revision) {
return new ArtifactInfo() {
@Override
public String getRevision() {
return revision;
}
@Override
public long getLastModified() {
return 0;
}
};
}
}

View File

@ -105,6 +105,10 @@ public abstract class IvyPostResolveTask extends IvyTask {
return resolve.createExclude();
}
public IvyOverride createOverride() {
return resolve.createOverride();
}
public IvyConflict createConflict() {
return resolve.createConflict();
}

View File

@ -96,6 +96,8 @@ public class IvyResolve extends IvyTask {
private List<IvyExclude> excludes = new ArrayList<>();
private List<IvyOverride> overrides = new ArrayList<>();
private List<IvyConflict> conflicts = new ArrayList<>();
public boolean isUseOrigin() {
@ -225,6 +227,12 @@ public class IvyResolve extends IvyTask {
return ex;
}
public IvyOverride createOverride() {
IvyOverride o = new IvyOverride();
overrides.add(o);
return o;
}
public IvyConflict createConflict() {
IvyConflict c = new IvyConflict();
conflicts.add(c);
@ -246,7 +254,8 @@ public class IvyResolve extends IvyTask {
type = getProperty(type, settings, "ivy.resolve.default.type.filter");
String[] confs = splitToArray(conf);
boolean childs = !dependencies.isEmpty() || !excludes.isEmpty() || !conflicts.isEmpty();
boolean childs = !dependencies.isEmpty() || !excludes.isEmpty() || !overrides.isEmpty()
|| !conflicts.isEmpty();
ResolveReport report;
if (childs) {
@ -282,6 +291,10 @@ public class IvyResolve extends IvyTask {
md.addExcludeRule(rule);
}
for (IvyOverride override : overrides) {
override.addOverride(md, settings);
}
for (IvyConflict conflict : conflicts) {
conflict.addConflict(md, settings);
}

View File

@ -18,6 +18,7 @@
package org.apache.ivy.core;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -166,7 +167,7 @@ public final class IvyPatternHelper {
tokens.put(ORIGINAL_ARTIFACTNAME_KEY, new OriginalArtifactNameValue(origin));
}
return substituteTokens(pattern, tokens, false);
return substituteTokens(pattern, tokens, false, true);
}
// CheckStyle:ParameterNumber ON
@ -225,10 +226,10 @@ public final class IvyPatternHelper {
public static String substituteTokens(String pattern, Map<String, String> tokens) {
Map<String, Object> tokensCopy = new HashMap<>();
tokensCopy.putAll(tokens);
return substituteTokens(pattern, tokensCopy, true);
return substituteTokens(pattern, tokensCopy, true, true);
}
private static String substituteTokens(String pattern, Map<String, Object> tokens, boolean external) {
private static String substituteTokens(String pattern, Map<String, Object> tokens, boolean external, boolean checkPathTraversal) {
Map<String, Object> tokensCopy = external ? tokens : new HashMap<>(tokens);
if (tokensCopy.containsKey(ORGANISATION_KEY) && !tokensCopy.containsKey(ORGANISATION_KEY2)) {
tokensCopy.put(ORGANISATION_KEY2, tokensCopy.get(ORGANISATION_KEY));
@ -330,7 +331,10 @@ public final class IvyPatternHelper {
}
String afterTokenSubstitution = buffer.toString();
checkAgainstPathTraversal(pattern, afterTokenSubstitution);
if (checkPathTraversal) {
checkAgainstPathTraversal(pattern, afterTokenSubstitution);
}
return afterTokenSubstitution;
}
@ -493,18 +497,49 @@ public final class IvyPatternHelper {
}
public static String getTokenRoot(String pattern) {
int index = pattern.indexOf('[');
if (index == -1) {
String token = getFirstToken(pattern);
if (token == null) {
// no token found, return the whole pattern
return pattern;
} else {
// it could be that pattern is something like "lib/([optional]/)[module]"
// we don't want the '(' in the result
int optionalIndex = pattern.indexOf('(');
if (optionalIndex >= 0) {
index = Math.min(index, optionalIndex);
}
return pattern.substring(0, index);
}
int index = pattern.indexOf('[' + token + ']');
if (index == -1) {
// should not happen, but just in case
return pattern;
}
// to tackle optional token parts, we follow this strategy:
// 1. substitute the token with a dummy value (e.g. "xxx")
// 2. substitute the token with an empty value
// 3. compare the two results and find the first character that is different
// -> this character is the first character that is not part of the root
String sub1 = substituteTokens(pattern, Collections.singletonMap(token, "xxx"), false, false);
String sub2 = substituteTokens(pattern, new HashMap<>(), true, false);
// due to the optional part, the second substitution could result in a shorter string
index = Math.min(index, sub2.length());
// now we compare the two strings character by character until we find a difference
for (int i = 0; i < index; i++) {
if (sub1.charAt(i) != sub2.charAt(i)) {
// we found the first character that is different, so we can return the root
index = i;
break;
}
}
// now let's find the last path separator before that index
// this tackles cases like "lib/config-[conf]/[module]" where we want to return "lib/" as root
for (int i = index - 1; i >= 0; i--) {
char c = sub1.charAt(i);
if (c == '/' || c == '\\') {
index = i + 1; // we want to include the separator in the result
break;
}
}
return sub1.substring(0, index);
}
public static String getFirstToken(String pattern) {

View File

@ -20,6 +20,7 @@ package org.apache.ivy.core.module.id;
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
import java.util.WeakHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -259,7 +260,7 @@ public class ModuleRevisionId extends UnmodifiableExtendableItem {
public String encodeToString() {
StringBuilder buf = new StringBuilder();
Map<String, String> attributes = new HashMap<>(getAttributes());
Map<String, String> attributes = new TreeMap<>(getAttributes());
attributes.keySet().removeAll(getExtraAttributes().keySet());
attributes.putAll(getQualifiedExtraAttributes());

View File

@ -26,6 +26,8 @@ import org.apache.ivy.core.module.descriptor.Artifact;
import org.apache.ivy.core.module.descriptor.DefaultArtifact;
import org.apache.ivy.core.settings.IvySettings;
import org.apache.ivy.plugins.IvySettingsAware;
import org.apache.ivy.plugins.pack.ArchivePacking;
import org.apache.ivy.plugins.pack.StreamPacking;
public class PackagingManager implements IvySettingsAware {

View File

@ -20,15 +20,13 @@ package org.apache.ivy.core.pack;
import java.util.HashMap;
import java.util.Map;
import org.apache.ivy.plugins.pack.ArchivePacking;
public class PackingRegistry {
private Map<String, ArchivePacking> packings = new HashMap<>();
public PackingRegistry() {
// register defaults
register(new ZipPacking());
register(new Pack200Packing());
register(new OsgiBundlePacking());
}
public void register(ArchivePacking packing) {

View File

@ -22,18 +22,7 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.*;
import org.apache.ivy.Ivy;
import org.apache.ivy.core.IvyContext;
@ -278,65 +267,51 @@ public class ResolveEngine {
}
IvyNode root = dependencies[0].getRoot();
Map<ModuleId, IvyNode> topLevelDeps = new HashMap<>();
for (IvyNode dependency : dependencies) {
if (!dependency.hasProblem()) {
DependencyDescriptor dd = dependency.getDependencyDescriptor(root);
if (dd != null) {
ModuleId orgMod = dependency.getModuleId();
topLevelDeps.put(orgMod, dependency);
}
if (dependency.hasProblem()) {
// skip dependencies with problems
continue;
}
}
for (IvyNode dependency : dependencies) {
if (!dependency.hasProblem() && !dependency.isCompletelyEvicted()) {
DependencyDescriptor dd = dependency.getDependencyDescriptor(root);
if (dd == null) {
ModuleId mid = dependency.getModuleId();
IvyNode tlDep = topLevelDeps.get(mid);
if (tlDep != null) {
dd = tlDep.getDependencyDescriptor(root);
}
}
if (dd != null) {
ModuleRevisionId depResolvedId = dependency.getResolvedId();
ModuleDescriptor depDescriptor = dependency.getDescriptor();
ModuleRevisionId depRevisionId = dd.getDependencyRevisionId();
ModuleRevisionId forcedRevisionId = forcedRevisions.get(dependency
.getModuleId());
if (dependency.getModuleRevision() != null
&& dependency.getModuleRevision().isForce()
&& !depResolvedId.equals(depRevisionId)
&& !settings.getVersionMatcher().isDynamic(depRevisionId)) {
// if we were forced to this revision and we
// are not a dynamic revision, reset to the
// asked revision
depResolvedId = depRevisionId;
depDescriptor = null;
}
if (depResolvedId == null) {
throw new NullPointerException("getResolvedId() is null for "
+ dependency.toString());
}
if (depRevisionId == null) {
throw new NullPointerException("getDependencyRevisionId() "
+ "is null for " + dd.toString());
}
String rev = depResolvedId.getRevision();
String forcedRev = forcedRevisionId == null ? rev : forcedRevisionId
.getRevision();
// The evicted modules have no description, so we can't put the status
String status = depDescriptor == null ? "?" : depDescriptor.getStatus();
Message.debug("storing dependency " + depResolvedId + " in props");
props.put(depRevisionId.encodeToString(), rev + " " + status + " "
+ forcedRev + " " + depResolvedId.getBranch());
}
DependencyDescriptor dd = dependency.getDependencyDescriptor(root);
if (dd == null) {
// we are only interested in direct dependencies
continue;
}
ModuleRevisionId depResolvedId = dependency.getResolvedId();
ModuleDescriptor depDescriptor = dependency.getDescriptor();
ModuleRevisionId depRevisionId = dd.getDependencyRevisionId();
ModuleRevisionId forcedRevisionId = forcedRevisions.get(dependency.getModuleId());
if (dependency.getModuleRevision() != null
&& dependency.getModuleRevision().isForce()
&& !depResolvedId.equals(depRevisionId)
&& !settings.getVersionMatcher().isDynamic(depRevisionId)) {
// if we were forced to this revision and we
// are not a dynamic revision, reset to the
// asked revision
depResolvedId = depRevisionId;
depDescriptor = null;
}
if (depResolvedId == null) {
throw new NullPointerException("getResolvedId() is null for "
+ dependency.toString());
}
if (depRevisionId == null) {
throw new NullPointerException("getDependencyRevisionId() "
+ "is null for " + dd.toString());
}
String rev = depResolvedId.getRevision();
String forcedRev = forcedRevisionId == null ? rev : forcedRevisionId
.getRevision();
// The evicted modules have no description, so we can't put the status
String status = depDescriptor == null ? "?" : depDescriptor.getStatus();
Message.debug("storing dependency " + depResolvedId + " in props");
props.put(depRevisionId.encodeToString(), rev + " " + status + " "
+ forcedRev + " " + depResolvedId.getBranch());
}
}
FileOutputStream out = new FileOutputStream(ivyPropertiesInCache);

View File

@ -33,7 +33,6 @@ import org.apache.ivy.core.module.id.ModuleId;
import org.apache.ivy.core.module.id.ModuleRevisionId;
import org.apache.ivy.core.module.id.ModuleRules;
import org.apache.ivy.core.module.status.StatusManager;
import org.apache.ivy.core.pack.ArchivePacking;
import org.apache.ivy.core.pack.PackingRegistry;
import org.apache.ivy.core.publish.PublishEngineSettings;
import org.apache.ivy.core.repository.RepositoryManagementEngineSettings;
@ -50,6 +49,7 @@ import org.apache.ivy.plugins.circular.WarnCircularDependencyStrategy;
import org.apache.ivy.plugins.conflict.ConflictManager;
import org.apache.ivy.plugins.conflict.LatestCompatibleConflictManager;
import org.apache.ivy.plugins.conflict.LatestConflictManager;
import org.apache.ivy.plugins.conflict.NearestConflictManager;
import org.apache.ivy.plugins.conflict.NoConflictManager;
import org.apache.ivy.plugins.conflict.StrictConflictManager;
import org.apache.ivy.plugins.latest.LatestLexicographicStrategy;
@ -67,6 +67,9 @@ import org.apache.ivy.plugins.matcher.MapMatcher;
import org.apache.ivy.plugins.matcher.PatternMatcher;
import org.apache.ivy.plugins.matcher.RegexpPatternMatcher;
import org.apache.ivy.plugins.namespace.Namespace;
import org.apache.ivy.plugins.pack.ArchivePacking;
import org.apache.ivy.plugins.pack.OsgiBundlePacking;
import org.apache.ivy.plugins.pack.ZipPacking;
import org.apache.ivy.plugins.parser.ModuleDescriptorParser;
import org.apache.ivy.plugins.parser.ModuleDescriptorParserRegistry;
import org.apache.ivy.plugins.parser.ParserSettings;
@ -267,6 +270,7 @@ public class IvySettings implements SortEngineSettings, PublishEngineSettings, P
latestTimeStrategy));
addConflictManager("all", new NoConflictManager());
addConflictManager("strict", new StrictConflictManager());
addConflictManager("nearest", new NearestConflictManager());
addMatcher(ExactPatternMatcher.INSTANCE);
addMatcher(RegexpPatternMatcher.INSTANCE);
@ -286,6 +290,21 @@ public class IvySettings implements SortEngineSettings, PublishEngineSettings, P
+ "org.apache.ivy.plugins.matcher.GlobPatternMatcher was not found", e);
}
addArchivePacking(new ZipPacking());
addArchivePacking(new OsgiBundlePacking());
try {
// Pack200Packing is optional. Only add it when available.
@SuppressWarnings("unchecked")
Class<? extends ArchivePacking> pack200 = (Class<? extends ArchivePacking>) IvySettings.class
.getClassLoader()
.loadClass("org.apache.ivy.plugins.pack.Pack200Packing");
addArchivePacking(pack200.newInstance());
} catch (Exception t) {
// ignore: the pack200 packing isn't on the classpath
Message.info("impossible to define pack200 packaging: "
+ "org.apache.ivy.plugins.pack.Pack200Packing was not found", t);
}
addReportOutputter(new LogReportOutputter());
addReportOutputter(new XmlReportOutputter());
@ -1554,6 +1573,10 @@ public class IvySettings implements SortEngineSettings, PublishEngineSettings, P
}
public synchronized void addConfigured(ArchivePacking packing) {
addArchivePacking(packing);
}
public synchronized void addArchivePacking(ArchivePacking packing) {
init(packing);
packingRegistry.register(packing);
}

View File

@ -41,9 +41,10 @@ latest-time = org.apache.ivy.plugins.latest.LatestTimeStrategy
fixed-cm = org.apache.ivy.plugins.conflict.FixedConflictManager
latest-cm = org.apache.ivy.plugins.conflict.LatestConflictManager
compatible-cm = org.apache.ivy.plugins.conflict.LatestCompatibleConflictManager
nearest-cm = org.apache.ivy.plugins.conflict.NearestConflictManager
no-cm = org.apache.ivy.plugins.conflict.NoConflictManager
strict-cm = org.apache.ivy.plugins.conflict.StrictConflictManager
regexp-cm = org.apache.ivy.plugins.conflict.RegexpConflictManager
strict-cm = org.apache.ivy.plugins.conflict.StrictConflictManager
namespace = org.apache.ivy.plugins.namespace.Namespace

View File

@ -0,0 +1,89 @@
/*
* 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.
*
*/
package org.apache.ivy.plugins.conflict;
import java.util.*;
import org.apache.ivy.core.resolve.IvyNode;
import org.apache.ivy.core.resolve.IvyNodeCallers;
import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
public class NearestConflictManager extends AbstractConflictManager {
@Override
public Collection<IvyNode> resolveConflicts(IvyNode parent, Collection<IvyNode> conflicts) {
if (conflicts.size() < 2) {
return conflicts;
}
// list containing the direct children of the parent
List<IvyNode> children = new ArrayList<>(conflicts.size());
for (IvyNode node : conflicts) {
DependencyDescriptor dd = node.getDependencyDescriptor(parent);
if (dd != null && parent.getResolvedId().equals(dd.getParentRevisionId())) {
if (dd.isForce()) {
return Collections.singleton(node);
}
children.add(node);
}
}
if (!children.isEmpty()) {
return children;
}
int distance = 0;
IvyNode node = null;
for (IvyNode child : conflicts) {
if (node == null) {
node = child;
// the first child has path through VisitNode
distance = node.getData().getCurrentVisitNode().getPath().size() - 2;
} else {
for (String conf : parent.getRequiredConfigurations()) {
int hops = calculateDistance(parent, conf, child);
if (hops <= distance) {
distance = hops;
node = child; // nearer or sooner
}
}
}
}
return Collections.singletonList(node);
}
private int calculateDistance(IvyNode parent, String conf, IvyNode child) {
int min = Short.MAX_VALUE;
for (IvyNodeCallers.Caller caller : child.getCallers(conf)) {
if (caller.getModuleRevisionId().equals(parent.getResolvedId())) {
return 0;
}
int distance = 1 + calculateDistance(parent, conf, child.findNode(caller.getModuleRevisionId()));
if (distance < min) {
min = distance;
}
}
return min;
}
}

View File

@ -1,32 +1,32 @@
/*
* 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.
*
*/
package org.apache.ivy.core.pack;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
public abstract class ArchivePacking {
public abstract String[] getNames();
public abstract void unpack(InputStream packed, File dest) throws IOException;
public abstract String getUnpackedExtension(String ext);
}
/*
* 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.
*
*/
package org.apache.ivy.plugins.pack;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
public abstract class ArchivePacking {
public abstract String[] getNames();
public abstract void unpack(InputStream packed, File dest) throws IOException;
public abstract String getUnpackedExtension(String ext);
}

View File

@ -1,47 +1,66 @@
/*
* 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.
*
*/
package org.apache.ivy.core.pack;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import org.apache.ivy.util.FileUtil;
/**
* Packaging which handle OSGi bundles with inner packed jar
*/
public class OsgiBundlePacking extends ZipPacking {
private static final String[] NAMES = {"bundle"};
@Override
public String[] getNames() {
return NAMES;
}
@Override
protected void writeFile(InputStream zip, File f) throws IOException {
// XXX maybe we should only unpack file listed by the 'Bundle-ClassPath' MANIFEST header ?
if (f.getName().endsWith(".jar.pack.gz")) {
zip = FileUtil.unwrapPack200(zip);
f = new File(f.getParentFile(), f.getName().substring(0, f.getName().length() - 8));
}
super.writeFile(zip, f);
}
}
/*
* 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.
*
*/
package org.apache.ivy.plugins.pack;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import org.apache.ivy.core.settings.IvySettings;
import org.apache.ivy.plugins.IvySettingsAware;
import org.apache.ivy.util.FileUtil;
/**
* Packaging which handle OSGi bundles with inner packed jar
*/
public class OsgiBundlePacking extends ZipPacking implements IvySettingsAware {
private static final String[] NAMES = {"bundle"};
private IvySettings settings;
@Override
public String[] getNames() {
return NAMES;
}
@Override
protected void writeFile(InputStream zip, File f) throws IOException {
// XXX maybe we should only unpack file listed by the 'Bundle-ClassPath' MANIFEST header ?
if (f.getName().endsWith(".jar.pack.gz")) {
// unpack the pack200 file
ArchivePacking pack200 = settings.getPackingRegistry().get("pack200");
if (pack200 == null) {
throw new IOException("Packing type 'pack200' not found!");
}
if (!(pack200 instanceof StreamPacking)) {
throw new IOException("Packing type 'pack200' is not a stream packing!");
}
f = new File(f.getParentFile(), f.getName().substring(0, f.getName().length() - 8));
zip = ((StreamPacking) pack200).unpack(zip);
}
super.writeFile(zip, f);
}
@Override
public void setSettings(IvySettings settings) {
this.settings = settings;
}
}

View File

@ -1,55 +1,53 @@
/*
* 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.
*
*/
package org.apache.ivy.core.pack;
import java.io.IOException;
import java.io.InputStream;
import org.apache.ivy.util.FileUtil;
public class Pack200Packing extends StreamPacking {
private static final String[] NAMES = {"pack200"};
@Override
public String[] getNames() {
return NAMES;
}
@Override
public String getUnpackedExtension(String ext) {
if (ext.endsWith("pack.gz")) {
ext = ext.substring(0, ext.length() - 7);
if (ext.endsWith(".")) {
ext = ext.substring(0, ext.length() - 1);
}
} else if (ext.endsWith("pack")) {
ext = ext.substring(0, ext.length() - 4);
if (ext.endsWith(".")) {
ext = ext.substring(0, ext.length() - 1);
}
}
return ext;
}
@Override
public InputStream unpack(InputStream packed) throws IOException {
return FileUtil.unwrapPack200(packed);
}
}
/*
* 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.
*
*/
package org.apache.ivy.plugins.pack;
import java.io.IOException;
import java.io.InputStream;
public class Pack200Packing extends StreamPacking {
private static final String[] NAMES = {"pack200"};
@Override
public String[] getNames() {
return NAMES;
}
@Override
public String getUnpackedExtension(String ext) {
if (ext.endsWith("pack.gz")) {
ext = ext.substring(0, ext.length() - 7);
if (ext.endsWith(".")) {
ext = ext.substring(0, ext.length() - 1);
}
} else if (ext.endsWith("pack")) {
ext = ext.substring(0, ext.length() - 4);
if (ext.endsWith(".")) {
ext = ext.substring(0, ext.length() - 1);
}
}
return ext;
}
@Override
public InputStream unpack(InputStream packed) throws IOException {
return Pack200Util.unpack(packed);
}
}

View File

@ -0,0 +1,45 @@
/*
* 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.
*
*/
package org.apache.ivy.plugins.pack;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.GZIPInputStream;
import org.apache.commons.compress.compressors.pack200.Pack200CompressorInputStream;
class Pack200Util {
static InputStream unpack(InputStream packed) throws IOException {
BufferedInputStream buffered = new BufferedInputStream(packed);
buffered.mark(4);
byte[] magic = new byte[4];
buffered.read(magic, 0, 4);
buffered.reset();
InputStream in = buffered;
if (magic[0] == (byte) 0x1F && magic[1] == (byte) 0x8B && magic[2] == (byte) 0x08) {
// this is a gziped pack200
in = new GZIPInputStream(in);
}
return new Pack200CompressorInputStream(in);
}
}

View File

@ -1,35 +1,35 @@
/*
* 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.
*
*/
package org.apache.ivy.core.pack;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import org.apache.ivy.util.FileUtil;
public abstract class StreamPacking extends ArchivePacking {
public abstract InputStream unpack(InputStream packed) throws IOException;
@Override
public void unpack(InputStream packed, File dest) throws IOException {
FileUtil.copy(unpack(packed), dest, null);
}
}
/*
* 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.
*
*/
package org.apache.ivy.plugins.pack;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import org.apache.ivy.util.FileUtil;
public abstract class StreamPacking extends ArchivePacking {
public abstract InputStream unpack(InputStream packed) throws IOException;
@Override
public void unpack(InputStream packed, File dest) throws IOException {
FileUtil.copy(unpack(packed), dest, null);
}
}

View File

@ -1,88 +1,88 @@
/*
* 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.
*
*/
package org.apache.ivy.core.pack;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.apache.ivy.util.FileUtil;
import org.apache.ivy.util.Message;
public class ZipPacking extends ArchivePacking {
private static final String[] NAMES = {"zip", "jar", "war"};
@Override
public String[] getNames() {
return NAMES;
}
@Override
public String getUnpackedExtension(String ext) {
if (ext.endsWith("zip") || ext.endsWith("jar") || ext.endsWith("war")) {
ext = ext.substring(0, ext.length() - 3);
if (ext.endsWith(".")) {
ext = ext.substring(0, ext.length() - 1);
}
}
return ext;
}
@Override
public void unpack(InputStream packed, File dest) throws IOException {
try (ZipInputStream zip = new ZipInputStream(packed)) {
ZipEntry entry = null;
while (((entry = zip.getNextEntry()) != null)) {
String entryName = entry.getName();
File f = FileUtil.resolveFile(dest, entryName);
if (!FileUtil.isLeadingPath(dest, f, true)) {
Message.verbose("\t\tskipping " + entryName + " as its target "
+ f.getCanonicalPath()
+ " is outside of " + dest.getCanonicalPath() + ".");
continue;
}
Message.verbose("\t\texpanding " + entryName + " to " + f);
// create intermediary directories - sometimes zip don't add them
File dirF = f.getParentFile();
if (dirF != null) {
dirF.mkdirs();
}
if (entry.isDirectory()) {
f.mkdirs();
} else {
writeFile(zip, f);
}
f.setLastModified(entry.getTime());
}
}
}
protected void writeFile(InputStream zip, File f) throws IOException {
try (FileOutputStream out = new FileOutputStream(f)) {
FileUtil.copy(zip, out, null, false);
}
}
}
/*
* 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.
*
*/
package org.apache.ivy.plugins.pack;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.apache.ivy.util.FileUtil;
import org.apache.ivy.util.Message;
public class ZipPacking extends ArchivePacking {
private static final String[] NAMES = {"zip", "jar", "war"};
@Override
public String[] getNames() {
return NAMES;
}
@Override
public String getUnpackedExtension(String ext) {
if (ext.endsWith("zip") || ext.endsWith("jar") || ext.endsWith("war")) {
ext = ext.substring(0, ext.length() - 3);
if (ext.endsWith(".")) {
ext = ext.substring(0, ext.length() - 1);
}
}
return ext;
}
@Override
public void unpack(InputStream packed, File dest) throws IOException {
try (ZipInputStream zip = new ZipInputStream(packed)) {
ZipEntry entry = null;
while (((entry = zip.getNextEntry()) != null)) {
String entryName = entry.getName();
File f = FileUtil.resolveFile(dest, entryName);
if (!FileUtil.isLeadingPath(dest, f, true)) {
Message.verbose("\t\tskipping " + entryName + " as its target "
+ f.getCanonicalPath()
+ " is outside of " + dest.getCanonicalPath() + ".");
continue;
}
Message.verbose("\t\texpanding " + entryName + " to " + f);
// create intermediary directories - sometimes zip don't add them
File dirF = f.getParentFile();
if (dirF != null) {
dirF.mkdirs();
}
if (entry.isDirectory()) {
f.mkdirs();
} else {
writeFile(zip, f);
}
f.setLastModified(entry.getTime());
}
}
}
protected void writeFile(InputStream zip, File f) throws IOException {
try (FileOutputStream out = new FileOutputStream(f)) {
FileUtil.copy(zip, out, null, false);
}
}
}

View File

@ -26,16 +26,22 @@ public class DefaultPomDependencyMgt implements PomDependencyMgt {
private String artifactId;
private String type;
private String classifier;
private String version;
private String scope;
private List<ModuleId> excludedModules;
public DefaultPomDependencyMgt(String groupId, String artifactId, String version, String scope,
public DefaultPomDependencyMgt(String groupId, String artifactId, String type, String classifier, String version, String scope,
List<ModuleId> excludedModules) {
this.groupId = groupId;
this.artifactId = artifactId;
this.type = type;
this.classifier = classifier;
this.version = version;
this.scope = scope;
this.excludedModules = excludedModules;
@ -53,6 +59,15 @@ public class DefaultPomDependencyMgt implements PomDependencyMgt {
return artifactId;
}
public String getType() {
return type;
}
@Override
public String getClassifier() {
return classifier;
}
public String getVersion() {
return version;
}

View File

@ -27,6 +27,10 @@ public interface PomDependencyMgt {
String getArtifactId();
String getType();
String getClassifier();
String getVersion();
String getScope();

View File

@ -17,16 +17,7 @@
*/
package org.apache.ivy.plugins.parser.m2;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.*;
import org.apache.ivy.core.cache.ArtifactOrigin;
import org.apache.ivy.core.module.descriptor.Artifact;
@ -55,6 +46,7 @@ import org.apache.ivy.plugins.resolver.DependencyResolver;
import org.apache.ivy.util.Message;
import static org.apache.ivy.core.module.descriptor.Configuration.Visibility.PUBLIC;
import static org.apache.ivy.util.StringUtils.defaultIfEmpty;
import static org.apache.ivy.util.StringUtils.isNullOrEmpty;
/**
@ -298,8 +290,7 @@ public class PomModuleDescriptorBuilder {
// is present, but empty.
List<ModuleId> excluded = dep.getExcludedModules();
if (excluded.isEmpty()) {
excluded = getDependencyMgtExclusions(ivyModuleDescriptor, dep.getGroupId(),
dep.getArtifactId());
excluded = getDependencyMgtExclusions(ivyModuleDescriptor, dep);
}
final boolean excludeAllTransitiveDeps = shouldExcludeAllTransitiveDeps(excluded);
// the same dependency mrid could appear twice in the module descriptor,
@ -414,16 +405,14 @@ public class PomModuleDescriptorBuilder {
public void addDependencyMgt(PomDependencyMgt dep) {
ivyModuleDescriptor.addDependencyManagement(dep);
String key = getDependencyMgtExtraInfoKeyForVersion(dep.getGroupId(), dep.getArtifactId());
String key = getDependencyMgtExtraInfoKeyForVersion(dep);
overwriteExtraInfoIfExists(key, dep.getVersion());
if (dep.getScope() != null) {
String scopeKey = getDependencyMgtExtraInfoKeyForScope(dep.getGroupId(),
dep.getArtifactId());
String scopeKey = getDependencyMgtExtraInfoKeyForScope(dep);
overwriteExtraInfoIfExists(scopeKey, dep.getScope());
}
if (!dep.getExcludedModules().isEmpty()) {
String exclusionPrefix = getDependencyMgtExtraInfoPrefixForExclusion(dep.getGroupId(),
dep.getArtifactId());
String exclusionPrefix = getDependencyMgtExtraInfoPrefixForExclusion(dep);
int index = 0;
for (ModuleId excludedModule : dep.getExcludedModules()) {
overwriteExtraInfoIfExists(
@ -494,6 +483,14 @@ public class PomModuleDescriptorBuilder {
return artifactId;
}
public String getType() {
return null;
}
public String getClassifier() {
return null;
}
public String getVersion() {
return version;
}
@ -508,22 +505,22 @@ public class PomModuleDescriptorBuilder {
}
private String getDefaultVersion(PomDependencyData dep) {
ModuleId moduleId = ModuleId.newInstance(dep.getGroupId(), dep.getArtifactId());
if (ivyModuleDescriptor.getDependencyManagementMap().containsKey(moduleId)) {
return ivyModuleDescriptor.getDependencyManagementMap().get(moduleId).getVersion();
DependencyMgtKey key = new DependencyMgtKey(dep);
if (ivyModuleDescriptor.getDependencyManagementMap().containsKey(key)) {
return ivyModuleDescriptor.getDependencyManagementMap().get(key).getVersion();
}
String key = getDependencyMgtExtraInfoKeyForVersion(dep.getGroupId(), dep.getArtifactId());
return ivyModuleDescriptor.getExtraInfoContentByTagName(key);
String tagName = getDependencyMgtExtraInfoKeyForVersion(dep);
return ivyModuleDescriptor.getExtraInfoContentByTagName(tagName);
}
private String getDefaultScope(PomDependencyData dep) {
String result;
ModuleId moduleId = ModuleId.newInstance(dep.getGroupId(), dep.getArtifactId());
if (ivyModuleDescriptor.getDependencyManagementMap().containsKey(moduleId)) {
result = ivyModuleDescriptor.getDependencyManagementMap().get(moduleId).getScope();
DependencyMgtKey key = new DependencyMgtKey(dep);
if (ivyModuleDescriptor.getDependencyManagementMap().containsKey(key)) {
result = ivyModuleDescriptor.getDependencyManagementMap().get(key).getScope();
} else {
String key = getDependencyMgtExtraInfoKeyForScope(dep.getGroupId(), dep.getArtifactId());
result = ivyModuleDescriptor.getExtraInfoContentByTagName(key);
String tagname = getDependencyMgtExtraInfoKeyForScope(dep);
result = ivyModuleDescriptor.getExtraInfoContentByTagName(tagname);
}
if (result == null || !MAVEN2_CONF_MAPPING.containsKey(result)) {
result = "compile";
@ -531,36 +528,58 @@ public class PomModuleDescriptorBuilder {
return result;
}
private static String getDependencyMgtExtraInfoKeyForVersion(String groupId, String artifactId) {
return DEPENDENCY_MANAGEMENT + EXTRA_INFO_DELIMITER + groupId + EXTRA_INFO_DELIMITER
+ artifactId + EXTRA_INFO_DELIMITER + "version";
private static String getDependencyMgtExtraInfoKeyForVersion(PomDependencyMgt dep) {
return getDependencyMgtExtraInfoKeyForProperty(dep, "version");
}
private static String getDependencyMgtExtraInfoKeyForScope(String groupId, String artifactId) {
return DEPENDENCY_MANAGEMENT + EXTRA_INFO_DELIMITER + groupId + EXTRA_INFO_DELIMITER
+ artifactId + EXTRA_INFO_DELIMITER + "scope";
private static String getDependencyMgtExtraInfoKeyForScope(PomDependencyMgt dep) {
return getDependencyMgtExtraInfoKeyForProperty(dep, "scope");
}
private static String getDependencyMgtExtraInfoPrefixForExclusion(PomDependencyMgt dep) {
return getDependencyMgtExtraInfoKeyForProperty(dep, "exclusion_");
}
private static String getDependencyMgtExtraInfoKeyForProperty(PomDependencyMgt dep, String propertyName) {
StringBuilder result = new StringBuilder(DEPENDENCY_MANAGEMENT);
result.append(EXTRA_INFO_DELIMITER)
.append(dep.getGroupId())
.append(EXTRA_INFO_DELIMITER)
.append(dep.getArtifactId());
// If the type and classifier are the default values, we don't need to include them in the key.
// However, if the type is the default value, but the classifier is not, we also do add the type.
// Otherwise, we can't distinguish between a
// - default type with a non-default classifier; and
// - non-default type with a default classifier.
String type = defaultIfEmpty(dep.getType(), DependencyMgtKey.DEFAULT_TYPE);
String classifier = dep.getClassifier();
if (classifier != null || !DependencyMgtKey.DEFAULT_TYPE.equals(type)) {
result.append(EXTRA_INFO_DELIMITER)
.append(type);
}
if (classifier != null) {
result.append(EXTRA_INFO_DELIMITER)
.append(classifier);
}
result.append(EXTRA_INFO_DELIMITER)
.append(propertyName);
return result.toString();
}
private static String getPropertyExtraInfoKey(String propertyName) {
return PROPERTIES + EXTRA_INFO_DELIMITER + propertyName;
}
private static String getDependencyMgtExtraInfoPrefixForExclusion(String groupId,
String artifactId) {
return DEPENDENCY_MANAGEMENT + EXTRA_INFO_DELIMITER + groupId + EXTRA_INFO_DELIMITER
+ artifactId + EXTRA_INFO_DELIMITER + "exclusion_";
}
private static List<ModuleId> getDependencyMgtExclusions(ModuleDescriptor descriptor,
String groupId, String artifactId) {
private static List<ModuleId> getDependencyMgtExclusions(ModuleDescriptor descriptor, PomDependencyMgt dep) {
if (descriptor instanceof PomModuleDescriptor) {
PomDependencyMgt dependencyMgt = ((PomModuleDescriptor) descriptor)
.getDependencyManagementMap().get(ModuleId.newInstance(groupId, artifactId));
.getDependencyManagementMap().get(new DependencyMgtKey(dep));
if (dependencyMgt != null) {
return dependencyMgt.getExcludedModules();
}
}
String exclusionPrefix = getDependencyMgtExtraInfoPrefixForExclusion(groupId, artifactId);
String exclusionPrefix = getDependencyMgtExtraInfoPrefixForExclusion(dep);
List<ModuleId> exclusionIds = new LinkedList<>();
for (ExtraInfoHolder extraInfoHolder : descriptor.getExtraInfos()) {
String key = extraInfoHolder.getName();
@ -578,32 +597,6 @@ public class PomModuleDescriptorBuilder {
return exclusionIds;
}
public static Map<ModuleId, String> getDependencyManagementMap(ModuleDescriptor md) {
Map<ModuleId, String> ret = new LinkedHashMap<>();
if (md instanceof PomModuleDescriptor) {
for (Map.Entry<ModuleId, PomDependencyMgt> e : ((PomModuleDescriptor) md)
.getDependencyManagementMap().entrySet()) {
PomDependencyMgt dependencyMgt = e.getValue();
ret.put(e.getKey(), dependencyMgt.getVersion());
}
} else {
for (ExtraInfoHolder extraInfoHolder : md.getExtraInfos()) {
String key = extraInfoHolder.getName();
if (key.startsWith(DEPENDENCY_MANAGEMENT)) {
String[] parts = key.split(EXTRA_INFO_DELIMITER);
if (parts.length != DEPENDENCY_MANAGEMENT_KEY_PARTS_COUNT) {
Message.warn("what seem to be a dependency management extra info "
+ "doesn't match expected pattern: " + key);
} else {
ret.put(ModuleId.newInstance(parts[1], parts[2]),
extraInfoHolder.getContent());
}
}
}
}
return ret;
}
public static List<PomDependencyMgt> getDependencyManagements(ModuleDescriptor md) {
List<PomDependencyMgt> result = new ArrayList<>();
@ -614,23 +607,31 @@ public class PomModuleDescriptorBuilder {
String key = extraInfoHolder.getName();
if (key.startsWith(DEPENDENCY_MANAGEMENT)) {
String[] parts = key.split(EXTRA_INFO_DELIMITER);
if (parts.length != DEPENDENCY_MANAGEMENT_KEY_PARTS_COUNT) {
if (parts.length < DEPENDENCY_MANAGEMENT_KEY_PARTS_COUNT || parts.length > DEPENDENCY_MANAGEMENT_KEY_PARTS_COUNT + 2) {
Message.warn("what seem to be a dependency management extra info "
+ "doesn't match expected pattern: " + key);
} else {
String versionKey = DEPENDENCY_MANAGEMENT + EXTRA_INFO_DELIMITER + parts[1]
+ EXTRA_INFO_DELIMITER + parts[2] + EXTRA_INFO_DELIMITER
+ "version";
String scopeKey = DEPENDENCY_MANAGEMENT + EXTRA_INFO_DELIMITER + parts[1]
+ EXTRA_INFO_DELIMITER + parts[2] + EXTRA_INFO_DELIMITER + "scope";
//m:dependency.management__groupId__artifactId[__type[__classifier]]__version
String groupId = parts[1];
String artifactId = parts[2];
String type = null;
String classifier = null;
if (parts.length == DEPENDENCY_MANAGEMENT_KEY_PARTS_COUNT + 1) {
type = parts[3];
} else if (parts.length == DEPENDENCY_MANAGEMENT_KEY_PARTS_COUNT + 2) {
type = parts[3];
classifier = parts[4];
}
PomDependencyMgt dep = new DefaultPomDependencyMgt(groupId, artifactId, type, classifier, null, null, null);
String versionKey = getDependencyMgtExtraInfoKeyForVersion(dep);
String scopeKey = getDependencyMgtExtraInfoKeyForScope(dep);
String version = md.getExtraInfoContentByTagName(versionKey);
String scope = md.getExtraInfoContentByTagName(scopeKey);
List<ModuleId> exclusions = getDependencyMgtExclusions(md, parts[1],
parts[2]);
result.add(new DefaultPomDependencyMgt(parts[1], parts[2], version, scope,
exclusions));
List<ModuleId> exclusions = getDependencyMgtExclusions(md, dep);
result.add(new DefaultPomDependencyMgt(groupId, artifactId, type, classifier, version, scope, exclusions));
}
}
}
@ -754,7 +755,7 @@ public class PomModuleDescriptorBuilder {
}
public static class PomModuleDescriptor extends DefaultModuleDescriptor {
private final Map<ModuleId, PomDependencyMgt> dependencyManagementMap = new LinkedHashMap<>();
private final Map<DependencyMgtKey, PomDependencyMgt> dependencyManagementMap = new LinkedHashMap<>();
// dependency descriptor keyed by its dependency revision id
private final Map<ModuleRevisionId, DependencyDescriptor> depDescriptors = new HashMap<>();
@ -763,12 +764,10 @@ public class PomModuleDescriptorBuilder {
}
public void addDependencyManagement(PomDependencyMgt dependencyMgt) {
dependencyManagementMap.put(
ModuleId.newInstance(dependencyMgt.getGroupId(), dependencyMgt.getArtifactId()),
dependencyMgt);
dependencyManagementMap.put(new DependencyMgtKey(dependencyMgt), dependencyMgt);
}
public Map<ModuleId, PomDependencyMgt> getDependencyManagementMap() {
public Map<DependencyMgtKey, PomDependencyMgt> getDependencyManagementMap() {
return dependencyManagementMap;
}
@ -778,4 +777,52 @@ public class PomModuleDescriptorBuilder {
this.depDescriptors.put(dependency.getDependencyRevisionId(), dependency);
}
}
public static class DependencyMgtKey {
private static final String DEFAULT_TYPE = "jar";
private final ModuleId moduleId;
private final String type; // default to 'jar' if not specified
private final String classifier; // default to null if not specified
public DependencyMgtKey(PomDependencyMgt dependencyMgt) {
moduleId = ModuleId.newInstance(dependencyMgt.getGroupId(), dependencyMgt.getArtifactId());
type = defaultIfEmpty(dependencyMgt.getType(), DEFAULT_TYPE);
classifier = dependencyMgt.getClassifier();
}
public String getGroupId() {
return moduleId.getOrganisation();
}
public String getArtifactId() {
return moduleId.getName();
}
public String getType() {
return type;
}
public String getClassifier() {
return classifier;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof DependencyMgtKey)) {
return false;
}
DependencyMgtKey that = (DependencyMgtKey) obj;
return Objects.equals(moduleId, that.moduleId)
&& Objects.equals(type, that.type)
&& Objects.equals(classifier, that.classifier);
}
@Override
public int hashCode() {
return Objects.hash(moduleId, type, classifier);
}
}
}

View File

@ -351,8 +351,8 @@ public final class PomModuleDescriptorParser implements ModuleDescriptorParser {
// add dependency management info from imported module
for (PomDependencyMgt importedDepMgt : getDependencyManagements(importDescr)) {
mdBuilder.addDependencyMgt(new DefaultPomDependencyMgt(importedDepMgt.getGroupId(),
importedDepMgt.getArtifactId(), importedDepMgt.getVersion(),
importedDepMgt.getScope(), importedDepMgt.getExcludedModules()));
importedDepMgt.getArtifactId(), importedDepMgt.getType(), importedDepMgt.getClassifier(),
importedDepMgt.getVersion(), importedDepMgt.getScope(), importedDepMgt.getExcludedModules()));
}
} else {
mdBuilder.addDependencyMgt(dep);
@ -378,7 +378,14 @@ public final class PomModuleDescriptorParser implements ModuleDescriptorParser {
ModuleDescriptor md = mdBuilder.getModuleDescriptor();
ModuleRevisionId mrid = md.getModuleRevisionId();
DependencyResolver resolver = ivySettings.getResolver(mrid);
// get the resolver configured on the engine and if none is configured then
// get the one configured in ivy settings
ResolveEngine engine = IvyContext.getContext().getIvy().getResolveEngine();
DependencyResolver resolver = engine.getDictatorResolver();
if (resolver == null) {
resolver = ivySettings.getResolver(mrid);
}
if (resolver == null) {
Message.debug(
@ -442,15 +449,21 @@ public final class PomModuleDescriptorParser implements ModuleDescriptorParser {
}
try {
DependencyDescriptor dd = new DefaultDependencyDescriptor(parentModRevID, true);
ResolveEngine engine = IvyContext.getContext().getIvy().getResolveEngine();
ResolveData data = IvyContext.getContext().getResolveData();
if (data == null) {
ResolveEngine engine = IvyContext.getContext().getIvy().getResolveEngine();
ResolveOptions options = new ResolveOptions();
options.setDownload(false);
data = new ResolveData(engine, options);
}
DependencyResolver resolver = ivySettings.getResolver(parentModRevID);
// get the resolver configured on the engine and if none is configured then
// get the one configured in ivy settings
DependencyResolver resolver = engine.getDictatorResolver();
if (resolver == null) {
resolver = ivySettings.getResolver(parentModRevID);
}
if (resolver == null) {
// TODO: Throw exception here?
return null;

View File

@ -38,11 +38,15 @@ import org.apache.ivy.core.IvyPatternHelper;
import org.apache.ivy.core.module.descriptor.Artifact;
import org.apache.ivy.core.module.descriptor.DependencyArtifactDescriptor;
import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
import org.apache.ivy.core.module.descriptor.DependencyDescriptorMediator;
import org.apache.ivy.core.module.descriptor.ExcludeRule;
import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
import org.apache.ivy.core.module.descriptor.OverrideDependencyDescriptorMediator;
import org.apache.ivy.core.module.id.ModuleRevisionId;
import org.apache.ivy.core.module.id.ModuleRules;
import org.apache.ivy.core.settings.IvySettings;
import org.apache.ivy.core.settings.IvyVariableContainer;
import org.apache.ivy.plugins.matcher.MapMatcher;
import org.apache.ivy.plugins.parser.m2.PomWriterOptions.ConfigurationScopeMapping;
import org.apache.ivy.plugins.parser.m2.PomWriterOptions.ExtraDependency;
import org.apache.ivy.util.ConfigurationUtils;
@ -72,22 +76,18 @@ public final class PomModuleDescriptorWriter {
throws IOException {
LineNumberReader in;
if (options.getTemplate() == null) {
in = new LineNumberReader(new InputStreamReader(
PomModuleDescriptorWriter.class.getResourceAsStream("pom.template")));
in = new LineNumberReader(new InputStreamReader(PomModuleDescriptorWriter.class.getResourceAsStream("pom.template")));
} else {
in = new LineNumberReader(new InputStreamReader(new FileInputStream(
options.getTemplate())));
in = new LineNumberReader(new InputStreamReader(new FileInputStream(options.getTemplate())));
}
if (output.getParentFile() != null) {
output.getParentFile().mkdirs();
}
PrintWriter out = new PrintWriter(new OutputStreamWriter(new FileOutputStream(output),
StandardCharsets.UTF_8));
try {
try (PrintWriter out = new PrintWriter(new OutputStreamWriter(new FileOutputStream(output), StandardCharsets.UTF_8))) {
IvySettings settings = IvyContext.getContext().getSettings();
IvyVariableContainer variables = new IvyVariableContainerWrapper(
settings.getVariableContainer());
IvyVariableContainer variables = new IvyVariableContainerWrapper(settings.getVariableContainer());
variables.setVariable("ivy.pom.license", SKIP_LINE, true);
variables.setVariable("ivy.pom.header", SKIP_LINE, true);
@ -103,53 +103,69 @@ public final class PomModuleDescriptorWriter {
variables.setVariable("ivy.pom.license", options.getLicenseHeader(), true);
}
if (options.isPrintIvyInfo()) {
String header = "<!--\n" + " Apache Maven 2 POM generated by Apache Ivy\n"
+ " " + Ivy.getIvyHomeURL() + "\n" + " Apache Ivy version: "
+ Ivy.getIvyVersion() + " " + Ivy.getIvyDate() + "\n" + "-->";
String header
= "<!--\n" // TODO: replace \n with lineSeparator()
+ " Apache Maven 2 POM generated by Apache Ivy\n"
+ " " + Ivy.getIvyHomeURL() + "\n"
+ " Apache Ivy version: " + Ivy.getIvyVersion() + " " + Ivy.getIvyDate() + "\n"
+ "-->";
variables.setVariable("ivy.pom.header", header, true);
}
setModuleVariables(md, variables, options);
boolean dependencyManagement = false;
boolean dependenciesPrinted = false;
boolean overridesPrinted = false;
int lastIndent = 0;
int indent = 0;
String line = in.readLine();
while (line != null) {
String line;
while ((line = in.readLine()) != null) {
line = IvyPatternHelper.substituteVariables(line, variables);
if (line.contains(SKIP_LINE)) {
// skip this line
line = in.readLine();
continue;
}
if (line.trim().isEmpty()) {
// empty line
out.println(line);
line = in.readLine();
continue;
if (!line.trim().isEmpty()) {
lastIndent = indent;
indent = line.indexOf('<');
if (line.contains("<dependencyManagement>")) {
dependencyManagement = true;
}
if (line.contains("</dependencyManagement>")) {
dependencyManagement = false;
}
if (line.contains("</dependencies>")) {
if (!overridesPrinted && dependencyManagement) {
printOverrides(md, out, indent, false);
overridesPrinted = true;
}
if (!dependenciesPrinted && !dependencyManagement) {
printDependencies(md, out, options, indent, false);
dependenciesPrinted = true;
}
}
if (line.contains("</project>")) {
if (!overridesPrinted) {
printOverrides(md, out, lastIndent, true);
overridesPrinted = true;
}
if (!dependenciesPrinted) {
printDependencies(md, out, options, lastIndent, true);
dependenciesPrinted = true;
}
}
}
lastIndent = indent;
indent = line.indexOf('<');
if (!dependenciesPrinted && line.contains("</dependencies>")) {
printDependencies(md, out, options, indent, false);
dependenciesPrinted = true;
}
if (!dependenciesPrinted && line.contains("</project>")) {
printDependencies(md, out, options, lastIndent, true);
dependenciesPrinted = true;
}
out.println(line);
line = in.readLine();
}
} finally {
in.close();
out.close();
}
}
@ -343,8 +359,59 @@ public final class PomModuleDescriptorWriter {
out.println("</exclusions>");
}
private static DependencyDescriptor[] getDependencies(ModuleDescriptor md,
PomWriterOptions options) {
private static void printOverrides(ModuleDescriptor md, PrintWriter out, int indent, boolean container) {
ModuleRules<DependencyDescriptorMediator> mr = md.getAllDependencyDescriptorMediators();
Map<MapMatcher, DependencyDescriptorMediator> m = new LinkedHashMap<>(mr.getAllRules());
m.values().removeIf(value -> !(value instanceof OverrideDependencyDescriptorMediator));
m.keySet().removeIf(key -> {
String artifactId = key.getAttributes().get("module");
return artifactId == null || artifactId.equals("*");
});
m.keySet().removeIf(key -> {
String groupId = key.getAttributes().get("organisation");
return groupId == null || groupId.equals("*");
});
if (m.isEmpty()) {
return;
}
if (container) {
indent(out, indent);
out.println("<dependencyManagement>");
indent(out, indent * 2);
out.println("<dependencies>");
} else {
indent /= 2; // <dependencies> is second-level child of <project>
}
for (Map.Entry<MapMatcher, DependencyDescriptorMediator> entry : m.entrySet()) {
String artifactId = entry.getKey().getAttributes().get("module");
String groupId = entry.getKey().getAttributes().get("organisation");
String version = ((OverrideDependencyDescriptorMediator) entry.getValue()).getVersion();
indent(out, indent * 3);
out.println("<dependency>");
indent(out, indent * 4);
out.println("<groupId>" + groupId + "</groupId>");
indent(out, indent * 4);
out.println("<artifactId>" + artifactId + "</artifactId>");
indent(out, indent * 4);
out.println("<version>" + version + "</version>");
indent(out, indent * 3);
out.println("</dependency>");
}
if (container) {
indent(out, indent * 2);
out.println("</dependencies>");
indent(out, indent);
out.println("</dependencyManagement>");
}
}
private static DependencyDescriptor[] getDependencies(ModuleDescriptor md, PomWriterOptions options) {
String[] confs = ConfigurationUtils.replaceWildcards(options.getConfs(), md);
List<DependencyDescriptor> result = new ArrayList<>();

View File

@ -394,6 +394,18 @@ public class PomReader {
return replaceProps(val);
}
@Override
public String getType() {
String val = getFirstChildText(depElement, TYPE);
return emptyIsNull(replaceProps(val));
}
@Override
public String getClassifier() {
String val = getFirstChildText(depElement, CLASSIFIER);
return emptyIsNull(replaceProps(val));
}
/*
* (non-Javadoc)
*
@ -406,7 +418,7 @@ public class PomReader {
public String getScope() {
String val = getFirstChildText(depElement, SCOPE);
return replaceProps(val);
return emptyIsNull(replaceProps(val));
}
public List<ModuleId> getExcludedModules() {
@ -428,6 +440,23 @@ public class PomReader {
}
return exclusions;
}
/**
* We return null where certain elements within a pom don't have a value specified.
* For example, there are pom.xml out there which just use "<classifier/>" in the dependencies.
* (dependencies in org.seleniumhq.selenium:selenium-java:3.141.59 are one such example)
* We do this so that callers of such elements don't have to keep repeating checks for empty value.
* For us an empty value, for many of such elements, is really the same as that element not being specified
*
* @param val The value to check
* @return
*/
private String emptyIsNull(final String val) {
if (val == null) {
return null;
}
return val.isEmpty() ? null : val;
}
}
public List<PomPluginElement> getPlugins() {
@ -487,6 +516,16 @@ public class PomReader {
return replaceProps(val);
}
@Override
public String getType() {
return null;
}
@Override
public String getClassifier() {
return null;
}
public String getScope() {
return null; // not used
}
@ -508,42 +547,9 @@ public class PomReader {
this.depElement = depElement;
}
@Override
public String getScope() {
String val = getFirstChildText(depElement, SCOPE);
return emptyIsNull(replaceProps(val));
}
public String getClassifier() {
String val = getFirstChildText(depElement, CLASSIFIER);
return emptyIsNull(replaceProps(val));
}
public String getType() {
String val = getFirstChildText(depElement, TYPE);
return emptyIsNull(replaceProps(val));
}
public boolean isOptional() {
return Boolean.parseBoolean(getFirstChildText(depElement, OPTIONAL));
}
/**
* We return null where certain elements within a pom don't have a value specified.
* For example, there are pom.xml out there which just use "<classifier/>" in the dependencies.
* (dependencies in org.seleniumhq.selenium:selenium-java:3.141.59 are one such example)
* We do this so that callers of such elements don't have to keep repeating checks for empty value.
* For us an empty value, for many of such elements, is really the same as that element not being specified
*
* @param val The value to check
* @return
*/
private String emptyIsNull(final String val) {
if (val == null) {
return null;
}
return val.equals("") ? null : val;
}
}
public class PomProfileElement {

View File

@ -83,6 +83,7 @@ import org.apache.ivy.util.FileUtil;
import org.apache.ivy.util.Message;
import org.apache.ivy.util.XMLHelper;
import org.apache.ivy.util.extendable.ExtendableItemHelper;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
@ -219,7 +220,7 @@ public class XmlModuleDescriptorParser extends AbstractModuleDescriptorParser {
}
protected static final List<String> ALLOWED_VERSIONS = Arrays.asList("1.0",
"1.1", "1.2", "1.3", "1.4", "2.0", "2.1", "2.2", "2.3", "2.4");
"1.1", "1.2", "1.3", "1.4", "2.0", "2.1", "2.2", "2.3", "2.4", "2.5", "2.6");
private static final String IVY_XSD_CONTENT;
@ -548,37 +549,30 @@ public class XmlModuleDescriptorParser extends AbstractModuleDescriptorParser {
* @param parent
* a given parent module descriptor
*/
protected void mergeWithOtherModuleDescriptor(List<String> extendTypes,
ModuleDescriptor parent) {
protected void mergeWithOtherModuleDescriptor(List<String> extendTypes, ModuleDescriptor parent) {
if (extendTypes.contains("all")) {
mergeAll(parent);
} else {
if (extendTypes.contains("info")) {
mergeInfo(parent);
}
if (extendTypes.contains("configurations")) {
mergeConfigurations(parent);
}
if (extendTypes.contains("dependencies")) {
mergeDependencies(parent.getDependencies());
}
if (extendTypes.contains("description")) {
mergeDescription(parent.getDescription());
}
if (extendTypes.contains("licenses")) {
mergeLicenses(parent.getLicenses());
}
if (extendTypes.contains("excludes")) {
mergeExcludes(parent.getAllExcludeRules());
}
}
mergeNamespaces(parent.getExtraAttributesNamespaces()); // IVY-1658
}
/**
@ -722,6 +716,17 @@ public class XmlModuleDescriptorParser extends AbstractModuleDescriptorParser {
}
}
private void mergeNamespaces(Map<String, String> namespaces) {
if (namespaces != null && !namespaces.isEmpty()) {
for (Map.Entry<String, String> entry : namespaces.entrySet()) {
Message.debug("Merging extra attribute namesapce: " + entry);
if (getMd().getExtraAttributesNamespaces().get(entry.getKey()) == null) {
getMd().addExtraAttributeNamespace(entry.getKey(), entry.getValue());
}
}
}
}
/**
* Returns the parent module using the location attribute (for dev purpose).
*
@ -1455,5 +1460,4 @@ public class XmlModuleDescriptorParser extends AbstractModuleDescriptorParser {
public String toString() {
return "ivy parser";
}
}

View File

@ -59,6 +59,7 @@ import org.apache.ivy.util.DateUtil;
import org.apache.ivy.util.Message;
import org.apache.ivy.util.XMLHelper;
import org.apache.ivy.util.extendable.ExtendableItemHelper;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
@ -291,12 +292,10 @@ public final class XmlModuleDescriptorUpdater {
// according to ivy.xsd, all <dependency> elements must occur before
// the <exclude>, <override> or <conflict> elements
if (options.isMerge()
&& ("exclude".equals(localName) || "override".equals(localName) || "conflict"
.equals(localName)) && "ivy-module/dependencies".equals(getContext())) {
&& !mergedDependencies
&& "ivy-module/dependencies".equals(getContext())) {
ModuleDescriptor merged = options.getMergedDescriptor();
writeInheritedDependencies(merged);
out.println();
out.print(getIndent());
}
context.push(qName);
@ -409,13 +408,24 @@ public final class XmlModuleDescriptorUpdater {
// copy
write("<" + qName);
for (int i = 0; i < attributes.getLength(); i++) {
write(" " + attributes.getQName(i) + "=\""
+ substitute(settings, attributes.getValue(i)) + "\"");
if (options.isMerge() && path.equals("ivy-module")) {
for (int i = 0, n = attributes.getLength(); i < n; i += 1) {
if (attributes.getQName(i).startsWith("xmlns:")) {
continue; // written next from namespace map
}
write(" " + attributes.getQName(i) + "=\"" + substitute(settings, attributes.getValue(i)) + "\"");
}
Map<String, String> namespaces = options.getMergedDescriptor().getExtraAttributesNamespaces();
for (Map.Entry<String, String> namespace : namespaces.entrySet()) {
write(" xmlns:" + namespace.getKey() + "=\"" + substitute(settings, namespace.getValue()) + "\"");
}
} else {
for (int i = 0, n = attributes.getLength(); i < n; i += 1) {
write(" " + attributes.getQName(i) + "=\"" + substitute(settings, attributes.getValue(i)) + "\"");
}
}
}
justOpen = qName;
// indent.append("\t");
}
private void startExtends(Attributes attributes) {
@ -979,7 +989,7 @@ public final class XmlModuleDescriptorUpdater {
* just write the inherited items inline, with a comment indicating where they
* came from.
*/
private void writeInheritedItems(ModuleDescriptor merged, InheritableItem[] items,
private boolean writeInheritedItems(ModuleDescriptor merged, InheritableItem[] items,
ItemPrinter printer, String itemName, boolean includeContainer) {
// first categorize inherited items by their source module, so that
// we can add some useful comments
@ -1002,6 +1012,10 @@ public final class XmlModuleDescriptorUpdater {
newMapping.isEmpty() ? "" : " defaultconfmapping=\"" + newMapping + "\"",
(confMappingOverride != null) ? " confmappingoverride=\"" + confMappingOverride + "\"" : ""));
context.push(itemName);
if ("dependencies".equals(itemName)) {
out.println();
out.print(getIndent());
}
justOpen = null;
}
@ -1027,13 +1041,17 @@ public final class XmlModuleDescriptorUpdater {
// restore the prior indent
out.print(currentIndent);
}
return hasItems;
}
private void writeInheritanceComment(String itemDescription, Object parentInfo) {
PrintWriter out = getWriter();
out.println();
out.println(getIndent() + "<!-- " + itemDescription + " inherited from " + parentInfo
+ " -->");
if (!"dependencies".equals(itemDescription)) {
out.println();
out.print(getIndent());
}
out.println("<!-- " + itemDescription + " inherited from " + parentInfo + " -->");
}
/**
@ -1101,11 +1119,27 @@ public final class XmlModuleDescriptorUpdater {
private void writeInheritedDependencies(ModuleDescriptor merged) {
if (!mergedDependencies) {
mergedDependencies = true;
writeInheritedItems(merged, merged.getDependencies(), DependencyPrinter.INSTANCE,
"dependencies", false);
InheritableItem[] items = getDependencies(merged);
if (writeInheritedItems(merged, items, DependencyPrinter.INSTANCE, "dependencies", false)) {
out.println("<!-- dependencies inherited end -->");
out.println(); // separate from next section
out.print(getIndent());
}
}
}
private DependencyDescriptor[] getDependencies(ModuleDescriptor merged) {
DependencyDescriptor[] dependencies = merged.getDependencies();
for (int i = 0; i < dependencies.length; i += 1) {
ModuleRevisionId mrid = dependencies[i].getDependencyRevisionId();
String rev = resolvedRevisions.get(mrid); // IVY-1410
if (rev != null && !rev.equals(mrid.getRevision())) {
dependencies[i] = dependencies[i].clone(ModuleRevisionId.newInstance(mrid, rev));
}
}
return dependencies;
}
/**
* <p>
* If publishing in merge mode, guarantee that any merged elements appearing before
@ -1125,7 +1159,7 @@ public final class XmlModuleDescriptorUpdater {
* a descriptor element name, for example "configurations" or "info"
*/
private void flushMergedElementsBefore(String moduleElement) {
if (options.isMerge() && context.size() == 1 && "ivy-module".equals(context.peek())
if (options.isMerge() && "ivy-module".equals(getContext())
&& !(mergedConfigurations && mergedDependencies)) {
// calculate the position of the element in ivy-module
@ -1160,7 +1194,6 @@ public final class XmlModuleDescriptorUpdater {
}
public void endElement(String uri, String localName, String qName) throws SAXException {
String path = getContext();
if (options.isMerge()) {
ModuleDescriptor merged = options.getMergedDescriptor();
@ -1174,10 +1207,6 @@ public final class XmlModuleDescriptorUpdater {
// write inherited configurations after all child configurations
writeInheritedConfigurations(merged);
break;
case "ivy-module/dependencies":
// write inherited dependencies after all child dependencies
writeInheritedDependencies(merged);
break;
case "ivy-module":
// write any remaining inherited data before we close the
// descriptor.
@ -1260,6 +1289,13 @@ public final class XmlModuleDescriptorUpdater {
justOpen = null;
}
if (options.isMerge()
&& !mergedDependencies
&& "ivy-module/dependencies".equals(getContext())) {
ModuleDescriptor merged = options.getMergedDescriptor();
writeInheritedDependencies(merged);
}
write("<!--");
write(String.valueOf(ch, start, length));
write("-->");

View File

@ -237,7 +237,7 @@ public class PackagerCacheEntry {
}
private static File getSubdir(File rootDir, ModuleRevisionId mr) {
return new File(rootDir, mr.getOrganisation() + File.separatorChar + mr.getName()
+ File.separatorChar + mr.getRevision());
String subDir = IvyPatternHelper.substitute("[organisation]/[module]/[revision]", mr);
return new File(rootDir, subDir);
}
}

View File

@ -22,10 +22,7 @@ import org.apache.ivy.util.url.TimeoutConstrainedURLHandler;
import org.apache.ivy.util.url.URLHandler;
import org.apache.ivy.util.url.URLHandlerRegistry;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
@ -42,11 +39,6 @@ import java.util.Collections;
import java.util.List;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.jar.JarOutputStream;
import java.util.zip.GZIPInputStream;
import java.util.zip.ZipInputStream;
import static java.util.jar.Pack200.newUnpacker;
/**
* Utility class used to deal with file related operations, like copy, full reading, symlink, ...
@ -693,101 +685,6 @@ public final class FileUtil {
return l;
}
public static InputStream unwrapPack200(InputStream packed) throws IOException {
BufferedInputStream buffered = new BufferedInputStream(packed);
buffered.mark(4);
byte[] magic = new byte[4];
buffered.read(magic, 0, 4);
buffered.reset();
InputStream in = buffered;
if (magic[0] == (byte) 0x1F && magic[1] == (byte) 0x8B && magic[2] == (byte) 0x08) {
// this is a gziped pack200
in = new GZIPInputStream(in);
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
JarOutputStream jar = new JarOutputStream(baos);
newUnpacker().unpack(new UncloseInputStream(in), jar);
jar.close();
return new ByteArrayInputStream(baos.toByteArray());
}
/**
* Wrap an input stream and do not close the stream on call to close(). Used to avoid closing a
* {@link ZipInputStream} used with {@link Pack200.Unpacker#unpack(File, JarOutputStream)}
*/
private static final class UncloseInputStream extends InputStream {
private InputStream wrapped;
public UncloseInputStream(InputStream wrapped) {
this.wrapped = wrapped;
}
@Override
public void close() throws IOException {
// do not close
}
@Override
public int read() throws IOException {
return wrapped.read();
}
@Override
public int hashCode() {
return wrapped.hashCode();
}
@Override
public int read(byte[] b) throws IOException {
return wrapped.read(b);
}
@Override
public boolean equals(Object obj) {
return wrapped.equals(obj);
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
return wrapped.read(b, off, len);
}
@Override
public long skip(long n) throws IOException {
return wrapped.skip(n);
}
@Override
public String toString() {
return wrapped.toString();
}
@Override
public int available() throws IOException {
return wrapped.available();
}
@Override
public void mark(int readlimit) {
wrapped.mark(readlimit);
}
@Override
public void reset() throws IOException {
wrapped.reset();
}
@Override
public boolean markSupported() {
return wrapped.markSupported();
}
}
private static final class DissectedPath {
private final String root;

View File

@ -244,4 +244,9 @@ public final class StringUtils {
}
return sb.toString();
}
public static String defaultIfEmpty(String value, String defaultValue) {
return (value == null || value.isEmpty()) ? defaultValue : value;
}
}

View File

@ -17,17 +17,6 @@
*/
package org.apache.ivy;
import org.apache.ivy.core.retrieve.RetrieveOptions;
import org.apache.ivy.util.CacheCleaner;
import org.apache.ivy.util.cli.CommandLine;
import org.apache.ivy.util.cli.ParseException;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
import java.io.File;
import java.net.URL;
import java.nio.file.Files;
@ -37,18 +26,27 @@ import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import org.apache.ivy.core.retrieve.RetrieveOptions;
import org.apache.ivy.util.CacheCleaner;
import org.apache.ivy.util.cli.CommandLine;
import org.apache.ivy.util.cli.ParseException;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
public class MainTest {
private File cache;
@Rule
public ExpectedException expExc = ExpectedException.none();
@Rule
public TemporaryFolder tempDir = new TemporaryFolder();
@ -65,51 +63,47 @@ public class MainTest {
@Test
public void testHelp() throws Exception {
run(new String[] {"-?"});
run("-?");
}
@Test
public void testBadOption() throws Exception {
expExc.expect(ParseException.class);
expExc.expectMessage("Unrecognized option: -bad");
run(new String[] {"-bad"});
public void testBadOption() {
Exception exception = assertThrows(ParseException.class, () -> run("-bad"));
assertEquals("Unrecognized option: -bad", exception.getMessage());
}
@Test
public void testMissingParameter() throws Exception {
expExc.expect(ParseException.class);
expExc.expectMessage("no argument for: ivy");
run(new String[] {"-ivy"});
public void testMissingParameter() {
Exception exception = assertThrows(ParseException.class, () -> run("-ivy"));
assertEquals("no argument for: ivy", exception.getMessage());
}
@Test
public void testResolveSimple() throws Exception {
run(new String[] {"-settings", "test/repositories/ivysettings.xml", "-ivy",
"test/repositories/1/org1/mod1.1/ivys/ivy-1.0.xml"});
run("-settings", "test/repositories/ivysettings.xml", "-ivy", "test/repositories/1/org1/mod1.1/ivys/ivy-1.0.xml");
assertTrue(new File("build/cache/org1/mod1.2/ivy-2.0.xml").exists());
}
@Test
public void testResolveSimpleWithConfs() throws Exception {
run(new String[] {"-settings", "test/repositories/ivysettings.xml", "-ivy",
"test/repositories/1/org1/mod1.1/ivys/ivy-1.0.xml", "-confs", "default"});
run("-settings", "test/repositories/ivysettings.xml", "-ivy", "test/repositories/1/org1/mod1.1/ivys/ivy-1.0.xml", "-confs", "default");
assertTrue(new File("build/cache/org1/mod1.2/ivy-2.0.xml").exists());
}
@Test
public void testResolveSimpleWithConfs2() throws Exception {
run(new String[] {"-settings", "test/repositories/ivysettings.xml", "-confs", "default",
"-ivy", "test/repositories/1/org1/mod1.1/ivys/ivy-1.0.xml"});
run("-settings", "test/repositories/ivysettings.xml", "-confs", "default", "-ivy", "test/repositories/1/org1/mod1.1/ivys/ivy-1.0.xml");
assertTrue(new File("build/cache/org1/mod1.2/ivy-2.0.xml").exists());
}
@Test
public void testExtraParams1() throws Exception {
String[] params = new String[] {"-settings", "test/repositories/ivysettings.xml", "-confs",
"default", "-ivy", "test/repositories/1/org1/mod1.1/ivys/ivy-1.0.xml", "foo1",
"foo2"};
String[] params = {
"-settings", "test/repositories/ivysettings.xml",
"-confs", "default",
"-ivy", "test/repositories/1/org1/mod1.1/ivys/ivy-1.0.xml",
"foo1", "foo2"
};
CommandLine line = Main.getParser().parse(params);
String[] leftOver = line.getLeftOverArgs();
assertNotNull(leftOver);
@ -120,9 +114,12 @@ public class MainTest {
@Test
public void testExtraParams2() throws Exception {
String[] params = new String[] {"-settings", "test/repositories/ivysettings.xml", "-confs",
"default", "-ivy", "test/repositories/1/org1/mod1.1/ivys/ivy-1.0.xml", "--",
"foo1", "foo2"};
String[] params = {
"-settings", "test/repositories/ivysettings.xml",
"-confs", "default",
"-ivy", "test/repositories/1/org1/mod1.1/ivys/ivy-1.0.xml",
"--", "foo1", "foo2"
};
CommandLine line = Main.getParser().parse(params);
String[] leftOver = line.getLeftOverArgs();
assertNotNull(leftOver);
@ -133,8 +130,11 @@ public class MainTest {
@Test
public void testExtraParams3() throws Exception {
String[] params = new String[] {"-settings", "test/repositories/ivysettings.xml", "-confs",
"default", "-ivy", "test/repositories/1/org1/mod1.1/ivys/ivy-1.0.xml"};
String[] params = {
"-settings", "test/repositories/ivysettings.xml",
"-confs", "default",
"-ivy", "test/repositories/1/org1/mod1.1/ivys/ivy-1.0.xml"
};
CommandLine line = Main.getParser().parse(params);
String[] leftOver = line.getLeftOverArgs();
assertNotNull(leftOver);
@ -146,7 +146,6 @@ public class MainTest {
* {@code types} argument to the command line must be parsed correctly when it's passed
* more than one value for the argument.
*
* @throws Exception if something goes wrong
* @see <a href="https://issues.apache.org/jira/browse/IVY-1355">IVY-1355</a>
*/
@Test
@ -165,8 +164,6 @@ public class MainTest {
/**
* Tests that the {@code overwriteMode} passed for the retrieve command works as expected
*
* @throws Exception if something goes wrong
*/
@Test
public void testRetrieveOverwriteMode() throws Exception {
@ -190,8 +187,6 @@ public class MainTest {
/**
* Tests that the {@code makepom} option works as expected
*
* @throws Exception if something goes wrong
*/
@Test
public void testMakePom() throws Exception {
@ -212,14 +207,12 @@ public class MainTest {
*/
@Test
public void testSettingsURL() throws Exception {
final URL settingsURL = new File("test/repositories/ivysettings.xml").toURI().toURL();
run(new String[] {"-settings", settingsURL.toString(), "-ivy",
"test/repositories/1/org1/mod1.1/ivys/ivy-1.0.xml"});
URL settingsURL = new File("test/repositories/ivysettings.xml").toURI().toURL();
run("-settings", settingsURL.toString(), "-ivy", "test/repositories/1/org1/mod1.1/ivys/ivy-1.0.xml");
assertTrue(new File("build/cache/org1/mod1.2/ivy-2.0.xml").exists());
}
private void run(String[] args) throws Exception {
private void run(String... args) throws Exception {
Main.run(Main.getParser(), args);
}
}

View File

@ -17,11 +17,6 @@
*/
package org.apache.ivy.ant;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.util.Arrays;
import java.util.Collections;
@ -29,16 +24,22 @@ import java.util.List;
import org.apache.ivy.TestHelper;
import org.apache.ivy.core.report.ArtifactDownloadReport;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Delete;
import org.apache.tools.ant.types.FileSet;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
public class IvyCacheFilesetTest {
@ -46,9 +47,6 @@ public class IvyCacheFilesetTest {
private Project project;
@Rule
public ExpectedException expExc = ExpectedException.none();
@Before
public void setUp() {
TestHelper.createCache();
@ -227,11 +225,10 @@ public class IvyCacheFilesetTest {
@Test
public void requireCommonBaseDirEmptyList() {
List<ArtifactDownloadReport> reports = Collections.emptyList();
// we expect a BuildException when we try to find a (non-existent) common base dir
// across file system roots
expExc.expect(BuildException.class);
List<ArtifactDownloadReport> reports = Collections.emptyList();
fileset.requireCommonBaseDir(reports);
assertThrows(BuildException.class, () -> fileset.requireCommonBaseDir(reports));
}
@Test
@ -241,14 +238,13 @@ public class IvyCacheFilesetTest {
// single file system root isn't what we are interested in, in this test method
return;
}
// we expect a BuildException when we try to find a (non-existent) common base dir
// across file system roots
expExc.expect(BuildException.class);
List<ArtifactDownloadReport> reports = Arrays.asList(
artifactDownloadReport(new File(fileSystemRoots[0], "a/b/c/d")),
artifactDownloadReport(new File(fileSystemRoots[1], "a/b/e/f"))
);
fileset.requireCommonBaseDir(reports);
);
// we expect a BuildException when we try to find a (non-existent) common base dir
// across file system roots
assertThrows(BuildException.class, () -> fileset.requireCommonBaseDir(reports));
}
@Test

View File

@ -17,20 +17,23 @@
*/
package org.apache.ivy.ant;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.io.File;
import org.apache.ivy.TestHelper;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
public class IvyCleanCacheTest {
private IvyCleanCache cleanCache;
private File cacheDir;
@ -41,9 +44,6 @@ public class IvyCleanCacheTest {
private File resolutionCache;
@Rule
public ExpectedException expExc = ExpectedException.none();
@Before
public void setUp() throws Exception {
Project p = TestHelper.newProject();
@ -106,10 +106,9 @@ public class IvyCleanCacheTest {
*/
@Test
public void testUnknownCache() {
expExc.expect(BuildException.class);
expExc.expectMessage("unknown cache 'yourcache'");
cleanCache.setResolution(false);
cleanCache.setCache("yourcache");
cleanCache.perform();
Exception exception = assertThrows(BuildException.class, () -> cleanCache.perform());
assertEquals("unknown cache 'yourcache'", exception.getMessage());
}
}

View File

@ -17,12 +17,6 @@
*/
package org.apache.ivy.ant;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.util.List;
@ -33,22 +27,27 @@ import org.apache.ivy.core.settings.IvySettings;
import org.apache.ivy.plugins.resolver.DependencyResolver;
import org.apache.ivy.plugins.resolver.IBiblioResolver;
import org.apache.ivy.plugins.resolver.IvyRepResolver;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.types.Reference;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
public class IvyConfigureTest {
private IvyConfigure configure;
private Project project;
@Rule
public ExpectedException expExc = ExpectedException.none();
@Before
public void setUp() {
project = TestHelper.newProject();
@ -278,10 +277,6 @@ public class IvyConfigureTest {
*/
@Test
public void testOverrideNotAllowed() {
expExc.expect(BuildException.class);
expExc.expectMessage("Overriding a previous definition of ivy:settings with the id '"
+ configure.getSettingsId() + "' is not allowed when using override='notallowed'.");
configure.setFile(new File("test/repositories/ivysettings.xml"));
configure.execute();
@ -293,7 +288,9 @@ public class IvyConfigureTest {
configure.setOverride("notallowed");
configure.setFile(new File("test/repositories/ivysettings.xml"));
configure.execute();
Exception exception = assertThrows(BuildException.class, () -> configure.execute());
assertEquals("Overriding a previous definition of ivy:settings with the id '"
+ configure.getSettingsId() + "' is not allowed when using override='notallowed'.", exception.getMessage());
}
/**
@ -301,18 +298,13 @@ public class IvyConfigureTest {
*/
@Test
public void testInvalidOverride() {
expExc.expect(IllegalArgumentException.class);
expExc.expectMessage("invalid override value 'unknown'. Valid values are "
+ "[true, false, notallowed]");
configure.setOverride("unknown");
Exception exception = assertThrows(IllegalArgumentException.class, () -> configure.setOverride("unknown"));
assertEquals("invalid override value 'unknown'. Valid values are [true, false, notallowed]", exception.getMessage());
}
/**
* Tests that if the Ivy settings file <code>include</code>s another file as
* <code>optional</code>, then the absence of that file doesn't lead to failures
*
* @throws Exception if something goes wrong
*/
@Test
public void testOptionalFileInclude() throws Exception {

View File

@ -22,9 +22,7 @@ import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import org.apache.ivy.TestHelper;
@ -120,8 +118,9 @@ public class IvyDeliverTest {
res.setProject(project);
res.execute();
deliver.setPubrevision("1.2");
deliver.setDeliverpattern("build/test/deliver/merge/ivy-[revision].xml");
deliver.setPubrevision("1.2");
deliver.setStatus("release");
deliver.execute();
// should have delivered the file to the specified destination
@ -140,10 +139,10 @@ public class IvyDeliverTest {
mergeLine = mergeLine.trim();
expectedLine = expectedLine.trim();
if (!mergeLine.startsWith("<info")) {
assertEquals("published descriptor matches at line[" + lineNo + "]",
expectedLine.trim(), mergeLine.trim());
if (mergeLine.startsWith("<info")) {
mergeLine = mergeLine.replaceFirst(" publication=\"\\d+\"", "");
}
assertEquals("published descriptor matches at line[" + lineNo + "]", expectedLine.trim(), mergeLine.trim());
++lineNo;
mergeLine = merged.readLine();
@ -396,6 +395,133 @@ public class IvyDeliverTest {
dds[0].getDependencyRevisionId());
}
/**
* Test case for IVY-1300.
*
* @throws Exception if something goes wrong
* @see <a href="https://issues.apache.org/jira/browse/IVY-1300">IVY-1300</a>
*/
@Test
public void testIVY1300() throws Exception {
project.setProperty("ivy.settings.file", "test/repositories/IVY-1300/ivysettings.xml");
project.setProperty("ivy.dep.file", "test/repositories/IVY-1300/assembly-ivy.xml");
IvyResolve res = new IvyResolve();
res.setValidate(false);
res.setProject(project);
res.execute();
deliver.setPubrevision("1");
deliver.setDeliverpattern("build/test/deliver/ivy-[revision].xml");
deliver.setStatus("release");
deliver.setValidate(false);
deliver.execute();
// verify that the dynamic revisions have been replaced by the resolved ones (before conflict resolution)
File deliveredIvyFile = new File("build/test/deliver/ivy-1.xml");
assertTrue(deliveredIvyFile.exists());
ModuleDescriptor md = XmlModuleDescriptorParser.getInstance().parseDescriptor(
new IvySettings(), deliveredIvyFile.toURI().toURL(), false);
DependencyDescriptor[] dds = md.getDependencies();
assertEquals(2, dds.length);
assertEquals(ModuleRevisionId.newInstance("myorg", "modA", "releasebranch", "1"),
dds[0].getDependencyRevisionId());
assertEquals(ModuleRevisionId.newInstance("myorg", "modB", "releasebranch", "1"),
dds[1].getDependencyRevisionId());
}
/**
* Test case for IVY-1485.
*
* @see <a href="https://issues.apache.org/jira/browse/IVY-1485">IVY-1485</a>
*/
@Test
public void testDeliverWithTransitiveDepsInDifferentConfs() throws Exception {
project.setProperty("ivy.settings.file", "test/repositories/IVY-1485/ivysettings.xml");
project.setProperty("ivy.dep.file", "test/repositories/IVY-1485/ivy-simple.xml");
IvyResolve res = new IvyResolve();
res.setValidate(false);
res.setProject(project);
res.execute();
deliver.setPubrevision("1");
deliver.setDeliverpattern("build/test/deliver/ivy-[revision].xml");
deliver.setStatus("release");
deliver.setValidate(false);
deliver.execute();
// now check that the transitive dependency didn't override the direct ones
File deliveredIvyFile = new File("build/test/deliver/ivy-1.xml");
assertTrue(deliveredIvyFile.exists());
ModuleDescriptor md = XmlModuleDescriptorParser.getInstance().parseDescriptor(
new IvySettings(), deliveredIvyFile.toURL(), false);
DependencyDescriptor[] dds = md.getDependencies();
assertEquals(2, dds.length);
assertEquals(ModuleRevisionId.newInstance("simple", "modA", "5"), dds[0].getDependencyRevisionId());
assertEquals(ModuleRevisionId.newInstance("simple", "modB", "1"), dds[1].getDependencyRevisionId());
}
/**
* Test case for IVY-1485.
*
* @see <a href="https://issues.apache.org/jira/browse/IVY-1485">IVY-1485</a>
*/
@Test
public void testDeliverWithTransitiveDepsInOverlappingConfsTransitiveNewer() throws Exception {
project.setProperty("ivy.settings.file", "test/repositories/IVY-1485/ivysettings.xml");
project.setProperty("ivy.dep.file", "test/repositories/IVY-1485/ivy-overlap-transitive-newer.xml");
IvyResolve res = new IvyResolve();
res.setValidate(false);
res.setProject(project);
res.execute();
deliver.setPubrevision("1");
deliver.setDeliverpattern("build/test/deliver/ivy-[revision].xml");
deliver.setStatus("release");
deliver.setValidate(false);
deliver.execute();
// now check that the transitive dependency didn't override the direct ones
File deliveredIvyFile = new File("build/test/deliver/ivy-1.xml");
assertTrue(deliveredIvyFile.exists());
ModuleDescriptor md = XmlModuleDescriptorParser.getInstance().parseDescriptor(
new IvySettings(), deliveredIvyFile.toURL(), false);
DependencyDescriptor[] dds = md.getDependencies();
assertEquals(2, dds.length);
assertEquals(ModuleRevisionId.newInstance("overlap-newer", "modA", "1"), dds[0].getDependencyRevisionId());
assertEquals(ModuleRevisionId.newInstance("overlap-newer", "modB", "1"), dds[1].getDependencyRevisionId());
}
/**
* Test case for IVY-1485.
*
* @see <a href="https://issues.apache.org/jira/browse/IVY-1485">IVY-1485</a>
*/
@Test
public void testDeliverWithTransitiveDepsInOverlappingConfsTransitiveOlder() throws Exception {
project.setProperty("ivy.settings.file", "test/repositories/IVY-1485/ivysettings.xml");
project.setProperty("ivy.dep.file", "test/repositories/IVY-1485/ivy-overlap-transitive-older.xml");
IvyResolve res = new IvyResolve();
res.setValidate(false);
res.setProject(project);
res.execute();
deliver.setPubrevision("1");
deliver.setDeliverpattern("build/test/deliver/ivy-[revision].xml");
deliver.setStatus("release");
deliver.setValidate(false);
deliver.execute();
// now check that the transitive dependency didn't override the direct ones
File deliveredIvyFile = new File("build/test/deliver/ivy-1.xml");
assertTrue(deliveredIvyFile.exists());
ModuleDescriptor md = XmlModuleDescriptorParser.getInstance().parseDescriptor(
new IvySettings(), deliveredIvyFile.toURL(), false);
DependencyDescriptor[] dds = md.getDependencies();
assertEquals(2, dds.length);
assertEquals(ModuleRevisionId.newInstance("overlap-older", "modA", "5"), dds[0].getDependencyRevisionId());
assertEquals(ModuleRevisionId.newInstance("overlap-older", "modB", "1"), dds[1].getDependencyRevisionId());
}
@Test
public void testWithDynEvicted() throws Exception {
project.setProperty("ivy.dep.file", "test/java/org/apache/ivy/ant/ivy-dyn-evicted.xml");
@ -418,27 +544,8 @@ public class IvyDeliverTest {
md.getModuleRevisionId());
DependencyDescriptor[] dds = md.getDependencies();
assertEquals(2, dds.length);
assertEquals(ModuleRevisionId.newInstance("org1", "mod1.2", "2.2"),
assertEquals(ModuleRevisionId.newInstance("org1", "mod1.2", "1.1"),
dds[0].getDependencyRevisionId());
IvyRetrieve ret = new IvyRetrieve();
ret.setProject(project);
ret.setPattern("build/test/retrieve/[artifact]-[revision].[ext]");
ret.execute();
File list = new File("build/test/retrieve");
String[] files = list.list();
HashSet<String> actualFileSet = new HashSet<>(Arrays.asList(files));
HashSet<String> expectedFileSet = new HashSet<>();
for (DependencyDescriptor dd : dds) {
String name = dd.getDependencyId().getName();
String rev = dd.getDependencyRevisionId().getRevision();
String ext = "jar";
String artifact = name + "-" + rev + "." + ext;
expectedFileSet.add(artifact);
}
assertEquals("Delivered Ivy descriptor inconsistent with retrieved artifacts",
expectedFileSet, actualFileSet);
}
/**
@ -470,28 +577,8 @@ public class IvyDeliverTest {
md.getModuleRevisionId());
DependencyDescriptor[] dds = md.getDependencies();
assertEquals(2, dds.length);
assertEquals(ModuleRevisionId.newInstance("org1", "mod1.2", "2.2"),
assertEquals(ModuleRevisionId.newInstance("org1", "mod1.2", "1.1"),
dds[1].getDependencyRevisionId());
IvyRetrieve ret = new IvyRetrieve();
ret.setProject(project);
ret.setPattern("build/test/retrieve/[artifact]-[revision].[ext]");
ret.execute();
File list = new File("build/test/retrieve");
String[] files = list.list();
HashSet<String> actualFileSet = new HashSet<>(Arrays.asList(files));
HashSet<String> expectedFileSet = new HashSet<>();
for (DependencyDescriptor dd : dds) {
String name = dd.getDependencyId().getName();
String rev = dd.getDependencyRevisionId().getRevision();
String ext = "jar";
String artifact = name + "-" + rev + "." + ext;
expectedFileSet.add(artifact);
}
assertEquals("Delivered Ivy descriptor inconsistent with retrieved artifacts",
expectedFileSet, actualFileSet);
list.delete();
}
@Test

View File

@ -28,21 +28,17 @@ import org.apache.tools.ant.Project;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThrows;
public class IvyDependencyUpdateCheckerTest extends AntTaskTestCase {
private IvyDependencyUpdateChecker dependencyUpdateChecker;
@Rule
public ExpectedException expExc = ExpectedException.none();
@Before
public void setUp() {
TestHelper.createCache();
@ -54,8 +50,8 @@ public class IvyDependencyUpdateCheckerTest extends AntTaskTestCase {
dependencyUpdateChecker.setProject(project);
}
@After
public void tearDown() {
@After
public void tearDown() {
TestHelper.cleanCache();
}
@ -137,8 +133,7 @@ public class IvyDependencyUpdateCheckerTest extends AntTaskTestCase {
*/
@Test(expected = BuildException.class)
public void testFailure() {
dependencyUpdateChecker
.setFile(new File("test/java/org/apache/ivy/ant/ivy-failure.xml"));
dependencyUpdateChecker.setFile(new File("test/java/org/apache/ivy/ant/ivy-failure.xml"));
dependencyUpdateChecker.execute();
}
@ -147,13 +142,10 @@ public class IvyDependencyUpdateCheckerTest extends AntTaskTestCase {
*/
@Test
public void testFailureWithMissingConfigurations() {
expExc.expect(BuildException.class);
expExc.expectMessage("unknown");
dependencyUpdateChecker
.setFile(new File("test/java/org/apache/ivy/ant/ivy-simple.xml"));
dependencyUpdateChecker.setFile(new File("test/java/org/apache/ivy/ant/ivy-simple.xml"));
dependencyUpdateChecker.setConf("default,unknown");
dependencyUpdateChecker.execute();
Exception exception = assertThrows(BuildException.class, () -> dependencyUpdateChecker.execute());
assertEquals("requested configuration not found in apache#resolve-simple;1.0: [ 'unknown' ]", exception.getCause().getMessage());
}
/**
@ -161,8 +153,7 @@ public class IvyDependencyUpdateCheckerTest extends AntTaskTestCase {
*/
@Test(expected = BuildException.class)
public void testFailureOnBadDependencyIvyFile() {
dependencyUpdateChecker.setFile(new File(
"test/java/org/apache/ivy/ant/ivy-failure2.xml"));
dependencyUpdateChecker.setFile(new File("test/java/org/apache/ivy/ant/ivy-failure2.xml"));
dependencyUpdateChecker.execute();
}
@ -171,15 +162,13 @@ public class IvyDependencyUpdateCheckerTest extends AntTaskTestCase {
*/
@Test(expected = BuildException.class)
public void testFailureOnBadStatusInDependencyIvyFile() {
dependencyUpdateChecker.setFile(new File(
"test/java/org/apache/ivy/ant/ivy-failure3.xml"));
dependencyUpdateChecker.setFile(new File("test/java/org/apache/ivy/ant/ivy-failure3.xml"));
dependencyUpdateChecker.execute();
}
@Test
public void testHaltOnFailure() {
dependencyUpdateChecker
.setFile(new File("test/java/org/apache/ivy/ant/ivy-failure.xml"));
dependencyUpdateChecker.setFile(new File("test/java/org/apache/ivy/ant/ivy-failure.xml"));
dependencyUpdateChecker.setHaltonfailure(false);
dependencyUpdateChecker.execute();
}
@ -190,10 +179,8 @@ public class IvyDependencyUpdateCheckerTest extends AntTaskTestCase {
dependencyUpdateChecker.setConf("*,!default");
dependencyUpdateChecker.execute();
// assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.1", "2.0"))
// .exists());
// assertFalse(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.0"))
// .exists());
// assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.1", "2.0")).exists());
// assertFalse(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.0")).exists());
assertLogContaining("Dependencies updates available :");
assertLogContaining("All dependencies are up to date");
@ -213,8 +200,7 @@ public class IvyDependencyUpdateCheckerTest extends AntTaskTestCase {
dependencyUpdateChecker.getProject().setProperty("ivy.dep.file", ivyFile.getAbsolutePath());
dependencyUpdateChecker.execute();
// assertTrue(getResolvedIvyFileInCache(
// ModuleRevisionId.newInstance("apache", "resolve-simple", "1.0")).exists());
// assertTrue(getResolvedIvyFileInCache(ModuleRevisionId.newInstance("apache", "resolve-simple", "1.0")).exists());
}
/**
@ -228,35 +214,58 @@ public class IvyDependencyUpdateCheckerTest extends AntTaskTestCase {
"test/java/org/apache/ivy/ant/ivy-simple.xml");
dependencyUpdateChecker.execute();
// assertTrue(getResolvedIvyFileInCache(
// ModuleRevisionId.newInstance("apache", "resolve-simple", "1.0")).exists());
// assertTrue(getResolvedIvyFileInCache(ModuleRevisionId.newInstance("apache", "resolve-simple", "1.0")).exists());
assertLogContaining("Dependencies updates available :");
assertLogContaining("org1#mod1.2\t2.0 -> 2.2");
}
/**
* Test case for IVY-1665.
*
* @see <a href="https://issues.apache.org/jira/browse/IVY-1665">IVY-1665</a>
*/
@Test
public void testLatestRelease() {
dependencyUpdateChecker.getProject().setProperty("ivy.settings.file", "test/repositories/IVY-1665/ivysettings.xml");
dependencyUpdateChecker.setRevisionToCheck("latest.release"); // exclude milestone (2.0-M1)
dependencyUpdateChecker.setOrganisation("bar");
dependencyUpdateChecker.setModule("foo");
dependencyUpdateChecker.setRevision("2.0-M1");
dependencyUpdateChecker.setInline(true);
dependencyUpdateChecker.execute();
assertLogNotContaining("bar#foo\t2.0-M1 -> 1.0");
// expect listing for 2.0 when it comes available
assertLogContaining("All dependencies are up to date");
}
@Test
public void testSimpleExtends() {
dependencyUpdateChecker.setFile(new File(
"test/java/org/apache/ivy/ant/ivy-extends-multiconf.xml"));
dependencyUpdateChecker.setFile(new File("test/java/org/apache/ivy/ant/ivy-extends-multiconf.xml"));
dependencyUpdateChecker.execute();
assertEquals("1", dependencyUpdateChecker.getProject().getProperty("ivy.parents.count"));
assertEquals("apache",
dependencyUpdateChecker.getProject().getProperty("ivy.parent[0].organisation"));
assertEquals("resolve-simple",
dependencyUpdateChecker.getProject().getProperty("ivy.parent[0].module"));
assertEquals("1.0",
dependencyUpdateChecker.getProject().getProperty("ivy.parent[0].revision"));
assertNull(dependencyUpdateChecker.getProject().getProperty("ivy.parent[0].branch"));
assertLogContaining("Dependencies updates available :");
Project project = dependencyUpdateChecker.getProject();
assertEquals("1", project.getProperty("ivy.parents.count"));
assertEquals("apache", project.getProperty("ivy.parent[0].organisation"));
assertEquals("resolve-simple", project.getProperty("ivy.parent[0].module"));
assertEquals("1.0", project.getProperty("ivy.parent[0].revision"));
assertNull(project.getProperty("ivy.parent[0].branch"));
assertLogContaining("Dependencies updates available");
// ivy-extends-multiconf.xml declares org1:mod1.1:1.1
assertLogContaining("org1#mod1.1\t1.1 -> 2.0");
assertLogContaining("org1#mod1.1\t1.0 -> 2.0");
assertLogContaining("org1#mod1.2\t2.1 -> 2.2");
assertLogContaining("org2#mod2.1\t0.3 -> 0.7");
// inherited from parent
// ivy-multiconf.xml declares org1:mod1.1:2.0 -- no update available
assertLogNotContaining("org1#mod1.1\t2.0");
// ivy-multiconf.xml declares org1:mod1.2:2.0
assertLogContaining("org1#mod1.2\t2.0 -> 2.2");
// ivy-extends-multiconf.xml declares org2:mod2.1:0.3
assertLogContaining("org2#mod2.1\t0.3 -> 0.7");
// org2:mod2.1:0.3 ivy.xml declares org1:mod1.1:1.0 -- but showTransitives is false
assertLogNotContaining("org1#mod1.1\t1.0 -> 2.0");
assertLogNotContaining("org1#mod1.1 (transitive)\t1.0 -> 2.0");
// org1:mod1.1:2.0 ivy.xml declares org1:mod1.2:2.1 -- it evicted direct dependency
assertLogNotContaining("org1#mod1.2\t2.1 -> 2.2");
assertLogNotContaining("org1#mod1.2 (transitive)\t2.1 -> 2.2");
}
}

View File

@ -39,23 +39,20 @@ import org.apache.tools.ant.taskdefs.Echo;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
public class IvyPublishTest {
private File cache;
private IvyPublish publish;
private Project project;
@Rule
public ExpectedException expExc = ExpectedException.none();
private File cache;
@Before
public void setUp() {
@ -405,8 +402,6 @@ public class IvyPublishTest {
*/
@Test
public void testHaltOnMissing() {
expExc.expect(BuildException.class);
expExc.expectMessage("missing artifact apache#resolve-simple;1.2!resolve-simple.jar");
project.setProperty("ivy.dep.file", "test/java/org/apache/ivy/ant/ivy-multiconf.xml");
IvyResolve res = new IvyResolve();
res.setProject(project);
@ -415,19 +410,16 @@ public class IvyPublishTest {
publish.setPubrevision("1.2");
publish.setResolver("1");
publish.setHaltonmissing(true);
try {
publish.execute();
} finally {
// should have delivered the ivy file
assertTrue(new File("build/test/publish/ivy-1.2.xml").exists());
// should not have published the files with "1" resolver
assertFalse(new File("test/repositories/1/apache/resolve-simple/ivys/ivy-1.2.xml")
.exists());
assertFalse(new File(
"test/repositories/1/apache/resolve-simple/jars/resolve-simple-1.2.jar")
.exists());
}
Exception exception = assertThrows(BuildException.class, () -> publish.execute());
assertEquals("missing artifact apache#resolve-simple;1.2!resolve-simple.jar", exception.getCause().getMessage());
// should have delivered the ivy file
assertTrue(new File("build/test/publish/ivy-1.2.xml").exists());
// should not have published the files with "1" resolver
assertFalse(new File("test/repositories/1/apache/resolve-simple/ivys/ivy-1.2.xml").exists());
assertFalse(new File("test/repositories/1/apache/resolve-simple/jars/resolve-simple-1.2.jar").exists());
}
/**
@ -437,8 +429,6 @@ public class IvyPublishTest {
*/
@Test
public void testHaltOnMissing2() throws IOException {
expExc.expect(BuildException.class);
expExc.expectMessage("missing artifact apache#multi;1.2!multi2.jar");
project.setProperty("ivy.dep.file", "test/java/org/apache/ivy/ant/ivy-publish-multi.xml");
IvyResolve res = new IvyResolve();
res.setProject(project);
@ -451,15 +441,15 @@ public class IvyPublishTest {
publish.setPubrevision("1.2");
publish.setResolver("transactional");
publish.setHaltonmissing(true);
try {
publish.execute();
} finally {
// should have delivered the ivy file
assertTrue(new File("build/test/publish/ivy-1.2.xml").exists());
// should not have published the files with "transactional" resolver
assertFalse(new File("build/test/transactional/apache/multi/1.2").exists());
}
Exception exception = assertThrows(BuildException.class, () -> publish.execute());
assertEquals("missing artifact apache#multi;1.2!multi2.jar", exception.getCause().getMessage());
// should have delivered the ivy file
assertTrue(new File("build/test/publish/ivy-1.2.xml").exists());
// should not have published the files with "transactional" resolver
assertFalse(new File("build/test/transactional/apache/multi/1.2").exists());
}
/**
@ -469,8 +459,6 @@ public class IvyPublishTest {
*/
@Test
public void testHaltOnMissing3() throws IOException {
expExc.expect(BuildException.class);
expExc.expectMessage("missing artifact apache#multi;1.2!multi2.jar");
project.setProperty("ivy.dep.file", "test/java/org/apache/ivy/ant/ivy-publish-multi.xml");
IvyResolve res = new IvyResolve();
res.setProject(project);
@ -483,15 +471,15 @@ public class IvyPublishTest {
publish.setPubrevision("1.2");
publish.setResolver("1");
publish.setHaltonmissing(true);
try {
publish.execute();
} finally {
// should have delivered the ivy file
assertTrue(new File("build/test/publish/ivy-1.2.xml").exists());
// should not have published the files with "transactional" resolver
assertFalse(new File("test/repositories/1/apache/multi").exists());
}
Exception exception = assertThrows(BuildException.class, () -> publish.execute());
assertEquals("missing artifact apache#multi;1.2!multi2.jar", exception.getCause().getMessage());
// should have delivered the ivy file
assertTrue(new File("build/test/publish/ivy-1.2.xml").exists());
// should not have published the files with "transactional" resolver
assertFalse(new File("test/repositories/1/apache/multi").exists());
}
@Test

View File

@ -31,24 +31,20 @@ import org.apache.tools.ant.taskdefs.Parallel;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
public class IvyResolveTest {
private Project project;
private IvyResolve resolve;
@Rule
public ExpectedException expExc = ExpectedException.none();
private Project project;
@Before
public void setUp() {
@ -324,12 +320,10 @@ public class IvyResolveTest {
@Test
public void testFailureWithMissingConfigurations() {
expExc.expect(BuildException.class);
expExc.expectMessage("unknown");
resolve.setFile(new File("test/java/org/apache/ivy/ant/ivy-simple.xml"));
resolve.setConf("default,unknown");
resolve.execute();
Exception exception = assertThrows(BuildException.class, () -> resolve.execute());
assertEquals("requested configuration not found in apache#resolve-simple;1.0: [ 'unknown' ]", exception.getCause().getMessage());
}
@Test(expected = BuildException.class)

View File

@ -15,13 +15,13 @@
"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.
under the License.
-->
<ivy-module version="2.0">
<ivy-module version="2.0">
<info organisation="apache" module="resolve-extends" revision="1.2" status="release">
<!-- <extends organisation="apache" module="resolve-simple" revision="1.0" location="./ivy-multiconf.xml"/> -->
<!-- description inherited from parent -->
<description>Demonstrates configuration-specific dependencies</description>
</info>
@ -31,22 +31,23 @@
<conf name="extra"/>
<!-- overrides conf in parent -->
<conf name="default" extends="compile" description="overrides the conf definition in parent descriptor"/>
<!-- configurations inherited from apache#resolve-simple;1.0 -->
<conf name="compile" visibility="public"/>
</configurations>
<publications/>
<dependencies>
<!-- not in parent -->
<dependency org="org2" name="mod2.1" rev="0.3" conf="default"/>
<!-- overrides parent -->
<dependency org="org1" name="mod1.1" rev="1.1" conf="default,compile->default" transitive="false"/>
<dependencies>
<!-- dependencies inherited from apache#resolve-simple;1.0 -->
<dependency org="org1" name="mod1.2" rev="2.0" conf="default->default"/>
<dependency org="org1" name="mod1.1" rev="2.0" transitive="false" conf="compile->default"/>
<!-- dependencies inherited end -->
<!-- not in parent -->
<dependency org="org2" name="mod2.1" rev="0.3" conf="default->compile(default)"/>
<!-- overrides parent -->
<dependency org="org1" name="mod1.1" rev="1.1" conf="default,compile->default" transitive="false"/>
</dependencies>
</ivy-module>
</ivy-module>

View File

@ -14,9 +14,9 @@
"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.
under the License.
-->
<ivy-module version="2.0">
<ivy-module version="2.0">
<info module="resolve-extends">
<extends organisation="apache" module="resolve-simple" revision="latest.integration" location="./ivy-multiconf.xml"/>
@ -33,9 +33,9 @@
<dependencies>
<!-- not in parent -->
<dependency org="org2" name="mod2.1" rev="0.3" conf="default" />
<dependency org="org2" name="mod2.1" rev="0.3" conf="default->compile(default)" />
<!-- overrides parent -->
<dependency org="org1" name="mod1.1" rev="1.1" conf="default,compile->default" transitive="false" />
</dependencies>
</ivy-module>
</ivy-module>

View File

@ -17,79 +17,35 @@
*/
package org.apache.ivy.core.deliver;
import org.apache.ivy.TestHelper;
import org.apache.ivy.ant.IvyDeliver;
import org.apache.ivy.ant.IvyResolve;
import org.apache.ivy.util.FileUtil;
import org.apache.tools.ant.Project;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.net.URI;
import static org.junit.Assert.assertFalse;
import org.apache.ivy.TestHelper;
import org.apache.ivy.ant.IvyDeliver;
import org.apache.ivy.ant.IvyResolve;
import org.apache.ivy.util.FileUtil;
import org.apache.commons.io.FileUtils;
import org.apache.tools.ant.Project;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertTrue;
public class DeliverTest {
private File cache;
private File cacheDir;
private File deliverDir;
private IvyDeliver ivyDeliver;
@Before
public void setUp() {
cache = new File("build/cache");
System.setProperty("ivy.cache.dir", cache.getAbsolutePath());
createCache();
deliverDir = new File("build/test/deliver");
deliverDir.mkdirs();
Project project = TestHelper.newProject();
project.init();
ivyDeliver = new IvyDeliver();
ivyDeliver.setProject(project);
ivyDeliver.setDeliverpattern(deliverDir.getAbsolutePath()
+ "/[type]s/[artifact]-[revision](-[classifier]).[ext]");
}
@After
public void tearDown() {
FileUtil.forceDelete(cache);
FileUtil.forceDelete(deliverDir);
}
private void createCache() {
cache.mkdirs();
}
/**
* Test case for IVY-1111.
*
* @throws Exception if something goes wrong
* @see <a href="https://issues.apache.org/jira/browse/IVY-1111">IVY-1111</a>
*/
@Test
public void testIVY1111() throws Exception {
Project project = ivyDeliver.getProject();
project.setProperty("ivy.settings.file", "test/repositories/IVY-1111/ivysettings.xml");
File ivyFile = new File(new URI(DeliverTest.class.getResource("ivy-1111.xml").toString()));
resolve(ivyFile);
ivyDeliver.setReplacedynamicrev(true);
ivyDeliver.doExecute();
String deliverContent = readFile(deliverDir.getAbsolutePath() + "/ivys/ivy-1.0.xml");
assertFalse(deliverContent.contains("rev=\"latest.integration\""));
assertTrue(deliverContent.contains("name=\"b\" rev=\"1.5\""));
cacheDir.mkdirs();
}
private void resolve(File ivyFile) {
@ -101,16 +57,150 @@ public class DeliverTest {
private String readFile(String fileName) throws IOException {
StringBuilder retval = new StringBuilder();
File ivyFile = new File(fileName);
BufferedReader reader = new BufferedReader(new FileReader(ivyFile));
String line = null;
while ((line = reader.readLine()) != null) {
retval.append(line).append("\n");
File file = new File(fileName);
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
String line = null;
while ((line = reader.readLine()) != null) {
retval.append(line).append("\n");
}
}
reader.close();
return retval.toString();
}
private File writeFile(String fileText) throws IOException {
File file = File.createTempFile("ivy", ".xml");
file.deleteOnExit();
FileUtils.write(file, fileText, "UTF-8");
return file;
}
@Before
public void setUp() {
cacheDir = new File("build/cache");
System.setProperty("ivy.cache.dir", cacheDir.getAbsolutePath());
createCache();
deliverDir = new File("build/test/deliver");
deliverDir.mkdirs();
Project project = TestHelper.newProject();
project.init();
ivyDeliver = new IvyDeliver();
ivyDeliver.setProject(project);
ivyDeliver.setDeliverpattern(deliverDir.getAbsolutePath() + "/[type]s/[artifact]-[revision](-[classifier]).[ext]");
}
@After
public void tearDown() {
FileUtil.forceDelete(cacheDir);
FileUtil.forceDelete(deliverDir);
}
/**
* Test case for <a href="https://issues.apache.org/jira/browse/IVY-1111">IVY-1111</a>.
*/
@Test
public void testDeliver1111() throws Exception {
ivyDeliver.getProject().setProperty("ivy.settings.file", "test/repositories/IVY-1111/ivysettings.xml");
String ivyFile
= "<ivy-module version='1.0' xmlns:e='http://ant.apache.org/ivy/extra'>\n"
+ " <info organisation='apache' module='IVY-1111' revision='1.0' e:att='att'/>\n"
+ " <dependencies>\n"
+ " <dependency org='test' name='a' rev='latest.integration'/>\n"
+ " <dependency org='test' name='b' rev='latest.integration' e:att='att'/>\n"
+ " <dependency org='junit' name='junit' rev='latest.integration'/>\n"
+ " </dependencies>\n"
+ "</ivy-module>\n";
resolve(writeFile(ivyFile));
ivyDeliver.setReplacedynamicrev(true);
ivyDeliver.doExecute();
ivyFile = readFile(deliverDir.getAbsolutePath() + "/ivys/ivy-1.0.xml");
assertTrue(ivyFile.contains("org=\"test\" name=\"a\" rev=\"1\" revConstraint=\"latest.integration\""));
assertTrue(ivyFile.contains("org=\"test\" name=\"b\" rev=\"1.5\" revConstraint=\"latest.integration\" e:att=\"att\""));
assertTrue(ivyFile.contains("org=\"junit\" name=\"junit\" rev=\"4.4\" revConstraint=\"latest.integration\""));
}
/**
* Test case for <a href="https://issues.apache.org/jira/browse/IVY-1410">IVY-1410</a>.
*/
@Test
public void testDeliver1410() throws Exception {
ivyDeliver.getProject().setProperty("ivy.settings.file", "test/repositories/ivysettings-1.xml");
String ivyFile
= "<ivy-module version='2.0'>\n"
+ " <info organisation='org' module='xxx'/>\n"
+ " <dependencies>\n"
+ " <dependency org='org1' name='mod1.1' rev='1.+'/>\n"
+ " </dependencies>\n"
+ "</ivy-module>\n";
ivyFile
= "<ivy-module version='2.0'>\n"
+ " <info organisation='org' module='yyy' revision='1.0'>\n"
+ " <extends organisation='org' module='xxx' extendType='dependencies'\n"
+ " location='" + writeFile(ivyFile).getName() + "' revision='latest'/>\n"
+ " </info>\n"
+ " <dependencies>\n"
+ " <dependency org='org2' name='mod2.1' rev='0.+'/>\n"
+ " </dependencies>\n"
+ "</ivy-module>\n";
resolve(writeFile(ivyFile));
ivyDeliver.setReplacedynamicrev(true);
ivyDeliver.doExecute();
ivyFile = readFile(deliverDir.getAbsolutePath() + "/ivys/ivy-1.0.xml");
assertTrue(ivyFile.contains("org=\"org1\" name=\"mod1.1\" rev=\"1.1\""));
assertTrue(ivyFile.contains("org=\"org2\" name=\"mod2.1\" rev=\"0.7\""));
}
/**
* Test case for <a href="https://issues.apache.org/jira/browse/IVY-1658">IVY-1658</a>.
*/
@Test
public void testDeliver1658() throws Exception {
String ivyFile
= "<ivy-module version='2.0'\n"
+ " xmlns:m='http://ant.apache.org/ivy/maven'\n"
+ " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'\n"
+ " xsi:noNamespaceSchemaLocation='http://ant.apache.org/ivy/schemas/ivy.xsd'>\n"
+ " <info module='xxx' organisation='zzz'/>\n"
+ " <dependencies>\n"
+ " <dependency name='groovy' org='org.codehaus.groovy' rev='3.0.25' transitive='false'>\n"
+ " <artifact name='groovy' m:classifier='indy'/>\n"
+ " </dependency>\n"
+ " </dependencies>\n"
+ "</ivy-module>\n";
ivyFile
= "<ivy-module version='2.0'\n"
+ " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'\n"
+ " xsi:noNamespaceSchemaLocation='http://ant.apache.org/ivy/schemas/ivy.xsd'>\n"
+ " <info module='yyy' organisation='zzz' revision='1.0'>\n"
+ " <extends module='xxx' organisation='zzz' extendType='dependencies'\n"
+ " location='" + writeFile(ivyFile).getName() + "' revision='latest'/>\n"
+ " </info>\n"
+ " <dependencies>\n"
+ " </dependencies>\n"
+ "</ivy-module>\n";
resolve(writeFile(ivyFile));
ivyDeliver.doExecute();
ivyFile = readFile(deliverDir.getAbsolutePath() + "/ivys/ivy-1.0.xml");
assertTrue(ivyFile.contains(" version=\"2.0\""));
assertTrue(ivyFile.contains(" xmlns:m=\"http://ant.apache.org/ivy/maven\""));
assertTrue(ivyFile.contains(" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""));
assertTrue(ivyFile.contains(" xsi:noNamespaceSchemaLocation=\"http://ant.apache.org/ivy/schemas/ivy.xsd\""));
}
}

View File

@ -83,6 +83,32 @@ public class InstallTest {
assertTrue(new File("build/test/install/org.apache/test/test-1.0.pom").exists());
}
@Test
public void testMavenParent() throws Exception {
Ivy ivy = Ivy.newInstance();
ivy.configure(new File("test/repositories/ivysettings.xml"));
@SuppressWarnings("unused")
ResolveReport rr = ivy.install(ModuleRevisionId.newInstance("org.apache", "test-parent", "1.0"),
ivy.getSettings().getDefaultResolver().getName(), "install", new InstallOptions());
assertTrue(new File("build/test/install/org.apache/test-parent/ivy-1.0.xml").exists());
assertTrue(new File("build/test/install/org.apache/test-parent/test-parent-1.0.jar").exists());
}
@Test
public void testMavenParentWithoutDefaultResolver() throws Exception {
Ivy ivy = Ivy.newInstance();
ivy.configure(new File("test/repositories/ivysettings-nodefaultresolver.xml"));
@SuppressWarnings("unused")
ResolveReport rr = ivy.install(ModuleRevisionId.newInstance("org.apache", "test-parent", "1.0"),
"test", "install", new InstallOptions());
assertTrue(new File("build/test/install/org.apache/test-parent/ivy-1.0.xml").exists());
assertTrue(new File("build/test/install/org.apache/test-parent/test-parent-1.0.jar").exists());
}
@Test
public void testNoValidate() throws Exception {
Ivy ivy = Ivy.newInstance();

View File

@ -15,15 +15,10 @@
* limitations under the License.
*
*/
package org.apache.ivy.core.module.descriptor;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
@ -32,59 +27,61 @@ import javax.xml.xpath.XPathConstants;
import org.apache.ivy.TestHelper;
import org.apache.ivy.ant.IvyMakePom;
import org.apache.ivy.util.TestXmlHelper;
import org.apache.tools.ant.Project;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import static org.apache.commons.io.FileUtils.readFileToString;
import static org.apache.commons.io.FileUtils.writeLines;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
/**
* Tests {@link IvyMakePom}
* Tests {@link IvyMakePom}.
*/
public class IvyMakePomTest {
private Project project;
private Project project = TestHelper.newProject();
@Rule
public TemporaryFolder workdir = new TemporaryFolder();
@Before
public void beforeTest() {
this.project = TestHelper.newProject();
}
/**
* Test case for IVY-1528. An Ivy file containing a <code>classifier</code> extra attribute in
* its dependency, must retain the <code>classifier</code> in the generated POM when converted
* to a POM file through {@link IvyMakePom}.
*
* @throws Exception if something goes wrong
* @see <a href="https://issues.apache.org/jira/browse/IVY-1528">IVY-1528</a>
* Test case for <a href="https://issues.apache.org/jira/browse/IVY-1528">IVY-1528</a>.
* <p>
* An Ivy file containing a <code>classifier</code> extra attribute in its
* dependency, must retain the <code>classifier</code> in the generated POM
* when converted to a POM file through {@link IvyMakePom}.
*/
@Test
public void testClassifier() throws Exception {
final File ivyFile = new File(IvyMakePomTest.class.getResource("ivy-to-pom-classifier.xml").toURI());
File ivyFile = new File(IvyMakePomTest.class.getResource("ivy-to-pom-classifier.xml").toURI());
assertTrue(ivyFile + " is either missing or not a file", ivyFile.isFile());
final IvyMakePom makepom = new IvyMakePom();
makepom.setProject(project);
final File generatedPomFile = workdir.newFile("test-ivy-to-pom-classifier.pom");
makepom.setPomFile(generatedPomFile);
makepom.setIvyFile(ivyFile);
// run the task
makepom.execute();
File pomFile = workdir.newFile("test-ivy-to-pom-classifier.pom");
// read the generated pom
final NodeList dependencies = (NodeList) TestXmlHelper.evaluateXPathExpr(generatedPomFile, "/project/dependencies/dependency", XPathConstants.NODESET);
IvyMakePom task = new IvyMakePom();
task.setIvyFile(ivyFile);
task.setPomFile(pomFile);
task.setProject(project);
task.execute();
NodeList dependencies = (NodeList) TestXmlHelper.evaluateXPathExpr(pomFile, "/project/dependencies/dependency", XPathConstants.NODESET);
assertNotNull("Dependencies element wasn't found in the generated POM file", dependencies);
assertEquals("Unexpected number of dependencies in the generated POM file", 2, dependencies.getLength());
final Set<String> expectedPomArtifactIds = new HashSet<>();
Set<String> expectedPomArtifactIds = new HashSet<>();
expectedPomArtifactIds.add("foo");
expectedPomArtifactIds.add("bar");
for (int i = 0; i < dependencies.getLength(); i++) {
final PomDependency pomDependency = PomDependency.parse(dependencies.item(i));
PomDependency pomDependency = PomDependency.parse(dependencies.item(i));
assertNotNull("Dependency generated was null", pomDependency);
assertTrue("Unexpected dependency " + pomDependency, expectedPomArtifactIds.contains(pomDependency.artifactId));
// we no longer expect this, so remove it
@ -103,6 +100,408 @@ public class IvyMakePomTest {
assertTrue("Some expected dependencies " + expectedPomArtifactIds + " were not found in the generated POM file", expectedPomArtifactIds.isEmpty());
}
/**
* Test case for <a href="https://issues.apache.org/jira/browse/IVY-1653">IVY-1653</a>.
*/
@Test
public void testMakePom1653() throws Exception {
File ivyFile = workdir.newFile("ivy-1653.xml");
writeLines(ivyFile, "UTF-8", Arrays.asList(
"<ivy-module version='2.0'>",
" <info module='name' organisation='org' revision='1.0.0-SNAPSHOT' />",
" <configurations>",
" <conf name='default' />",
" </configurations>",
" <dependencies defaultconf='default' defaultconfmapping='*->master,runtime()'>",
" <dependency org='org.springframework' name='spring-aop' rev='6.2.9' />",
" <override org='org.aspectj' module='aspectjrt' rev='1.9.24' />",
" </dependencies>",
"</ivy-module>"
));
File pomFile = workdir.newFile("ivy-1653.pom");
IvyMakePom task = new IvyMakePom();
task.setIvyFile(ivyFile);
task.setPomFile(pomFile);
task.setPrintIvyInfo(false);
task.setProject(project);
IvyMakePom.Mapping mapping = task.createMapping();
mapping.setConf("default");
mapping.setScope("compile");
task.execute();
String[] expect = {
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>",
"<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</groupId>",
" <artifactId>name</artifactId>",
" <packaging>jar</packaging>",
" <version>1.0.0-SNAPSHOT</version>",
" <dependencyManagement>",
" <dependencies>",
" <dependency>",
" <groupId>org.aspectj</groupId>",
" <artifactId>aspectjrt</artifactId>",
" <version>1.9.24</version>",
" </dependency>",
" </dependencies>",
" </dependencyManagement>",
" <dependencies>",
" <dependency>",
" <groupId>org.springframework</groupId>",
" <artifactId>spring-aop</artifactId>",
" <version>6.2.9</version>",
" <scope>compile</scope>",
" </dependency>",
" </dependencies>",
"</project>",
""
};
assertEquals(String.join(System.lineSeparator(), expect), readFileToString(pomFile, "UTF-8"));
}
@Test
public void testMakePomWithTemplate() throws Exception {
File ivyFile = workdir.newFile("ivy.xml");
writeLines(ivyFile, "UTF-8", Arrays.asList(
"<ivy-module version='2.0'>",
" <info module='name' organisation='org' revision='1.0.0-SNAPSHOT' />",
" <configurations>",
" <conf name='default' />",
" </configurations>",
" <dependencies defaultconf='default' defaultconfmapping='*->master,runtime()'>",
" <dependency org='org.springframework' name='spring-aop' rev='6.2.9' />",
" </dependencies>",
"</ivy-module>"
));
File pomFile = workdir.newFile("ivy.pom");
File templateFile = workdir.newFile("the.pom");
writeLines(templateFile, "UTF-8", Arrays.asList(
"<project>",
" <groupId>${ivy.pom.groupId}</groupId>",
" <artifactId>${ivy.pom.artifactId}</artifactId>",
" <version>${ivy.pom.version}</version>",
" <dependencies>",
" <dependency>",
" <groupId>org.springframework</groupId>",
" <artifactId>spring-core</artifactId>",
" <version>6.2.9</version>",
" <scope>compile</scope>",
" </dependency>",
" </dependencies>",
"</project>"
));
IvyMakePom task = new IvyMakePom();
task.setIvyFile(ivyFile);
task.setPomFile(pomFile);
task.setPrintIvyInfo(false);
task.setProject(project);
task.setTemplateFile(templateFile);
IvyMakePom.Mapping mapping = task.createMapping();
mapping.setConf("default");
mapping.setScope("compile");
task.execute();
String[] expect = {
"<project>",
" <groupId>org</groupId>",
" <artifactId>name</artifactId>",
" <version>1.0.0-SNAPSHOT</version>",
" <dependencies>",
" <dependency>",
" <groupId>org.springframework</groupId>",
" <artifactId>spring-core</artifactId>",
" <version>6.2.9</version>",
" <scope>compile</scope>",
" </dependency>",
" <dependency>",
" <groupId>org.springframework</groupId>",
" <artifactId>spring-aop</artifactId>",
" <version>6.2.9</version>",
" <scope>compile</scope>",
" </dependency>",
" </dependencies>",
"</project>",
""
};
assertEquals(String.join(System.lineSeparator(), expect), readFileToString(pomFile, "UTF-8"));
}
/**
* Test case for <a href="https://issues.apache.org/jira/browse/IVY-1653">IVY-1653</a>.
*/
@Test
public void testMakePomWithTemplate1653() throws Exception {
File ivyFile = workdir.newFile("ivy.xml");
writeLines(ivyFile, "UTF-8", Arrays.asList(
"<ivy-module version='2.0'>",
" <info module='name' organisation='org' revision='1.0.0-SNAPSHOT' />",
" <configurations>",
" <conf name='default' />",
" </configurations>",
" <dependencies defaultconf='default' defaultconfmapping='*->master,runtime()'>",
" <dependency org='org.springframework' name='spring-aop' rev='6.2.9' />",
" <override org='org.springframework' module='spring-core' rev='6.2.19' />",
" </dependencies>",
"</ivy-module>"
));
File pomFile = workdir.newFile("ivy.pom");
File templateFile = workdir.newFile("the.pom");
writeLines(templateFile, "UTF-8", Arrays.asList(
"<project>",
" <groupId>${ivy.pom.groupId}</groupId>",
" <artifactId>${ivy.pom.artifactId}</artifactId>",
" <version>${ivy.pom.version}</version>",
" <dependencyManagement>",
" <dependencies>",
" <dependency>",
" <groupId>org.aspectj</groupId>",
" <artifactId>aspectjrt</artifactId>",
" <version>1.9.24</version>",
" </dependency>",
" </dependencies>",
" </dependencyManagement>",
"</project>"
));
IvyMakePom task = new IvyMakePom();
task.setIvyFile(ivyFile);
task.setPomFile(pomFile);
task.setPrintIvyInfo(false);
task.setProject(project);
task.setTemplateFile(templateFile);
IvyMakePom.Mapping mapping = task.createMapping();
mapping.setConf("default");
mapping.setScope("compile");
task.execute();
String[] expect = {
"<project>",
" <groupId>org</groupId>",
" <artifactId>name</artifactId>",
" <version>1.0.0-SNAPSHOT</version>",
" <dependencyManagement>",
" <dependencies>",
" <dependency>",
" <groupId>org.aspectj</groupId>",
" <artifactId>aspectjrt</artifactId>",
" <version>1.9.24</version>",
" </dependency>",
" <dependency>",
" <groupId>org.springframework</groupId>",
" <artifactId>spring-core</artifactId>",
" <version>6.2.19</version>",
" </dependency>",
" </dependencies>",
" </dependencyManagement>",
" <dependencies>",
" <dependency>",
" <groupId>org.springframework</groupId>",
" <artifactId>spring-aop</artifactId>",
" <version>6.2.9</version>",
" <scope>compile</scope>",
" </dependency>",
" </dependencies>",
"</project>",
""
};
assertEquals(String.join(System.lineSeparator(), expect), readFileToString(pomFile, "UTF-8"));
}
/**
* Test case for <a href="https://issues.apache.org/jira/browse/IVY-1667">IVY-1667</a>.
*/
@Test
public void testMakePomWithTemplate1667() throws Exception {
File ivyFile = workdir.newFile("ivy.xml");
writeLines(ivyFile, "UTF-8", Arrays.asList(
"<ivy-module version='2.0'>",
" <info module='name' organisation='org' revision='1.0.0-SNAPSHOT' />",
" <configurations>",
" <conf name='default' />",
" </configurations>",
" <dependencies defaultconf='default' defaultconfmapping='*->master,runtime()'>",
" <dependency org='org.springframework' name='spring-aop' rev='6.2.9' />",
" </dependencies>",
"</ivy-module>"
));
File pomFile = workdir.newFile("ivy.pom");
File templateFile = workdir.newFile("the.pom");
writeLines(templateFile, "UTF-8", Arrays.asList(
"<project>",
" <groupId>${ivy.pom.groupId}</groupId>",
" <artifactId>${ivy.pom.artifactId}</artifactId>",
" <version>${ivy.pom.version}</version>",
" <dependencyManagement>",
" <dependencies>",
" <dependency>",
" <groupId>org.aspectj</groupId>",
" <artifactId>aspectjrt</artifactId>",
" <version>1.9.24</version>",
" </dependency>",
" </dependencies>",
" </dependencyManagement>",
"</project>"
));
IvyMakePom task = new IvyMakePom();
task.setIvyFile(ivyFile);
task.setPomFile(pomFile);
task.setPrintIvyInfo(false);
task.setProject(project);
task.setTemplateFile(templateFile);
IvyMakePom.Mapping mapping = task.createMapping();
mapping.setConf("default");
mapping.setScope("compile");
task.execute();
String[] expect = {
"<project>",
" <groupId>org</groupId>",
" <artifactId>name</artifactId>",
" <version>1.0.0-SNAPSHOT</version>",
" <dependencyManagement>",
" <dependencies>",
" <dependency>",
" <groupId>org.aspectj</groupId>",
" <artifactId>aspectjrt</artifactId>",
" <version>1.9.24</version>",
" </dependency>",
" </dependencies>",
" </dependencyManagement>",
" <dependencies>",
" <dependency>",
" <groupId>org.springframework</groupId>",
" <artifactId>spring-aop</artifactId>",
" <version>6.2.9</version>",
" <scope>compile</scope>",
" </dependency>",
" </dependencies>",
"</project>",
""
};
assertEquals(String.join(System.lineSeparator(), expect), readFileToString(pomFile, "UTF-8"));
}
/**
* Test case for <a href="https://issues.apache.org/jira/browse/IVY-1667">IVY-1667</a>.
*/
@Test
public void testMakePomWithTemplate1667_2() throws Exception {
File ivyFile = workdir.newFile("ivy.xml");
writeLines(ivyFile, "UTF-8", Arrays.asList(
"<ivy-module version='2.0'>",
" <info module='name' organisation='org' revision='1.0.0-SNAPSHOT' />",
" <configurations>",
" <conf name='default' />",
" </configurations>",
" <dependencies defaultconf='default' defaultconfmapping='*->master,runtime()'>",
" <dependency org='org.springframework' name='spring-core' rev='6.2.9' />",
" </dependencies>",
"</ivy-module>"
));
File pomFile = workdir.newFile("ivy.pom");
File templateFile = workdir.newFile("the.pom");
writeLines(templateFile, "UTF-8", Arrays.asList(
"<project>",
" <groupId>${ivy.pom.groupId}</groupId>",
" <artifactId>${ivy.pom.artifactId}</artifactId>",
" <version>${ivy.pom.version}</version>",
" <dependencyManagement>",
" <dependencies>",
" <dependency>",
" <groupId>org.aspectj</groupId>",
" <artifactId>aspectjrt</artifactId>",
" <version>1.9.24</version>",
" </dependency>",
" </dependencies>",
" </dependencyManagement>",
" <dependencies>",
" <dependency>",
" <groupId>org.springframework</groupId>",
" <artifactId>spring-aop</artifactId>",
" <version>6.2.9</version>",
" <scope>compile</scope>",
" </dependency>",
" </dependencies>",
"</project>"
));
IvyMakePom task = new IvyMakePom();
task.setIvyFile(ivyFile);
task.setPomFile(pomFile);
task.setPrintIvyInfo(false);
task.setProject(project);
task.setTemplateFile(templateFile);
IvyMakePom.Mapping mapping = task.createMapping();
mapping.setConf("default");
mapping.setScope("compile");
task.execute();
String[] expect = {
"<project>",
" <groupId>org</groupId>",
" <artifactId>name</artifactId>",
" <version>1.0.0-SNAPSHOT</version>",
" <dependencyManagement>",
" <dependencies>",
" <dependency>",
" <groupId>org.aspectj</groupId>",
" <artifactId>aspectjrt</artifactId>",
" <version>1.9.24</version>",
" </dependency>",
" </dependencies>",
" </dependencyManagement>",
" <dependencies>",
" <dependency>",
" <groupId>org.springframework</groupId>",
" <artifactId>spring-aop</artifactId>",
" <version>6.2.9</version>",
" <scope>compile</scope>",
" </dependency>",
" <dependency>",
" <groupId>org.springframework</groupId>",
" <artifactId>spring-core</artifactId>",
" <version>6.2.9</version>",
" <scope>compile</scope>",
" </dependency>",
" </dependencies>",
"</project>",
""
};
assertEquals(String.join(System.lineSeparator(), expect), readFileToString(pomFile, "UTF-8"));
}
//--------------------------------------------------------------------------
private static final class PomDependency {
private final String groupId;
private final String artifactId;

View File

@ -17,20 +17,17 @@
*/
package org.apache.ivy.core.module.id;
import static org.junit.Assert.assertEquals;
import java.util.HashMap;
import java.util.Map;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
public class ModuleRevisionIdTest {
@Rule
public ExpectedException expExc = ExpectedException.none();
@Test
public void testParse() {
testParse("#A;1.0");
@ -67,10 +64,8 @@ public class ModuleRevisionIdTest {
}
private void testParseFailure(String mrid) {
expExc.expect(IllegalArgumentException.class);
expExc.expectMessage(mrid);
ModuleRevisionId.parse(mrid);
Exception exception = assertThrows(IllegalArgumentException.class, () -> ModuleRevisionId.parse(mrid));
assertTrue(exception.getMessage().contains(mrid));
}
@Test
@ -91,10 +86,14 @@ public class ModuleRevisionIdTest {
testEncodeDecodeToString(
ModuleRevisionId.newInstance("org/apache", "pre/name", "1.0-dev8/2", extraAttributes));
String encoded = ModuleRevisionId.newInstance("org/apache", "pre/name", "1.0-dev8/2", extraAttributes).encodeToString();
// We expect the encoding/ordering to be stable for reproducibility.
// If necessary this may vary across Ivy versions,
// but ideally only intentionally.
assertEquals("+att.name:#@#:+att.value:#@#:+att/name:#@#:+att/value:#@#:+att<name:#@#:+att<value:#@#:+branch:#@#:+@#:NULL:#@:#@#:+extra:#@#:+extravalue:#@#:+module:#@#:+pre/name:#@#:+nullatt:#@#:+@#:NULL:#@:#@#:+organisation:#@#:+org/apache:#@#:+revision:#@#:+1.0-dev8/2:#@#:", encoded);
}
private void testEncodeDecodeToString(ModuleRevisionId mrid) {
assertEquals(mrid, ModuleRevisionId.decode(mrid.encodeToString()));
}
}

View File

@ -17,6 +17,26 @@
*/
package org.apache.ivy.core.resolve;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.apache.ivy.Ivy;
import org.apache.ivy.TestHelper;
import org.apache.ivy.core.cache.ArtifactOrigin;
@ -52,56 +72,28 @@ import org.apache.ivy.util.CacheCleaner;
import org.apache.ivy.util.FileUtil;
import org.apache.ivy.util.MockMessageLogger;
import org.apache.ivy.util.XMLHelper;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.xml.sax.Attributes;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import static org.apache.ivy.util.StringUtils.joinArray;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
/**
*
*/
public class ResolveTest {
public final class ResolveTest {
private Ivy ivy;
private File cache;
private File deliverDir;
private File workDir;
@Rule
public ExpectedException expExc = ExpectedException.none();
private File cache, workDir, deliverDir;
@Before
public void setUp() throws Exception {
@ -746,29 +738,22 @@ public class ResolveTest {
// set up repository
FileUtil.forceDelete(new File("build/testCache2"));
FileUtil.copy(new File("test/repositories/1/org1/mod1.2/jars/mod1.2-2.0.jar"), new File(
"build/testCache2/mod1.2-1.5.jar"), null);
FileUtil.copy(new File("test/repositories/1/org1/mod1.2/jars/mod1.2-2.0.jar"), new File("build/testCache2/mod1.2-1.5.jar"), null);
// we first do a simple resolve so that module is in cache
ResolveReport report = ivy.resolve(new File(
"test/repositories/1/org1/mod1.4/ivys/ivy-1.0.2.xml"),
getResolveOptions(new String[] {"*"}));
ResolveReport report = ivy.resolve(new File("test/repositories/1/org1/mod1.4/ivys/ivy-1.0.2.xml"), getResolveOptions(new String[] {"*"}));
assertFalse(report.hasError());
assertEquals(Collections.singleton(ModuleRevisionId.newInstance("org1", "mod1.2", "1.5")),
report.getConfigurationReport("default").getModuleRevisionIds());
assertEquals(Collections.singleton(ModuleRevisionId.newInstance("org1", "mod1.2", "1.5")), report.getConfigurationReport("default").getModuleRevisionIds());
// now we update the repository
FileUtil.copy(new File("test/repositories/1/org1/mod1.2/jars/mod1.2-2.0.jar"), new File(
"build/testCache2/mod1.2-1.6.jar"), null);
FileUtil.copy(new File("test/repositories/1/org1/mod1.2/jars/mod1.2-2.0.jar"), new File("build/testCache2/mod1.2-1.6.jar"), null);
// now do a new resolve: it should not use cached data
report = ivy.resolve(new File("test/repositories/1/org1/mod1.4/ivys/ivy-1.0.2.xml"),
getResolveOptions(new String[] {"*"}));
report = ivy.resolve(new File("test/repositories/1/org1/mod1.4/ivys/ivy-1.0.2.xml"), getResolveOptions(new String[] {"*"}));
assertFalse(report.hasError());
assertEquals(Collections.singleton(ModuleRevisionId.newInstance("org1", "mod1.2", "1.6")),
report.getConfigurationReport("default").getModuleRevisionIds());
assertEquals(Collections.singleton(ModuleRevisionId.newInstance("org1", "mod1.2", "1.6")), report.getConfigurationReport("default").getModuleRevisionIds());
}
@Test
@ -3479,34 +3464,24 @@ public class ResolveTest {
/**
* Circular dependency: mod6.3 depends on mod6.2, which itself depends on mod6.3;
* circular dependency strategy set to error.
*
* @throws Exception if something goes wrong
*/
@Test
public void testCircular() throws Exception {
expExc.expect(CircularDependencyException.class);
expExc.expectMessage("org6#mod6.3;1.0->org6#mod6.2;1.0->org6#mod6.3;latest.integration");
ResolveReport report = ivy.resolve(new File("test/repositories/2/mod6.3/ivy-1.0.xml"),
getResolveOptions(new String[] {"default"}));
ResolveReport report = ivy.resolve(new File("test/repositories/2/mod6.3/ivy-1.0.xml"), getResolveOptions(new String[] {"default"}));
assertFalse(report.hasError());
ivy.getSettings().setCircularDependencyStrategy(
IgnoreCircularDependencyStrategy.getInstance());
report = ivy.resolve(new File("test/repositories/2/mod6.3/ivy-1.0.xml"),
getResolveOptions(new String[] {"default"}));
ivy.getSettings().setCircularDependencyStrategy(IgnoreCircularDependencyStrategy.getInstance());
report = ivy.resolve(new File("test/repositories/2/mod6.3/ivy-1.0.xml"), getResolveOptions(new String[] {"default"}));
assertFalse(report.hasError());
ivy.getSettings().setCircularDependencyStrategy(
WarnCircularDependencyStrategy.getInstance());
report = ivy.resolve(new File("test/repositories/2/mod6.3/ivy-1.0.xml"),
getResolveOptions(new String[] {"default"}));
ivy.getSettings().setCircularDependencyStrategy(WarnCircularDependencyStrategy.getInstance());
report = ivy.resolve(new File("test/repositories/2/mod6.3/ivy-1.0.xml"), getResolveOptions(new String[] {"default"}));
assertFalse(report.hasError());
ivy.getSettings().setCircularDependencyStrategy(
ErrorCircularDependencyStrategy.getInstance());
ivy.resolve(new File("test/repositories/2/mod6.3/ivy-1.0.xml"),
getResolveOptions(new String[] {"default"}));
ivy.getSettings().setCircularDependencyStrategy(ErrorCircularDependencyStrategy.getInstance());
Exception e = assertThrows(CircularDependencyException.class, () ->
ivy.resolve(new File("test/repositories/2/mod6.3/ivy-1.0.xml"), getResolveOptions(new String[] {"default"})));
assertEquals("org6#mod6.3;1.0->org6#mod6.2;1.0->org6#mod6.3;latest.integration", e.getMessage());
}
/**
@ -3517,17 +3492,13 @@ public class ResolveTest {
*/
@Test
public void testCircular2() throws Exception {
expExc.expect(CircularDependencyException.class);
expExc.expectMessage("org8#mod8.5;NONE->org8#mod8.6;2.+->org8#mod8.5;2.+");
ResolveReport report = ivy.resolve(new File("test/repositories/circular/ivy.xml"),
getResolveOptions(new String[] {"*"}));
ResolveReport report = ivy.resolve(new File("test/repositories/circular/ivy.xml"), getResolveOptions(new String[] {"*"}));
assertFalse(report.hasError());
ivy.getSettings().setCircularDependencyStrategy(
ErrorCircularDependencyStrategy.getInstance());
ivy.resolve(new File("test/repositories/circular/ivy.xml"),
getResolveOptions(new String[] {"*"}));
ivy.getSettings().setCircularDependencyStrategy(ErrorCircularDependencyStrategy.getInstance());
Exception e = assertThrows(CircularDependencyException.class, () ->
ivy.resolve(new File("test/repositories/circular/ivy.xml"), getResolveOptions(new String[] {"*"})));
assertEquals("org8#mod8.5;NONE->org8#mod8.6;2.+->org8#mod8.5;2.+", e.getMessage());
}
/**
@ -3540,36 +3511,28 @@ public class ResolveTest {
*/
@Test
public void testCircular3() throws Exception {
expExc.expect(CircularDependencyException.class);
expExc.expectMessage("org6#mod6.3;1.2->org6#mod6.2;1.1->...");
ResolveReport report = ivy.resolve(new File("test/repositories/2/mod6.3/ivy-1.2.xml"),
getResolveOptions(new String[] {"default", "test"}));
ResolveReport report = ivy.resolve(new File("test/repositories/2/mod6.3/ivy-1.2.xml"), getResolveOptions(new String[] {"default", "test"}));
assertFalse(report.hasError());
// we should have mod 6.2 artifact in both configurations
assertEquals(1, report.getConfigurationReport("default").getArtifactsNumber());
assertEquals(1, report.getConfigurationReport("test").getArtifactsNumber());
ivy.getSettings().setCircularDependencyStrategy(
IgnoreCircularDependencyStrategy.getInstance());
report = ivy.resolve(new File("test/repositories/2/mod6.3/ivy-1.2.xml"),
getResolveOptions(new String[] {"default", "test"}));
ivy.getSettings().setCircularDependencyStrategy(IgnoreCircularDependencyStrategy.getInstance());
report = ivy.resolve(new File("test/repositories/2/mod6.3/ivy-1.2.xml"), getResolveOptions(new String[] {"default", "test"}));
assertFalse(report.hasError());
assertEquals(1, report.getConfigurationReport("default").getArtifactsNumber());
assertEquals(1, report.getConfigurationReport("test").getArtifactsNumber());
ivy.getSettings().setCircularDependencyStrategy(
WarnCircularDependencyStrategy.getInstance());
report = ivy.resolve(new File("test/repositories/2/mod6.3/ivy-1.2.xml"),
getResolveOptions(new String[] {"default", "test"}));
ivy.getSettings().setCircularDependencyStrategy(WarnCircularDependencyStrategy.getInstance());
report = ivy.resolve(new File("test/repositories/2/mod6.3/ivy-1.2.xml"), getResolveOptions(new String[] {"default", "test"}));
assertFalse(report.hasError());
assertEquals(1, report.getConfigurationReport("default").getArtifactsNumber());
assertEquals(1, report.getConfigurationReport("test").getArtifactsNumber());
ivy.getSettings().setCircularDependencyStrategy(
ErrorCircularDependencyStrategy.getInstance());
ivy.resolve(new File("test/repositories/2/mod6.3/ivy-1.2.xml"),
getResolveOptions(new String[] {"default", "test"}));
ivy.getSettings().setCircularDependencyStrategy(ErrorCircularDependencyStrategy.getInstance());
Exception e = assertThrows(CircularDependencyException.class, () ->
ivy.resolve(new File("test/repositories/2/mod6.3/ivy-1.2.xml"), getResolveOptions(new String[] {"default", "test"})));
assertEquals("org6#mod6.3;1.2->org6#mod6.2;1.1->...", e.getMessage());
}
@Test
@ -4421,13 +4384,11 @@ public class ResolveTest {
assertTrue(getArchiveFileInCache("org5", "mod5.1", "4.1", "art51B", "jar", "jar").exists());
}
/**
* Test for issues IVY-982 and IVY-1547,
* which have to do with resolve engine ignoring negated configurations
* on the left side of the maps-to operator.
*/
@Test
public void testResolveWithNegation() throws Exception {
ConfigurationResolveReport crp;
@ -5107,8 +5068,8 @@ public class ResolveTest {
ivy.getSettings().setDefaultResolver("parentChain");
final File pom = new File("test/repositories/parentPom/org/apache/dm/sibling1/1.0/sibling1-1.0.pom");
final ResolveReport report = ivy.resolve(pom, getResolveOptions(new String[]{"*"}));
Assert.assertNotNull("Resolve report is null", report);
Assert.assertFalse("Resolve report has errors", report.hasError());
assertNotNull("Resolve report is null", report);
assertFalse("Resolve report has errors", report.hasError());
}
@Test
@ -6261,71 +6222,6 @@ public class ResolveTest {
ivy.deliver(pubrev, deliveryPattern, dopts);
}
/**
* Test case for IVY-1300.
*
* @throws Exception if something goes wrong
* @see <a href="https://issues.apache.org/jira/browse/IVY-1300">IVY-1300</a>
*/
@Test
public void testIVY1300() throws Exception {
ivy = Ivy.newInstance();
ivy.configure(new File("test/repositories/IVY-1300/ivysettings.xml"));
ResolveOptions opts = new ResolveOptions();
opts.setConfs(new String[] {"*"});
opts.setResolveId("resolveid");
opts.setTransitive(true);
ResolveReport report = ivy.resolve(new File("test/repositories/IVY-1300/assembly-ivy.xml"),
opts);
assertFalse(report.hasError());
ModuleRevisionId modAExpectedRevId = ModuleRevisionId.newInstance("myorg", "modA", "trunk",
"5");
ModuleRevisionId modBExpectedRevId = ModuleRevisionId.newInstance("myorg", "modB",
"releasebranch", "1");
// check that the resolve report has the expected results, namely that
// trunk/5 is considered later than branch/1 purely because 5>1. Of
// course it is more likely that we would want to consider this a
// 'bad comparison', but this Unit Test is not about that. It is about
// inconsistency of results between the resolve report and the
// delivered descriptor. In fact the delivered descriptor is out of
// step, because retrieve and the report both agree that trunk/5 is
// selected. Deliver begs to differ.
Set<ModuleRevisionId> reportMrids = report.getConfigurationReport("default")
.getModuleRevisionIds();
assertEquals(
new HashSet<>(Arrays.asList(modAExpectedRevId, modBExpectedRevId)),
reportMrids);
DeliverOptions dopts = new DeliverOptions();
dopts.setGenerateRevConstraint(true);
dopts.setConfs(new String[] {"*"});
dopts.setStatus("release");
dopts.setPubdate(new Date());
dopts.setResolveId("resolveid");
String pubrev = "1";
String deliveryPattern = "build/test/deliver/assembly-[revision].xml";
ivy.deliver(pubrev, deliveryPattern, dopts);
// now check that the resolve report has the same info as the delivered descriptor
File deliveredIvyFile = new File("build/test/deliver/assembly-1.xml");
assertTrue(deliveredIvyFile.exists());
ModuleDescriptor md = XmlModuleDescriptorParser.getInstance().parseDescriptor(
ivy.getSettings(), deliveredIvyFile.toURI().toURL(), false);
DependencyDescriptor[] dds = md.getDependencies();
assertEquals(2, dds.length);
assertEquals(ModuleRevisionId.newInstance("myorg", "modB", "releasebranch", "1"),
dds[1].getDependencyRevisionId());
assertEquals(ModuleRevisionId.newInstance("myorg", "modA", "trunk", "5"),
dds[0].getDependencyRevisionId());
}
@Test
public void testUseCacheOnly() throws Exception {
ResolveOptions option = getResolveOptions(new String[] {"*"}).setValidate(false);

View File

@ -41,11 +41,9 @@ import org.apache.ivy.util.MockMessageLogger;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Copy;
import org.apache.tools.ant.taskdefs.Delete;
import org.apache.tools.ant.taskdefs.condition.JavaVersion;
import org.apache.tools.ant.types.FilterChain;
import org.apache.tools.ant.filters.TokenFilter.ReplaceString;
import org.junit.After;
import org.junit.Assume;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
@ -500,10 +498,6 @@ public class RetrieveTest {
*/
@Test
public void testUnpackExt() throws Exception {
final JavaVersion java14OrHigher = new JavaVersion();
java14OrHigher.setAtLeast("14");
Assume.assumeFalse("Pack200 tools and API have been removed since JDK 14", java14OrHigher.eval());
final ResolveOptions roptions = getResolveOptions(new String[] {"*"});
final URL url = new File("test/repositories/1/packaging/module10/ivys/ivy-1.0.xml").toURI()

View File

@ -17,6 +17,11 @@
*/
package org.apache.ivy.core.settings;
import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.util.List;
import org.apache.ivy.core.cache.DefaultRepositoryCacheManager;
import org.apache.ivy.core.cache.ResolutionCacheManager;
import org.apache.ivy.core.module.descriptor.Artifact;
@ -43,27 +48,20 @@ import org.apache.ivy.plugins.version.ChainVersionMatcher;
import org.apache.ivy.plugins.version.MavenTimedSnapshotVersionMatcher;
import org.apache.ivy.plugins.version.MockVersionMatcher;
import org.apache.ivy.plugins.version.VersionMatcher;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.util.List;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
/**
* Test the parsing of Ivy settings file through the {@link XmlSettingsParser}
*/
public class XmlSettingsParserTest {
@Rule
public ExpectedException expExc = ExpectedException.none();
@Test
public void test() throws Exception {
@ -261,18 +259,15 @@ public class XmlSettingsParserTest {
/**
* Test of resolver referencing a non existent cache.
*
* @throws Exception if something goes wrong
*/
@Test
public void testInvalidCache() throws Exception {
expExc.expect(ParseException.class);
expExc.expectMessage("mycache");
public void testInvalidCache() {
IvySettings settings = new IvySettings();
XmlSettingsParser parser = new XmlSettingsParser(settings);
parser.parse(XmlSettingsParserTest.class.getResource("ivysettings-cache-invalid.xml"));
Exception exception = assertThrows(ParseException.class, () ->
parser.parse(XmlSettingsParserTest.class.getResource("ivysettings-cache-invalid.xml")));
assertTrue(exception.getMessage().endsWith("unknown cache manager 'mycache'. Available caches are [mycache2]"));
}
@Test

View File

@ -17,20 +17,17 @@
*/
package org.apache.ivy.osgi.core;
import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.runners.Enclosed;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import java.text.ParseException;
import java.util.Arrays;
import java.util.Collection;
import static org.hamcrest.Matchers.hasProperty;
import static org.hamcrest.Matchers.is;
import org.junit.Test;
import org.junit.experimental.runners.Enclosed;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThrows;
@RunWith(Enclosed.class)
public class ManifestHeaderTest {
@ -92,15 +89,11 @@ public class ManifestHeaderTest {
ManifestHeaderValue value = new ManifestHeaderValue("glassfish javax.servlet.3.1.0.b33");
assertEquals("glassfish javax.servlet.3.1.0.b33", value.getSingleValue());
}
}
@RunWith(Parameterized.class)
public static class IllegalOptionTests {
@Rule
public ExpectedException expExc = ExpectedException.none();
@Parameterized.Parameters(name = "Illegal token at {1} in {0}")
public static Collection<Object[]> data() {
return Arrays.asList(new Object[][] {{"value1=", 6},
@ -119,12 +112,10 @@ public class ManifestHeaderTest {
* Expected failure when the parameter is illegal
*/
@Test
public void testSyntaxError() throws ParseException {
expExc.expect(ParseException.class);
expExc.expect(hasProperty("errorOffset", is(offset)));
new ManifestHeaderValue(value);
public void testSyntaxError() {
ParseException exception = assertThrows(ParseException.class, () -> new ManifestHeaderValue(value));
assertEquals(offset, exception.getErrorOffset());
}
}
@RunWith(Parameterized.class)
@ -155,7 +146,5 @@ public class ManifestHeaderTest {
public void testNormalisation() throws Exception {
assertEquals(new ManifestHeaderValue(normalised), new ManifestHeaderValue(value));
}
}
}

View File

@ -0,0 +1,96 @@
/*
* 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.
*
*/
package org.apache.ivy.plugins.conflict;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.text.ParseException;
import org.apache.ivy.Ivy;
import org.apache.ivy.TestFixture;
import org.apache.ivy.TestHelper;
import org.apache.ivy.core.report.ConfigurationResolveReport;
import org.apache.ivy.core.report.ResolveReport;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class NearestConflictManagerTest {
private TestFixture fixture;
@Before
public void setUp() {
fixture = new TestFixture();
ConflictManager cm = fixture.getSettings().getConflictManager("nearest");
fixture.getSettings().setDefaultConflictManager(cm);
}
@After
public void tearDown() {
fixture.clean();
}
@Test
public void testInitFromSettings() throws Exception {
Ivy ivy = new Ivy();
ivy.configure(NearestConflictManagerTest.class.getResource("ivysettings-nearest.xml"));
ConflictManager cm = ivy.getSettings().getDefaultConflictManager();
assertTrue(cm instanceof NearestConflictManager);
}
@Test
public void testNearestResolve1() throws Exception {
fixture.addMD("#A;1-> { #B;1.4 #C;1.0 }").addMD("#B;1.4->#D;1.5")
.addMD("#C;1.0->#D;1.6").addMD("#D;1.5").addMD("#D;1.6").init();
resolveAndAssert("#A;1", "#B;1.4, #C;1.0, #D;1.5");
}
@Test
public void testNearestResolve2() throws Exception {
fixture.addMD("#A;1-> { #B;1.4 #C;1.0 }").addMD("#B;1.4->#D;1.6")
.addMD("#C;1.0->#D;1.5").addMD("#D;1.5").addMD("#D;1.6").init();
resolveAndAssert("#A;1", "#B;1.4, #C;1.0, #D;1.6");
}
@Test
public void testNearestResolve3() throws Exception {
fixture.addMD("#A;1-> { #B;1.4 #C;1.0 }").addMD("#B;1.4->#E;1.0").addMD("#E;1.0->#D;1.5")
.addMD("#C;1.0->#D;1.6").addMD("#D;1.5").addMD("#D;1.6").init();
resolveAndAssert("#A;1", "#B;1.4, #C;1.0, #D;1.6, #E;1.0");
}
@Test
public void testNearestResolve4() throws Exception {
fixture.addMD("#A;1-> { #B;1.4 #C;1.0 #D;1.5 }").addMD("#B;1.4->#E;1.0").addMD("#E;1.0->#D;1.5")
.addMD("#C;1.0->#D;1.6").addMD("#D;1.5").addMD("#D;1.6").init();
resolveAndAssert("#A;1", "#B;1.4, #C;1.0, #D;1.5, #E;1.0");
}
private void resolveAndAssert(String mrid, String expectedModuleSet) throws ParseException,
IOException {
ResolveReport report = fixture.resolve(mrid);
assertFalse(report.hasError());
ConfigurationResolveReport defaultReport = report.getConfigurationReport("default");
TestHelper.assertModuleRevisionIds(expectedModuleSet, defaultReport.getModuleRevisionIds());
}
}

View File

@ -22,24 +22,25 @@ import java.io.File;
import org.apache.ivy.Ivy;
import org.apache.ivy.core.resolve.ResolveOptions;
import org.apache.ivy.util.FileUtil;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThrows;
public class RegexpConflictManagerTest {
private Ivy ivy;
private File cache;
@Rule
public ExpectedException expExc = ExpectedException.none();
@Before
public void setUp() throws Exception {
ivy = new Ivy();
ivy.configure(RegexpConflictManagerTest.class.getResource("ivysettings-regexp-test.xml"));
cache = new File("build/cache");
cache.mkdirs();
}
@ -51,17 +52,13 @@ public class RegexpConflictManagerTest {
@Test
public void testNoApiConflictResolve() throws Exception {
ivy.resolve(RegexpConflictManagerTest.class.getResource("ivy-no-regexp-conflict.xml"),
getResolveOptions());
ivy.resolve(RegexpConflictManagerTest.class.getResource("ivy-no-regexp-conflict.xml"), getResolveOptions());
}
@Test
public void testConflictResolve() throws Exception {
expExc.expect(StrictConflictException.class);
expExc.expectMessage("org1#mod1.2;2.0.0:2.0 (needed by [apache#resolve-noconflict;1.0]) conflicts with org1#mod1.2;2.1.0:2.1 (needed by [apache#resolve-noconflict;1.0])");
ivy.resolve(RegexpConflictManagerTest.class.getResource("ivy-conflict.xml"),
getResolveOptions());
public void testConflictResolve() {
Exception exception = assertThrows(StrictConflictException.class, () -> ivy.resolve(RegexpConflictManagerTest.class.getResource("ivy-conflict.xml"), getResolveOptions()));
assertEquals("org1#mod1.2;2.0.0:2.0 (needed by [apache#resolve-noconflict;1.0]) conflicts with org1#mod1.2;2.1.0:2.1 (needed by [apache#resolve-noconflict;1.0])", exception.getMessage());
}
private ResolveOptions getResolveOptions() {

View File

@ -0,0 +1,31 @@
<!--
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>
<settings defaultResolver="test" defaultConflictManager="nearest" />
<caches defaultCacheDir="${ivy.basedir}/build/cache" />
<resolvers>
<filesystem name="test">
<ivy pattern="${ivy.basedir}/test/repositories/latest-compatible/[module]/[revision]/[artifact].[ext]"/>
<artifact
pattern="${ivy.basedir}/test/repositories/latest-compatible/[module]/[revision]/[artifact].[ext]"/>
</filesystem>
</resolvers>
</ivysettings>

View File

@ -1,72 +1,72 @@
/*
* 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.
*
*/
package org.apache.ivy.core.pack;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertFalse;
import org.apache.ivy.TestHelper;
import org.apache.ivy.util.DefaultMessageLogger;
import org.apache.ivy.util.FileUtil;
import org.apache.ivy.util.Message;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Mkdir;
import org.apache.tools.ant.taskdefs.Delete;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class ZipPackingTest {
private static final Project PROJECT = TestHelper.newProject();
private static final File TEST_DIR = PROJECT.resolveFile("build/test/pack");
@Before
public void setUp() {
Mkdir mkdir = new Mkdir();
mkdir.setProject(PROJECT);
mkdir.setDir(TEST_DIR);
mkdir.execute();
Message.setDefaultLogger(new DefaultMessageLogger(Message.MSG_INFO));
}
@After
public void tearDown() {
Delete del = new Delete();
del.setProject(PROJECT);
del.setDir(TEST_DIR);
del.execute();
}
@Test
public void zipPackingExtractsArchive() throws IOException {
try (InputStream zip = new FileInputStream(PROJECT.resolveFile("test/zip/test.zip"))) {
new ZipPacking().unpack(zip, TEST_DIR);
}
assertTrue("Expecting file a", FileUtil.resolveFile(TEST_DIR, "a").isFile());
assertTrue("Expecting directory b", FileUtil.resolveFile(TEST_DIR, "b").isDirectory());
assertTrue("Expecting file b/c", FileUtil.resolveFile(TEST_DIR, "b/c").isFile());
assertTrue("Expecting directory d", FileUtil.resolveFile(TEST_DIR, "d").isDirectory());
assertFalse("Not expecting file e", PROJECT.resolveFile("build/test/e").exists());
}
}
/*
* 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.
*
*/
package org.apache.ivy.plugins.pack;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertFalse;
import org.apache.ivy.TestHelper;
import org.apache.ivy.util.DefaultMessageLogger;
import org.apache.ivy.util.FileUtil;
import org.apache.ivy.util.Message;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Mkdir;
import org.apache.tools.ant.taskdefs.Delete;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class ZipPackingTest {
private static final Project PROJECT = TestHelper.newProject();
private static final File TEST_DIR = PROJECT.resolveFile("build/test/pack");
@Before
public void setUp() {
Mkdir mkdir = new Mkdir();
mkdir.setProject(PROJECT);
mkdir.setDir(TEST_DIR);
mkdir.execute();
Message.setDefaultLogger(new DefaultMessageLogger(Message.MSG_INFO));
}
@After
public void tearDown() {
Delete del = new Delete();
del.setProject(PROJECT);
del.setDir(TEST_DIR);
del.execute();
}
@Test
public void zipPackingExtractsArchive() throws IOException {
try (InputStream zip = new FileInputStream(PROJECT.resolveFile("test/zip/test.zip"))) {
new ZipPacking().unpack(zip, TEST_DIR);
}
assertTrue("Expecting file a", FileUtil.resolveFile(TEST_DIR, "a").isFile());
assertTrue("Expecting directory b", FileUtil.resolveFile(TEST_DIR, "b").isDirectory());
assertTrue("Expecting file b/c", FileUtil.resolveFile(TEST_DIR, "b/c").isFile());
assertTrue("Expecting directory d", FileUtil.resolveFile(TEST_DIR, "d").isDirectory());
assertFalse("Not expecting file e", PROJECT.resolveFile("build/test/e").exists());
}
}

View File

@ -17,13 +17,6 @@
*/
package org.apache.ivy.plugins.parser.m2;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.fail;
import java.io.File;
import java.io.IOException;
import java.net.URL;
@ -58,13 +51,21 @@ import org.apache.ivy.plugins.parser.xml.XmlModuleDescriptorParserTest;
import org.apache.ivy.plugins.repository.url.URLResource;
import org.apache.ivy.plugins.resolver.DependencyResolver;
import org.apache.ivy.plugins.resolver.MockResolver;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
public class PomModuleDescriptorParserTest extends AbstractModuleDescriptorParserTester {
private IvySettings settings = new IvySettings();
@ -86,9 +87,6 @@ public class PomModuleDescriptorParserTest extends AbstractModuleDescriptorParse
private MockResolver mockedResolver = new MockedDependencyResolver();
@Rule
public ExpectedException expExc = ExpectedException.none();
@Rule
public TemporaryFolder workDir = new TemporaryFolder();
@ -220,12 +218,10 @@ public class PomModuleDescriptorParserTest extends AbstractModuleDescriptorParse
}
@Test
public void testParentNotFound() throws Exception {
expExc.expect(IOException.class);
expExc.expectMessage("Impossible to load parent");
PomModuleDescriptorParser.getInstance().parseDescriptor(new IvySettings(),
getClass().getResource("test-parent-not-found.pom"), false);
public void testParentNotFound() {
Exception exception = assertThrows(IOException.class, () ->
PomModuleDescriptorParser.getInstance().parseDescriptor(new IvySettings(), getClass().getResource("test-parent-not-found.pom"), false));
assertTrue(exception.getMessage().startsWith("Impossible to load parent"));
}
@Test
@ -427,7 +423,7 @@ public class PomModuleDescriptorParserTest extends AbstractModuleDescriptorParse
assertEquals(5, dds.length);
for (int i = 0; i < dds.length; i++) {
assertEquals(2, dds[i].getAllDependencyArtifacts().length);
int withExt = i == 0 || i == 3 ? 1: 0;
int withExt = i == 0 || i == 3 ? 1 : 0;
assertEquals(extraAtt, dds[i].getAllDependencyArtifacts()[withExt].getExtraAttributes());
}
}
@ -873,6 +869,44 @@ public class PomModuleDescriptorParserTest extends AbstractModuleDescriptorParse
assertEquals("The configuration must be test", "test", dds[0].getModuleConfigurations()[0]);
}
@Test
public void testDependencyManagementWithClassifier() throws ParseException, IOException {
ModuleDescriptor md = PomModuleDescriptorParser.getInstance().parseDescriptor(settings,
getClass().getResource("test-dependencyMgt-with-classifier.pom"), false);
assertNotNull(md);
assertEquals(ModuleRevisionId.newInstance("org.apache", "test-depMgt", "1.1"),
md.getModuleRevisionId());
DependencyDescriptor[] dds = md.getDependencies();
assertNotNull(dds);
assertEquals(1, dds.length);
assertEquals(ModuleRevisionId.newInstance("commons-logging", "commons-logging", "1.0.4"),
dds[0].getDependencyRevisionId());
assertEquals(1, dds[0].getAllDependencyArtifacts().length);
assertEquals("jar", dds[0].getAllDependencyArtifacts()[0].getExt());
assertEquals("jar", dds[0].getAllDependencyArtifacts()[0].getType());
Map<String, String> extraAtt = Collections.singletonMap("classifier", "asl");
assertEquals(extraAtt, dds[0].getAllDependencyArtifacts()[0].getExtraAttributes());
}
@Test
public void testDependencyManagementWithType() throws ParseException, IOException {
ModuleDescriptor md = PomModuleDescriptorParser.getInstance().parseDescriptor(settings,
getClass().getResource("test-dependencyMgt-with-type.pom"), false);
assertNotNull(md);
assertEquals(ModuleRevisionId.newInstance("org.apache", "test-depMgt", "1.1"),
md.getModuleRevisionId());
DependencyDescriptor[] dds = md.getDependencies();
assertNotNull(dds);
assertEquals(1, dds.length);
assertEquals(ModuleRevisionId.newInstance("commons-logging", "commons-logging", "1.0.4"),
dds[0].getDependencyRevisionId());
assertEquals(1, dds[0].getAllDependencyArtifacts().length);
assertEquals("dll", dds[0].getAllDependencyArtifacts()[0].getExt());
assertEquals("dll", dds[0].getAllDependencyArtifacts()[0].getType());
}
@Test
public void testParentDependencyMgt() throws ParseException, IOException {
settings.setDictatorResolver(new MockResolver() {
@ -1247,17 +1281,14 @@ public class PomModuleDescriptorParserTest extends AbstractModuleDescriptorParse
for (final String expectedPackagingType : packagingTypesToTest) {
String sysPropToSet = null;
switch (expectedPackagingType) {
case "bundle": {
case "bundle":
sysPropToSet = "PomModuleDescriptorParserTest.some-other-test-prop";
break;
}
case "jar": {
case "jar":
sysPropToSet = "PomModuleDescriptorParserTest.some-test-prop";
break;
}
default: {
default:
fail("Unexpected packaging type");
}
}
// activate the relevant profile, based on a system property
System.setProperty(sysPropToSet, "foo");

View File

@ -0,0 +1,53 @@
<?xml version="1.0"?>
<!--
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.
-->
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>org.apache</groupId>
<artifactId>test-depMgt</artifactId>
<name>Test Module for Ivy M2 parsing</name>
<version>1.1</version>
<url>http://ivy.jayasoft.org/</url>
<organization>
<name>Jayasoft</name>
<url>http://www.jayasoft.org/</url>
</organization>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<classifier>asl</classifier>
<version>1.0.4</version>
</dependency>
<dependency>
<groupId>commons-collection</groupId>
<artifactId>commons-collection</artifactId>
<version>1.0.5</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<classifier>asl</classifier>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,53 @@
<?xml version="1.0"?>
<!--
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.
-->
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>org.apache</groupId>
<artifactId>test-depMgt</artifactId>
<name>Test Module for Ivy M2 parsing</name>
<version>1.1</version>
<url>http://ivy.jayasoft.org/</url>
<organization>
<name>Jayasoft</name>
<url>http://www.jayasoft.org/</url>
</organization>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<type>dll</type>
<version>1.0.4</version>
</dependency>
<dependency>
<groupId>commons-collection</groupId>
<artifactId>commons-collection</artifactId>
<version>1.0.5</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<type>dll</type>
</dependency>
</dependencies>
</project>

View File

@ -17,6 +17,22 @@
*/
package org.apache.ivy.plugins.parser.xml;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.text.ParseException;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashSet;
import java.util.Set;
import org.apache.ivy.Ivy;
import org.apache.ivy.core.module.descriptor.Artifact;
import org.apache.ivy.core.module.descriptor.Configuration;
@ -41,40 +57,23 @@ import org.apache.ivy.util.DefaultMessageLogger;
import org.apache.ivy.util.FileUtil;
import org.apache.ivy.util.Message;
import org.apache.ivy.util.XMLHelper;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.text.ParseException;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashSet;
import java.util.Set;
import org.junit.Before;
import org.junit.Test;
import static org.apache.ivy.core.module.descriptor.Configuration.Visibility.PRIVATE;
import static org.apache.ivy.core.module.descriptor.Configuration.Visibility.PUBLIC;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
public class XmlModuleDescriptorParserTest extends AbstractModuleDescriptorParserTester {
private IvySettings settings = null;
@Rule
public ExpectedException expExc = ExpectedException.none();
private IvySettings settings;
@Before
public void setUp() {
@ -148,52 +147,42 @@ public class XmlModuleDescriptorParserTest extends AbstractModuleDescriptorParse
}
@Test
public void testBad() throws IOException, ParseException {
expExc.expect(ParseException.class);
expExc.expectMessage("'modul'");
public void testBad() {
assertTrue(XMLHelper.canUseSchemaValidation());
XmlModuleDescriptorParser.getInstance().parseDescriptor(settings,
getClass().getResource("test-bad.xml"), true);
Exception exception = assertThrows(ParseException.class, () ->
XmlModuleDescriptorParser.getInstance().parseDescriptor(settings, getClass().getResource("test-bad.xml"), true));
assertTrue(exception.getMessage().contains("'modul'"));
}
@Test
public void testBadOrg() throws IOException, ParseException {
expExc.expect(ParseException.class);
expExc.expectMessage("organization");
public void testBadOrg() {
assertTrue(XMLHelper.canUseSchemaValidation());
XmlModuleDescriptorParser.getInstance().parseDescriptor(settings,
getClass().getResource("test-bad-org.xml"), true);
Exception exception = assertThrows(ParseException.class, () ->
XmlModuleDescriptorParser.getInstance().parseDescriptor(settings, getClass().getResource("test-bad-org.xml"), true));
assertTrue(exception.getMessage().contains("organization"));
}
@Test
public void testBadConfs() throws IOException, ParseException {
expExc.expect(ParseException.class);
expExc.expectMessage("invalidConf");
XmlModuleDescriptorParser.getInstance().parseDescriptor(settings,
getClass().getResource("test-bad-confs.xml"), true);
public void testBadConfs() {
Exception exception = assertThrows(ParseException.class, () ->
XmlModuleDescriptorParser.getInstance().parseDescriptor(settings, getClass().getResource("test-bad-confs.xml"), true));
assertTrue(exception.getMessage().contains("invalidConf"));
}
@Test
public void testCyclicConfs2() throws IOException, ParseException {
expExc.expect(ParseException.class);
expExc.expectMessage("A => B => A");
XmlModuleDescriptorParser.getInstance().parseDescriptor(settings,
getClass().getResource("test-cyclic-confs1.xml"), true);
public void testCyclicConfs2() {
Exception exception = assertThrows(ParseException.class, () ->
XmlModuleDescriptorParser.getInstance().parseDescriptor(settings, getClass().getResource("test-cyclic-confs1.xml"), true));
assertTrue(exception.getMessage().contains("A => B => A"));
}
@Test
public void testCyclicConfs3() throws IOException, ParseException {
expExc.expect(ParseException.class);
expExc.expectMessage("A => C => B => A");
XmlModuleDescriptorParser.getInstance().parseDescriptor(settings,
getClass().getResource("test-cyclic-confs2.xml"), true);
public void testCyclicConfs3() {
Exception exception = assertThrows(ParseException.class, () ->
XmlModuleDescriptorParser.getInstance().parseDescriptor(settings, getClass().getResource("test-cyclic-confs2.xml"), true));
assertTrue(exception.getMessage().contains("A => C => B => A"));
}
@Test
@ -1474,7 +1463,7 @@ public class XmlModuleDescriptorParserTest extends AbstractModuleDescriptorParse
final Path targetDir = Paths.get(System.getProperty("java.io.tmpdir"), "foo%2Fbar");
Files.createDirectories(targetDir);
final Path parentIvyXMLPath = Paths.get(targetDir.toString(), "parent-ivy.xml");
try (final InputStream is = parentIvyXML.openStream()) {
try (InputStream is = parentIvyXML.openStream()) {
Files.copy(is, parentIvyXMLPath, StandardCopyOption.REPLACE_EXISTING);
}
assertTrue("Parent ivy xml file wasn't copied", Files.isRegularFile(parentIvyXMLPath));

View File

@ -51,21 +51,16 @@ import org.apache.ivy.util.FileUtil;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
/**
*
*/
public class FileSystemResolverTest extends AbstractDependencyResolverTest {
// CheckStyle:MagicNumberCheck OFF
private static final String FS = File.separator;
@ -89,9 +84,6 @@ public class FileSystemResolverTest extends AbstractDependencyResolverTest {
setupLastModified();
}
@Rule
public ExpectedException expExc = ExpectedException.none();
@Before
public void setUp() {
settings = new IvySettings();
@ -889,21 +881,14 @@ public class FileSystemResolverTest extends AbstractDependencyResolverTest {
resolver.abortPublishTransaction();
assertFalse(new File("test/repositories/1/myorg/mymodule/myrevision/ivy.xml").exists());
assertFalse(new File(
"test/repositories/1/myorg/mymodule/myrevision/myartifact-myrevision.myext")
.exists());
assertFalse(new File("test/repositories/1/myorg/mymodule/myrevision/myartifact-myrevision.myext").exists());
}
/**
* Publishing with transaction=true and an unsupported pattern must fail.
*
* @throws Exception if something goes wrong
*/
@Test
public void testUnsupportedTransaction() throws Exception {
expExc.expect(IllegalStateException.class);
expExc.expectMessage("transactional");
public void testUnsupportedTransaction() {
FileSystemResolver resolver = new FileSystemResolver();
resolver.setName("test");
resolver.setSettings(settings);
@ -919,20 +904,18 @@ public class FileSystemResolverTest extends AbstractDependencyResolverTest {
"myext");
File src = new File("test/repositories/ivysettings.xml");
resolver.beginPublishTransaction(mrid, false);
resolver.publish(artifact, src, false);
Exception exception = assertThrows(IllegalStateException.class, () -> {
resolver.beginPublishTransaction(mrid, false);
resolver.publish(artifact, src, false);
});
assertTrue(exception.getMessage().contains("transactional"));
}
/**
* Publishing with transaction=true and an unsupported combination of patterns must fail.
*
* @throws Exception if something goes wrong
*/
@Test
public void testUnsupportedTransaction2() throws Exception {
expExc.expect(IllegalStateException.class);
expExc.expectMessage("transactional");
public void testUnsupportedTransaction2() {
FileSystemResolver resolver = new FileSystemResolver();
resolver.setName("test");
resolver.setSettings(settings);
@ -950,21 +933,19 @@ public class FileSystemResolverTest extends AbstractDependencyResolverTest {
"myext");
File src = new File("test/repositories/ivysettings.xml");
resolver.beginPublishTransaction(mrid, false);
resolver.publish(ivyArtifact, src, false);
resolver.publish(artifact, src, false);
Exception exception = assertThrows(IllegalStateException.class, () -> {
resolver.beginPublishTransaction(mrid, false);
resolver.publish(ivyArtifact, src, false);
resolver.publish(artifact, src, false);
});
assertTrue(exception.getMessage().contains("transactional"));
}
/**
* Publishing with transaction=true and overwrite mode must fail.
*
* @throws Exception if something goes wrong
*/
@Test
public void testUnsupportedTransaction3() throws Exception {
expExc.expect(IllegalStateException.class);
expExc.expectMessage("transactional");
public void testUnsupportedTransaction3() {
FileSystemResolver resolver = new FileSystemResolver();
resolver.setName("test");
resolver.setSettings(settings);
@ -978,9 +959,12 @@ public class FileSystemResolverTest extends AbstractDependencyResolverTest {
"myext");
File src = new File("test/repositories/ivysettings.xml");
// overwrite transaction not supported
resolver.beginPublishTransaction(mrid, true);
resolver.publish(artifact, src, true);
Exception exception = assertThrows(IllegalStateException.class, () -> {
// overwrite transaction not supported
resolver.beginPublishTransaction(mrid, true);
resolver.publish(artifact, src, true);
});
assertTrue(exception.getMessage().contains("transactional"));
}
@Test

View File

@ -17,9 +17,6 @@
*/
package org.apache.ivy.plugins.resolver;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import java.io.File;
import java.util.List;
@ -38,25 +35,24 @@ import org.apache.ivy.core.resolve.ResolveOptions;
import org.apache.ivy.core.resolve.ResolvedModuleRevision;
import org.apache.ivy.core.settings.IvySettings;
import org.apache.ivy.core.sort.SortEngine;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
/**
*
*/
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
public class IvyRepResolverTest extends AbstractDependencyResolverTest {
private IvySettings settings;
private ResolveEngine engine;
private ResolveData data;
@Rule
public ExpectedException expExc = ExpectedException.none();
@Before
public void setUp() {
settings = new IvySettings();
@ -97,21 +93,19 @@ public class IvyRepResolverTest extends AbstractDependencyResolverTest {
/**
* Test case for IVY-625. Must fail if no ivyroot specified.
*
* @throws Exception if something goes wrong
* @see <a href="https://issues.apache.org/jira/browse/IVY-625">IVY-625</a>
*/
@Test
public void testMandatoryRoot() throws Exception {
expExc.expect(IllegalStateException.class);
expExc.expectMessage("ivyroot");
public void testMandatoryRoot() {
IvyRepResolver resolver = new IvyRepResolver();
resolver.setName("test");
resolver.setSettings(settings);
ModuleRevisionId mrid = ModuleRevisionId.newInstance("apache", "commons-cli", "1.0");
resolver.getDependency(new DefaultDependencyDescriptor(mrid, false), data);
Exception exception = assertThrows(IllegalStateException.class, () ->
resolver.getDependency(new DefaultDependencyDescriptor(mrid, false), data));
assertTrue(exception.getMessage().contains("ivyroot"));
}
@Test

View File

@ -72,14 +72,13 @@ public class IvyPatternHelperTest {
@Test
public void testTokenRoot() {
String pattern = "lib/[type]/[artifact].[ext]";
assertEquals("lib/", IvyPatternHelper.getTokenRoot(pattern));
}
@Test
public void testTokenRootWithOptionalFirstToken() {
String pattern = "lib/([type]/)[artifact].[ext]";
assertEquals("lib/", IvyPatternHelper.getTokenRoot(pattern));
assertEquals("lib/", IvyPatternHelper.getTokenRoot("lib/[type]/[artifact].[ext]"));
assertEquals("lib/", IvyPatternHelper.getTokenRoot("lib/([type]/)[artifact].[ext]"));
assertEquals("lib/", IvyPatternHelper.getTokenRoot("lib(/[type])/[artifact].[ext]"));
assertEquals("lib/", IvyPatternHelper.getTokenRoot("lib/(type-[type]/)[artifact].[ext]"));
assertEquals("lib/", IvyPatternHelper.getTokenRoot("lib(/type-[type])/[artifact].[ext]"));
assertEquals("lib/", IvyPatternHelper.getTokenRoot("lib/([type]/)"));
assertEquals("lib/lib (JDK 17)/", IvyPatternHelper.getTokenRoot("lib/lib (JDK 17)/[artifact].[ext]")); //IVY-1660
}
@Test(expected = IllegalArgumentException.class)

View File

@ -28,6 +28,7 @@ import org.junit.Test;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;
/**
* Test BasicURLHandler
@ -67,6 +68,7 @@ public class BasicURLHandlerTest {
@Test
public void testContentEncoding() throws Exception {
assumeTrue(handler.isReachable(new URL("http://carsten.codimi.de/"), 5000));
assertDownloadOK(new URL("http://carsten.codimi.de/gzip.yaws/daniels.html"), new File(
testDir, "gzip.txt"));
assertDownloadOK(new URL(

View File

@ -17,17 +17,6 @@
*/
package org.apache.ivy.util.url;
import org.apache.ivy.TestHelper;
import org.apache.ivy.core.settings.NamedTimeoutConstraint;
import org.apache.ivy.core.settings.TimeoutConstraint;
import org.apache.ivy.util.FileUtil;
import org.apache.ivy.util.url.URLHandler.URLInfo;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import java.io.File;
import java.io.IOException;
import java.net.InetSocketAddress;
@ -37,30 +26,32 @@ import java.nio.file.Path;
import java.util.Collections;
import java.util.Random;
import org.apache.ivy.TestHelper;
import org.apache.ivy.core.settings.NamedTimeoutConstraint;
import org.apache.ivy.core.settings.TimeoutConstraint;
import org.apache.ivy.util.FileUtil;
import org.apache.ivy.util.url.URLHandler.URLInfo;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.apache.ivy.plugins.resolver.IBiblioResolver.DEFAULT_M2_ROOT;
import static org.hamcrest.Matchers.endsWith;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;
public class HttpClientHandlerTest {
/**
* Test {@link HttpClientHandler}
*/
public class HttpclientURLHandlerTest {
// remote.test
private File testDir;
private HttpClientHandler handler;
private final TimeoutConstraint defaultTimeoutConstraint;
{
defaultTimeoutConstraint = new NamedTimeoutConstraint("default-http-client-handler-timeout");
((NamedTimeoutConstraint) defaultTimeoutConstraint).setConnectionTimeout(5000);
}
@Rule
public ExpectedException expExc = ExpectedException.none();
private TimeoutConstraint defaultTimeoutConstraint;
@Before
public void setUp() {
@ -68,14 +59,16 @@ public class HttpclientURLHandlerTest {
testDir.mkdirs();
handler = new HttpClientHandler();
defaultTimeoutConstraint = new NamedTimeoutConstraint("default-http-client-handler-timeout");
((NamedTimeoutConstraint) defaultTimeoutConstraint).setConnectionTimeout(5000);
}
@After
public void tearDown() {
try {
handler.close();
} catch (Exception e) {
// ignore
} catch (Exception ignore) {
}
FileUtil.forceDelete(testDir);
}
@ -91,7 +84,6 @@ public class HttpclientURLHandlerTest {
/**
* Test case for IVY-390.
*
* @throws Exception if something goes wrong
* @see <a href="https://issues.apache.org/jira/browse/IVY-390">IVY-390</a>
*/
@SuppressWarnings({"resource", "deprecation"})
@ -107,6 +99,7 @@ public class HttpclientURLHandlerTest {
@Test
public void testContentEncoding() throws Exception {
assumeTrue(handler.isReachable(new URL("http://carsten.codimi.de/"), 5000));
assertDownloadOK(new URL("http://carsten.codimi.de/gzip.yaws/daniels.html"), new File(
testDir, "gzip.txt"));
assertDownloadOK(new URL(
@ -129,18 +122,10 @@ public class HttpclientURLHandlerTest {
* {@link CredentialsStore Ivy credentials store} works as expected when it interacts
* with a HTTP server which requires authentication for accessing resources.
*
* @throws Exception if something goes wrong
* @see <a href="https://issues.apache.org/jira/browse/IVY-1336">IVY-1336</a>
*/
@Test
public void testCredentials() throws Exception {
// we catch it and check for presence of 401 in the exception message.
// It's not exactly an contract that the IOException will have the 401 message
// but for now that's how it's implemented and it's fine to check for the presence
// of that message at the moment
expExc.expect(IOException.class);
expExc.expectMessage(endsWith("ivysettings.xml' 401 - 'Unauthorized"));
final CredentialsStore credentialsStore = CredentialsStore.INSTANCE;
final String realm = "test-http-client-handler-realm";
final String host = "localhost";
@ -153,7 +138,7 @@ public class HttpclientURLHandlerTest {
final Path repoRoot = new File("test/repositories").toPath();
assertTrue(repoRoot + " is not a directory", Files.isDirectory(repoRoot));
// create a server backed by BASIC auth with the set of "allowed" credentials
try (final AutoCloseable server = TestHelper.createBasicAuthHttpServerBackedRepo(serverBindAddr,
try (AutoCloseable server = TestHelper.createBasicAuthHttpServerBackedRepo(serverBindAddr,
contextRoot, repoRoot, realm, Collections.singletonMap(userName, password))) {
final File target = new File(testDir, "downloaded.xml");
@ -167,7 +152,7 @@ public class HttpclientURLHandlerTest {
// now create a server backed by BASIC auth with a set of credentials that do *not* match
// with what the Ivy credentials store will return for a given realm+host combination, i.e.
// Ivy credential store will return back invalid credentials and the server will reject them
try (final AutoCloseable server = TestHelper.createBasicAuthHttpServerBackedRepo(serverBindAddr,
try (AutoCloseable server = TestHelper.createBasicAuthHttpServerBackedRepo(serverBindAddr,
contextRoot, repoRoot, realm, Collections.singletonMap("other-" + userName, "other-" + password))) {
final File target = new File(testDir, "should-not-have-been-downloaded.xml");
@ -175,7 +160,12 @@ public class HttpclientURLHandlerTest {
final URL src = new URL("http://localhost:" + serverBindAddr.getPort() + "/"
+ contextRoot + "/ivysettings.xml");
// download it (expected to fail)
handler.download(src, target, null, defaultTimeoutConstraint);
Exception exception = assertThrows(IOException.class, () -> handler.download(src, target, null, defaultTimeoutConstraint));
// we catch it and check for presence of 401 in the exception message.
// It's not exactly an contract that the IOException will have the 401 message
// but for now that's how it's implemented and it's fine to check for the presence
// of that message at the moment
assertTrue(exception.getMessage().endsWith("ivysettings.xml' 401 - 'Unauthorized"));
}
}

View File

@ -0,0 +1,32 @@
<!--
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.
-->
<ivy-module version="2.0">
<info organisation="overlap-newer" module="projectassembly" revision="1"/>
<configurations>
<conf name="conf1"/>
<conf name="conf2"/>
<conf name="conf3"/>
</configurations>
<publications>
</publications>
<dependencies>
<dependency name="modA" rev="1" conf="conf1,conf2->default"/>
<dependency name="modB" rev="1" conf="conf2,conf3->default"/>
</dependencies>
</ivy-module>

View File

@ -0,0 +1,32 @@
<!--
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.
-->
<ivy-module version="2.0">
<info organisation="overlap-older" module="projectassembly" revision="1"/>
<configurations>
<conf name="conf1"/>
<conf name="conf2"/>
<conf name="conf3"/>
</configurations>
<publications>
</publications>
<dependencies>
<dependency name="modA" rev="5" conf="conf1,conf2->default"/>
<dependency name="modB" rev="1" conf="conf2,conf3->default"/>
</dependencies>
</ivy-module>

View File

@ -0,0 +1,31 @@
<!--
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.
-->
<ivy-module version="2.0">
<info organisation="simple" module="projectassembly" revision="1"/>
<configurations>
<conf name="conf1"/>
<conf name="conf2"/>
</configurations>
<publications>
</publications>
<dependencies>
<dependency name="modA" rev="5" conf="conf1->default"/>
<dependency name="modB" rev="1" conf="conf1,conf2->default"/>
</dependencies>
</ivy-module>

View File

@ -0,0 +1,27 @@
<!--
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>
<settings defaultResolver="local" />
<resolvers>
<filesystem name="local" checkmodified="true" local="true">
<ivy pattern="${ivy.settings.dir}/[organisation]/[module]/[revision]/ivy.xml"/>
<artifact pattern="${ivy.settings.dir}/[organisation]/[module]/[revision]/[artifact].[ext]"/>
</filesystem>
</resolvers>
</ivysettings>

View File

@ -14,13 +14,13 @@
"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.
under the License.
-->
<ivy-module version="1.0" xmlns:e="http://ant.apache.org/ivy/extra">
<info organisation="apache" module="IVY-1111" revision="1.0" e:att="att"/>
<dependencies>
<dependency org="test" name="a" rev="latest.integration"/>
<dependency org="test" name="b" rev="latest.integration" e:att="att"/>
<dependency org="junit" name="junit" rev="latest.integration"/>
</dependencies>
<ivy-module version="2.0">
<info organisation="overlap-newer" module="modA" revision="1" />
<configurations>
<conf name="default"/>
</configurations>
<publications>
</publications>
</ivy-module>

View File

@ -0,0 +1,26 @@
<!--
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.
-->
<ivy-module version="2.0">
<info organisation="overlap-newer" module="modA" revision="5" />
<configurations>
<conf name="default"/>
</configurations>
<publications>
</publications>
</ivy-module>

View File

@ -0,0 +1,29 @@
<!--
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.
-->
<ivy-module version="2.0">
<info organisation="overlap-newer" module="modB" revision="1" />
<configurations>
<conf name="default"/>
</configurations>
<publications>
</publications>
<dependencies>
<dependency org="overlap-newer" name="modA" rev="5" conf="default->default"/>
</dependencies>
</ivy-module>

View File

@ -0,0 +1,26 @@
<!--
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.
-->
<ivy-module version="2.0">
<info organisation="overlap-older" module="modA" revision="1" />
<configurations>
<conf name="default"/>
</configurations>
<publications>
</publications>
</ivy-module>

Some files were not shown because too many files have changed in this diff Show More