Compare commits

..

179 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
Maarten Coene 2b8bff07ee
Fixed doap_Ivy.rdf 2024-12-26 11:54:50 +01:00
Maarten Coene f3215e06e6
Prepare 2.5.3 release 2024-12-23 12:47:34 +01:00
Maarten Coene f82387a131
Prepare 2.5.3 release 2024-12-23 12:47:10 +01:00
Maarten Coene ea446adbb4
Prepare 2.5.3. release 2024-12-23 11:07:48 +01:00
Maarten Coene e1753e8b4b
Prepare 2.5.3. release 2024-12-23 11:07:20 +01:00
Maarten Coene 4c7f310077
Fixed a spacing issue in the documentation footer. 2024-12-22 19:12:12 +01:00
Maarten Coene 466b299fc9
Fixed a spacing issue in the documentation footer. 2024-12-22 19:11:49 +01:00
COENE Maarten b5246c559e Fix sign task 2024-12-22 16:28:18 +01:00
Maarten Coene 79cd9b6552
bump year 2024-12-20 12:53:11 +01:00
Maarten Coene 879ef9e92b
Merge pull request #104 from maartenc/release_2.5.3
Prepare 2.5.3 release
2024-12-20 12:46:19 +01:00
Maarten Coene 54bf314780 Prepare 2.5.3 release 2024-12-20 12:45:13 +01:00
Maarten Coene 5196470c0d Fix junit tests on Windows 2024-12-20 12:44:12 +01:00
Maarten Coene 098c73410e Exclude IntelliJ IDEA artifacts 2024-12-19 10:25:42 +01:00
Maarten Coene 7c364592f0 Prepare 2.5.3 release 2024-12-19 10:09:53 +01:00
Maarten Coene 9828c8f99a
Fix indentation 2024-12-18 17:46:10 +01:00
Maarten Coene 95a8cbe57a
Fixed junit test: IvyDE has been archived 2024-11-18 09:47:25 +01:00
Maarten Coene a7ddb5b80b
Merge pull request #103 from maartenc/IVY-1651
IVY-1651: improved documentation regarding patterns and retrieve task
2024-11-17 12:32:08 +01:00
Maarten Coene 0e83732542 IVY-1651: improved documentation regarding patterns and retrieve task 2024-11-17 12:28:43 +01:00
Maarten Coene 6d0e0aa57a
Merge pull request #102 from maartenc/IVY-1649
Fix for IVY-1649 and IVY-1650
2024-11-13 00:06:53 +01:00
Maarten Coene d30c90bf86 Added default implementation for the new interface method to improve backwards compatibility + some javadoc 2024-11-13 00:01:03 +01:00
Maarten Coene e786dbb2d5 IVY-1649, IVY-1650: Fixed invalid cached Ivy file in combination with qualified extra attributes. 2024-11-12 23:51:01 +01:00
Stefan Bodewig 503aafc594 IVY-1648 some tests are failing on Java8 2023-09-15 18:09:50 +02:00
Stefan Bodewig 5d69c9a544 IVY-1647 better check whether properties/features can be set 2023-09-15 17:26:32 +02:00
Stefan Bodewig e00e9e0ee0 prepare for next development iteration 2023-08-20 16:32:58 +02:00
Stefan Bodewig 6c0560f93c update release notes with CVE-2022-46751 2023-08-20 11:59:44 +02:00
Stefan Bodewig 2be17bc18b CVE-2022-46751 don't parse doctypes and access external entities by default 2023-08-17 16:53:14 +02:00
Stefan Bodewig 6ac4f36c9e bump copyright line 2023-08-17 16:52:06 +02:00
Stefan Bodewig 6fc8657b81 prepare Ivy 2.5.2 2023-08-16 20:58:47 +02:00
Stefan Bodewig aa011feaef record HttpClient upgrade 2023-06-21 13:26:53 +02:00
Stefan Bodewig 5f11f05fe3 IVY-1642 fix POM translation for multiple artifacts in one module 2023-04-25 21:19:13 +02:00
Stefan Bodewig c63ce79f52 IVY-1641: fix NullPointerException if content type has no charset 2023-03-17 12:59:02 +01:00
Stefan Bodewig 8a5ef6825b upgrade dependencies with known vulnerabilities 2022-12-05 19:58:18 +01:00
Stefan Bodewig fe57d58632 add last two Ivy releases 2022-11-05 13:07:29 +01:00
Stefan Bodewig 4ffed6329f back to normal development 2022-11-04 12:32:53 +01:00
Stefan Bodewig 9c4802b70c update release notes with CVE information 2022-11-02 18:28:21 +01:00
Stefan Bodewig 3f374602d4 CVE-2022-37866 prevent path-traversal with bogus module coordinates 2022-11-01 10:26:24 +01:00
Stefan Bodewig 03b6b8c3ae CVE-2022-37865 ZipPacking allows overwriting arbitrary files 2022-11-01 10:14:19 +01:00
Stefan Bodewig 9d7b5e133f ignore failing test 2022-11-01 10:13:33 +01:00
Stefan Bodewig 55179bb0b6 need newer version of RAT for https license URIs 2022-11-01 10:13:15 +01:00
Stefan Bodewig ff6adbeb00 prepare Ivy 2.5.1 2022-11-01 09:56:06 +01:00
Stefan Bodewig 259d054396 switch to https 2022-08-07 19:41:57 +02:00
Jaikiran Pai cd9296a409 add contributor of IVY-1632 to contributors list 2022-01-15 09:57:01 +05:30
Jaikiran a2701d733a
Merge pull request #96 from bernolanger/master
IVY-1632: Use valid value for HTTP header "Accept".
2022-01-15 04:21:07 +00:00
Jaikiran Pai 1fe3c3cff6 repo.jfrog.org is no longer available 2021-12-23 10:42:52 +05:30
Berno Langer 17a0d80da3 IVY-1632: Use valid value for HTTP header "Accept".
The default accept header of Java isn't valid as described at
https://bugs.openjdk.java.net/browse/JDK-8163921

Therefore set an accept header that accepts simply anything in the
ivy:retrieve Ant task.
2021-12-20 09:39:25 +01:00
Maarten Coene c14e2ba5a7
Merge pull request #95 from maartenc/IvyRetrieveEmptySet
IVY-1631: ivy:retrieve Ant task and empty FileSet bug
2021-11-24 16:18:41 +01:00
Maarten Coene 0170436231 Extra test to check that the created path is also empty 2021-11-24 13:10:59 +01:00
Maarten Coene 17f2727826 Extra test to check that the created path is also empty 2021-11-24 13:06:08 +01:00
Maarten Coene 0864db0364 set the project a bit sooner so it can be used within the other methods 2021-11-23 17:47:28 +01:00
Maarten Coene f760b390e5 IVY-1631: when the ivy:retrieve Ant task retrieves the jars to a non-empty directory, but the retrieve task itself didn't retrieve any files, the created fileset was not empty but contained the existing files in that directory. 2021-11-23 17:37:04 +01:00
Jaikiran Pai 8e2bdfb302 IVY-1616 Properly parse the artifact origin location, if the location is a file: URI 2021-03-29 13:06:52 +05:30
Jason Guild 424fa89419 IVY-1615 implement retrieval of ivysettings from url in standalone.
Closes #91 pull request at github.com/apache/ant-ivy repo
2021-03-29 10:12:45 +05:30
Jaikiran Pai ac9af265f9 Update release notes 2021-03-29 09:39:22 +05:30
Jaikiran Pai 370e52b74a IVY-1618 Don't change the dependency resolver configure on Ivy settings when setting the one on ResolveEngine 2021-03-29 09:33:15 +05:30
Jaikiran Pai a4ab62a717 IVY-1626 Add a note to bintray resolver documentation, that bintray and JCenter are being decommissioned 2021-03-29 08:44:32 +05:30
Jaikiran Pai f1093f67d4 IVY-1628 Add a testcase to reproduce the issue and verify the fix 2021-03-25 09:51:06 +05:30
Jaikiran Pai 083e3f685c IVY-1628 Fix potential ConcurrentModificationException 2021-03-23 07:30:30 +05:30
Maarten Coene 79bd0ce1f4 Documentation fix: the [originalname] token does NOT contains the extension! 2021-02-17 09:55:36 +01:00
Jaikiran Pai 2cf83cc35a IVY-1614 Add a test to show that Maven version range exclusion syntax is correctly honoured 2021-02-13 10:24:00 +05:30
Jaikiran Pai 70dfaf2467 Allow jacoco coverage to be disabled when running tests
This allows us to run the Ivy testsuite against latest Java
early access versions without having to wait for the instrumentation
libraries (that jacoco coverage needs) to start supporting the
class version of the new Java version being tested.
2021-01-16 19:47:22 +05:30
Jaikiran Pai 824e8eebfe Skip Pack200 tests from JDK >=14 (since Pack200 tools and API have now been removed from that JDK version) 2021-01-16 09:54:16 +05:30
Jaikiran Pai 27491e3688 Use https for IvyDE updatesite test 2021-01-15 20:59:19 +05:30
Jaikiran Pai 66547a20a0 jfrog repo now redirects http to https - use https in the test 2021-01-15 20:20:43 +05:30
Jaikiran Pai ad87c251aa Upgrade to 0.8.6 of jacoco 2021-01-15 18:21:07 +05:30
Simon Legner bb8cfa726c
RetrieveEngine: remove superfluous space in error 2020-04-05 12:26:10 +02:00
Jaikiran Pai 87de654504 Use newer version of jacoco 2019-11-02 18:53:44 +05:30
Jaikiran Pai 4c1347531e Add Java 8 runtime requirement to release notes 2019-11-02 18:39:56 +05:30
Jaikiran Pai 6364399673 Remove property which seems to be unused 2019-11-02 18:36:00 +05:30
Jaikiran Pai 6edcf2631d No longer required in Java 8 2019-11-02 18:32:22 +05:30
Jaikiran Pai 28eb66db03 Upgrade ivy.api.reference version to 2.5.0
Contributed-by: Gintautas Grigelionis
Pull request: https://github.com/apache/ant-ivy/pull/90/
2019-11-02 18:24:17 +05:30
Jaikiran Pai 5a5e3eb084 Use newer version of Ivy in example
Contributed-by: Gintautas Grigelionis
Pull request: https://github.com/apache/ant-ivy/pull/90
2019-11-02 18:23:15 +05:30
Jaikiran Pai b5f8c9d7e5 Fix link in release notes.
Contributed-by: Gintautas Grigelionis
Pull request: https://github.com/apache/ant-ivy/pull/90/
2019-11-02 18:19:09 +05:30
Jaikiran Pai 8e29e307d6 Upgrade to latest versions of bouncycastle and httpclient
Contributed-by: Gintautas Grigelionis
Pull request: https://github.com/apache/ant-ivy/pull/90/
2019-11-02 18:18:34 +05:30
Jaikiran Pai c0c8df492d Remove the workaround introduced in commit 5918182e0d, now that we require minimum Java 8 runtime 2019-11-02 18:11:07 +05:30
Jaikiran Pai bf82dbedbe Minimum Java version is now 1.8 2019-11-02 18:07:14 +05:30
Jaikiran Pai a9c0602304 next version is 2.6.0 2019-11-02 09:12:35 +05:30
Jan Matrne ecf6c2e009 BREAKING: Removed old fr\jayasoft\ivy\ant\antlib.xml AntLib definition file (jira:IVY-1612) 2019-10-25 08:41:22 +02:00
Jaikiran Pai be85129fce next dev version 2019-10-24 16:24:17 +05:30
176 changed files with 5884 additions and 2054 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-2019 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

@ -115,7 +115,11 @@ the configuration name
`[originalname]`::
(*__since 1.4__*) +
the original artifact name (including the extension)
the original artifact name (not including the extension)
`[classifier]`::
(*__since 1.4__*) +
the artifact classifier for Maven dependencies
The difference between type and extension is explained in the Ivy file documentation.

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

@ -54,7 +54,7 @@ If you want to use Ivy only in your Ant build scripts, and have an internet conn
[source,xml]
----
<project xmlns:ivy="antlib:org.apache.ivy.ant">
<property name="ivy.install.version" value="2.1.0-rc2"/>
<property name="ivy.install.version" value="2.5.0"/>
<condition property="ivy.home" value="${env.IVY_HOME}">
<isset property="env.IVY_HOME"/>
</condition>

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_.

View File

@ -15,26 +15,11 @@
* limitations under the License.
*
*/
package org.apache.ivy.util.url;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import java.net.URL;
import java.util.List;
import org.junit.Test;
public class ArtifactoryListingTest {
// remote.test
@Test
public void testWicketListing() throws Exception {
ApacheURLLister lister = new ApacheURLLister();
List<URL> content = lister.listAll(new URL(
"http://repo.jfrog.org/artifactory/libs-releases-local/org/apache/wicket/wicket/"));
assertNotNull(content);
assertEquals(3, content.size());
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
20th October 2019 - The Apache Ivy project is pleased to announce its 2.5.0 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,78 +34,15 @@ More information about the project can be found on the website link:https://ant.
== Key features in this release
Key features of this 2.5.0 release are:
* The minimum runtime Java version required is now Java 7
* Ivy now uses BouncyCastle OpenPGP API 1.59. Due to the non backward compatibility of that library, earlier versions are not supported.
* Ivy now uses HttpComponents HttpClient 4.5.x version with HTTP backed resolvers. Users are expected to have this version of the library (and its dependencies) in their runtime classpath if they want to use such resolvers. The previous (similarly named but not the same) commons-httpclient library is no longer used or supported. (jira:IVY-1563[])
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.4.0:*
- FIX: Local conflict manager didn't handle deeper conflicts in transitive dependencies (jira:IVY-1404[])
- FIX: Made the Maven 'test' configuration public so we can use the test-jar as dependency (jira:IVY-1444[])
- FIX: NullPointerException in dependencytree with no dependencies (jira:IVY-1539[])
- FIX: checkIfChanged is not settable attribute for checkdepsupdate ant task (jira:IVY-1549[])
- FIX: ArrayIndexOutOfBoundsException when using a p2 repository for dependencies (jira:IVY-1504[])
- FIX: fixdeps remove transitive 'kept' dependencies
- FIX: PomModuleDescriptorParser should parse licenses from parent POM (jira:IVY-1526[]) (Thanks to Jaikiran Pai)
- FIX: dynamic revisions are not cached per resolver (jira:IVY-1430[]) (Thanks to Stephen Haberman)
- FIX: Dependencies failed using branch attribute (and extra attributes) (jira:IVY-1141[]) (Thanks to Stephen Haberman)
- FIX: useCacheOnly should allow lookup of changing dependencies in cache (jira:IVY-1515[]) (Thanks to Ilya)
- FIX: Translation of POM to Ivy XML with * exclusion is removing main artifact (jira:IVY-1531[]) (Thanks to Jaikiran Pai)
- FIX: Have makepom task take description from ivy-module > info > description element (jira:IVY-1520[])
- FIX: Fix RetrieveEngine to take into account the correct extension while dealing with unpacked artifacts (jira:IVY-1478[]) (Thanks to Jaikiran Pai)
- FIX: ParseException "Unsupported repository, resources names are not uris" for ivy.xml with parent on Windows (jira:IVY-1448[]) (Thanks to Riccardo Foschia and Jaikiran Pai)
- FIX: Ivy 2.4.0 improperly handles modules with colon (:) in version (jira:IVY-1522[]) (Thanks to Jaikiran Pai)
- FIX: Delay the processing of configured cache ttls, until the IvySettings object is usable (jira:IVY-1495[]) (Thanks to Jaikiran Pai)
- FIX: Including optional ivysettings of type 'file' doesn't work when file doesn't exist (jira:IVY-1555[]) (Thanks to Jaikiran Pai)
- FIX: Makepom ignores dependency classifiers (jira:IVY-1528[]) (Thanks to Jaikiran Pai)
- FIX: Infinite loop in dependency tree (jira:IVY-1540[]) (Thanks to Jaikiran Pai)
- FIX: HTTP issue: Basic authentication is stuck in 401 loop (jira:IVY-1336[])
- FIX: command line: -types seems to not accept comma (jira:IVY-1355[])
- FIX: Mixed use of symlinks leads to cache corruption (jira:IVY-1498[]) (Thanks to Stephen Haberman)
- FIX: Some cached locations are stored incorrectly resulting in MalformedURLException (jira:IVY-1566[]) (Thanks to Aur&eacute;lien Pupier)
- FIX: defaultconf/mapping attributes ignored when extended/included from parent file (jira:IVY-1315[] jira:IVY-1419[] jira:IVY-1420[] jira:IVY-1437[]) (Thanks to Willem Verstraeten)
- FIX: ApacheURLLister skips versions with URL encoded characters (jira:IVY-1442[] jira:IVY-1573[])
- FIX: Configuration lists are sensitive to whitespace; multiple split/merge methods (jira:IVY-309[] jira:IVY-1282[])
- FIX: Warnings about illegal reflection access due to lack of methods to retrieve default authenticator in Java 5 to 8 (jira:IVY-1569[])
- FIX: Cycle in parent POM ancestry yields StackOverflowError in PomModuleDescriptorParser (jira:IVY-1545[]) (Thanks to Brett Randall)
- FIX: The method hasIvyListener in org.apache.ivy.core.event.EventManager always returned false
- FIX: Allow conditionally activated properties through Maven profiles, to be referenced in the `pom.xml` (jira:IVY-1577[])
- FIX: Fix Maven dependency resolution for dependencies with multiple different classifiers (jira:IVY-1576[])
- FIX: Correct parent classloader when lauching resolved artifacts from CLI (jira:IVY-1483[]) (Thanks to Stephan Feder)
- FIX: Make Main.run() public (usable with REPL) (jira:IVY-1321[] jira:IVY-1578[]) (Thanks to Greg Perry)
- FIX: Make ivy.deps.changed work with extra attributes (jira:IVY-1104[]) (Thanks to Arseny Aprelev)
- FIX: Implement dependency configuration negation (jira:IVY-982[] jira:IVY-1547[]) (Thanks to Arseny Aprelev)
- FIX: Don't throw a CircularDependencyException when parsing an import scoped dependency in dependencyManagement section of a pom (jira:IVY-1588[])
- FIX: Respect exclude regardless of resolution order (jira:IVY-1486[]) (thanks to David Turner)
- FIX: ModuleDescriptorMemoryCache didn't detect outdated entries when Ivy file was updated in the cache by another process
- FIX: Store ArtifactOrigin's location as a URL
- FIX: Retrieve task, with symlink enabled, would not create symlinks for artifacts in certain specific cases (jira:IVY-1594[])
- FIX: Generated ivy.xml from pom with multiple dependencies with different classifier does not contain the main dependency (jira:IVY-1580[])
- IMPROVEMENT: Throw an IllegalStateException when retrieving the resolutionCacheRoot on the DefaultResolutionCacheManager if the basedir (or IvySettings) is not set (jira:IVY-1482[])
- IMPROVEMENT: Optimization: limit the revision numbers scanned if revision prefix is specified (Thanks to Ernestas Vaiciukevi&ccaron;ius)
- IMPROVEMENT: Update BouncyCastle to 1.59 (jira:IVY-1521[]) (Thanks to Michal Srb)
- IMPROVEMENT: `symlinkmass` option of retrieve task has been deprecated in this release and will no longer be supported since, starting this version of Ivy, Ivy uses Java standard API(s) for symlink management and as such doesn't spawn a process to execute symlink creation shell commands, like it used to do earlier. The `symlinkmass` option was previously there to launch just one single process instead of multiple processes for symlink creation. Now with the usage of the Java standard API(s), this option no longer is relevant.
- IMPROVEMENT: Ivy command line now supports passing `overwriteMode` option to `retrieve` task (jira:IVY-1447[])
- IMPROVEMENT: Support timestamped SNAPSHOT versions from Maven repository (jira:IVY-1153[] jira:IVY-1476[])
- IMPROVEMENT: Update Commons VFS to 2.2
- IMPROVEMENT: Ivy now supports activating of Maven profiles, in `pom.xml`, by `jdk`, `os`, `property` and `file` (jira:IVY-1558[] jira:IVY-1577[])
- IMPROVEMENT: Better thread safety of the resolve process
- NEW: Lets SSH-based resolvers use an `~/.ssh/config` file to find username/hostname/keyfile options (Thanks to Colin Stanfill)
- NEW: Add ivy.maven.lookup.sources and ivy.maven.lookup.javadoc variables to control the lookup of the additional artifacts. Defaults to true, for backward compatibility (jira:IVY-1529[])
- NEW: Add (conditional) support for SHA-256, SHA-512 and SHA-384 checksum algorithms (jira:IVY-1554[]) (Thanks to Jaikiran Pai)
- NEW: The standalone Ivy jar can now be used to generate a pom file for the resolved module, using the `makepom` option (Thanks to link:https://github.com/aanno[Thomas Pasch])
- NEW: The buildlist task can now have `root` and `leaf` subelements to specify the organisation (and other attributes) of the root and leaf modules (jira:/IVY-1242[]) and (jira:IVY-1293[])
*List of changes since Ivy 2.6.1:*
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 :
@ -128,9 +65,11 @@ 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
* Jaikiran Pai
* Jon Schneider
* Gilles Scokart
* Stefan Bodewig
*Contributors:*
@ -140,6 +79,7 @@ Here is the list of people who have contributed source code and documentation up
* Andreas Axelsson
* St&eacute;phane Bailliez
* Karl Baum
* Moritz Baumann
* Andrew Bernhagen
* Mikkel Bjerg
* Per Arnold Blaasmo
@ -153,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
@ -163,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
@ -177,6 +119,7 @@ Here is the list of people who have contributed source code and documentation up
* Mitch Gitman
* Evgeny Goldin
* Scott Goldstein
* Jason A. Guild
* Stephen Haberman
* Aaron Hachez
* Ben Hale
@ -195,10 +138,12 @@ 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
* Thomas Kurpick
* Berno Langer
* Costin Leau
* Ilya Leoshkevich
* Tat Leung
@ -207,19 +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

@ -56,6 +56,7 @@
A default, defines a link:https://bintray.com/bintray/jcenter[JCenter] bintray resolver.
In most circumstances you won't need any other resolvers as JCenter is already a super-set of many other repositories, including Maven Central.
NOTE: Bintray and JCenter are being decommissioned by their service provider in the year 2021/2022. Once they are decommissioned, this resolver will no longer work. The original announcement can be read at https://jfrog.com/blog/into-the-sunset-bintray-jcenter-gocenter-and-chartcenter/
'''

View File

@ -72,9 +72,9 @@ This resolver shares the link:../settings/resolvers{outfilesuffix}#common[common
[options="header",cols="15%,50%,35%"]
|=======
|Attribute|Description|Required
|m2compatible|True if this resolver should be Maven 2 compatible, false otherwise (*__since 1.3__*)|No, defaults to false
|m2compatible|True if this resolver should be Maven 2 compatible, false otherwise (*__since 1.3__*).|No, defaults to false
|local|True if this resolver should be considered local, false otherwise (*__since 1.4__*). See useOrigin attribute on the link:../settings/caches{outfilesuffix}[caches] element for details.|No, defaults to true
|transactional|true to force the use of transaction, false to prevent the use of transaction, auto to get transaction when possible (*__since 2.0__*). See above for details.|No, defaults to auto
|transactional|True to force the use of transaction, false to prevent the use of transaction, auto to get transaction when possible (*__since 2.0__*). See above for details.|No, defaults to auto
|=======
@ -84,6 +84,6 @@ This resolver shares the link:../settings/resolvers{outfilesuffix}#common[common
[options="header"]
|=======
|Element|Description|Cardinality
|ivy|defines a pattern for Ivy files, using the pattern attribute|0..n
|artifact|defines a pattern for artifacts, using the pattern attribute|1..n
|ivy|Defines a link:../concept{outfilesuffix}#patterns[pattern] for Ivy files, using the pattern attribute.|0..n
|artifact|Defines a link:../concept{outfilesuffix}#patterns[pattern] for artifacts, using the pattern attribute.|1..n
|=======

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

@ -53,8 +53,8 @@ This resolver shares the link:../settings/resolvers{outfilesuffix}#common[common
[options="header"]
|=======
|Element|Description|Cardinality
|ivy|defines a pattern for Ivy files, using the pattern attribute|0..n
|artifact|defines a pattern for artifacts, using the pattern attribute|1..n
|ivy|Defines a link:../concept{outfilesuffix}#patterns[pattern] for Ivy files, using the pattern attribute.|0..n
|artifact|Defines a link:../concept{outfilesuffix}#patterns[pattern] for artifacts, using the pattern attribute.|1..n
|=======

View File

@ -50,8 +50,8 @@ This resolver shares the link:../settings/resolvers{outfilesuffix}#common[common
[options="header"]
|=======
|Element|Description|Cardinality
|ivy|defines a pattern for Ivy files, using the pattern attribute|0..n
|artifact|defines a pattern for artifacts, using the pattern attribute|1..n
|ivy|Defines a link:../concept{outfilesuffix}#patterns[pattern] for Ivy files, using the pattern attribute.|0..n
|artifact|Defines a link:../concept{outfilesuffix}#patterns[pattern] for artifacts, using the pattern attribute.|1..n
|=======

View File

@ -82,8 +82,8 @@ Configure a resourceURL in situations where you don't want to rely on (or wait f
[options="header"]
|=======
|Element|Description|Cardinality
|ivy|Defines a pattern for ivy.xml files, using the pattern attribute|1..n
|artifact|Defines a pattern for packager.xml files, using the pattern attribute|1..n
|ivy|Defines a link:../concept{outfilesuffix}#patterns[pattern] for Ivy files, using the pattern attribute.|0..n
|artifact|Defines a link:../concept{outfilesuffix}#patterns[pattern] for artifacts, using the pattern attribute.|1..n
|=======

View File

@ -70,8 +70,8 @@ This resolver shares the link:../settings/resolvers{outfilesuffix}#common[common
[options="header"]
|=======
|Element|Description|Cardinality
|ivy|defines a pattern for Ivy files, using the pattern attribute|0..n
|artifact|defines a pattern for artifacts, using the pattern attribute|1..n
|ivy|Defines a link:../concept{outfilesuffix}#patterns[pattern] for Ivy files, using the pattern attribute.|0..n
|artifact|Defines a link:../concept{outfilesuffix}#patterns[pattern] for artifacts, using the pattern attribute.|1..n
|=======

View File

@ -59,8 +59,8 @@ This resolver shares the link:../settings/resolvers{outfilesuffix}#common[common
[options="header"]
|=======
|Element|Description|Cardinality
|ivy|defines a pattern for Ivy files, using the pattern attribute|0..n
|artifact|defines a pattern for artifacts, using the pattern attribute|1..n
|ivy|Defines a link:../concept{outfilesuffix}#patterns[pattern] for Ivy files, using the pattern attribute.|0..n
|artifact|Defines a link:../concept{outfilesuffix}#patterns[pattern] for artifacts, using the pattern attribute.|1..n
|=======

View File

@ -49,8 +49,8 @@ This resolver shares the link:../settings/resolvers{outfilesuffix}#common[common
[options="header"]
|=======
|Element|Description|Cardinality
|ivy|defines a pattern for Ivy files, using the pattern attribute|0..n
|artifact|defines a pattern for artifacts, using the pattern attribute|1..n
|ivy|Defines a link:../concept{outfilesuffix}#patterns[pattern] for Ivy files, using the pattern attribute.|0..n
|artifact|Defines a link:../concept{outfilesuffix}#patterns[pattern] for artifacts, using the pattern attribute.|1..n
|=======

View File

@ -41,8 +41,8 @@ This resolver shares the link:../settings/resolvers{outfilesuffix}#common[common
[options="header"]
|=======
|Element|Description|Cardinality
|ivy|defines a pattern for Ivy files, using the pattern attribute|0..n
|artifact|defines a pattern for artifacts, using the pattern attribute|1..n
|ivy|Defines a link:../concept{outfilesuffix}#patterns[pattern] for Ivy files, using the pattern attribute.|0..n
|artifact|Defines a link:../concept{outfilesuffix}#patterns[pattern] for artifacts, using the pattern attribute.|1..n
|=======

View File

@ -38,7 +38,7 @@
<!-- here is the version of Ivy we will use. change this property to try a newer
version if you want -->
<property name="ivy.install.version" value="2.4.0"/>
<property name="ivy.install.version" value="2.5.0"/>
<property name="ivy.jar.dir" value="${basedir}/ivy"/>
<property name="ivy.jar.file" value="${ivy.jar.dir}/ivy.jar"/>

View File

@ -23,6 +23,8 @@ In order to work as you want, Ivy sometimes needs some settings. Actually, Ivy c
Settings are specified through an XML file, usually called `ivysettings.xml`. To configure Ivy from Ant, you just have to use the link:use/settings{outfilesuffix}[settings] datatype with the path of your settings file.
In addition certain link:systemproperties{outfilesuffix}[Java system properties] affect the XML parsing behavior of Ivy.
Here is an example of the settings file:
[source, xml]

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

@ -0,0 +1,67 @@
////
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.
////
= Java System Properties Affecting Ivy
== XML Parser Settings
Starting with Ivy 2.5.2 Ivy's XML parser can be controlled via the use
of two newly introduced system properties.
If you want to restore the default behavior of Ivy 2.5.1 and earlier
you need to set `ivy.xml.allow-doctype-processing` to `true` and
`ivy.xml.external-resources` to `ALL`.
=== `ivy.xml.allow-doctype-processing`
This system property accepts `true` or `false` as values. When set to
`false` Ivy will not allow any processing of doctype declarations at
all, while setting it to `true` enables it.
The default is to allow doctype processing if and only if Ivy is
parsing a Maven POM file.
=== `ivy.xml.external-resources`
This system property controls if external resources are read during
doctype processing - and if so, where they can be loadad from. The
value of this system property is only ever used if
`ivy.xml.allow-doctype-processing` is not `false`.
The accepted values are
* `PROHIBIT` makes Ivy fail if any doctype tries to load an external
resource.
* `IGNORE` makes Ivy ignore any external resource that the doctype
declaration wants to load.
* `LOCAL_ONLY` allows external resources to be loaded via `file:` or
`jar:file` URIs only.
* `ALL` allows external resources to be loaded from any URI.
The default behavior is to not allow doctype processing at all, but if
it is enabled the value `PROHIBIT` is assumed unless the property has
been set explicitly.
When reading Maven POMs a specific internal system id is recognized as
resource and will be loaded from a resource shipping with the Ivy
distribution in order to deal with invalid POM files accepted by
Apache Maven - and the default value for this property is
`IGNORE`in that case. See
link:https://issues.apache.org/jira/browse/IVY-921[IVY-921] for
details.

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"
@ -44,7 +44,7 @@ html lang=(attr :lang, 'en' unless attr? :nolang)
i
| Copyright &copy; 2007 -
= " " + Time.now.year.to_s + " "
| The Apache Software Foundation, Licensed under the
' The Apache Software Foundation, Licensed under the
a href="http://www.apache.org/licenses/" Apache License, Version 2.0
| .
br/

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%"
@ -81,7 +85,7 @@ html lang=(attr :lang, 'en' unless attr? :nolang)
i
| Copyright &copy; 2007 -
= " " + Time.now.year.to_s + " "
| The Apache Software Foundation, Licensed under the
' The Apache Software Foundation, Licensed under the
a href="http://www.apache.org/licenses/" Apache License, Version 2.0
| .
br/

View File

@ -150,6 +150,11 @@
}
]
},
{
"id": "systemproperties",
"title": "System Properties",
"children": []
},
{
"id":"settings",
"title":"Settings Files",

View File

@ -87,7 +87,7 @@ This element takes the following attributes: +
* `organisation`: the organisation of the root module (defaults to *) +
* `module`: the name of the root module (defaults to *) +
* `revision`: the revision of the root module (defaults to *) +
* `branch`: the branch of the root module (default to *)
* `branch`: the branch of the root module (default to *) +
* `file`: a specific ivy.xml file to use as root module|0..n
|leaf|(*__since 2.5__*) Declares a leaf module.
@ -95,7 +95,7 @@ This element takes the following attributes: +
* `organisation`: the organisation of the leaf module (defaults to *) +
* `module`: the name of the leaf module (defaults to *) +
* `revision`: the revision of the leaf module (defaults to *) +
* `branch`: the branch of the leaf module (default to *)
* `branch`: the branch of the leaf module (default to *) +
* `file`: a specific ivy.xml file to use as leaf module|0..n
|=======

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

@ -35,8 +35,8 @@ For instance, for the pattern `lib/[conf]/[artifact].[ext]`, the root will be `l
[options="header",cols="15%,50%,35%"]
|=======
|Attribute|Description|Required
|pattern|the pattern to use to copy the dependencies|No. Defaults to `${ivy.retrieve.pattern}`
|ivypattern|the pattern to use to copy the Ivy files of dependencies (*__since 1.3__*)|No. Dependency Ivy files are not retrieved by default.
|pattern|The link:../concept{outfilesuffix}#patterns[pattern] to use to copy the dependencies. Make sure to specify a pattern that defines unique filenames for the artifacts.|No. Defaults to `${ivy.retrieve.pattern}`
|ivypattern|the link:../concept{outfilesuffix}#patterns[pattern] to use to copy the Ivy files of dependencies (*__since 1.3__*)|No. Dependency Ivy files are not retrieved by default.
|conf|a comma separated list of the configurations to retrieve|No. Defaults to the configurations resolved by the last resolve call, or `$$*$$` if no resolve was explicitly called
|sync|`true` to synchronize the destination, false to just make a copy (*__since 1.4__*)|No. Defaults to `false`
|type|comma separated list of accepted artifact types (*__since 1.4__*)|No. All artifact types are accepted by default.

View File

@ -58,9 +58,6 @@
<sysproperty key="ivy.local.default.root" value="${tutorial.local-repo}"/>
<sysproperty key="ivy.cache.ttl.default" value="1s"/>
<sysproperty key="skip.download" value="true"/>
<!-- We select specific HTTPS protocols, based on the Java version we are running
on -->
<sysproperty key="https.protocols" value="${java.sysprop.https.protocols}"/>
<arg line="-f @{antfile}"/>
<arg line="@{target}"/>
</java>
@ -291,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/**"/>
@ -314,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">
@ -321,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]"/>
@ -337,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>
@ -364,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}"/>
@ -376,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>
@ -393,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">
@ -401,6 +410,8 @@
<include name="*.jar"/>
<include name="*.zip"/>
<include name="*.gz"/>
<include name="*.cdx.json"/>
<include name="*.cdx.xml"/>
</fileset>
</checksum>
</target>
@ -441,9 +452,9 @@
<ivy2:cachepath organisation="org.apache.commons" settingsRef="sign.settingsId" transitive="false" log="download-only"
module="commons-openpgp" revision="1.0-SNAPSHOT" inline="true" pathid="openpgp.classpath"/>
<ivy2:cachepath organisation="org.bouncycastle" settingsRef="sign.settingsId" log="download-only"
module="bcprov-jdk16" revision="1.45" inline="true" pathid="bouncycastle.bcprov.classpath"/>
module="bcprov-jdk15on" revision="1.60" inline="true" pathid="bouncycastle.bcprov.classpath"/>
<ivy2:cachepath organisation="org.bouncycastle" settingsRef="sign.settingsId" transitive="false" log="download-only"
module="bcpg-jdk16" revision="1.45" inline="true" pathid="bouncycastle.bcpg.classpath"/>
module="bcpg-jdk15on" revision="1.60" inline="true" pathid="bouncycastle.bcpg.classpath"/>
<!--
For some reason, if we use the openpgp:signer task here directly, the bouncycastle security
@ -474,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"/>
@ -483,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.12"
<ivy:cachepath organisation="org.apache.rat" module="apache-rat-tasks" revision="0.16.1"
inline="true" conf="default" pathid="rat.classpath"
log="download-only"/>
@ -495,9 +508,12 @@
<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"/>
<exclude name=".ivy2/**/*"/>
<exclude name=".idea/**/*"/>
<exclude name="build/**/*"/>
<exclude name="bin/**/*"/>
<exclude name="**/*.md5"/>
@ -556,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>
@ -563,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"
@ -637,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

@ -44,10 +44,9 @@ checkstyle.report.dir=${reports.dir}/checkstyle
checkstyle.src.dir=${basedir}/src/etc/checkstyle
rat.report.dir=${reports.dir}/rat
ivy.minimum.javaversion=1.7
ivy.minimum.javaversion=1.8
debug.mode=on
ivy.install.version=1.4.1
ivy.api.reference=2.4.0
ivy.api.reference=2.5.0
#status=integration

View File

@ -23,12 +23,10 @@
<property file="build.properties"/>
<property name="final.name" value="ivy.jar"/>
<!-- Java 7 runs into TLS protocol issues when dealing with repositories
that no longer support older protocols -->
<condition property="java.sysprop.https.protocols" value="" else="TLSv1.2">
<javaversion atleast="1.8"/>
</condition>
<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}">
@ -259,10 +257,6 @@
<exclude name="**/*.java"/>
</fileset>
</copy>
<!-- copy antlib for backward compatibility with fr.jayasoft.ivy package -->
<copy file="${ant.classes.build.dir}/org/apache/ivy/ant/antlib.xml"
todir="${ant.classes.build.dir}/fr/jayasoft/ivy/ant"/>
</target>
<target name="compile-optional" depends="compile-ant">
@ -438,7 +432,7 @@
</target>
<target name="init-jacoco" depends="jar" unless="skip.test">
<ivy:cachepath organisation="org.jacoco" module="org.jacoco.ant" revision="0.8.3"
<ivy:cachepath organisation="org.jacoco" module="org.jacoco.ant" revision="${jacoco.version}"
inline="true" conf="default" pathid="jacoco.classpath" log="download-only"/>
<taskdef uri="antlib:org.jacoco.ant" resource="org/jacoco/ant/antlib.xml"
classpathref="jacoco.classpath"/>
@ -449,8 +443,10 @@
<!-- multiple runs into the same logfile let the later report generation fail -->
<delete file="${jacoco.log}"/>
<property name="jacoco.coverage.enabled" value="true"/>
<jacoco:coverage xmlns:jacoco="antlib:org.jacoco.ant" destfile="${jacoco.log}"
exclclassloader="sun.reflect.DelegatingClassLoader:javassist.Loader">
exclclassloader="sun.reflect.DelegatingClassLoader:javassist.Loader"
enabled="${jacoco.coverage.enabled}">
<junit
haltonfailure="off"
haltonerror="off"
@ -470,9 +466,6 @@
<syspropertyset>
<propertyref prefix="http"/>
</syspropertyset>
<!-- We select specific HTTPS protocols, based on the Java version we are running
on -->
<sysproperty key="https.protocols" value="${java.sysprop.https.protocols}"/>
<!-- Added this to test IVY-65 -->
<jvmarg value="-Duser.region=TR"/>
@ -608,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,41 @@
<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>
<created>2023-12-23</created>
<revision>2.5.3</revision>
</Version>
</release>
<release>
<Version>
<name>Apache Ivy 2.5.2</name>
<created>2023-08-20</created>
<revision>2.5.2</revision>
</Version>
</release>
<release>
<Version>
<name>Apache Ivy 2.5.1</name>
<created>2022-11-04</created>
<revision>2.5.1</revision>
</Version>
</release>
<release>
<Version>
<name>Apache Ivy 2.5.0</name>
<created>2019-10-20</created>
<revision>2.5.0</revision>
</Version>
</release>
<release>
<Version>
<name>Apache Ivy 2.4.0</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

@ -38,7 +38,7 @@
<!-- here is the version of ivy we will use. change this property to try a newer
version if you want -->
<property name="ivy.install.version" value="2.0.0-beta1"/>
<property name="ivy.install.version" value="2.5.0"/>
<property name="ivy.jar.dir" value="${basedir}/ivy"/>
<property name="ivy.jar.file" value="${ivy.jar.dir}/ivy.jar"/>

View File

@ -24,6 +24,8 @@ import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
@ -76,8 +78,8 @@ public final class Main {
return new CommandLineParser()
.addCategory("settings options")
.addOption(
new OptionBuilder("settings").arg("settingsfile")
.description("use given file for settings").create())
new OptionBuilder("settings").arg("settingsfile|url")
.description("use given file or URL for settings").create())
.addOption(
new OptionBuilder("properties").arg("propertiesfile")
.description("use given file for properties not specified in settings").create())
@ -515,17 +517,39 @@ public final class Main {
if ("".equals(settingsPath)) {
ivy.configureDefault();
} else {
File conffile = new File(settingsPath);
if (!conffile.exists()) {
error("ivy configuration file not found: " + conffile);
} else if (conffile.isDirectory()) {
error("ivy configuration file is not a file: " + conffile);
final URI confUri = getSettingsURI(settingsPath);
if ("file".equals(confUri.getScheme())) {
File conffile = new File(confUri);
if (!conffile.exists()) {
throw new IOException("ivy configuration file not found: " + conffile);
} else if (conffile.isDirectory()) {
throw new IOException("ivy configuration file is not a file: " + conffile);
}
ivy.configure(conffile);
} else {
try {
ivy.configure(confUri.toURL());
} catch (IOException ioe) {
throw new IOException("ivy configuration failed to load from: " + settingsPath, ioe);
}
}
ivy.configure(conffile);
}
return settings;
}
private static URI getSettingsURI(String settingsPath) {
URI settingsUri;
try {
settingsUri = new URI(settingsPath);
if (settingsUri.getScheme() == null) {
settingsUri = new File(settingsPath).toURI();
}
} catch (URISyntaxException badUriEx) {
return new File(settingsPath).toURI();
}
return settingsUri;
}
private static void initMessage(CommandLine line, Ivy ivy) {
if (line.hasOption("debug")) {
ivy.getLoggerEngine().pushLogger(new DefaultMessageLogger(Message.MSG_DEBUG));

View File

@ -0,0 +1,71 @@
/*
* 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.ant;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.types.Resource;
import java.util.Iterator;
import java.util.NoSuchElementException;
class EmptyFileSet extends FileSet {
private DirectoryScanner ds = new EmptyDirectoryScanner();
public Iterator<Resource> iterator() {
return new EmptyIterator<>();
}
public Object clone() {
return new EmptyFileSet();
}
public int size() {
return 0;
}
public DirectoryScanner getDirectoryScanner(Project project) {
return ds;
}
private static class EmptyIterator<T> implements Iterator<T> {
public boolean hasNext() {
return false;
}
public T next() {
throw new NoSuchElementException("EmptyFileSet Iterator");
}
public void remove() {
throw new IllegalStateException("EmptyFileSet Iterator");
}
}
private static class EmptyDirectoryScanner extends DirectoryScanner {
public String[] getIncludedFiles() {
return new String[0];
}
}
}

View File

@ -28,8 +28,6 @@ import java.util.Set;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult;
@ -43,6 +41,7 @@ import org.apache.ivy.core.resolve.IvyNode;
import org.apache.ivy.core.resolve.ResolveOptions;
import org.apache.ivy.core.resolve.ResolvedModuleRevision;
import org.apache.ivy.core.retrieve.RetrieveOptions;
import org.apache.ivy.util.XMLHelper;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.xml.sax.SAXException;
@ -170,10 +169,8 @@ public class IvyArtifactReport extends IvyPostResolveTask {
}
private TransformerHandler createTransformerHandler(FileOutputStream fileOutputStream)
throws TransformerFactoryConfigurationError, TransformerConfigurationException {
SAXTransformerFactory transformerFact = (SAXTransformerFactory) SAXTransformerFactory
.newInstance();
TransformerHandler saxHandler = transformerFact.newTransformerHandler();
throws TransformerConfigurationException {
TransformerHandler saxHandler = XMLHelper.getTransformerHandler();
saxHandler.getTransformer().setOutputProperty(OutputKeys.ENCODING, "UTF-8");
saxHandler.getTransformer().setOutputProperty(OutputKeys.INDENT, "yes");
saxHandler.setResult(new StreamResult(fileOutputStream));

View File

@ -21,15 +21,11 @@ import java.io.File;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.NoSuchElementException;
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.types.FileSet;
import org.apache.tools.ant.types.PatternSet.NameEntry;
import org.apache.tools.ant.types.Resource;
/**
* Creates an ant fileset consisting in all artifacts found during a resolve. Note that this task
@ -194,49 +190,4 @@ public class IvyCacheFileset extends IvyCacheTask {
}
return r;
}
private static class EmptyFileSet extends FileSet {
private DirectoryScanner ds = new EmptyDirectoryScanner();
public Iterator<Resource> iterator() {
return new EmptyIterator<>();
}
public Object clone() {
return new EmptyFileSet();
}
public int size() {
return 0;
}
public DirectoryScanner getDirectoryScanner(Project project) {
return ds;
}
}
private static class EmptyIterator<T> implements Iterator<T> {
public boolean hasNext() {
return false;
}
public T next() {
throw new NoSuchElementException("EmptyFileSet Iterator");
}
public void remove() {
throw new IllegalStateException("EmptyFileSet Iterator");
}
}
private static class EmptyDirectoryScanner extends DirectoryScanner {
public String[] getIncludedFiles() {
return new String[0];
}
}
}

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

@ -33,7 +33,6 @@ import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
@ -48,6 +47,7 @@ import org.apache.ivy.plugins.report.XmlReportOutputter;
import org.apache.ivy.plugins.report.XmlReportParser;
import org.apache.ivy.util.FileUtil;
import org.apache.ivy.util.Message;
import org.apache.ivy.util.XMLHelper;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.taskdefs.XSLTProcess;
import org.apache.tools.ant.util.JAXPUtils;
@ -313,8 +313,7 @@ public class IvyReport extends IvyTask {
Source xsltSource = new StreamSource(xsltStream, JAXPUtils.getSystemId(style));
// create transformer
TransformerFactory tFactory = TransformerFactory.newInstance();
Transformer transformer = tFactory.newTransformer(xsltSource);
Transformer transformer = XMLHelper.getTransformer(xsltSource);
// add standard parameters
transformer.setParameter("confs", conf);

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

@ -126,16 +126,24 @@ public class IvyRetrieve extends IvyPostResolveTask {
}
if (getSetId() != null) {
FileSet fileset = new FileSet();
fileset.setProject(getProject());
getProject().addReference(getSetId(), fileset);
FileSet fileset;
fileset.setDir(report.getRetrieveRoot());
Collection<File> retrievedFiles = report.getRetrievedFiles();
if (retrievedFiles.isEmpty()) {
fileset = new EmptyFileSet();
fileset.setProject(getProject());
} else {
fileset = new FileSet();
fileset.setProject(getProject());
fileset.setDir(report.getRetrieveRoot());
for (File file : report.getRetrievedFiles()) {
PatternSet.NameEntry ne = fileset.createInclude();
ne.setName(getPath(report.getRetrieveRoot(), file));
for (File file : retrievedFiles) {
PatternSet.NameEntry ne = fileset.createInclude();
ne.setName(getPath(report.getRetrieveRoot(), file));
}
}
getProject().addReference(getSetId(), fileset);
}
} catch (Exception ex) {
throw new BuildException("impossible to ivy retrieve: " + ex, ex);

View File

@ -18,10 +18,12 @@
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;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -135,7 +137,7 @@ public final class IvyPatternHelper {
if (token.indexOf(':') > 0) {
token = token.substring(token.indexOf(':') + 1);
}
tokens.put(token, entry.getValue());
tokens.put(token, new Validated(token, entry.getValue()));
}
}
if (extraArtifactAttributes != null) {
@ -144,19 +146,19 @@ public final class IvyPatternHelper {
if (token.indexOf(':') > 0) {
token = token.substring(token.indexOf(':') + 1);
}
tokens.put(token, entry.getValue());
tokens.put(token, new Validated(token, entry.getValue()));
}
}
tokens.put(ORGANISATION_KEY, org == null ? "" : org);
tokens.put(ORGANISATION_KEY2, org == null ? "" : org);
tokens.put(ORGANISATION_KEY, org == null ? "" : new Validated(ORGANISATION_KEY, org));
tokens.put(ORGANISATION_KEY2, org == null ? "" : new Validated(ORGANISATION_KEY2, org));
tokens.put(ORGANISATION_PATH_KEY, org == null ? "" : org.replace('.', '/'));
tokens.put(MODULE_KEY, module == null ? "" : module);
tokens.put(BRANCH_KEY, branch == null ? "" : branch);
tokens.put(REVISION_KEY, revision == null ? "" : revision);
tokens.put(ARTIFACT_KEY, artifact == null ? module : artifact);
tokens.put(TYPE_KEY, type == null ? "jar" : type);
tokens.put(EXT_KEY, ext == null ? "jar" : ext);
tokens.put(CONF_KEY, conf == null ? "default" : conf);
tokens.put(MODULE_KEY, module == null ? "" : new Validated(MODULE_KEY, module));
tokens.put(BRANCH_KEY, branch == null ? "" : new Validated(BRANCH_KEY, branch));
tokens.put(REVISION_KEY, revision == null ? "" : new Validated(REVISION_KEY, revision));
tokens.put(ARTIFACT_KEY, new Validated(ARTIFACT_KEY, artifact == null ? module : artifact));
tokens.put(TYPE_KEY, type == null ? "jar" : new Validated(TYPE_KEY, type));
tokens.put(EXT_KEY, ext == null ? "jar" : new Validated(EXT_KEY, ext));
tokens.put(CONF_KEY, conf == null ? "default" : new Validated(CONF_KEY, conf));
if (origin == null) {
tokens.put(ORIGINAL_ARTIFACTNAME_KEY, new OriginalArtifactNameValue(org, module,
branch, revision, artifact, type, ext, extraModuleAttributes,
@ -165,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
@ -224,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));
@ -328,7 +330,12 @@ public final class IvyPatternHelper {
+ pattern);
}
return buffer.toString();
String afterTokenSubstitution = buffer.toString();
if (checkPathTraversal) {
checkAgainstPathTraversal(pattern, afterTokenSubstitution);
}
return afterTokenSubstitution;
}
public static String substituteVariable(String pattern, String variable, String value) {
@ -490,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) {
@ -518,4 +556,49 @@ public final class IvyPatternHelper {
}
return pattern.substring(startIndex + 1, endIndex);
}
/**
* This class returns a captured value after validating it doesn't
* contain any path traversal sequence.
*
* <p>{@code toString}</p> will be invoked when the value is
* actually used as a token inside of a pattern passed to {@link
* #substituteTokens}.</p>
*/
private static class Validated {
private final String tokenName, tokenValue;
private Validated(String tokenName, String tokenValue) {
this.tokenName = tokenName;
this.tokenValue = tokenValue;
}
@Override
public String toString() {
if (tokenValue != null && !tokenValue.isEmpty()) {
StringTokenizer tok = new StringTokenizer(tokenValue.replace("\\", "/"), "/");
while (tok.hasMoreTokens()) {
if ("..".equals(tok.nextToken())) {
throw new IllegalArgumentException("\'" + tokenName + "\' value " + tokenValue + " contains an illegal path sequence");
}
}
}
return tokenValue;
}
}
private static void checkAgainstPathTraversal(String pattern, String afterTokenSubstitution) {
String root = getTokenRoot(pattern);
int rootLen = root.length(); // it is OK to have a token root containing .. sequences
if (root.endsWith("/") || root.endsWith("\\")) {
--rootLen;
}
String patternedPartWithNormalizedSlashes =
afterTokenSubstitution.substring(rootLen).replace("\\", "/");
if (patternedPartWithNormalizedSlashes.endsWith("/..")
|| patternedPartWithNormalizedSlashes.indexOf("/../") >= 0) {
throw new IllegalArgumentException("path after token expansion contains an illegal sequence");
}
}
}

View File

@ -21,6 +21,8 @@ import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
@ -385,7 +387,7 @@ public class DefaultRepositoryCacheManager implements RepositoryCacheManager, Iv
public File getArchiveFileInCache(Artifact artifact, ArtifactOrigin origin) {
File archive = new File(getRepositoryCacheRoot(), getArchivePathInCache(artifact, origin));
if (!archive.exists() && !ArtifactOrigin.isUnknown(origin) && origin.isLocal()) {
File original = Checks.checkAbsolute(origin.getLocation(), artifact
File original = Checks.checkAbsolute(parseArtifactOriginFilePath(origin), artifact
+ " origin location");
if (original.exists()) {
return original;
@ -407,7 +409,7 @@ public class DefaultRepositoryCacheManager implements RepositoryCacheManager, Iv
*/
private File getArchiveFileInCache(Artifact artifact, ArtifactOrigin origin, boolean useOrigin) {
if (useOrigin && !ArtifactOrigin.isUnknown(origin) && origin.isLocal()) {
return Checks.checkAbsolute(origin.getLocation(), artifact + " origin location");
return Checks.checkAbsolute(parseArtifactOriginFilePath(origin), artifact + " origin location");
}
return new File(getRepositoryCacheRoot(), getArchivePathInCache(artifact, origin));
}
@ -681,8 +683,10 @@ public class DefaultRepositoryCacheManager implements RepositoryCacheManager, Iv
}
private PropertiesFile getCachedDataFile(ModuleRevisionId mRevId) {
return new PropertiesFile(new File(getRepositoryCacheRoot(), IvyPatternHelper.substitute(
getDataFilePattern(), mRevId)), "ivy cached data file for " + mRevId);
File file = new File(getRepositoryCacheRoot(), IvyPatternHelper.substitute(
getDataFilePattern(), mRevId));
assertInsideCache(file);
return new PropertiesFile(file, "ivy cached data file for " + mRevId);
}
/**
@ -691,9 +695,10 @@ public class DefaultRepositoryCacheManager implements RepositoryCacheManager, Iv
*/
private PropertiesFile getCachedDataFile(String resolverName, ModuleRevisionId mRevId) {
// we append ".${resolverName} onto the end of the regular ivydata location
return new PropertiesFile(new File(getRepositoryCacheRoot(),
IvyPatternHelper.substitute(getDataFilePattern(), mRevId) + "." + resolverName),
"ivy cached data file for " + mRevId);
File file = new File(getRepositoryCacheRoot(),
IvyPatternHelper.substitute(getDataFilePattern(), mRevId) + "." + resolverName);
assertInsideCache(file);
return new PropertiesFile(file, "ivy cached data file for " + mRevId);
}
public ResolvedModuleRevision findModuleInCache(DependencyDescriptor dd,
@ -1027,6 +1032,7 @@ public class DefaultRepositoryCacheManager implements RepositoryCacheManager, Iv
+ resourceResolver
+ "': pointing repository to ivy cache is forbidden !");
}
assertInsideCache(archiveFile);
if (listener != null) {
listener.startArtifactDownload(this, artifactRef, artifact, origin);
}
@ -1145,6 +1151,7 @@ public class DefaultRepositoryCacheManager implements RepositoryCacheManager, Iv
}
// actual download
assertInsideCache(archiveFile);
if (archiveFile.exists()) {
archiveFile.delete();
}
@ -1532,6 +1539,49 @@ public class DefaultRepositoryCacheManager implements RepositoryCacheManager, Iv
Message.debug("\t\tchangingMatcher: " + getChangingMatcherName());
}
/**
* @throws IllegalArgumentException if the given path points outside of the cache.
*/
public final void assertInsideCache(File fileInCache) {
File root = getRepositoryCacheRoot();
if (root != null && !FileUtil.isLeadingPath(root, fileInCache)) {
throw new IllegalArgumentException(fileInCache + " is outside of the cache");
}
}
/**
* If the {@link ArtifactOrigin#getLocation() location of the artifact origin} is a
* {@code file:} scheme URI, then this method parses that URI and returns back the
* path of the file it represents. Else returns back {@link ArtifactOrigin#getLocation()}
* @param origin The artifact origin
* @return
*/
private static String parseArtifactOriginFilePath(final ArtifactOrigin origin) {
if (origin == null || origin.getLocation() == null) {
return null;
}
final String location = origin.getLocation();
if (!location.startsWith("file:")) {
// no need to parse it into a URI, if it's not a "file" scheme URI
return location;
}
final URI uri;
try {
uri = new URI(location);
} catch (URISyntaxException e) {
return location;
}
if (!uri.isAbsolute()) {
// no scheme in URI, just return the original location
return location;
} else if (uri.getScheme().equals("file")) {
// return the file path
return uri.getPath();
}
// not a "file" scheme URI, just return back the original location
return location;
}
/**
* Resource downloader which makes a copy of the previously existing file before overriding it.
* <p>

View File

@ -180,6 +180,7 @@ public class DefaultResolutionCacheManager implements ResolutionCacheManager, Iv
IOException {
ModuleRevisionId mrevId = md.getResolvedModuleRevisionId();
File ivyFileInCache = getResolvedIvyFileInCache(mrevId);
assertInsideCache(ivyFileInCache);
md.toIvyFile(ivyFileInCache);
Properties paths = new Properties();
@ -188,12 +189,22 @@ public class DefaultResolutionCacheManager implements ResolutionCacheManager, Iv
if (!paths.isEmpty()) {
File parentsFile = getResolvedIvyPropertiesInCache(ModuleRevisionId.newInstance(mrevId,
mrevId.getRevision() + "-parents"));
assertInsideCache(parentsFile);
FileOutputStream out = new FileOutputStream(parentsFile);
paths.store(out, null);
out.close();
}
}
/**
* @throws IllegalArgumentException if the given path points outside of the cache.
*/
public final void assertInsideCache(File fileInCache) {
if (!FileUtil.isLeadingPath(getResolutionCacheRoot(), fileInCache)) {
throw new IllegalArgumentException(fileInCache + " is outside of the cache");
}
}
private void saveLocalParents(ModuleRevisionId baseMrevId, ModuleDescriptor md, File mdFile,
Properties paths) throws ParseException, IOException {
for (ExtendsDescriptor parent : md.getInheritedDescriptors()) {
@ -206,6 +217,7 @@ public class DefaultResolutionCacheManager implements ResolutionCacheManager, Iv
ModuleRevisionId pRevId = ModuleRevisionId.newInstance(baseMrevId,
baseMrevId.getRevision() + "-parent." + paths.size());
File parentFile = getResolvedIvyFileInCache(pRevId);
assertInsideCache(parentFile);
parentMd.toIvyFile(parentFile);
paths.setProperty(mdFile.getName() + "|" + parent.getLocation(),

View File

@ -229,6 +229,10 @@ public class DefaultDependencyDescriptor implements DependencyDescriptor {
return getDependencyRevisionId().getModuleId();
}
public ModuleDescriptor getModuleDescriptor() {
return md;
}
public ModuleRevisionId getDependencyRevisionId() {
return revId;
}

View File

@ -111,7 +111,7 @@ public class DefaultModuleDescriptor implements ModuleDescriptor {
for (DependencyArtifactDescriptor artifact : artifacts) {
moduleDescriptor.addArtifact(DEFAULT_CONFIGURATION,
new MDArtifact(moduleDescriptor, artifact.getName(), artifact.getType(),
artifact.getExt(), artifact.getUrl(), artifact.getExtraAttributes()));
artifact.getExt(), artifact.getUrl(), artifact.getQualifiedExtraAttributes()));
}
} else {
moduleDescriptor.addArtifact(DEFAULT_CONFIGURATION,

View File

@ -44,6 +44,16 @@ import org.apache.ivy.util.extendable.ExtendableItem;
public interface DependencyDescriptor extends ExtendableItem, InheritableItem {
ModuleId getDependencyId();
/**
* Returns the {@link ModuleDescriptor} declaring this dependency descriptor.
* Returns null if this dependency descriptor is not declared in a {@link ModuleDescriptor}.
*
* @return the {@link ModuleDescriptor} of this dependency descriptor
*/
default ModuleDescriptor getModuleDescriptor() {
return null;
}
/**
* Used to indicate that this revision must be used in case of conflicts, independently of
* conflicts manager. This only works for direct dependencies, and not transitive ones.

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

@ -49,6 +49,7 @@ import org.apache.ivy.core.module.descriptor.IncludeRule;
import org.apache.ivy.core.module.descriptor.MDArtifact;
import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
import org.apache.ivy.core.module.id.ArtifactId;
import org.apache.ivy.core.module.id.ArtifactRevisionId;
import org.apache.ivy.core.module.id.ModuleId;
import org.apache.ivy.core.module.id.ModuleRevisionId;
import org.apache.ivy.core.resolve.IvyNodeCallers.Caller;
@ -165,7 +166,13 @@ public class IvyNode implements Comparable<IvyNode> {
} else {
markRootModuleConfLoaded(rootModuleConf);
if (md == null) {
DependencyResolver resolver = data.getSettings().getResolver(getId());
ResolveEngine engine = IvyContext.getContext().getIvy().getResolveEngine();
// 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 = data.getSettings().getResolver(getId());
}
if (resolver == null) {
Message.error("no resolver found for " + getModuleId()
+ ": check your configuration");
@ -867,6 +874,7 @@ public class IvyNode implements Comparable<IvyNode> {
// now exclude artifacts that aren't accepted by any caller
Iterator<Artifact> iter = artifacts.iterator();
Set<ArtifactRevisionId> artifactRevisionsSeen = new HashSet<ArtifactRevisionId>();
while (iter.hasNext()) {
Artifact artifact = iter.next();
boolean excluded = callers.doesCallersExclude(rootModuleConf, artifact);
@ -874,6 +882,10 @@ public class IvyNode implements Comparable<IvyNode> {
Message.debug(this + " in " + rootModuleConf + ": excluding " + artifact);
iter.remove();
}
if (!artifactRevisionsSeen.add(artifact.getId())) {
Message.debug(this + " in " + rootModuleConf + ": skipping duplicate " + artifact);
iter.remove();
}
}
return artifacts.toArray(new Artifact[artifacts.size()]);
}

View File

@ -24,15 +24,10 @@ import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.apache.ivy.core.module.descriptor.DefaultIncludeRule;
import org.apache.ivy.core.module.descriptor.DependencyArtifactDescriptor;
import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
import org.apache.ivy.core.module.descriptor.IncludeRule;
import org.apache.ivy.core.module.descriptor.WorkspaceModuleDescriptor;
import org.apache.ivy.core.module.id.ArtifactId;
import org.apache.ivy.core.module.id.ModuleId;
import org.apache.ivy.plugins.matcher.ExactPatternMatcher;
import org.apache.ivy.plugins.matcher.PatternMatcher;
/**
* Class collecting usage data for an IvyNode.
@ -243,35 +238,15 @@ public class IvyNodeUsage {
if (dependersInConf == null) {
return null;
}
final Set<IncludeRule> dependencyIncludes = new HashSet<>();
// true if the depedency descriptor of any of the depender *doesn't* have an explicit
// "<artifact>" or an "<include>". false otherwise
boolean atLeastOneDependerNeedsAllArtifacts = false;
// true if the dependency descriptor of any of the depender either has an explicit "<artifact>"
// or an "<include>". false otherwise
boolean atLeastOneDependerHasSpecificArtifactSelection = false;
for (final Depender depender : dependersInConf) {
final DependencyArtifactDescriptor dads[] = depender.dd.getDependencyArtifacts(depender.dd.getModuleConfigurations());
final boolean declaresArtifacts = dads != null && dads.length > 0;
final IncludeRule[] rules = depender.dd.getIncludeRules(depender.dependerConf);
final boolean hasIncludeRule = rules != null && rules.length > 0;
if (hasIncludeRule) {
dependencyIncludes.addAll(Arrays.asList(rules));
Set<IncludeRule> dependencyIncludes = new HashSet<>();
for (Depender depender : dependersInConf) {
IncludeRule[] rules = depender.dd.getIncludeRules(depender.dependerConf);
if (rules == null || rules.length == 0) {
// no include rule in at least one depender -> we must include everything,
// and so return no include rule at all
return null;
}
if (declaresArtifacts || hasIncludeRule) {
atLeastOneDependerHasSpecificArtifactSelection = true;
}
if (!hasIncludeRule && !declaresArtifacts) {
atLeastOneDependerNeedsAllArtifacts = true;
}
}
// so there's at least one depender D1 which has a specific artifact dependency and at the
// same time there's a depender D2 which doesn't have any explicit artifact/includes.
// so it is expected that an implicit "include all artifacts" is applied so that dependencies
// such as D2 get (all) the artifacts that are published by the dependency's module
if (atLeastOneDependerHasSpecificArtifactSelection && atLeastOneDependerNeedsAllArtifacts) {
// add a "include all artifacts" rule
dependencyIncludes.add(includeAllArtifacts());
dependencyIncludes.addAll(Arrays.asList(rules));
}
return dependencyIncludes;
}
@ -338,13 +313,4 @@ public class IvyNodeUsage {
return false;
}
private static IncludeRule includeAllArtifacts() {
final ArtifactId aid = new ArtifactId(
new ModuleId(PatternMatcher.ANY_EXPRESSION, PatternMatcher.ANY_EXPRESSION),
PatternMatcher.ANY_EXPRESSION, PatternMatcher.ANY_EXPRESSION,
PatternMatcher.ANY_EXPRESSION);
return new DefaultIncludeRule(aid, ExactPatternMatcher.INSTANCE, null);
}
}

View File

@ -22,23 +22,13 @@ 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;
import org.apache.ivy.core.LogOptions;
import org.apache.ivy.core.cache.ArtifactOrigin;
import org.apache.ivy.core.cache.DefaultResolutionCacheManager;
import org.apache.ivy.core.cache.ResolutionCacheManager;
import org.apache.ivy.core.event.EventManager;
import org.apache.ivy.core.event.download.PrepareDownloadEvent;
@ -126,7 +116,6 @@ public class ResolveEngine {
*/
public void setDictatorResolver(DependencyResolver dictatorResolver) {
this.dictatorResolver = dictatorResolver;
settings.setDictatorResolver(dictatorResolver);
}
public ResolveReport resolve(File ivySource) throws ParseException, IOException {
@ -263,6 +252,9 @@ public class ResolveEngine {
// this is used by the deliver task to resolve dynamic revisions to static ones
File ivyPropertiesInCache = cacheManager.getResolvedIvyPropertiesInCache(md
.getResolvedModuleRevisionId());
if (cacheManager instanceof DefaultResolutionCacheManager) {
((DefaultResolutionCacheManager) cacheManager).assertInsideCache(ivyPropertiesInCache);
}
Properties props = new Properties();
if (dependencies.length > 0) {
Map<ModuleId, ModuleRevisionId> forcedRevisions = new HashMap<>();
@ -275,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

@ -290,6 +290,11 @@ public class RetrieveEngine {
String destIvyPattern = IvyPatternHelper.substituteVariables(options.getDestIvyPattern(),
settings.getVariables());
File fileRetrieveRoot = settings.resolveFile(IvyPatternHelper
.getTokenRoot(destFilePattern));
File ivyRetrieveRoot = destIvyPattern == null ? null : settings
.resolveFile(IvyPatternHelper.getTokenRoot(destIvyPattern));
// find what we must retrieve where
// ArtifactDownloadReport source -> Set (String copyDestAbsolutePath)
@ -340,6 +345,7 @@ public class RetrieveEngine {
}
String destPattern = "ivy".equals(adr.getType()) ? destIvyPattern : destFilePattern;
File root = "ivy".equals(adr.getType()) ? ivyRetrieveRoot : fileRetrieveRoot;
if (!"ivy".equals(adr.getType())
&& !options.getArtifactFilter().accept(adr.getArtifact())) {
@ -357,7 +363,14 @@ public class RetrieveEngine {
dest = new HashSet<>();
artifactsToCopy.put(adr, dest);
}
String copyDest = settings.resolveFile(destFileName).getAbsolutePath();
File copyDestFile = settings.resolveFile(destFileName).getAbsoluteFile();
if (root != null &&
!FileUtil.isLeadingPath(root, copyDestFile)) {
Message.warn("not retrieving artifact " + artifact + " as its destination "
+ copyDestFile + " is not inside " + root);
continue;
}
String copyDest = copyDestFile.getPath();
String[] destinations = new String[] {copyDest};
if (options.getMapper() != null) {
@ -411,7 +424,7 @@ public class RetrieveEngine {
ArtifactDownloadReport current = artifactsList.get(i);
if (winnerMD.equals(current.getArtifact().getModuleRevisionId())) {
throw new RuntimeException("Multiple artifacts of the module " + winnerMD
+ " are retrieved to the same file! Update the retrieve pattern "
+ " are retrieved to the same file! Update the retrieve pattern"
+ " to fix this error.");
}
}

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

@ -32,8 +32,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.parsers.SAXParserFactory;
import org.apache.ivy.core.IvyPatternHelper;
import org.apache.ivy.core.cache.RepositoryCacheManager;
import org.apache.ivy.core.module.status.StatusManager;
@ -46,6 +44,7 @@ import org.apache.ivy.util.Checks;
import org.apache.ivy.util.Configurator;
import org.apache.ivy.util.FileResolver;
import org.apache.ivy.util.Message;
import org.apache.ivy.util.XMLHelper;
import org.apache.ivy.util.url.CredentialsStore;
import org.apache.ivy.util.url.TimeoutConstrainedURLHandler;
import org.apache.ivy.util.url.URLHandlerRegistry;
@ -151,10 +150,8 @@ public class XmlSettingsParser extends DefaultHandler {
@SuppressWarnings("deprecation")
private void doParse(URL settingsUrl) throws IOException, ParseException {
this.settings = settingsUrl;
try (InputStream stream = URLHandlerRegistry.getDefault().openStream(settingsUrl)) {
InputSource inSrc = new InputSource(stream);
inSrc.setSystemId(settingsUrl.toExternalForm());
SAXParserFactory.newInstance().newSAXParser().parse(settingsUrl.toExternalForm(), this);
try {
XMLHelper.parse(settingsUrl, null, this);
ivy.validate();
} catch (IOException e) {
throw e;

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

@ -22,9 +22,7 @@ import java.text.ParseException;
import java.util.Set;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult;
@ -45,6 +43,7 @@ import org.apache.ivy.osgi.repo.ManifestAndLocation;
import org.apache.ivy.osgi.util.Version;
import org.apache.ivy.osgi.util.VersionRange;
import org.apache.ivy.util.Message;
import org.apache.ivy.util.XMLHelper;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
@ -53,12 +52,10 @@ public class OBRXMLWriter {
public static ContentHandler newHandler(OutputStream out, String encoding, boolean indent)
throws TransformerConfigurationException {
SAXTransformerFactory tf = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
TransformerHandler hd = tf.newTransformerHandler();
Transformer serializer = tf.newTransformer();
TransformerHandler hd = XMLHelper.getTransformerHandler();
hd.getTransformer().setOutputProperty(OutputKeys.ENCODING, encoding);
hd.getTransformer().setOutputProperty(OutputKeys.INDENT, indent ? "yes" : "no");
StreamResult stream = new StreamResult(out);
serializer.setOutputProperty(OutputKeys.ENCODING, encoding);
serializer.setOutputProperty(OutputKeys.INDENT, indent ? "yes" : "no");
hd.setResult(stream);
return hd;
}

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,81 +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)) {
File f = new File(dest, entry.getName());
Message.verbose("\t\texpanding " + entry.getName() + " 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,13 +290,14 @@ 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,
// so we check if we already have created a dependency descriptor for the dependency mrid
final DependencyDescriptor existing = this.ivyModuleDescriptor.depDescriptors.get(moduleRevId);
final String[] existingConfigurations = existing == null ? new String[0]
: existing.getModuleConfigurations();
final DefaultDependencyDescriptor dd = (existing != null && existing instanceof DefaultDependencyDescriptor)
? (DefaultDependencyDescriptor) existing
: new PomDependencyDescriptor(dep, ivyModuleDescriptor, moduleRevId, !excludeAllTransitiveDeps);
@ -314,7 +307,14 @@ public class PomModuleDescriptorBuilder {
ConfMapper mapping = MAVEN2_CONF_MAPPING.get(scope);
mapping.addMappingConfs(dd, dep.isOptional());
Map<String, String> extraAtt = new HashMap<>();
if (dep.getClassifier() != null || dep.getType() != null && !"jar".equals(dep.getType())) {
final String optionalizedScope = dep.isOptional() ? "optional" : scope;
if (isNonDefaultArtifact(dep)) {
if (existing != null && existing.getAllDependencyArtifacts().length == 0) {
String moduleConfiguration = existingConfigurations.length == 1
? existingConfigurations[0] : optionalizedScope;
// previously added dependency has been the "default artifact"
dd.addDependencyArtifact(moduleConfiguration, createDefaultArtifact(dd));
}
String type = "jar";
if (dep.getType() != null) {
type = dep.getType();
@ -339,9 +339,11 @@ public class PomModuleDescriptorBuilder {
dd, dd.getDependencyId().getName(), type, ext, null, extraAtt);
// here we have to assume a type and ext for the artifact, so this is a limitation
// compared to how m2 behave with classifiers
final String optionalizedScope = dep.isOptional() ? "optional" : scope;
depArtifact.addConfiguration(optionalizedScope);
dd.addDependencyArtifact(optionalizedScope, depArtifact);
} else if (existing != null) {
// this is the "default" artifact and some non-default artifact has already been added
dd.addDependencyArtifact(optionalizedScope, createDefaultArtifact(dd));
}
for (ModuleId excludedModule : excluded) {
@ -362,6 +364,15 @@ public class PomModuleDescriptorBuilder {
}
}
private boolean isNonDefaultArtifact(PomDependencyData dep) {
return dep.getClassifier() != null || dep.getType() != null && !"jar".equals(dep.getType());
}
private DefaultDependencyArtifactDescriptor createDefaultArtifact(DefaultDependencyDescriptor dd) {
return new DefaultDependencyArtifactDescriptor(dd, dd.getDependencyId().getName(),
"jar", "jar", null, null);
}
private static boolean shouldExcludeAllTransitiveDeps(final List<ModuleId> exclusions) {
if (exclusions == null || exclusions.isEmpty()) {
return false;
@ -394,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(
@ -474,6 +483,14 @@ public class PomModuleDescriptorBuilder {
return artifactId;
}
public String getType() {
return null;
}
public String getClassifier() {
return null;
}
public String getVersion() {
return version;
}
@ -488,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";
@ -511,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();
@ -558,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<>();
@ -594,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));
}
}
}
@ -734,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<>();
@ -743,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;
}
@ -758,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

@ -130,12 +130,13 @@ public class PomReader {
public InputSource resolveEntity(String publicId, String systemId)
throws SAXException, IOException {
if (systemId != null && systemId.endsWith("m2-entities.ent")) {
// IVY-921: return an InputSource for our local packaged m2-entities.ent file
return new InputSource(
PomReader.class.getResourceAsStream("m2-entities.ent"));
}
return null;
}
});
}, true, XMLHelper.ExternalResources.IGNORE);
projectElement = pomDomDoc.getDocumentElement();
if (!PROJECT.equals(projectElement.getNodeName())
&& !MODEL.equals(projectElement.getNodeName())) {
@ -393,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)
*
@ -405,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() {
@ -427,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() {
@ -486,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
}
@ -507,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

@ -17,9 +17,13 @@
*/
package org.apache.ivy.plugins.parser.xml;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
@ -79,7 +83,9 @@ 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;
import static org.apache.ivy.core.module.descriptor.Configuration.Visibility.getVisibility;
@ -214,7 +220,9 @@ 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;
/* how and what do we have to parse */
private ParserSettings settings;
@ -248,6 +256,40 @@ public class XmlModuleDescriptorParser extends AbstractModuleDescriptorParser {
private Stack<ExtraInfoHolder> extraInfoStack = new Stack<>();
static {
String ivyXSDContent = null;
final InputStream is = Parser.class.getResourceAsStream("ivy.xsd");
if (is != null) {
final StringBuilder sb = new StringBuilder();
try {
try {
final BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
String line = null;
while ((line = reader.readLine()) != null) {
if (sb.length() != 0) {
sb.append("\n");
}
sb.append(line);
}
} catch (UnsupportedEncodingException e) {
// ignore
ivyXSDContent = null;
} catch (IOException e) {
// ignore
ivyXSDContent = null;
}
} finally {
try {
is.close();
} catch (Exception e) {
// ignore
}
}
ivyXSDContent = sb.length() == 0 ? null : sb.toString();
}
IVY_XSD_CONTENT = ivyXSDContent;
}
public Parser(ModuleDescriptorParser parser, ParserSettings ivySettings) {
super(parser);
settings = ivySettings;
@ -268,10 +310,14 @@ public class XmlModuleDescriptorParser extends AbstractModuleDescriptorParser {
public void parse() throws ParseException {
try {
URL schemaURL = validate ? getSchemaURL() : null;
XMLHelper.ExternalResources e =
validate && System.getProperty(XMLHelper.EXTERNAL_RESOURCES) == null
? XMLHelper.ExternalResources.IGNORE
: XMLHelper.ExternalResources.fromSystemProperty();
if (descriptorURL != null) {
XMLHelper.parse(descriptorURL, schemaURL, this);
XMLHelper.parse(descriptorURL, schemaURL, this, null, e);
} else {
XMLHelper.parse(descriptorInput, schemaURL, this, null);
XMLHelper.parse(descriptorInput, schemaURL, this, null, e);
}
checkConfigurations();
replaceConfigurationWildcards();
@ -296,6 +342,26 @@ public class XmlModuleDescriptorParser extends AbstractModuleDescriptorParser {
}
}
@Override
public InputSource resolveEntity(final String publicId, final String systemId)
throws IOException, SAXException {
if (isApacheOrgIvyXSDSystemId(systemId) && IVY_XSD_CONTENT != null) {
// redirect the schema location to local file based ivy.xsd whose content
// we have already read and is available in-memory.
final InputSource source = new InputSource(new StringReader(IVY_XSD_CONTENT));
return source;
}
return super.resolveEntity(publicId, systemId);
}
private static boolean isApacheOrgIvyXSDSystemId(final String systemId) {
if (systemId == null) {
return false;
}
return systemId.equals("http://ant.apache.org/ivy/schemas/ivy.xsd")
|| systemId.equals("https://ant.apache.org/ivy/schemas/ivy.xsd");
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes)
throws SAXException {
@ -483,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
}
/**
@ -657,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).
*
@ -1390,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

@ -22,6 +22,7 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import org.apache.ivy.core.cache.DefaultResolutionCacheManager;
import org.apache.ivy.core.cache.ResolutionCacheManager;
import org.apache.ivy.core.report.ConfigurationResolveReport;
import org.apache.ivy.core.report.ResolveReport;
@ -52,6 +53,9 @@ public class XmlReportOutputter implements ReportOutputter {
ResolutionCacheManager cacheMgr) throws IOException {
File reportFile = cacheMgr.getConfigurationResolveReportInCache(resolveId,
report.getConfiguration());
if (cacheMgr instanceof DefaultResolutionCacheManager) {
((DefaultResolutionCacheManager) cacheMgr).assertInsideCache(reportFile);
}
File reportParentDir = reportFile.getParentFile();
reportParentDir.mkdirs();
OutputStream stream = new FileOutputStream(reportFile);

View File

@ -27,9 +27,6 @@ import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.apache.ivy.core.cache.ArtifactOrigin;
import org.apache.ivy.core.module.descriptor.Artifact;
import org.apache.ivy.core.module.descriptor.DefaultArtifact;
@ -38,6 +35,7 @@ import org.apache.ivy.core.report.ArtifactDownloadReport;
import org.apache.ivy.core.report.DownloadStatus;
import org.apache.ivy.core.report.MetadataArtifactDownloadReport;
import org.apache.ivy.util.DateUtil;
import org.apache.ivy.util.XMLHelper;
import org.apache.ivy.util.extendable.ExtendableItemHelper;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
@ -242,8 +240,7 @@ public class XmlReportParser {
}
public void parse() throws Exception {
SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser();
saxParser.parse(report, new XmlReportParserHandler());
XMLHelper.parse(report.toURI().toURL(), null, new XmlReportParserHandler());
}
private static boolean parseBoolean(String str) {

View File

@ -49,13 +49,15 @@ public class FileRepository extends AbstractRepository {
}
public void get(String source, File destination) throws IOException {
File s = getFile(source);
fireTransferInitiated(getResource(source), TransferEvent.REQUEST_GET);
copy(getFile(source), destination, true);
copy(s, destination, true);
}
public void put(File source, String destination, boolean overwrite) throws IOException {
File d = getFile(destination);
fireTransferInitiated(getResource(destination), TransferEvent.REQUEST_PUT);
copy(source, getFile(destination), overwrite);
copy(source, d, overwrite);
}
public void move(File src, File dest) throws IOException {
@ -112,7 +114,11 @@ public class FileRepository extends AbstractRepository {
if (baseDir == null) {
return Checks.checkAbsolute(source, "source");
}
return FileUtil.resolveFile(baseDir, source);
File file = FileUtil.resolveFile(baseDir, source);
if (!FileUtil.isLeadingPath(baseDir, file)) {
throw new IllegalArgumentException(source + " outside of repository root");
}
return file;
}
public boolean isLocal() {

View File

@ -244,6 +244,15 @@ public abstract class BasicResolver extends AbstractResolver {
nsMd = DefaultModuleDescriptor.newDefaultInstance(nsMrid,
nsDd.getAllDependencyArtifacts());
ModuleDescriptor md = dd.getModuleDescriptor();
if (md != null) {
Map<String, String> extraAttributesNamespaces = md.getExtraAttributesNamespaces();
for (Map.Entry<String, String> entry : extraAttributesNamespaces.entrySet()) {
((DefaultModuleDescriptor) nsMd).addExtraAttributeNamespace(entry.getKey(), entry.getValue());
}
}
ResolvedResource artifactRef = findFirstArtifactRef(nsMd, nsDd, data);
checkInterrupted();

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, ...
@ -610,6 +602,68 @@ public final class FileUtil {
return new DissectedPath(File.separator, pathToDissect);
}
/**
* Learn whether one path "leads" another.
*
* <p>This method uses {@link #normalize} under the covers and
* does not resolve symbolic links.</p>
*
* <p>If either path tries to go beyond the file system root
* (i.e. it contains more ".." segments than can be travelled up)
* the method will return false.</p>
*
* @param leading The leading path, must not be null, must be absolute.
* @param path The path to check, must not be null, must be absolute.
* @return true if path starts with leading; false otherwise.
* @since Ant 1.7
*/
public static boolean isLeadingPath(File leading, File path) {
String l = normalize(leading.getAbsolutePath()).getAbsolutePath();
String p = normalize(path.getAbsolutePath()).getAbsolutePath();
if (l.equals(p)) {
return true;
}
// ensure that l ends with a /
// so we never think /foo was a parent directory of /foobar
if (!l.endsWith(File.separator)) {
l += File.separator;
}
// ensure "/foo/" is not considered a parent of "/foo/../../bar"
String up = File.separator + ".." + File.separator;
if (l.contains(up) || p.contains(up) || (p + File.separator).contains(up)) {
return false;
}
return p.startsWith(l);
}
/**
* Learn whether one path "leads" another.
*
* @param leading The leading path, must not be null, must be absolute.
* @param path The path to check, must not be null, must be absolute.
* @param resolveSymlinks whether symbolic links shall be resolved
* prior to comparing the paths.
* @return true if path starts with leading; false otherwise.
* @since Ant 1.9.13
* @throws IOException if resolveSymlinks is true and invoking
* getCanonicaPath on either argument throws an exception
*/
public static boolean isLeadingPath(File leading, File path, boolean resolveSymlinks)
throws IOException {
if (!resolveSymlinks) {
return isLeadingPath(leading, path);
}
final File l = leading.getCanonicalFile();
File p = path.getCanonicalFile();
do {
if (l.equals(p)) {
return true;
}
p = p.getParentFile();
} while (p != null);
return false;
}
/**
* Get the length of the file, or the sum of the children lengths if it is a directory
*
@ -631,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

@ -17,34 +17,35 @@
*/
package org.apache.ivy.util;
import java.util.ArrayList;
import java.util.List;
public final class MessageLoggerHelper {
public static void sumupProblems(MessageLogger logger) {
List<String> myProblems = logger.getProblems();
if (myProblems.size() > 0) {
List<String> myWarns = logger.getWarns();
List<String> myErrors = logger.getErrors();
logger.info(""); // new line on info to isolate error summary
if (!myErrors.isEmpty()) {
logger.log(":: problems summary ::", Message.MSG_ERR);
} else {
logger.log(":: problems summary ::", Message.MSG_WARN);
}
if (myWarns.size() > 0) {
logger.log(":::: WARNINGS", Message.MSG_WARN);
for (String msg : myWarns) {
logger.log("\t" + msg + "\n", Message.MSG_WARN);
}
}
if (myErrors.size() > 0) {
logger.log(":::: ERRORS", Message.MSG_ERR);
for (String msg : myErrors) {
logger.log("\t" + msg + "\n", Message.MSG_ERR);
}
}
logger.info("\n:: USE VERBOSE OR DEBUG MESSAGE LEVEL FOR MORE DETAILS");
if (logger.getProblems().isEmpty()) {
return;
}
final List<String> warns = new ArrayList<>(logger.getWarns());
final List<String> errors = new ArrayList<>(logger.getErrors());
logger.info(""); // new line on info to isolate error summary
if (!errors.isEmpty()) {
logger.log(":: problems summary ::", Message.MSG_ERR);
} else {
logger.log(":: problems summary ::", Message.MSG_WARN);
}
if (warns.size() > 0) {
logger.log(":::: WARNINGS", Message.MSG_WARN);
for (String msg : warns) {
logger.log("\t" + msg + "\n", Message.MSG_WARN);
}
}
if (errors.size() > 0) {
logger.log(":::: ERRORS", Message.MSG_ERR);
for (String msg : errors) {
logger.log("\t" + msg + "\n", Message.MSG_ERR);
}
}
logger.info("\n:: USE VERBOSE OR DEBUG MESSAGE LEVEL FOR MORE DETAILS");
}
private MessageLoggerHelper() {

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