diff --git a/.asf.yaml b/.asf.yaml index 8162c5ec3..2ac11146a 100644 --- a/.asf.yaml +++ b/.asf.yaml @@ -28,3 +28,13 @@ github: squash: true merge: false rebase: true + protected_branches: + master: {} + pull_requests: + del_branch_on_merge: true + features: + issues: true +notifications: + commits: commits@maven.apache.org + issues: issues@maven.apache.org + pullrequests: issues@maven.apache.org diff --git a/.github/ISSUE_TEMPLATE/BUG.yml b/.github/ISSUE_TEMPLATE/BUG.yml new file mode 100644 index 000000000..699181ff1 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/BUG.yml @@ -0,0 +1,48 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema + +name: Bug Report +description: File a bug report +labels: ["bug"] + +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to fill out this bug report. + + Simple fixes in single PRs do not require issues. + + **Do you use the latest project version?** + + - type: input + id: version + attributes: + label: Affected version + validations: + required: true + + - type: textarea + id: message + attributes: + label: Bug description + validations: + required: true + + diff --git a/.github/ISSUE_TEMPLATE/FEATURE.yml b/.github/ISSUE_TEMPLATE/FEATURE.yml new file mode 100644 index 000000000..ddfd1a45e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/FEATURE.yml @@ -0,0 +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 +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema + +name: Feature request +description: File a proposal for new feature, improvement +labels: ["enhancement"] + +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to fill out this new feature, improvement proposal. + + - type: textarea + id: message + attributes: + label: New feature, improvement proposal + validations: + required: true diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 000000000..ba0544b5b --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,27 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/configuring-issue-templates-for-your-repository#configuring-the-template-chooser + +blank_issues_enabled: false + +contact_links: + + - name: Project Mailing Lists + url: https://maven.apache.org/mailing-lists.html + about: Please ask a question or discuss here + diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 7b7230f1f..afa7b1323 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -24,6 +24,13 @@ updates: # Jetty >=10 requires Java 11+ - dependency-name: "org.eclipse.jetty:*" versions: [">= 10.0"] + # Mockito >=5 requires Java 11+ + - dependency-name: "org.mockito:*" + versions: [">= 5.0.0"] + # Maven 3 so use SLF4J 1.7.x + - dependency-name: "org.slf4j:*" + versions: [">= 2.0.0"] + - package-ecosystem: "github-actions" directory: "/" schedule: diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index fd85bb33f..51e18bc14 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,29 +1,23 @@ -Following this checklist to help us incorporate your +Following this checklist to help us incorporate your contribution quickly and easily: - - [ ] Make sure there is a [JIRA issue](https://issues.apache.org/jira/browse/MDEP) filed - for the change (usually before you start working on it). Trivial changes like typos do not - require a JIRA issue. Your pull request should address just this issue, without - pulling in other changes. - - [ ] Each commit in the pull request should have a meaningful subject line and body. - - [ ] Format the pull request title like `[MDEP-XXX] - Fixes bug in ApproximateQuantiles`, - where you replace `MDEP-XXX` with the appropriate JIRA issue. Best practice - is to use the JIRA issue title in the pull request title and in the first line of the - commit message. - - [ ] Write a pull request description that is detailed enough to understand what the pull request does, how, and why. - - [ ] Run `mvn clean verify` to make sure basic checks pass. A more thorough check will - be performed on your pull request automatically. - - [ ] You have run the integration tests successfully (`mvn -Prun-its clean verify`). +- [ ] Your pull request should address just one issue, without pulling in other changes. +- [ ] Write a pull request description that is detailed enough to understand what the pull request does, how, and why. +- [ ] Each commit in the pull request should have a meaningful subject line and body. + Note that commits might be squashed by a maintainer on merge. +- [ ] Write unit tests that match behavioral changes, where the tests fail if the changes to the runtime are not applied. + This may not always be possible but is a best-practice. +- [ ] Run `mvn verify` to make sure basic checks pass. + A more thorough check will be performed on your pull request automatically. +- [ ] You have run the integration tests successfully (`mvn -Prun-its verify`). If your pull request is about ~20 lines of code you don't need to sign an [Individual Contributor License Agreement](https://www.apache.org/licenses/icla.pdf) if you are unsure please ask on the developers list. -To make clear that you license your contribution under +To make clear that you license your contribution under the [Apache License Version 2.0, January 2004](http://www.apache.org/licenses/LICENSE-2.0) you have to acknowledge this by using the following check-box. - - [ ] I hereby declare this contribution to be licensed under the [Apache License Version 2.0, January 2004](http://www.apache.org/licenses/LICENSE-2.0) - - - [ ] In any other case, please file an [Apache Individual Contributor License Agreement](https://www.apache.org/licenses/icla.pdf). - +- [ ] I hereby declare this contribution to be licenced under the [Apache License Version 2.0, January 2004](http://www.apache.org/licenses/LICENSE-2.0) +- [ ] In any other case, please file an [Apache Individual Contributor License Agreement](https://www.apache.org/licenses/icla.pdf). diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml new file mode 100644 index 000000000..9b801fc6b --- /dev/null +++ b/.github/release-drafter.yml @@ -0,0 +1,21 @@ + + +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +_extends: maven-gh-actions-shared +tag-template: maven-dependency-plugin-$RESOLVED_VERSION diff --git a/.github/workflows/maven-verify.yml b/.github/workflows/maven-verify.yml index 4d67fdcf9..ce4b500dc 100644 --- a/.github/workflows/maven-verify.yml +++ b/.github/workflows/maven-verify.yml @@ -24,4 +24,6 @@ on: jobs: build: name: Verify - uses: apache/maven-gh-actions-shared/.github/workflows/maven-verify.yml@v3 + uses: apache/maven-gh-actions-shared/.github/workflows/maven-verify.yml@v4 + with: + maven4-enabled: true diff --git a/.github/workflows/pr-automation.yml b/.github/workflows/pr-automation.yml new file mode 100644 index 000000000..530759572 --- /dev/null +++ b/.github/workflows/pr-automation.yml @@ -0,0 +1,27 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +name: PR Automation +on: + pull_request_target: + types: + - closed + +jobs: + pr-automation: + name: PR Automation + uses: apache/maven-gh-actions-shared/.github/workflows/pr-automation.yml@v4 diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml new file mode 100644 index 000000000..83008b18e --- /dev/null +++ b/.github/workflows/release-drafter.yml @@ -0,0 +1,29 @@ + + +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +name: Release Drafter +on: + push: + branches: + - master + workflow_dispatch: + +jobs: + update_release_draft: + uses: apache/maven-gh-actions-shared/.github/workflows/release-drafter.yml@v4 diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml new file mode 100644 index 000000000..85ae8637d --- /dev/null +++ b/.github/workflows/stale.yml @@ -0,0 +1,28 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +name: Stale + +on: + schedule: + - cron: '16 3 * * *' + issue_comment: + types: [ 'created' ] + +jobs: + stale: + uses: 'apache/maven-gh-actions-shared/.github/workflows/stale.yml@v4' diff --git a/.gitignore b/.gitignore index bc313a1fe..c1b42ca0f 100644 --- a/.gitignore +++ b/.gitignore @@ -15,8 +15,5 @@ out/ /dependencies.xml .java-version .checkstyle -# This file is being created by Mock Repository Manager -# during integration tests -src/it/mrm/repository/_ResourceArtifact-1.0.jar /dependency-reduced-pom.xml .factorypath diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md index 9f143c0fc..18cb862a1 100644 --- a/README.md +++ b/README.md @@ -17,15 +17,13 @@ Contributing to [Apache Maven Dependency Plugin](https://maven.apache.org/plugins/maven-dependency-plugin/) ====================== -[![ASF Jira](https://img.shields.io/endpoint?url=https%3A%2F%2Fmaven.apache.org%2Fbadges%2Fasf_jira-MDEP.json)][jira] [![Apache License, Version 2.0, January 2004](https://img.shields.io/github/license/apache/maven.svg?label=License)][license] [![Maven Central](https://img.shields.io/maven-central/v/org.apache.maven.plugins/maven-dependency-plugin.svg?label=Maven%20Central)](https://search.maven.org/artifact/org.apache.maven.plugins/maven-dependency-plugin) -[![Reproducible Builds](https://img.shields.io/badge/Reproducible_Builds-ok-green?labelColor=blue)](https://github.com/jvm-repo-rebuild/reproducible-central/blob/master/content/org/apache/maven/plugins/maven-dependency-plugin/README.md) +[![Reproducible Builds](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/jvm-repo-rebuild/reproducible-central/master/content/org/apache/maven/plugins/maven-dependency-plugin//badge.json)](https://github.com/jvm-repo-rebuild/reproducible-central/blob/master/content/org/apache/maven/plugins/maven-dependency-plugin/README.md) [![Jenkins Status](https://img.shields.io/jenkins/s/https/ci-maven.apache.org/job/Maven/job/maven-box/job/maven-dependency-plugin/job/master.svg?)][build] [![Jenkins tests](https://img.shields.io/jenkins/t/https/ci-maven.apache.org/job/Maven/job/maven-box/job/maven-dependency-plugin/job/master.svg?)][test-results] - -You have found a bug or you have an idea for a cool new feature? Contributing +You have found a bug, or you have an idea for a cool new feature? Contributing code is a great way to give something back to the open source community. Before you dig right into the code, there are a few guidelines that we need contributors to follow so that we can have a chance of keeping on top of @@ -34,7 +32,6 @@ things. Getting Started --------------- -+ Make sure you have a [JIRA account](https://issues.apache.org/jira/). + Make sure you have a [GitHub account](https://github.com/signup/free). + If you're planning to implement a new feature, it makes sense to discuss your changes on the [dev list][ml-list] first. @@ -60,37 +57,23 @@ There are some guidelines which will make applying PRs easier for us: + Create minimal diffs - disable on save actions like reformat source code or organize imports. If you feel the source code should be reformatted, create a separate PR for this change. + Check for unnecessary whitespace with `git diff --check` before committing. -+ Make sure your commit messages are in the proper format. Your commit message should contain the key of the JIRA issue. -``` -[MDEP-XXX] - Subject of the JIRA Ticket - Optional supplemental description. -``` + Make sure you have added the necessary tests (JUnit/IT) for your changes. + Run all the tests with `mvn -Prun-its verify` to assure nothing else was accidentally broken. + Submit a pull request to the repository in the Apache organization. -+ Update your JIRA ticket and include a link to the pull request in the ticket. If you plan to contribute on a regular basis, please consider filing a [contributor license agreement][cla]. -Making Trivial Changes ----------------------- - -For changes of a trivial nature to comments and documentation, it is not always -necessary to create a new ticket in JIRA. In this case, it is appropriate to -start the first line of a commit with '(doc)' instead of a ticket number. - Additional Resources -------------------- + [Contributing patches](https://maven.apache.org/guides/development/guide-maven-development.html#Creating_and_submitting_a_patch) -+ [Apache Maven Dependency JIRA project page][jira] + [Contributor License Agreement][cla] + [General GitHub documentation](https://help.github.com/) + [GitHub pull request documentation](https://docs.github.com/en/github/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork) -+ [Apache Maven Twitter Account](https://twitter.com/ASFMavenProject) -+ #Maven IRC channel on freenode.org ++ [Apache Maven X Account](https://x.com/ASFMavenProject) ++ [Apache Maven Bluesky Account](https://bsky.app/profile/maven.apache.org) ++ [Apache Maven Mastodon Account](https://mastodon.social/deck/@ASFMavenProject@fosstodon.org) -[jira]: https://issues.apache.org/jira/projects/MDEP/ [license]: https://www.apache.org/licenses/LICENSE-2.0 [ml-list]: https://maven.apache.org/mailing-lists.html [code-style]: https://maven.apache.org/developers/conventions/code.html diff --git a/pom.xml b/pom.xml index 62af4bf7c..fa13cef1f 100644 --- a/pom.xml +++ b/pom.xml @@ -23,12 +23,12 @@ under the License. org.apache.maven.plugins maven-plugins - 38 - + 45 + maven-dependency-plugin - 3.5.0 + 3.9.0 maven-plugin Apache Maven Dependency Plugin @@ -59,21 +59,24 @@ under the License. Maarten Mulders + + Lisa Hardy + - ${mavenVersion} + 3.6.3 scm:git:https://gitbox.apache.org/repos/asf/maven-dependency-plugin.git scm:git:https://gitbox.apache.org/repos/asf/maven-dependency-plugin.git - maven-dependency-plugin-3.5.0 + maven-dependency-plugin-3.9.0 https://github.com/apache/maven-dependency-plugin/tree/${project.scm.tag} - JIRA - https://issues.apache.org/jira/browse/MDEP + GitHub Issues + https://github.com/apache/maven-dependency-plugin/issues Jenkins @@ -87,32 +90,22 @@ under the License. - 3.2.5 - 9.4.49.v20220914 - 3.3.0 - 1.0.0.v20140518 8 - 2023-01-06T22:57:48Z - 1.7.36 - 4.6.0 - + 3.9.11 + 1.9.24 + 1.7.36 + 9.4.58.v20250814 + 4.11.0 + 4.10.1 + 3.3.0 - - - - - - org.eclipse.sisu - org.eclipse.sisu.inject - 0.3.0.M1 - - - org.eclipse.sisu - org.eclipse.sisu.plexus - 0.3.0.M1 - - - + + 3.9.1 + + + true + 2025-09-29T05:53:29Z + @@ -152,23 +145,24 @@ under the License. ${mavenVersion} provided + + - org.apache.maven - maven-aether-provider - ${mavenVersion} - provided + org.apache.maven.doxia + doxia-sink-api + 2.0.0 org.apache.maven.reporting - maven-reporting-impl - 3.2.0 + maven-reporting-api + 4.0.0 - commons-io - commons-io - 2.11.0 + org.apache.maven.reporting + maven-reporting-impl + 4.0.0 @@ -177,68 +171,103 @@ under the License. plexus-archiver ${plexus-archiver.version} + + org.eclipse.sisu + org.eclipse.sisu.plexus + provided + + + + org.apache.commons + commons-lang3 + 3.19.0 + + + commons-io + commons-io + 2.20.0 + test + org.codehaus.plexus plexus-utils - 3.5.0 + + + org.codehaus.plexus + plexus-xml org.codehaus.plexus plexus-io - 3.4.0 + 3.5.1 + + + org.codehaus.plexus + plexus-i18n + 1.0.0 org.apache.maven.shared maven-dependency-analyzer - 1.13.0 + 1.16.0 org.apache.maven.shared maven-dependency-tree - 3.2.1 + 3.3.0 org.apache.maven.shared maven-common-artifact-filters - 3.3.2 + 3.4.0 org.apache.maven.shared maven-artifact-transfer 0.13.1 + + + org.apache.maven + maven-artifact + + + org.apache.maven + maven-core + + org.apache.maven.shared maven-shared-utils - 3.3.4 - - - - org.apache.commons - commons-collections4 - 4.2 + 3.4.2 org.apache.maven.plugin-tools maven-plugin-annotations + ${version.maven-plugin-tools} + provided + + + javax.inject + javax.inject + 1 provided - org.eclipse.aether - aether-api + org.apache.maven.resolver + maven-resolver-api ${resolverVersion} provided - org.eclipse.aether - aether-util + org.apache.maven.resolver + maven-resolver-util ${resolverVersion} - provided @@ -248,26 +277,65 @@ under the License. compile + + org.slf4j + slf4j-api + ${slf4jVersion} + + + + + org.apache.velocity + velocity-engine-core + 2.4.1 + + + org.apache.velocity.tools + velocity-tools-generic + 3.1 + - org.eclipse.aether - aether-connector-basic + org.apache.maven.resolver + maven-resolver-connector-basic ${resolverVersion} test - org.eclipse.aether - aether-transport-file + org.apache.maven.resolver + maven-resolver-transport-file ${resolverVersion} test - org.eclipse.aether - aether-transport-http + org.apache.maven.resolver + maven-resolver-transport-http ${resolverVersion} test + + org.junit.jupiter + junit-jupiter-api + test + + + org.junit.jupiter + junit-jupiter-params + test + + + org.glassfish + jakarta.json + 2.0.1 + test + + + + org.junit.vintage + junit-vintage-engine + test + junit junit @@ -279,11 +347,30 @@ under the License. maven-plugin-testing-harness ${pluginTestingVersion} test + + + org.codehaus.plexus + plexus-container-default + + org.mockito mockito-core - 4.9.0 + ${mockito.version} + test + + + org.mockito + mockito-junit-jupiter + ${mockito.version} + test + + + + org.assertj + assertj-core + 3.27.6 test @@ -316,7 +403,7 @@ under the License. org.slf4j slf4j-simple - ${slf4j.version} + ${slf4jVersion} test @@ -333,16 +420,7 @@ under the License. These files contain results for integration tests which can't contain license header otherwise the IT's will fail. --> - src/it/projects/tree/expected.txt - src/it/projects/tree-includes/expected.txt - src/it/projects/tree-multimodule/expected.txt - src/it/projects/tree-multimodule/module-a/expected.txt - src/it/projects/tree-multimodule/module-b/expected.txt - src/it/projects/tree-verbose-multimodule/expected.txt - src/it/projects/tree-verbose-multimodule/module-a/expected.txt - src/it/projects/tree-verbose-multimodule/module-b/expected.txt - src/it/projects/tree-verbose/expected*.txt - src/it/projects/tree-verbose-small/expected.txt + src/it/projects/**/expected*.txt src/test/resources/unit/verbose-serializer-test/* + org.apache.maven.resolver:maven-resolver-connector-basic + org.apache.maven.resolver:maven-resolver-transport-file + org.apache.maven.resolver:maven-resolver-transport-http + org.junit.vintage:junit-vintage-engine + + + + + @@ -372,12 +469,15 @@ under the License. maven-surefire-plugin - -Xmx384m - - ${maven.home} - + -Xmx512m + 2 + true + + org.eclipse.sisu + sisu-maven-plugin + @@ -405,32 +505,34 @@ under the License. src/it/mrm/settings.xml - ${repository.proxy.url} + 3.11.0 + true org.jsoup jsoup - 1.15.3 + 1.21.2 org.codehaus.mojo mrm-maven-plugin - 1.4.1 + 1.7.0 repository.proxy.url src/it/mrm/repository + ${project.build.directory}/mock-repo ${project.build.directory}/local-repo - + diff --git a/src/changes/changes.xml b/src/config/checkstyle-suppressions.xml similarity index 57% rename from src/changes/changes.xml rename to src/config/checkstyle-suppressions.xml index 065cb8404..3fea1ee7c 100644 --- a/src/changes/changes.xml +++ b/src/config/checkstyle-suppressions.xml @@ -1,4 +1,4 @@ - + - - - - Dependency Maven Plugin - Brian Fox - - - - - - Initial Release of Plugin - - Issue for initial import of plugin - Add strip version functionality to copyMojo - - - + + + + diff --git a/src/it/mrm/repository/a-with-dep.pom b/src/it/mrm/repository/a-with-dep.pom new file mode 100644 index 000000000..d3d163a87 --- /dev/null +++ b/src/it/mrm/repository/a-with-dep.pom @@ -0,0 +1,37 @@ + + + + + 4.0.0 + + org.apache.maven.its.dependency + a-with-dep + 1.0.0 + + + + org.apache.maven.its.dependency + b-with-dep + 1.0.0 + + + diff --git a/src/it/mrm/repository/b-with-dep.pom b/src/it/mrm/repository/b-with-dep.pom new file mode 100644 index 000000000..60c213fea --- /dev/null +++ b/src/it/mrm/repository/b-with-dep.pom @@ -0,0 +1,38 @@ + + + + + 4.0.0 + + org.apache.maven.its.dependency + b-with-dep + 1.0.0 + + + + org.apache.maven.its.dependency + c-without-dep + 1.0.0 + + + + diff --git a/src/it/mrm/repository/c-without-dep.pom b/src/it/mrm/repository/c-without-dep.pom new file mode 100644 index 000000000..36721d29d --- /dev/null +++ b/src/it/mrm/repository/c-without-dep.pom @@ -0,0 +1,30 @@ + + + + + 4.0.0 + + org.apache.maven.its.dependency + c-without-dep + 1.0.0 + + diff --git a/src/it/mrm/settings.xml b/src/it/mrm/settings.xml index bd5f56925..63bd2bf03 100644 --- a/src/it/mrm/settings.xml +++ b/src/it/mrm/settings.xml @@ -38,12 +38,10 @@ under the License. true ignore - never true ignore - always @@ -54,12 +52,10 @@ under the License. true ignore - never true ignore - always diff --git a/src/it/projects/sources/invoker.properties b/src/it/projects/analyze-excluded-classes/invoker.properties similarity index 97% rename from src/it/projects/sources/invoker.properties rename to src/it/projects/analyze-excluded-classes/invoker.properties index 4c31605a2..0eca1be80 100644 --- a/src/it/projects/sources/invoker.properties +++ b/src/it/projects/analyze-excluded-classes/invoker.properties @@ -15,4 +15,4 @@ # specific language governing permissions and limitations # under the License. -invoker.goals = ${project.groupId}:${project.artifactId}:${project.version}:sources +invoker.goals = ${project.groupId}:${project.artifactId}:${project.version}:analyze diff --git a/src/it/projects/analyze-excluded-classes/pom.xml b/src/it/projects/analyze-excluded-classes/pom.xml new file mode 100644 index 000000000..7d678478f --- /dev/null +++ b/src/it/projects/analyze-excluded-classes/pom.xml @@ -0,0 +1,70 @@ + + + + + 4.0.0 + + org.apache.maven.its.dependency + test + 1.0-SNAPSHOT + + Test + + Test dependency:analyze with excluded classes + + + + UTF-8 + + + + + org.apache.maven + maven-artifact + @mavenVersion@ + + + org.apache.maven + maven-core + @mavenVersion@ + + + + + + + + maven-dependency-plugin + @project.version@ + + true + true + true + + org.example.Bad.* + + + + + + + diff --git a/src/it/projects/analyze-excluded-classes/setup.groovy b/src/it/projects/analyze-excluded-classes/setup.groovy new file mode 100644 index 000000000..c45210978 --- /dev/null +++ b/src/it/projects/analyze-excluded-classes/setup.groovy @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +// prepare a class with wrong bytecode +def badClass = new File(basedir, 'target/classes/org/example/BadClass.class') + +badClass.getParentFile().mkdirs() +badClass << 'some content' + +assert badClass.isFile() diff --git a/src/it/projects/tree-includes/verify.bsh b/src/it/projects/analyze-excluded-classes/src/main/java/Main.java similarity index 63% rename from src/it/projects/tree-includes/verify.bsh rename to src/it/projects/analyze-excluded-classes/src/main/java/Main.java index 39689abaf..e4d166fa1 100644 --- a/src/it/projects/tree-includes/verify.bsh +++ b/src/it/projects/analyze-excluded-classes/src/main/java/Main.java @@ -17,21 +17,15 @@ * under the License. */ -import java.io.*; +import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.repository.metadata.Metadata; +import org.apache.maven.model.Model; -import org.codehaus.plexus.util.*; - -String actual = FileUtils.fileRead( new File( basedir, "target/tree.txt" ) ); -String expected = FileUtils.fileRead( new File( basedir, "expected.txt" ) ); - -actual = actual.replaceAll( "[\n\r]+", "\n" ); -expected = expected.replaceAll( "[\n\r]+", "\n" ); +public class Main +{ + public static final String SCOPE_COMPILE = Artifact.SCOPE_COMPILE; -System.out.println( "Checking dependency tree..." ); + public Model model = null; -if ( !actual.equals( expected ) ) -{ - throw new Exception( "Unexpected dependency tree" ); + public Metadata metadata = null; } - -return true; diff --git a/src/it/projects/analyze-excluded-classes/verify.groovy b/src/it/projects/analyze-excluded-classes/verify.groovy new file mode 100644 index 000000000..96b61dc73 --- /dev/null +++ b/src/it/projects/analyze-excluded-classes/verify.groovy @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +File classFile = new File( basedir, "target/classes/Main.class" ) +assert classFile.exists() +assert classFile.isFile() : "Build was not forked, class missing " + classFile + +File file = new File( basedir, "build.log" ) +assert file.exists() + +String buildLog = file.getText( "UTF-8" ) +assert buildLog.contains( '[WARNING] Used undeclared dependencies found:') +assert buildLog.contains( '[WARNING] org.apache.maven:maven-model:jar:') +assert buildLog.contains( '[WARNING] Unused declared dependencies found:') +assert buildLog.contains( '[WARNING] org.apache.maven:maven-core:jar:') diff --git a/src/it/projects/analyze-ignore-all-non-test-scope-dependency/pom.xml b/src/it/projects/analyze-ignore-all-non-test-scope-dependency/pom.xml index a762b0b69..3bf859f54 100644 --- a/src/it/projects/analyze-ignore-all-non-test-scope-dependency/pom.xml +++ b/src/it/projects/analyze-ignore-all-non-test-scope-dependency/pom.xml @@ -49,6 +49,7 @@ maven-dependency-plugin + @project.version@ true true diff --git a/src/it/projects/analyze-ignore-dependency/pom.xml b/src/it/projects/analyze-ignore-dependency/pom.xml index c802f08e5..20aba9f99 100644 --- a/src/it/projects/analyze-ignore-dependency/pom.xml +++ b/src/it/projects/analyze-ignore-dependency/pom.xml @@ -49,6 +49,7 @@ maven-dependency-plugin + @project.version@ true true diff --git a/src/it/projects/analyze-ignore-non-test-scope-dependency/pom.xml b/src/it/projects/analyze-ignore-non-test-scope-dependency/pom.xml index 34cb9fed0..a97bfbce7 100644 --- a/src/it/projects/analyze-ignore-non-test-scope-dependency/pom.xml +++ b/src/it/projects/analyze-ignore-non-test-scope-dependency/pom.xml @@ -49,6 +49,7 @@ maven-dependency-plugin + @project.version@ true true diff --git a/src/it/projects/analyze-ignore-unused-declared-dependency/pom.xml b/src/it/projects/analyze-ignore-unused-declared-dependency/pom.xml index 650fb6304..c8fd5bcd5 100644 --- a/src/it/projects/analyze-ignore-unused-declared-dependency/pom.xml +++ b/src/it/projects/analyze-ignore-unused-declared-dependency/pom.xml @@ -49,6 +49,7 @@ maven-dependency-plugin + @project.version@ true true diff --git a/src/it/projects/analyze-ignore-used-undeclared-dependency/pom.xml b/src/it/projects/analyze-ignore-used-undeclared-dependency/pom.xml index 0fa6d51c6..281cb3b59 100644 --- a/src/it/projects/analyze-ignore-used-undeclared-dependency/pom.xml +++ b/src/it/projects/analyze-ignore-used-undeclared-dependency/pom.xml @@ -49,6 +49,7 @@ maven-dependency-plugin + @project.version@ true true diff --git a/src/it/projects/analyze-invalid-exclude-multumodule-project/invoker.properties b/src/it/projects/analyze-invalid-exclude-multumodule-project/invoker.properties new file mode 100644 index 000000000..8b1dfce16 --- /dev/null +++ b/src/it/projects/analyze-invalid-exclude-multumodule-project/invoker.properties @@ -0,0 +1,19 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# 'install' is for this IT to work with Maven 2.2.1. Not required for Maven 3.0+. +invoker.goals = ${project.groupId}:${project.artifactId}:${project.version}:analyze-exclusions diff --git a/src/it/projects/analyze-invalid-exclude-multumodule-project/module1/pom.xml b/src/it/projects/analyze-invalid-exclude-multumodule-project/module1/pom.xml new file mode 100644 index 000000000..fb2662662 --- /dev/null +++ b/src/it/projects/analyze-invalid-exclude-multumodule-project/module1/pom.xml @@ -0,0 +1,55 @@ + + + + + 4.0.0 + + + org.apache.maven.its.dependency + test-parent + 1.0-SNAPSHOT + + + test-module1 + + + + org.apache.maven.its.dependency + a-with-dep + 1.0.0 + + + org.apache.maven.its.dependency + invalid-exclusion2 + + + org.apache.maven.its.dependency + c-without-dep + + + org.apache.maven.its.dependency + invalid-exclusion3 + + + + + diff --git a/src/it/projects/tree/verify.bsh b/src/it/projects/analyze-invalid-exclude-multumodule-project/module1/src/main/java/foo/Main.java similarity index 63% rename from src/it/projects/tree/verify.bsh rename to src/it/projects/analyze-invalid-exclude-multumodule-project/module1/src/main/java/foo/Main.java index 39689abaf..7ca91f797 100644 --- a/src/it/projects/tree/verify.bsh +++ b/src/it/projects/analyze-invalid-exclude-multumodule-project/module1/src/main/java/foo/Main.java @@ -16,22 +16,17 @@ * specific language governing permissions and limitations * under the License. */ +package foo; -import java.io.*; +import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.repository.metadata.Metadata; +import org.apache.maven.model.Model; -import org.codehaus.plexus.util.*; - -String actual = FileUtils.fileRead( new File( basedir, "target/tree.txt" ) ); -String expected = FileUtils.fileRead( new File( basedir, "expected.txt" ) ); - -actual = actual.replaceAll( "[\n\r]+", "\n" ); -expected = expected.replaceAll( "[\n\r]+", "\n" ); +public class Main +{ + public static final String SCOPE_COMPILE = Artifact.SCOPE_COMPILE; -System.out.println( "Checking dependency tree..." ); + public Model model = null; -if ( !actual.equals( expected ) ) -{ - throw new Exception( "Unexpected dependency tree" ); + public Metadata metadata = null; } - -return true; diff --git a/src/it/projects/analyze-invalid-exclude-multumodule-project/module2/pom.xml b/src/it/projects/analyze-invalid-exclude-multumodule-project/module2/pom.xml new file mode 100644 index 000000000..59f3a92b8 --- /dev/null +++ b/src/it/projects/analyze-invalid-exclude-multumodule-project/module2/pom.xml @@ -0,0 +1,48 @@ + + + + + 4.0.0 + + + org.apache.maven.its.dependency + test-parent + 1.0-SNAPSHOT + + + test-module2 + + + + org.apache.maven.its.dependency + test-module1 + ${project.version} + + + org.apache.maven.its.dependency + a-with-dep + + + + + + diff --git a/src/it/projects/analyze-invalid-exclude-multumodule-project/module2/src/main/java/foo/Main.java b/src/it/projects/analyze-invalid-exclude-multumodule-project/module2/src/main/java/foo/Main.java new file mode 100644 index 000000000..7ca91f797 --- /dev/null +++ b/src/it/projects/analyze-invalid-exclude-multumodule-project/module2/src/main/java/foo/Main.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package foo; + +import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.repository.metadata.Metadata; +import org.apache.maven.model.Model; + +public class Main +{ + public static final String SCOPE_COMPILE = Artifact.SCOPE_COMPILE; + + public Model model = null; + + public Metadata metadata = null; +} diff --git a/src/it/projects/analyze-invalid-exclude-multumodule-project/pom.xml b/src/it/projects/analyze-invalid-exclude-multumodule-project/pom.xml new file mode 100644 index 000000000..8e9c27a90 --- /dev/null +++ b/src/it/projects/analyze-invalid-exclude-multumodule-project/pom.xml @@ -0,0 +1,72 @@ + + + + + 4.0.0 + + org.apache.maven.its.dependency + test-parent + 1.0-SNAPSHOT + pom + + Test + + Test dependency:analyze on a multi-module project + + + + UTF-8 + + + + module1 + module2 + + + + + + org.apache.maven.its.dependency + a-with-dep + 1.0.0 + + + org.apache.maven.its.dependency + invalid-exclusion1 + + + + + + + + + + + maven-dependency-plugin + @project.version@ + + + + + + diff --git a/src/it/projects/analyze-invalid-exclude-multumodule-project/verify.groovy b/src/it/projects/analyze-invalid-exclude-multumodule-project/verify.groovy new file mode 100644 index 000000000..b052186e5 --- /dev/null +++ b/src/it/projects/analyze-invalid-exclude-multumodule-project/verify.groovy @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + +static void checkMessagedInLogs(logLines, messages) { + def index = logLines.indexOf(messages[0]) + assert index > 0: "no messages: '" + messages[0] + "' in log" + + def logMessages = logLines[index..index + messages.size() - 1] + + assert logMessages == messages + +} + +def file = new File(basedir, "build.log") +assert file.exists() + +def logLines = buildLog = file.readLines() + +checkMessagedInLogs(logLines, [ + '[WARNING] Test defines following unnecessary excludes', + '[WARNING] org.apache.maven.its.dependency:a-with-dep:1.0.0', + '[WARNING] - org.apache.maven.its.dependency:invalid-exclusion1 @ line: 52' +]) + +checkMessagedInLogs(logLines, [ + '[WARNING] test-module1 defines following unnecessary excludes', + '[WARNING] org.apache.maven.its.dependency:a-with-dep:1.0.0', + '[WARNING] - org.apache.maven.its.dependency:invalid-exclusion2 @ line: 40', + '[WARNING] - org.apache.maven.its.dependency:invalid-exclusion3 @ line: 48' + +]) + +assert logLines.count('[INFO] No problems with dependencies exclusions') == 1 diff --git a/src/it/projects/analyze-invalid-exclude/invoker.properties b/src/it/projects/analyze-invalid-exclude/invoker.properties new file mode 100644 index 000000000..541715067 --- /dev/null +++ b/src/it/projects/analyze-invalid-exclude/invoker.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +invoker.goals = ${project.groupId}:${project.artifactId}:${project.version}:analyze-exclusions diff --git a/src/it/projects/analyze-invalid-exclude/pom.xml b/src/it/projects/analyze-invalid-exclude/pom.xml new file mode 100644 index 000000000..5c65025ca --- /dev/null +++ b/src/it/projects/analyze-invalid-exclude/pom.xml @@ -0,0 +1,102 @@ + + + + + 4.0.0 + + org.apache.maven.its.dependency + test + 1.0-SNAPSHOT + + test-module + + Test dependency:analyze-exclusion + + + + UTF-8 + + + + + + org.apache.maven.its.dependency + a-with-dep + 1.0.0 + + + org.apache.maven.its.dependency + invalid-exclusion1 + + + + + + + + + org.apache.maven.its.dependency + b-with-dep + 1.0.0 + + + org.apache.maven.its.dependency + c-without-dep + + + org.apache.maven.its.dependency + invalid-exclusion3 + + + + + org.apache.maven.its.dependency + a-with-dep + + + org.apache.maven.its.dependency + invalid-exclusion2 + + + org.apache.maven.its.dependency + c-without-dep + + + + + org.apache.maven.its.dependency + c-without-dep + 1.0.0 + + + + + + + + maven-dependency-plugin + @project.version@ + + + + + diff --git a/src/it/projects/analyze-invalid-exclude/src/main/java/Main.java b/src/it/projects/analyze-invalid-exclude/src/main/java/Main.java new file mode 100644 index 000000000..e4d166fa1 --- /dev/null +++ b/src/it/projects/analyze-invalid-exclude/src/main/java/Main.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.repository.metadata.Metadata; +import org.apache.maven.model.Model; + +public class Main +{ + public static final String SCOPE_COMPILE = Artifact.SCOPE_COMPILE; + + public Model model = null; + + public Metadata metadata = null; +} diff --git a/src/it/projects/analyze-invalid-exclude/verify.groovy b/src/it/projects/analyze-invalid-exclude/verify.groovy new file mode 100644 index 000000000..fb3c8c7a6 --- /dev/null +++ b/src/it/projects/analyze-invalid-exclude/verify.groovy @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +def file = new File(basedir, "build.log"); +assert file.exists(); + +def logLines = buildLog = file.readLines() + +def index = logLines.indexOf('[WARNING] test-module defines following unnecessary excludes') +assert index > 0: "no messages in log" + +def messages = logLines[index..index + 5]; + +assert messages == [ + '[WARNING] test-module defines following unnecessary excludes', + '[WARNING] org.apache.maven.its.dependency:a-with-dep:1.0.0', + '[WARNING] - org.apache.maven.its.dependency:invalid-exclusion1 @ line: 46', + '[WARNING] - org.apache.maven.its.dependency:invalid-exclusion2 @ line: 75', + '[WARNING] org.apache.maven.its.dependency:b-with-dep:1.0.0', + '[WARNING] - org.apache.maven.its.dependency:invalid-exclusion3 @ line: 65' +] + + diff --git a/src/it/projects/analyze-report/invoker.properties b/src/it/projects/analyze-report/invoker.properties index a3d335ef8..050bfcf1b 100644 --- a/src/it/projects/analyze-report/invoker.properties +++ b/src/it/projects/analyze-report/invoker.properties @@ -5,9 +5,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 -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @@ -15,4 +15,4 @@ # specific language governing permissions and limitations # under the License. -invoker.goals = site +invoker.goals = ${project.groupId}:${project.artifactId}:${project.version}:analyze-report diff --git a/src/it/projects/analyze-report/pom.xml b/src/it/projects/analyze-report/pom.xml index 1cc764e48..a55389717 100644 --- a/src/it/projects/analyze-report/pom.xml +++ b/src/it/projects/analyze-report/pom.xml @@ -53,46 +53,4 @@ 2.0.6 - - - - - - maven-dependency-plugin - @project.version@ - - - maven-site-plugin - 3.10.0 - - - - - - - - - maven-project-info-reports-plugin - 3.2.1 - - - - index - - - - - - org.apache.maven.plugins - maven-dependency-plugin - - - - analyze-report - - - - - - diff --git a/src/it/projects/analyze-report/verify.bsh b/src/it/projects/analyze-report/verify.bsh index d32f9f902..55b19f0b5 100644 --- a/src/it/projects/analyze-report/verify.bsh +++ b/src/it/projects/analyze-report/verify.bsh @@ -6,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 - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @@ -19,7 +19,7 @@ import java.io.*; -File htmlFile = new File( basedir, "target/site/dependency-analysis.html" ); +File htmlFile = new File( basedir, "target/reports/dependency-analysis.html" ); if ( !htmlFile.isFile() ) { diff --git a/src/it/projects/analyze-testDependencyWithNonTestScope/invoker.properties b/src/it/projects/analyze-testDependencyWithNonTestScope/invoker.properties index 38edf1c32..050bfcf1b 100644 --- a/src/it/projects/analyze-testDependencyWithNonTestScope/invoker.properties +++ b/src/it/projects/analyze-testDependencyWithNonTestScope/invoker.properties @@ -5,9 +5,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 -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @@ -15,5 +15,4 @@ # specific language governing permissions and limitations # under the License. -invoker.goals = clean ${project.groupId}:${project.artifactId}:${project.version}:analyze-report -invoker.maven.version = 3.0+ +invoker.goals = ${project.groupId}:${project.artifactId}:${project.version}:analyze-report diff --git a/src/it/projects/analyze-testDependencyWithNonTestScope/pom.xml b/src/it/projects/analyze-testDependencyWithNonTestScope/pom.xml index 8e8a292cf..89dbdefe3 100644 --- a/src/it/projects/analyze-testDependencyWithNonTestScope/pom.xml +++ b/src/it/projects/analyze-testDependencyWithNonTestScope/pom.xml @@ -28,7 +28,6 @@ UTF-8 - 1.7 1.7 @@ -37,6 +36,7 @@ maven-dependency-plugin + @project.version@ true true diff --git a/src/it/projects/analyze-testDependencyWithNonTestScope/verify.bsh b/src/it/projects/analyze-testDependencyWithNonTestScope/verify.bsh index ba623ba7a..46c27ff4b 100644 --- a/src/it/projects/analyze-testDependencyWithNonTestScope/verify.bsh +++ b/src/it/projects/analyze-testDependencyWithNonTestScope/verify.bsh @@ -6,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 - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @@ -24,7 +24,7 @@ import org.jsoup.nodes.Document; import org.jsoup.nodes.Element; import org.jsoup.select.Elements; -File htmlFile = new File( basedir, "target/site/dependency-analysis.html" ); +File htmlFile = new File( basedir, "target/reports/dependency-analysis.html" ); if ( !htmlFile.isFile() ) { @@ -37,7 +37,7 @@ if ( htmlFile.length() == 0 ) Document doc = Jsoup.parse( htmlFile, "UTF-8"); -Elements entry = doc.select( "#contentBox > section > section:nth-child(5) > table > tbody > tr.b" ); +Elements entry = doc.select( "#bodyColumn > section > section:nth-child(5) > table > tbody > tr.b" ); if( entry.isEmpty() ) { @@ -50,7 +50,7 @@ else if ( entry.size() != 1 ) } Element groupIdElement = doc.select( -"#contentBox > section > section:nth-child(5) > table > tbody > tr.b > td:nth-child(1)" ).first(); +"#bodyColumn > section > section:nth-child(5) > table > tbody > tr.b > td:nth-child(1)" ).first(); String groupId = groupIdElement.text(); diff --git a/src/it/projects/analyze/pom.xml b/src/it/projects/analyze/pom.xml index fc13441d4..e3072ae88 100644 --- a/src/it/projects/analyze/pom.xml +++ b/src/it/projects/analyze/pom.xml @@ -52,6 +52,12 @@ maven-model 2.0.6 + + + org.slf4j + slf4j-simple + 2.0.16 + @@ -59,6 +65,7 @@ maven-dependency-plugin + @project.version@ true true diff --git a/src/it/projects/analyze/verify.groovy b/src/it/projects/analyze/verify.groovy index 0ff117d26..4b430120a 100644 --- a/src/it/projects/analyze/verify.groovy +++ b/src/it/projects/analyze/verify.groovy @@ -17,25 +17,27 @@ * under the License. */ -File classFile = new File( basedir, "target/classes/Main.class" ); -assert classFile.exists(); +File classFile = new File( basedir, "target/classes/Main.class" ) +assert classFile.exists() if ( !classFile.isFile() ) { - throw new Exception( "Build was not forked, class missing " + classFile ); + throw new Exception( "Build was not forked, class missing " + classFile ) } -File file = new File( basedir, "build.log" ); -assert file.exists(); +File file = new File( basedir, "build.log" ) +assert file.exists() -String buildLog = file.getText( "UTF-8" ); -assert buildLog.contains( '[INFO] Used declared dependencies found:'); -assert buildLog.contains( '[INFO] org.apache.maven:maven-artifact:jar:2.0.6:compile'); -assert buildLog.contains( '[INFO] org.apache.maven:maven-model:jar:2.0.6:compile'); -assert buildLog.contains( '[WARNING] Used undeclared dependencies found:'); -assert buildLog.contains( '[WARNING] org.apache.maven:maven-repository-metadata:jar:2.0.6:compile'); -assert buildLog.contains( '[WARNING] class org.apache.maven.artifact.repository.metadata.Metadata'); -assert buildLog.contains( '[WARNING] Unused declared dependencies found:'); -assert buildLog.contains( '[WARNING] org.apache.maven:maven-project:jar:2.0.6:compile'); +String buildLog = file.getText( "UTF-8" ) +assert buildLog.contains( '[INFO] Used declared dependencies found:') +assert buildLog.contains( '[INFO] org.apache.maven:maven-artifact:jar:2.0.6:compile') +assert buildLog.contains( '[INFO] org.apache.maven:maven-model:jar:2.0.6:compile') +assert buildLog.contains( '[WARNING] Used undeclared dependencies found:') +assert buildLog.contains( '[WARNING] org.apache.maven:maven-repository-metadata:jar:2.0.6:compile') +assert buildLog.contains( '[WARNING] class org.apache.maven.artifact.repository.metadata.Metadata') +assert buildLog.contains( '[WARNING] Unused declared dependencies found:') +assert buildLog.contains( '[WARNING] org.apache.maven:maven-project:jar:2.0.6:compile') +assert buildLog.contains( '[INFO] Ignored unused declared dependencies:') +assert buildLog.contains( '[INFO] org.slf4j:slf4j-simple:jar:2.0.16:compile') +assert !buildLog.contains( '[WARNING] org.slf4j:slf4j-simple:jar:2.0.16:compile') - -return true; +return true diff --git a/src/it/projects/build-classpath-output-file-and-property/pom.xml b/src/it/projects/build-classpath-output-file-and-property/pom.xml index 82dee75e7..0b44be25e 100644 --- a/src/it/projects/build-classpath-output-file-and-property/pom.xml +++ b/src/it/projects/build-classpath-output-file-and-property/pom.xml @@ -42,7 +42,7 @@ 1.0 - + @@ -62,7 +62,7 @@ org.apache.maven.plugins maven-enforcer-plugin - 1.4.1 + 3.3.0 enforce-property diff --git a/src/it/projects/copy-and-unpack-with-alternate-local-repo/verify.bsh b/src/it/projects/copy-and-unpack-with-alternate-local-repo/verify.bsh index e4046ae62..9bfa43941 100644 --- a/src/it/projects/copy-and-unpack-with-alternate-local-repo/verify.bsh +++ b/src/it/projects/copy-and-unpack-with-alternate-local-repo/verify.bsh @@ -22,21 +22,18 @@ import java.io.*; File file = new File( basedir, "target/dependency/junit-3.8.1.jar" ); -System.out.println( "Checking for existence of " + file ); if ( !file.isFile() ) { throw new Exception( "Missing " + file ); } file = new File( basedir, "target/dependency/junit" ); -System.out.println( "Checking for existence of " + file ); if ( !file.isDirectory() ) { throw new Exception( "Missing " + file ); } file = new File( basedir, "target/repo/junit/junit/3.8.1/junit-3.8.1.jar" ); -System.out.println( "Checking for existence of " + file ); if ( !file.isFile() ) { throw new Exception( "Missing " + file ); diff --git a/src/it/projects/copy-cli/verify.bsh b/src/it/projects/copy-cli/verify.bsh index 93fad1551..da93772de 100644 --- a/src/it/projects/copy-cli/verify.bsh +++ b/src/it/projects/copy-cli/verify.bsh @@ -28,7 +28,6 @@ String[] expectedFiles = { for ( String expectedFile : expectedFiles ) { File file = new File( libDir, expectedFile ); - System.out.println( "Checking for existence of " + file ); if ( !file.isFile() ) { throw new Exception( "Missing file " + file ); diff --git a/src/it/projects/sources/test.properties b/src/it/projects/copy-dependencies-with-conflict/invoker.properties similarity index 95% rename from src/it/projects/sources/test.properties rename to src/it/projects/copy-dependencies-with-conflict/invoker.properties index 238ec42e9..f50e476fd 100644 --- a/src/it/projects/sources/test.properties +++ b/src/it/projects/copy-dependencies-with-conflict/invoker.properties @@ -15,4 +15,4 @@ # specific language governing permissions and limitations # under the License. -outputFile = target/resolved.txt +invoker.goals = clean process-sources diff --git a/src/it/projects/copy-dependencies-with-conflict/pom.xml b/src/it/projects/copy-dependencies-with-conflict/pom.xml new file mode 100644 index 000000000..b7c6cf627 --- /dev/null +++ b/src/it/projects/copy-dependencies-with-conflict/pom.xml @@ -0,0 +1,77 @@ + + + + + 4.0.0 + + org.apache.maven.its.dependency + test + 1.0-SNAPSHOT + + Test with conflicts + + Test dependency:copy-dependencies with conflicting artifact IDs + + + + + + + org.jdom + jdom + 1.1.3 + + + org.lucee + jdom + 1.1.3 + + + + + UTF-8 + + + + + package + + + + maven-dependency-plugin + @project.version@ + + + test-2 + + copy-dependencies + + + true + ${project.build.directory}/it/copy-dep-test-2 + + + + + + + diff --git a/src/it/projects/copy-dependencies-with-conflict/verify.groovy b/src/it/projects/copy-dependencies-with-conflict/verify.groovy new file mode 100644 index 000000000..b66deb089 --- /dev/null +++ b/src/it/projects/copy-dependencies-with-conflict/verify.groovy @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +File file = new File( basedir, "build.log" ) +assert file.exists() + +String buildLog = file.getText( "UTF-8" ) +assert buildLog.contains( '[WARNING] Overwriting ' ) +assert buildLog.contains( '[DEBUG] Copying artifact \'org.jdom:jdom:jar:1.1.3\'' ) +assert buildLog.contains( '[DEBUG] Copying artifact \'org.jdom:jdom:pom:1.1.3\'' ) +assert buildLog.contains( '[DEBUG] Copying artifact \'org.jdom:jdom:jar:1.1.3\'' ) +assert buildLog.contains( '[DEBUG] Copying artifact \'org.lucee:jdom:jar:1.1.3\'' ) +assert buildLog.contains( '[WARNING] Multiple files with the name jdom-1.1.3.jar in the dependency tree.' ) + +return true diff --git a/src/it/projects/copy-dependencies/pom.xml b/src/it/projects/copy-dependencies/pom.xml index cff5a89f6..398aeeb27 100644 --- a/src/it/projects/copy-dependencies/pom.xml +++ b/src/it/projects/copy-dependencies/pom.xml @@ -101,7 +101,6 @@ true ${project.build.directory}/it/copy-dep-test-1 - false diff --git a/src/it/projects/copy-dependencies/verify.bsh b/src/it/projects/copy-dependencies/verify.bsh index 80031daf5..7a3ce8606 100644 --- a/src/it/projects/copy-dependencies/verify.bsh +++ b/src/it/projects/copy-dependencies/verify.bsh @@ -24,7 +24,6 @@ void checkExpected( File dir, String[] expectedFiles ) for ( String expectedFile : expectedFiles ) { File file = new File( dir, expectedFile ); - System.out.println( "Checking for existence of " + file ); if ( !file.isFile() ) { throw new Exception( "Missing file " + file ); @@ -39,7 +38,6 @@ void checkExpected( File dir, String[] expectedFiles, String[] unexpectedFiles ) for ( String unexpectedFile : unexpectedFiles ) { File file = new File( dir, unexpectedFile ); - System.out.println( "Checking for inexistence of " + file ); if ( file.isFile() ) { throw new Exception( "Unexpected file " + file + " found" ); diff --git a/src/it/projects/copy-from-reactor/child-b/pom.xml b/src/it/projects/copy-from-reactor/child-b/pom.xml index 891439ab5..6ef74e860 100644 --- a/src/it/projects/copy-from-reactor/child-b/pom.xml +++ b/src/it/projects/copy-from-reactor/child-b/pom.xml @@ -52,6 +52,7 @@ maven-dependency-plugin + @project.version@ test diff --git a/src/it/projects/copy-from-reactor/verify.bsh b/src/it/projects/copy-from-reactor/verify.bsh index d4c63a651..9367fb019 100644 --- a/src/it/projects/copy-from-reactor/verify.bsh +++ b/src/it/projects/copy-from-reactor/verify.bsh @@ -28,7 +28,6 @@ String[] expectedFiles = { for ( String expectedFile : expectedFiles ) { File file = new File( libDir, expectedFile ); - System.out.println( "Checking for existence of " + file ); if ( !file.isFile() ) { throw new Exception( "Missing file " + file ); diff --git a/src/it/projects/copy-from-remote-repository/pom.xml b/src/it/projects/copy-from-remote-repository/pom.xml index f55e60363..1e991a852 100644 --- a/src/it/projects/copy-from-remote-repository/pom.xml +++ b/src/it/projects/copy-from-remote-repository/pom.xml @@ -42,6 +42,9 @@ fake-remote-repository file:///${basedir}/repo/ + + ignore + diff --git a/src/it/projects/copy-from-remote-repository/verify.bsh b/src/it/projects/copy-from-remote-repository/verify.bsh index 1e390870f..6edc839fd 100644 --- a/src/it/projects/copy-from-remote-repository/verify.bsh +++ b/src/it/projects/copy-from-remote-repository/verify.bsh @@ -26,7 +26,6 @@ String[] expectedFiles = { for ( String expectedFile : expectedFiles ) { File file = new File( localRepositoryPath, expectedFile ); - System.out.println( "Checking for existence of " + file ); if ( !file.isFile() ) { throw new Exception( "Missing file " + file ); diff --git a/src/it/projects/copy-with-prependGroupId/verify.bsh b/src/it/projects/copy-with-prependGroupId/verify.bsh index 8018ef236..38018ab5d 100644 --- a/src/it/projects/copy-with-prependGroupId/verify.bsh +++ b/src/it/projects/copy-with-prependGroupId/verify.bsh @@ -28,7 +28,6 @@ String[] expectedFiles = { for ( String expectedFile : expectedFiles ) { File file = new File( libDir, expectedFile ); - System.out.println( "Checking for existence of " + file ); if ( !file.isFile() ) { throw new Exception( "Missing file " + file ); diff --git a/src/it/projects/copy/verify.bsh b/src/it/projects/copy/verify.bsh index 93fad1551..da93772de 100644 --- a/src/it/projects/copy/verify.bsh +++ b/src/it/projects/copy/verify.bsh @@ -28,7 +28,6 @@ String[] expectedFiles = { for ( String expectedFile : expectedFiles ) { File file = new File( libDir, expectedFile ); - System.out.println( "Checking for existence of " + file ); if ( !file.isFile() ) { throw new Exception( "Missing file " + file ); diff --git a/src/it/projects/filterunpack/verify.groovy b/src/it/projects/filterunpack/verify.groovy index 330e6aa30..8ed2f2517 100644 --- a/src/it/projects/filterunpack/verify.groovy +++ b/src/it/projects/filterunpack/verify.groovy @@ -24,7 +24,7 @@ for (item in expected) def file = new File(basedir, 'target/dependency' + item) if (!file.exists()) { - throw new RuntimeException("Missing "+file.name); + throw new RuntimeException("Missing "+file.name) } } @@ -35,8 +35,8 @@ for (item in notExpected) def file = new File(basedir, 'target/dependency' + item) if (file.exists()) { - throw new RuntimeException("This file shouldn't be here: "+file.name); + throw new RuntimeException("This file shouldn't be here: "+file.name) } } -return true; +return true diff --git a/src/it/projects/get-artifact-maven-plugin/verify.bsh b/src/it/projects/get-artifact-maven-plugin/verify.bsh index 2f8cad07a..e75bdf475 100644 --- a/src/it/projects/get-artifact-maven-plugin/verify.bsh +++ b/src/it/projects/get-artifact-maven-plugin/verify.bsh @@ -27,7 +27,6 @@ String[] expectedFiles = { for ( String expectedFile : expectedFiles ) { File file = new File( localRepositoryPath, expectedFile ); - System.out.println( "Checking for existence of " + file ); if ( !file.isFile() ) { throw new Exception( "Missing file " + file ); diff --git a/src/it/projects/get-artifact-no-transitive/verify.bsh b/src/it/projects/get-artifact-no-transitive/verify.bsh index dfa7d2981..3c53da8d7 100644 --- a/src/it/projects/get-artifact-no-transitive/verify.bsh +++ b/src/it/projects/get-artifact-no-transitive/verify.bsh @@ -27,7 +27,6 @@ String[] expectedFiles = { for ( String expectedFile : expectedFiles ) { File file = new File( localRepositoryPath, expectedFile ); - System.out.println( "Checking for existence of " + file ); if ( !file.isFile() ) { throw new Exception( "Missing file " + file ); @@ -42,7 +41,6 @@ String[] notExpectedFiles = { for ( String notExpectedFile : notExpectedFiles ) { File file = new File( localRepositoryPath, notExpectedFile ); - System.out.println( "Checking for absence of " + file ); if ( file.isFile() ) { throw new Exception( "Existing file " + file ); diff --git a/src/it/projects/get-artifact/verify.bsh b/src/it/projects/get-artifact/verify.bsh index a586d5653..25120f4fb 100644 --- a/src/it/projects/get-artifact/verify.bsh +++ b/src/it/projects/get-artifact/verify.bsh @@ -29,7 +29,6 @@ String[] expectedFiles = { for ( String expectedFile : expectedFiles ) { File file = new File( localRepositoryPath, expectedFile ); - System.out.println( "Checking for existence of " + file ); if ( !file.isFile() ) { throw new Exception( "Missing file " + file ); diff --git a/src/it/projects/get-gav/verify.bsh b/src/it/projects/get-gav/verify.bsh index a586d5653..25120f4fb 100644 --- a/src/it/projects/get-gav/verify.bsh +++ b/src/it/projects/get-gav/verify.bsh @@ -29,7 +29,6 @@ String[] expectedFiles = { for ( String expectedFile : expectedFiles ) { File file = new File( localRepositoryPath, expectedFile ); - System.out.println( "Checking for existence of " + file ); if ( !file.isFile() ) { throw new Exception( "Missing file " + file ); diff --git a/src/it/projects/go-offline/pom.xml b/src/it/projects/go-offline/pom.xml index fc59fc1e6..b185dc590 100644 --- a/src/it/projects/go-offline/pom.xml +++ b/src/it/projects/go-offline/pom.xml @@ -36,12 +36,24 @@ UTF-8 + org.apache.maven - maven-project - 2.0.6 + maven-core + 3.9.11 + + + + + org.apache.maven.plugins + maven-clean-plugin + 3.5.0 + + + + diff --git a/src/it/projects/go-offline/verify.groovy b/src/it/projects/go-offline/verify.groovy new file mode 100644 index 000000000..550cc2caf --- /dev/null +++ b/src/it/projects/go-offline/verify.groovy @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +File file = new File(basedir, 'build.log') +assert file.exists() + +String buildLog = file.getText("UTF-8") + +assert buildLog.contains('[INFO] Resolved plugin: maven-clean-plugin-3.5.0.jar') +assert buildLog.contains('[INFO] Resolved plugin dependency:') +assert buildLog.contains('[INFO] maven-clean-plugin-3.5.0.jar') +assert buildLog.contains('[INFO] plexus-utils-4.0.2.jar') + +assert buildLog.contains('[INFO] Resolved dependency: maven-core-3.9.11.jar') +assert buildLog.contains('[INFO] Resolved dependency: maven-model-3.9.11.jar') +assert buildLog.contains('[INFO] Resolved dependency: maven-settings-3.9.11.jar') + + diff --git a/src/it/projects/list-repositories/pom.xml b/src/it/projects/list-repositories/pom.xml index 5b3be7983..d74bc248d 100644 --- a/src/it/projects/list-repositories/pom.xml +++ b/src/it/projects/list-repositories/pom.xml @@ -1,47 +1,54 @@ - - - - - 4.0.0 - - org.apache.maven.its.dependency - test - 1.0-SNAPSHOT - - Test - - Test dependency:list-repositories - - - - UTF-8 - - - - - org.apache.maven - maven-project - 2.0.6 - - - - + + + + + 4.0.0 + + org.apache.maven.its.dependency + test + 1.0-SNAPSHOT + + Test + + Test dependency:list-repositories + + + + UTF-8 + + + + + fake-remote-repository + http://localhost:2345 + + + + + + org.apache.maven + maven-core + 3.2.5 + + + + \ No newline at end of file diff --git a/src/it/projects/list-repositories/verify.groovy b/src/it/projects/list-repositories/verify.groovy new file mode 100644 index 000000000..bd311cf9c --- /dev/null +++ b/src/it/projects/list-repositories/verify.groovy @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +File file = new File( basedir, "build.log" ) +assert file.exists() + +String buildLog = file.getText( "UTF-8" ) +assert buildLog.contains( 'Project remote repositories used by this build:') +assert buildLog.contains( '* fake-remote-repository (http://localhost:2345, default, releases+snapshots)') +assert buildLog.contains( '* sonatype-nexus-snapshots (https://oss.sonatype.org/content/repositories/snapshots, default, snapshots) mirrored by mrm-maven-plugin') +if (!mavenVersion.startsWith('4.')) { + // Maven 4 drop central repo from default super pom - so model doesn't have it + assert buildLog.contains('* central (https://repo.maven.apache.org/maven2, default, releases) mirrored by mrm-maven-plugin') +} diff --git a/src/it/projects/mdep-204-go-offline-resolve-intermodule/module-1/pom.xml b/src/it/projects/mdep-204-go-offline-resolve-intermodule/module-1/pom.xml index 07bec4073..5bff94ea0 100644 --- a/src/it/projects/mdep-204-go-offline-resolve-intermodule/module-1/pom.xml +++ b/src/it/projects/mdep-204-go-offline-resolve-intermodule/module-1/pom.xml @@ -35,7 +35,7 @@ org.apache.commons commons-lang3 - 3.9 + 3.18.0 diff --git a/src/it/projects/mdep-204-go-offline-resolve-intermodule/module-2/pom.xml b/src/it/projects/mdep-204-go-offline-resolve-intermodule/module-2/pom.xml index 50f7922d7..db9e97b12 100644 --- a/src/it/projects/mdep-204-go-offline-resolve-intermodule/module-2/pom.xml +++ b/src/it/projects/mdep-204-go-offline-resolve-intermodule/module-2/pom.xml @@ -42,7 +42,7 @@ ch.qos.logback logback-classic - 1.2.3 + 1.2.13 diff --git a/src/it/projects/mdep-439-analyze-java8/invoker.properties b/src/it/projects/mdep-439-analyze-java8/invoker.properties index b81576bc0..35372acc1 100644 --- a/src/it/projects/mdep-439-analyze-java8/invoker.properties +++ b/src/it/projects/mdep-439-analyze-java8/invoker.properties @@ -5,9 +5,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 -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @@ -15,5 +15,4 @@ # specific language governing permissions and limitations # under the License. -invoker.java.version = 1.8+ invoker.goals=clean verify diff --git a/src/it/projects/mdep-439-analyze-java8/pom.xml b/src/it/projects/mdep-439-analyze-java8/pom.xml index 27ce72494..7d00e9c1a 100644 --- a/src/it/projects/mdep-439-analyze-java8/pom.xml +++ b/src/it/projects/mdep-439-analyze-java8/pom.xml @@ -23,7 +23,7 @@ under the License. 4.0.0 - + org.sugis.maven dep-analyze-java8 dep-analyze-java8 @@ -56,7 +56,7 @@ under the License. org.apache.maven.plugins maven-compiler-plugin - 3.1 + @version.maven-compiler-plugin@ 1.8 1.8 diff --git a/src/it/projects/mdep-450-project-with-ancestor/verify.groovy b/src/it/projects/mdep-450-project-with-ancestor/verify.groovy index 19a18cedc..0d48aaba5 100644 --- a/src/it/projects/mdep-450-project-with-ancestor/verify.groovy +++ b/src/it/projects/mdep-450-project-with-ancestor/verify.groovy @@ -17,10 +17,10 @@ * under the License. */ -File file = new File( basedir, "build.log" ); -assert file.exists(); +File file = new File( basedir, "build.log" ) +assert file.exists() -String buildLog = file.getText( "UTF-8" ); -assert buildLog.contains( 'Ancestor POMs: org.apache:apache:5' ); +String buildLog = file.getText( "UTF-8" ) +assert buildLog.contains( 'Ancestor POMs: org.apache:apache:5' ) -return true; +return true diff --git a/src/it/projects/mdep-450-project-without-ancestor/verify.groovy b/src/it/projects/mdep-450-project-without-ancestor/verify.groovy index fd0afd7f5..15bbe6625 100644 --- a/src/it/projects/mdep-450-project-without-ancestor/verify.groovy +++ b/src/it/projects/mdep-450-project-without-ancestor/verify.groovy @@ -17,10 +17,10 @@ * under the License. */ -File file = new File( basedir, "build.log" ); -assert file.exists(); +File file = new File( basedir, "build.log" ) +assert file.exists() -String buildLog = file.getText( "UTF-8" ); -assert buildLog.contains( 'No Ancestor POMs!' ); +String buildLog = file.getText( "UTF-8" ) +assert buildLog.contains( 'No Ancestor POMs!' ) -return true; +return true diff --git a/src/it/projects/mdep-571-resolve-java9/invoker.properties b/src/it/projects/mdep-571-resolve-java9/invoker.properties index f4bce4e4c..e6c16a727 100644 --- a/src/it/projects/mdep-571-resolve-java9/invoker.properties +++ b/src/it/projects/mdep-571-resolve-java9/invoker.properties @@ -1,19 +1,19 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -invoker.java.version = 1.9+ -invoker.goals = ${project.groupId}:${project.artifactId}:${project.version}:resolve +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +invoker.java.version = 9+ +invoker.goals = ${project.groupId}:${project.artifactId}:${project.version}:resolve diff --git a/src/it/projects/mdep-571-resolve-java9/verify.groovy b/src/it/projects/mdep-571-resolve-java9/verify.groovy index e93e874c9..2fe1f641b 100644 --- a/src/it/projects/mdep-571-resolve-java9/verify.groovy +++ b/src/it/projects/mdep-571-resolve-java9/verify.groovy @@ -17,10 +17,10 @@ * under the License. */ -File file = new File( basedir, "build.log" ); -assert file.exists(); +File file = new File( basedir, "build.log" ) +assert file.exists() -String buildLog = file.getText( "UTF-8" ); -assert buildLog.contains( 'org.slf4j:slf4j-api:jar:1.7.6:compile -- module' ); +String buildLog = file.getText( "UTF-8" ) +assert buildLog.contains( 'org.slf4j:slf4j-api:jar:1.7.6:compile -- module' ) -return true; +return true diff --git a/src/it/projects/mdep-572-unpack-tar-long-file/child1/pom.xml b/src/it/projects/mdep-572-unpack-tar-long-file/child1/pom.xml index 93a49d7dd..ba478bab9 100644 --- a/src/it/projects/mdep-572-unpack-tar-long-file/child1/pom.xml +++ b/src/it/projects/mdep-572-unpack-tar-long-file/child1/pom.xml @@ -32,7 +32,7 @@ under the License. maven-assembly-plugin - 3.0.0 + @version.maven-assembly-plugin@ diff --git a/src/it/projects/mdep-578_display-reason-invalid-module/verify.groovy b/src/it/projects/mdep-578_display-reason-invalid-module/verify.groovy index 7bfaa91db..c1e00cac0 100644 --- a/src/it/projects/mdep-578_display-reason-invalid-module/verify.groovy +++ b/src/it/projects/mdep-578_display-reason-invalid-module/verify.groovy @@ -17,20 +17,20 @@ * under the License. */ -File file = new File( basedir, "build.log" ); -assert file.exists(); +File file = new File( basedir, "build.log" ) +assert file.exists() -String buildLog = file.getText( "UTF-8" ); +String buildLog = file.getText( "UTF-8" ) // Cause message is JDK specific and can change over time // JDOMAbout$Author.class found in top-level directory (unnamed package not allowed in module) -assert buildLog.contains( "Can't extract module name from jdom-1.0.jar: " ); +assert buildLog.contains( "Can't extract module name from jdom-1.0.jar: " ) // geronimo.servlet.2.4.spec: Invalid module name: '2' is not a Java identifier -assert buildLog.contains( "Can't extract module name from geronimo-servlet_2.4_spec-1.1.1.jar: " ); +assert buildLog.contains( "Can't extract module name from geronimo-servlet_2.4_spec-1.1.1.jar: " ) // geronimo.jta.1.1.spec: Invalid module name: '1' is not a Java identifier -assert buildLog.contains( "Can't extract module name from geronimo-jta_1.1_spec-1.1.jar: " ); +assert buildLog.contains( "Can't extract module name from geronimo-jta_1.1_spec-1.1.jar: " ) -return true; +return true diff --git a/src/it/projects/mdep-580_display-manifest-automodules/verify.groovy b/src/it/projects/mdep-580_display-manifest-automodules/verify.groovy index 20b88d711..539131bfa 100644 --- a/src/it/projects/mdep-580_display-manifest-automodules/verify.groovy +++ b/src/it/projects/mdep-580_display-manifest-automodules/verify.groovy @@ -17,11 +17,11 @@ * under the License. */ -File file = new File( basedir, "build.log" ); -assert file.exists(); +File file = new File( basedir, "build.log" ) +assert file.exists() -String buildLog = file.getText( "UTF-8" ); +String buildLog = file.getText( "UTF-8" ) -assert buildLog.contains( "org.apache.maven.resolver:maven-resolver-api:jar:1.1.0:compile -- module org.apache.maven.resolver [auto]" ); +assert buildLog.contains( "org.apache.maven.resolver:maven-resolver-api:jar:1.1.0:compile -- module org.apache.maven.resolver [auto]" ) -return true; +return true diff --git a/src/it/projects/mdep-586-unpacking-resources/verify.groovy b/src/it/projects/mdep-586-unpacking-resources/verify.groovy index a35849839..991b88b00 100644 --- a/src/it/projects/mdep-586-unpacking-resources/verify.groovy +++ b/src/it/projects/mdep-586-unpacking-resources/verify.groovy @@ -17,8 +17,8 @@ * under the License. */ -File file = new File( basedir, "build.log" ); -assert file.isFile(); +File file = new File( basedir, "build.log" ) +assert file.isFile() File file1 = new File( basedir, "resources1/resource1.txt" ) assert file1.isFile() diff --git a/src/it/projects/mdep-599-analyze-java9/pom.xml b/src/it/projects/mdep-599-analyze-java9/pom.xml index be1f345d2..cc5103af1 100644 --- a/src/it/projects/mdep-599-analyze-java9/pom.xml +++ b/src/it/projects/mdep-599-analyze-java9/pom.xml @@ -37,7 +37,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.7.0 + @version.maven-compiler-plugin@ diff --git a/src/it/projects/mdep-602-log-on-error-level-when-failOnWarning/pom.xml b/src/it/projects/mdep-602-log-on-error-level-when-failOnWarning/pom.xml index 16eae6740..36f8bc84f 100644 --- a/src/it/projects/mdep-602-log-on-error-level-when-failOnWarning/pom.xml +++ b/src/it/projects/mdep-602-log-on-error-level-when-failOnWarning/pom.xml @@ -45,6 +45,7 @@ under the License. maven-dependency-plugin + @project.version@ true diff --git a/src/it/projects/mdep-602-log-on-error-level-when-failOnWarning/verify.groovy b/src/it/projects/mdep-602-log-on-error-level-when-failOnWarning/verify.groovy index e3ff35309..3959742e1 100644 --- a/src/it/projects/mdep-602-log-on-error-level-when-failOnWarning/verify.groovy +++ b/src/it/projects/mdep-602-log-on-error-level-when-failOnWarning/verify.groovy @@ -17,11 +17,11 @@ * under the License. */ -File file = new File( basedir, "build.log" ); -assert file.exists(); +File file = new File( basedir, "build.log" ) +assert file.exists() -String buildLog = file.getText( "UTF-8" ); -assert buildLog.contains( '[ERROR] Unused declared dependencies found:'); -assert buildLog.contains( '[ERROR] org.apache.maven:maven-project:jar:2.0.6:compile' ); +String buildLog = file.getText( "UTF-8" ) +assert buildLog.contains( '[ERROR] Unused declared dependencies found:') +assert buildLog.contains( '[ERROR] org.apache.maven:maven-project:jar:2.0.6:compile' ) -return true; +return true diff --git a/src/it/projects/mdep-663_analyze_unsupported_version/pom.xml b/src/it/projects/mdep-663_analyze_unsupported_version/pom.xml index bc6002aa9..58ed74d9e 100644 --- a/src/it/projects/mdep-663_analyze_unsupported_version/pom.xml +++ b/src/it/projects/mdep-663_analyze_unsupported_version/pom.xml @@ -28,7 +28,6 @@ UTF-8 - @@ -37,7 +36,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.7.0 + @version.maven-compiler-plugin@ ${java.specification.version} diff --git a/src/it/projects/mdep-689-apply-filtering-go-offline-goal/invoker.properties b/src/it/projects/mdep-689-apply-filtering-go-offline-goal/invoker.properties new file mode 100644 index 000000000..4623ccd63 --- /dev/null +++ b/src/it/projects/mdep-689-apply-filtering-go-offline-goal/invoker.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +invoker.goals = clean ${project.groupId}:${project.artifactId}:${project.version}:go-offline diff --git a/src/it/projects/mdep-689-apply-filtering-go-offline-goal/pom.xml b/src/it/projects/mdep-689-apply-filtering-go-offline-goal/pom.xml new file mode 100644 index 000000000..0fee5f399 --- /dev/null +++ b/src/it/projects/mdep-689-apply-filtering-go-offline-goal/pom.xml @@ -0,0 +1,109 @@ + + + + + + 4.0.0 + org.apache.maven.plugins.dependency + mdep-739-go-offline-respect-classifiers + 1.0.0-SNAPSHOT + Test that dependency:go-offline applies exclude filters + + + skip.this.groupid + dummy-artifact + 1.0 + + + skip.this.groupid.too + dummy-artifact + 1.0 + + + org.junit.jupiter + skip-this-artifact + 1.0 + + + org.junit.jupiter + skip-this-artifact-too + 1.0-SNAPSHOT + + + ch.qos.logback + logback-access + 1.4.7 + skipThisClassifier + + + ch.qos.logback + logback-core + 1.5.6 + skipThisClassifierToo + + + org.slf4j + slf4j-api + 2.0.13 + compile + + + ch.qos.logback + logback-classic + 1.5.4 + system + + ${project.build.directory}/local-repo/junit/junit/4.13.2/junit-4.13.2.jar + + + org.slf4j + slf4j-simple + 2.0.13 + + + ch.qos.logback + logback-examples + 1.4.7 + ear + + + + + + + maven-dependency-plugin + @project.version@ + + skip.this.groupid,skip.this.groupid.too + skip-this-artifact,skip-this-artifact-too + + + system + ear + skipThisClassifier,skipThisClassifierToo + + + + + + diff --git a/src/it/projects/mdep-689-apply-filtering-go-offline-goal/verify.groovy b/src/it/projects/mdep-689-apply-filtering-go-offline-goal/verify.groovy new file mode 100644 index 000000000..1bc9464f7 --- /dev/null +++ b/src/it/projects/mdep-689-apply-filtering-go-offline-goal/verify.groovy @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +File file = new File( basedir, "build.log" ) +assert file.exists() + +String buildLog = file.getText( "UTF-8" ) + +// Make sure non-exluded explicit dependencies are resolved +assert buildLog.contains( 'Resolved dependency: slf4j-simple-2.0.13.jar' ) +assert buildLog.contains( 'Resolved dependency: slf4j-api-2.0.13.jar' ) + +// Did group excludes work? +assert !buildLog.contains( 'Resolving artifact skip.this.groupid' ) + +// Did artifact excludes work? +assert !buildLog.contains( 'Resolving artifact org.junit.jupiter:skip-this-artifact' ) + +// Did scope exludes work? +assert !buildLog.contains( 'Resolving artifact ch.qos.logback:logback-classic' ) + +// Did type excludes work? +assert !buildLog.contains( 'Resolving artifact ch.qos.logback:logback-examples' ) + +// Did classifier excludes work? +assert !buildLog.contains( 'Resolving artifact ch.qos.logback:logback-core:jar:skipThisClassifierToo' ) +assert !buildLog.contains( 'Resolving artifact ch.qos.logback:logback-core' ) + +assert !buildLog.contains( 'Resolving artifact ch.qos.logback:logback-access:jar:skipThisClassifier' ) +assert !buildLog.contains( 'Resolving artifact ch.qos.logback:logback-access' ) + + + +return true diff --git a/src/it/projects/mdep-714-analyze-ignore-unused-runtime/pom.xml b/src/it/projects/mdep-714-analyze-ignore-unused-runtime/pom.xml index 15afd8dc2..a1f76cccf 100644 --- a/src/it/projects/mdep-714-analyze-ignore-unused-runtime/pom.xml +++ b/src/it/projects/mdep-714-analyze-ignore-unused-runtime/pom.xml @@ -50,6 +50,7 @@ maven-dependency-plugin + @project.version@ true true diff --git a/src/it/projects/mdep-739-go-offline-respect-classifiers/verify.groovy b/src/it/projects/mdep-739-go-offline-respect-classifiers/verify.groovy index fcc7dc004..dded7be02 100644 --- a/src/it/projects/mdep-739-go-offline-respect-classifiers/verify.groovy +++ b/src/it/projects/mdep-739-go-offline-respect-classifiers/verify.groovy @@ -17,10 +17,10 @@ * under the License. */ -File file = new File( basedir, "build.log" ); -assert file.exists(); +File file = new File( basedir, "build.log" ) +assert file.exists() -String buildLog = file.getText( "UTF-8" ); -assert buildLog.contains( 'Resolved dependency: spring-cloud-stream-3.1.2-test-binder.jar' ); +String buildLog = file.getText( "UTF-8" ) +assert buildLog.contains( 'Resolved dependency: spring-cloud-stream-3.1.2-test-binder.jar' ) -return true; +return true diff --git a/src/it/projects/mdep-752-analyze-ignored-packaging-custom/pom.xml b/src/it/projects/mdep-752-analyze-ignored-packaging-custom/pom.xml index 8fa4df173..a07d01e71 100644 --- a/src/it/projects/mdep-752-analyze-ignored-packaging-custom/pom.xml +++ b/src/it/projects/mdep-752-analyze-ignored-packaging-custom/pom.xml @@ -46,6 +46,7 @@ maven-dependency-plugin + @project.version@ true diff --git a/src/it/projects/mdep-752-analyze-ignored-packaging-custom/verify.groovy b/src/it/projects/mdep-752-analyze-ignored-packaging-custom/verify.groovy index 392d161a7..cacac0aa5 100644 --- a/src/it/projects/mdep-752-analyze-ignored-packaging-custom/verify.groovy +++ b/src/it/projects/mdep-752-analyze-ignored-packaging-custom/verify.groovy @@ -17,14 +17,14 @@ * under the License. */ -File file = new File( basedir, "build.log" ); -assert file.exists(); +File file = new File( basedir, "build.log" ) +assert file.exists() -String buildLog = file.getText( "UTF-8" ); +String buildLog = file.getText( "UTF-8" ) // custom configuration for ignoredPackagings should be applied to Mojo -assert buildLog.contains( 'ignoredPackagings = [pom, ear, ejb]' ); -assert buildLog.contains( '[INFO] Skipping pom project' ); -assert buildLog.contains( '[INFO] Skipping ear project' ); -assert buildLog.contains( '[INFO] Skipping ejb project' ); +assert buildLog.contains( 'ignoredPackagings = [pom, ear, ejb]' ) +assert buildLog.contains( '[INFO] Skipping pom project' ) +assert buildLog.contains( '[INFO] Skipping ear project' ) +assert buildLog.contains( '[INFO] Skipping ejb project' ) -return true; +return true diff --git a/src/it/projects/mdep-752-analyze-ignored-packaging-defaults/verify.groovy b/src/it/projects/mdep-752-analyze-ignored-packaging-defaults/verify.groovy index 2de46b262..b585e5d67 100644 --- a/src/it/projects/mdep-752-analyze-ignored-packaging-defaults/verify.groovy +++ b/src/it/projects/mdep-752-analyze-ignored-packaging-defaults/verify.groovy @@ -17,11 +17,11 @@ * under the License. */ -File file = new File( basedir, "build.log" ); -assert file.exists(); +File file = new File( basedir, "build.log" ) +assert file.exists() -String buildLog = file.getText( "UTF-8" ); -assert buildLog.contains( '[INFO] Skipping pom project' ); -assert buildLog.contains( '[INFO] Skipping ear project' ); +String buildLog = file.getText( "UTF-8" ) +assert buildLog.contains( '[INFO] Skipping pom project' ) +assert buildLog.contains( '[INFO] Skipping ear project' ) -return true; +return true diff --git a/src/it/projects/mdep-779-analyze-only-verbose-shows-class-names/pom.xml b/src/it/projects/mdep-779-analyze-only-verbose-shows-class-names/pom.xml index 2a8e65209..690938fbd 100644 --- a/src/it/projects/mdep-779-analyze-only-verbose-shows-class-names/pom.xml +++ b/src/it/projects/mdep-779-analyze-only-verbose-shows-class-names/pom.xml @@ -33,9 +33,21 @@ - dom4j - dom4j - 1.6.1 + org.apache.maven.shared + maven-shared-utils + 3.4.2 + + + + maven-compiler-plugin + @version.maven-compiler-plugin@ + + 8 + 8 + + + + diff --git a/src/it/projects/mdep-779-analyze-only-verbose-shows-class-names/src/main/java/usedUndeclaredReference/Project.java b/src/it/projects/mdep-779-analyze-only-verbose-shows-class-names/src/main/java/usedUndeclaredReference/Project.java index 5432b4056..a9d3fe68e 100644 --- a/src/it/projects/mdep-779-analyze-only-verbose-shows-class-names/src/main/java/usedUndeclaredReference/Project.java +++ b/src/it/projects/mdep-779-analyze-only-verbose-shows-class-names/src/main/java/usedUndeclaredReference/Project.java @@ -21,5 +21,5 @@ public class Project { - public static final Class CLASS_REF = org.apache.xmlcommons.Version.class; + public static final Class CLASS_REF = org.apache.commons.io.IOUtils.class; } diff --git a/src/it/projects/mdep-779-analyze-only-verbose-shows-class-names/verify.bsh b/src/it/projects/mdep-779-analyze-only-verbose-shows-class-names/verify.bsh index 35957daaf..7632bd758 100644 --- a/src/it/projects/mdep-779-analyze-only-verbose-shows-class-names/verify.bsh +++ b/src/it/projects/mdep-779-analyze-only-verbose-shows-class-names/verify.bsh @@ -6,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 - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @@ -23,9 +23,11 @@ String log = FileUtils.fileRead( new File( basedir, "build.log" ) ); log = StringUtils.unifyLineSeparators(log, "\n"); -String expected = "[WARNING] Used undeclared dependencies found:\n" - + "[WARNING] xml-apis:xml-apis:jar:1.0.b2:compile\n" - + "[WARNING] class org.apache.xmlcommons.Version\n"; +String expected = "[WARNING] Used undeclared dependencies found:\n" + + "[WARNING] commons-io:commons-io:jar:2.11.0:compile\n" + + "[WARNING] class org.apache.commons.io.IOUtils\n" + + "[WARNING] Unused declared dependencies found:\n" + + "[WARNING] org.apache.maven.shared:maven-shared-utils:jar:3.4.2:compile"; if ( !log.contains(expected) ) { diff --git a/src/it/projects/mdep-839-list/invoker.properties b/src/it/projects/mdep-839-list/invoker.properties new file mode 100644 index 000000000..55afe77c1 --- /dev/null +++ b/src/it/projects/mdep-839-list/invoker.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +invoker.goals = ${project.groupId}:${project.artifactId}:${project.version}:list diff --git a/src/it/projects/mdep-839-list/pom.xml b/src/it/projects/mdep-839-list/pom.xml new file mode 100644 index 000000000..f6cd86069 --- /dev/null +++ b/src/it/projects/mdep-839-list/pom.xml @@ -0,0 +1,54 @@ + + + + + 4.0.0 + + org.apache.maven.its.dependency + test + 1.0-SNAPSHOT + + Test + + Test dependency:list-repositories + + + + UTF-8 + + + + + fake-remote-repository + http://localhost:2345 + + + + + + org.apache.maven + maven-core + 3.9.9 + + + + \ No newline at end of file diff --git a/src/it/projects/go-offline/test.properties b/src/it/projects/mdep-839-list/test.properties similarity index 96% rename from src/it/projects/go-offline/test.properties rename to src/it/projects/mdep-839-list/test.properties index 2a312e22e..406dd9aba 100644 --- a/src/it/projects/go-offline/test.properties +++ b/src/it/projects/mdep-839-list/test.properties @@ -15,4 +15,5 @@ # specific language governing permissions and limitations # under the License. -outputFile = target/tree.txt +outputFile = classpath.txt + diff --git a/src/it/projects/mdep-839-list/verify.groovy b/src/it/projects/mdep-839-list/verify.groovy new file mode 100644 index 000000000..50cd4ea0f --- /dev/null +++ b/src/it/projects/mdep-839-list/verify.groovy @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +File file = new File( basedir, "classpath.txt" ) +assert file.exists() : "output file $file does not exist" + +String output = file.getText( "UTF-8" ) +assert output.startsWith( 'The following files have been resolved:') +// no escape codes +assert !output.contains( '\u001B' ) + + diff --git a/src/it/projects/mdep-952-unpack-fails-if-extension-of-artifact-is-used/invoker.properties b/src/it/projects/mdep-952-unpack-fails-if-extension-of-artifact-is-used/invoker.properties new file mode 100644 index 000000000..df09c584b --- /dev/null +++ b/src/it/projects/mdep-952-unpack-fails-if-extension-of-artifact-is-used/invoker.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +invoker.goals = ${project.groupId}:${project.artifactId}:${project.version}:unpack -Dartifact=org.apache.commons:commons-lang3:3.17.0::jar -DoutputDirectory=. diff --git a/src/it/projects/mdep-952-unpack-fails-if-extension-of-artifact-is-used/pom.xml b/src/it/projects/mdep-952-unpack-fails-if-extension-of-artifact-is-used/pom.xml new file mode 100644 index 000000000..6c3ae6a1e --- /dev/null +++ b/src/it/projects/mdep-952-unpack-fails-if-extension-of-artifact-is-used/pom.xml @@ -0,0 +1,25 @@ + + + + 4.0.0 + com.mycompany.app + my-app + 1 + \ No newline at end of file diff --git a/src/it/projects/mdep-952-unpack-fails-if-extension-of-artifact-is-used/verify.groovy b/src/it/projects/mdep-952-unpack-fails-if-extension-of-artifact-is-used/verify.groovy new file mode 100644 index 000000000..e5eae39a5 --- /dev/null +++ b/src/it/projects/mdep-952-unpack-fails-if-extension-of-artifact-is-used/verify.groovy @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +File file = new File( basedir, "build.log" ) +assert file.exists() + +String buildLog = file.getText( "UTF-8" ) +assert buildLog.contains( 'BUILD SUCCESS' ) +assert !buildLog.contains( 'BUILD FAILURE' ) + +return true diff --git a/src/it/projects/purge-local-repository-bad-dep/invoker.properties b/src/it/projects/purge-local-repository-bad-dep/invoker.properties index 098745b51..6a64fc6e9 100644 --- a/src/it/projects/purge-local-repository-bad-dep/invoker.properties +++ b/src/it/projects/purge-local-repository-bad-dep/invoker.properties @@ -5,9 +5,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 -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @@ -16,5 +16,3 @@ # under the License. invoker.goals = ${project.groupId}:${project.artifactId}:${project.version}:purge-local-repository -# [MNG-5366] Does not work in Maven >= 3.0.4 due to the resolveAlways operation not correctly forcing a new download -invoker.maven.version = !3.0.4,!3.0.5,!3.1.0,!3.1.1,!3.2.1,!3.2.2,!3.2.3 diff --git a/src/it/projects/purge-local-repository-bad-dep/verify.groovy b/src/it/projects/purge-local-repository-bad-dep/verify.groovy index 0e7767633..65b44f164 100644 --- a/src/it/projects/purge-local-repository-bad-dep/verify.groovy +++ b/src/it/projects/purge-local-repository-bad-dep/verify.groovy @@ -19,19 +19,19 @@ void checkFilePresence( String path ) { - File depJar = new File( localRepositoryPath, path ); + File depJar = new File( localRepositoryPath, path ) if ( !depJar.exists() ) { - throw new Exception( "Direct dependency jar was not re-resolved: " + depJar ); + throw new Exception( "Direct dependency jar was not re-resolved: " + depJar ) } } -checkFilePresence( "org/apache/maven/its/dependency/purge-local-repository/1.0/purge-local-repository-1.0.jar" ); -checkFilePresence( "org/apache/maven/its/dependency/purge-local-repository/1.0/purge-local-repository-1.0.pom" ); +checkFilePresence( "org/apache/maven/its/dependency/purge-local-repository/1.0/purge-local-repository-1.0.jar" ) +checkFilePresence( "org/apache/maven/its/dependency/purge-local-repository/1.0/purge-local-repository-1.0.pom" ) -String buildLog = new File( basedir, "build.log" ).getText( "UTF-8" ); -assert buildLog.contains( 'Unable to resolve artifact: org.apache.maven.its.dependency:i-do-not-exist:jar:1.0' ); -assert buildLog.contains( 'Purging artifact: org.apache.maven.its.dependency:purge-local-repository:jar:1.0' ); -assert buildLog.contains( 'Resolving artifact: org.apache.maven.its.dependency:purge-local-repository:jar:1.0' ); +String buildLog = new File( basedir, "build.log" ).getText( "UTF-8" ) +assert buildLog.contains( 'Unable to resolve artifact: org.apache.maven.its.dependency:i-do-not-exist:jar:1.0' ) +assert buildLog.contains( 'Purging artifact: org.apache.maven.its.dependency:purge-local-repository:jar:1.0' ) +assert buildLog.contains( 'Resolving artifact: org.apache.maven.its.dependency:purge-local-repository:jar:1.0' ) -return true; +return true diff --git a/src/it/projects/purge-local-repository-bad-pom/invoker.properties b/src/it/projects/purge-local-repository-bad-pom/invoker.properties index 9ea542aa9..6a64fc6e9 100644 --- a/src/it/projects/purge-local-repository-bad-pom/invoker.properties +++ b/src/it/projects/purge-local-repository-bad-pom/invoker.properties @@ -5,9 +5,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 -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @@ -16,5 +16,3 @@ # under the License. invoker.goals = ${project.groupId}:${project.artifactId}:${project.version}:purge-local-repository -# [MNG-5366] Only works works with Maven 3.0.x except for 3.0.4 -invoker.maven.version = 3.0.0+, !3.0.4 diff --git a/src/it/projects/purge-local-repository-bad-pom/verify.bsh b/src/it/projects/purge-local-repository-bad-pom/verify.bsh index 45b5cc9a6..0ecebd67a 100644 --- a/src/it/projects/purge-local-repository-bad-pom/verify.bsh +++ b/src/it/projects/purge-local-repository-bad-pom/verify.bsh @@ -19,8 +19,6 @@ import java.io.*; -System.out.println( "Checking for presence of purged dependency directories" ); - File depJar = new File( localRepositoryPath, "org/apache/maven/its/dependency/purge-local-repository/1.0/purge-local-repository-1.0.jar" ); if ( !depJar.exists() ) diff --git a/src/it/projects/purge-local-repository-include/invoker.properties b/src/it/projects/purge-local-repository-include/invoker.properties index 5feb77ebd..8f449f312 100644 --- a/src/it/projects/purge-local-repository-include/invoker.properties +++ b/src/it/projects/purge-local-repository-include/invoker.properties @@ -5,9 +5,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 -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @@ -16,4 +16,3 @@ # under the License. invoker.goals = ${project.groupId}:${project.artifactId}:${project.version}:resolve ${project.groupId}:${project.artifactId}:${project.version}:purge-local-repository -invoker.maven.version = 3.1.0+ \ No newline at end of file diff --git a/src/it/projects/purge-local-repository-include/verify.groovy b/src/it/projects/purge-local-repository-include/verify.groovy index 41104d735..baabe8f71 100644 --- a/src/it/projects/purge-local-repository-include/verify.groovy +++ b/src/it/projects/purge-local-repository-include/verify.groovy @@ -19,30 +19,30 @@ void checkFilePresence( String path ) { - File depJar = new File( localRepositoryPath, path ); + File depJar = new File( localRepositoryPath, path ) if ( !depJar.exists() ) { - throw new Exception( "Dependency jar was not re-resolved: " + depJar ); + throw new Exception( "Dependency jar was not re-resolved: " + depJar ) } } void checkFileAbsence( String path ) { - File depJar = new File( localRepositoryPath, path ); + File depJar = new File( localRepositoryPath, path ) if ( depJar.exists() ) { - throw new Exception( "Dependency jar was not purged: " + depJar ); + throw new Exception( "Dependency jar was not purged: " + depJar ) } } -checkFilePresence( "org/apache/maven/its/dependency/purge-local-repository/1.0/purge-local-repository-1.0.jar" ); -checkFilePresence( "org/apache/maven/its/dependency/purge-local-repository/1.0/purge-local-repository-1.0.pom" ); +checkFilePresence( "org/apache/maven/its/dependency/purge-local-repository/1.0/purge-local-repository-1.0.jar" ) +checkFilePresence( "org/apache/maven/its/dependency/purge-local-repository/1.0/purge-local-repository-1.0.pom" ) -checkFileAbsence( "org/apache/maven/its/dependency/purge-local-repository-2/1.0/purge-local-repository-2-1.0.jar" ); -checkFileAbsence( "org/apache/maven/its/dependency/purge-local-repository-2/1.0/purge-local-repository-2-1.0.pom" ); +checkFileAbsence( "org/apache/maven/its/dependency/purge-local-repository-2/1.0/purge-local-repository-2-1.0.jar" ) +checkFileAbsence( "org/apache/maven/its/dependency/purge-local-repository-2/1.0/purge-local-repository-2-1.0.pom" ) -String buildLog = new File( basedir, "build.log" ).getText( "UTF-8" ); -assert !buildLog.contains( 'Purging artifact: org.apache.maven.its.dependency:purge-local-repository:jar:1.0' ); -assert buildLog.contains( 'Purging artifact: org.apache.maven.its.dependency:purge-local-repository-2:jar:1.0' ); +String buildLog = new File( basedir, "build.log" ).getText( "UTF-8" ) +assert !buildLog.contains( 'Purging artifact: org.apache.maven.its.dependency:purge-local-repository:jar:1.0' ) +assert buildLog.contains( 'Purging artifact: org.apache.maven.its.dependency:purge-local-repository-2:jar:1.0' ) -return true; +return true diff --git a/src/it/projects/purge-local-repository-multi-module-execution/setup.bsh b/src/it/projects/purge-local-repository-multi-module-execution/setup.bsh index 27051f6c3..f55d12dd2 100644 --- a/src/it/projects/purge-local-repository-multi-module-execution/setup.bsh +++ b/src/it/projects/purge-local-repository-multi-module-execution/setup.bsh @@ -25,8 +25,6 @@ void createJar( String artifactId ) purgedJar.getParentFile().mkdirs(); purgedJar.createNewFile(); - - System.out.println( "Created dummy JAR " + purgedJar ); } createJar( "purged-a" ); diff --git a/src/it/projects/purge-local-repository-multi-module-execution/verify.bsh b/src/it/projects/purge-local-repository-multi-module-execution/verify.bsh index fde1a2bf7..c5f00b8a1 100644 --- a/src/it/projects/purge-local-repository-multi-module-execution/verify.bsh +++ b/src/it/projects/purge-local-repository-multi-module-execution/verify.bsh @@ -22,9 +22,7 @@ import java.io.File; void checkFilePurged( String artifactId ) { File purgedJar = new File( localRepositoryPath, "org/apache/maven/its/dependency/" + artifactId + "/1.0/" + artifactId + "-1.0.jar" ); - - System.out.println( "Checking for absence of dummy JAR " + purgedJar ); - + if ( purgedJar.exists() ) { throw new Exception( "JAR was not purged: " + purgedJar ); diff --git a/src/it/projects/purge-local-repository-multi-module/setup.bsh b/src/it/projects/purge-local-repository-multi-module/setup.bsh index 27051f6c3..f55d12dd2 100644 --- a/src/it/projects/purge-local-repository-multi-module/setup.bsh +++ b/src/it/projects/purge-local-repository-multi-module/setup.bsh @@ -25,8 +25,6 @@ void createJar( String artifactId ) purgedJar.getParentFile().mkdirs(); purgedJar.createNewFile(); - - System.out.println( "Created dummy JAR " + purgedJar ); } createJar( "purged-a" ); diff --git a/src/it/projects/purge-local-repository-multi-module/verify.groovy b/src/it/projects/purge-local-repository-multi-module/verify.groovy index 81fd494cd..03177852f 100644 --- a/src/it/projects/purge-local-repository-multi-module/verify.groovy +++ b/src/it/projects/purge-local-repository-multi-module/verify.groovy @@ -19,17 +19,17 @@ void checkFileAbsence( String path ) { - File depJar = new File( localRepositoryPath, path ); + File depJar = new File( localRepositoryPath, path ) if ( depJar.exists() ) { - throw new Exception( "Dependency jar was not purged: " + depJar ); + throw new Exception( "Dependency jar was not purged: " + depJar ) } } -checkFileAbsence("purged-a" ); -checkFileAbsence("purged-b" ); +checkFileAbsence("purged-a" ) +checkFileAbsence("purged-b" ) -String buildLog = new File( basedir, "build.log" ).getText( "UTF-8" ); -assert buildLog.contains( 'Deleting 1 transitive dependency for project child1 from ' ); -assert buildLog.contains( 'Deleting 1 transitive dependency for project child2 from ' ); -assert buildLog.contains( 'with artifact version resolution fuzziness' ); +String buildLog = new File( basedir, "build.log" ).getText( "UTF-8" ) +assert buildLog.contains( 'Deleting 1 transitive dependency for project child1 from ' ) +assert buildLog.contains( 'Deleting 1 transitive dependency for project child2 from ' ) +assert buildLog.contains( 'with artifact version resolution fuzziness' ) diff --git a/src/it/projects/purge-local-repository-non-transitive/verify.bsh b/src/it/projects/purge-local-repository-non-transitive/verify.bsh index e913c82ad..2766ec78a 100644 --- a/src/it/projects/purge-local-repository-non-transitive/verify.bsh +++ b/src/it/projects/purge-local-repository-non-transitive/verify.bsh @@ -21,8 +21,6 @@ import java.io.*; File depDir = new File( localRepositoryPath, "org/apache/maven/its/dependency/purge-local-repository/1.0" ); -System.out.println( "Checking for absence of purged dependency directory " + depDir ); - if ( depDir.exists() ) { throw new Exception( "Directory was not deleted: " + depDir ); diff --git a/src/it/projects/purge-local-repository-reresolve/invoker.properties b/src/it/projects/purge-local-repository-reresolve/invoker.properties index 69ba6bff1..8f449f312 100644 --- a/src/it/projects/purge-local-repository-reresolve/invoker.properties +++ b/src/it/projects/purge-local-repository-reresolve/invoker.properties @@ -5,9 +5,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 -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @@ -16,5 +16,3 @@ # under the License. invoker.goals = ${project.groupId}:${project.artifactId}:${project.version}:resolve ${project.groupId}:${project.artifactId}:${project.version}:purge-local-repository -# [MNG-5366] Does not work in Maven >= 3.0.4 due to the resolveAlways operation not correctly forcing a new download -invoker.maven.version = !3.0.4,!3.0.5,!3.1.0,!3.1.1,!3.2.1,!3.2.2,!3.2.3 diff --git a/src/it/projects/purge-local-repository-reresolve/verify.bsh b/src/it/projects/purge-local-repository-reresolve/verify.bsh index 45b5cc9a6..0ecebd67a 100644 --- a/src/it/projects/purge-local-repository-reresolve/verify.bsh +++ b/src/it/projects/purge-local-repository-reresolve/verify.bsh @@ -19,8 +19,6 @@ import java.io.*; -System.out.println( "Checking for presence of purged dependency directories" ); - File depJar = new File( localRepositoryPath, "org/apache/maven/its/dependency/purge-local-repository/1.0/purge-local-repository-1.0.jar" ); if ( !depJar.exists() ) diff --git a/src/it/projects/purge-local-repository-snapshots-only/setup.bsh b/src/it/projects/purge-local-repository-snapshots-only/setup.bsh index 00eacb5dc..4552c8f9e 100644 --- a/src/it/projects/purge-local-repository-snapshots-only/setup.bsh +++ b/src/it/projects/purge-local-repository-snapshots-only/setup.bsh @@ -24,14 +24,9 @@ File purgedJar = new File( localRepositoryPath, "org/apache/maven/its/dependency purgedJar.getParentFile().mkdirs(); purgedJar.createNewFile(); -System.out.println( "Created dummy JAR " + purgedJar ); - purgedJar = new File( localRepositoryPath, "org/apache/maven/its/dependency/snap-purged/1.0-SNAPSHOT/snap-purged-1.0-SNAPSHOT.jar" ); purgedJar.getParentFile().mkdirs(); purgedJar.createNewFile(); -System.out.println( "Created dummy JAR " + purgedJar ); - - return true; diff --git a/src/it/projects/purge-local-repository-snapshots-only/verify.bsh b/src/it/projects/purge-local-repository-snapshots-only/verify.bsh index 60d0c7f6e..fad0644da 100644 --- a/src/it/projects/purge-local-repository-snapshots-only/verify.bsh +++ b/src/it/projects/purge-local-repository-snapshots-only/verify.bsh @@ -21,8 +21,6 @@ import java.io.*; File nonPurgedJar = new File( localRepositoryPath, "org/apache/maven/its/dependency/purged/1.0/purged-1.0.jar" ); -System.out.println( "Checking for presence of dummy JAR " + nonPurgedJar ); - if ( !nonPurgedJar.exists() ) { throw new Exception( "JAR was purged: " + nonPurgedJar ); @@ -31,8 +29,6 @@ if ( !nonPurgedJar.exists() ) File purgedJar = new File( localRepositoryPath, "org/apache/maven/its/dependency/snap-purged/1.0-SNAPSHOT/snap-purged-1.0-SNAPSHOT.jar" ); -System.out.println( "Checking for absence of dummy JAR " + purgedJar ); - if ( purgedJar.exists() ) { throw new Exception( "JAR was not purged: " + purgedJar ); diff --git a/src/it/projects/purge-local-repository-version-range/invoker.properties b/src/it/projects/purge-local-repository-version-range/invoker.properties index 098745b51..6a64fc6e9 100644 --- a/src/it/projects/purge-local-repository-version-range/invoker.properties +++ b/src/it/projects/purge-local-repository-version-range/invoker.properties @@ -5,9 +5,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 -# +# # http://www.apache.org/licenses/LICENSE-2.0 -# +# # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @@ -16,5 +16,3 @@ # under the License. invoker.goals = ${project.groupId}:${project.artifactId}:${project.version}:purge-local-repository -# [MNG-5366] Does not work in Maven >= 3.0.4 due to the resolveAlways operation not correctly forcing a new download -invoker.maven.version = !3.0.4,!3.0.5,!3.1.0,!3.1.1,!3.2.1,!3.2.2,!3.2.3 diff --git a/src/it/projects/purge-local-repository-version-range/verify.bsh b/src/it/projects/purge-local-repository-version-range/verify.bsh index 45b5cc9a6..0ecebd67a 100644 --- a/src/it/projects/purge-local-repository-version-range/verify.bsh +++ b/src/it/projects/purge-local-repository-version-range/verify.bsh @@ -19,8 +19,6 @@ import java.io.*; -System.out.println( "Checking for presence of purged dependency directories" ); - File depJar = new File( localRepositoryPath, "org/apache/maven/its/dependency/purge-local-repository/1.0/purge-local-repository-1.0.jar" ); if ( !depJar.exists() ) diff --git a/src/it/projects/purge-local-repository-without-pom/setup.bsh b/src/it/projects/purge-local-repository-without-pom/setup.bsh index 026446997..dba9cfb39 100644 --- a/src/it/projects/purge-local-repository-without-pom/setup.bsh +++ b/src/it/projects/purge-local-repository-without-pom/setup.bsh @@ -24,6 +24,4 @@ File purgedJar = new File( localRepositoryPath, "org/apache/maven/its/dependency purgedJar.getParentFile().mkdirs(); purgedJar.createNewFile(); -System.out.println( "Created dummy JAR " + purgedJar ); - return true; diff --git a/src/it/projects/purge-local-repository-without-pom/verify.groovy b/src/it/projects/purge-local-repository-without-pom/verify.groovy index 409e6bcaa..4d0df7374 100644 --- a/src/it/projects/purge-local-repository-without-pom/verify.groovy +++ b/src/it/projects/purge-local-repository-without-pom/verify.groovy @@ -19,14 +19,14 @@ void checkFileAbsence( String path ) { - File depJar = new File( localRepositoryPath, path ); + File depJar = new File( localRepositoryPath, path ) if ( depJar.exists() ) { - throw new Exception( "Dependency jar was not purged: " + depJar ); + throw new Exception( "Dependency jar was not purged: " + depJar ) } } -checkFileAbsence( "org/apache/maven/its/dependency/purged-without-pom/1.0/purged-without-pom-1.0.jar" ); +checkFileAbsence( "org/apache/maven/its/dependency/purged-without-pom/1.0/purged-without-pom-1.0.jar" ) -String buildLog = new File( basedir, "build.log" ).getText( "UTF-8" ); -assert buildLog.contains( 'Deleting 1 manual dependency from ' ); +String buildLog = new File( basedir, "build.log" ).getText( "UTF-8" ) +assert buildLog.contains( 'Deleting 1 manual dependency from ' ) diff --git a/src/it/projects/purge-local-repository/setup.bsh b/src/it/projects/purge-local-repository/setup.bsh index cfb579166..92b835d1a 100644 --- a/src/it/projects/purge-local-repository/setup.bsh +++ b/src/it/projects/purge-local-repository/setup.bsh @@ -24,6 +24,4 @@ File purgedJar = new File( localRepositoryPath, "org/apache/maven/its/dependency purgedJar.getParentFile().mkdirs(); purgedJar.createNewFile(); -System.out.println( "Created dummy JAR " + purgedJar ); - return true; diff --git a/src/it/projects/purge-local-repository/verify.groovy b/src/it/projects/purge-local-repository/verify.groovy index ffb1734c3..7c97d11a0 100644 --- a/src/it/projects/purge-local-repository/verify.groovy +++ b/src/it/projects/purge-local-repository/verify.groovy @@ -19,16 +19,15 @@ void checkFileAbsence( String path ) { - File depJar = new File( localRepositoryPath, path ); - System.out.println( "Checking for absence of dummy JAR " + depJar ); + File depJar = new File( localRepositoryPath, path ) if ( depJar.exists() ) { - throw new Exception( "Dependency jar was not purged: " + depJar ); + throw new Exception( "Dependency jar was not purged: " + depJar ) } } -checkFileAbsence( "org/apache/maven/its/dependency/purged/1.0/purged-1.0.jar" ); +checkFileAbsence( "org/apache/maven/its/dependency/purged/1.0/purged-1.0.jar" ) -String buildLog = new File( basedir, "build.log" ).getText( "UTF-8" ); -assert buildLog.contains( 'Deleting 1 transitive dependency for project test from ' ); -assert buildLog.contains( 'with artifact version resolution fuzziness' ); +String buildLog = new File( basedir, "build.log" ).getText( "UTF-8" ) +assert buildLog.contains( 'Deleting 1 transitive dependency for project test from ' ) +assert buildLog.contains( 'with artifact version resolution fuzziness' ) diff --git a/src/it/projects/resolve-plugins-exclude-reactor/child-b/pom.xml b/src/it/projects/resolve-plugins-exclude-reactor/child-b/pom.xml index 891439ab5..6ef74e860 100644 --- a/src/it/projects/resolve-plugins-exclude-reactor/child-b/pom.xml +++ b/src/it/projects/resolve-plugins-exclude-reactor/child-b/pom.xml @@ -52,6 +52,7 @@ maven-dependency-plugin + @project.version@ test diff --git a/src/it/projects/resolve-plugins-exclude-reactor/verify.groovy b/src/it/projects/resolve-plugins-exclude-reactor/verify.groovy index 4f7718f6d..540c60d58 100644 --- a/src/it/projects/resolve-plugins-exclude-reactor/verify.groovy +++ b/src/it/projects/resolve-plugins-exclude-reactor/verify.groovy @@ -23,4 +23,4 @@ new File(basedir, "target/resolved.txt").eachLine { line -> } } -return true; +return true diff --git a/src/it/projects/resolve-plugins-with-exclude/verify.groovy b/src/it/projects/resolve-plugins-with-exclude/verify.groovy index 90471f0f8..9b669b097 100644 --- a/src/it/projects/resolve-plugins-with-exclude/verify.groovy +++ b/src/it/projects/resolve-plugins-with-exclude/verify.groovy @@ -26,4 +26,4 @@ new File(basedir, "target/resolved.txt").eachLine { line -> } } -return true; +return true diff --git a/src/it/projects/resolve-plugins/pom.xml b/src/it/projects/resolve-plugins/pom.xml index 5a20fa27b..c0df89152 100644 --- a/src/it/projects/resolve-plugins/pom.xml +++ b/src/it/projects/resolve-plugins/pom.xml @@ -36,4 +36,55 @@ UTF-8 + + + + + org.apache.maven.plugins + maven-assembly-plugin + 3.7.1 + + + org.apache.maven.plugins + maven-surefire-plugin + 3.5.4 + + + org.apache.maven.plugins + maven-project-info-reports-plugin + + + org.apache.commons + commons-lang3 + 3.18.0 + + + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + 3.5.4 + + + org.apache.maven.plugins + maven-assembly-plugin + + + + + + + org.apache.maven.plugins + maven-project-info-reports-plugin + + + org.apache.maven.plugins + maven-surefire-report-plugin + + + + diff --git a/src/it/projects/resolve-sources/invoker.properties b/src/it/projects/resolve-sources/invoker.properties new file mode 100644 index 000000000..55dfe7a20 --- /dev/null +++ b/src/it/projects/resolve-sources/invoker.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +invoker.goals = ${project.groupId}:${project.artifactId}:${project.version}:resolve-sources diff --git a/src/it/projects/sources/pom.xml b/src/it/projects/resolve-sources/pom.xml similarity index 97% rename from src/it/projects/sources/pom.xml rename to src/it/projects/resolve-sources/pom.xml index f04fc4d88..1f3f64828 100644 --- a/src/it/projects/sources/pom.xml +++ b/src/it/projects/resolve-sources/pom.xml @@ -29,7 +29,7 @@ Test - Test dependency:sources + Test dependency:resolve-sources diff --git a/src/it/projects/resolve-sources/test.properties b/src/it/projects/resolve-sources/test.properties new file mode 100644 index 000000000..d6b4c923d --- /dev/null +++ b/src/it/projects/resolve-sources/test.properties @@ -0,0 +1,20 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +outputFile = target/resolved.txt +# This is intentional to prove that no classifier is passed (read-only value) +classifier = foo diff --git a/src/it/projects/setup-custom-ear-lifecycle/plugin/pom.xml b/src/it/projects/setup-custom-ear-lifecycle/plugin/pom.xml index ca1f9b3af..011ebf42b 100644 --- a/src/it/projects/setup-custom-ear-lifecycle/plugin/pom.xml +++ b/src/it/projects/setup-custom-ear-lifecycle/plugin/pom.xml @@ -41,7 +41,7 @@ under the License. org.apache.maven.plugins maven-plugin-plugin - 3.7.0 + @version.maven-plugin-tools@ @@ -75,7 +75,7 @@ under the License. org.apache.maven.plugin-tools maven-plugin-annotations - 3.7.0 + @version.maven-plugin-tools@ provided diff --git a/src/it/projects/setup-custom-ear-lifecycle/pom.xml b/src/it/projects/setup-custom-ear-lifecycle/pom.xml index 32b004d6d..ad10f6b31 100644 --- a/src/it/projects/setup-custom-ear-lifecycle/pom.xml +++ b/src/it/projects/setup-custom-ear-lifecycle/pom.xml @@ -25,14 +25,14 @@ under the License. maven-custom-ear 1.0 pom - + org.apache.maven.plugins maven-compiler-plugin - 2.5.1 + @version.maven-compiler-plugin@ diff --git a/src/it/projects/tree-excluded/expected-v4.txt b/src/it/projects/tree-excluded/expected-v4.txt new file mode 100644 index 000000000..82cd95252 --- /dev/null +++ b/src/it/projects/tree-excluded/expected-v4.txt @@ -0,0 +1,13 @@ +org.apache.maven.its.dependency:test:jar:1.0-SNAPSHOT +\- org.apache.maven:maven-project:jar:2.0.6:compile + +- org.apache.maven:maven-settings:jar:2.0.6:compile + +- org.apache.maven:maven-profile:jar:2.0.6:compile + +- org.apache.maven:maven-model:jar:2.0.6:compile + +- org.apache.maven:maven-artifact-manager:jar:2.0.6:compile + | +- org.apache.maven:maven-repository-metadata:jar:2.0.6:compile + | \- org.apache.maven.wagon:wagon-provider-api:jar:1.0-beta-2:compile + +- org.apache.maven:maven-plugin-registry:jar:2.0.6:compile + +- org.apache.maven:maven-artifact:jar:2.0.6:compile + \- org.codehaus.plexus:plexus-container-default:jar:1.0-alpha-9-stable-1:compile + +- junit:junit:jar:3.8.1:compile + \- classworlds:classworlds:jar:1.1:compile diff --git a/src/it/projects/tree-excluded/expected.txt b/src/it/projects/tree-excluded/expected.txt new file mode 100644 index 000000000..38be1dd0d --- /dev/null +++ b/src/it/projects/tree-excluded/expected.txt @@ -0,0 +1,13 @@ +org.apache.maven.its.dependency:test:jar:1.0-SNAPSHOT +\- org.apache.maven:maven-project:jar:2.0.6:compile + +- org.apache.maven:maven-settings:jar:2.0.6:compile + +- org.apache.maven:maven-profile:jar:2.0.6:compile + +- org.apache.maven:maven-model:jar:2.0.6:compile + +- org.apache.maven:maven-artifact-manager:jar:2.0.6:compile + | +- org.apache.maven:maven-repository-metadata:jar:2.0.6:compile + | \- org.apache.maven.wagon:wagon-provider-api:jar:1.0-beta-2:compile + +- org.apache.maven:maven-plugin-registry:jar:2.0.6:compile + +- org.apache.maven:maven-artifact:jar:2.0.6:compile + \- org.codehaus.plexus:plexus-container-default:jar:1.0-alpha-9-stable-1:compile + +- junit:junit:jar:3.8.1:compile + \- classworlds:classworlds:jar:1.1-alpha-2:compile diff --git a/src/it/projects/tree-excluded/invoker.properties b/src/it/projects/tree-excluded/invoker.properties new file mode 100644 index 000000000..afb73d253 --- /dev/null +++ b/src/it/projects/tree-excluded/invoker.properties @@ -0,0 +1,18 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +invoker.goals = ${project.groupId}:${project.artifactId}:${project.version}:tree diff --git a/src/it/projects/tree-excluded/pom.xml b/src/it/projects/tree-excluded/pom.xml new file mode 100644 index 000000000..dac11a5b1 --- /dev/null +++ b/src/it/projects/tree-excluded/pom.xml @@ -0,0 +1,47 @@ + + + + + 4.0.0 + + org.apache.maven.its.dependency + test + 1.0-SNAPSHOT + + dependency:tree -Dexcludes + + Test dependency:tree -Dexcludes=... + + + + UTF-8 + + + + + org.apache.maven + maven-project + 2.0.6 + + + + diff --git a/src/it/projects/tree-excluded/test.properties b/src/it/projects/tree-excluded/test.properties new file mode 100644 index 000000000..42a01ce23 --- /dev/null +++ b/src/it/projects/tree-excluded/test.properties @@ -0,0 +1,19 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +outputFile = target/tree.txt +excludes = org.codehaus.plexus:* diff --git a/src/it/projects/tree-excluded/verify.groovy b/src/it/projects/tree-excluded/verify.groovy new file mode 100644 index 000000000..e9d8d8135 --- /dev/null +++ b/src/it/projects/tree-excluded/verify.groovy @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import static org.assertj.core.api.Assertions.assertThat + +// Maven 4 use transitive dependency manager +def expected = mavenVersion.startsWith('4.') ? "expected-v4.txt" : "expected.txt" + +assertThat(new File(basedir, "target/tree.txt")) + .hasSameTextualContentAs(new File(basedir, expected)) + +return true diff --git a/src/it/projects/tree-includes/verify.groovy b/src/it/projects/tree-includes/verify.groovy new file mode 100644 index 000000000..b79d25ba4 --- /dev/null +++ b/src/it/projects/tree-includes/verify.groovy @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import static org.assertj.core.api.Assertions.assertThat + +assertThat(new File(basedir, "target/tree.txt")) + .hasSameTextualContentAs(new File(basedir, "expected.txt")) + +return true diff --git a/src/it/projects/tree-multimodule/module-a/expected-v4.txt b/src/it/projects/tree-multimodule/module-a/expected-v4.txt new file mode 100644 index 000000000..2d7981077 --- /dev/null +++ b/src/it/projects/tree-multimodule/module-a/expected-v4.txt @@ -0,0 +1,14 @@ +org.apache.maven.its.dependency:tree-multimodule-module-a:jar:1.0-SNAPSHOT +\- org.apache.maven:maven-project:jar:2.0.6:compile + +- org.apache.maven:maven-settings:jar:2.0.6:compile + +- org.apache.maven:maven-profile:jar:2.0.6:compile + +- org.apache.maven:maven-model:jar:2.0.6:compile + +- org.apache.maven:maven-artifact-manager:jar:2.0.6:compile + | +- org.apache.maven:maven-repository-metadata:jar:2.0.6:compile + | \- org.apache.maven.wagon:wagon-provider-api:jar:1.0-beta-2:compile + +- org.apache.maven:maven-plugin-registry:jar:2.0.6:compile + +- org.codehaus.plexus:plexus-utils:jar:1.4.1:compile + +- org.apache.maven:maven-artifact:jar:2.0.6:compile + \- org.codehaus.plexus:plexus-container-default:jar:1.0-alpha-9-stable-1:compile + +- junit:junit:jar:3.8.1:compile + \- classworlds:classworlds:jar:1.1:compile diff --git a/src/it/projects/tree-multimodule/module-b/expected-v4.txt b/src/it/projects/tree-multimodule/module-b/expected-v4.txt new file mode 100644 index 000000000..00f930ed6 --- /dev/null +++ b/src/it/projects/tree-multimodule/module-b/expected-v4.txt @@ -0,0 +1,15 @@ +org.apache.maven.its.dependency:tree-multimodule-module-b:jar:1.0-SNAPSHOT +\- org.apache.maven.its.dependency:tree-multimodule-module-a:jar:1.0-SNAPSHOT:compile + \- org.apache.maven:maven-project:jar:2.0.6:compile + +- org.apache.maven:maven-settings:jar:2.0.6:compile + +- org.apache.maven:maven-profile:jar:2.0.6:compile + +- org.apache.maven:maven-model:jar:2.0.6:compile + +- org.apache.maven:maven-artifact-manager:jar:2.0.6:compile + | +- org.apache.maven:maven-repository-metadata:jar:2.0.6:compile + | \- org.apache.maven.wagon:wagon-provider-api:jar:1.0-beta-2:compile + +- org.apache.maven:maven-plugin-registry:jar:2.0.6:compile + +- org.codehaus.plexus:plexus-utils:jar:1.4.1:compile + +- org.apache.maven:maven-artifact:jar:2.0.6:compile + \- org.codehaus.plexus:plexus-container-default:jar:1.0-alpha-9-stable-1:compile + +- junit:junit:jar:3.8.1:compile + \- classworlds:classworlds:jar:1.1:compile diff --git a/src/it/projects/tree-multimodule/verify.bsh b/src/it/projects/tree-multimodule/verify.bsh deleted file mode 100644 index a4fce7eda..000000000 --- a/src/it/projects/tree-multimodule/verify.bsh +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import java.io.*; - -import org.codehaus.plexus.util.*; - -String actual = FileUtils.fileRead( new File( basedir, "target/tree.txt" ) ); -String expected = FileUtils.fileRead( new File( basedir, "expected.txt" ) ); - -actual = actual.replaceAll( "[\n\r]+", "\n" ); -expected = expected.replaceAll( "[\n\r]+", "\n" ); - -System.out.println( "Checking root dependency tree..." ); - -if ( !actual.equals( expected ) ) -{ - throw new Exception( "Unexpected root dependency tree" ); -} - -actual = FileUtils.fileRead( new File( basedir, "module-a/target/tree.txt" ) ); -expected = FileUtils.fileRead( new File( basedir, "module-a/expected.txt" ) ); - -actual = actual.replaceAll( "[\n\r]+", "\n" ); -expected = expected.replaceAll( "[\n\r]+", "\n" ); - -System.out.println( "Checking module-a dependency tree..." ); - -if ( !actual.equals( expected ) ) -{ - throw new Exception( "Unexpected module-a dependency tree" ); -} - -actual = FileUtils.fileRead( new File( basedir, "module-b/target/tree.txt" ) ); -expected = FileUtils.fileRead( new File( basedir, "module-b/expected.txt" ) ); - -actual = actual.replaceAll( "[\n\r]+", "\n" ); -expected = expected.replaceAll( "[\n\r]+", "\n" ); - -System.out.println( "Checking module-b dependency tree..." ); - -if ( !actual.equals( expected ) ) -{ - throw new Exception( "Unexpected module-b dependency tree" ); -} - -return true; diff --git a/src/it/projects/tree-verbose/verify.bsh b/src/it/projects/tree-multimodule/verify.groovy similarity index 59% rename from src/it/projects/tree-verbose/verify.bsh rename to src/it/projects/tree-multimodule/verify.groovy index 26391a483..03cfc779e 100644 --- a/src/it/projects/tree-verbose/verify.bsh +++ b/src/it/projects/tree-multimodule/verify.groovy @@ -17,20 +17,18 @@ * under the License. */ -import java.io.*; +import static org.assertj.core.api.Assertions.assertThat -import org.codehaus.plexus.util.*; +// Maven 4 use transitive dependency manager +def expected = mavenVersion.startsWith('4.') ? "expected-v4.txt" : "expected.txt" -String actual = FileUtils.fileRead( new File( basedir, "target/tree.txt" ) ); -String expected = FileUtils.fileRead( new File( basedir, "expected.txt" ) ); +assertThat(new File(basedir, "target/tree.txt")) + .hasSameTextualContentAs(new File(basedir, "expected.txt")) -actual = actual.replaceAll( "[\n\r]+", "\n" ); -expected = expected.replaceAll( "[\n\r]+", "\n" ); +assertThat(new File(basedir, "module-a/target/tree.txt")) + .hasSameTextualContentAs(new File(basedir, "module-a/" + expected)) -if ( !actual.equals( expected ) ) -{ - throw new Exception( "Unexpected dependency tree." + System.lineSeparator() + "Expected:" + System.lineSeparator() - + expected + System.lineSeparator() + "Actual:" + System.lineSeparator() + actual ); -} +assertThat(new File(basedir, "module-b/target/tree.txt")) + .hasSameTextualContentAs(new File(basedir, "module-b/" + expected)) return true; diff --git a/src/it/projects/tree-scope/expected1-v4.txt b/src/it/projects/tree-scope/expected1-v4.txt new file mode 100644 index 000000000..cbec48bd7 --- /dev/null +++ b/src/it/projects/tree-scope/expected1-v4.txt @@ -0,0 +1,37 @@ +org.apache.maven.its.dependency:test:jar:1.0-SNAPSHOT +\- org.apache.maven:maven-core:jar:3.6.3:compile + +- org.apache.maven:maven-model:jar:3.6.3:compile + +- org.apache.maven:maven-settings:jar:3.6.3:compile + +- org.apache.maven:maven-settings-builder:jar:3.6.3:compile + | +- org.codehaus.plexus:plexus-interpolation:jar:1.25:compile + | \- org.sonatype.plexus:plexus-sec-dispatcher:jar:1.4:compile + | \- org.sonatype.plexus:plexus-cipher:jar:1.7:compile + +- org.apache.maven:maven-builder-support:jar:3.6.3:compile + +- org.apache.maven:maven-repository-metadata:jar:3.6.3:compile + +- org.apache.maven:maven-artifact:jar:3.6.3:compile + +- org.apache.maven:maven-plugin-api:jar:3.6.3:compile + +- org.apache.maven:maven-model-builder:jar:3.6.3:compile + +- org.apache.maven:maven-resolver-provider:jar:3.6.3:compile + +- org.apache.maven.resolver:maven-resolver-impl:jar:1.4.1:compile + +- org.apache.maven.resolver:maven-resolver-api:jar:1.4.1:compile + +- org.apache.maven.resolver:maven-resolver-spi:jar:1.4.1:compile + +- org.apache.maven.resolver:maven-resolver-util:jar:1.4.1:compile + +- org.apache.maven.shared:maven-shared-utils:jar:3.2.1:compile + | \- commons-io:commons-io:jar:2.5:compile + +- org.eclipse.sisu:org.eclipse.sisu.plexus:jar:0.3.4:compile + | \- javax.enterprise:cdi-api:jar:1.0:compile + | \- javax.annotation:jsr250-api:jar:1.0:compile + +- org.eclipse.sisu:org.eclipse.sisu.inject:jar:0.3.4:compile + +- com.google.inject:guice:jar:no_aop:4.2.1:compile + | +- aopalliance:aopalliance:jar:1.0:compile + | \- com.google.guava:guava:jar:25.1-android:compile + | +- com.google.code.findbugs:jsr305:jar:3.0.1:compile + | +- org.checkerframework:checker-compat-qual:jar:2.0.0:compile + | +- com.google.errorprone:error_prone_annotations:jar:2.1.3:compile + | +- com.google.j2objc:j2objc-annotations:jar:1.1:compile + | \- org.codehaus.mojo:animal-sniffer-annotations:jar:1.14:compile + +- javax.inject:javax.inject:jar:1:compile + +- org.codehaus.plexus:plexus-utils:jar:3.2.1:compile + +- org.codehaus.plexus:plexus-classworlds:jar:2.6.0:compile + +- org.codehaus.plexus:plexus-component-annotations:jar:2.1.0:compile + \- org.apache.commons:commons-lang3:jar:3.8.1:compile diff --git a/src/it/projects/tree-scope/expected1.txt b/src/it/projects/tree-scope/expected1.txt new file mode 100644 index 000000000..a86117e10 --- /dev/null +++ b/src/it/projects/tree-scope/expected1.txt @@ -0,0 +1,37 @@ +org.apache.maven.its.dependency:test:jar:1.0-SNAPSHOT +\- org.apache.maven:maven-core:jar:3.6.3:compile + +- org.apache.maven:maven-model:jar:3.6.3:compile + +- org.apache.maven:maven-settings:jar:3.6.3:compile + +- org.apache.maven:maven-settings-builder:jar:3.6.3:compile + | +- org.codehaus.plexus:plexus-interpolation:jar:1.25:compile + | \- org.sonatype.plexus:plexus-sec-dispatcher:jar:1.4:compile + | \- org.sonatype.plexus:plexus-cipher:jar:1.4:compile + +- org.apache.maven:maven-builder-support:jar:3.6.3:compile + +- org.apache.maven:maven-repository-metadata:jar:3.6.3:compile + +- org.apache.maven:maven-artifact:jar:3.6.3:compile + +- org.apache.maven:maven-plugin-api:jar:3.6.3:compile + +- org.apache.maven:maven-model-builder:jar:3.6.3:compile + +- org.apache.maven:maven-resolver-provider:jar:3.6.3:compile + +- org.apache.maven.resolver:maven-resolver-impl:jar:1.4.1:compile + +- org.apache.maven.resolver:maven-resolver-api:jar:1.4.1:compile + +- org.apache.maven.resolver:maven-resolver-spi:jar:1.4.1:compile + +- org.apache.maven.resolver:maven-resolver-util:jar:1.4.1:compile + +- org.apache.maven.shared:maven-shared-utils:jar:3.2.1:compile + | \- commons-io:commons-io:jar:2.5:compile + +- org.eclipse.sisu:org.eclipse.sisu.plexus:jar:0.3.4:compile + | \- javax.enterprise:cdi-api:jar:1.0:compile + | \- javax.annotation:jsr250-api:jar:1.0:compile + +- org.eclipse.sisu:org.eclipse.sisu.inject:jar:0.3.4:compile + +- com.google.inject:guice:jar:no_aop:4.2.1:compile + | +- aopalliance:aopalliance:jar:1.0:compile + | \- com.google.guava:guava:jar:25.1-android:compile + | +- com.google.code.findbugs:jsr305:jar:3.0.2:compile + | +- org.checkerframework:checker-compat-qual:jar:2.0.0:compile + | +- com.google.errorprone:error_prone_annotations:jar:2.1.3:compile + | +- com.google.j2objc:j2objc-annotations:jar:1.1:compile + | \- org.codehaus.mojo:animal-sniffer-annotations:jar:1.14:compile + +- javax.inject:javax.inject:jar:1:compile + +- org.codehaus.plexus:plexus-utils:jar:3.2.1:compile + +- org.codehaus.plexus:plexus-classworlds:jar:2.6.0:compile + +- org.codehaus.plexus:plexus-component-annotations:jar:2.1.0:compile + \- org.apache.commons:commons-lang3:jar:3.8.1:compile diff --git a/src/it/projects/tree-scope/expected2-v4.txt b/src/it/projects/tree-scope/expected2-v4.txt new file mode 100644 index 000000000..1b7e59ae3 --- /dev/null +++ b/src/it/projects/tree-scope/expected2-v4.txt @@ -0,0 +1,39 @@ +org.apache.maven.its.dependency:test:jar:1.0-SNAPSHOT ++- org.apache.maven:maven-core:jar:3.6.3:compile +| +- org.apache.maven:maven-model:jar:3.6.3:compile +| +- org.apache.maven:maven-settings:jar:3.6.3:compile +| +- org.apache.maven:maven-settings-builder:jar:3.6.3:compile +| | +- org.codehaus.plexus:plexus-interpolation:jar:1.25:compile +| | \- org.sonatype.plexus:plexus-sec-dispatcher:jar:1.4:compile +| | \- org.sonatype.plexus:plexus-cipher:jar:1.7:compile +| +- org.apache.maven:maven-builder-support:jar:3.6.3:compile +| +- org.apache.maven:maven-repository-metadata:jar:3.6.3:compile +| +- org.apache.maven:maven-artifact:jar:3.6.3:compile +| +- org.apache.maven:maven-plugin-api:jar:3.6.3:compile +| +- org.apache.maven:maven-model-builder:jar:3.6.3:compile +| +- org.apache.maven:maven-resolver-provider:jar:3.6.3:compile +| +- org.apache.maven.resolver:maven-resolver-impl:jar:1.4.1:compile +| +- org.apache.maven.resolver:maven-resolver-api:jar:1.4.1:compile +| +- org.apache.maven.resolver:maven-resolver-spi:jar:1.4.1:compile +| +- org.apache.maven.resolver:maven-resolver-util:jar:1.4.1:compile +| +- org.apache.maven.shared:maven-shared-utils:jar:3.2.1:compile +| | \- commons-io:commons-io:jar:2.5:compile +| +- org.eclipse.sisu:org.eclipse.sisu.plexus:jar:0.3.4:compile +| | \- javax.enterprise:cdi-api:jar:1.0:compile +| | \- javax.annotation:jsr250-api:jar:1.0:compile +| +- org.eclipse.sisu:org.eclipse.sisu.inject:jar:0.3.4:compile +| +- com.google.inject:guice:jar:no_aop:4.2.1:compile +| | +- aopalliance:aopalliance:jar:1.0:compile +| | \- com.google.guava:guava:jar:25.1-android:compile +| | +- com.google.code.findbugs:jsr305:jar:3.0.1:compile +| | +- org.checkerframework:checker-compat-qual:jar:2.0.0:compile +| | +- com.google.errorprone:error_prone_annotations:jar:2.1.3:compile +| | +- com.google.j2objc:j2objc-annotations:jar:1.1:compile +| | \- org.codehaus.mojo:animal-sniffer-annotations:jar:1.14:compile +| +- javax.inject:javax.inject:jar:1:compile +| +- org.codehaus.plexus:plexus-utils:jar:3.2.1:compile +| +- org.codehaus.plexus:plexus-classworlds:jar:2.6.0:compile +| +- org.codehaus.plexus:plexus-component-annotations:jar:2.1.0:compile +| \- org.apache.commons:commons-lang3:jar:3.8.1:compile +\- org.slf4j:slf4j-simple:jar:2.0.13:test + \- org.slf4j:slf4j-api:jar:2.0.13:compile diff --git a/src/it/projects/tree-scope/expected2.txt b/src/it/projects/tree-scope/expected2.txt new file mode 100644 index 000000000..03f4e394b --- /dev/null +++ b/src/it/projects/tree-scope/expected2.txt @@ -0,0 +1,39 @@ +org.apache.maven.its.dependency:test:jar:1.0-SNAPSHOT ++- org.apache.maven:maven-core:jar:3.6.3:compile +| +- org.apache.maven:maven-model:jar:3.6.3:compile +| +- org.apache.maven:maven-settings:jar:3.6.3:compile +| +- org.apache.maven:maven-settings-builder:jar:3.6.3:compile +| | +- org.codehaus.plexus:plexus-interpolation:jar:1.25:compile +| | \- org.sonatype.plexus:plexus-sec-dispatcher:jar:1.4:compile +| | \- org.sonatype.plexus:plexus-cipher:jar:1.4:compile +| +- org.apache.maven:maven-builder-support:jar:3.6.3:compile +| +- org.apache.maven:maven-repository-metadata:jar:3.6.3:compile +| +- org.apache.maven:maven-artifact:jar:3.6.3:compile +| +- org.apache.maven:maven-plugin-api:jar:3.6.3:compile +| +- org.apache.maven:maven-model-builder:jar:3.6.3:compile +| +- org.apache.maven:maven-resolver-provider:jar:3.6.3:compile +| +- org.apache.maven.resolver:maven-resolver-impl:jar:1.4.1:compile +| +- org.apache.maven.resolver:maven-resolver-api:jar:1.4.1:compile +| +- org.apache.maven.resolver:maven-resolver-spi:jar:1.4.1:compile +| +- org.apache.maven.resolver:maven-resolver-util:jar:1.4.1:compile +| +- org.apache.maven.shared:maven-shared-utils:jar:3.2.1:compile +| | \- commons-io:commons-io:jar:2.5:compile +| +- org.eclipse.sisu:org.eclipse.sisu.plexus:jar:0.3.4:compile +| | \- javax.enterprise:cdi-api:jar:1.0:compile +| | \- javax.annotation:jsr250-api:jar:1.0:compile +| +- org.eclipse.sisu:org.eclipse.sisu.inject:jar:0.3.4:compile +| +- com.google.inject:guice:jar:no_aop:4.2.1:compile +| | +- aopalliance:aopalliance:jar:1.0:compile +| | \- com.google.guava:guava:jar:25.1-android:compile +| | +- com.google.code.findbugs:jsr305:jar:3.0.2:compile +| | +- org.checkerframework:checker-compat-qual:jar:2.0.0:compile +| | +- com.google.errorprone:error_prone_annotations:jar:2.1.3:compile +| | +- com.google.j2objc:j2objc-annotations:jar:1.1:compile +| | \- org.codehaus.mojo:animal-sniffer-annotations:jar:1.14:compile +| +- javax.inject:javax.inject:jar:1:compile +| +- org.codehaus.plexus:plexus-utils:jar:3.2.1:compile +| +- org.codehaus.plexus:plexus-classworlds:jar:2.6.0:compile +| +- org.codehaus.plexus:plexus-component-annotations:jar:2.1.0:compile +| \- org.apache.commons:commons-lang3:jar:3.8.1:compile +\- org.slf4j:slf4j-simple:jar:2.0.13:test + \- org.slf4j:slf4j-api:jar:2.0.13:compile diff --git a/src/it/projects/tree-scope/invoker.properties b/src/it/projects/tree-scope/invoker.properties new file mode 100644 index 000000000..0999b3e48 --- /dev/null +++ b/src/it/projects/tree-scope/invoker.properties @@ -0,0 +1,22 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +invoker.goals.1 = ${project.groupId}:${project.artifactId}:${project.version}:tree +invoker.userPropertiesFile.1 = test1.properties + +invoker.goals.2 = ${project.groupId}:${project.artifactId}:${project.version}:tree +invoker.userPropertiesFile.2 = test2.properties diff --git a/src/it/projects/tree-scope/pom.xml b/src/it/projects/tree-scope/pom.xml new file mode 100644 index 000000000..6b915596c --- /dev/null +++ b/src/it/projects/tree-scope/pom.xml @@ -0,0 +1,55 @@ + + + + + 4.0.0 + + org.apache.maven.its.dependency + test + 1.0-SNAPSHOT + + Test + + Test dependency:tree with scope + + + + UTF-8 + + + + + org.apache.maven + maven-core + 3.6.3 + + + + org.slf4j + slf4j-simple + 2.0.13 + test + + + + + diff --git a/src/it/projects/tree-scope/test1.properties b/src/it/projects/tree-scope/test1.properties new file mode 100644 index 000000000..42b6c4298 --- /dev/null +++ b/src/it/projects/tree-scope/test1.properties @@ -0,0 +1,19 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +outputFile = target/tree1.txt +scope = compile diff --git a/src/it/projects/tree-scope/test2.properties b/src/it/projects/tree-scope/test2.properties new file mode 100644 index 000000000..784d605e5 --- /dev/null +++ b/src/it/projects/tree-scope/test2.properties @@ -0,0 +1,19 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +outputFile = target/tree2.txt +scope = test diff --git a/src/it/projects/tree-scope/verify.groovy b/src/it/projects/tree-scope/verify.groovy new file mode 100644 index 000000000..521bd47b2 --- /dev/null +++ b/src/it/projects/tree-scope/verify.groovy @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + +import static org.assertj.core.api.Assertions.assertThat + +// Maven 4 use transitive dependency manager +def expected1 = mavenVersion.startsWith('4.') ? "expected1-v4.txt" : "expected1.txt" +def expected2 = mavenVersion.startsWith('4.') ? "expected2-v4.txt" : "expected2.txt" + +assertThat(new File(basedir, "target/tree1.txt")) + .hasSameTextualContentAs(new File(basedir, expected1)) + +assertThat(new File(basedir, "target/tree2.txt")) + .hasSameTextualContentAs(new File(basedir, expected2)) + +return true \ No newline at end of file diff --git a/src/it/projects/tree-verbose-multimodule/module-a/expected-v4.txt b/src/it/projects/tree-verbose-multimodule/module-a/expected-v4.txt new file mode 100644 index 000000000..027731031 --- /dev/null +++ b/src/it/projects/tree-verbose-multimodule/module-a/expected-v4.txt @@ -0,0 +1,30 @@ +org.apache.maven.its.dependency:tree-multimodule-module-a:jar:1.0-SNAPSHOT +\- org.apache.maven:maven-project:jar:2.0.6:compile + +- org.apache.maven:maven-settings:jar:2.0.6:compile + | +- (org.apache.maven:maven-model:jar:2.0.6:compile - version managed from 2.0.6; omitted for duplicate) + | +- (org.codehaus.plexus:plexus-utils:jar:1.4.1:compile - version managed from 1.4.1; omitted for duplicate) + | \- (org.codehaus.plexus:plexus-container-default:jar:1.0-alpha-9-stable-1:compile - version managed from 1.0-alpha-9-stable-1; omitted for duplicate) + +- org.apache.maven:maven-profile:jar:2.0.6:compile + | +- (org.apache.maven:maven-model:jar:2.0.6:compile - version managed from 2.0.6; omitted for duplicate) + | +- (org.codehaus.plexus:plexus-utils:jar:1.4.1:compile - version managed from 1.4.1; omitted for duplicate) + | \- (org.codehaus.plexus:plexus-container-default:jar:1.0-alpha-9-stable-1:compile - version managed from 1.0-alpha-9-stable-1; omitted for duplicate) + +- org.apache.maven:maven-model:jar:2.0.6:compile + | \- (org.codehaus.plexus:plexus-utils:jar:1.4.1:compile - version managed from 1.4.1; omitted for duplicate) + +- org.apache.maven:maven-artifact-manager:jar:2.0.6:compile + | +- org.apache.maven:maven-repository-metadata:jar:2.0.6:compile (version managed from 2.0.6) + | | \- (org.codehaus.plexus:plexus-utils:jar:1.4.1:compile - version managed from 1.4.1; omitted for duplicate) + | +- (org.codehaus.plexus:plexus-utils:jar:1.4.1:compile - version managed from 1.4.1; omitted for duplicate) + | +- (org.apache.maven:maven-artifact:jar:2.0.6:compile - version managed from 2.0.6; omitted for duplicate) + | +- (org.codehaus.plexus:plexus-container-default:jar:1.0-alpha-9-stable-1:compile - version managed from 1.0-alpha-9-stable-1; omitted for duplicate) + | \- org.apache.maven.wagon:wagon-provider-api:jar:1.0-beta-2:compile (version managed from 1.0-beta-2) + | \- (org.codehaus.plexus:plexus-utils:jar:1.4.1:compile - version managed from 1.0.4; omitted for duplicate) + +- org.apache.maven:maven-plugin-registry:jar:2.0.6:compile + | +- (org.codehaus.plexus:plexus-utils:jar:1.4.1:compile - version managed from 1.4.1; omitted for duplicate) + | \- (org.codehaus.plexus:plexus-container-default:jar:1.0-alpha-9-stable-1:compile - version managed from 1.0-alpha-9-stable-1; omitted for duplicate) + +- org.codehaus.plexus:plexus-utils:jar:1.4.1:compile + +- org.apache.maven:maven-artifact:jar:2.0.6:compile + | \- (org.codehaus.plexus:plexus-utils:jar:1.4.1:compile - version managed from 1.4.1; omitted for duplicate) + \- org.codehaus.plexus:plexus-container-default:jar:1.0-alpha-9-stable-1:compile + +- junit:junit:jar:3.8.1:compile + +- (org.codehaus.plexus:plexus-utils:jar:1.4.1:compile - version managed from 1.0.4; omitted for duplicate) + \- classworlds:classworlds:jar:1.1:compile (version managed from 1.1-alpha-2) diff --git a/src/it/projects/tree-verbose-multimodule/module-b/expected-v4.txt b/src/it/projects/tree-verbose-multimodule/module-b/expected-v4.txt new file mode 100644 index 000000000..ffc3a86ce --- /dev/null +++ b/src/it/projects/tree-verbose-multimodule/module-b/expected-v4.txt @@ -0,0 +1,31 @@ +org.apache.maven.its.dependency:tree-multimodule-module-b:jar:1.0-SNAPSHOT +\- org.apache.maven.its.dependency:tree-multimodule-module-a:jar:1.0-SNAPSHOT:compile + \- org.apache.maven:maven-project:jar:2.0.6:compile + +- org.apache.maven:maven-settings:jar:2.0.6:compile + | +- (org.apache.maven:maven-model:jar:2.0.6:compile - version managed from 2.0.6; omitted for duplicate) + | +- (org.codehaus.plexus:plexus-utils:jar:1.4.1:compile - version managed from 1.4.1; omitted for duplicate) + | \- (org.codehaus.plexus:plexus-container-default:jar:1.0-alpha-9-stable-1:compile - version managed from 1.0-alpha-9-stable-1; omitted for duplicate) + +- org.apache.maven:maven-profile:jar:2.0.6:compile + | +- (org.apache.maven:maven-model:jar:2.0.6:compile - version managed from 2.0.6; omitted for duplicate) + | +- (org.codehaus.plexus:plexus-utils:jar:1.4.1:compile - version managed from 1.4.1; omitted for duplicate) + | \- (org.codehaus.plexus:plexus-container-default:jar:1.0-alpha-9-stable-1:compile - version managed from 1.0-alpha-9-stable-1; omitted for duplicate) + +- org.apache.maven:maven-model:jar:2.0.6:compile + | \- (org.codehaus.plexus:plexus-utils:jar:1.4.1:compile - version managed from 1.4.1; omitted for duplicate) + +- org.apache.maven:maven-artifact-manager:jar:2.0.6:compile + | +- org.apache.maven:maven-repository-metadata:jar:2.0.6:compile (version managed from 2.0.6) + | | \- (org.codehaus.plexus:plexus-utils:jar:1.4.1:compile - version managed from 1.4.1; omitted for duplicate) + | +- (org.codehaus.plexus:plexus-utils:jar:1.4.1:compile - version managed from 1.4.1; omitted for duplicate) + | +- (org.apache.maven:maven-artifact:jar:2.0.6:compile - version managed from 2.0.6; omitted for duplicate) + | +- (org.codehaus.plexus:plexus-container-default:jar:1.0-alpha-9-stable-1:compile - version managed from 1.0-alpha-9-stable-1; omitted for duplicate) + | \- org.apache.maven.wagon:wagon-provider-api:jar:1.0-beta-2:compile (version managed from 1.0-beta-2) + | \- (org.codehaus.plexus:plexus-utils:jar:1.4.1:compile - version managed from 1.0.4; omitted for duplicate) + +- org.apache.maven:maven-plugin-registry:jar:2.0.6:compile + | +- (org.codehaus.plexus:plexus-utils:jar:1.4.1:compile - version managed from 1.4.1; omitted for duplicate) + | \- (org.codehaus.plexus:plexus-container-default:jar:1.0-alpha-9-stable-1:compile - version managed from 1.0-alpha-9-stable-1; omitted for duplicate) + +- org.codehaus.plexus:plexus-utils:jar:1.4.1:compile + +- org.apache.maven:maven-artifact:jar:2.0.6:compile + | \- (org.codehaus.plexus:plexus-utils:jar:1.4.1:compile - version managed from 1.4.1; omitted for duplicate) + \- org.codehaus.plexus:plexus-container-default:jar:1.0-alpha-9-stable-1:compile + +- junit:junit:jar:3.8.1:compile + +- (org.codehaus.plexus:plexus-utils:jar:1.4.1:compile - version managed from 1.0.4; omitted for duplicate) + \- classworlds:classworlds:jar:1.1:compile (version managed from 1.1-alpha-2) diff --git a/src/it/projects/tree-verbose-multimodule/verify.bsh b/src/it/projects/tree-verbose-multimodule/verify.bsh deleted file mode 100644 index fcbece716..000000000 --- a/src/it/projects/tree-verbose-multimodule/verify.bsh +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import java.io.*; - -import org.codehaus.plexus.util.*; - -String actual = FileUtils.fileRead( new File( basedir, "target/tree.txt" ) ); -String expected = FileUtils.fileRead( new File( basedir, "expected.txt" ) ); - -actual = actual.replaceAll( "[\n\r]+", "\n" ); -expected = expected.replaceAll( "[\n\r]+", "\n" ); - -if ( !actual.equals( expected ) ) -{ - throw new Exception( "Unexpected root dependency tree" ); -} - -actual = FileUtils.fileRead( new File( basedir, "module-a/target/tree.txt" ) ); -expected = FileUtils.fileRead( new File( basedir, "module-a/expected.txt" ) ); - -actual = actual.replaceAll( "[\n\r]+", "\n" ); -expected = expected.replaceAll( "[\n\r]+", "\n" ); - -if ( !actual.equals( expected ) ) -{ - throw new Exception( "Unexpected module-a dependency tree" ); -} - -actual = FileUtils.fileRead( new File( basedir, "module-b/target/tree.txt" ) ); -expected = FileUtils.fileRead( new File( basedir, "module-b/expected.txt" ) ); - -actual = actual.replaceAll( "[\n\r]+", "\n" ); -expected = expected.replaceAll( "[\n\r]+", "\n" ); - -if ( !actual.equals( expected ) ) -{ - throw new Exception( "Unexpected module-b dependency tree" ); -} - -return true; diff --git a/src/it/projects/tree-verbose-small/verify.bsh b/src/it/projects/tree-verbose-multimodule/verify.groovy similarity index 59% rename from src/it/projects/tree-verbose-small/verify.bsh rename to src/it/projects/tree-verbose-multimodule/verify.groovy index cf0ab8f67..03cfc779e 100644 --- a/src/it/projects/tree-verbose-small/verify.bsh +++ b/src/it/projects/tree-verbose-multimodule/verify.groovy @@ -17,19 +17,18 @@ * under the License. */ -import java.io.*; -import org.codehaus.plexus.util.*; +import static org.assertj.core.api.Assertions.assertThat -String actual = FileUtils.fileRead( new File( basedir, "target/tree.txt" ) ); -String expected = FileUtils.fileRead( new File( basedir, "expected.txt" ) ); +// Maven 4 use transitive dependency manager +def expected = mavenVersion.startsWith('4.') ? "expected-v4.txt" : "expected.txt" -actual = actual.replaceAll( "[\n\r]+", "\n" ); -expected = expected.replaceAll( "[\n\r]+", "\n" ); +assertThat(new File(basedir, "target/tree.txt")) + .hasSameTextualContentAs(new File(basedir, "expected.txt")) -if ( !actual.equals( expected ) ) -{ - throw new Exception( "Unexpected dependency tree." + System.lineSeparator() + "Expected:" + System.lineSeparator() - + expected + System.lineSeparator() + "Actual:" + System.lineSeparator() + actual ); -} +assertThat(new File(basedir, "module-a/target/tree.txt")) + .hasSameTextualContentAs(new File(basedir, "module-a/" + expected)) + +assertThat(new File(basedir, "module-b/target/tree.txt")) + .hasSameTextualContentAs(new File(basedir, "module-b/" + expected)) return true; diff --git a/src/it/projects/tree-verbose-small/verify.groovy b/src/it/projects/tree-verbose-small/verify.groovy new file mode 100644 index 000000000..0da3382c4 --- /dev/null +++ b/src/it/projects/tree-verbose-small/verify.groovy @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import static org.assertj.core.api.Assertions.assertThat + +assertThat(new File(basedir, "target/tree.txt")) + .hasSameTextualContentAs(new File(basedir, "expected.txt")) + +return true \ No newline at end of file diff --git a/src/it/projects/tree-verbose/expected-v4.txt b/src/it/projects/tree-verbose/expected-v4.txt new file mode 100644 index 000000000..e0095ea97 --- /dev/null +++ b/src/it/projects/tree-verbose/expected-v4.txt @@ -0,0 +1,89 @@ +org.apache.maven.its.dependency:tree-verbose:jar:1.0-SNAPSHOT ++- org.apache.maven:maven-project:jar:2.0.6:compile +| +- org.apache.maven:maven-settings:jar:2.0.6:compile +| | +- (org.apache.maven:maven-model:jar:2.0.5:test - version managed from 2.0.6; scope managed from compile; omitted for conflict with 2.0.7) +| | +- (org.codehaus.plexus:plexus-utils:jar:1.4.1:compile - version managed from 1.4.1; omitted for duplicate) +| | \- (org.codehaus.plexus:plexus-container-default:jar:1.0-alpha-9-stable-1:compile - version managed from 1.0-alpha-9-stable-1; omitted for duplicate) +| +- (org.apache.maven:maven-profile:jar:2.0.6:compile - omitted for conflict with 2.0.4) +| +- (org.apache.maven:maven-model:jar:2.0.5:test - version managed from 2.0.6; scope managed from compile; omitted for conflict with 2.0.7) +| +- org.apache.maven:maven-artifact-manager:jar:2.0.6:compile +| | +- org.apache.maven:maven-repository-metadata:jar:2.0.6:compile (version managed from 2.0.6) +| | | \- (org.codehaus.plexus:plexus-utils:jar:1.4.1:compile - version managed from 1.4.1; omitted for duplicate) +| | +- (org.codehaus.plexus:plexus-utils:jar:1.4.1:compile - version managed from 1.4.1; omitted for duplicate) +| | +- (org.codehaus.plexus:plexus-container-default:jar:1.0-alpha-9-stable-1:compile - version managed from 1.0-alpha-9-stable-1; omitted for duplicate) +| | \- org.apache.maven.wagon:wagon-provider-api:jar:1.0-beta-2:compile (version managed from 1.0-beta-2) +| | \- (org.codehaus.plexus:plexus-utils:jar:1.4.1:compile - version managed from 1.0.4; omitted for duplicate) +| +- org.apache.maven:maven-plugin-registry:jar:2.0.6:compile +| | +- (org.codehaus.plexus:plexus-utils:jar:1.4.1:compile - version managed from 1.4.1; omitted for duplicate) +| | \- (org.codehaus.plexus:plexus-container-default:jar:1.0-alpha-9-stable-1:compile - version managed from 1.0-alpha-9-stable-1; omitted for duplicate) +| +- org.codehaus.plexus:plexus-utils:jar:1.4.1:compile +| \- org.codehaus.plexus:plexus-container-default:jar:1.0-alpha-9-stable-1:compile +| +- junit:junit:jar:3.8.1:compile +| +- (org.codehaus.plexus:plexus-utils:jar:1.4.1:compile - version managed from 1.0.4; omitted for duplicate) +| \- classworlds:classworlds:jar:1.1:compile (version managed from 1.1-alpha-2) ++- org.apache.maven:maven-profile:jar:2.0.4:test (scope not updated to compile) +| +- (org.apache.maven:maven-model:jar:2.0.5:test - version managed from 2.0.4; scope managed from compile; omitted for conflict with 2.0.7) +| +- (org.codehaus.plexus:plexus-utils:jar:1.1:test - omitted for conflict with 1.4.1) +| \- (org.codehaus.plexus:plexus-container-default:jar:1.0-alpha-9:test - omitted for conflict with 1.0-alpha-9-stable-1) ++- org.apache.maven:maven-model:jar:2.0.7:runtime +| \- (org.codehaus.plexus:plexus-utils:jar:1.4.1:runtime - omitted for duplicate) +\- org.apache.xmlgraphics:batik-bridge:jar:1.7:compile + +- org.apache.xmlgraphics:batik-anim:jar:1.7:compile + | +- (org.apache.xmlgraphics:batik-awt-util:jar:1.7:compile - omitted for duplicate) + | +- (org.apache.xmlgraphics:batik-dom:jar:1.7:compile - omitted for duplicate) + | +- (org.apache.xmlgraphics:batik-ext:jar:1.7:compile - omitted for duplicate) + | +- (org.apache.xmlgraphics:batik-parser:jar:1.7:compile - omitted for duplicate) + | +- (org.apache.xmlgraphics:batik-svg-dom:jar:1.7:compile - omitted for duplicate) + | +- (org.apache.xmlgraphics:batik-util:jar:1.7:compile - omitted for duplicate) + | +- (xml-apis:xml-apis:jar:1.3.04:compile - omitted for duplicate) + | \- (xml-apis:xml-apis-ext:jar:1.3.04:compile - omitted for duplicate) + +- org.apache.xmlgraphics:batik-awt-util:jar:1.7:compile + | \- (org.apache.xmlgraphics:batik-util:jar:1.7:compile - omitted for duplicate) + +- org.apache.xmlgraphics:batik-css:jar:1.7:compile + | +- (org.apache.xmlgraphics:batik-ext:jar:1.7:compile - omitted for duplicate) + | +- (org.apache.xmlgraphics:batik-util:jar:1.7:compile - omitted for duplicate) + | +- (xml-apis:xml-apis:jar:1.3.04:compile - omitted for duplicate) + | \- (xml-apis:xml-apis-ext:jar:1.3.04:compile - omitted for duplicate) + +- org.apache.xmlgraphics:batik-dom:jar:1.7:compile + | +- (org.apache.xmlgraphics:batik-css:jar:1.7:compile - omitted for duplicate) + | +- (org.apache.xmlgraphics:batik-ext:jar:1.7:compile - omitted for duplicate) + | +- (org.apache.xmlgraphics:batik-util:jar:1.7:compile - omitted for duplicate) + | +- (org.apache.xmlgraphics:batik-xml:jar:1.7:compile - omitted for duplicate) + | +- (xalan:xalan:jar:2.6.0:compile - omitted for duplicate) + | +- (xml-apis:xml-apis:jar:1.3.04:compile - omitted for duplicate) + | \- (xml-apis:xml-apis-ext:jar:1.3.04:compile - omitted for duplicate) + +- org.apache.xmlgraphics:batik-ext:jar:1.7:compile + | \- (xml-apis:xml-apis:jar:1.3.04:compile - omitted for duplicate) + +- org.apache.xmlgraphics:batik-gvt:jar:1.7:compile + | +- (org.apache.xmlgraphics:batik-awt-util:jar:1.7:compile - omitted for duplicate) + | +- (org.apache.xmlgraphics:batik-util:jar:1.7:compile - omitted for duplicate) + | \- (xml-apis:xml-apis:jar:1.3.04:compile - omitted for duplicate) + +- org.apache.xmlgraphics:batik-parser:jar:1.7:compile + | +- (org.apache.xmlgraphics:batik-awt-util:jar:1.7:compile - omitted for duplicate) + | +- (org.apache.xmlgraphics:batik-util:jar:1.7:compile - omitted for duplicate) + | \- (org.apache.xmlgraphics:batik-xml:jar:1.7:compile - omitted for duplicate) + +- org.apache.xmlgraphics:batik-script:jar:1.7:compile + | +- (org.apache.xmlgraphics:batik-dom:jar:1.7:compile - omitted for duplicate) + | +- (org.apache.xmlgraphics:batik-ext:jar:1.7:compile - omitted for duplicate) + | +- (org.apache.xmlgraphics:batik-svg-dom:jar:1.7:compile - omitted for duplicate) + | +- (org.apache.xmlgraphics:batik-util:jar:1.7:compile - omitted for duplicate) + | +- org.apache.xmlgraphics:batik-js:jar:1.7:compile + | | \- (xml-apis:xml-apis:jar:1.3.04:compile - omitted for duplicate) + | \- (xml-apis:xml-apis:jar:1.3.04:compile - omitted for duplicate) + +- org.apache.xmlgraphics:batik-svg-dom:jar:1.7:compile + | +- (org.apache.xmlgraphics:batik-anim:jar:1.7:compile - omitted for duplicate) + | +- (org.apache.xmlgraphics:batik-awt-util:jar:1.7:compile - omitted for duplicate) + | +- (org.apache.xmlgraphics:batik-css:jar:1.7:compile - omitted for duplicate) + | +- (org.apache.xmlgraphics:batik-dom:jar:1.7:compile - omitted for duplicate) + | +- (org.apache.xmlgraphics:batik-ext:jar:1.7:compile - omitted for duplicate) + | +- (org.apache.xmlgraphics:batik-parser:jar:1.7:compile - omitted for duplicate) + | +- (org.apache.xmlgraphics:batik-util:jar:1.7:compile - omitted for duplicate) + | +- (xml-apis:xml-apis:jar:1.3.04:compile - omitted for duplicate) + | \- (xml-apis:xml-apis-ext:jar:1.3.04:compile - omitted for duplicate) + +- org.apache.xmlgraphics:batik-util:jar:1.7:compile + +- org.apache.xmlgraphics:batik-xml:jar:1.7:compile + | \- (org.apache.xmlgraphics:batik-util:jar:1.7:compile - omitted for duplicate) + +- xalan:xalan:jar:2.6.0:compile + | \- (xml-apis:xml-apis:jar:1.0.b2:compile - omitted for conflict with 1.3.04) + +- xml-apis:xml-apis:jar:1.3.04:compile + \- xml-apis:xml-apis-ext:jar:1.3.04:compile diff --git a/src/it/projects/tree-verbose/verify.groovy b/src/it/projects/tree-verbose/verify.groovy new file mode 100644 index 000000000..e9d8d8135 --- /dev/null +++ b/src/it/projects/tree-verbose/verify.groovy @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import static org.assertj.core.api.Assertions.assertThat + +// Maven 4 use transitive dependency manager +def expected = mavenVersion.startsWith('4.') ? "expected-v4.txt" : "expected.txt" + +assertThat(new File(basedir, "target/tree.txt")) + .hasSameTextualContentAs(new File(basedir, expected)) + +return true diff --git a/src/it/projects/tree/expected-v4.txt b/src/it/projects/tree/expected-v4.txt new file mode 100644 index 000000000..48b9a84f6 --- /dev/null +++ b/src/it/projects/tree/expected-v4.txt @@ -0,0 +1,38 @@ +org.apache.maven.its.dependency:test:jar:1.0-SNAPSHOT ++- org.apache.maven:maven-core:jar:3.6.3:compile +| +- org.apache.maven:maven-model:jar:3.6.3:compile +| +- org.apache.maven:maven-settings:jar:3.6.3:compile +| +- org.apache.maven:maven-settings-builder:jar:3.6.3:compile +| | +- org.codehaus.plexus:plexus-interpolation:jar:1.25:compile +| | \- org.sonatype.plexus:plexus-sec-dispatcher:jar:1.4:compile +| | \- org.sonatype.plexus:plexus-cipher:jar:1.7:compile +| +- org.apache.maven:maven-builder-support:jar:3.6.3:compile +| +- org.apache.maven:maven-repository-metadata:jar:3.6.3:compile +| +- org.apache.maven:maven-artifact:jar:3.6.3:compile +| +- org.apache.maven:maven-plugin-api:jar:3.6.3:compile +| +- org.apache.maven:maven-model-builder:jar:3.6.3:compile +| +- org.apache.maven:maven-resolver-provider:jar:3.6.3:compile +| | \- org.slf4j:slf4j-api:jar:1.7.29:compile +| +- org.apache.maven.resolver:maven-resolver-impl:jar:1.4.1:compile +| +- org.apache.maven.resolver:maven-resolver-api:jar:1.4.1:compile +| +- org.apache.maven.resolver:maven-resolver-spi:jar:1.4.1:compile +| +- org.apache.maven.resolver:maven-resolver-util:jar:1.4.1:compile +| +- org.apache.maven.shared:maven-shared-utils:jar:3.2.1:compile +| | \- commons-io:commons-io:jar:2.5:compile +| +- org.eclipse.sisu:org.eclipse.sisu.plexus:jar:0.3.4:compile +| | \- javax.enterprise:cdi-api:jar:1.0:compile +| | \- javax.annotation:jsr250-api:jar:1.0:compile +| +- org.eclipse.sisu:org.eclipse.sisu.inject:jar:0.3.4:compile +| +- com.google.inject:guice:jar:no_aop:4.2.1:compile +| | +- aopalliance:aopalliance:jar:1.0:compile +| | \- com.google.guava:guava:jar:25.1-android:compile +| | +- com.google.code.findbugs:jsr305:jar:3.0.1:compile +| | +- org.checkerframework:checker-compat-qual:jar:2.0.0:compile +| | +- com.google.errorprone:error_prone_annotations:jar:2.1.3:compile +| | +- com.google.j2objc:j2objc-annotations:jar:1.1:compile +| | \- org.codehaus.mojo:animal-sniffer-annotations:jar:1.14:compile +| +- javax.inject:javax.inject:jar:1:compile +| +- org.codehaus.plexus:plexus-utils:jar:3.2.1:compile +| +- org.codehaus.plexus:plexus-classworlds:jar:2.6.0:compile +| \- org.codehaus.plexus:plexus-component-annotations:jar:2.1.0:compile +\- org.apache.commons:commons-lang3:jar:3.18.0:compile (optional) diff --git a/src/it/projects/tree/expected.txt b/src/it/projects/tree/expected.txt index 4f2038776..0c8f28deb 100644 --- a/src/it/projects/tree/expected.txt +++ b/src/it/projects/tree/expected.txt @@ -1,14 +1,38 @@ org.apache.maven.its.dependency:test:jar:1.0-SNAPSHOT -\- org.apache.maven:maven-project:jar:2.0.6:compile - +- org.apache.maven:maven-settings:jar:2.0.6:compile - +- org.apache.maven:maven-profile:jar:2.0.6:compile - +- org.apache.maven:maven-model:jar:2.0.6:compile - +- org.apache.maven:maven-artifact-manager:jar:2.0.6:compile - | +- org.apache.maven:maven-repository-metadata:jar:2.0.6:compile - | \- org.apache.maven.wagon:wagon-provider-api:jar:1.0-beta-2:compile - +- org.apache.maven:maven-plugin-registry:jar:2.0.6:compile - +- org.codehaus.plexus:plexus-utils:jar:1.4.1:compile - +- org.apache.maven:maven-artifact:jar:2.0.6:compile - \- org.codehaus.plexus:plexus-container-default:jar:1.0-alpha-9-stable-1:compile - +- junit:junit:jar:3.8.1:compile - \- classworlds:classworlds:jar:1.1-alpha-2:compile ++- org.apache.maven:maven-core:jar:3.6.3:compile +| +- org.apache.maven:maven-model:jar:3.6.3:compile +| +- org.apache.maven:maven-settings:jar:3.6.3:compile +| +- org.apache.maven:maven-settings-builder:jar:3.6.3:compile +| | +- org.codehaus.plexus:plexus-interpolation:jar:1.25:compile +| | \- org.sonatype.plexus:plexus-sec-dispatcher:jar:1.4:compile +| | \- org.sonatype.plexus:plexus-cipher:jar:1.4:compile +| +- org.apache.maven:maven-builder-support:jar:3.6.3:compile +| +- org.apache.maven:maven-repository-metadata:jar:3.6.3:compile +| +- org.apache.maven:maven-artifact:jar:3.6.3:compile +| +- org.apache.maven:maven-plugin-api:jar:3.6.3:compile +| +- org.apache.maven:maven-model-builder:jar:3.6.3:compile +| +- org.apache.maven:maven-resolver-provider:jar:3.6.3:compile +| | \- org.slf4j:slf4j-api:jar:1.7.29:compile +| +- org.apache.maven.resolver:maven-resolver-impl:jar:1.4.1:compile +| +- org.apache.maven.resolver:maven-resolver-api:jar:1.4.1:compile +| +- org.apache.maven.resolver:maven-resolver-spi:jar:1.4.1:compile +| +- org.apache.maven.resolver:maven-resolver-util:jar:1.4.1:compile +| +- org.apache.maven.shared:maven-shared-utils:jar:3.2.1:compile +| | \- commons-io:commons-io:jar:2.5:compile +| +- org.eclipse.sisu:org.eclipse.sisu.plexus:jar:0.3.4:compile +| | \- javax.enterprise:cdi-api:jar:1.0:compile +| | \- javax.annotation:jsr250-api:jar:1.0:compile +| +- org.eclipse.sisu:org.eclipse.sisu.inject:jar:0.3.4:compile +| +- com.google.inject:guice:jar:no_aop:4.2.1:compile +| | +- aopalliance:aopalliance:jar:1.0:compile +| | \- com.google.guava:guava:jar:25.1-android:compile +| | +- com.google.code.findbugs:jsr305:jar:3.0.2:compile +| | +- org.checkerframework:checker-compat-qual:jar:2.0.0:compile +| | +- com.google.errorprone:error_prone_annotations:jar:2.1.3:compile +| | +- com.google.j2objc:j2objc-annotations:jar:1.1:compile +| | \- org.codehaus.mojo:animal-sniffer-annotations:jar:1.14:compile +| +- javax.inject:javax.inject:jar:1:compile +| +- org.codehaus.plexus:plexus-utils:jar:3.2.1:compile +| +- org.codehaus.plexus:plexus-classworlds:jar:2.6.0:compile +| \- org.codehaus.plexus:plexus-component-annotations:jar:2.1.0:compile +\- org.apache.commons:commons-lang3:jar:3.18.0:compile (optional) diff --git a/src/it/projects/tree/pom.xml b/src/it/projects/tree/pom.xml index 30794e64b..c757695b3 100644 --- a/src/it/projects/tree/pom.xml +++ b/src/it/projects/tree/pom.xml @@ -39,8 +39,14 @@ org.apache.maven - maven-project - 2.0.6 + maven-core + 3.6.3 + + + org.apache.commons + commons-lang3 + 3.18.0 + true diff --git a/src/it/projects/tree/verify.groovy b/src/it/projects/tree/verify.groovy new file mode 100644 index 000000000..e9d8d8135 --- /dev/null +++ b/src/it/projects/tree/verify.groovy @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import static org.assertj.core.api.Assertions.assertThat + +// Maven 4 use transitive dependency manager +def expected = mavenVersion.startsWith('4.') ? "expected-v4.txt" : "expected.txt" + +assertThat(new File(basedir, "target/tree.txt")) + .hasSameTextualContentAs(new File(basedir, expected)) + +return true diff --git a/src/it/projects/unpack-cli/verify.bsh b/src/it/projects/unpack-cli/verify.bsh index fc16bb2f9..4b93d0726 100644 --- a/src/it/projects/unpack-cli/verify.bsh +++ b/src/it/projects/unpack-cli/verify.bsh @@ -21,21 +21,18 @@ import java.io.*; File file = new File( basedir, "target/output spaces directory" ); -System.out.println( "Checking for existence of " + file ); if ( !file.isDirectory() ) { throw new Exception( "Missing " + file ); } file = new File( file, "qdox-1.5" ); -System.out.println( "Checking for existence of " + file ); if ( !file.isDirectory() ) { throw new Exception( "Missing " + file ); } file = new File( file, "build.xml" ); -System.out.println( "Checking for existence of " + file ); if ( !file.isFile() ) { throw new Exception( "Missing " + file ); @@ -43,7 +40,6 @@ if ( !file.isFile() ) //until MDEP-242 is fixed, the next test will passed file = new File( file.getParent(), "src" ); -System.out.println( "Checking for existence of " + file ); if ( !file.isDirectory() ) { throw new Exception( "Missing " + file ); diff --git a/src/it/projects/unpack-custom-ear/verify.groovy b/src/it/projects/unpack-custom-ear/verify.groovy index 36eb8352a..9b92ae56d 100644 --- a/src/it/projects/unpack-custom-ear/verify.groovy +++ b/src/it/projects/unpack-custom-ear/verify.groovy @@ -1,22 +1,22 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -def buildLog = new File( basedir, 'build.log' ) -assert buildLog.exists() -assert buildLog.length() != 0 -assert buildLog.text.contains( "[DEBUG] Found unArchiver by type: " ) +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +def buildLog = new File( basedir, 'build.log' ) +assert buildLog.exists() +assert buildLog.length() != 0 +assert buildLog.text.contains( "[DEBUG] Found unArchiver: org.apache.maven.archiver.LogUnArchiver by type: custom-ear" ) diff --git a/src/it/projects/unpack-dependencies-with-filemappers/verify.groovy b/src/it/projects/unpack-dependencies-with-filemappers/verify.groovy index de665cc1e..03edbd03c 100644 --- a/src/it/projects/unpack-dependencies-with-filemappers/verify.groovy +++ b/src/it/projects/unpack-dependencies-with-filemappers/verify.groovy @@ -24,7 +24,7 @@ for (item in expected) def file = new File(basedir, 'target/dependency/mapped/' + item) if (!file.exists()) { - throw new RuntimeException("Missing "+file.name); + throw new RuntimeException("Missing "+file.name) } } @@ -35,8 +35,8 @@ for (item in notExpected) def file = new File(basedir, 'target/dependency/' + item) if (file.exists()) { - throw new RuntimeException("This file shouldn't be here: "+file.name); + throw new RuntimeException("This file shouldn't be here: "+file.name) } } -return true; +return true diff --git a/src/it/projects/unpack-dependencies/verify.groovy b/src/it/projects/unpack-dependencies/verify.groovy index 665562965..70757222c 100644 --- a/src/it/projects/unpack-dependencies/verify.groovy +++ b/src/it/projects/unpack-dependencies/verify.groovy @@ -24,7 +24,7 @@ for (item in expected) def file = new File(basedir, 'target/dependency/' + item) if (!file.exists()) { - throw new RuntimeException("Missing "+file.name); + throw new RuntimeException("Missing " + file.name) } } @@ -35,8 +35,8 @@ for (item in notExpected) def file = new File(basedir, 'target/dependency/' + item) if (file.exists()) { - throw new RuntimeException("This file shouldn't be here: "+file.name); + throw new RuntimeException("This file shouldn't be here: " + file.name) } } -return true; +return true diff --git a/src/it/projects/unpack-from-remote-repository/pom.xml b/src/it/projects/unpack-from-remote-repository/pom.xml index c16b6f2c8..e29d6dc5b 100644 --- a/src/it/projects/unpack-from-remote-repository/pom.xml +++ b/src/it/projects/unpack-from-remote-repository/pom.xml @@ -42,6 +42,9 @@ fake-remote-repository file:///${basedir}/repo/ + + ignore + diff --git a/src/it/projects/unpack-from-remote-repository/verify.bsh b/src/it/projects/unpack-from-remote-repository/verify.bsh index 23f034522..3e4efdfed 100644 --- a/src/it/projects/unpack-from-remote-repository/verify.bsh +++ b/src/it/projects/unpack-from-remote-repository/verify.bsh @@ -26,7 +26,6 @@ String[] expectedFiles = { for ( String expectedFile : expectedFiles ) { File file = new File( localRepositoryPath, expectedFile ); - System.out.println( "Checking for existence of " + file ); if ( !file.isFile() ) { throw new Exception( "Missing file " + file ); diff --git a/src/it/projects/unpack/verify.bsh b/src/it/projects/unpack/verify.bsh index fc16bb2f9..4b93d0726 100644 --- a/src/it/projects/unpack/verify.bsh +++ b/src/it/projects/unpack/verify.bsh @@ -21,21 +21,18 @@ import java.io.*; File file = new File( basedir, "target/output spaces directory" ); -System.out.println( "Checking for existence of " + file ); if ( !file.isDirectory() ) { throw new Exception( "Missing " + file ); } file = new File( file, "qdox-1.5" ); -System.out.println( "Checking for existence of " + file ); if ( !file.isDirectory() ) { throw new Exception( "Missing " + file ); } file = new File( file, "build.xml" ); -System.out.println( "Checking for existence of " + file ); if ( !file.isFile() ) { throw new Exception( "Missing " + file ); @@ -43,7 +40,6 @@ if ( !file.isFile() ) //until MDEP-242 is fixed, the next test will passed file = new File( file.getParent(), "src" ); -System.out.println( "Checking for existence of " + file ); if ( !file.isDirectory() ) { throw new Exception( "Missing " + file ); diff --git a/src/it/projects/used-dependencies/module/pom.xml b/src/it/projects/used-dependencies/module/pom.xml index b954917f4..07c6608ec 100644 --- a/src/it/projects/used-dependencies/module/pom.xml +++ b/src/it/projects/used-dependencies/module/pom.xml @@ -39,6 +39,7 @@ maven-dependency-plugin + @project.version@ org.apache.maven.plugins.dependency:annotation diff --git a/src/it/projects/used-dependencies/pom.xml b/src/it/projects/used-dependencies/pom.xml index fe8f90367..17bb47a46 100644 --- a/src/it/projects/used-dependencies/pom.xml +++ b/src/it/projects/used-dependencies/pom.xml @@ -39,7 +39,7 @@ maven-dependency-plugin - @pom.version@ + @project.version@ true diff --git a/src/main/java/org/apache/maven/plugins/dependency/AbstractDependencyMojo.java b/src/main/java/org/apache/maven/plugins/dependency/AbstractDependencyMojo.java index 66c64c8e2..47296eb74 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/AbstractDependencyMojo.java +++ b/src/main/java/org/apache/maven/plugins/dependency/AbstractDependencyMojo.java @@ -18,95 +18,22 @@ */ package org.apache.maven.plugins.dependency; -import java.io.File; -import java.io.IOException; -import java.lang.reflect.Field; import java.util.List; -import org.apache.maven.artifact.Artifact; -import org.apache.maven.artifact.repository.ArtifactRepository; + import org.apache.maven.execution.MavenSession; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; -import org.apache.maven.plugins.annotations.Component; +import org.apache.maven.plugin.logging.SystemStreamLog; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.plugins.dependency.utils.DependencySilentLog; -import org.apache.maven.project.DefaultProjectBuildingRequest; import org.apache.maven.project.MavenProject; -import org.apache.maven.project.ProjectBuildingRequest; -import org.codehaus.plexus.archiver.ArchiverException; -import org.codehaus.plexus.archiver.UnArchiver; -import org.codehaus.plexus.archiver.manager.ArchiverManager; -import org.codehaus.plexus.archiver.manager.NoSuchArchiverException; -import org.codehaus.plexus.archiver.zip.ZipUnArchiver; -import org.codehaus.plexus.components.io.filemappers.FileMapper; -import org.codehaus.plexus.components.io.fileselectors.IncludeExcludeFileSelector; -import org.codehaus.plexus.util.FileUtils; -import org.codehaus.plexus.util.ReflectionUtils; -import org.codehaus.plexus.util.StringUtils; import org.sonatype.plexus.build.incremental.BuildContext; /** * @author Brian Fox */ public abstract class AbstractDependencyMojo extends AbstractMojo { - /** - * To look up Archiver/UnArchiver implementations - */ - @Component - private ArchiverManager archiverManager; - - /** - * For IDE build support - */ - @Component - private BuildContext buildContext; - - /** - * Skip plugin execution only during incremental builds (e.g. triggered from M2E). - * - * @since 3.4.0 - * @see #skip - */ - @Parameter(defaultValue = "false") - private boolean skipDuringIncrementalBuild; - - /** - *

- * will use the jvm chmod, this is available for user and all level group level will be ignored - *

- * since 2.6 is on by default - * - * @since 2.5.1 - */ - @Parameter(property = "dependency.useJvmChmod", defaultValue = "true") - private boolean useJvmChmod = true; - - /** - * ignore to set file permissions when unpacking a dependency - * - * @since 2.7 - */ - @Parameter(property = "dependency.ignorePermissions", defaultValue = "false") - private boolean ignorePermissions; - - /** - * POM - */ - @Parameter(defaultValue = "${project}", readonly = true, required = true) - private MavenProject project; - - /** - * Remote repositories which will be searched for artifacts. - */ - @Parameter(defaultValue = "${project.remoteArtifactRepositories}", readonly = true, required = true) - private List remoteRepositories; - - /** - * Remote repositories which will be searched for plugins. - */ - @Parameter(defaultValue = "${project.pluginArtifactRepositories}", readonly = true, required = true) - private List remotePluginRepositories; /** * Contains the full list of projects in the reactor. @@ -115,27 +42,20 @@ public abstract class AbstractDependencyMojo extends AbstractMojo { protected List reactorProjects; /** - * The Maven session + * The Maven session. */ - @Parameter(defaultValue = "${session}", readonly = true, required = true) - protected MavenSession session; + protected final MavenSession session; /** * If the plugin should be silent. * * @since 2.0 + * @deprecated to be removed in 4.0; use -q command line option instead */ + @Deprecated @Parameter(property = "silent", defaultValue = "false") private boolean silent; - /** - * Output absolute filename for resolved artifacts - * - * @since 2.0 - */ - @Parameter(property = "outputAbsoluteArtifactFilename", defaultValue = "false") - protected boolean outputAbsoluteArtifactFilename; - /** * Skip plugin execution completely. * @@ -144,6 +64,31 @@ public abstract class AbstractDependencyMojo extends AbstractMojo { @Parameter(property = "mdep.skip", defaultValue = "false") private boolean skip; + /** + * Skip plugin execution only during incremental builds (e.g. triggered from M2E). + * + * @see #skip + * @since 3.4.0 + */ + @Parameter(defaultValue = "false") + private boolean skipDuringIncrementalBuild; + + /** + * For IDE build support. + */ + private final BuildContext buildContext; + + /** + * POM. + */ + private final MavenProject project; + + protected AbstractDependencyMojo(MavenSession session, BuildContext buildContext, MavenProject project) { + this.session = session; + this.buildContext = buildContext; + this.project = project; + } + // Mojo methods ----------------------------------------------------------- /* @@ -166,230 +111,12 @@ public final void execute() throws MojoExecutionException, MojoFailureException protected abstract void doExecute() throws MojoExecutionException, MojoFailureException; /** - * @return Returns the archiverManager. - */ - public ArchiverManager getArchiverManager() { - return this.archiverManager; - } - - /** - * Does the actual copy of the file and logging. - * - * @param artifact represents the file to copy. - * @param destFile file name of destination file. - * @throws MojoExecutionException with a message if an error occurs. - */ - protected void copyFile(File artifact, File destFile) throws MojoExecutionException { - try { - getLog().info("Copying " - + (this.outputAbsoluteArtifactFilename ? artifact.getAbsolutePath() : artifact.getName()) + " to " - + destFile); - - if (artifact.isDirectory()) { - // usual case is a future jar packaging, but there are special cases: classifier and other packaging - throw new MojoExecutionException("Artifact has not been packaged yet. When used on reactor artifact, " - + "copy should be executed after packaging: see MDEP-187."); - } - - FileUtils.copyFile(artifact, destFile); - buildContext.refresh(destFile); - } catch (IOException e) { - throw new MojoExecutionException("Error copying artifact from " + artifact + " to " + destFile, e); - } - } - - /** - * @param artifact {@link Artifact} - * @param location The location. - * @param encoding The encoding. - * @param fileMappers {@link FileMapper}s to be used for rewriting each target path, or {@code null} if no rewriting - * shall happen. - * @throws MojoExecutionException in case of an error. - */ - protected void unpack(Artifact artifact, File location, String encoding, FileMapper[] fileMappers) - throws MojoExecutionException { - unpack(artifact, location, null, null, encoding, fileMappers); - } - - /** - * Unpacks the archive file. - * - * @param artifact File to be unpacked. - * @param location Location where to put the unpacked files. - * @param includes Comma separated list of file patterns to include i.e. **/.xml, - * **/*.properties - * @param excludes Comma separated list of file patterns to exclude i.e. **/*.xml, - * **/*.properties - * @param encoding Encoding of artifact. Set {@code null} for default encoding. - * @param fileMappers {@link FileMapper}s to be used for rewriting each target path, or {@code null} if no rewriting - * shall happen. - * @throws MojoExecutionException In case of errors. - */ - protected void unpack( - Artifact artifact, - File location, - String includes, - String excludes, - String encoding, - FileMapper[] fileMappers) - throws MojoExecutionException { - unpack(artifact, artifact.getType(), location, includes, excludes, encoding, fileMappers); - } - - /** - * @param artifact {@link Artifact} - * @param type The type. - * @param location The location. - * @param includes includes list. - * @param excludes excludes list. - * @param encoding the encoding. - * @param fileMappers {@link FileMapper}s to be used for rewriting each target path, or {@code null} if no rewriting - * shall happen. - * @throws MojoExecutionException in case of an error. - */ - protected void unpack( - Artifact artifact, - String type, - File location, - String includes, - String excludes, - String encoding, - FileMapper[] fileMappers) - throws MojoExecutionException { - File file = artifact.getFile(); - try { - logUnpack(file, location, includes, excludes); - - location.mkdirs(); - if (!location.exists()) { - throw new MojoExecutionException( - "Location to write unpacked files to could not be created: " + location); - } - - if (file.isDirectory()) { - // usual case is a future jar packaging, but there are special cases: classifier and other packaging - throw new MojoExecutionException("Artifact has not been packaged yet. When used on reactor artifact, " - + "unpack should be executed after packaging: see MDEP-98."); - } - - UnArchiver unArchiver; - - try { - unArchiver = archiverManager.getUnArchiver(type); - getLog().debug("Found unArchiver by type: " + unArchiver); - } catch (NoSuchArchiverException e) { - unArchiver = archiverManager.getUnArchiver(file); - getLog().debug("Found unArchiver by extension: " + unArchiver); - } - - if (encoding != null && unArchiver instanceof ZipUnArchiver) { - ((ZipUnArchiver) unArchiver).setEncoding(encoding); - getLog().info("Unpacks '" + type + "' with encoding '" + encoding + "'."); - } - - unArchiver.setIgnorePermissions(ignorePermissions); - - unArchiver.setSourceFile(file); - - unArchiver.setDestDirectory(location); - - if (StringUtils.isNotEmpty(excludes) || StringUtils.isNotEmpty(includes)) { - // Create the selectors that will filter - // based on include/exclude parameters - // MDEP-47 - IncludeExcludeFileSelector[] selectors = - new IncludeExcludeFileSelector[] {new IncludeExcludeFileSelector()}; - - if (StringUtils.isNotEmpty(excludes)) { - selectors[0].setExcludes(excludes.split(",")); - } - - if (StringUtils.isNotEmpty(includes)) { - selectors[0].setIncludes(includes.split(",")); - } - - unArchiver.setFileSelectors(selectors); - } - if (this.silent) { - silenceUnarchiver(unArchiver); - } - - unArchiver.setFileMappers(fileMappers); - - unArchiver.extract(); - } catch (NoSuchArchiverException e) { - throw new MojoExecutionException("Unknown archiver type", e); - } catch (ArchiverException e) { - throw new MojoExecutionException("Error unpacking file: " + file + " to: " + location, e); - } - buildContext.refresh(location); - } - - private void silenceUnarchiver(UnArchiver unArchiver) { - // dangerous but handle any errors. It's the only way to silence the unArchiver. - try { - Field field = ReflectionUtils.getFieldByNameIncludingSuperclasses("logger", unArchiver.getClass()); - - field.setAccessible(true); - - field.set(unArchiver, this.getLog()); - } catch (Exception e) { - // was a nice try. Don't bother logging because the log is silent. - } - } - - /** - * @return Returns a new ProjectBuildingRequest populated from the current session and the current project remote - * repositories, used to resolve artifacts. - */ - public ProjectBuildingRequest newResolveArtifactProjectBuildingRequest() { - return newProjectBuildingRequest(remoteRepositories); - } - - /** - * @return Returns a new ProjectBuildingRequest populated from the current session and the current project remote - * repositories, used to resolve plugins. - */ - protected ProjectBuildingRequest newResolvePluginProjectBuildingRequest() { - return newProjectBuildingRequest(remotePluginRepositories); - } - - private ProjectBuildingRequest newProjectBuildingRequest(List repositories) { - ProjectBuildingRequest buildingRequest = new DefaultProjectBuildingRequest(session.getProjectBuildingRequest()); - - buildingRequest.setRemoteRepositories(repositories); - - return buildingRequest; - } - - /** - * @return Returns the project. + * @return returns the project */ public MavenProject getProject() { return this.project; } - /** - * @param archiverManager The archiverManager to set. - */ - public void setArchiverManager(ArchiverManager archiverManager) { - this.archiverManager = archiverManager; - } - - /** - * @return {@link #useJvmChmod} - */ - public boolean isUseJvmChmod() { - return useJvmChmod; - } - - /** - * @param useJvmChmod {@link #useJvmChmod} - */ - public void setUseJvmChmod(boolean useJvmChmod) { - this.useJvmChmod = useJvmChmod; - } - /** * @return {@link #skip} */ @@ -409,48 +136,24 @@ public void setSkip(boolean skip) { /** * @return {@link #silent} + * @deprecated to be removed in 4.0 */ + @Deprecated protected final boolean isSilent() { return silent; } /** * @param silent {@link #silent} + * @deprecated to be removed in 4.0; no API replacement, use -q command line option instead */ + @Deprecated public void setSilent(boolean silent) { this.silent = silent; if (silent) { setLog(new DependencySilentLog()); + } else if (getLog() instanceof DependencySilentLog) { + setLog(new SystemStreamLog()); } } - - private void logUnpack(File file, File location, String includes, String excludes) { - if (!getLog().isInfoEnabled()) { - return; - } - - StringBuilder msg = new StringBuilder(); - msg.append("Unpacking "); - msg.append(file); - msg.append(" to "); - msg.append(location); - - if (includes != null && excludes != null) { - msg.append(" with includes \""); - msg.append(includes); - msg.append("\" and excludes \""); - msg.append(excludes); - msg.append("\""); - } else if (includes != null) { - msg.append(" with includes \""); - msg.append(includes); - msg.append("\""); - } else if (excludes != null) { - msg.append(" with excludes \""); - msg.append(excludes); - msg.append("\""); - } - - getLog().info(msg.toString()); - } } diff --git a/src/main/java/org/apache/maven/plugins/dependency/DisplayAncestorsMojo.java b/src/main/java/org/apache/maven/plugins/dependency/DisplayAncestorsMojo.java index 248bef790..06f7f5a1b 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/DisplayAncestorsMojo.java +++ b/src/main/java/org/apache/maven/plugins/dependency/DisplayAncestorsMojo.java @@ -18,15 +18,16 @@ */ package org.apache.maven.plugins.dependency; +import javax.inject.Inject; + import java.util.ArrayList; import java.util.List; -import java.util.Locale; + import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; -import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.project.MavenProject; /** @@ -39,12 +40,13 @@ @Mojo(name = "display-ancestors", threadSafe = true, requiresProject = true, defaultPhase = LifecyclePhase.VALIDATE) public class DisplayAncestorsMojo extends AbstractMojo { - /** - * POM - */ - @Parameter(defaultValue = "${project}", readonly = true) private MavenProject project; + @Inject + public DisplayAncestorsMojo(MavenProject project) { + this.project = project; + } + @Override public void execute() throws MojoExecutionException, MojoFailureException { final List ancestors = collectAncestors(); @@ -61,14 +63,8 @@ private ArrayList collectAncestors() { MavenProject currentAncestor = project.getParent(); while (currentAncestor != null) { - final String gav = String.format( - Locale.US, - "%s:%s:%s", - currentAncestor.getGroupId(), - currentAncestor.getArtifactId(), - currentAncestor.getVersion()); - - ancestors.add(gav); + ancestors.add(currentAncestor.getGroupId() + ":" + currentAncestor.getArtifactId() + ":" + + currentAncestor.getVersion()); currentAncestor = currentAncestor.getParent(); } diff --git a/src/main/java/org/apache/maven/plugins/dependency/GetMojo.java b/src/main/java/org/apache/maven/plugins/dependency/GetMojo.java index 283c753c4..619c5986c 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/GetMojo.java +++ b/src/main/java/org/apache/maven/plugins/dependency/GetMojo.java @@ -18,11 +18,14 @@ */ package org.apache.maven.plugins.dependency; +import javax.inject.Inject; + import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; + import org.apache.maven.artifact.handler.ArtifactHandler; import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager; import org.apache.maven.artifact.repository.ArtifactRepository; @@ -33,7 +36,6 @@ import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; -import org.apache.maven.plugins.annotations.Component; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.project.DefaultProjectBuildingRequest; @@ -48,7 +50,6 @@ import org.apache.maven.shared.transfer.dependencies.DependableCoordinate; import org.apache.maven.shared.transfer.dependencies.resolve.DependencyResolver; import org.apache.maven.shared.transfer.dependencies.resolve.DependencyResolverException; -import org.codehaus.plexus.util.StringUtils; /** * Resolves a single artifact, eventually transitively, from the specified remote repositories. Caveat: will always @@ -58,67 +59,29 @@ public class GetMojo extends AbstractMojo { private static final Pattern ALT_REPO_SYNTAX_PATTERN = Pattern.compile("(.+)::(.*)::(.+)"); - @Parameter(defaultValue = "${session}", required = true, readonly = true) - private MavenSession session; + private final MavenSession session; - @Component - private ArtifactResolver artifactResolver; + private final ArtifactResolver artifactResolver; - @Component - private DependencyResolver dependencyResolver; + private final DependencyResolver dependencyResolver; - @Component - private ArtifactHandlerManager artifactHandlerManager; + private final ArtifactHandlerManager artifactHandlerManager; /** * Map that contains the layouts. */ - @Component(role = ArtifactRepositoryLayout.class) - private Map repositoryLayouts; + private final Map repositoryLayouts; /** * The repository system. */ - @Component - private RepositorySystem repositorySystem; - - private DefaultDependableCoordinate coordinate = new DefaultDependableCoordinate(); - - /** - * The groupId of the artifact to download. Ignored if {@link #artifact} is used. - */ - @Parameter(property = "groupId") - private String groupId; - - /** - * The artifactId of the artifact to download. Ignored if {@link #artifact} is used. - */ - @Parameter(property = "artifactId") - private String artifactId; - - /** - * The version of the artifact to download. Ignored if {@link #artifact} is used. - */ - @Parameter(property = "version") - private String version; - - /** - * The classifier of the artifact to download. Ignored if {@link #artifact} is used. - * - * @since 2.3 - */ - @Parameter(property = "classifier") - private String classifier; + private final RepositorySystem repositorySystem; - /** - * The packaging of the artifact to download. Ignored if {@link #artifact} is used. - */ - @Parameter(property = "packaging", defaultValue = "jar") - private String packaging = "jar"; + private final DefaultDependableCoordinate coordinate = new DefaultDependableCoordinate(); /** * Repositories in the format id::[layout]::url or just url, separated by comma. ie. - * central::default::https://repo.maven.apache.org/maven2,myrepo::::https://repo.acme.com,https://repo.acme2.com + * central::default::https://repo.maven.apache.org/maven2,myrepo::::https://repo.acme.com,https://repo.acme2.com. */ @Parameter(property = "remoteRepositories") private String remoteRepositories; @@ -129,14 +92,11 @@ public class GetMojo extends AbstractMojo { @Parameter(property = "artifact") private String artifact; - /** - * - */ @Parameter(defaultValue = "${project.remoteArtifactRepositories}", readonly = true, required = true) private List pomRemoteRepositories; /** - * Download transitively, retrieving the specified artifact and all of its dependencies. + * Resolve transitively, retrieving the specified artifact and all of its dependencies. */ @Parameter(property = "transitive", defaultValue = "true") private boolean transitive = true; @@ -149,6 +109,22 @@ public class GetMojo extends AbstractMojo { @Parameter(property = "mdep.skip", defaultValue = "false") private boolean skip; + @Inject + public GetMojo( + MavenSession session, + ArtifactResolver artifactResolver, + DependencyResolver dependencyResolver, + ArtifactHandlerManager artifactHandlerManager, + Map repositoryLayouts, + RepositorySystem repositorySystem) { + this.session = session; + this.artifactResolver = artifactResolver; + this.dependencyResolver = dependencyResolver; + this.artifactHandlerManager = artifactHandlerManager; + this.repositoryLayouts = repositoryLayouts; + this.repositorySystem = repositorySystem; + } + @Override public void execute() throws MojoExecutionException, MojoFailureException { if (isSkip()) { @@ -161,7 +137,7 @@ public void execute() throws MojoExecutionException, MojoFailureException { + "e.g. -Dartifact=org.apache.maven.plugins:maven-downloader-plugin:1.0"); } if (artifact != null) { - String[] tokens = StringUtils.split(artifact, ":"); + String[] tokens = artifact.split(":"); if (tokens.length < 3 || tokens.length > 5) { throw new MojoFailureException("Invalid artifact, you must specify " + "groupId:artifactId:version[:packaging[:classifier]] " + artifact); @@ -188,7 +164,7 @@ public void execute() throws MojoExecutionException, MojoFailureException { if (remoteRepositories != null) { // Use the same format as in the deploy plugin id::layout::url - String[] repos = StringUtils.split(remoteRepositories, ","); + String[] repos = remoteRepositories.split(","); for (String repo : repos) { repoList.add(parseRepository(repo, always)); } @@ -245,7 +221,7 @@ ArtifactRepository parseRepository(String repo, ArtifactRepositoryPolicy policy) } id = matcher.group(1).trim(); - if (!StringUtils.isEmpty(matcher.group(2))) { + if (matcher.group(2) != null && !matcher.group(2).isEmpty()) { layout = getLayout(matcher.group(2).trim()); } url = matcher.group(3).trim(); @@ -271,36 +247,52 @@ protected boolean isSkip() { } /** - * @param groupId The groupId. + * The groupId of the artifact to resolve. Ignored if {@link #artifact} is used. + * + * @param groupId the groupId */ + @Parameter(property = "groupId") public void setGroupId(String groupId) { this.coordinate.setGroupId(groupId); } /** - * @param artifactId The artifactId. + * The artifactId of the artifact to resolve. Ignored if {@link #artifact} is used. + * + * @param artifactId the artifactId */ + @Parameter(property = "artifactId") public void setArtifactId(String artifactId) { this.coordinate.setArtifactId(artifactId); } /** - * @param version The version. + * The version of the artifact to resolve. Ignored if {@link #artifact} is used. + * + * @param version the version */ + @Parameter(property = "version") public void setVersion(String version) { this.coordinate.setVersion(version); } /** - * @param classifier The classifier to be used. + * The classifier of the artifact to resolve. Ignored if {@link #artifact} is used. + * + * @param classifier the classifier to be used + * @since 2.3 */ + @Parameter(property = "classifier") public void setClassifier(String classifier) { this.coordinate.setClassifier(classifier); } /** - * @param type packaging. + * The packaging of the artifact to resolve. Ignored if {@link #artifact} is used. + * + * @param type packaging */ + @Parameter(property = "packaging", defaultValue = "jar") public void setPackaging(String type) { this.coordinate.setType(type); } diff --git a/src/main/java/org/apache/maven/plugins/dependency/ListClassesMojo.java b/src/main/java/org/apache/maven/plugins/dependency/ListClassesMojo.java index 18b11b0d1..15866fd8e 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/ListClassesMojo.java +++ b/src/main/java/org/apache/maven/plugins/dependency/ListClassesMojo.java @@ -18,161 +18,166 @@ */ package org.apache.maven.plugins.dependency; +import javax.inject.Inject; + +import java.io.File; import java.io.IOException; -import java.util.ArrayList; import java.util.Enumeration; import java.util.List; -import java.util.Map; import java.util.jar.JarEntry; import java.util.jar.JarFile; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import org.apache.maven.artifact.handler.ArtifactHandler; -import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager; -import org.apache.maven.artifact.repository.ArtifactRepository; -import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy; -import org.apache.maven.artifact.repository.MavenArtifactRepository; -import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout; -import org.apache.maven.execution.MavenSession; + import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; -import org.apache.maven.plugins.annotations.Component; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; -import org.apache.maven.project.DefaultProjectBuildingRequest; -import org.apache.maven.project.ProjectBuildingRequest; -import org.apache.maven.repository.RepositorySystem; -import org.apache.maven.settings.Settings; -import org.apache.maven.shared.transfer.artifact.ArtifactCoordinate; -import org.apache.maven.shared.transfer.artifact.DefaultArtifactCoordinate; -import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResolver; -import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResolverException; -import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult; -import org.apache.maven.shared.transfer.dependencies.DefaultDependableCoordinate; -import org.apache.maven.shared.transfer.dependencies.DependableCoordinate; -import org.apache.maven.shared.transfer.dependencies.resolve.DependencyResolver; -import org.apache.maven.shared.transfer.dependencies.resolve.DependencyResolverException; +import org.apache.maven.plugins.dependency.utils.ParamArtifact; +import org.apache.maven.plugins.dependency.utils.ResolverUtil; +import org.eclipse.aether.artifact.Artifact; +import org.eclipse.aether.resolution.ArtifactResolutionException; +import org.eclipse.aether.resolution.DependencyResolutionException; /** * Retrieves and lists all classes contained in the specified artifact from the specified remote repositories. + * + * @since 3.1.3 */ @Mojo(name = "list-classes", requiresProject = false, threadSafe = true) public class ListClassesMojo extends AbstractMojo { - private static final Pattern ALT_REPO_SYNTAX_PATTERN = Pattern.compile("(.+)::(.*)::(.+)"); - - @Parameter(defaultValue = "${session}", required = true, readonly = true) - private MavenSession session; - - @Component - private ArtifactResolver artifactResolver; - @Component - private DependencyResolver dependencyResolver; + private final ResolverUtil resolverUtil; - @Component - private ArtifactHandlerManager artifactHandlerManager; + private ParamArtifact paramArtifact = new ParamArtifact(); - /** - * Map that contains the layouts. - */ - @Component(role = ArtifactRepositoryLayout.class) - private Map repositoryLayouts; - - /** - * The repository system. - */ - @Component - private RepositorySystem repositorySystem; - - private DefaultDependableCoordinate coordinate = new DefaultDependableCoordinate(); + @Inject + public ListClassesMojo(ResolverUtil resolverUtil) { + this.resolverUtil = resolverUtil; + } /** - * The group ID of the artifact to download. Ignored if {@link #artifact} is used. + * The group ID of the artifact to download. Ignored if {@code artifact} is used. + * + * @since 3.1.3 */ @Parameter(property = "groupId") - private String groupId; + public void setGroupId(String groupId) { + paramArtifact.setGroupId(groupId); + } /** - * The artifact ID of the artifact to download. Ignored if {@link #artifact} is used. + * The artifact ID of the artifact to download. Ignored if {@code artifact} is used. + * + * @since 3.1.3 */ @Parameter(property = "artifactId") - private String artifactId; + public void setArtifactId(String artifactId) { + paramArtifact.setArtifactId(artifactId); + } /** - * The version of the artifact to download. Ignored if {@link #artifact} is used. + * The version of the artifact to download. Ignored if {@code artifact} is used. + * + * @since 3.1.3 */ @Parameter(property = "version") - private String version; + public void setVersion(String version) { + paramArtifact.setVersion(version); + } /** - * The classifier of the artifact to download. Ignored if {@link #artifact} is used. + * The classifier of the artifact to download. Ignored if {@code artifact} is used. * - * @since 2.3 + * @since 3.1.3 */ @Parameter(property = "classifier") - private String classifier; + public void setClassifier(String classifier) { + paramArtifact.setClassifier(classifier); + } /** - * The packaging of the artifact to download. Ignored if {@link #artifact} is used. + * The packaging of the artifact to download. Ignored if {@code artifact} is used. + * + * @since 3.1.3 */ @Parameter(property = "packaging", defaultValue = "jar") - private String packaging = "jar"; + public void setPackaging(String packaging) { + paramArtifact.setPackaging(packaging); + } /** - * Repositories in the format id::[layout]::url or just URLs, separated by comma. That is, - * central::default::https://repo.maven.apache.org/maven2,myrepo::::https://repo.acme.com,https://repo.acme2.com + * A string of the form {@code groupId:artifactId:version[:packaging[:classifier]]}. + * + * @since 3.1.3 */ - @Parameter(property = "remoteRepositories") - private String remoteRepositories; + @Parameter(property = "artifact") + public void setArtifact(String artifact) { + paramArtifact.setArtifact(artifact); + } /** - * A string of the form groupId:artifactId:version[:packaging[:classifier]]. + * Repositories in the format {@code id::[layout::]url} or just URLs. That is, + * + * central::default::https://repo.maven.apache.org/maven2,myrepo::https://repo.acme.com,https://repo.acme2.com + * + * + * @since 3.1.3 */ - @Parameter(property = "artifact") - private String artifact; - - @Parameter(defaultValue = "${project.remoteArtifactRepositories}", readonly = true, required = true) - private List pomRemoteRepositories; + @Parameter(property = "remoteRepositories") + private List remoteRepositories; /** * Download transitively, retrieving the specified artifact and all of its dependencies. + * + * @since 3.1.3 */ @Parameter(property = "transitive", defaultValue = "false") private boolean transitive = false; /** * Skip plugin execution completely. + * + * @since 3.6.0 */ @Parameter(property = "mdep.skip", defaultValue = "false") private boolean skip; @Override public void execute() throws MojoExecutionException, MojoFailureException { - ProjectBuildingRequest buildingRequest = makeBuildingRequest(); + if (skip) { + getLog().info("Skipping plugin execution"); + return; + } + + if (!paramArtifact.isDataSet()) { + throw new MojoExecutionException("You must specify an artifact OR GAV separately, " + + "e.g. -Dartifact=org.apache.maven.plugins:maven-downloader-plugin:1.0 OR " + + "-DgroupId=org.apache.maven.plugins -DartifactId=maven-downloader-plugin -Dversion=1.0"); + } + + Artifact artifact = resolverUtil.createArtifactFromParams(paramArtifact); try { if (transitive) { - Iterable artifacts = - dependencyResolver.resolveDependencies(buildingRequest, coordinate, null); + List artifacts = + resolverUtil.resolveDependencies(artifact, resolverUtil.remoteRepositories(remoteRepositories)); - for (ArtifactResult result : artifacts) { - printClassesFromArtifactResult(result); + for (Artifact a : artifacts) { + printClassesFromArtifactResult(a.getFile()); } } else { - ArtifactResult result = - artifactResolver.resolveArtifact(buildingRequest, toArtifactCoordinate(coordinate)); - - printClassesFromArtifactResult(result); + Artifact a = + resolverUtil.resolveArtifact(artifact, resolverUtil.remoteRepositories(remoteRepositories)); + printClassesFromArtifactResult(a.getFile()); } - } catch (ArtifactResolverException | DependencyResolverException | IOException e) { + } catch (IOException | ArtifactResolutionException | DependencyResolutionException e) { throw new MojoExecutionException("Couldn't download artifact: " + e.getMessage(), e); } } - private void printClassesFromArtifactResult(ArtifactResult result) throws IOException { + private void printClassesFromArtifactResult(File file) throws IOException { // open jar file in try-with-resources statement to guarantee the file closes after use regardless of errors - try (JarFile jarFile = new JarFile(result.getArtifact().getFile())) { + try (JarFile jarFile = new JarFile(file)) { Enumeration entries = jarFile.entries(); while (entries.hasMoreElements()) { @@ -191,100 +196,4 @@ private void printClassesFromArtifactResult(ArtifactResult result) throws IOExce } } } - - private ProjectBuildingRequest makeBuildingRequest() throws MojoExecutionException, MojoFailureException { - if (artifact == null) { - throw new MojoFailureException("You must specify an artifact, " - + "e.g. -Dartifact=org.apache.maven.plugins:maven-downloader-plugin:1.0"); - } - - String[] tokens = artifact.split(":"); - if (tokens.length < 3 || tokens.length > 5) { - throw new MojoFailureException("Invalid artifact, you must specify " - + "groupId:artifactId:version[:packaging[:classifier]] " + artifact); - } - coordinate.setGroupId(tokens[0]); - coordinate.setArtifactId(tokens[1]); - coordinate.setVersion(tokens[2]); - if (tokens.length >= 4) { - coordinate.setType(tokens[3]); - } - if (tokens.length == 5) { - coordinate.setClassifier(tokens[4]); - } - - ArtifactRepositoryPolicy always = new ArtifactRepositoryPolicy( - true, ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS, ArtifactRepositoryPolicy.CHECKSUM_POLICY_WARN); - - List repoList = new ArrayList<>(); - - if (pomRemoteRepositories != null) { - repoList.addAll(pomRemoteRepositories); - } - - if (remoteRepositories != null) { - // Use the same format as in the deploy plugin id::layout::url - String[] repos = remoteRepositories.split(","); - for (String repo : repos) { - repoList.add(parseRepository(repo, always)); - } - } - - ProjectBuildingRequest buildingRequest = new DefaultProjectBuildingRequest(session.getProjectBuildingRequest()); - - Settings settings = session.getSettings(); - repositorySystem.injectMirror(repoList, settings.getMirrors()); - repositorySystem.injectProxy(repoList, settings.getProxies()); - repositorySystem.injectAuthentication(repoList, settings.getServers()); - - buildingRequest.setRemoteRepositories(repoList); - - return buildingRequest; - } - - private ArtifactCoordinate toArtifactCoordinate(DependableCoordinate dependableCoordinate) { - ArtifactHandler artifactHandler = artifactHandlerManager.getArtifactHandler(dependableCoordinate.getType()); - DefaultArtifactCoordinate artifactCoordinate = new DefaultArtifactCoordinate(); - artifactCoordinate.setGroupId(dependableCoordinate.getGroupId()); - artifactCoordinate.setArtifactId(dependableCoordinate.getArtifactId()); - artifactCoordinate.setVersion(dependableCoordinate.getVersion()); - artifactCoordinate.setClassifier(dependableCoordinate.getClassifier()); - artifactCoordinate.setExtension(artifactHandler.getExtension()); - return artifactCoordinate; - } - - protected ArtifactRepository parseRepository(String repo, ArtifactRepositoryPolicy policy) - throws MojoFailureException { - // if it's a simple url - String id = "temp"; - ArtifactRepositoryLayout layout = getLayout("default"); - - // if it's an extended repo URL of the form id::layout::url - if (repo.contains("::")) { - Matcher matcher = ALT_REPO_SYNTAX_PATTERN.matcher(repo); - if (!matcher.matches()) { - throw new MojoFailureException( - repo, - "Invalid syntax for repository: " + repo, - "Invalid syntax for repository. Use \"id::layout::url\" or \"URL\"."); - } - - id = matcher.group(1).trim(); - if (!(matcher.group(2) == null || matcher.group(2).trim().isEmpty())) { - layout = getLayout(matcher.group(2).trim()); - } - repo = matcher.group(3).trim(); - } - return new MavenArtifactRepository(id, repo, layout, policy, policy); - } - - private ArtifactRepositoryLayout getLayout(String id) throws MojoFailureException { - ArtifactRepositoryLayout layout = repositoryLayouts.get(id); - - if (layout == null) { - throw new MojoFailureException(id, "Invalid repository layout", "Invalid repository layout: " + id); - } - - return layout; - } } diff --git a/src/main/java/org/apache/maven/plugins/dependency/ListRepositoriesMojo.java b/src/main/java/org/apache/maven/plugins/dependency/ListRepositoriesMojo.java new file mode 100644 index 000000000..01b9cc21c --- /dev/null +++ b/src/main/java/org/apache/maven/plugins/dependency/ListRepositoriesMojo.java @@ -0,0 +1,173 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.maven.plugins.dependency; + +import javax.inject.Inject; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +import org.apache.maven.RepositoryUtils; +import org.apache.maven.execution.MavenSession; +import org.apache.maven.model.DependencyManagement; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.project.MavenProject; +import org.eclipse.aether.RepositorySystem; +import org.eclipse.aether.artifact.ArtifactTypeRegistry; +import org.eclipse.aether.collection.CollectRequest; +import org.eclipse.aether.collection.CollectResult; +import org.eclipse.aether.collection.DependencyCollectionException; +import org.eclipse.aether.graph.DependencyNode; +import org.eclipse.aether.graph.DependencyVisitor; +import org.eclipse.aether.repository.RemoteRepository; +import org.eclipse.aether.util.graph.visitor.TreeDependencyVisitor; +import org.sonatype.plexus.build.incremental.BuildContext; + +/** + * Goal that collects all project dependencies and then lists the repositories used by the build and by the transitive + * dependencies. + * + * @author Brian Fox + * @since 2.2 + */ +@Mojo(name = "list-repositories", threadSafe = true) +public class ListRepositoriesMojo extends AbstractDependencyMojo { + + private final RepositorySystem repositorySystem; + + @Inject + public ListRepositoriesMojo( + MavenSession session, BuildContext buildContext, MavenProject project, RepositorySystem repositorySystem) { + super(session, buildContext, project); + this.repositorySystem = repositorySystem; + } + + /** + * Displays a list of the repositories used by this build. + * + * @throws MojoExecutionException with a message if an error occurs + */ + @Override + protected void doExecute() throws MojoExecutionException { + + CollectRequest request = new CollectRequest(); + request.setRepositories(getProject().getRemoteProjectRepositories()); + request.setRootArtifact(RepositoryUtils.toArtifact(getProject().getArtifact())); + + ArtifactTypeRegistry artifactTypeRegistry = + session.getRepositorySession().getArtifactTypeRegistry(); + + request.setDependencies(getProject().getDependencies().stream() + .map(d -> RepositoryUtils.toDependency(d, artifactTypeRegistry)) + .collect(Collectors.toList())); + + request.setManagedDependencies(Optional.ofNullable(getProject().getDependencyManagement()) + .map(DependencyManagement::getDependencies) + .orElseGet(Collections::emptyList) + .stream() + .map(d -> RepositoryUtils.toDependency(d, artifactTypeRegistry)) + .collect(Collectors.toList())); + + try { + CollectResult collectResult = repositorySystem.collectDependencies(session.getRepositorySession(), request); + Set repositories = new HashSet<>(); + collectResult.getRoot().accept(new TreeDependencyVisitor(new DependencyVisitor() { + @Override + public boolean visitEnter(DependencyNode node) { + repositories.addAll(node.getRepositories()); + debugLogNodeRepo(node); + return true; + } + + @Override + public boolean visitLeave(DependencyNode node) { + return true; + } + })); + + if (repositories.isEmpty()) { + getLog().info("No remote repository is used by this build." + System.lineSeparator()); + return; + } + + StringBuilder message = new StringBuilder(); + + Map> repoGroupByMirrors = repositories.stream() + .collect(Collectors.groupingBy( + repo -> repo.getMirroredRepositories().isEmpty())); + + prepareRemoteRepositoriesList( + message, repoGroupByMirrors.getOrDefault(Boolean.TRUE, Collections.emptyList())); + prepareRemoteMirrorRepositoriesList( + message, repoGroupByMirrors.getOrDefault(Boolean.FALSE, Collections.emptyList())); + + getLog().info(message); + + } catch (DependencyCollectionException e) { + throw new MojoExecutionException(e.getMessage(), e); + } + } + + private void debugLogNodeRepo(DependencyNode node) { + if (!getLog().isDebugEnabled()) { + return; + } + + getLog().debug("Node: " + node + " resolved from:"); + node.getRepositories().forEach(repo -> { + if (repo.getMirroredRepositories().isEmpty()) { + getLog().debug(" - " + repo); + } else { + getLog().debug(" - " + repo + " as mirror for:"); + repo.getMirroredRepositories().forEach(mrepo -> getLog().debug(" - " + mrepo)); + } + }); + } + + private void prepareRemoteMirrorRepositoriesList( + StringBuilder message, Collection remoteProjectRepositories) { + + Map mirrorMap = new HashMap<>(); + remoteProjectRepositories.forEach( + repo -> repo.getMirroredRepositories().forEach(mrepo -> mirrorMap.put(mrepo, repo))); + + mirrorMap.forEach((repo, mirror) -> message.append(" * ") + .append(repo) + .append(" mirrored by ") + .append(mirror) + .append(System.lineSeparator())); + } + + private void prepareRemoteRepositoriesList( + StringBuilder message, Collection remoteProjectRepositories) { + + message.append("Project remote repositories used by this build:").append(System.lineSeparator()); + + remoteProjectRepositories.forEach( + repo -> message.append(" * ").append(repo).append(System.lineSeparator())); + } +} diff --git a/src/main/java/org/apache/maven/plugins/dependency/PropertiesMojo.java b/src/main/java/org/apache/maven/plugins/dependency/PropertiesMojo.java index 54c0eeee6..22f0d8357 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/PropertiesMojo.java +++ b/src/main/java/org/apache/maven/plugins/dependency/PropertiesMojo.java @@ -18,7 +18,10 @@ */ package org.apache.maven.plugins.dependency; +import javax.inject.Inject; + import java.util.Set; + import org.apache.maven.artifact.Artifact; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; @@ -46,10 +49,14 @@ public class PropertiesMojo extends AbstractMojo { /** - * The current Maven project + * The current Maven project. */ - @Parameter(defaultValue = "${project}", readonly = true, required = true) - private MavenProject project; + private final MavenProject project; + + @Inject + public PropertiesMojo(MavenProject project) { + this.project = project; + } /** * Skip plugin execution completely. @@ -62,7 +69,7 @@ public class PropertiesMojo extends AbstractMojo { /** * Main entry into mojo. Gets the list of dependencies and iterates through setting a property for each artifact. * - * @throws MojoExecutionException with a message if an error occurs. + * @throws MojoExecutionException with a message if an error occurs */ @Override public void execute() throws MojoExecutionException { diff --git a/src/main/java/org/apache/maven/plugins/dependency/PurgeLocalRepositoryMojo.java b/src/main/java/org/apache/maven/plugins/dependency/PurgeLocalRepositoryMojo.java index 01be06394..c5cfc6e85 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/PurgeLocalRepositoryMojo.java +++ b/src/main/java/org/apache/maven/plugins/dependency/PurgeLocalRepositoryMojo.java @@ -18,6 +18,8 @@ */ package org.apache.maven.plugins.dependency; +import javax.inject.Inject; + import java.io.File; import java.io.IOException; import java.util.ArrayList; @@ -26,6 +28,7 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Set; + import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.ArtifactUtils; import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager; @@ -39,7 +42,6 @@ import org.apache.maven.plugin.MojoExecution.Source; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; -import org.apache.maven.plugins.annotations.Component; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.project.MavenProject; @@ -61,7 +63,6 @@ import org.apache.maven.shared.utils.logging.MessageBuilder; import org.apache.maven.shared.utils.logging.MessageUtils; import org.codehaus.plexus.util.FileUtils; -import org.codehaus.plexus.util.StringUtils; /** * When run on a project, remove the project dependencies from the local repository, and optionally re-resolve them. @@ -80,31 +81,38 @@ public class PurgeLocalRepositoryMojo extends AbstractMojo { private static final String GROUP_ID_FUZZINESS = "groupId"; /** - * The Maven projects in the reactor. + * The current Maven project. */ - @Parameter(defaultValue = "${reactorProjects}", readonly = true, required = true) - private List reactorProjects; + private final MavenProject project; + + private final MavenSession session; /** - * The current Maven project. + * Artifact handler manager. */ - @Parameter(defaultValue = "${project}", readonly = true, required = true) - private MavenProject project; + private final ArtifactHandlerManager artifactHandlerManager; - @Parameter(defaultValue = "${session}", readonly = true, required = true) - private MavenSession session; + /** + * The dependency resolver. + */ + private final DependencyResolver dependencyResolver; /** - * This mojo execution, used to determine if it was launched from the lifecycle or the command-line. + * The artifact resolver used to re-resolve dependencies, if that option is enabled. */ - @Parameter(defaultValue = "${mojo}", required = true, readonly = true) - private MojoExecution mojoExecution; + private final ArtifactResolver artifactResolver; /** - * Artifact handler manager. + * The Maven projects in the reactor. */ - @Component - private ArtifactHandlerManager artifactHandlerManager; + @Parameter(defaultValue = "${reactorProjects}", readonly = true, required = true) + private List reactorProjects; + + /** + * This mojo execution, used to determine if it was launched from the lifecycle or the command-line. + */ + @Parameter(defaultValue = "${mojo}", required = true, readonly = true) + private MojoExecution mojoExecution; /** * The list of dependencies in the form of groupId:artifactId which should BE deleted/purged from the local @@ -172,18 +180,6 @@ public class PurgeLocalRepositoryMojo extends AbstractMojo { @Parameter(defaultValue = "${localRepository}", readonly = true, required = true) private ArtifactRepository localRepository; - /** - * The dependency resolver - */ - @Component - private DependencyResolver dependencyResolver; - - /** - * The artifact resolver used to re-resolve dependencies, if that option is enabled. - */ - @Component - private ArtifactResolver artifactResolver; - /** * Determines how liberally the plugin will delete an artifact from the local repository. Values are:
*
    @@ -224,6 +220,20 @@ public class PurgeLocalRepositoryMojo extends AbstractMojo { @Parameter(property = "skip", defaultValue = "false") private boolean skip; + @Inject + public PurgeLocalRepositoryMojo( + MavenProject project, + MavenSession session, + ArtifactHandlerManager artifactHandlerManager, + DependencyResolver dependencyResolver, + ArtifactResolver artifactResolver) { + this.session = session; + this.project = project; + this.artifactHandlerManager = artifactHandlerManager; + this.dependencyResolver = dependencyResolver; + this.artifactResolver = artifactResolver; + } + /** * Includes only direct project dependencies. */ @@ -233,9 +243,9 @@ private class DirectDependencyFilter extends AbstractFilter { private final List directDependencies; /** - * Default constructor + * Default constructor. * - * @param directDependencies Set of dependencies objects which represent the direct dependencies of the project + * @param directDependencies set of dependencies objects which represent the direct dependencies of the project */ DirectDependencyFilter(Artifact projectArtifact, List directDependencies) { this.projectArtifact = projectArtifact; @@ -277,7 +287,7 @@ private boolean artifactsGAMatch(Node node, String groupId, String artifactId) { } /** - * Includes only snapshot artifacts + * Includes only snapshot artifacts. */ private static class SnapshotsFilter extends AbstractFilter { @Override @@ -297,11 +307,11 @@ public void execute() throws MojoExecutionException, MojoFailureException { return; } - if (!StringUtils.isEmpty(manualInclude)) { + if (!(manualInclude == null || manualInclude.isEmpty())) { manualIncludes = this.parseIncludes(manualInclude); } // If it's a manual purge, the only step is to delete from the local repo - if (manualIncludes != null && manualIncludes.size() > 0) { + if (manualIncludes != null && !manualIncludes.isEmpty()) { manualPurge(manualIncludes); return; } @@ -320,7 +330,7 @@ public void execute() throws MojoExecutionException, MojoFailureException { * Determines if all projects in the reactor should be purged from their dependencies. When this goal is started on * the command-line, it is always the case. When it is bound to a phase in the lifecycle, it is never the case. * - * @return true if all projects in the reactor should be purged, false otherwise. + * @return true if all projects in the reactor should be purged, false otherwise */ private boolean shouldPurgeAllProjectsInReactor() { Source source = mojoExecution.getSource(); @@ -330,9 +340,9 @@ private boolean shouldPurgeAllProjectsInReactor() { /** * Purges the local repository for the dependencies in the given Maven project. * - * @param theProject Maven project. - * @param purgedArtifacts The artifacts that were already purged. - * @throws MojoFailureException in case of errors during the purge. + * @param theProject maven project + * @param purgedArtifacts the artifacts that were already purged + * @throws MojoFailureException in case of errors during the purge */ private void purgeLocalRepository(MavenProject theProject, Set purgedArtifacts) throws MojoFailureException { @@ -365,8 +375,8 @@ private void purgeLocalRepository(MavenProject theProject, Set purgedA /** * Purge/Delete artifacts from the local repository according to the given patterns. * - * @param theIncludes The includes. - * @throws MojoExecutionException in case of an error. + * @param theIncludes the includes + * @throws MojoExecutionException in case of an error */ private void manualPurge(List theIncludes) throws MojoExecutionException { MessageBuilder messageBuilder = MessageUtils.buffer(); @@ -378,16 +388,16 @@ private void manualPurge(List theIncludes) throws MojoExecutionException .a(theIncludes.size() != 1 ? "dependencies" : "dependency") .a(" from ") .strong(localRepository.getBasedir()) - .toString()); + .build()); for (String gavPattern : theIncludes) { - if (StringUtils.isEmpty(gavPattern)) { + if (gavPattern == null || gavPattern.isEmpty()) { getLog().debug("Skipping empty gav pattern"); continue; } String relativePath = gavToPath(gavPattern); - if (StringUtils.isEmpty(relativePath)) { + if (relativePath == null || relativePath.isEmpty()) { getLog().debug("Skipping empty relative path for gav pattern: " + gavPattern); continue; } @@ -407,13 +417,13 @@ private void manualPurge(List theIncludes) throws MojoExecutionException } /** - * Convert a groupId:artifactId:version to a file system path + * Convert a groupId:artifactId:version to a file system path. * * @param gav the groupId:artifactId:version string * @return the corresponding path */ private String gavToPath(String gav) { - if (StringUtils.isEmpty(gav)) { + if (gav == null || gav.isEmpty()) { return null; } @@ -430,11 +440,11 @@ private String gavToPath(String gav) { /** * Create the includes exclude filter to use when resolving and purging dependencies Also excludes any "system" - * scope dependencies + * scope dependencies. * - * @param theProject The Maven project. - * @param dependencies The dependencies to use as a reference if we're excluding transitive dependencies - * @param purgedArtifacts The artifacts already purged. + * @param theProject the Maven project + * @param dependencies the dependencies to use as a reference if we're excluding transitive dependencies + * @param purgedArtifacts the artifacts already purged * @return the created filter */ private TransformableFilter createPurgeArtifactsFilter( @@ -449,14 +459,14 @@ private TransformableFilter createPurgeArtifactsFilter( } // The CLI includes/excludes overrides configuration in the pom - if (!StringUtils.isEmpty(this.include)) { + if (!(this.include == null || this.include.isEmpty())) { this.includes = parseIncludes(this.include); } if (this.includes != null) { subFilters.add(new PatternInclusionsFilter(includes)); } - if (!StringUtils.isEmpty(this.exclude)) { + if (!(this.exclude == null || this.exclude.isEmpty())) { this.excludes = parseIncludes(this.exclude); } if (this.excludes != null) { @@ -484,8 +494,8 @@ private TransformableFilter createPurgeArtifactsFilter( /** * Returns a string that represents a pattern for an exclude filter for the given artifact. * - * @param artifact Artifact. - * @return String representation of a pattern for an exclude filter for the given artifact. + * @param artifact artifact + * @return string representation of a pattern for an exclude filter for the given artifact */ private String toPatternExcludes(Artifact artifact) { return artifact.getGroupId() + ":" + artifact.getArtifactId() + ":" @@ -493,9 +503,9 @@ private String toPatternExcludes(Artifact artifact) { } /** - * Convert comma separated list of includes to List object + * Convert comma separated list of includes to List object. * - * @param theInclude The list of includes + * @param theInclude the list of includes * @return the includes list */ private List parseIncludes(String theInclude) { @@ -569,7 +579,7 @@ private void purgeArtifacts(MavenProject theProject, Set artifacts) { .a(" with artifact ") .strong(resolutionFuzziness) .a(" resolution fuzziness") - .toString()); + .build()); for (Artifact artifact : artifacts) { verbose("Purging artifact: " + artifact.getId()); @@ -622,7 +632,7 @@ private void reResolveArtifacts(MavenProject theProject, Set artifacts } } - if (missingArtifacts.size() > 0) { + if (!missingArtifacts.isEmpty()) { StringBuilder message = new StringBuilder("required artifacts missing:"); message.append(System.lineSeparator()); for (Artifact missingArtifact : missingArtifacts) { diff --git a/src/main/java/org/apache/maven/plugins/dependency/analyze/AbstractAnalyzeMojo.java b/src/main/java/org/apache/maven/plugins/dependency/analyze/AbstractAnalyzeMojo.java index fe6e19c3e..ac79d7178 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/analyze/AbstractAnalyzeMojo.java +++ b/src/main/java/org/apache/maven/plugins/dependency/analyze/AbstractAnalyzeMojo.java @@ -28,6 +28,7 @@ import java.util.List; import java.util.Map; import java.util.Set; + import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.resolver.filter.ArtifactFilter; import org.apache.maven.plugin.AbstractMojo; @@ -39,11 +40,8 @@ import org.apache.maven.shared.dependency.analyzer.ProjectDependencyAnalysis; import org.apache.maven.shared.dependency.analyzer.ProjectDependencyAnalyzer; import org.apache.maven.shared.dependency.analyzer.ProjectDependencyAnalyzerException; -import org.apache.maven.shared.utils.StringUtils; -import org.codehaus.plexus.PlexusConstants; import org.codehaus.plexus.PlexusContainer; -import org.codehaus.plexus.context.Context; -import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable; +import org.codehaus.plexus.component.repository.exception.ComponentLookupException; import org.codehaus.plexus.util.xml.PrettyPrintXMLWriter; /** @@ -53,21 +51,9 @@ * @author Mark Hobson * @since 2.0-alpha-5 */ -public abstract class AbstractAnalyzeMojo extends AbstractMojo implements Contextualizable { +public abstract class AbstractAnalyzeMojo extends AbstractMojo { // fields ----------------------------------------------------------------- - /** - * The plexus context to look-up the right {@link ProjectDependencyAnalyzer} implementation depending on the mojo - * configuration. - */ - private Context context; - - /** - * The Maven project to analyze. - */ - @Parameter(defaultValue = "${project}", readonly = true, required = true) - private MavenProject project; - /** * Specify the project dependency analyzer to use (plexus component role-hint). By default, * maven-dependency-analyzer is used. To use this, you must declare @@ -92,15 +78,15 @@ public abstract class AbstractAnalyzeMojo extends AbstractMojo implements Contex private boolean verbose; /** - * Ignore Runtime/Provided/Test/System scopes for unused dependency analysis. - * + * Ignore runtime/provided/test/system scopes for unused dependency analysis. + *

    * Non-test scoped list will be not affected. */ @Parameter(property = "ignoreNonCompile", defaultValue = "false") private boolean ignoreNonCompile; /** - * Ignore Runtime scope for unused dependency analysis. + * Ignore runtime scope for unused dependency analysis. * * @since 3.2.0 */ @@ -143,7 +129,7 @@ public abstract class AbstractAnalyzeMojo extends AbstractMojo implements Contex private String scriptableFlag; /** - * Flag to use for scriptable output + * Flag to use for scriptable output. * * @since 2.0-alpha-5 */ @@ -151,7 +137,7 @@ public abstract class AbstractAnalyzeMojo extends AbstractMojo implements Contex private File baseDir; /** - * Target folder + * Target folder. * * @since 2.0-alpha-5 */ @@ -215,7 +201,7 @@ public abstract class AbstractAnalyzeMojo extends AbstractMojo implements Contex private String[] ignoredUsedUndeclaredDependencies = new String[0]; /** - * List of dependencies that will be ignored if they are declared but unused. The filter syntax is: + * List of dependencies that are ignored if they are declared but unused. The filter syntax is: * *

          * [groupId]:[artifactId]:[type]:[version]
    @@ -224,17 +210,22 @@ public abstract class AbstractAnalyzeMojo extends AbstractMojo implements Contex
          * where each pattern segment is optional and supports full and partial * wildcards. An empty pattern
          * segment is treated as an implicit wildcard. *
          * 

    - * For example, org.apache.* will match all artifacts whose group id starts with - * org.apache., and :::*-SNAPSHOT will match all snapshot artifacts. + * For example, org.apache.* matches all artifacts whose group id starts with + * org.apache., and :::*-SNAPSHOT matches all snapshot artifacts. *

    * + *

    Certain dependencies that are known to be used and loaded by reflection + * are always ignored. This includes {@code org.slf4j:slf4j-simple::}.

    + * * @since 2.10 */ @Parameter private String[] ignoredUnusedDeclaredDependencies = new String[0]; + private String[] unconditionallyIgnoredDeclaredDependencies = {"org.slf4j:slf4j-simple::"}; + /** - * List of dependencies that will be ignored if they are in not test scope but are only used in test classes. + * List of dependencies that are ignored if they are in not test scope but are only used in test classes. * The filter syntax is: * *
    @@ -244,14 +235,14 @@ public abstract class AbstractAnalyzeMojo extends AbstractMojo implements Contex
          * where each pattern segment is optional and supports full and partial * wildcards. An empty pattern
          * segment is treated as an implicit wildcard. *
          * 

    - * For example, org.apache.* will match all artifacts whose group id starts with + * For example, org.apache.* matched all artifacts whose group id starts with * org.apache., and :::*-SNAPSHOT will match all snapshot artifacts. *

    * * @since 3.3.0 */ - @Parameter - private String[] ignoredNonTestScopedDependencies = new String[0]; + @Parameter(defaultValue = "org.slf4j:slf4j-simple::") + private String[] ignoredNonTestScopedDependencies; /** * List of project packaging that will be ignored. @@ -260,10 +251,32 @@ public abstract class AbstractAnalyzeMojo extends AbstractMojo implements Contex * * @since 3.2.1 */ - // defaultValue value on @Parameter - not work with Maven 3.2.5 - // When is set defaultValue always win, and there is no possibility to override by plugin configuration. - @Parameter - private List ignoredPackagings = Arrays.asList("pom", "ear"); + @Parameter(defaultValue = "pom,ear") + private List ignoredPackagings; + + /** + * List of class patterns excluded from analyze. Java regular expression pattern is applied to full class name. + * + * @since 3.7.0 + */ + @Parameter(property = "mdep.analyze.excludedClasses") + private Set excludedClasses; + + /** + * The plexusContainer to look up the {@link ProjectDependencyAnalyzer} implementation depending on the mojo + * configuration. + */ + private final PlexusContainer plexusContainer; + + /** + * The Maven project to analyze. + */ + private final MavenProject project; + + protected AbstractAnalyzeMojo(PlexusContainer plexusContainer, MavenProject project) { + this.plexusContainer = plexusContainer; + this.project = project; + } // Mojo methods ----------------------------------------------------------- @@ -296,23 +309,18 @@ public void execute() throws MojoExecutionException, MojoFailureException { /** * @return {@link ProjectDependencyAnalyzer} - * @throws MojoExecutionException in case of an error. + * @throws MojoExecutionException in case of an error */ protected ProjectDependencyAnalyzer createProjectDependencyAnalyzer() throws MojoExecutionException { + try { - final PlexusContainer container = (PlexusContainer) context.get(PlexusConstants.PLEXUS_KEY); - return container.lookup(ProjectDependencyAnalyzer.class, analyzer); - } catch (Exception exception) { + return plexusContainer.lookup(ProjectDependencyAnalyzer.class, analyzer); + } catch (ComponentLookupException exception) { throw new MojoExecutionException( "Failed to instantiate ProjectDependencyAnalyser" + " / role-hint " + analyzer, exception); } } - @Override - public void contextualize(Context theContext) { - this.context = theContext; - } - /** * @return {@link #skip} */ @@ -325,7 +333,7 @@ protected final boolean isSkip() { private boolean checkDependencies() throws MojoExecutionException { ProjectDependencyAnalysis analysis; try { - analysis = createProjectDependencyAnalyzer().analyze(project); + analysis = createProjectDependencyAnalyzer().analyze(project, excludedClasses); if (usedDependencies != null) { analysis = analysis.forceDeclaredDependenciesUsage(usedDependencies); @@ -358,6 +366,7 @@ private boolean checkDependencies() throws MojoExecutionException { ignoredUnusedDeclared.addAll(filterDependencies(unusedDeclared, ignoredDependencies)); ignoredUnusedDeclared.addAll(filterDependencies(unusedDeclared, ignoredUnusedDeclaredDependencies)); + ignoredUnusedDeclared.addAll(filterDependencies(unusedDeclared, unconditionallyIgnoredDeclaredDependencies)); if (ignoreAllNonTestScoped) { ignoredNonTestScope.addAll(filterDependencies(nonTestScope, new String[] {"*"})); @@ -380,7 +389,7 @@ private boolean checkDependencies() throws MojoExecutionException { logDependencyWarning("Used undeclared dependencies found:"); if (verbose) { - logArtifacts(usedUndeclaredWithClasses, true); + logArtifacts(usedUndeclaredWithClasses); } else { logArtifacts(usedUndeclaredWithClasses.keySet(), true); } @@ -461,7 +470,7 @@ private void logArtifacts(Set artifacts, boolean warn) { } } - private void logArtifacts(Map> artifacts, boolean warn) { + private void logArtifacts(Map> artifacts) { if (artifacts.isEmpty()) { getLog().info(" None"); } else { @@ -469,16 +478,9 @@ private void logArtifacts(Map> artifacts, boolean warn) { // called because artifact will set the version to -SNAPSHOT only if I do this. MNG-2961 entry.getKey().isSnapshot(); - if (warn) { - logDependencyWarning(" " + entry.getKey()); - for (String clazz : entry.getValue()) { - logDependencyWarning(" class " + clazz); - } - } else { - getLog().info(" " + entry.getKey()); - for (String clazz : entry.getValue()) { - getLog().info(" class " + clazz); - } + logDependencyWarning(" " + entry.getKey()); + for (String clazz : entry.getValue()) { + logDependencyWarning(" class " + clazz); } } } @@ -500,9 +502,6 @@ private void writeDependencyXML(Set artifacts) { PrettyPrintXMLWriter writer = new PrettyPrintXMLWriter(out); for (Artifact artifact : artifacts) { - // called because artifact will set the version to -SNAPSHOT only if I do this. MNG-2961 - artifact.isSnapshot(); - writer.startElement("dependency"); writer.startElement("groupId"); writer.writeText(artifact.getGroupId()); @@ -513,7 +512,7 @@ private void writeDependencyXML(Set artifacts) { writer.startElement("version"); writer.writeText(artifact.getBaseVersion()); String classifier = artifact.getClassifier(); - if (StringUtils.isNotBlank(classifier)) { + if (classifier != null && !classifier.trim().isEmpty()) { writer.startElement("classifier"); writer.writeText(artifact.getClassifier()); writer.endElement(); diff --git a/src/main/java/org/apache/maven/plugins/dependency/analyze/AnalyzeDepMgt.java b/src/main/java/org/apache/maven/plugins/dependency/analyze/AnalyzeDepMgt.java index afb52f999..1df1d74a4 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/analyze/AnalyzeDepMgt.java +++ b/src/main/java/org/apache/maven/plugins/dependency/analyze/AnalyzeDepMgt.java @@ -18,6 +18,8 @@ */ package org.apache.maven.plugins.dependency.analyze; +import javax.inject.Inject; + import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashSet; @@ -25,6 +27,7 @@ import java.util.Map; import java.util.Set; import java.util.stream.Collectors; + import org.apache.maven.artifact.Artifact; import org.apache.maven.model.Dependency; import org.apache.maven.model.DependencyManagement; @@ -36,7 +39,6 @@ import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.plugins.annotations.ResolutionScope; import org.apache.maven.project.MavenProject; -import org.codehaus.plexus.util.StringUtils; /** * This mojo looks at the dependencies after final resolution and looks for mismatches in your dependencyManagement @@ -50,11 +52,7 @@ public class AnalyzeDepMgt extends AbstractMojo { // fields ----------------------------------------------------------------- - /** - * - */ - @Parameter(defaultValue = "${project}", readonly = true, required = true) - private MavenProject project; + private final MavenProject project; /** * Fail the build if a problem is detected. @@ -76,6 +74,11 @@ public class AnalyzeDepMgt extends AbstractMojo { @Parameter(property = "mdep.analyze.skip", defaultValue = "false") private boolean skip; + @Inject + public AnalyzeDepMgt(MavenProject project) { + this.project = project; + } + // Mojo methods ----------------------------------------------------------- /* @@ -102,7 +105,7 @@ public void execute() throws MojoExecutionException, MojoFailureException { /** * Does the work of checking the DependencyManagement Section. * - * @return true if errors are found. + * @return true if errors are found * @throws MojoExecutionException */ private boolean checkDependencyManagement() throws MojoExecutionException { @@ -142,7 +145,7 @@ private boolean checkDependencyManagement() throws MojoExecutionException { // log exclusion errors List exclusionErrors = getExclusionErrors(exclusions, allDependencyArtifacts); for (Artifact exclusion : exclusionErrors) { - getLog().info(StringUtils.stripEnd(getArtifactManagementKey(exclusion), ":") + getLog().info(getArtifactManagementKey(exclusion) + " was excluded in DepMgt, but version " + exclusion.getVersion() + " has been found in the dependency tree."); foundError = true; @@ -167,8 +170,8 @@ private boolean checkDependencyManagement() throws MojoExecutionException { /** * Returns a map of the exclusions using the Dependency ManagementKey as the keyset. * - * @param exclusionList to be added to the map. - * @return a map of the exclusions using the Dependency ManagementKey as the keyset. + * @param exclusionList to be added to the map + * @return a map of the exclusions using the Dependency ManagementKey as the keyset */ public Map addExclusions(List exclusionList) { if (exclusionList != null) { @@ -181,9 +184,9 @@ public Map addExclusions(List exclusionList) { * Returns a List of the artifacts that should have been excluded, but were found in the dependency tree. * * @param exclusions a map of the DependencyManagement exclusions, with the ManagementKey as the key and Dependency - * as the value. - * @param allDependencyArtifacts resolved artifacts to be compared. - * @return list of artifacts that should have been excluded. + * as the value + * @param allDependencyArtifacts resolved artifacts to be compared + * @return list of artifacts that should have been excluded */ public List getExclusionErrors(Map exclusions, Set allDependencyArtifacts) { return allDependencyArtifacts.stream() @@ -193,26 +196,26 @@ public List getExclusionErrors(Map exclusions, Set< /** * @param artifact {@link Artifact} - * @return The resulting GA. + * @return the resulting GA */ public String getExclusionKey(Artifact artifact) { return artifact.getGroupId() + ":" + artifact.getArtifactId(); } /** - * @param ex The exclusion key. - * @return The resulting combination of groupId+artifactId. + * @param ex the exclusion key + * @return the resulting combination of groupId+artifactId */ public String getExclusionKey(Exclusion ex) { return ex.getGroupId() + ":" + ex.getArtifactId(); } /** - * Calculate the mismatches between the DependencyManagement and resolved artifacts + * Calculate the mismatches between the DependencyManagement and resolved artifacts. * - * @param depMgtMap contains the Dependency.GetManagementKey as the keyset for quick lookup. - * @param allDependencyArtifacts contains the set of all artifacts to compare. - * @return a map containing the resolved artifact as the key and the listed dependency as the value. + * @param depMgtMap a keyset of the Dependency.GetManagementKey for quick lookup + * @param allDependencyArtifacts the set of all artifacts to compare + * @return a map containing the resolved artifact as the key and the listed dependency as the value */ public Map getMismatch( Map depMgtMap, Set allDependencyArtifacts) { @@ -221,9 +224,6 @@ public Map getMismatch( for (Artifact dependencyArtifact : allDependencyArtifacts) { Dependency depFromDepMgt = depMgtMap.get(getArtifactManagementKey(dependencyArtifact)); if (depFromDepMgt != null) { - // workaround for MNG-2961 - dependencyArtifact.isSnapshot(); - if (depFromDepMgt.getVersion() != null && !depFromDepMgt.getVersion().equals(dependencyArtifact.getBaseVersion())) { mismatchMap.put(dependencyArtifact, depFromDepMgt); @@ -237,9 +237,9 @@ public Map getMismatch( * This function displays the log to the screen showing the versions and information about the artifacts that don't * match. * - * @param dependencyArtifact the artifact that was resolved. - * @param dependencyFromDepMgt the dependency listed in the DependencyManagement section. - * @throws MojoExecutionException in case of errors. + * @param dependencyArtifact the artifact that was resolved + * @param dependencyFromDepMgt the dependency listed in the DependencyManagement section + * @throws MojoExecutionException in case of errors */ public void logMismatch(Artifact dependencyArtifact, Dependency dependencyFromDepMgt) throws MojoExecutionException { @@ -248,7 +248,7 @@ public void logMismatch(Artifact dependencyArtifact, Dependency dependencyFromDe "Invalid params: Artifact: " + dependencyArtifact + " Dependency: " + dependencyFromDepMgt); } - getLog().info("\tDependency: " + StringUtils.stripEnd(dependencyFromDepMgt.getManagementKey(), ":")); + getLog().info("\tDependency: " + dependencyFromDepMgt.getManagementKey()); getLog().info("\t\tDepMgt : " + dependencyFromDepMgt.getVersion()); getLog().info("\t\tResolved: " + dependencyArtifact.getBaseVersion()); } @@ -285,13 +285,6 @@ protected final MavenProject getProject() { return this.project; } - /** - * @param theProject the project to set - */ - public void setProject(MavenProject theProject) { - this.project = theProject; - } - /** * @return the ignoreDirect */ diff --git a/src/main/java/org/apache/maven/plugins/dependency/analyze/AnalyzeDuplicateMojo.java b/src/main/java/org/apache/maven/plugins/dependency/analyze/AnalyzeDuplicateMojo.java index fe6aa8728..1d59ff8d6 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/analyze/AnalyzeDuplicateMojo.java +++ b/src/main/java/org/apache/maven/plugins/dependency/analyze/AnalyzeDuplicateMojo.java @@ -18,15 +18,18 @@ */ package org.apache.maven.plugins.dependency.analyze; +import javax.inject.Inject; + import java.io.IOException; import java.io.Reader; -import java.util.ArrayList; import java.util.Collections; +import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; -import org.apache.commons.collections4.CollectionUtils; +import java.util.stream.Collectors; + import org.apache.maven.model.Dependency; import org.apache.maven.model.Model; import org.apache.maven.model.io.xpp3.MavenXpp3Reader; @@ -36,7 +39,7 @@ import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.project.MavenProject; -import org.codehaus.plexus.util.ReaderFactory; +import org.codehaus.plexus.util.xml.XmlStreamReader; import org.codehaus.plexus.util.xml.pull.XmlPullParserException; /** @@ -64,9 +67,13 @@ public class AnalyzeDuplicateMojo extends AbstractMojo { /** * The Maven project to analyze. */ - @Parameter(defaultValue = "${project}", readonly = true, required = true) private MavenProject project; + @Inject + public AnalyzeDuplicateMojo(MavenProject project) { + this.project = project; + } + /** * {@inheritDoc} */ @@ -79,7 +86,7 @@ public void execute() throws MojoExecutionException, MojoFailureException { MavenXpp3Reader pomReader = new MavenXpp3Reader(); Model model; - try (Reader reader = ReaderFactory.newXmlReader(project.getFile())) { + try (Reader reader = new XmlStreamReader(project.getFile())) { model = pomReader.read(reader); } catch (IOException | XmlPullParserException e) { throw new MojoExecutionException("Exception: " + e.getMessage(), e); @@ -115,7 +122,7 @@ private void createMessage( Set duplicateDependencies, StringBuilder sb, String messageDuplicateDepInDependencies) { if (!duplicateDependencies.isEmpty()) { if (sb.length() > 0) { - sb.append("\n"); + sb.append(System.lineSeparator()); } sb.append(messageDuplicateDepInDependencies); for (Iterator it = duplicateDependencies.iterator(); it.hasNext(); ) { @@ -123,21 +130,18 @@ private void createMessage( sb.append("\to ").append(dup); if (it.hasNext()) { - sb.append("\n"); + sb.append(System.lineSeparator()); } } } } private Set findDuplicateDependencies(List modelDependencies) { - List modelDependencies2 = new ArrayList<>(); - for (Dependency dep : modelDependencies) { - modelDependencies2.add(dep.getManagementKey()); - } - - // @formatter:off - return new LinkedHashSet<>( - CollectionUtils.disjunction(modelDependencies2, new LinkedHashSet<>(modelDependencies2))); - // @formatter:on + List modelDependencies2 = + modelDependencies.stream().map(Dependency::getManagementKey).collect(Collectors.toList()); + // remove one instance of each element from the list + modelDependencies2.removeIf(new HashSet<>(modelDependencies2)::remove); + // keep a single instance of each duplicate + return new LinkedHashSet<>(modelDependencies2); } } diff --git a/src/main/java/org/apache/maven/plugins/dependency/analyze/AnalyzeMojo.java b/src/main/java/org/apache/maven/plugins/dependency/analyze/AnalyzeMojo.java index 84907bb60..1cab87532 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/analyze/AnalyzeMojo.java +++ b/src/main/java/org/apache/maven/plugins/dependency/analyze/AnalyzeMojo.java @@ -18,17 +18,21 @@ */ package org.apache.maven.plugins.dependency.analyze; +import javax.inject.Inject; + import org.apache.maven.plugins.annotations.Execute; import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.ResolutionScope; +import org.apache.maven.project.MavenProject; +import org.codehaus.plexus.PlexusContainer; /** * Analyzes the dependencies of this project and determines which are: used and declared; used and undeclared; unused - * and declared. This goal is intended to be used standalone, thus it always executes the test-compile - * phase - use the dependency:analyze-only goal instead when participating in the build lifecycle. + * and declared. This goal is intended to be used standalone. Thus, it always executes the test-compile + * phase. Use the dependency:analyze-only goal instead when participating in the build lifecycle. *

    - * By default, maven-dependency-analyzer is used + * By default, maven-dependency-analyzer is used * to perform the analysis, with limitations due to the fact that it works at bytecode level, but any analyzer can be * plugged in through analyzer parameter. *

    @@ -41,4 +45,9 @@ @Execute(phase = LifecyclePhase.TEST_COMPILE) public class AnalyzeMojo extends AbstractAnalyzeMojo { // subclassed to provide annotations + + @Inject + public AnalyzeMojo(PlexusContainer plexusContainer, MavenProject project) { + super(plexusContainer, project); + } } diff --git a/src/main/java/org/apache/maven/plugins/dependency/analyze/AnalyzeOnlyMojo.java b/src/main/java/org/apache/maven/plugins/dependency/analyze/AnalyzeOnlyMojo.java index 43d1e3021..ba7d0ddd9 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/analyze/AnalyzeOnlyMojo.java +++ b/src/main/java/org/apache/maven/plugins/dependency/analyze/AnalyzeOnlyMojo.java @@ -18,9 +18,13 @@ */ package org.apache.maven.plugins.dependency.analyze; +import javax.inject.Inject; + import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.ResolutionScope; +import org.apache.maven.project.MavenProject; +import org.codehaus.plexus.PlexusContainer; /** * Analyzes the dependencies of this project and determines which are: used and declared; used and undeclared; unused @@ -28,7 +32,7 @@ * test-compile phase has been executed - use the dependency:analyze goal instead when running * standalone. *

    - * By default, maven-dependency-analyzer is used + * By default, maven-dependency-analyzer is used * to perform the analysis, with limitations due to the fact that it works at bytecode level, but any analyzer can be * plugged in through analyzer parameter. *

    @@ -46,4 +50,9 @@ // @formatter:on public class AnalyzeOnlyMojo extends AbstractAnalyzeMojo { // subclassed to provide annotations + + @Inject + public AnalyzeOnlyMojo(PlexusContainer plexusContainer, MavenProject project) { + super(plexusContainer, project); + } } diff --git a/src/main/java/org/apache/maven/plugins/dependency/analyze/AnalyzeReportMojo.java b/src/main/java/org/apache/maven/plugins/dependency/analyze/AnalyzeReport.java similarity index 75% rename from src/main/java/org/apache/maven/plugins/dependency/analyze/AnalyzeReportMojo.java rename to src/main/java/org/apache/maven/plugins/dependency/analyze/AnalyzeReport.java index 5e3e40fa3..038a1fdac 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/analyze/AnalyzeReportMojo.java +++ b/src/main/java/org/apache/maven/plugins/dependency/analyze/AnalyzeReport.java @@ -18,10 +18,11 @@ */ package org.apache.maven.plugins.dependency.analyze; +import javax.inject.Inject; + import java.util.Locale; -import java.util.ResourceBundle; -import org.apache.maven.doxia.sink.Sink; -import org.apache.maven.plugins.annotations.Component; +import java.util.Set; + import org.apache.maven.plugins.annotations.Execute; import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; @@ -32,6 +33,7 @@ import org.apache.maven.shared.dependency.analyzer.ProjectDependencyAnalysis; import org.apache.maven.shared.dependency.analyzer.ProjectDependencyAnalyzer; import org.apache.maven.shared.dependency.analyzer.ProjectDependencyAnalyzerException; +import org.codehaus.plexus.i18n.I18N; /** * Analyzes the dependencies of this project and produces a report that summarizes which are: used and declared; used @@ -41,17 +43,21 @@ */ @Mojo(name = "analyze-report", requiresDependencyResolution = ResolutionScope.TEST, threadSafe = true) @Execute(phase = LifecyclePhase.TEST_COMPILE) -public class AnalyzeReportMojo extends AbstractMavenReport { +public class AnalyzeReport extends AbstractMavenReport { // fields ----------------------------------------------------------------- /** * The Maven project dependency analyzer to use. */ - @Component - private ProjectDependencyAnalyzer analyzer; + private final ProjectDependencyAnalyzer analyzer; + + /** + * Internationalization component. + */ + private final I18N i18n; /** - * Ignore Runtime/Provided/Test/System scopes for unused dependency analysis + * Ignore Runtime/Provided/Test/System scopes for unused dependency analysis. * * @since 2.2 */ @@ -75,6 +81,20 @@ public class AnalyzeReportMojo extends AbstractMavenReport { @Parameter(property = "mdep.analyze.skip", defaultValue = "false") private boolean skip; + /** + * List Excluded classes patterns from analyze. Java regular expression pattern is applied to full class name. + * + * @since 3.7.0 + */ + @Parameter(property = "mdep.analyze.excludedClasses") + private Set excludedClasses; + + @Inject + public AnalyzeReport(ProjectDependencyAnalyzer analyzer, I18N i18n) { + this.analyzer = analyzer; + this.i18n = i18n; + } + // Mojo methods ----------------------------------------------------------- /* @@ -85,7 +105,7 @@ public void executeReport(Locale locale) throws MavenReportException { // Step 1: Analyze the project ProjectDependencyAnalysis analysis; try { - analysis = analyzer.analyze(project); + analysis = analyzer.analyze(project, excludedClasses); if (usedDependencies != null) { analysis = analysis.forceDeclaredDependenciesUsage(usedDependencies); @@ -99,13 +119,9 @@ public void executeReport(Locale locale) throws MavenReportException { analysis = analysis.ignoreNonCompile(); } - // Step 2: Create sink and bundle - Sink sink = getSink(); - ResourceBundle bundle = getBundle(locale); - // Step 3: Generate the report - AnalyzeReportView analyzethis = new AnalyzeReportView(); - analyzethis.generateReport(analysis, sink, bundle); + AnalyzeReportRenderer r = new AnalyzeReportRenderer(getSink(), i18n, locale, analysis); + r.render(); } // MavenReport methods ---------------------------------------------------- @@ -113,51 +129,49 @@ public void executeReport(Locale locale) throws MavenReportException { @Override public boolean canGenerateReport() { if (skip) { - getLog().info("Skipping plugin execution"); return false; } // Step 0: Checking pom availability if ("pom".equals(project.getPackaging())) { - getLog().info("Skipping pom project"); return false; } return true; } - /* - * @see org.apache.maven.reporting.AbstractMavenReport#getOutputName() + /** + * {@inheritDoc} */ @Override public String getOutputName() { return "dependency-analysis"; } - /* - * @see org.apache.maven.reporting.AbstractMavenReport#getName(java.util.Locale) + /** + * {@inheritDoc} */ @Override public String getName(Locale locale) { - return getBundle(locale).getString("analyze.report.name"); + return getI18nString(locale, "name"); } - /* - * @see org.apache.maven.reporting.AbstractMavenReport#getDescription(java.util.Locale) + /** + * {@inheritDoc} */ @Override public String getDescription(Locale locale) { - return getBundle(locale).getString("analyze.report.description"); + return getI18nString(locale, "description"); } // protected methods ------------------------------------------------------ /** - * @param locale the current locale - * @return The resource bundle {@link ResourceBundle} + * @param locale the locale + * @param key the key to search for + * @return the text appropriate for the locale */ - protected ResourceBundle getBundle(Locale locale) { - return ResourceBundle.getBundle( - "analyze-report", locale, this.getClass().getClassLoader()); + protected String getI18nString(Locale locale, String key) { + return i18n.getString("analyze-report", locale, "report.analyze." + key); } } diff --git a/src/main/java/org/apache/maven/plugins/dependency/analyze/AnalyzeReportRenderer.java b/src/main/java/org/apache/maven/plugins/dependency/analyze/AnalyzeReportRenderer.java new file mode 100644 index 000000000..af46a1b6e --- /dev/null +++ b/src/main/java/org/apache/maven/plugins/dependency/analyze/AnalyzeReportRenderer.java @@ -0,0 +1,125 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.maven.plugins.dependency.analyze; + +import java.util.Collection; +import java.util.Locale; + +import org.apache.maven.artifact.Artifact; +import org.apache.maven.doxia.sink.Sink; +import org.apache.maven.reporting.AbstractMavenReportRenderer; +import org.apache.maven.shared.dependency.analyzer.ProjectDependencyAnalysis; +import org.codehaus.plexus.i18n.I18N; + +/** + * This is the view part of the analyze-report mojo. It generates the HTML report for the project website. The HTML + * output is same as the CLI output. + */ +public class AnalyzeReportRenderer extends AbstractMavenReportRenderer { + private final I18N i18n; + + private final Locale locale; + + private final ProjectDependencyAnalysis analysis; + + public AnalyzeReportRenderer(Sink sink, I18N i18n, Locale locale, ProjectDependencyAnalysis analysis) { + super(sink); + this.i18n = i18n; + this.locale = locale; + this.analysis = analysis; + } + + @Override + public String getTitle() { + return getI18nString("title"); + } + + /** + * @param key the key + * @return the translated string + */ + private String getI18nString(String key) { + return i18n.getString("analyze-report", locale, "report.analyze." + key); + } + + protected void renderBody() { + startSection(getTitle()); + + boolean reported = false; + + // Generate Used Declared dependencies: + if (!analysis.getUsedDeclaredArtifacts().isEmpty()) { + startSection(getI18nString("UsedDeclaredDependencies")); + renderDependenciesTable(sink, analysis.getUsedDeclaredArtifacts()); + endSection(); + reported = true; + } + + // Generate Used Undeclared dependencies: + + if (!analysis.getUsedUndeclaredArtifacts().isEmpty()) { + startSection(getI18nString("UsedUndeclaredDependencies")); + renderDependenciesTable(sink, analysis.getUsedUndeclaredArtifacts()); + endSection(); + reported = true; + } + + // Generate Unused declared dependencies: + if (!analysis.getUnusedDeclaredArtifacts().isEmpty()) { + startSection(getI18nString("UnusedDeclaredDependencies")); + renderDependenciesTable(sink, analysis.getUnusedDeclaredArtifacts()); + endSection(); + reported = true; + } + + // Generate Non-Test Scoped Test Dependencies: + if (!analysis.getTestArtifactsWithNonTestScope().isEmpty()) { + startSection(getI18nString("CompileScopeTestOnlyDependencies")); + renderDependenciesTable(sink, analysis.getTestArtifactsWithNonTestScope()); + endSection(); + reported = true; + } + + if (!reported) { + text(getI18nString("noDependencyProblems")); + } + + endSection(); + } + + private void renderDependenciesTable(Sink sink, Collection artifacts) { + startTable(); + + tableHeader(new String[] {"GroupId", "ArtifactId", "Version", "Scope", "Classifier", "Type", "Optional"}); + + for (Artifact artifact : artifacts) { + tableRow(new String[] { + artifact.getGroupId(), + artifact.getArtifactId(), + artifact.getVersion(), + artifact.getScope(), + artifact.getClassifier(), + artifact.getType(), + artifact.isOptional() ? "" : "false" + }); + } + + endTable(); + } +} diff --git a/src/main/java/org/apache/maven/plugins/dependency/analyze/AnalyzeReportView.java b/src/main/java/org/apache/maven/plugins/dependency/analyze/AnalyzeReportView.java deleted file mode 100644 index c36cb4e38..000000000 --- a/src/main/java/org/apache/maven/plugins/dependency/analyze/AnalyzeReportView.java +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.maven.plugins.dependency.analyze; - -import java.util.Iterator; -import java.util.ResourceBundle; -import org.apache.maven.artifact.Artifact; -import org.apache.maven.doxia.sink.Sink; -import org.apache.maven.shared.dependency.analyzer.ProjectDependencyAnalysis; - -/** - * This is the view part of the analyze-report mojo. It generates the HTML report for the project website. The HTML - * output is same as the CLI output. - */ -public class AnalyzeReportView { - /** - * Generates the HTML report. - * - * @param analysis {@link ProjectDependencyAnalysis} - * @param sink {@link Sink} - * @param bundle {@link ResourceBundle} - */ - public void generateReport(ProjectDependencyAnalysis analysis, Sink sink, ResourceBundle bundle) { - sink.head(); - sink.title(); - sink.text(bundle.getString("analyze.report.header")); - sink.title_(); - sink.head_(); - sink.body(); - - // Generate title - sink.section1(); - sink.sectionTitle1(); - sink.text(bundle.getString("analyze.report.mainTitle")); - sink.sectionTitle1_(); - - // Generate Used Declared dependencies: - sink.section2(); - sink.sectionTitle2(); - sink.text(bundle.getString("analyze.report.UsedDeclaredDependencies")); - sink.sectionTitle2_(); - if (analysis.getUsedDeclaredArtifacts().isEmpty()) { - sink.paragraph(); - sink.text(bundle.getString("analyze.report.noDependency")); - sink.paragraph_(); - sink.horizontalRule(); - } else { - generateDependenciesTable(sink, analysis.getUsedDeclaredArtifacts().iterator()); - } - sink.section2_(); - - // Generate Used Undeclared dependencies: - sink.section2(); - sink.sectionTitle2(); - sink.text(bundle.getString("analyze.report.UsedUndeclaredDependencies")); - sink.sectionTitle2_(); - if (analysis.getUsedUndeclaredArtifacts().isEmpty()) { - sink.paragraph(); - sink.text(bundle.getString("analyze.report.noDependency")); - sink.paragraph_(); - sink.horizontalRule(); - } else { - generateDependenciesTable( - sink, analysis.getUsedUndeclaredArtifacts().iterator()); - } - sink.section2_(); - - // Generate Unused declared dependencies: - sink.section2(); - sink.sectionTitle2(); - sink.text(bundle.getString("analyze.report.UnusedDeclaredDependencies")); - sink.sectionTitle2_(); - if (analysis.getUnusedDeclaredArtifacts().isEmpty()) { - sink.paragraph(); - sink.text(bundle.getString("analyze.report.noDependency")); - sink.paragraph_(); - sink.horizontalRule(); - } else { - generateDependenciesTable( - sink, analysis.getUnusedDeclaredArtifacts().iterator()); - } - sink.section2_(); - - // Generate Non-Test Scoped Test Dependencies: - sink.section2(); - sink.sectionTitle2(); - sink.text("Compile Scoped Test Dependencies"); - sink.sectionTitle2_(); - if (analysis.getTestArtifactsWithNonTestScope().isEmpty()) { - sink.paragraph(); - sink.text("None"); - sink.paragraph_(); - sink.horizontalRule(); - } else { - generateDependenciesTable( - sink, analysis.getTestArtifactsWithNonTestScope().iterator()); - } - sink.section2_(); - - sink.section1_(); - - // Closing the report - sink.body_(); - sink.flush(); - sink.close(); - } - - /** - * Generate a table for the given dependencies iterator. - * - * @param sink {@link Sink} - * @param iter {@link Artifact} - */ - public void generateDependenciesTable(Sink sink, Iterator iter) { - sink.table(); - sink.tableRows(null, false); - - sink.tableRow(); - sink.tableCell(); - sink.bold(); - sink.text("GroupId"); - sink.bold_(); - sink.tableCell_(); - - sink.tableCell(); - sink.bold(); - sink.text("ArtifactId"); - sink.bold_(); - sink.tableCell_(); - - sink.tableCell(); - sink.bold(); - sink.text("Version"); - sink.bold_(); - sink.tableCell_(); - - sink.tableCell(); - sink.bold(); - sink.text("Scope"); - sink.bold_(); - sink.tableCell_(); - - sink.tableCell(); - sink.bold(); - sink.text("Classifier"); - sink.bold_(); - sink.tableCell_(); - - sink.tableCell(); - sink.bold(); - sink.text("Type"); - sink.bold_(); - sink.tableCell_(); - - sink.tableCell(); - sink.bold(); - sink.text("Optional"); - sink.bold_(); - sink.tableCell_(); - - sink.tableRow_(); - while (iter.hasNext()) { - Artifact artifact = iter.next(); - - sink.tableRow(); - sink.tableCell(); - sink.text(artifact.getGroupId()); - sink.tableCell_(); - sink.tableCell(); - sink.text(artifact.getArtifactId()); - sink.tableCell_(); - sink.tableCell(); - sink.text(artifact.getVersion()); - sink.tableCell_(); - sink.tableCell(); - sink.text(artifact.getScope()); - sink.tableCell_(); - sink.tableCell(); - sink.text(artifact.getClassifier()); - sink.tableCell_(); - sink.tableCell(); - sink.text(artifact.getType()); - sink.tableCell_(); - sink.tableCell(); - if (artifact.isOptional()) { - sink.text(""); - } else { - sink.text("false"); - } - - sink.tableCell_(); - sink.tableRow_(); - } - - sink.tableRows_(); - sink.table_(); - sink.horizontalRule(); - } -} diff --git a/src/main/java/org/apache/maven/plugins/dependency/exclusion/AnalyzeExclusionsMojo.java b/src/main/java/org/apache/maven/plugins/dependency/exclusion/AnalyzeExclusionsMojo.java new file mode 100644 index 000000000..e45c76c4e --- /dev/null +++ b/src/main/java/org/apache/maven/plugins/dependency/exclusion/AnalyzeExclusionsMojo.java @@ -0,0 +1,187 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.maven.plugins.dependency.exclusion; + +import javax.inject.Inject; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Consumer; + +import org.apache.maven.RepositoryUtils; +import org.apache.maven.execution.MavenSession; +import org.apache.maven.model.Dependency; +import org.apache.maven.model.Exclusion; +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.plugins.annotations.ResolutionScope; +import org.apache.maven.plugins.dependency.utils.ResolverUtil; +import org.apache.maven.project.MavenProject; +import org.eclipse.aether.artifact.ArtifactTypeRegistry; +import org.eclipse.aether.collection.DependencyCollectionException; + +import static java.util.stream.Collectors.toList; +import static java.util.stream.Collectors.toSet; +import static org.apache.maven.plugins.dependency.exclusion.Coordinates.coordinates; + +/** + * Analyzes the exclusions defined on dependencies in this project and reports if any of them are unneeded. + *

    + * Relevant use case is when an artifact in a later version has removed usage of a dependency, making the exclusion no + * longer necessary. + *

    + * + * @since 3.7.0 + */ +@Mojo(name = "analyze-exclusions", requiresDependencyCollection = ResolutionScope.TEST, threadSafe = true) +public class AnalyzeExclusionsMojo extends AbstractMojo { + + private final MavenProject project; + + private final ResolverUtil resolverUtil; + + private final MavenSession session; + + @Inject + public AnalyzeExclusionsMojo(MavenProject project, ResolverUtil resolverUtil, MavenSession session) { + this.project = project; + this.resolverUtil = resolverUtil; + this.session = session; + } + + /** + * Whether to fail the build if invalid exclusions is found. + * + * @since 3.7.0 + */ + @Parameter(property = "mdep.exclusion.fail", defaultValue = "false") + private boolean exclusionFail; + + /** + * Skip plugin execution completely. + * + * @since 3.7.0 + */ + @Parameter(property = "mdep.skip", defaultValue = "false") + private boolean skip; + + /** + * Current project modelId. + */ + private String projectModelId; + + @Override + public void execute() throws MojoExecutionException { + if (skip) { + getLog().debug("Skipping execution"); + return; + } + + projectModelId = project.getGroupId() + ":" + project.getArtifactId() + ":" + project.getVersion(); + + Map> dependenciesWithExclusions = new HashMap<>(); + + project.getDependencyManagement().getDependencies().forEach(dependency -> { + Collection exclusions = getExclusionsForDependency(dependency); + if (!exclusions.isEmpty()) { + dependenciesWithExclusions + .computeIfAbsent(coordinates(dependency), d -> new ArrayList<>()) + .addAll(exclusions); + } + }); + + project.getDependencies().forEach(dependency -> { + Collection exclusions = getExclusionsForDependency(dependency); + if (!exclusions.isEmpty()) { + dependenciesWithExclusions + .computeIfAbsent(coordinates(dependency), d -> new ArrayList<>()) + .addAll(exclusions); + } + }); + + if (dependenciesWithExclusions.isEmpty()) { + getLog().debug("No dependencies defined with exclusions - exiting"); + return; + } + + ExclusionChecker checker = new ExclusionChecker(); + + ArtifactTypeRegistry artifactTypeRegistry = + session.getRepositorySession().getArtifactTypeRegistry(); + for (Map.Entry> entry : dependenciesWithExclusions.entrySet()) { + + Coordinates currentCoordinates = entry.getKey(); + + Collection actualDependencies; + try { + actualDependencies = resolverUtil.collectDependencies( + RepositoryUtils.toDependency(currentCoordinates.getDependency(), artifactTypeRegistry) + .setExclusions(null)); + } catch (DependencyCollectionException e) { + throw new MojoExecutionException(e.getMessage(), e); + } + + Set actualCoordinates = actualDependencies.stream() + .map(org.eclipse.aether.graph.Dependency::getArtifact) + .map(a -> coordinates(a.getGroupId(), a.getArtifactId())) + .collect(toSet()); + + Set exclusions = + entry.getValue().stream().map(Coordinates::coordinates).collect(toSet()); + + checker.check(currentCoordinates, exclusions, actualCoordinates); + } + + if (!checker.getViolations().isEmpty()) { + if (exclusionFail) { + logViolations(project.getName(), checker.getViolations(), value -> getLog().error(value)); + throw new MojoExecutionException("Invalid exclusions found"); + } else { + logViolations(project.getName(), checker.getViolations(), value -> getLog().warn(value)); + } + } else { + getLog().info("No problems with dependencies exclusions"); + } + } + + private Collection getExclusionsForDependency(Dependency dependency) { + return dependency.getExclusions().stream() + .filter(this::isExclusionInProject) + .collect(toList()); + } + + private boolean isExclusionInProject(Exclusion exclusion) { + String modelId = exclusion.getLocation("").getSource().getModelId(); + return projectModelId.equals(modelId); + } + + private void logViolations(String name, Map> violations, Consumer logger) { + logger.accept(name + " defines following unnecessary excludes"); + violations.forEach((dependency, invalidExclusions) -> { + logger.accept(" " + dependency); + invalidExclusions.forEach(invalidExclusion -> logger.accept(" - " + invalidExclusion)); + }); + } +} diff --git a/src/main/java/org/apache/maven/plugins/dependency/exclusion/Coordinates.java b/src/main/java/org/apache/maven/plugins/dependency/exclusion/Coordinates.java new file mode 100644 index 000000000..d81f7b37b --- /dev/null +++ b/src/main/java/org/apache/maven/plugins/dependency/exclusion/Coordinates.java @@ -0,0 +1,145 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.maven.plugins.dependency.exclusion; + +import java.lang.reflect.Proxy; +import java.nio.file.FileSystems; +import java.nio.file.Path; +import java.nio.file.PathMatcher; +import java.util.Objects; +import java.util.function.Predicate; + +import org.apache.maven.model.Dependency; +import org.apache.maven.model.Exclusion; +import org.apache.maven.model.InputLocation; + +/** + * Simple "record" to hold the coordinates of the dependency which is excluded. + *

    + * When dealing with exclusions the version is not important. Only groupId and artifactId is used. + *

    + */ +class Coordinates implements Comparable { + + private final String groupId; + + private final String artifactId; + + private final Dependency dependency; + + private final InputLocation location; + + private Coordinates(String groupId, String artifactId, Dependency dependency, InputLocation location) { + this.groupId = groupId; + this.artifactId = artifactId; + this.dependency = dependency; + this.location = location; + } + + public static Coordinates coordinates(String groupId, String artifactId) { + return new Coordinates(groupId, artifactId, null, null); + } + + public static Coordinates coordinates(Dependency dependency) { + return new Coordinates(dependency.getGroupId(), dependency.getArtifactId(), dependency, null); + } + + public static Coordinates coordinates(Exclusion exclusion) { + return new Coordinates(exclusion.getGroupId(), exclusion.getArtifactId(), null, exclusion.getLocation("")); + } + + public String getGroupId() { + return groupId; + } + + public String getArtifactId() { + return artifactId; + } + + public Dependency getDependency() { + return dependency; + } + + Predicate getExclusionPattern() { + PathMatcher groupId = FileSystems.getDefault().getPathMatcher("glob:" + getGroupId()); + PathMatcher artifactId = FileSystems.getDefault().getPathMatcher("glob:" + getArtifactId()); + Predicate predGroupId = a -> groupId.matches(createPathProxy(a.getGroupId())); + Predicate predArtifactId = a -> artifactId.matches(createPathProxy(a.getArtifactId())); + + return predGroupId.and(predArtifactId); + } + + /** + * In order to reuse the glob matcher from the filesystem, we need + * to create Path instances. Those are only used with the toString method. + * This hack works because the only system-dependent thing is the path + * separator which should not be part of the groupId or artifactId. + */ + private static Path createPathProxy(String value) { + return (Path) Proxy.newProxyInstance( + Coordinates.class.getClassLoader(), new Class[] {Path.class}, (proxy1, method, args) -> { + if ("toString".equals(method.getName())) { + return value; + } + throw new UnsupportedOperationException(); + }); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Coordinates that = (Coordinates) o; + return Objects.equals(groupId, that.groupId) + && Objects.equals(artifactId, that.artifactId) + && Objects.equals(location, that.location); + } + + @Override + public int hashCode() { + return Objects.hash(groupId, artifactId, location); + } + + @Override + public int compareTo(Coordinates that) { + + if (location != null && that.location != null) { + return location.getLineNumber() - that.location.getLineNumber(); + } + + return toString().compareTo(that.toString()); + } + + @Override + public String toString() { + String version = ""; + if (dependency != null) { + version = ":" + dependency.getVersion(); + } + String line = ""; + if (location != null) { + line = " @ line: " + location.getLineNumber(); + } + return groupId + ":" + artifactId + version + line; + } +} diff --git a/src/main/java/org/apache/maven/plugins/dependency/exclusion/ExclusionChecker.java b/src/main/java/org/apache/maven/plugins/dependency/exclusion/ExclusionChecker.java new file mode 100644 index 000000000..1340461b7 --- /dev/null +++ b/src/main/java/org/apache/maven/plugins/dependency/exclusion/ExclusionChecker.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.maven.plugins.dependency.exclusion; + +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; + +import static java.util.stream.Collectors.toList; + +class ExclusionChecker { + + private final Map> violations = new TreeMap<>(); + + Map> getViolations() { + return violations; + } + + void check(Coordinates artifact, Set excludes, Set actualDependencies) { + List invalidExclusions = excludes.stream() + .filter(exclude -> actualDependencies.stream().noneMatch(exclude.getExclusionPattern())) + .sorted() + .collect(toList()); + + if (!invalidExclusions.isEmpty()) { + violations.put(artifact, invalidExclusions); + } + } +} diff --git a/src/main/java/org/apache/maven/plugins/dependency/fromConfiguration/AbstractFromConfigurationMojo.java b/src/main/java/org/apache/maven/plugins/dependency/fromConfiguration/AbstractFromConfigurationMojo.java index 6e6dd5271..88914298e 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/fromConfiguration/AbstractFromConfigurationMojo.java +++ b/src/main/java/org/apache/maven/plugins/dependency/fromConfiguration/AbstractFromConfigurationMojo.java @@ -22,29 +22,37 @@ import java.util.Collections; import java.util.List; import java.util.Objects; + +import org.apache.commons.lang3.StringUtils; +import org.apache.maven.RepositoryUtils; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.handler.ArtifactHandler; import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager; +import org.apache.maven.execution.MavenSession; import org.apache.maven.model.Dependency; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; -import org.apache.maven.plugins.annotations.Component; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.plugins.dependency.AbstractDependencyMojo; import org.apache.maven.plugins.dependency.utils.DependencyUtil; import org.apache.maven.plugins.dependency.utils.filters.ArtifactItemFilter; import org.apache.maven.project.MavenProject; -import org.apache.maven.project.ProjectBuildingRequest; import org.apache.maven.shared.artifact.filter.collection.ArtifactFilterException; -import org.apache.maven.shared.transfer.artifact.DefaultArtifactCoordinate; -import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResolver; -import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResolverException; -import org.apache.maven.shared.transfer.repository.RepositoryManager; -import org.codehaus.plexus.util.StringUtils; +import org.eclipse.aether.DefaultRepositoryCache; +import org.eclipse.aether.DefaultRepositorySystemSession; +import org.eclipse.aether.RepositorySystem; +import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.artifact.DefaultArtifact; +import org.eclipse.aether.repository.LocalRepository; +import org.eclipse.aether.repository.LocalRepositoryManager; +import org.eclipse.aether.resolution.ArtifactRequest; +import org.eclipse.aether.resolution.ArtifactResolutionException; +import org.eclipse.aether.resolution.ArtifactResult; +import org.sonatype.plexus.build.incremental.BuildContext; /** * Abstract parent class used by mojos that get Artifact information from the plugin configuration as an ArrayList of - * ArtifactItems + * ArtifactItems. * * @author Brian Fox * @see ArtifactItem @@ -59,7 +67,7 @@ public abstract class AbstractFromConfigurationMojo extends AbstractDependencyMo private File outputDirectory; /** - * Overwrite release artifacts + * Overwrite release artifacts. * * @since 1.0 */ @@ -67,7 +75,7 @@ public abstract class AbstractFromConfigurationMojo extends AbstractDependencyMo private boolean overWriteReleases; /** - * Overwrite snapshot artifacts + * Overwrite snapshot artifacts. * * @since 1.0 */ @@ -75,11 +83,21 @@ public abstract class AbstractFromConfigurationMojo extends AbstractDependencyMo private boolean overWriteSnapshots; /** - * Overwrite if newer + * Overwrite if newer. * * @since 2.0 + * @deprecated use 'overWriteIfNewer' or 'mdep.overWriteIfNewer' as this does nothing now */ + @Deprecated @Parameter(property = "mdep.overIfNewer", defaultValue = "true") + private boolean overIfNewer; + + /** + * Overwrite if newer. + * + * @since 3.7.0 + */ + @Parameter(property = "mdep.overWriteIfNewer", defaultValue = "true") private boolean overWriteIfNewer; /** @@ -93,28 +111,34 @@ public abstract class AbstractFromConfigurationMojo extends AbstractDependencyMo /** * Path to override default local repository during plugin's execution. To remove all downloaded artifacts as part - * of the build, set this value to a location under your project's target directory + * of the build, set this value to a location under your project's target directory. * * @since 2.2 */ @Parameter private File localRepositoryDirectory; - @Component - private ArtifactResolver artifactResolver; + private final ArtifactHandlerManager artifactHandlerManager; - @Component - private RepositoryManager repositoryManager; + private final RepositorySystem repositorySystem; - @Component - private ArtifactHandlerManager artifactHandlerManager; + protected AbstractFromConfigurationMojo( + MavenSession session, + BuildContext buildContext, + MavenProject project, + ArtifactHandlerManager artifactHandlerManager, + RepositorySystem repositorySystem) { + super(session, buildContext, project); + this.artifactHandlerManager = artifactHandlerManager; + this.repositorySystem = repositorySystem; + } abstract ArtifactItemFilter getMarkedArtifactFilter(ArtifactItem item); /** - * artifactItems is filled by either field injection or by setArtifact(). + * ArtifactItems is filled by either field injection or by setArtifact(). * - * @throws MojoFailureException in case of an error. + * @throws MojoFailureException in case of an error */ protected void verifyRequirements() throws MojoFailureException { if (artifactItems == null || artifactItems.isEmpty()) { @@ -127,25 +151,25 @@ protected void verifyRequirements() throws MojoFailureException { * output Directory if it doesn't exist. * * @param processArtifactItemsRequest preprocessing instructions - * @return An ArrayList of preprocessed ArtifactItems - * @throws MojoExecutionException with a message if an error occurs. + * @return an ArrayList of preprocessed ArtifactItems + * @throws MojoExecutionException with a message if an error occurs * @see ArtifactItem */ protected List getProcessedArtifactItems(ProcessArtifactItemsRequest processArtifactItemsRequest) throws MojoExecutionException { - boolean removeVersion = processArtifactItemsRequest.isRemoveVersion(), - prependGroupId = processArtifactItemsRequest.isPrependGroupId(), - useBaseVersion = processArtifactItemsRequest.isUseBaseVersion(); + boolean removeVersion = processArtifactItemsRequest.isRemoveVersion(); + boolean prependGroupId = processArtifactItemsRequest.isPrependGroupId(); + boolean useBaseVersion = processArtifactItemsRequest.isUseBaseVersion(); boolean removeClassifier = processArtifactItemsRequest.isRemoveClassifier(); - if (artifactItems == null || artifactItems.size() < 1) { + if (artifactItems == null || artifactItems.isEmpty()) { throw new MojoExecutionException("There are no artifactItems configured."); } for (ArtifactItem artifactItem : artifactItems) { - this.getLog().info("Configured Artifact: " + artifactItem.toString()); + this.getLog().debug("Configured Artifact: " + artifactItem.toString()); if (artifactItem.getOutputDirectory() == null) { artifactItem.setOutputDirectory(this.outputDirectory); @@ -153,13 +177,14 @@ protected List getProcessedArtifactItems(ProcessArtifactItemsReque artifactItem.getOutputDirectory().mkdirs(); // make sure we have a version. - if (StringUtils.isEmpty(artifactItem.getVersion())) { + if (artifactItem.getVersion() == null || artifactItem.getVersion().isEmpty()) { fillMissingArtifactVersion(artifactItem); } artifactItem.setArtifact(this.getArtifact(artifactItem)); - if (StringUtils.isEmpty(artifactItem.getDestFileName())) { + if (artifactItem.getDestFileName() == null + || artifactItem.getDestFileName().isEmpty()) { artifactItem.setDestFileName(DependencyUtil.getFormattedFileName( artifactItem.getArtifact(), removeVersion, prependGroupId, useBaseVersion, removeClassifier)); } @@ -173,64 +198,67 @@ protected List getProcessedArtifactItems(ProcessArtifactItemsReque return artifactItems; } - private boolean checkIfProcessingNeeded(ArtifactItem item) throws MojoExecutionException, ArtifactFilterException { - return StringUtils.equalsIgnoreCase(item.getOverWrite(), "true") + private boolean checkIfProcessingNeeded(ArtifactItem item) throws ArtifactFilterException { + return "true".equalsIgnoreCase(item.getOverWrite()) || getMarkedArtifactFilter(item).isArtifactIncluded(item); } + private RepositorySystemSession createSystemSessionForLocalRepo() { + RepositorySystemSession repositorySystemSession = session.getRepositorySession(); + if (localRepositoryDirectory != null) { + // "clone" repository session and replace localRepository + DefaultRepositorySystemSession newSession = + new DefaultRepositorySystemSession(session.getRepositorySession()); + // Clear cache, since we're using a new local repository + newSession.setCache(new DefaultRepositoryCache()); + LocalRepositoryManager localRepositoryManager = repositorySystem.newLocalRepositoryManager( + newSession, new LocalRepository(localRepositoryDirectory)); + + newSession.setLocalRepositoryManager(localRepositoryManager); + repositorySystemSession = newSession; + getLog().debug("localRepoPath: " + + localRepositoryManager.getRepository().getBasedir()); + } + + return repositorySystemSession; + } + /** * Resolves the Artifact from the remote repository if necessary. If no version is specified, it will be retrieved * from the dependency list or from the DependencyManagement section of the pom. * - * @param artifactItem containing information about artifact from plugin configuration. - * @return Artifact object representing the specified file. - * @throws MojoExecutionException with a message if the version can't be found in DependencyManagement. + * @param artifactItem containing information about artifact from plugin configuration + * @return artifact object representing the specified file + * @throws MojoExecutionException if the version can't be found in DependencyManagement */ protected Artifact getArtifact(ArtifactItem artifactItem) throws MojoExecutionException { - Artifact artifact; try { - // mdep-50 - rolledback for now because it's breaking some functionality. - /* - * List listeners = new ArrayList(); Set theSet = new HashSet(); theSet.add( artifact ); - * ArtifactResolutionResult artifactResolutionResult = artifactCollector.collect( theSet, project - * .getArtifact(), managedVersions, this.local, project.getRemoteArtifactRepositories(), - * artifactMetadataSource, null, listeners ); Iterator iter = - * artifactResolutionResult.getArtifactResolutionNodes().iterator(); while ( iter.hasNext() ) { - * ResolutionNode node = (ResolutionNode) iter.next(); artifact = node.getArtifact(); } - */ - - ProjectBuildingRequest buildingRequest = newResolveArtifactProjectBuildingRequest(); - - if (localRepositoryDirectory != null) { - buildingRequest = - repositoryManager.setLocalRepositoryBasedir(buildingRequest, localRepositoryDirectory); - } - - // Map dependency to artifact coordinate - DefaultArtifactCoordinate coordinate = new DefaultArtifactCoordinate(); - coordinate.setGroupId(artifactItem.getGroupId()); - coordinate.setArtifactId(artifactItem.getArtifactId()); - coordinate.setVersion(artifactItem.getVersion()); - coordinate.setClassifier(artifactItem.getClassifier()); - final String extension; + ArtifactHandler artifactHandler = artifactHandlerManager.getArtifactHandler(artifactItem.getType()); if (artifactHandler != null) { extension = artifactHandler.getExtension(); } else { extension = artifactItem.getType(); } - coordinate.setExtension(extension); - artifact = artifactResolver - .resolveArtifact(buildingRequest, coordinate) - .getArtifact(); - } catch (ArtifactResolverException e) { + DefaultArtifact artifact = new DefaultArtifact( + artifactItem.getGroupId(), + artifactItem.getArtifactId(), + artifactItem.getClassifier(), + extension, + artifactItem.getVersion()); + + RepositorySystemSession repositorySession = createSystemSessionForLocalRepo(); + + ArtifactRequest request = new ArtifactRequest(artifact, getProject().getRemoteProjectRepositories(), null); + ArtifactResult artifactResult = repositorySystem.resolveArtifact(repositorySession, request); + return RepositoryUtils.toArtifact(artifactResult.getArtifact()); + + } catch (ArtifactResolutionException e) { throw new MojoExecutionException("Unable to find/resolve artifact.", e); } - - return artifact; } /** @@ -238,7 +266,7 @@ protected Artifact getArtifact(ArtifactItem artifactItem) throws MojoExecutionEx * with the correct version. It will first look for an exact match on artifactId/groupId/classifier/type and if it * doesn't find a match, it will try again looking for artifactId and groupId only. * - * @param artifact representing configured file. + * @param artifact representing configured file * @throws MojoExecutionException */ private void fillMissingArtifactVersion(ArtifactItem artifact) throws MojoExecutionException { @@ -261,8 +289,8 @@ private void fillMissingArtifactVersion(ArtifactItem artifact) throws MojoExecut * Tries to find missing version from a list of dependencies. If found, the artifact is updated with the correct * version. * - * @param artifact representing configured file. - * @param dependencies list of dependencies to search. + * @param artifact representing configured file + * @param dependencies list of dependencies to search * @param looseMatch only look at artifactId and groupId * @return the found dependency */ @@ -282,70 +310,70 @@ private boolean findDependencyVersion(ArtifactItem artifact, List de } /** - * @return Returns the artifactItems. + * @return returns the artifactItems */ public List getArtifactItems() { return this.artifactItems; } /** - * @param theArtifactItems The artifactItems to set. + * @param theArtifactItems the artifactItems to set */ public void setArtifactItems(List theArtifactItems) { this.artifactItems = theArtifactItems; } /** - * @return Returns the outputDirectory. + * @return returns the outputDirectory */ public File getOutputDirectory() { return this.outputDirectory; } /** - * @param theOutputDirectory The outputDirectory to set. + * @param theOutputDirectory the outputDirectory to set */ public void setOutputDirectory(File theOutputDirectory) { this.outputDirectory = theOutputDirectory; } /** - * @return Returns the overWriteIfNewer. + * @return returns the overWriteIfNewer */ public boolean isOverWriteIfNewer() { return this.overWriteIfNewer; } /** - * @param theOverWriteIfNewer The overWriteIfNewer to set. + * @param theOverWriteIfNewer the overWriteIfNewer to set */ public void setOverWriteIfNewer(boolean theOverWriteIfNewer) { this.overWriteIfNewer = theOverWriteIfNewer; } /** - * @return Returns the overWriteReleases. + * @return returns the overWriteReleases */ public boolean isOverWriteReleases() { return this.overWriteReleases; } /** - * @param theOverWriteReleases The overWriteReleases to set. + * @param theOverWriteReleases the overWriteReleases to set */ public void setOverWriteReleases(boolean theOverWriteReleases) { this.overWriteReleases = theOverWriteReleases; } /** - * @return Returns the overWriteSnapshots. + * @return returns the overWriteSnapshots */ public boolean isOverWriteSnapshots() { return this.overWriteSnapshots; } /** - * @param theOverWriteSnapshots The overWriteSnapshots to set. + * @param theOverWriteSnapshots the overWriteSnapshots to set */ public void setOverWriteSnapshots(boolean theOverWriteSnapshots) { this.overWriteSnapshots = theOverWriteSnapshots; @@ -359,8 +387,8 @@ public void setLocalRepositoryDirectory(File localRepositoryDirectory) { } /** - * @param artifact The artifact. - * @throws MojoFailureException in case of an error. + * @param artifact the artifact + * @throws MojoFailureException in case of an error */ public void setArtifact(String artifact) throws MojoFailureException { if (artifact != null) { diff --git a/src/main/java/org/apache/maven/plugins/dependency/fromConfiguration/ArtifactItem.java b/src/main/java/org/apache/maven/plugins/dependency/fromConfiguration/ArtifactItem.java index 214ca924a..4fbea1c3f 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/fromConfiguration/ArtifactItem.java +++ b/src/main/java/org/apache/maven/plugins/dependency/fromConfiguration/ArtifactItem.java @@ -20,8 +20,10 @@ import java.io.File; import java.util.Objects; + import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.ArtifactUtils; +import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.plugins.dependency.utils.DependencyUtil; import org.apache.maven.shared.transfer.dependencies.DependableCoordinate; import org.codehaus.plexus.components.io.filemappers.FileMapper; @@ -29,81 +31,67 @@ /** * ArtifactItem represents information specified in the plugin configuration section for each artifact. * - * @since 1.0 * @author Brian Fox + * @since 1.0 */ public class ArtifactItem implements DependableCoordinate { /** - * Group Id of Artifact - * - * @parameter - * @required + * Group ID of artifact. */ + @Parameter(required = true) private String groupId; /** - * Name of Artifact - * - * @parameter - * @required + * Name of artifact. */ + @Parameter(required = true) private String artifactId; /** - * Version of Artifact - * - * @parameter + * Version of artifact. */ + @Parameter private String version = null; /** - * Type of Artifact (War,Jar,etc) - * - * @parameter - * @required + * Type of artifact (War, Jar, etc.) */ + @Parameter(required = true) private String type = "jar"; /** - * Classifier for Artifact (tests,sources,etc) - * - * @parameter + * Classifier for artifact (tests, sources, etc.) */ + @Parameter private String classifier; /** - * Location to use for this Artifact. Overrides default location. - * - * @parameter + * Location to use for this artifact. Overrides default location. */ + @Parameter private File outputDirectory; /** - * Provides ability to change destination file name - * - * @parameter + * Provides ability to change destination file name. */ + @Parameter private String destFileName; /** - * Force Overwrite..this is the one to set in pom + * Force Overwrite. This is the one to set in pom. */ private String overWrite; /** * Encoding of artifact. Overrides default encoding. - * - * @parameter */ + @Parameter private String encoding; - /** - * - */ private boolean needsProcessing; /** - * Artifact Item + * Artifact Item. */ private Artifact artifact; @@ -121,13 +109,12 @@ public class ArtifactItem implements DependableCoordinate { * {@link FileMapper}s to be used for rewriting each target path, or {@code null} if no rewriting shall happen. * * @since 3.1.2 - * - * @parameter */ + @Parameter private FileMapper[] fileMappers; /** - * Default ctor. + * Default constructor. */ public ArtifactItem() { // default constructor @@ -153,77 +140,82 @@ private String filterEmptyString(String in) { } /** - * @return Returns the artifactId. + * @return returns the artifact ID */ + @Override public String getArtifactId() { return artifactId; } /** - * @param theArtifact The artifactId to set. + * @param theArtifact the artifact ID to set */ public void setArtifactId(String theArtifact) { this.artifactId = filterEmptyString(theArtifact); } /** - * @return Returns the groupId. + * @return returns the group ID */ + @Override public String getGroupId() { return groupId; } /** - * @param groupId The groupId to set. + * @param groupId the group ID to set */ public void setGroupId(String groupId) { this.groupId = filterEmptyString(groupId); } /** - * @return Returns the type. + * @return returns the type */ + @Override public String getType() { return type; } /** - * @param type The type to set. + * @param type the type to set */ public void setType(String type) { this.type = filterEmptyString(type); } /** - * @return Returns the version. + * @return returns the version */ + @Override public String getVersion() { return version; } /** - * @param version The version to set. + * @param version the version to set */ public void setVersion(String version) { this.version = filterEmptyString(version); } /** - * @return Returns the base version. + * @return teturns the base version */ public String getBaseVersion() { return ArtifactUtils.toSnapshotVersion(version); } /** - * @return Classifier. + * @return classifier */ + @Override public String getClassifier() { return classifier; } /** - * @param classifier Classifier. + * @param classifier classifier */ public void setClassifier(String classifier) { this.classifier = filterEmptyString(classifier); @@ -239,63 +231,63 @@ public String toString() { } /** - * @return Returns the location. + * @return returns the location */ public File getOutputDirectory() { return outputDirectory; } /** - * @param outputDirectory The outputDirectory to set. + * @param outputDirectory the outputDirectory to set */ public void setOutputDirectory(File outputDirectory) { this.outputDirectory = outputDirectory; } /** - * @return Returns the location. + * @return returns the location */ public String getDestFileName() { return destFileName; } /** - * @param destFileName The destFileName to set. + * @param destFileName the destination file name to set */ public void setDestFileName(String destFileName) { this.destFileName = filterEmptyString(destFileName); } /** - * @return Returns the needsProcessing. + * @return returns the needsProcessing */ public boolean isNeedsProcessing() { return this.needsProcessing; } /** - * @param needsProcessing The needsProcessing to set. + * @param needsProcessing the needsProcessing to set */ public void setNeedsProcessing(boolean needsProcessing) { this.needsProcessing = needsProcessing; } /** - * @return Returns the overWriteSnapshots. + * @return teturns the overWriteSnapshots */ public String getOverWrite() { return this.overWrite; } /** - * @param overWrite The overWrite to set. + * @param overWrite the overWrite to set */ public void setOverWrite(String overWrite) { this.overWrite = overWrite; } /** - * @return Returns the encoding. + * @return returns the encoding * @since 3.0 */ public String getEncoding() { @@ -303,7 +295,7 @@ public String getEncoding() { } /** - * @param encoding The encoding to set. + * @param encoding the encoding to set * @since 3.0 */ public void setEncoding(String encoding) { @@ -311,42 +303,42 @@ public void setEncoding(String encoding) { } /** - * @return Returns the artifact. + * @return returns the artifact */ public Artifact getArtifact() { return this.artifact; } /** - * @param artifact The artifact to set. + * @param artifact the artifact to set */ public void setArtifact(Artifact artifact) { this.artifact = artifact; } /** - * @return Returns a comma separated list of excluded items + * @return returns a comma separated list of excluded items */ public String getExcludes() { return DependencyUtil.cleanToBeTokenizedString(this.excludes); } /** - * @param excludes A comma separated list of items to exclude i.e. **\/*.xml, **\/*.properties + * @param excludes a comma separated list of items to exclude; for example, **\/*.xml, **\/*.properties */ public void setExcludes(String excludes) { this.excludes = excludes; } /** - * @return Returns a comma separated list of included items + * @return returns a comma separated list of items to include */ public String getIncludes() { return DependencyUtil.cleanToBeTokenizedString(this.includes); } /** - * @param includes A comma separated list of items to include i.e. **\/*.xml, **\/*.properties + * @param includes comma separated list of items to include; for example, **\/*.xml, **\/*.properties */ public void setIncludes(String includes) { this.includes = includes; @@ -354,8 +346,7 @@ public void setIncludes(String includes) { /** * @return {@link FileMapper}s to be used for rewriting each target path, or {@code null} if no rewriting shall - * happen. - * + * happen * @since 3.1.2 */ public FileMapper[] getFileMappers() { @@ -364,8 +355,7 @@ public FileMapper[] getFileMappers() { /** * @param fileMappers {@link FileMapper}s to be used for rewriting each target path, or {@code null} if no - * rewriting shall happen. - * + * rewriting shall happen * @since 3.1.2 */ public void setFileMappers(FileMapper[] fileMappers) { diff --git a/src/main/java/org/apache/maven/plugins/dependency/fromConfiguration/CopyMojo.java b/src/main/java/org/apache/maven/plugins/dependency/fromConfiguration/CopyMojo.java index b6ccb4807..dab686a50 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/fromConfiguration/CopyMojo.java +++ b/src/main/java/org/apache/maven/plugins/dependency/fromConfiguration/CopyMojo.java @@ -18,15 +18,26 @@ */ package org.apache.maven.plugins.dependency.fromConfiguration; +import javax.inject.Inject; + import java.io.File; +import java.io.IOException; import java.util.List; + +import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager; +import org.apache.maven.execution.MavenSession; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.plugins.dependency.utils.CopyUtil; import org.apache.maven.plugins.dependency.utils.filters.ArtifactItemFilter; import org.apache.maven.plugins.dependency.utils.filters.DestFileFilter; +import org.apache.maven.project.MavenProject; +import org.eclipse.aether.RepositorySystem; +import org.sonatype.plexus.build.incremental.BuildContext; /** * Goal that copies a list of artifacts from the repository to defined locations. @@ -37,20 +48,22 @@ @Mojo(name = "copy", defaultPhase = LifecyclePhase.PROCESS_SOURCES, requiresProject = false, threadSafe = true) public class CopyMojo extends AbstractFromConfigurationMojo { + private final CopyUtil copyUtil; + /** - * Strip artifact version during copy + * Strip artifact version during copy. */ @Parameter(property = "mdep.stripVersion", defaultValue = "false") private boolean stripVersion = false; /** - * Strip artifact classifier during copy + * Strip artifact classifier during copy. */ @Parameter(property = "mdep.stripClassifier", defaultValue = "false") private boolean stripClassifier = false; /** - * Prepend artifact groupId during copy + * Prepend artifact groupId during copy. * * @since 2.7 */ @@ -58,7 +71,7 @@ public class CopyMojo extends AbstractFromConfigurationMojo { private boolean prependGroupId = false; /** - * Use artifact baseVersion during copy + * Use artifact baseVersion during copy. * * @since 2.7 */ @@ -73,23 +86,23 @@ public class CopyMojo extends AbstractFromConfigurationMojo { @Parameter(property = "artifact") private String artifact; - /** - * not used in this goal - */ - @Parameter - protected boolean useJvmChmod = true; - - /** - * not used in this goal - */ - @Parameter - protected boolean ignorePermissions; + @Inject + public CopyMojo( + MavenSession session, + BuildContext buildContext, + MavenProject project, + ArtifactHandlerManager artifactHandlerManager, + CopyUtil copyUtil, + RepositorySystem repositorySystem) { + super(session, buildContext, project, artifactHandlerManager, repositorySystem); + this.copyUtil = copyUtil; + } /** * Main entry into mojo. This method gets the ArtifactItems and iterates through each one passing it to * copyArtifact. * - * @throws MojoExecutionException with a message if an error occurs. + * @throws MojoExecutionException with a message if an error occurs * @see ArtifactItem * @see #getArtifactItems * @see #copyArtifact(ArtifactItem) @@ -100,11 +113,12 @@ protected void doExecute() throws MojoExecutionException, MojoFailureException { List theArtifactItems = getProcessedArtifactItems( new ProcessArtifactItemsRequest(stripVersion, prependGroupId, useBaseVersion, stripClassifier)); + for (ArtifactItem artifactItem : theArtifactItems) { if (artifactItem.isNeedsProcessing()) { copyArtifact(artifactItem); } else { - this.getLog().info(artifactItem + " already exists in " + artifactItem.getOutputDirectory()); + getLog().info(artifactItem + " already exists in " + artifactItem.getOutputDirectory()); } } } @@ -112,14 +126,23 @@ protected void doExecute() throws MojoExecutionException, MojoFailureException { /** * Resolves the artifact from the repository and copies it to the specified location. * - * @param artifactItem containing the information about the Artifact to copy. - * @throws MojoExecutionException with a message if an error occurs. - * @see #copyFile(File, File) + * @param artifactItem containing the information about the artifact to copy + * @throws MojoExecutionException with a message if an error occurs + * @see CopyUtil#copyArtifactFile(Artifact, File) */ protected void copyArtifact(ArtifactItem artifactItem) throws MojoExecutionException { File destFile = new File(artifactItem.getOutputDirectory(), artifactItem.getDestFileName()); - - copyFile(artifactItem.getArtifact().getFile(), destFile); + if (destFile.exists()) { + getLog().warn("Overwriting " + destFile); + } + try { + copyUtil.copyArtifactFile(artifactItem.getArtifact(), destFile); + } catch (IOException e) { + throw new MojoExecutionException( + "Failed to copy artifact '" + artifactItem.getArtifact() + "' (" + + artifactItem.getArtifact().getFile() + ") to " + destFile, + e); + } } @Override @@ -139,35 +162,35 @@ protected ArtifactItemFilter getMarkedArtifactFilter(ArtifactItem item) { } /** - * @return Returns the stripVersion. + * @return returns the stripVersion */ public boolean isStripVersion() { return this.stripVersion; } /** - * @param stripVersion The stripVersion to set. + * @param stripVersion the stripVersion to set */ public void setStripVersion(boolean stripVersion) { this.stripVersion = stripVersion; } /** - * @return Returns the stripClassifier. + * @return returns the stripClassifier */ public boolean isStripClassifier() { return this.stripClassifier; } /** - * @param stripClassifier The stripClassifier to set. + * @param stripClassifier the stripClassifier to set */ public void setStripClassifier(boolean stripClassifier) { this.stripClassifier = stripClassifier; } /** - * @param useBaseVersion The useBaseVersion to set. + * @param useBaseVersion the useBaseVersion to set */ public void setUseBaseVersion(boolean useBaseVersion) { this.useBaseVersion = useBaseVersion; diff --git a/src/main/java/org/apache/maven/plugins/dependency/fromConfiguration/ProcessArtifactItemsRequest.java b/src/main/java/org/apache/maven/plugins/dependency/fromConfiguration/ProcessArtifactItemsRequest.java index e70897d5d..a2d9fa80f 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/fromConfiguration/ProcessArtifactItemsRequest.java +++ b/src/main/java/org/apache/maven/plugins/dependency/fromConfiguration/ProcessArtifactItemsRequest.java @@ -24,22 +24,22 @@ */ public class ProcessArtifactItemsRequest { /** - * remove the version from the filename. + * Remove the version from the filename. */ private boolean removeVersion; /** - * remove the classifier from the filename. + * Remove the classifier from the filename. */ private boolean removeClassifier; /** - * prepend the groupId to the filename. + * Prepend the groupId to the filename. */ private boolean prependGroupId; /** - * use the baseVersion of the artifact instead of version for the filename. + * Use the baseVersion of the artifact instead of version for the filename. */ private boolean useBaseVersion; diff --git a/src/main/java/org/apache/maven/plugins/dependency/fromConfiguration/UnpackMojo.java b/src/main/java/org/apache/maven/plugins/dependency/fromConfiguration/UnpackMojo.java index b76add1e0..e4854371c 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/fromConfiguration/UnpackMojo.java +++ b/src/main/java/org/apache/maven/plugins/dependency/fromConfiguration/UnpackMojo.java @@ -18,19 +18,27 @@ */ package org.apache.maven.plugins.dependency.fromConfiguration; +import javax.inject.Inject; + import java.io.File; import java.util.List; + +import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager; +import org.apache.maven.execution.MavenSession; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.plugins.dependency.utils.UnpackUtil; import org.apache.maven.plugins.dependency.utils.filters.ArtifactItemFilter; import org.apache.maven.plugins.dependency.utils.filters.MarkerFileFilter; import org.apache.maven.plugins.dependency.utils.markers.MarkerHandler; import org.apache.maven.plugins.dependency.utils.markers.UnpackFileMarkerHandler; +import org.apache.maven.project.MavenProject; import org.codehaus.plexus.components.io.filemappers.FileMapper; -import org.codehaus.plexus.util.StringUtils; +import org.eclipse.aether.RepositorySystem; +import org.sonatype.plexus.build.incremental.BuildContext; /** * Goal that retrieves a list of artifacts from the repository and unpacks them in a defined location. @@ -41,10 +49,14 @@ @Mojo(name = "unpack", defaultPhase = LifecyclePhase.PROCESS_SOURCES, requiresProject = false, threadSafe = true) public class UnpackMojo extends AbstractFromConfigurationMojo { + private final UnpackUtil unpackUtil; + /** - * Directory to store flag files after unpack + * Directory to store flag files after unpack. */ - @Parameter(defaultValue = "${project.build.directory}/dependency-maven-plugin-markers") + @Parameter( + property = "markersDirectory", + defaultValue = "${project.build.directory}/dependency-maven-plugin-markers") private File markersDirectory; /** @@ -67,6 +79,14 @@ public class UnpackMojo extends AbstractFromConfigurationMojo { @Parameter(property = "mdep.unpack.excludes") private String excludes; + /** + * Ignore to set file permissions when unpacking a dependency. + * + * @since 2.7 + */ + @Parameter(property = "dependency.ignorePermissions", defaultValue = "false") + private boolean ignorePermissions; + /** * {@link FileMapper} to be used for rewriting each target path, or {@code null} if no rewriting shall happen. * @@ -84,11 +104,23 @@ public class UnpackMojo extends AbstractFromConfigurationMojo { @Parameter(property = "artifact") private String artifact; + @Inject + public UnpackMojo( + MavenSession session, + BuildContext buildContext, + MavenProject project, + ArtifactHandlerManager artifactHandlerManager, + UnpackUtil unpackUtil, + RepositorySystem repositorySystem) { + super(session, buildContext, project, artifactHandlerManager, repositorySystem); + this.unpackUtil = unpackUtil; + } + /** * Main entry into mojo. This method gets the ArtifactItems and iterates through each one passing it to * unpackArtifact. * - * @throws MojoExecutionException with a message if an error occurs. + * @throws MojoExecutionException with a message if an error occurs * @see ArtifactItem * @see #getArtifactItems * @see #unpackArtifact(ArtifactItem) @@ -114,21 +146,23 @@ protected void doExecute() throws MojoExecutionException, MojoFailureException { /** * This method gets the Artifact object and calls DependencyUtil.unpackFile. * - * @param artifactItem containing the information about the Artifact to unpack. - * @throws MojoExecutionException with a message if an error occurs. + * @param artifactItem containing the information about the Artifact to unpack + * @throws MojoExecutionException with a message if an error occurs * @see #getArtifact */ private void unpackArtifact(ArtifactItem artifactItem) throws MojoExecutionException { MarkerHandler handler = new UnpackFileMarkerHandler(artifactItem, this.markersDirectory); - unpack( - artifactItem.getArtifact(), + unpackUtil.unpack( + artifactItem.getArtifact().getFile(), artifactItem.getType(), artifactItem.getOutputDirectory(), artifactItem.getIncludes(), artifactItem.getExcludes(), artifactItem.getEncoding(), - artifactItem.getFileMappers()); + ignorePermissions, + artifactItem.getFileMappers(), + getLog()); handler.setMarker(); } @@ -141,18 +175,18 @@ ArtifactItemFilter getMarkedArtifactFilter(ArtifactItem item) { } /** - * @param removeVersion removeVersion. + * @param removeVersion removeVersion * @return list of {@link ArtifactItem} - * @throws MojoExecutionException in case of an error. + * @throws MojoExecutionException in case of an error */ protected List getProcessedArtifactItems(boolean removeVersion) throws MojoExecutionException { List items = super.getProcessedArtifactItems(new ProcessArtifactItemsRequest(removeVersion, false, false, false)); for (ArtifactItem artifactItem : items) { - if (StringUtils.isEmpty(artifactItem.getIncludes())) { + if (artifactItem.getIncludes().isEmpty()) { artifactItem.setIncludes(getIncludes()); } - if (StringUtils.isEmpty(artifactItem.getExcludes())) { + if (artifactItem.getExcludes().isEmpty()) { artifactItem.setExcludes(getExcludes()); } } @@ -160,42 +194,42 @@ protected List getProcessedArtifactItems(boolean removeVersion) th } /** - * @return Returns the markersDirectory. + * @return returns the markersDirectory */ public File getMarkersDirectory() { return this.markersDirectory; } /** - * @param theMarkersDirectory The markersDirectory to set. + * @param theMarkersDirectory the markersDirectory to set */ public void setMarkersDirectory(File theMarkersDirectory) { this.markersDirectory = theMarkersDirectory; } /** - * @return Returns a comma separated list of excluded items + * @return returns a comma separated list of excluded items */ public String getExcludes() { return this.excludes; } /** - * @param excludes A comma separated list of items to exclude i.e. **\/*.xml, **\/*.properties + * @param excludes a comma separated list of items to exclude i.e. **\/*.xml, **\/*.properties */ public void setExcludes(String excludes) { this.excludes = excludes; } /** - * @return Returns a comma separated list of included items + * @return returns a comma separated list of included items */ public String getIncludes() { return this.includes; } /** - * @param includes A comma separated list of items to include i.e. **\/*.xml, **\/*.properties + * @param includes a comma separated list of items to include i.e. **\/*.xml, **\/*.properties */ public void setIncludes(String includes) { this.includes = includes; @@ -203,8 +237,7 @@ public void setIncludes(String includes) { /** * @return {@link FileMapper}s to be used for rewriting each target path, or {@code null} if no rewriting shall - * happen. - * + * happen * @since 3.1.2 */ public FileMapper[] getFileMappers() { @@ -213,8 +246,7 @@ public FileMapper[] getFileMappers() { /** * @param fileMappers {@link FileMapper}s to be used for rewriting each target path, or {@code null} if no - * rewriting shall happen. - * + * rewriting shall happen * @since 3.1.2 */ public void setFileMappers(FileMapper[] fileMappers) { diff --git a/src/main/java/org/apache/maven/plugins/dependency/fromDependencies/AbstractDependencyFilterMojo.java b/src/main/java/org/apache/maven/plugins/dependency/fromDependencies/AbstractDependencyFilterMojo.java index 7d1ab01a1..992807f98 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/fromDependencies/AbstractDependencyFilterMojo.java +++ b/src/main/java/org/apache/maven/plugins/dependency/fromDependencies/AbstractDependencyFilterMojo.java @@ -18,21 +18,27 @@ */ package org.apache.maven.plugins.dependency.fromDependencies; +import javax.inject.Inject; + import java.io.File; import java.util.ArrayList; import java.util.Collection; import java.util.LinkedHashSet; import java.util.Set; + +import org.apache.maven.RepositoryUtils; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager; +import org.apache.maven.execution.MavenSession; import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugins.annotations.Component; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.plugins.dependency.AbstractDependencyMojo; import org.apache.maven.plugins.dependency.utils.DependencyStatusSets; import org.apache.maven.plugins.dependency.utils.DependencyUtil; +import org.apache.maven.plugins.dependency.utils.ResolverUtil; import org.apache.maven.plugins.dependency.utils.translators.ArtifactTranslator; import org.apache.maven.plugins.dependency.utils.translators.ClassifierTypeTranslator; +import org.apache.maven.project.DefaultProjectBuildingRequest; import org.apache.maven.project.MavenProject; import org.apache.maven.project.ProjectBuilder; import org.apache.maven.project.ProjectBuildingException; @@ -46,31 +52,19 @@ import org.apache.maven.shared.artifact.filter.collection.ProjectTransitivityFilter; import org.apache.maven.shared.artifact.filter.collection.ScopeFilter; import org.apache.maven.shared.artifact.filter.collection.TypeFilter; -import org.apache.maven.shared.transfer.artifact.ArtifactCoordinate; -import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResolver; -import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResolverException; -import org.apache.maven.shared.transfer.dependencies.resolve.DependencyResolver; -import org.apache.maven.shared.transfer.repository.RepositoryManager; -import org.codehaus.plexus.util.StringUtils; +import org.eclipse.aether.resolution.ArtifactResolutionException; +import org.sonatype.plexus.build.incremental.BuildContext; /** - * Class that encapsulates the plugin parameters, and contains methods that handle dependency filtering + * Class that encapsulates the plugin parameters, and contains methods that handle dependency filtering. * * @author Brian Fox * @see org.apache.maven.plugins.dependency.AbstractDependencyMojo */ public abstract class AbstractDependencyFilterMojo extends AbstractDependencyMojo { - @Component - private ArtifactResolver artifactResolver; - - @Component - private DependencyResolver dependencyResolver; - - @Component - private RepositoryManager repositoryManager; /** - * Overwrite release artifacts + * Overwrite release artifacts. * * @since 1.0 */ @@ -78,7 +72,7 @@ public abstract class AbstractDependencyFilterMojo extends AbstractDependencyMoj protected boolean overWriteReleases; /** - * Overwrite snapshot artifacts + * Overwrite snapshot artifacts. * * @since 1.0 */ @@ -94,7 +88,7 @@ public abstract class AbstractDependencyFilterMojo extends AbstractDependencyMoj protected boolean overWriteIfNewer; /** - * If we should exclude transitive dependencies + * If we should exclude transitive dependencies. * * @since 2.0 */ @@ -102,7 +96,7 @@ public abstract class AbstractDependencyFilterMojo extends AbstractDependencyMoj protected boolean excludeTransitive; /** - * Comma Separated list of Types to include. Empty String indicates include everything (default). + * Comma-separated list of Types to include. Empty String indicates include everything (default). * * @since 2.0 */ @@ -110,7 +104,7 @@ public abstract class AbstractDependencyFilterMojo extends AbstractDependencyMoj protected String includeTypes; /** - * Comma Separated list of Types to exclude. Empty String indicates don't exclude anything (default). + * Comma-separated list of Types to exclude. Empty String indicates don't exclude anything (default). * * @since 2.0 */ @@ -136,7 +130,9 @@ public abstract class AbstractDependencyFilterMojo extends AbstractDependencyMoj /** * Scope threshold to exclude, if no value is defined for include. - * An empty string indicates no dependencies (default).
    + * An empty string indicates no dependencies (default). Unlike the other + * exclusion parameters, this property does not support a comma-delimited + * list of scope exclusions. Just one scope may be excluded at a time.
    * The scope threshold value being interpreted is the scope as * Maven filters for creating a classpath, not as specified in the pom. In summary: *
      @@ -154,7 +150,7 @@ public abstract class AbstractDependencyFilterMojo extends AbstractDependencyMoj protected String excludeScope; /** - * Comma Separated list of Classifiers to include. Empty String indicates include everything (default). + * Comma-separated list of Classifiers to include. Empty string indicates include everything (default). * * @since 2.0 */ @@ -162,7 +158,7 @@ public abstract class AbstractDependencyFilterMojo extends AbstractDependencyMoj protected String includeClassifiers; /** - * Comma Separated list of Classifiers to exclude. Empty String indicates don't exclude anything (default). + * Comma-separated list of Classifiers to exclude. Empty String indicates don't exclude anything (default). * * @since 2.0 */ @@ -170,7 +166,7 @@ public abstract class AbstractDependencyFilterMojo extends AbstractDependencyMoj protected String excludeClassifiers; /** - * Specify classifier to look for. Example: sources + * Specify classifier to look for. Example: sources. * * @since 2.0 */ @@ -178,7 +174,7 @@ public abstract class AbstractDependencyFilterMojo extends AbstractDependencyMoj protected String classifier; /** - * Specify type to look for when constructing artifact based on classifier. Example: java-source,jar,war + * Specify type to look for when constructing artifact based on classifier. Example: java-source,jar,war. * * @since 2.0 */ @@ -186,7 +182,7 @@ public abstract class AbstractDependencyFilterMojo extends AbstractDependencyMoj protected String type; /** - * Comma separated list of Artifact names to exclude. + * Comma-separated list of artifact IDs to exclude. * * @since 2.0 */ @@ -194,7 +190,7 @@ public abstract class AbstractDependencyFilterMojo extends AbstractDependencyMoj protected String excludeArtifactIds; /** - * Comma separated list of Artifact names to include. Empty String indicates include everything (default). + * Comma-separated list of artifact IDs to include. Empty String indicates include everything (default). * * @since 2.0 */ @@ -202,7 +198,7 @@ public abstract class AbstractDependencyFilterMojo extends AbstractDependencyMoj protected String includeArtifactIds; /** - * Comma separated list of GroupId Names to exclude. + * Comma-separated list of group IDs to exclude. * * @since 2.0 */ @@ -210,7 +206,7 @@ public abstract class AbstractDependencyFilterMojo extends AbstractDependencyMoj protected String excludeGroupIds; /** - * Comma separated list of GroupIds to include. Empty String indicates include everything (default). + * Comma-separated list of group IDs to include. Empty string indicates include everything (default). * * @since 2.0 */ @@ -218,44 +214,56 @@ public abstract class AbstractDependencyFilterMojo extends AbstractDependencyMoj protected String includeGroupIds; /** - * Directory to store flag files + * Directory to store flag files. * * @since 2.0 */ - // CHECKSTYLE_OFF: LineLength @Parameter( property = "markersDirectory", defaultValue = "${project.build.directory}/dependency-maven-plugin-markers") - // CHECKSTYLE_ON: LineLength protected File markersDirectory; /** - * Prepend the groupId during copy. + * Prepend the group ID during copy. * * @since 2.2 */ @Parameter(property = "mdep.prependGroupId", defaultValue = "false") protected boolean prependGroupId = false; - @Component - private ProjectBuilder projectBuilder; + private final ResolverUtil resolverUtil; + + private final ProjectBuilder projectBuilder; - @Component - private ArtifactHandlerManager artifactHandlerManager; + private final ArtifactHandlerManager artifactHandlerManager; + + @Inject + protected AbstractDependencyFilterMojo( + MavenSession session, + BuildContext buildContext, + MavenProject project, + ResolverUtil resolverUtil, + ProjectBuilder projectBuilder, + ArtifactHandlerManager artifactHandlerManager) { + super(session, buildContext, project); + this.resolverUtil = resolverUtil; + this.projectBuilder = projectBuilder; + this.artifactHandlerManager = artifactHandlerManager; + } /** * Return an {@link ArtifactsFilter} indicating which artifacts must be filtered out. * - * @return an {@link ArtifactsFilter} indicating which artifacts must be filtered out. + * @return an {@link ArtifactsFilter} indicating which artifacts must be filtered out */ protected abstract ArtifactsFilter getMarkedArtifactFilter(); /** * Retrieves dependencies, either direct only or all including transitive. * - * @param stopOnFailure true to fail if resolution does not work or false not to fail. - * @return A set of artifacts - * @throws MojoExecutionException in case of errors. + * @param stopOnFailure true to fail if resolution does not work or false not to fail + * @return a set of artifacts + * @throws MojoExecutionException in case of errors */ protected Set getResolvedDependencies(boolean stopOnFailure) throws MojoExecutionException { @@ -265,9 +273,9 @@ protected Set getResolvedDependencies(boolean stopOnFailure) throws Mo } /** - * @param stopOnFailure true/false. + * @param stopOnFailure true/false * @return {@link DependencyStatusSets} - * @throws MojoExecutionException in case of an error. + * @throws MojoExecutionException in case of an error */ protected DependencyStatusSets getDependencySets(boolean stopOnFailure) throws MojoExecutionException { return getDependencySets(stopOnFailure, false); @@ -275,12 +283,12 @@ protected DependencyStatusSets getDependencySets(boolean stopOnFailure) throws M /** * Method creates filters and filters the projects dependencies. This method also transforms the dependencies if - * classifier is set. The dependencies are filtered in least specific to most specific order + * classifier is set. The dependencies are filtered in least specific to most specific order. * - * @param stopOnFailure true to fail if artifacts can't be resolved false otherwise. - * @param includeParents true if parents should be included or not false. + * @param stopOnFailure true to fail if artifacts can't be resolved false otherwise + * @param includeParents true if parents should be included or not false * @return DependencyStatusSets - Bean of TreeSets that contains information on the projects dependencies - * @throws MojoExecutionException in case of errors. + * @throws MojoExecutionException in case of errors */ protected DependencyStatusSets getDependencySets(boolean stopOnFailure, boolean includeParents) throws MojoExecutionException { @@ -336,7 +344,7 @@ protected DependencyStatusSets getDependencySets(boolean stopOnFailure, boolean // transform artifacts if classifier is set DependencyStatusSets status; - if (StringUtils.isNotEmpty(classifier)) { + if (classifier != null && !classifier.isEmpty()) { status = getClassifierTranslatedDependencies(artifacts, stopOnFailure); } else { status = filterMarkedDependencies(artifacts); @@ -347,11 +355,12 @@ protected DependencyStatusSets getDependencySets(boolean stopOnFailure, boolean private MavenProject buildProjectFromArtifact(Artifact artifact) throws MojoExecutionException { try { - return projectBuilder - .build(artifact, session.getProjectBuildingRequest()) - .getProject(); + ProjectBuildingRequest buildingRequest = + new DefaultProjectBuildingRequest(session.getProjectBuildingRequest()); + buildingRequest.setProcessPlugins(false); + return projectBuilder.build(artifact, buildingRequest).getProject(); } catch (ProjectBuildingException e) { - throw new MojoExecutionException(e.getMessage(), e); + throw new MojoExecutionException("Coud not build project for " + artifact.getId(), e); } } @@ -364,28 +373,25 @@ private void addParentArtifacts(MavenProject project, Set artifacts) t break; } try { - ProjectBuildingRequest buildingRequest = newResolveArtifactProjectBuildingRequest(); - - Artifact resolvedArtifact = artifactResolver - .resolveArtifact(buildingRequest, project.getArtifact()) - .getArtifact(); + org.eclipse.aether.artifact.Artifact resolvedArtifact = resolverUtil.resolveArtifact( + RepositoryUtils.toArtifact(project.getArtifact()), project.getRemoteProjectRepositories()); - artifacts.add(resolvedArtifact); - } catch (ArtifactResolverException e) { + artifacts.add(RepositoryUtils.toArtifact(resolvedArtifact)); + } catch (ArtifactResolutionException e) { throw new MojoExecutionException(e.getMessage(), e); } } } /** - * Transform artifacts + * Transform artifacts. * - * @param artifacts set of artifacts {@link Artifact}. - * @param stopOnFailure true/false. + * @param artifacts set of artifacts {@link Artifact} + * @param stopOnFailure true/false * @return DependencyStatusSets - Bean of TreeSets that contains information on the projects dependencies - * @throws MojoExecutionException in case of an error. + * @throws MojoExecutionException in case of an error */ - protected DependencyStatusSets getClassifierTranslatedDependencies(Set artifacts, boolean stopOnFailure) + private DependencyStatusSets getClassifierTranslatedDependencies(Set artifacts, boolean stopOnFailure) throws MojoExecutionException { Set unResolvedArtifacts = new LinkedHashSet<>(); Set resolvedArtifacts = artifacts; @@ -394,10 +400,10 @@ protected DependencyStatusSets getClassifierTranslatedDependencies(Set // possibly translate artifacts into a new set of artifacts based on the // classifier and type // if this did something, we need to resolve the new artifacts - if (StringUtils.isNotEmpty(classifier)) { + if (classifier != null && !classifier.isEmpty()) { ArtifactTranslator translator = new ClassifierTypeTranslator(artifactHandlerManager, this.classifier, this.type); - Collection coordinates = translator.translate(artifacts, getLog()); + Collection coordinates = translator.translate(artifacts, getLog()); status = filterMarkedDependencies(artifacts); @@ -420,11 +426,11 @@ protected DependencyStatusSets getClassifierTranslatedDependencies(Set } /** - * Filter the marked dependencies + * Filter the marked dependencies. * - * @param artifacts The artifacts set {@link Artifact}. - * @return status set {@link DependencyStatusSets}. - * @throws MojoExecutionException in case of an error. + * @param artifacts the artifacts set {@link Artifact} + * @return status set {@link DependencyStatusSets} + * @throws MojoExecutionException in case of an error */ protected DependencyStatusSets filterMarkedDependencies(Set artifacts) throws MojoExecutionException { // remove files that have markers already @@ -447,29 +453,26 @@ protected DependencyStatusSets filterMarkedDependencies(Set artifacts) } /** - * @param coordinates The set of artifact coordinates{@link ArtifactCoordinate}. + * @param artifacts the set of artifacts * @param stopOnFailure true if we should fail with exception if an artifact couldn't be resolved - * false otherwise. + * false otherwise * @return the resolved artifacts. {@link Artifact}. - * @throws MojoExecutionException in case of error. + * @throws MojoExecutionException in case of error */ - protected Set resolve(Set coordinates, boolean stopOnFailure) + private Set resolve(Set artifacts, boolean stopOnFailure) throws MojoExecutionException { - ProjectBuildingRequest buildingRequest = newResolveArtifactProjectBuildingRequest(); Set resolvedArtifacts = new LinkedHashSet<>(); - for (ArtifactCoordinate coordinate : coordinates) { + for (org.eclipse.aether.artifact.Artifact artifact : artifacts) { try { - Artifact artifact = artifactResolver - .resolveArtifact(buildingRequest, coordinate) - .getArtifact(); - resolvedArtifacts.add(artifact); - } catch (ArtifactResolverException ex) { - // an error occurred during resolution, log it an continue - getLog().debug("error resolving: " + coordinate); - getLog().debug(ex); + org.eclipse.aether.artifact.Artifact resolveArtifact = + resolverUtil.resolveArtifact(artifact, getProject().getRemoteProjectRepositories()); + resolvedArtifacts.add(RepositoryUtils.toArtifact(resolveArtifact)); + } catch (ArtifactResolutionException ex) { + // an error occurred during resolution, log it and continue + getLog().debug("error resolving: " + artifact, ex); if (stopOnFailure) { - throw new MojoExecutionException("error resolving: " + coordinate, ex); + throw new MojoExecutionException("error resolving: " + artifact, ex); } } } @@ -477,14 +480,14 @@ protected Set resolve(Set coordinates, boolean sto } /** - * @return Returns the markersDirectory. + * @return returns the markersDirectory */ public File getMarkersDirectory() { return this.markersDirectory; } /** - * @param theMarkersDirectory The markersDirectory to set. + * @param theMarkersDirectory the markersDirectory to set */ public void setMarkersDirectory(File theMarkersDirectory) { this.markersDirectory = theMarkersDirectory; @@ -493,37 +496,23 @@ public void setMarkersDirectory(File theMarkersDirectory) { // TODO: Set marker files. /** - * @return true, if the groupId should be prepended to the filename. + * @return true, if the groupId should be prepended to the filename */ public boolean isPrependGroupId() { return prependGroupId; } /** - * @param prependGroupId - true if the groupId must be prepended during the copy. + * @param prependGroupId true if the groupId must be prepended during the copy */ public void setPrependGroupId(boolean prependGroupId) { this.prependGroupId = prependGroupId; } /** - * @return {@link #artifactResolver} - */ - protected final ArtifactResolver getArtifactResolver() { - return artifactResolver; - } - - /** - * @return {@link #dependencyResolver} - */ - protected final DependencyResolver getDependencyResolver() { - return dependencyResolver; - } - - /** - * @return {@link #repositoryManager} + * @return {@link #resolverUtil} */ - protected final RepositoryManager getRepositoryManager() { - return repositoryManager; + protected final ResolverUtil getResolverUtil() { + return resolverUtil; } } diff --git a/src/main/java/org/apache/maven/plugins/dependency/fromDependencies/AbstractFromDependenciesMojo.java b/src/main/java/org/apache/maven/plugins/dependency/fromDependencies/AbstractFromDependenciesMojo.java index 1226c8ada..19038fac4 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/fromDependencies/AbstractFromDependenciesMojo.java +++ b/src/main/java/org/apache/maven/plugins/dependency/fromDependencies/AbstractFromDependenciesMojo.java @@ -19,7 +19,14 @@ package org.apache.maven.plugins.dependency.fromDependencies; import java.io.File; + +import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager; +import org.apache.maven.execution.MavenSession; import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.plugins.dependency.utils.ResolverUtil; +import org.apache.maven.project.MavenProject; +import org.apache.maven.project.ProjectBuilder; +import org.sonatype.plexus.build.incremental.BuildContext; /** * Abstract Parent class used by mojos that get Artifact information from the project dependencies. @@ -36,13 +43,13 @@ public abstract class AbstractFromDependenciesMojo extends AbstractDependencyFil protected File outputDirectory; /** - * Strip artifact version during copy + * Strip artifact version during copy. */ @Parameter(property = "mdep.stripVersion", defaultValue = "false") protected boolean stripVersion = false; /** - * Strip artifact type during copy + * Strip artifact type during copy. * * @since 3.4.0 */ @@ -50,7 +57,7 @@ public abstract class AbstractFromDependenciesMojo extends AbstractDependencyFil protected boolean stripType = false; /** - * Strip artifact classifier during copy + * Strip artifact classifier during copy. */ @Parameter(property = "mdep.stripClassifier", defaultValue = "false") protected boolean stripClassifier = false; @@ -74,7 +81,7 @@ public abstract class AbstractFromDependenciesMojo extends AbstractDependencyFil /** * Place each type of file in a separate subdirectory. (example /outputDirectory/runtime /outputDirectory/provided - * etc) + * etc.) * * @since 2.2 */ @@ -82,7 +89,7 @@ public abstract class AbstractFromDependenciesMojo extends AbstractDependencyFil protected boolean useSubDirectoryPerScope; /** - * Place each type of file in a separate subdirectory. (example /outputDirectory/jars /outputDirectory/wars etc) + * Place each type of file in a separate subdirectory. (example /outputDirectory/jars /outputDirectory/wars etc.) * * @since 2.0-alpha-1 */ @@ -103,59 +110,69 @@ public abstract class AbstractFromDependenciesMojo extends AbstractDependencyFil * @since 2.0-alpha-2 */ @Parameter(property = "mdep.failOnMissingClassifierArtifact", defaultValue = "false") - protected boolean failOnMissingClassifierArtifact = true; + protected boolean failOnMissingClassifierArtifact; + + protected AbstractFromDependenciesMojo( + MavenSession session, + BuildContext buildContext, + MavenProject project, + ResolverUtil resolverUtil, + ProjectBuilder projectBuilder, + ArtifactHandlerManager artifactHandlerManager) { + super(session, buildContext, project, resolverUtil, projectBuilder, artifactHandlerManager); + } /** - * @return Returns the outputDirectory. + * @return returns the output directory */ public File getOutputDirectory() { return this.outputDirectory; } /** - * @param theOutputDirectory The outputDirectory to set. + * @param theOutputDirectory the outputDirectory to set */ public void setOutputDirectory(File theOutputDirectory) { this.outputDirectory = theOutputDirectory; } /** - * @return Returns the useSubDirectoryPerArtifact. + * @return returns the useSubDirectoryPerArtifact */ public boolean isUseSubDirectoryPerArtifact() { return this.useSubDirectoryPerArtifact; } /** - * @param theUseSubDirectoryPerArtifact The useSubDirectoryPerArtifact to set. + * @param theUseSubDirectoryPerArtifact the useSubDirectoryPerArtifact to set */ public void setUseSubDirectoryPerArtifact(boolean theUseSubDirectoryPerArtifact) { this.useSubDirectoryPerArtifact = theUseSubDirectoryPerArtifact; } /** - * @return Returns the useSubDirectoryPerScope + * @return returns the useSubDirectoryPerScope */ public boolean isUseSubDirectoryPerScope() { return this.useSubDirectoryPerScope; } /** - * @param theUseSubDirectoryPerScope The useSubDirectoryPerScope to set. + * @param theUseSubDirectoryPerScope the useSubDirectoryPerScope to set */ public void setUseSubDirectoryPerScope(boolean theUseSubDirectoryPerScope) { this.useSubDirectoryPerScope = theUseSubDirectoryPerScope; } /** - * @return Returns the useSubDirectoryPerType. + * @return returns the useSubDirectoryPerType */ public boolean isUseSubDirectoryPerType() { return this.useSubDirectoryPerType; } /** - * @param theUseSubDirectoryPerType The useSubDirectoryPerType to set. + * @param theUseSubDirectoryPerType the useSubDirectoryPerType to set */ public void setUseSubDirectoryPerType(boolean theUseSubDirectoryPerType) { this.useSubDirectoryPerType = theUseSubDirectoryPerType; @@ -211,7 +228,7 @@ public boolean isUseRepositoryLayout() { } /** - * @param useRepositoryLayout - true if dependencies must be planted in a repository layout + * @param useRepositoryLayout true if dependencies must be planted in a repository layout */ public void setUseRepositoryLayout(boolean useRepositoryLayout) { this.useRepositoryLayout = useRepositoryLayout; diff --git a/src/main/java/org/apache/maven/plugins/dependency/fromDependencies/BuildClasspathMojo.java b/src/main/java/org/apache/maven/plugins/dependency/fromDependencies/BuildClasspathMojo.java index 8424f7084..c0cc14f03 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/fromDependencies/BuildClasspathMojo.java +++ b/src/main/java/org/apache/maven/plugins/dependency/fromDependencies/BuildClasspathMojo.java @@ -18,15 +18,14 @@ */ package org.apache.maven.plugins.dependency.fromDependencies; -import java.io.BufferedReader; -import java.io.BufferedWriter; +import javax.inject.Inject; + import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; import java.io.Writer; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; import java.util.ArrayList; import java.util.Comparator; import java.util.Iterator; @@ -35,19 +34,25 @@ import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.apache.commons.lang3.StringUtils; import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager; +import org.apache.maven.execution.MavenSession; import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugins.annotations.Component; import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.plugins.annotations.ResolutionScope; import org.apache.maven.plugins.dependency.utils.DependencyUtil; +import org.apache.maven.plugins.dependency.utils.ResolverUtil; +import org.apache.maven.project.MavenProject; import org.apache.maven.project.MavenProjectHelper; -import org.apache.maven.project.ProjectBuildingRequest; +import org.apache.maven.project.ProjectBuilder; import org.apache.maven.shared.artifact.filter.collection.ArtifactsFilter; -import org.apache.maven.shared.transfer.repository.RepositoryManager; -import org.codehaus.plexus.util.StringUtils; +import org.sonatype.plexus.build.incremental.BuildContext; /** * This goal outputs a classpath string of dependencies from the local repository to a file or log. @@ -55,13 +60,11 @@ * @author ankostis * @since 2.0-alpha-2 */ -// CHECKSTYLE_OFF: LineLength @Mojo( name = "build-classpath", requiresDependencyResolution = ResolutionScope.TEST, defaultPhase = LifecyclePhase.GENERATE_SOURCES, threadSafe = true) -// CHECKSTYLE_ON: LineLength public class BuildClasspathMojo extends AbstractDependencyFilterMojo implements Comparator { @Parameter(property = "outputEncoding", defaultValue = "${project.reporting.outputEncoding}") @@ -87,7 +90,7 @@ public class BuildClasspathMojo extends AbstractDependencyFilterMojo implements private String prefix; /** - * A property to set to the content of the classpath string. + * If defined, the name of a property to which the classpath string will be written. */ @Parameter(property = "mdep.outputProperty") private String outputProperty; @@ -107,7 +110,7 @@ public class BuildClasspathMojo extends AbstractDependencyFilterMojo implements /** * Override the char used between the paths. This field is initialized to contain the first character of the value * of the system property file.separator. On UNIX systems the value of this field is '/'; on Microsoft Windows - * systems it is '\'. The default is File.separator + * systems it is '\'. The default is File.separator. * * @since 2.0 */ @@ -159,29 +162,35 @@ public class BuildClasspathMojo extends AbstractDependencyFilterMojo implements @Parameter(property = "mdep.useBaseVersion", defaultValue = "true") private boolean useBaseVersion = true; - /** - * Maven ProjectHelper - */ - @Component - private MavenProjectHelper projectHelper; - - @Component - private RepositoryManager repositoryManager; + private final MavenProjectHelper projectHelper; + + @Inject + protected BuildClasspathMojo( + MavenSession session, + BuildContext buildContext, + MavenProject project, + ResolverUtil resolverUtil, + ProjectBuilder projectBuilder, + ArtifactHandlerManager artifactHandlerManager, + MavenProjectHelper projectHelper) { + super(session, buildContext, project, resolverUtil, projectBuilder, artifactHandlerManager); + this.projectHelper = projectHelper; + } /** * Main entry into mojo. Gets the list of dependencies and iterates to create a classpath. * - * @throws MojoExecutionException with a message if an error occurs. + * @throws MojoExecutionException with a message if an error occurs * @see #getResolvedDependencies(boolean) */ @Override protected void doExecute() throws MojoExecutionException { // initialize the separators. - boolean isFileSepSet = StringUtils.isNotEmpty(fileSeparator); - boolean isPathSepSet = StringUtils.isNotEmpty(pathSeparator); + boolean isFileSepSet = fileSeparator != null && !fileSeparator.isEmpty(); + boolean isPathSepSet = pathSeparator != null && !pathSeparator.isEmpty(); // don't allow them to have absolute paths when they attach. - if (attach && StringUtils.isEmpty(localRepoProperty)) { + if (attach && (localRepoProperty == null || localRepoProperty.isEmpty())) { localRepoProperty = "${M2_REPO}"; } @@ -243,8 +252,8 @@ protected void doExecute() throws MojoExecutionException { } /** - * @param cpString The classpath. - * @throws MojoExecutionException in case of an error. + * @param cpString the classpath + * @throws MojoExecutionException in case of an error */ protected void attachFile(String cpString) throws MojoExecutionException { File attachedFile = new File(getProject().getBuild().getDirectory(), "classpath"); @@ -254,7 +263,7 @@ protected void attachFile(String cpString) throws MojoExecutionException { } /** - * Appends the artifact path into the specified StringBuilder. + * Appends the artifact path to the specified StringBuilder. * * @param art {@link Artifact} * @param sb {@link StringBuilder} @@ -263,15 +272,13 @@ protected void appendArtifactPath(Artifact art, StringBuilder sb) { if (prefix == null) { String file = art.getFile().getPath(); // substitute the property for the local repo path to make the classpath file portable. - if (StringUtils.isNotEmpty(localRepoProperty)) { - ProjectBuildingRequest projectBuildingRequest = session.getProjectBuildingRequest(); - File localBasedir = repositoryManager.getLocalRepositoryBasedir(projectBuildingRequest); - + if (localRepoProperty != null && !localRepoProperty.isEmpty()) { + File localBasedir = + session.getRepositorySession().getLocalRepository().getBasedir(); file = StringUtils.replace(file, localBasedir.getAbsolutePath(), localRepoProperty); } sb.append(file); } else { - // TODO: add param for prepending groupId and version. sb.append(prefix); sb.append(File.separator); sb.append(DependencyUtil.getFormattedFileName( @@ -283,7 +290,7 @@ protected void appendArtifactPath(Artifact art, StringBuilder sb) { * Checks that new classpath differs from that found inside the old classpathFile. * * @return true if the specified classpath equals the one found inside the file, false otherwise (including when - * file does not exist but new classpath does). + * file does not exist but new classpath does) */ private boolean isUpToDate(String cpString) { try { @@ -306,9 +313,8 @@ private void storeClasspathFile(String cpString, File out) throws MojoExecutionE // make sure the parent path exists. out.getParentFile().mkdirs(); - String encoding = Objects.toString(outputEncoding, "UTF-8"); - - try (Writer w = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(out), encoding))) { + String encoding = Objects.toString(outputEncoding, StandardCharsets.UTF_8.name()); + try (Writer w = Files.newBufferedWriter(out.toPath(), Charset.forName(encoding))) { w.write(cpString); getLog().info("Wrote classpath file '" + out + "'."); } catch (IOException ex) { @@ -332,15 +338,11 @@ protected String readClasspathFile() throws IOException { if (!outputFile.isFile()) { return null; } - StringBuilder sb = new StringBuilder(); - String encoding = Objects.toString(outputEncoding, "UTF-8"); - try (BufferedReader r = new BufferedReader(new InputStreamReader(new FileInputStream(outputFile), encoding))) { - for (String line = r.readLine(); line != null; line = r.readLine()) { - sb.append(line); - } + String encoding = Objects.toString(outputEncoding, StandardCharsets.UTF_8.name()); - return sb.toString(); + try (Stream lines = Files.lines(outputFile.toPath(), Charset.forName(encoding))) { + return lines.collect(Collectors.joining()); } } @@ -351,7 +353,7 @@ protected String readClasspathFile() throws IOException { * @param art2 second object * @return the value 0 if the argument string is equal to this string; a value less than 0 * if this string is lexicographically less than the string argument; and a value greater than - * 0 if this string is lexicographically greater than the string argument. + * 0 if this string is lexicographically greater than the string argument */ @Override public int compare(Artifact art1, Artifact art2) { diff --git a/src/main/java/org/apache/maven/plugins/dependency/fromDependencies/CopyDependenciesMojo.java b/src/main/java/org/apache/maven/plugins/dependency/fromDependencies/CopyDependenciesMojo.java index 31d2477d7..ece098283 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/fromDependencies/CopyDependenciesMojo.java +++ b/src/main/java/org/apache/maven/plugins/dependency/fromDependencies/CopyDependenciesMojo.java @@ -18,41 +18,54 @@ */ package org.apache.maven.plugins.dependency.fromDependencies; +import javax.inject.Inject; + import java.io.File; +import java.io.IOException; import java.util.Collections; +import java.util.HashMap; import java.util.Map; import java.util.Set; + +import org.apache.maven.RepositoryUtils; import org.apache.maven.artifact.Artifact; -import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout; +import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager; +import org.apache.maven.execution.MavenSession; import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugins.annotations.Component; import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.plugins.annotations.ResolutionScope; +import org.apache.maven.plugins.dependency.utils.CopyUtil; import org.apache.maven.plugins.dependency.utils.DependencyStatusSets; import org.apache.maven.plugins.dependency.utils.DependencyUtil; +import org.apache.maven.plugins.dependency.utils.ResolverUtil; import org.apache.maven.plugins.dependency.utils.filters.DestFileFilter; +import org.apache.maven.project.MavenProject; +import org.apache.maven.project.ProjectBuilder; import org.apache.maven.project.ProjectBuildingRequest; import org.apache.maven.shared.artifact.filter.collection.ArtifactsFilter; -import org.apache.maven.shared.transfer.artifact.DefaultArtifactCoordinate; import org.apache.maven.shared.transfer.artifact.install.ArtifactInstaller; import org.apache.maven.shared.transfer.artifact.install.ArtifactInstallerException; -import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResolverException; +import org.apache.maven.shared.transfer.repository.RepositoryManager; +import org.eclipse.aether.resolution.ArtifactResolutionException; +import org.eclipse.aether.util.artifact.SubArtifact; +import org.sonatype.plexus.build.incremental.BuildContext; /** - * Goal that copies the project dependencies from the repository to a defined location. + * Goal that copies the files for a project's dependencies from the repository to a directory. + * The default location to copy to is target/dependencies. + * Since all files are copied to the same directory by default, a dependency that + * has the same file name as another dependency will be overwritten. * * @author Brian Fox * @since 1.0 */ -// CHECKSTYLE_OFF: LineLength @Mojo( name = "copy-dependencies", requiresDependencyResolution = ResolutionScope.TEST, defaultPhase = LifecyclePhase.PROCESS_SOURCES, threadSafe = true) -// CHECKSTYLE_ON: LineLength public class CopyDependenciesMojo extends AbstractFromDependenciesMojo { /** * Also copy the pom of each artifact. @@ -60,19 +73,13 @@ public class CopyDependenciesMojo extends AbstractFromDependenciesMojo { * @since 2.0 */ @Parameter(property = "mdep.copyPom", defaultValue = "false") - protected boolean copyPom = true; + protected boolean copyPom; - /** - * - */ - @Component - private ArtifactInstaller installer; + private final CopyUtil copyUtil; - /** - * - */ - @Component(role = ArtifactRepositoryLayout.class) - private Map repositoryLayouts; + private final ArtifactInstaller installer; + + private final RepositoryManager repositoryManager; /** * Either append the artifact's baseVersion or uniqueVersion to the filename. Will only be used if @@ -92,21 +99,35 @@ public class CopyDependenciesMojo extends AbstractFromDependenciesMojo { protected boolean addParentPoms; /** - * not used in this goal - */ - @Parameter - protected boolean useJvmChmod = true; - - /** - * not used in this goal + * Also copy the signature files (.asc) of each artifact. + * + * @since 3.2.0 */ - @Parameter - protected boolean ignorePermissions; + @Parameter(property = "mdep.copySignatures", defaultValue = "false") + protected boolean copySignatures; + + @Inject + @SuppressWarnings("checkstyle:ParameterNumber") + public CopyDependenciesMojo( + MavenSession session, + BuildContext buildContext, + MavenProject project, + ResolverUtil resolverUtil, + RepositoryManager repositoryManager, + ProjectBuilder projectBuilder, + ArtifactHandlerManager artifactHandlerManager, + CopyUtil copyUtil, + ArtifactInstaller installer) { + super(session, buildContext, project, resolverUtil, projectBuilder, artifactHandlerManager); + this.copyUtil = copyUtil; + this.installer = installer; + this.repositoryManager = repositoryManager; + } /** * Main entry into mojo. Gets the list of dependencies and iterates through calling copyArtifact. * - * @throws MojoExecutionException with a message if an error occurs. + * @throws MojoExecutionException with a message if an error occurs * @see #getDependencySets(boolean, boolean) * @see #copyArtifact(Artifact, boolean, boolean, boolean, boolean) */ @@ -116,13 +137,28 @@ protected void doExecute() throws MojoExecutionException { Set artifacts = dss.getResolvedDependencies(); if (!useRepositoryLayout) { + Map copies = new HashMap<>(); + for (Artifact artifactItem : artifacts) { + String destFileName = DependencyUtil.getFormattedFileName( + artifactItem, stripVersion, prependGroupId, useBaseVersion, stripClassifier); + int numCopies = copies.getOrDefault(destFileName, 0); + copies.put(destFileName, numCopies + 1); + } + for (Map.Entry entry : copies.entrySet()) { + if (entry.getValue() > 1) { + getLog().warn("Multiple files with the name " + entry.getKey() + " in the dependency tree."); + getLog().warn( + "Not all JARs will be available. Consider using prependGroupId, useSubDirectoryPerArtifact, or useRepositoryLayout."); + } + } + for (Artifact artifact : artifacts) { copyArtifact( artifact, isStripVersion(), this.prependGroupId, this.useBaseVersion, this.stripClassifier); } } else { - ProjectBuildingRequest buildingRequest = getRepositoryManager() - .setLocalRepositoryBasedir(session.getProjectBuildingRequest(), outputDirectory); + ProjectBuildingRequest buildingRequest = + repositoryManager.setLocalRepositoryBasedir(session.getProjectBuildingRequest(), outputDirectory); artifacts.forEach(artifact -> installArtifact(artifact, buildingRequest)); } @@ -134,19 +170,13 @@ protected void doExecute() throws MojoExecutionException { if (isCopyPom() && !useRepositoryLayout) { copyPoms(getOutputDirectory(), artifacts, this.stripVersion); - copyPoms(getOutputDirectory(), skippedArtifacts, this.stripVersion, this.stripClassifier); // Artifacts - // that already - // exist may - // not yet have - // poms + copyPoms(getOutputDirectory(), skippedArtifacts, this.stripVersion, this.stripClassifier); + // Artifacts that already exist may not yet have poms } } /** - * install the artifact and the corresponding pom if copyPoms=true - * - * @param artifact - * @param buildingRequest + * Install the artifact and the corresponding pom if copyPoms=true. */ private void installArtifact(Artifact artifact, ProjectBuildingRequest buildingRequest) { try { @@ -184,11 +214,11 @@ private void installBaseSnapshot(Artifact artifact, ProjectBuildingRequest build * Copies the Artifact after building the destination file name if overridden. This method also checks if the * classifier is set and adds it to the destination file name if needed. * - * @param artifact representing the object to be copied. - * @param removeVersion specifies if the version should be removed from the file name when copying. - * @param prependGroupId specifies if the groupId should be prepend to the file while copying. - * @param theUseBaseVersion specifies if the baseVersion of the artifact should be used instead of the version. - * @throws MojoExecutionException with a message if an error occurs. + * @param artifact the object to be copied + * @param removeVersion specifies if the version should be removed from the file name when copying + * @param prependGroupId specifies if the group ID should be prefixed to the file while copying + * @param theUseBaseVersion specifies if the baseVersion of the artifact should be used instead of the version + * @throws MojoExecutionException with a message if an error occurs * @see #copyArtifact(Artifact, boolean, boolean, boolean, boolean) */ protected void copyArtifact( @@ -201,25 +231,27 @@ protected void copyArtifact( * Copies the Artifact after building the destination file name if overridden. This method also checks if the * classifier is set and adds it to the destination file name if needed. * - * @param artifact representing the object to be copied. - * @param removeVersion specifies if the version should be removed from the file name when copying. - * @param prependGroupId specifies if the groupId should be prepend to the file while copying. - * @param theUseBaseVersion specifies if the baseVersion of the artifact should be used instead of the version. - * @param removeClassifier specifies if the classifier should be removed from the file name when copying. - * @throws MojoExecutionException with a message if an error occurs. - * @see #copyFile(File, File) + * @param artifact the object to be copied + * @param removeVersion specifies if the version should be removed from the file name when copying + * @param prependGroupId specifies if the groupId should be prefixed to the file while copying + * @param useBaseVersion specifies if the baseVersion of the artifact should be used instead of the version + * @param removeClassifier specifies if the classifier should be removed from the file name when copying + * @throws MojoExecutionException with a message if an error occurs + * @see CopyUtil#copyArtifactFile(Artifact, File) * @see DependencyUtil#getFormattedOutputDirectory(boolean, boolean, boolean, boolean, boolean, boolean, File, Artifact) */ + private static final String SIGNATURE_EXTENSION = ".asc"; + protected void copyArtifact( Artifact artifact, boolean removeVersion, boolean prependGroupId, - boolean theUseBaseVersion, + boolean useBaseVersion, boolean removeClassifier) throws MojoExecutionException { String destFileName = DependencyUtil.getFormattedFileName( - artifact, removeVersion, prependGroupId, theUseBaseVersion, removeClassifier); + artifact, removeVersion, prependGroupId, useBaseVersion, removeClassifier); File destDir = DependencyUtil.getFormattedOutputDirectory( useSubDirectoryPerScope, @@ -231,17 +263,66 @@ protected void copyArtifact( outputDirectory, artifact); File destFile = new File(destDir, destFileName); + if (destFile.exists()) { + getLog().warn("Overwriting " + destFile); + } + try { + copyUtil.copyArtifactFile(artifact, destFile); + + // Copy the signature file if the copySignatures flag is true + if (copySignatures) { + copySignatureFile(artifact, destDir, destFileName); + } + + } catch (IOException e) { + throw new MojoExecutionException( + "Failed to copy artifact '" + artifact + "' (" + artifact.getFile() + ") to " + destFile, e); + } + } + + /** + * Copies the signature file of the artifact to the destination directory, if it exists or can be resolved. + * If the signature file does not exist and cannot be resolved, a warning is logged. + * + * @param artifact the artifact whose signature file should be copied + * @param destDir the destination directory + * @param destFileName the destination file name without the extension + */ + private void copySignatureFile(Artifact artifact, File destDir, String destFileName) { + File signatureFile = new File(artifact.getFile().getAbsolutePath() + SIGNATURE_EXTENSION); + + if (!signatureFile.exists()) { + try { + org.eclipse.aether.artifact.Artifact aArtifact = RepositoryUtils.toArtifact(artifact); + org.eclipse.aether.artifact.Artifact aSignatureArtifact = + new SubArtifact(aArtifact, null, "jar" + SIGNATURE_EXTENSION); + org.eclipse.aether.artifact.Artifact resolvedSignature = getResolverUtil() + .resolveArtifact(aSignatureArtifact, getProject().getRemoteProjectRepositories()); + signatureFile = resolvedSignature.getFile(); + } catch (ArtifactResolutionException e) { + getLog().warn("Failed to resolve signature file for artifact: " + artifact, e); + } + } - copyFile(artifact.getFile(), destFile); + if (signatureFile != null && signatureFile.exists()) { + File signatureDestFile = new File(destDir, destFileName + SIGNATURE_EXTENSION); + try { + copyUtil.copyFile(signatureFile, signatureDestFile); + } catch (IOException e) { + getLog().warn("Failed to copy signature file: " + signatureFile, e); + } + } else { + getLog().warn("Signature file for artifact " + artifact + " not found and could not be resolved."); + } } /** * Copy the pom files associated with the artifacts. * - * @param destDir The destination directory {@link File}. - * @param artifacts The artifacts {@link Artifact}. - * @param removeVersion remove version or not. - * @throws MojoExecutionException in case of errors. + * @param destDir the destination directory {@link File} + * @param artifacts the artifacts {@link Artifact} + * @param removeVersion remove version or not + * @throws MojoExecutionException in case of errors */ public void copyPoms(File destDir, Set artifacts, boolean removeVersion) throws MojoExecutionException { @@ -251,11 +332,11 @@ public void copyPoms(File destDir, Set artifacts, boolean removeVersio /** * Copy the pom files associated with the artifacts. * - * @param destDir The destination directory {@link File}. - * @param artifacts The artifacts {@link Artifact}. - * @param removeVersion remove version or not. - * @param removeClassifier remove the classifier or not. - * @throws MojoExecutionException in case of errors. + * @param destDir the destination directory {@link File} + * @param artifacts the artifacts {@link Artifact} + * @param removeVersion remove version or not + * @param removeClassifier remove the classifier or not + * @throws MojoExecutionException in case of errors */ public void copyPoms(File destDir, Set artifacts, boolean removeVersion, boolean removeClassifier) throws MojoExecutionException { @@ -272,7 +353,14 @@ public void copyPoms(File destDir, Set artifacts, boolean removeVersio DependencyUtil.getFormattedFileName( pomArtifact, removeVersion, prependGroupId, useBaseVersion, removeClassifier)); if (!pomDestFile.exists()) { - copyFile(pomArtifact.getFile(), pomDestFile); + try { + copyUtil.copyArtifactFile(pomArtifact, pomDestFile); + } catch (IOException e) { + throw new MojoExecutionException( + "Failed to copy artifact '" + pomArtifact + "' (" + pomArtifact.getFile() + ") to " + + pomDestFile, + e); + } } } } @@ -283,21 +371,16 @@ public void copyPoms(File destDir, Set artifacts, boolean removeVersio * @return {@link Artifact} */ protected Artifact getResolvedPomArtifact(Artifact artifact) { - DefaultArtifactCoordinate coordinate = new DefaultArtifactCoordinate(); - coordinate.setGroupId(artifact.getGroupId()); - coordinate.setArtifactId(artifact.getArtifactId()); - coordinate.setVersion(artifact.getVersion()); - coordinate.setExtension("pom"); Artifact pomArtifact = null; // Resolve the pom artifact using repos try { - ProjectBuildingRequest buildingRequest = newResolveArtifactProjectBuildingRequest(); - - pomArtifact = getArtifactResolver() - .resolveArtifact(buildingRequest, coordinate) - .getArtifact(); - } catch (ArtifactResolverException e) { + org.eclipse.aether.artifact.Artifact aArtifact = RepositoryUtils.toArtifact(artifact); + org.eclipse.aether.artifact.Artifact aPomArtifact = new SubArtifact(aArtifact, null, "pom"); + org.eclipse.aether.artifact.Artifact resolvedPom = + getResolverUtil().resolveArtifact(aPomArtifact, getProject().getRemoteProjectRepositories()); + pomArtifact = RepositoryUtils.toArtifact(resolvedPom); + } catch (ArtifactResolutionException e) { getLog().info(e.getMessage()); } return pomArtifact; @@ -327,7 +410,7 @@ public boolean isCopyPom() { } /** - * @param copyPom - true if the pom of each artifact must be copied + * @param copyPom true if the pom of each artifact must be copied */ public void setCopyPom(boolean copyPom) { this.copyPom = copyPom; diff --git a/src/main/java/org/apache/maven/plugins/dependency/fromDependencies/RenderDependenciesMojo.java b/src/main/java/org/apache/maven/plugins/dependency/fromDependencies/RenderDependenciesMojo.java new file mode 100644 index 000000000..6a4291480 --- /dev/null +++ b/src/main/java/org/apache/maven/plugins/dependency/fromDependencies/RenderDependenciesMojo.java @@ -0,0 +1,278 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.maven.plugins.dependency.fromDependencies; + +import javax.inject.Inject; + +import java.io.File; +import java.io.IOException; +import java.io.StringWriter; +import java.io.Writer; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Objects; +import java.util.Properties; +import java.util.function.Function; +import java.util.stream.Collectors; + +import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager; +import org.apache.maven.execution.MavenSession; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugins.annotations.LifecyclePhase; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.plugins.annotations.ResolutionScope; +import org.apache.maven.plugins.dependency.utils.ResolverUtil; +import org.apache.maven.project.MavenProject; +import org.apache.maven.project.MavenProjectHelper; +import org.apache.maven.project.ProjectBuilder; +import org.apache.maven.shared.artifact.filter.collection.ArtifactsFilter; +import org.apache.velocity.Template; +import org.apache.velocity.VelocityContext; +import org.apache.velocity.app.VelocityEngine; +import org.apache.velocity.tools.generic.CollectionTool; +import org.sonatype.plexus.build.incremental.BuildContext; + +import static java.util.Optional.ofNullable; + +/** + * This goal renders dependencies based on a velocity template. + * + * @since 3.9.0 + */ +@Mojo( + name = "render-dependencies", + requiresDependencyResolution = ResolutionScope.TEST, + defaultPhase = LifecyclePhase.GENERATE_SOURCES, + threadSafe = true) +public class RenderDependenciesMojo extends AbstractDependencyFilterMojo { + /** + * Encoding to write the rendered template. + * @since 3.9.0 + */ + @Parameter(property = "outputEncoding", defaultValue = "${project.reporting.outputEncoding}") + private String outputEncoding; + + /** + * The file to write the rendered template string. If undefined, it just prints the classpath as [INFO]. + * @since 3.9.0 + */ + @Parameter(property = "mdep.outputFile") + private File outputFile; + + /** + * If not null or empty it will attach the artifact with this classifier. + * @since 3.9.0 + */ + @Parameter(property = "mdep.classifier", defaultValue = "template") + private String classifier; + + /** + * Extension to use for the attached file if classifier is not null/empty. + * @since 3.9.0 + */ + @Parameter(property = "mdep.extension", defaultValue = "txt") + private String extension; + + /** + * Velocity template to use to render the output file. + * It can be inline or a file path. + * @since 3.9.0 + */ + @Parameter(property = "mdep.template", required = true) + private String template; + + private final MavenProjectHelper projectHelper; + + @Inject + protected RenderDependenciesMojo( + MavenSession session, + BuildContext buildContext, + MavenProject project, + ResolverUtil resolverUtil, + ProjectBuilder projectBuilder, + ArtifactHandlerManager artifactHandlerManager, + MavenProjectHelper projectHelper) { + super(session, buildContext, project, resolverUtil, projectBuilder, artifactHandlerManager); + this.projectHelper = projectHelper; + } + + /** + * Main entry into mojo. + * + * @throws MojoExecutionException with a message if an error occurs + */ + @Override + protected void doExecute() throws MojoExecutionException { + // sort them to ease template work and ensure it is deterministic + final List artifacts = + ofNullable(getResolvedDependencies(true)).orElseGet(Collections::emptySet).stream() + .sorted(Comparator.comparing(Artifact::getGroupId) + .thenComparing(Artifact::getArtifactId) + .thenComparing(Artifact::getBaseVersion) + .thenComparing(orEmpty(Artifact::getClassifier)) + .thenComparing(orEmpty(Artifact::getType))) + .collect(Collectors.toList()); + + if (artifacts.isEmpty()) { + getLog().warn("No dependencies found."); + } + + final String rendered = render(artifacts); + + if (outputFile == null) { + getLog().info(rendered); + } else { + store(rendered, outputFile); + } + if (classifier != null && !classifier.isEmpty()) { + attachFile(rendered); + } + } + + /** + * Do render the template. + * @param artifacts input. + * @return the template rendered. + */ + private String render(final List artifacts) { + final Path templatePath = getTemplatePath(); + final boolean fromFile = templatePath != null && Files.exists(templatePath); + + final Properties props = new Properties(); + props.setProperty("runtime.strict_mode.enable", "true"); + if (fromFile) { + props.setProperty( + "resource.loader.file.path", + templatePath.toAbsolutePath().getParent().toString()); + } + + final VelocityEngine ve = new VelocityEngine(props); + ve.init(); + + final VelocityContext context = new VelocityContext(); + context.put("artifacts", artifacts); + context.put("sorter", new CollectionTool()); + + // Merge template + context + final StringWriter writer = new StringWriter(); + try (StringWriter ignored = writer) { + if (fromFile) { + final Template template = + ve.getTemplate(templatePath.getFileName().toString()); + template.merge(context, writer); + } else { + ve.evaluate(context, writer, "tpl-" + Math.abs(hashCode()), template); + } + } catch (final IOException e) { + // no-op, not possible + } + + return writer.toString(); + } + + private Path getTemplatePath() { + try { + return Paths.get(template); + } catch (final RuntimeException re) { + return null; + } + } + + /** + * Trivial null protection impl for comparing callback. + * @param getter nominal getter. + * @return a comparer of getter defaulting on empty if getter value is null. + */ + private Comparator orEmpty(final Function getter) { + return Comparator.comparing(a -> ofNullable(getter.apply(a)).orElse("")); + } + + /** + * @param content the rendered template + * @throws MojoExecutionException in case of an error + */ + protected void attachFile(final String content) throws MojoExecutionException { + final File attachedFile; + if (outputFile == null) { + attachedFile = new File(getProject().getBuild().getDirectory(), classifier); + store(content, attachedFile); + } else { // already written + attachedFile = outputFile; + } + projectHelper.attachArtifact(getProject(), extension, classifier, attachedFile); + } + + /** + * Stores the specified string into that file. + * + * @param content the string to write into the file + */ + private void store(final String content, final File out) throws MojoExecutionException { + // make sure the parent path exists. + final Path parent = out.toPath().getParent(); + if (parent != null) { + try { + Files.createDirectories(parent); + } catch (final IOException e) { + throw new MojoExecutionException(e); + } + } + + final String encoding = Objects.toString(outputEncoding, StandardCharsets.UTF_8.name()); + try (Writer w = Files.newBufferedWriter(out.toPath(), Charset.forName(encoding))) { + w.write(content); + getLog().info("Wrote file '" + out + "'."); + } catch (final IOException ex) { + throw new MojoExecutionException("Error while writing to file '" + out, ex); + } + } + + @Override + protected ArtifactsFilter getMarkedArtifactFilter() { + return null; + } + + public void setExtension(final String extension) { + this.extension = extension; + } + + public void setOutputEncoding(final String outputEncoding) { + this.outputEncoding = outputEncoding; + } + + public void setOutputFile(final File outputFile) { + this.outputFile = outputFile; + } + + public void setClassifier(final String classifier) { + this.classifier = classifier; + } + + public void setTemplate(final String template) { + this.template = template; + } +} diff --git a/src/main/java/org/apache/maven/plugins/dependency/fromDependencies/UnpackDependenciesMojo.java b/src/main/java/org/apache/maven/plugins/dependency/fromDependencies/UnpackDependenciesMojo.java index e7c812688..707178373 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/fromDependencies/UnpackDependenciesMojo.java +++ b/src/main/java/org/apache/maven/plugins/dependency/fromDependencies/UnpackDependenciesMojo.java @@ -18,8 +18,13 @@ */ package org.apache.maven.plugins.dependency.fromDependencies; +import javax.inject.Inject; + import java.io.File; + import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager; +import org.apache.maven.execution.MavenSession; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; @@ -27,10 +32,15 @@ import org.apache.maven.plugins.annotations.ResolutionScope; import org.apache.maven.plugins.dependency.utils.DependencyStatusSets; import org.apache.maven.plugins.dependency.utils.DependencyUtil; +import org.apache.maven.plugins.dependency.utils.ResolverUtil; +import org.apache.maven.plugins.dependency.utils.UnpackUtil; import org.apache.maven.plugins.dependency.utils.filters.MarkerFileFilter; import org.apache.maven.plugins.dependency.utils.markers.DefaultFileMarkerHandler; +import org.apache.maven.project.MavenProject; +import org.apache.maven.project.ProjectBuilder; import org.apache.maven.shared.artifact.filter.collection.ArtifactsFilter; import org.codehaus.plexus.components.io.filemappers.FileMapper; +import org.sonatype.plexus.build.incremental.BuildContext; /** * Goal that unpacks the project dependencies from the repository to a defined location. @@ -46,6 +56,7 @@ threadSafe = true) // CHECKSTYLE_ON: LineLength public class UnpackDependenciesMojo extends AbstractFromDependenciesMojo { + /** * A comma separated list of file patterns to include when unpacking the artifact. i.e. * **/*.xml,**/*.properties NOTE: Excludes patterns override the includes. (component code = @@ -66,6 +77,14 @@ public class UnpackDependenciesMojo extends AbstractFromDependenciesMojo { @Parameter(property = "mdep.unpack.excludes") private String excludes; + /** + * Ignore to set file permissions when unpacking a dependency. + * + * @since 2.7 + */ + @Parameter(property = "dependency.ignorePermissions", defaultValue = "false") + private boolean ignorePermissions; + /** * Encoding of artifacts. * @@ -82,13 +101,27 @@ public class UnpackDependenciesMojo extends AbstractFromDependenciesMojo { @Parameter(property = "mdep.unpack.filemappers") private FileMapper[] fileMappers; + private final UnpackUtil unpackUtil; + + @Inject + public UnpackDependenciesMojo( + MavenSession session, + BuildContext buildContext, + MavenProject project, + ResolverUtil resolverUtil, + ProjectBuilder projectBuilder, + ArtifactHandlerManager artifactHandlerManager, + UnpackUtil unpackUtil) { + super(session, buildContext, project, resolverUtil, projectBuilder, artifactHandlerManager); + this.unpackUtil = unpackUtil; + } + /** * Main entry into mojo. This method gets the dependencies and iterates through each one passing it to * DependencyUtil.unpackFile(). * - * @throws MojoExecutionException with a message if an error occurs. + * @throws MojoExecutionException with a message if an error occurs * @see #getDependencySets(boolean) - * @see #unpack(Artifact, File, String, FileMapper[]) */ @Override protected void doExecute() throws MojoExecutionException { @@ -104,7 +137,16 @@ protected void doExecute() throws MojoExecutionException { stripType, outputDirectory, artifact); - unpack(artifact, destDir, getIncludes(), getExcludes(), getEncoding(), getFileMappers()); + unpackUtil.unpack( + artifact.getFile(), + artifact.getType(), + destDir, + getIncludes(), + getExcludes(), + getEncoding(), + ignorePermissions, + getFileMappers(), + getLog()); DefaultFileMarkerHandler handler = new DefaultFileMarkerHandler(artifact, this.markersDirectory); handler.setMarker(); } @@ -124,35 +166,35 @@ protected ArtifactsFilter getMarkedArtifactFilter() { } /** - * @return Returns a comma separated list of excluded items + * @return returns a comma separated list of excluded items */ public String getExcludes() { return DependencyUtil.cleanToBeTokenizedString(this.excludes); } /** - * @param excludes A comma separated list of items to exclude i.e. **\/*.xml, **\/*.properties + * @param excludes a comma separated list of items to exclude i.e. **\/*.xml, **\/*.properties */ public void setExcludes(String excludes) { this.excludes = excludes; } /** - * @return Returns a comma separated list of included items + * @return returns a comma separated list of included items */ public String getIncludes() { return DependencyUtil.cleanToBeTokenizedString(this.includes); } /** - * @param includes A comma separated list of items to include i.e. **\/*.xml, **\/*.properties + * @param includes a comma separated list of items to include i.e. **\/*.xml, **\/*.properties */ public void setIncludes(String includes) { this.includes = includes; } /** - * @param encoding The encoding to set. + * @param encoding the encoding to set * @since 3.0 */ public void setEncoding(String encoding) { @@ -160,7 +202,7 @@ public void setEncoding(String encoding) { } /** - * @return Returns the encoding. + * @return returns the encoding * @since 3.0 */ public String getEncoding() { @@ -169,8 +211,7 @@ public String getEncoding() { /** * @return {@link FileMapper}s to be used for rewriting each target path, or {@code null} if no rewriting shall - * happen. - * + * happen * @since 3.1.2 */ public FileMapper[] getFileMappers() { @@ -179,8 +220,7 @@ public FileMapper[] getFileMappers() { /** * @param fileMappers {@link FileMapper}s to be used for rewriting each target path, or {@code null} if no - * rewriting shall happen. - * + * rewriting shall happen * @since 3.1.2 */ public void setFileMappers(FileMapper[] fileMappers) { diff --git a/src/main/java/org/apache/maven/plugins/dependency/resolvers/AbstractResolveMojo.java b/src/main/java/org/apache/maven/plugins/dependency/resolvers/AbstractResolveMojo.java index 20f5a9b93..222af532e 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/resolvers/AbstractResolveMojo.java +++ b/src/main/java/org/apache/maven/plugins/dependency/resolvers/AbstractResolveMojo.java @@ -19,27 +19,21 @@ package org.apache.maven.plugins.dependency.resolvers; import java.io.File; -import java.util.LinkedHashSet; -import java.util.Set; -import org.apache.maven.artifact.Artifact; + +import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager; +import org.apache.maven.execution.MavenSession; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.plugins.dependency.fromDependencies.AbstractDependencyFilterMojo; -import org.apache.maven.plugins.dependency.utils.DependencyUtil; -import org.apache.maven.project.ProjectBuildingRequest; -import org.apache.maven.shared.artifact.filter.collection.ArtifactIdFilter; -import org.apache.maven.shared.artifact.filter.collection.ClassifierFilter; -import org.apache.maven.shared.artifact.filter.collection.FilterArtifacts; -import org.apache.maven.shared.artifact.filter.collection.GroupIdFilter; -import org.apache.maven.shared.artifact.filter.collection.ScopeFilter; -import org.apache.maven.shared.artifact.filter.collection.TypeFilter; -import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult; -import org.apache.maven.shared.transfer.dependencies.DependableCoordinate; -import org.apache.maven.shared.transfer.dependencies.resolve.DependencyResolverException; +import org.apache.maven.plugins.dependency.utils.ResolverUtil; +import org.apache.maven.project.MavenProject; +import org.apache.maven.project.ProjectBuilder; +import org.sonatype.plexus.build.incremental.BuildContext; /** * @author Brian Fox */ public abstract class AbstractResolveMojo extends AbstractDependencyFilterMojo { + /** * If specified, this parameter causes the dependencies to be written to the path specified instead of * the console. @@ -57,80 +51,13 @@ public abstract class AbstractResolveMojo extends AbstractDependencyFilterMojo { @Parameter(property = "appendOutput", defaultValue = "false") protected boolean appendOutput; - /** - * Don't resolve plugins that are in the current reactor. - * - * @since 2.7 - */ - @Parameter(property = "excludeReactor", defaultValue = "true") - protected boolean excludeReactor; - - /** - * not used in this goal - */ - @Parameter - protected boolean useJvmChmod = true; - - /** - * not used in this goal - */ - @Parameter - protected boolean ignorePermissions; - - /** - * @return {@link FilterArtifacts} - */ - protected FilterArtifacts getArtifactsFilter() { - final FilterArtifacts filter = new FilterArtifacts(); - - if (excludeReactor) { - - filter.addFilter(new ExcludeReactorProjectsArtifactFilter(reactorProjects, getLog())); - } - - filter.addFilter(new ScopeFilter( - DependencyUtil.cleanToBeTokenizedString(this.includeScope), - DependencyUtil.cleanToBeTokenizedString(this.excludeScope))); - - filter.addFilter(new TypeFilter( - DependencyUtil.cleanToBeTokenizedString(this.includeTypes), - DependencyUtil.cleanToBeTokenizedString(this.excludeTypes))); - - filter.addFilter(new ClassifierFilter( - DependencyUtil.cleanToBeTokenizedString(this.includeClassifiers), - DependencyUtil.cleanToBeTokenizedString(this.excludeClassifiers))); - - filter.addFilter(new GroupIdFilter( - DependencyUtil.cleanToBeTokenizedString(this.includeGroupIds), - DependencyUtil.cleanToBeTokenizedString(this.excludeGroupIds))); - - filter.addFilter(new ArtifactIdFilter( - DependencyUtil.cleanToBeTokenizedString(this.includeArtifactIds), - DependencyUtil.cleanToBeTokenizedString(this.excludeArtifactIds))); - - return filter; - } - - /** - * This method resolves all transitive dependencies of an artifact. - * - * @param artifact the artifact used to retrieve dependencies - * @return resolved set of dependencies - * @throws DependencyResolverException in case of error while resolving artifacts. - */ - protected Set resolveArtifactDependencies(final DependableCoordinate artifact) - throws DependencyResolverException { - ProjectBuildingRequest buildingRequest = newResolveArtifactProjectBuildingRequest(); - - Iterable artifactResults = - getDependencyResolver().resolveDependencies(buildingRequest, artifact, null); - - Set artifacts = new LinkedHashSet<>(); - - for (final ArtifactResult artifactResult : artifactResults) { - artifacts.add(artifactResult.getArtifact()); - } - - return artifacts; + protected AbstractResolveMojo( + MavenSession session, + BuildContext buildContext, + MavenProject project, + ResolverUtil resolverUtil, + ProjectBuilder projectBuilder, + ArtifactHandlerManager artifactHandlerManager) { + super(session, buildContext, project, resolverUtil, projectBuilder, artifactHandlerManager); } } diff --git a/src/main/java/org/apache/maven/plugins/dependency/resolvers/CollectDependenciesMojo.java b/src/main/java/org/apache/maven/plugins/dependency/resolvers/CollectDependenciesMojo.java index bc23a637d..bd8927586 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/resolvers/CollectDependenciesMojo.java +++ b/src/main/java/org/apache/maven/plugins/dependency/resolvers/CollectDependenciesMojo.java @@ -18,33 +18,51 @@ */ package org.apache.maven.plugins.dependency.resolvers; +import javax.inject.Inject; + +import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager; +import org.apache.maven.execution.MavenSession; import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.ResolutionScope; +import org.apache.maven.plugins.dependency.utils.ResolverUtil; +import org.apache.maven.project.MavenProject; +import org.apache.maven.project.ProjectBuilder; +import org.sonatype.plexus.build.incremental.BuildContext; /** *

      - * Goal that collects the project dependencies from the repository. This goal requires Maven 3.0 or higher to function - * because it uses "requiresDependencyCollection". This means that it lists the groupId:artifactId:version information + * Goal that collects the project dependencies from the repository. This goal + * uses "requiresDependencyCollection" to list the groupId:artifactId:version information * by downloading the pom files without downloading the actual artifacts such as jar files. *

      *

      * This is very useful when full dependency resolution might fail due to projects which haven't been built yet. *

      *

      - * It is identical to {@link ResolveDependenciesMojo} except for using the requiresDependencyCollection annotation - * attribute instead of requiresDependencyResolution. + * It is identical to resolve + * except for using the requiresDependencyCollection annotation attribute instead of requiresDependencyResolution. *

      * * @author Eric Pabst * @author Brian Fox * @since 3.0 */ -// CHECKSTYLE_OFF: LineLength @Mojo( name = "collect", requiresDependencyCollection = ResolutionScope.TEST, defaultPhase = LifecyclePhase.GENERATE_SOURCES, threadSafe = true) -// CHECKSTYLE_ON: LineLength -public class CollectDependenciesMojo extends ResolveDependenciesMojo {} +public class CollectDependenciesMojo extends ResolveDependenciesMojo { + + @Inject + protected CollectDependenciesMojo( + MavenSession session, + BuildContext buildContext, + MavenProject project, + ResolverUtil resolverUtil, + ProjectBuilder projectBuilder, + ArtifactHandlerManager artifactHandlerManager) { + super(session, buildContext, project, resolverUtil, projectBuilder, artifactHandlerManager); + } +} diff --git a/src/main/java/org/apache/maven/plugins/dependency/resolvers/ExcludeReactorProjectsArtifactFilter.java b/src/main/java/org/apache/maven/plugins/dependency/resolvers/ExcludeReactorProjectsArtifactFilter.java index 42e42fec3..a93ef2af7 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/resolvers/ExcludeReactorProjectsArtifactFilter.java +++ b/src/main/java/org/apache/maven/plugins/dependency/resolvers/ExcludeReactorProjectsArtifactFilter.java @@ -22,6 +22,7 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Set; + import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.ArtifactUtils; import org.apache.maven.artifact.resolver.filter.ArtifactFilter; diff --git a/src/main/java/org/apache/maven/plugins/dependency/resolvers/ExcludeReactorProjectsDependencyFilter.java b/src/main/java/org/apache/maven/plugins/dependency/resolvers/ExcludeReactorProjectsDependencyFilter.java index 98a60bfda..ef82569fa 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/resolvers/ExcludeReactorProjectsDependencyFilter.java +++ b/src/main/java/org/apache/maven/plugins/dependency/resolvers/ExcludeReactorProjectsDependencyFilter.java @@ -20,56 +20,39 @@ import java.util.List; import java.util.Set; +import java.util.function.Predicate; import java.util.stream.Collectors; + import org.apache.maven.artifact.ArtifactUtils; import org.apache.maven.model.Dependency; -import org.apache.maven.plugin.logging.Log; import org.apache.maven.project.MavenProject; -import org.apache.maven.shared.artifact.filter.resolve.AbstractFilter; -import org.apache.maven.shared.artifact.filter.resolve.Node; -import org.apache.maven.shared.artifact.filter.resolve.TransformableFilter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** - * {@link TransformableFilter} implementation that excludes artifacts found in the Reactor. + * Filter implementation that excludes artifacts found in the Reactor. * * @author Maarten Mulders */ -public class ExcludeReactorProjectsDependencyFilter extends AbstractFilter { - private final Log log; +public class ExcludeReactorProjectsDependencyFilter implements Predicate { + private final Logger log = LoggerFactory.getLogger(ExcludeReactorProjectsDependencyFilter.class); private final Set reactorArtifactKeys; - public ExcludeReactorProjectsDependencyFilter(final List reactorProjects, final Log log) { - this.log = log; + public ExcludeReactorProjectsDependencyFilter(final List reactorProjects) { this.reactorArtifactKeys = reactorProjects.stream() .map(project -> ArtifactUtils.key(project.getArtifact())) .collect(Collectors.toSet()); } @Override - public boolean accept(final Node node, final List parents) { - final Dependency dependency = node.getDependency(); - if (dependency != null) { - final String dependencyArtifactKey = - ArtifactUtils.key(dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersion()); - - final boolean result = isDependencyArtifactInReactor(dependencyArtifactKey); - - if (log.isDebugEnabled() && result) { - log.debug("Skipped dependency " + dependencyArtifactKey + " because it is present in the reactor"); + public boolean test(Dependency dependency) { + String key = ArtifactUtils.key(dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersion()); + if (reactorArtifactKeys.contains(key)) { + if (log.isDebugEnabled()) { + log.debug("Skipped dependency {} because it is present in the reactor", key); } - - return !result; + return false; } return true; } - - private boolean isDependencyArtifactInReactor(final String dependencyArtifactKey) { - for (final String reactorArtifactKey : this.reactorArtifactKeys) { - // This check only includes GAV. Should we take a look at the types, too? - if (reactorArtifactKey.equals(dependencyArtifactKey)) { - return true; - } - } - return false; - } } diff --git a/src/main/java/org/apache/maven/plugins/dependency/resolvers/GoOfflineMojo.java b/src/main/java/org/apache/maven/plugins/dependency/resolvers/GoOfflineMojo.java index a0f8e09ab..e86d0f832 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/resolvers/GoOfflineMojo.java +++ b/src/main/java/org/apache/maven/plugins/dependency/resolvers/GoOfflineMojo.java @@ -18,159 +18,277 @@ */ package org.apache.maven.plugins.dependency.resolvers; +import javax.inject.Inject; + +import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.HashSet; -import java.util.LinkedHashSet; +import java.util.List; import java.util.Set; +import java.util.function.Predicate; import java.util.stream.Collectors; + +import org.apache.maven.RepositoryUtils; import org.apache.maven.artifact.Artifact; -import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.artifact.DefaultArtifact; +import org.apache.maven.artifact.handler.DefaultArtifactHandler; +import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager; +import org.apache.maven.execution.MavenSession; import org.apache.maven.model.Dependency; +import org.apache.maven.model.DependencyManagement; +import org.apache.maven.model.Plugin; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.plugins.dependency.fromDependencies.AbstractDependencyFilterMojo; import org.apache.maven.plugins.dependency.utils.DependencyUtil; -import org.apache.maven.project.ProjectBuildingRequest; +import org.apache.maven.plugins.dependency.utils.ResolverUtil; +import org.apache.maven.project.MavenProject; +import org.apache.maven.project.ProjectBuilder; +import org.apache.maven.shared.artifact.filter.collection.ArtifactFilterException; +import org.apache.maven.shared.artifact.filter.collection.ArtifactIdFilter; import org.apache.maven.shared.artifact.filter.collection.ArtifactsFilter; -import org.apache.maven.shared.artifact.filter.resolve.TransformableFilter; -import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResult; -import org.apache.maven.shared.transfer.dependencies.DefaultDependableCoordinate; -import org.apache.maven.shared.transfer.dependencies.DependableCoordinate; -import org.apache.maven.shared.transfer.dependencies.resolve.DependencyResolverException; +import org.apache.maven.shared.artifact.filter.collection.ClassifierFilter; +import org.apache.maven.shared.artifact.filter.collection.FilterArtifacts; +import org.apache.maven.shared.artifact.filter.collection.GroupIdFilter; +import org.apache.maven.shared.artifact.filter.collection.ScopeFilter; +import org.apache.maven.shared.artifact.filter.collection.TypeFilter; +import org.eclipse.aether.artifact.ArtifactTypeRegistry; +import org.eclipse.aether.resolution.ArtifactResolutionException; +import org.eclipse.aether.resolution.DependencyResolutionException; +import org.sonatype.plexus.build.incremental.BuildContext; + +import static java.util.Optional.ofNullable; /** * Goal that resolves all project dependencies, including plugins and reports and their dependencies. * - * Brian Fox + * @author Brian Fox * @author Maarten Mulders + * @author Lisa Hardy * @since 2.0 */ @Mojo(name = "go-offline", threadSafe = true) -public class GoOfflineMojo extends AbstractResolveMojo { +public class GoOfflineMojo extends AbstractDependencyFilterMojo { + + /** + * Don't resolve plugins and artifacts that are in the current reactor. + * + * @since 2.7 + */ + @Parameter(property = "excludeReactor", defaultValue = "true") + protected boolean excludeReactor; + + @Inject + // CHECKSTYLE_OFF: ParameterNumber + public GoOfflineMojo( + MavenSession session, + BuildContext buildContext, + MavenProject project, + ResolverUtil resolverUtil, + ProjectBuilder projectBuilder, + ArtifactHandlerManager artifactHandlerManager) { + super(session, buildContext, project, resolverUtil, projectBuilder, artifactHandlerManager); + } + // CHECKSTYLE_ON: ParameterNumber + /** * Main entry into mojo. Gets the list of dependencies, resolves all that are not in the Reactor, and iterates * through displaying the resolved versions. * - * @throws MojoExecutionException with a message if an error occurs. + * @throws MojoExecutionException with a message if an error occurs */ @Override protected void doExecute() throws MojoExecutionException { try { - final Set plugins = resolvePluginArtifacts(); + final Set plugins = getProjectPlugins(); - final Set dependencies = resolveDependencyArtifacts(); + for (Plugin plugin : plugins) { + org.eclipse.aether.artifact.Artifact artifact = + getResolverUtil().resolvePlugin(plugin); - if (!isSilent()) { - for (Artifact artifact : plugins) { - this.getLog().info("Resolved plugin: " + DependencyUtil.getFormattedFileName(artifact, false)); + logMessage("Resolved plugin: " + + DependencyUtil.getFormattedFileName(RepositoryUtils.toArtifact(artifact), false)); + if (!excludeTransitive) { + logMessage("Resolved plugin dependency:"); + List artifacts = + getResolverUtil().resolveDependencies(plugin); + for (org.eclipse.aether.artifact.Artifact a : artifacts) { + logMessage( + " " + DependencyUtil.getFormattedFileName(RepositoryUtils.toArtifact(a), false)); + } } + } - for (Artifact artifact : dependencies) { - this.getLog().info("Resolved dependency: " + DependencyUtil.getFormattedFileName(artifact, false)); - } + final List dependencies = resolveDependencyArtifacts(); + + for (org.eclipse.aether.artifact.Artifact artifact : dependencies) { + logMessage("Resolved dependency: " + + DependencyUtil.getFormattedFileName(RepositoryUtils.toArtifact(artifact), false)); } - } catch (DependencyResolverException e) { + } catch (ArtifactFilterException | ArtifactResolutionException | DependencyResolutionException e) { throw new MojoExecutionException(e.getMessage(), e); } } + private void logMessage(String message) { + if (isSilent()) { + getLog().debug(message); + } else { + getLog().info(message); + } + } + /** * This method resolves the dependency artifacts from the project. * - * @return set of resolved dependency artifacts. - * @throws DependencyResolverException in case of an error while resolving the artifacts. + * @return lis of resolved dependency artifacts + * @throws ArtifactFilterException in case of an error while filtering the artifacts + * @throws DependencyResolutionException in case of an error while resolving the artifacts */ - protected Set resolveDependencyArtifacts() throws DependencyResolverException { + protected List resolveDependencyArtifacts() + throws ArtifactFilterException, DependencyResolutionException { Collection dependencies = getProject().getDependencies(); - Set dependableCoordinates = dependencies.stream() - .map(this::createDependendableCoordinateFromDependency) - .collect(Collectors.toSet()); + dependencies = filterDependencies(dependencies); - ProjectBuildingRequest buildingRequest = newResolveArtifactProjectBuildingRequest(); + Predicate excludeReactorProjectsDependencyFilter = d -> true; + if (this.excludeReactor) { + excludeReactorProjectsDependencyFilter = new ExcludeReactorProjectsDependencyFilter(this.reactorProjects); + } - return resolveDependableCoordinate(buildingRequest, dependableCoordinates, "dependencies"); - } + ArtifactTypeRegistry artifactTypeRegistry = + session.getRepositorySession().getArtifactTypeRegistry(); - private Set resolveDependableCoordinate( - final ProjectBuildingRequest buildingRequest, - final Collection dependableCoordinates, - final String type) - throws DependencyResolverException { - final TransformableFilter filter = getTransformableFilter(); + List dependableCoordinates = dependencies.stream() + .filter(excludeReactorProjectsDependencyFilter) + .map(d -> RepositoryUtils.toDependency(d, artifactTypeRegistry)) + .collect(Collectors.toList()); - this.getLog().debug("Resolving '" + type + "' with following repositories:"); - for (ArtifactRepository repo : buildingRequest.getRemoteRepositories()) { - getLog().debug(repo.getId() + " (" + repo.getUrl() + ")"); - } + List managedDependencies = ofNullable( + getProject().getDependencyManagement()) + .map(DependencyManagement::getDependencies) + .map(list -> list.stream() + .map(d -> RepositoryUtils.toDependency(d, artifactTypeRegistry)) + .collect(Collectors.toList())) + .orElse(null); - final Set results = new HashSet<>(); + return getResolverUtil() + .resolveDependenciesForArtifact( + RepositoryUtils.toArtifact(getProject().getArtifact()), + dependableCoordinates, + managedDependencies, + getProject().getRemoteProjectRepositories()); + } - for (DependableCoordinate dependableCoordinate : dependableCoordinates) { - final Iterable artifactResults = - getDependencyResolver().resolveDependencies(buildingRequest, dependableCoordinate, filter); + /** + * This method retrieve plugins list from the project. + * + * @return set of plugin used in project + */ + private Set getProjectPlugins() { + Predicate pluginsFilter = new PluginsIncludeExcludeFilter( + toList(includeGroupIds), + toList(excludeGroupIds), + toList(includeArtifactIds), + toList(excludeArtifactIds)); - for (final ArtifactResult artifactResult : artifactResults) { - results.add(artifactResult.getArtifact()); - } + Predicate reactorExclusionFilter = plugin -> true; + if (excludeReactor) { + reactorExclusionFilter = new PluginsReactorExcludeFilter(session.getProjects()); } - return results; + return getResolverUtil().getProjectPlugins(getProject()).stream() + .filter(reactorExclusionFilter) + .filter(pluginsFilter) + .collect(Collectors.toSet()); } - private TransformableFilter getTransformableFilter() { - if (this.excludeReactor) { - return new ExcludeReactorProjectsDependencyFilter(this.reactorProjects, getLog()); - } else { - return null; + private List toList(String list) { + if (list == null || list.isEmpty()) { + return Collections.emptyList(); } + return Arrays.asList(DependencyUtil.cleanToBeTokenizedString(list).split(",")); } - /** - * This method resolves the plugin artifacts from the project. - * - * @return set of resolved plugin artifacts. - * @throws DependencyResolverException in case of an error while resolving the artifacts. - */ - protected Set resolvePluginArtifacts() throws DependencyResolverException { + private Collection filterDependencies(Collection deps) throws ArtifactFilterException { - Set plugins = getProject().getPluginArtifacts(); - Set reports = getProject().getReportArtifacts(); + Set artifacts = createArtifactSetFromDependencies(deps); - Set artifacts = new LinkedHashSet<>(); - artifacts.addAll(reports); - artifacts.addAll(plugins); + final FilterArtifacts filter = getArtifactsFilter(); + artifacts = filter.filter(artifacts); - Set dependableCoordinates = artifacts.stream() - .map(this::createDependendableCoordinateFromArtifact) - .collect(Collectors.toSet()); - - ProjectBuildingRequest buildingRequest = newResolvePluginProjectBuildingRequest(); + return createDependencySetFromArtifacts(artifacts); + } - return resolveDependableCoordinate(buildingRequest, dependableCoordinates, "plugins"); + private Set createArtifactSetFromDependencies(Collection deps) { + Set artifacts = new HashSet<>(); + for (Dependency dep : deps) { + DefaultArtifactHandler handler = new DefaultArtifactHandler(dep.getType()); + artifacts.add(new DefaultArtifact( + dep.getGroupId(), + dep.getArtifactId(), + dep.getVersion(), + dep.getScope(), + dep.getType(), + dep.getClassifier(), + handler)); + } + return artifacts; } - private DependableCoordinate createDependendableCoordinateFromArtifact(final Artifact artifact) { - final DefaultDependableCoordinate result = new DefaultDependableCoordinate(); - result.setGroupId(artifact.getGroupId()); - result.setArtifactId(artifact.getArtifactId()); - result.setVersion(artifact.getVersion()); - result.setType(artifact.getType()); - result.setClassifier(artifact.getClassifier()); + private Collection createDependencySetFromArtifacts(Set artifacts) { + Set dependencies = new HashSet<>(); + + for (Artifact artifact : artifacts) { + Dependency d = new Dependency(); + d.setGroupId(artifact.getGroupId()); + d.setArtifactId(artifact.getArtifactId()); + d.setVersion(artifact.getVersion()); + d.setType(artifact.getType()); + d.setClassifier(artifact.getClassifier()); + d.setScope(artifact.getScope()); + dependencies.add(d); + } - return result; + return dependencies; } - private DependableCoordinate createDependendableCoordinateFromDependency(final Dependency dependency) { - final DefaultDependableCoordinate result = new DefaultDependableCoordinate(); - result.setGroupId(dependency.getGroupId()); - result.setArtifactId(dependency.getArtifactId()); - result.setVersion(dependency.getVersion()); - result.setType(dependency.getType()); - result.setClassifier(dependency.getClassifier()); + /** + * @return {@link FilterArtifacts} + */ + // TODO: refactor this to use Resolver API filters + protected FilterArtifacts getArtifactsFilter() { + final FilterArtifacts filter = new FilterArtifacts(); + + if (excludeReactor) { + filter.addFilter(new ExcludeReactorProjectsArtifactFilter(reactorProjects, getLog())); + } + + filter.addFilter(new ScopeFilter( + DependencyUtil.cleanToBeTokenizedString(this.includeScope), + DependencyUtil.cleanToBeTokenizedString(this.excludeScope))); + + filter.addFilter(new TypeFilter( + DependencyUtil.cleanToBeTokenizedString(this.includeTypes), + DependencyUtil.cleanToBeTokenizedString(this.excludeTypes))); + + filter.addFilter(new ClassifierFilter( + DependencyUtil.cleanToBeTokenizedString(this.includeClassifiers), + DependencyUtil.cleanToBeTokenizedString(this.excludeClassifiers))); + + filter.addFilter(new GroupIdFilter( + DependencyUtil.cleanToBeTokenizedString(this.includeGroupIds), + DependencyUtil.cleanToBeTokenizedString(this.excludeGroupIds))); + + filter.addFilter(new ArtifactIdFilter( + DependencyUtil.cleanToBeTokenizedString(this.includeArtifactIds), + DependencyUtil.cleanToBeTokenizedString(this.excludeArtifactIds))); - return result; + return filter; } @Override diff --git a/src/main/java/org/apache/maven/plugins/dependency/resolvers/ListMojo.java b/src/main/java/org/apache/maven/plugins/dependency/resolvers/ListMojo.java index 54cb52c46..306b12d98 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/resolvers/ListMojo.java +++ b/src/main/java/org/apache/maven/plugins/dependency/resolvers/ListMojo.java @@ -18,8 +18,16 @@ */ package org.apache.maven.plugins.dependency.resolvers; +import javax.inject.Inject; + +import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager; +import org.apache.maven.execution.MavenSession; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.ResolutionScope; +import org.apache.maven.plugins.dependency.utils.ResolverUtil; +import org.apache.maven.project.MavenProject; +import org.apache.maven.project.ProjectBuilder; +import org.sonatype.plexus.build.incremental.BuildContext; /** * Displays the list of dependencies for this project. @@ -29,5 +37,18 @@ */ @Mojo(name = "list", requiresDependencyResolution = ResolutionScope.TEST, threadSafe = true) public class ListMojo extends ResolveDependenciesMojo { + + @Inject + // CHECKSTYLE_OFF: ParameterNumber + public ListMojo( + MavenSession session, + BuildContext buildContext, + MavenProject project, + ResolverUtil resolverUtil, + ProjectBuilder projectBuilder, + ArtifactHandlerManager artifactHandlerManager) { + super(session, buildContext, project, resolverUtil, projectBuilder, artifactHandlerManager); + } + // CHECKSTYLE_ON: ParameterNumber // alias for dependency:resolve } diff --git a/src/main/java/org/apache/maven/plugins/dependency/resolvers/ListRepositoriesMojo.java b/src/main/java/org/apache/maven/plugins/dependency/resolvers/ListRepositoriesMojo.java deleted file mode 100644 index 59a785ce3..000000000 --- a/src/main/java/org/apache/maven/plugins/dependency/resolvers/ListRepositoriesMojo.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.maven.plugins.dependency.resolvers; - -import org.apache.maven.artifact.repository.ArtifactRepository; -import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugins.annotations.Component; -import org.apache.maven.plugins.annotations.Mojo; -import org.apache.maven.plugins.annotations.ResolutionScope; -import org.apache.maven.plugins.dependency.AbstractDependencyMojo; -import org.apache.maven.shared.transfer.dependencies.collect.CollectorResult; -import org.apache.maven.shared.transfer.dependencies.collect.DependencyCollector; -import org.apache.maven.shared.transfer.dependencies.collect.DependencyCollectorException; - -/** - * Goal that resolves all project dependencies and then lists the repositories used by the build and by the transitive - * dependencies - * - * @author Brian Fox - * @since 2.2 - */ -@Mojo(name = "list-repositories", requiresDependencyResolution = ResolutionScope.TEST, threadSafe = true) -public class ListRepositoriesMojo extends AbstractDependencyMojo { - /** - * Dependency collector, needed to resolve dependencies. - */ - @Component(role = DependencyCollector.class) - private DependencyCollector dependencyCollector; - - /** - * Displays a list of the repositories used by this build. - * - * @throws MojoExecutionException with a message if an error occurs. - */ - @Override - protected void doExecute() throws MojoExecutionException { - try { - CollectorResult collectResult = dependencyCollector.collectDependencies( - session.getProjectBuildingRequest(), getProject().getModel()); - - this.getLog().info("Repositories used by this build:"); - - for (ArtifactRepository repo : collectResult.getRemoteRepositories()) { - this.getLog().info(repo.toString()); - } - } catch (DependencyCollectorException e) { - throw new MojoExecutionException("Unable to resolve artifacts", e); - } - } -} diff --git a/src/main/java/org/apache/maven/plugins/dependency/resolvers/OldResolveDependencySourcesMojo.java b/src/main/java/org/apache/maven/plugins/dependency/resolvers/OldResolveDependencySourcesMojo.java new file mode 100644 index 000000000..866c1b84e --- /dev/null +++ b/src/main/java/org/apache/maven/plugins/dependency/resolvers/OldResolveDependencySourcesMojo.java @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.maven.plugins.dependency.resolvers; + +import javax.inject.Inject; + +import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager; +import org.apache.maven.execution.MavenSession; +import org.apache.maven.plugins.annotations.LifecyclePhase; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.ResolutionScope; +import org.apache.maven.plugins.dependency.utils.ResolverUtil; +import org.apache.maven.project.MavenProject; +import org.apache.maven.project.ProjectBuilder; +import org.sonatype.plexus.build.incremental.BuildContext; + +/** + * Goal that resolves the project source dependencies from the repository. + * + * @author Brian Fox + * @since 2.0-alpha2 + * @deprecated in favor of {@code resolve-sources} goal and will be removed in a future version + */ +@Mojo( + name = "sources", + defaultPhase = LifecyclePhase.GENERATE_SOURCES, + requiresDependencyResolution = ResolutionScope.TEST, + threadSafe = true) +@Deprecated +public class OldResolveDependencySourcesMojo extends ResolveDependencySourcesMojo { + + @Inject + // CHECKSTYLE_OFF: ParameterNumber + public OldResolveDependencySourcesMojo( + MavenSession session, + BuildContext buildContext, + MavenProject project, + ResolverUtil resolverUtil, + ProjectBuilder projectBuilder, + ArtifactHandlerManager artifactHandlerManager) { + super(session, buildContext, project, resolverUtil, projectBuilder, artifactHandlerManager); + } + // CHECKSTYLE_ON: ParameterNumber +} diff --git a/src/main/java/org/apache/maven/plugins/dependency/resolvers/PluginsIncludeExcludeFilter.java b/src/main/java/org/apache/maven/plugins/dependency/resolvers/PluginsIncludeExcludeFilter.java new file mode 100644 index 000000000..7de7a7f44 --- /dev/null +++ b/src/main/java/org/apache/maven/plugins/dependency/resolvers/PluginsIncludeExcludeFilter.java @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.maven.plugins.dependency.resolvers; + +import java.util.List; +import java.util.function.Predicate; + +import org.apache.maven.model.Plugin; + +/** + * A filter to include or exclude plugins. + */ +class PluginsIncludeExcludeFilter implements Predicate { + private final List includesGroupId; + + private final List excludesGroupId; + + private final List includesArtifactId; + + private final List excludesArtifactId; + + PluginsIncludeExcludeFilter( + List includeGroupIds, + List excludeGroupIds, + List includeArtifactIds, + List excludeArtifactIds) { + this.includesGroupId = includeGroupIds; + this.excludesGroupId = excludeGroupIds; + this.includesArtifactId = includeArtifactIds; + this.excludesArtifactId = excludeArtifactIds; + } + + @Override + public boolean test(Plugin plugin) { + if (!includesGroupId.isEmpty() && !includesGroupId.contains(plugin.getGroupId())) { + return false; + } + + if (excludesGroupId.contains(plugin.getGroupId())) { + return false; + } + + if (!includesArtifactId.isEmpty() && !includesArtifactId.contains(plugin.getArtifactId())) { + return false; + } + + return !excludesArtifactId.contains(plugin.getArtifactId()); + } +} diff --git a/src/main/java/org/apache/maven/plugins/dependency/resolvers/PluginsReactorExcludeFilter.java b/src/main/java/org/apache/maven/plugins/dependency/resolvers/PluginsReactorExcludeFilter.java new file mode 100644 index 000000000..42c11c3ac --- /dev/null +++ b/src/main/java/org/apache/maven/plugins/dependency/resolvers/PluginsReactorExcludeFilter.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.maven.plugins.dependency.resolvers; + +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; +import java.util.function.Predicate; + +import org.apache.maven.artifact.ArtifactUtils; +import org.apache.maven.model.Plugin; +import org.apache.maven.project.MavenProject; + +/** + * A filter to exclude plugins that are part of the current reactor build. + */ +class PluginsReactorExcludeFilter implements Predicate { + + private final Set reactorArtifactKeys; + + PluginsReactorExcludeFilter(List reactorProjects) { + this.reactorArtifactKeys = new LinkedHashSet<>(reactorProjects.size()); + for (final MavenProject project : reactorProjects) { + this.reactorArtifactKeys.add(ArtifactUtils.key(project.getArtifact())); + } + } + + @Override + public boolean test(Plugin plugin) { + String pluginKey = ArtifactUtils.key(plugin.getGroupId(), plugin.getArtifactId(), plugin.getVersion()); + return !reactorArtifactKeys.contains(pluginKey); + } +} diff --git a/src/main/java/org/apache/maven/plugins/dependency/resolvers/ResolveDependenciesMojo.java b/src/main/java/org/apache/maven/plugins/dependency/resolvers/ResolveDependenciesMojo.java index be09c9afb..b9bf0fb5b 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/resolvers/ResolveDependenciesMojo.java +++ b/src/main/java/org/apache/maven/plugins/dependency/resolvers/ResolveDependenciesMojo.java @@ -18,6 +18,8 @@ */ package org.apache.maven.plugins.dependency.resolvers; +import javax.inject.Inject; + import java.io.File; import java.io.IOException; import java.lang.reflect.InvocationTargetException; @@ -30,7 +32,10 @@ import java.util.Set; import java.util.jar.JarFile; import java.util.jar.Manifest; + import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager; +import org.apache.maven.execution.MavenSession; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; @@ -38,33 +43,35 @@ import org.apache.maven.plugins.annotations.ResolutionScope; import org.apache.maven.plugins.dependency.utils.DependencyStatusSets; import org.apache.maven.plugins.dependency.utils.DependencyUtil; +import org.apache.maven.plugins.dependency.utils.ResolverUtil; import org.apache.maven.plugins.dependency.utils.filters.ResolveFileFilter; import org.apache.maven.plugins.dependency.utils.markers.SourcesFileMarkerHandler; +import org.apache.maven.project.MavenProject; +import org.apache.maven.project.ProjectBuilder; import org.apache.maven.shared.artifact.filter.collection.ArtifactsFilter; import org.apache.maven.shared.utils.logging.MessageBuilder; import org.apache.maven.shared.utils.logging.MessageUtils; +import org.sonatype.plexus.build.incremental.BuildContext; /** - * Goal that resolves the project dependencies from the repository. When using this goal while running on Java 9 the + * Goal that resolves the project dependencies from the repository. When running on Java 9, the * module names will be visible as well. * * @author Brian Fox * @since 2.0 */ -// CHECKSTYLE_OFF: LineLength @Mojo( name = "resolve", requiresDependencyResolution = ResolutionScope.TEST, defaultPhase = LifecyclePhase.GENERATE_SOURCES, threadSafe = true) -// CHECKSTYLE_ON: LineLength public class ResolveDependenciesMojo extends AbstractResolveMojo { @Parameter(property = "outputEncoding", defaultValue = "${project.reporting.outputEncoding}") private String outputEncoding; /** - * If we should display the scope when resolving + * If we should display the scope when resolving. * * @since 2.0-alpha-2 */ @@ -72,7 +79,15 @@ public class ResolveDependenciesMojo extends AbstractResolveMojo { protected boolean outputScope; /** - * Only used to store results for integration test validation + * Output absolute filename for resolved artifacts. + * + * @since 2.0 + */ + @Parameter(property = "outputAbsoluteArtifactFilename", defaultValue = "false") + private boolean outputAbsoluteArtifactFilename; + + /** + * Only used to store results for integration test validation. */ DependencyStatusSets results; @@ -92,6 +107,19 @@ public class ResolveDependenciesMojo extends AbstractResolveMojo { @Parameter(property = "includeParents", defaultValue = "false") boolean includeParents; + @Inject + // CHECKSTYLE_OFF: ParameterNumber + public ResolveDependenciesMojo( + MavenSession session, + BuildContext buildContext, + MavenProject project, + ResolverUtil resolverUtil, + ProjectBuilder projectBuilder, + ArtifactHandlerManager artifactHandlerManager) { + super(session, buildContext, project, resolverUtil, projectBuilder, artifactHandlerManager); + } + // CHECKSTYLE_ON: ParameterNumber + /** * Main entry into mojo. Gets the list of dependencies and iterates through displaying the resolved version. * @@ -135,7 +163,9 @@ protected ArtifactsFilter getMarkedArtifactFilter() { */ public String getOutput(boolean outputAbsoluteArtifactFilename, boolean theOutputScope, boolean theSort) { StringBuilder sb = new StringBuilder(); - sb.append(System.lineSeparator()); + if (outputFile == null) { + sb.append(System.lineSeparator()); + } sb.append("The following files have been resolved:"); sb.append(System.lineSeparator()); if (results.getResolvedDependencies() == null @@ -175,9 +205,13 @@ private StringBuilder buildArtifactListOutput( Set artifacts, boolean outputAbsoluteArtifactFilename, boolean theOutputScope, boolean theSort) { StringBuilder sb = new StringBuilder(); List artifactStringList = new ArrayList<>(); + /* if (outputFile != null) { + MessageUtils.setColorEnabled(false); + } else { + MessageUtils.setColorEnabled(true); + } */ for (Artifact artifact : artifacts) { MessageBuilder messageBuilder = MessageUtils.buffer(); - messageBuilder.a(" "); if (theOutputScope) { @@ -217,7 +251,7 @@ private StringBuilder buildArtifactListOutput( } } } - artifactStringList.add(messageBuilder + System.lineSeparator()); + artifactStringList.add(messageBuilder.build() + System.lineSeparator()); } if (theSort) { Collections.sort(artifactStringList); @@ -277,7 +311,7 @@ private ModuleDescriptor getModuleDescriptor(File artifactFile) { } catch (ClassNotFoundException | SecurityException | IllegalAccessException | IllegalArgumentException e) { // do nothing } catch (NoSuchMethodException e) { - e.printStackTrace(); + getLog().warn(e); } catch (InvocationTargetException e) { Throwable cause = e.getCause(); while (cause.getCause() != null) { @@ -288,7 +322,7 @@ private ModuleDescriptor getModuleDescriptor(File artifactFile) { return moduleDescriptor; } - private class ModuleDescriptor { + private static class ModuleDescriptor { String name; boolean automatic = true; diff --git a/src/main/java/org/apache/maven/plugins/dependency/resolvers/ResolveDependencySourcesMojo.java b/src/main/java/org/apache/maven/plugins/dependency/resolvers/ResolveDependencySourcesMojo.java index 21e8cce3b..24c7b7a67 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/resolvers/ResolveDependencySourcesMojo.java +++ b/src/main/java/org/apache/maven/plugins/dependency/resolvers/ResolveDependencySourcesMojo.java @@ -18,37 +18,49 @@ */ package org.apache.maven.plugins.dependency.resolvers; -import org.apache.maven.plugin.MojoExecutionException; +import javax.inject.Inject; + +import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager; +import org.apache.maven.execution.MavenSession; import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.plugins.annotations.ResolutionScope; +import org.apache.maven.plugins.dependency.utils.ResolverUtil; +import org.apache.maven.project.MavenProject; +import org.apache.maven.project.ProjectBuilder; +import org.sonatype.plexus.build.incremental.BuildContext; /** * Goal that resolves the project source dependencies from the repository. * * @author Brian Fox - * @since 2.0-alpha2 + * @since 2.0-alpha2/3.7.0 */ @Mojo( - name = "sources", + name = "resolve-sources", defaultPhase = LifecyclePhase.GENERATE_SOURCES, requiresDependencyResolution = ResolutionScope.TEST, threadSafe = true) public class ResolveDependencySourcesMojo extends ResolveDependenciesMojo { - private static final String SOURCE_CLASSIFIER = "sources"; + private static final String SOURCES_CLASSIFIER = "sources"; - /** - * Main entry into mojo. Gets the list of dependencies and iterates through resolving the source jars. - * - * @throws MojoExecutionException with a message if an error occurs. - */ - @Override - protected void doExecute() throws MojoExecutionException { - if (this.classifier == null || this.classifier.isEmpty()) { - this.classifier = SOURCE_CLASSIFIER; - } + @Inject + // CHECKSTYLE_OFF: ParameterNumber + public ResolveDependencySourcesMojo( + MavenSession session, + BuildContext buildContext, + MavenProject project, + ResolverUtil resolverUtil, + ProjectBuilder projectBuilder, + ArtifactHandlerManager artifactHandlerManager) { + super(session, buildContext, project, resolverUtil, projectBuilder, artifactHandlerManager); + } + // CHECKSTYLE_ON: ParameterNumber - super.doExecute(); + @Parameter(name = "classifier", defaultValue = SOURCES_CLASSIFIER, readonly = true) + public void setClassifier(String classifier) { + this.classifier = classifier; } } diff --git a/src/main/java/org/apache/maven/plugins/dependency/resolvers/ResolvePluginsMojo.java b/src/main/java/org/apache/maven/plugins/dependency/resolvers/ResolvePluginsMojo.java index b2393f717..2840ae615 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/resolvers/ResolvePluginsMojo.java +++ b/src/main/java/org/apache/maven/plugins/dependency/resolvers/ResolvePluginsMojo.java @@ -18,23 +18,31 @@ */ package org.apache.maven.plugins.dependency.resolvers; +import javax.inject.Inject; + +import java.io.File; import java.io.IOException; -import java.util.LinkedHashSet; +import java.util.List; import java.util.Objects; +import java.util.Optional; import java.util.Set; -import org.apache.maven.artifact.Artifact; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +import org.apache.maven.execution.MavenSession; +import org.apache.maven.model.Plugin; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.plugins.dependency.AbstractDependencyMojo; import org.apache.maven.plugins.dependency.utils.DependencyUtil; -import org.apache.maven.project.ProjectBuildingRequest; -import org.apache.maven.shared.artifact.filter.collection.ArtifactFilterException; -import org.apache.maven.shared.artifact.filter.collection.ArtifactsFilter; -import org.apache.maven.shared.artifact.filter.collection.FilterArtifacts; -import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResolverException; -import org.apache.maven.shared.transfer.dependencies.DefaultDependableCoordinate; -import org.apache.maven.shared.transfer.dependencies.resolve.DependencyResolverException; +import org.apache.maven.plugins.dependency.utils.ResolverUtil; +import org.apache.maven.project.MavenProject; +import org.eclipse.aether.artifact.Artifact; +import org.eclipse.aether.resolution.ArtifactResolutionException; +import org.eclipse.aether.resolution.DependencyResolutionException; +import org.sonatype.plexus.build.incremental.BuildContext; /** * Goal that resolves all project plugins and reports and their dependencies. @@ -43,66 +51,144 @@ * @since 2.0 */ @Mojo(name = "resolve-plugins", defaultPhase = LifecyclePhase.GENERATE_SOURCES, threadSafe = true) -public class ResolvePluginsMojo extends AbstractResolveMojo { +public class ResolvePluginsMojo extends AbstractDependencyMojo { + + /** + * If specified, this parameter causes the dependencies to be written to the path specified instead of + * the console. + * + * @since 2.0 + */ + @Parameter(property = "outputFile") + protected File outputFile; + + /** + * If we should exclude transitive dependencies. + * This means only the plugin artifacts itself will be resolved not plugin dependencies. + * + * @since 2.0 + */ + @Parameter(property = "excludeTransitive", defaultValue = "false") + protected boolean excludeTransitive; + + /** + * List of artifact IDs to exclude. + * + * @since 2.0 + */ + @Parameter(property = "excludeArtifactIds", defaultValue = "") + protected List excludeArtifactIds; + + /** + * List of artifact IDs to include. Empty list indicates include everything (default). + * + * @since 2.0 + */ + @Parameter(property = "includeArtifactIds", defaultValue = "") + protected List includeArtifactIds; + + /** + * List of group IDs to exclude. + * + * @since 2.0 + */ + @Parameter(property = "excludeGroupIds", defaultValue = "") + protected List excludeGroupIds; + + /** + * List of group IDs to include. Empty list indicates include everything (default). + * + * @since 2.0 + */ + @Parameter(property = "includeGroupIds", defaultValue = "") + protected List includeGroupIds; + /** + * Whether to append outputs into the output file or overwrite it. + * + * @since 2.2 + */ + @Parameter(property = "appendOutput", defaultValue = "false") + protected boolean appendOutput; + + /** + * Don't resolve plugins that are in the current reactor. + * + * @since 2.7 + */ + @Parameter(property = "excludeReactor", defaultValue = "true") + protected boolean excludeReactor; + + /** + * The encoding of the output file. + * + * @since 3.2.0 + */ @Parameter(property = "outputEncoding", defaultValue = "${project.reporting.outputEncoding}") private String outputEncoding; + /** + * Output absolute filename for resolved artifacts. + * + * @since 2.0 + */ + @Parameter(property = "outputAbsoluteArtifactFilename", defaultValue = "false") + private boolean outputAbsoluteArtifactFilename; + + private final ResolverUtil resolverUtil; + + @Inject + public ResolvePluginsMojo( + MavenSession session, BuildContext buildContext, MavenProject project, ResolverUtil resolverUtil) { + super(session, buildContext, project); + this.resolverUtil = resolverUtil; + } + /** * Main entry into mojo. Gets the list of dependencies and iterates through displaying the resolved version. * - * @throws MojoExecutionException with a message if an error occurs. + * @throws MojoExecutionException with a message if an error occurs */ @Override protected void doExecute() throws MojoExecutionException { try { // ideally this should either be DependencyCoordinates or DependencyNode - final Set plugins = resolvePluginArtifacts(); + final Set plugins = getProjectPlugins(); StringBuilder sb = new StringBuilder(); sb.append(System.lineSeparator()); sb.append("The following plugins have been resolved:"); sb.append(System.lineSeparator()); - if (plugins == null || plugins.isEmpty()) { + if (plugins.isEmpty()) { sb.append(" none"); sb.append(System.lineSeparator()); } else { - for (Artifact plugin : plugins) { + for (Plugin plugin : plugins) { + Artifact pluginArtifact = resolverUtil.resolvePlugin(plugin); String artifactFilename = null; if (outputAbsoluteArtifactFilename) { - try { - // we want to print the absolute file name here - artifactFilename = - plugin.getFile().getAbsoluteFile().getPath(); - } catch (NullPointerException e) { - // ignore the null pointer, we'll output a null string - artifactFilename = null; - } + // we want to print the absolute file name here + artifactFilename = Optional.ofNullable(pluginArtifact.getFile()) + .map(File::getAbsoluteFile) + .map(File::getPath) + .orElse(null); } - String id = plugin.toString(); + String id = pluginArtifact.toString(); sb.append(" ") .append(id) .append(outputAbsoluteArtifactFilename ? ":" + artifactFilename : "") .append(System.lineSeparator()); if (!excludeTransitive) { - DefaultDependableCoordinate pluginCoordinate = new DefaultDependableCoordinate(); - pluginCoordinate.setGroupId(plugin.getGroupId()); - pluginCoordinate.setArtifactId(plugin.getArtifactId()); - pluginCoordinate.setVersion(plugin.getVersion()); - - for (final Artifact artifact : resolveArtifactDependencies(pluginCoordinate)) { + for (Artifact artifact : resolverUtil.resolveDependencies(plugin)) { artifactFilename = null; if (outputAbsoluteArtifactFilename) { - try { - // we want to print the absolute file name here - artifactFilename = - artifact.getFile().getAbsoluteFile().getPath(); - } catch (NullPointerException e) { - // ignore the null pointer, we'll output a null string - artifactFilename = null; - } + // we want to print the absolute file name here + artifactFilename = Optional.ofNullable(artifact.getFile()) + .map(File::getAbsoluteFile) + .map(File::getPath) + .orElse(null); } id = artifact.toString(); @@ -123,58 +209,29 @@ protected void doExecute() throws MojoExecutionException { DependencyUtil.write(output, outputFile, appendOutput, encoding); } } - } catch (IOException | ArtifactFilterException | ArtifactResolverException | DependencyResolverException e) { + } catch (IOException | ArtifactResolutionException | DependencyResolutionException e) { throw new MojoExecutionException(e.getMessage(), e); } } /** - * This method resolves the plugin artifacts from the project. + * This return plugin list of the project after applying the include/exclude filters. * - * @return set of resolved plugin artifacts - * @throws ArtifactFilterException in case of an error - * @throws ArtifactResolverException in case of an error + * @return set of project plugin */ - protected Set resolvePluginArtifacts() throws ArtifactFilterException, ArtifactResolverException { - final Set plugins = getProject().getPluginArtifacts(); - final Set reports = getProject().getReportArtifacts(); - - Set artifacts = new LinkedHashSet<>(); - artifacts.addAll(reports); - artifacts.addAll(plugins); - - final FilterArtifacts filter = getArtifactsFilter(); - artifacts = filter.filter(artifacts); - - Set resolvedArtifacts = new LinkedHashSet<>(artifacts.size()); - // final ArtifactFilter filter = getPluginFilter(); - for (final Artifact artifact : new LinkedHashSet<>(artifacts)) { - // if ( !filter.include( artifact ) ) - // { - // final String logStr = - // String.format( " Plugin SKIPPED: %s", DependencyUtil.getFormattedFileName( artifact, false ) ); - // - // if ( !silent ) - // { - // this.getLog().info( logStr ); - // } - // - // artifacts.remove( artifact ); - // continue; - // } - - ProjectBuildingRequest buildingRequest = newResolvePluginProjectBuildingRequest(); - - // resolve the new artifact - resolvedArtifacts.add(getArtifactResolver() - .resolveArtifact(buildingRequest, artifact) - .getArtifact()); + private Set getProjectPlugins() { + + Predicate pluginsFilter = new PluginsIncludeExcludeFilter( + includeGroupIds, excludeGroupIds, includeArtifactIds, excludeArtifactIds); + + Predicate reactorExclusionFilter = plugin -> true; + if (excludeReactor) { + reactorExclusionFilter = new PluginsReactorExcludeFilter(session.getProjects()); } - return artifacts; - } - @Override - protected ArtifactsFilter getMarkedArtifactFilter() { - return null; + return resolverUtil.getProjectPlugins(getProject()).stream() + .filter(reactorExclusionFilter) + .filter(pluginsFilter) + .collect(Collectors.toSet()); } } diff --git a/src/main/java/org/apache/maven/plugins/dependency/tree/AbstractSerializingVisitor.java b/src/main/java/org/apache/maven/plugins/dependency/tree/AbstractSerializingVisitor.java index 8f8f40ed8..658813164 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/tree/AbstractSerializingVisitor.java +++ b/src/main/java/org/apache/maven/plugins/dependency/tree/AbstractSerializingVisitor.java @@ -18,7 +18,6 @@ */ package org.apache.maven.plugins.dependency.tree; -import java.io.PrintWriter; import java.io.Writer; /** @@ -31,7 +30,7 @@ public abstract class AbstractSerializingVisitor { /** * The writer to serialize to. */ - protected final PrintWriter writer; + protected final Writer writer; /** * Constructor. @@ -39,13 +38,9 @@ public abstract class AbstractSerializingVisitor { * Build a new AbstractSerializingDependencyNodeVisitor with the writer to serialize to. *

      * - * @param writer the writer to serialize to. + * @param writer the writer to serialize to */ public AbstractSerializingVisitor(Writer writer) { - if (writer instanceof PrintWriter) { - this.writer = (PrintWriter) writer; - } else { - this.writer = new PrintWriter(writer, true); - } + this.writer = writer; } } diff --git a/src/main/java/org/apache/maven/plugins/dependency/tree/BuildingDependencyNodeVisitor.java b/src/main/java/org/apache/maven/plugins/dependency/tree/BuildingDependencyNodeVisitor.java index 7834c50db..411a1fb5c 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/tree/BuildingDependencyNodeVisitor.java +++ b/src/main/java/org/apache/maven/plugins/dependency/tree/BuildingDependencyNodeVisitor.java @@ -21,6 +21,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Stack; + import org.apache.maven.artifact.Artifact; import org.apache.maven.model.Exclusion; import org.apache.maven.shared.dependency.graph.DependencyNode; @@ -69,7 +70,7 @@ public BuildingDependencyNodeVisitor() { public BuildingDependencyNodeVisitor(DependencyNodeVisitor visitor) { this.visitor = visitor; - parentNodes = new Stack(); + parentNodes = new Stack<>(); } // DependencyNodeVisitor methods ------------------------------------------ @@ -89,7 +90,7 @@ public boolean visit(DependencyNode node) { node.getOptional(), node.getExclusions(), node.toNodeString()); - newNode.setChildren(new ArrayList()); + newNode.setChildren(new ArrayList<>()); if (parentNodes.empty()) { rootNode = newNode; diff --git a/src/main/java/org/apache/maven/plugins/dependency/tree/DOTDependencyNodeVisitor.java b/src/main/java/org/apache/maven/plugins/dependency/tree/DOTDependencyNodeVisitor.java index bf4e0a947..0508a313a 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/tree/DOTDependencyNodeVisitor.java +++ b/src/main/java/org/apache/maven/plugins/dependency/tree/DOTDependencyNodeVisitor.java @@ -18,8 +18,11 @@ */ package org.apache.maven.plugins.dependency.tree; +import java.io.IOException; +import java.io.UncheckedIOException; import java.io.Writer; import java.util.List; + import org.apache.maven.shared.dependency.graph.DependencyNode; import org.apache.maven.shared.dependency.graph.traversal.DependencyNodeVisitor; @@ -35,7 +38,7 @@ public class DOTDependencyNodeVisitor extends AbstractSerializingVisitor impleme /** * Constructor. * - * @param writer the writer to write to. + * @param writer the writer to write to */ public DOTDependencyNodeVisitor(Writer writer) { super(writer); @@ -46,16 +49,23 @@ public DOTDependencyNodeVisitor(Writer writer) { */ @Override public boolean visit(DependencyNode node) { - if (node.getParent() == null || node.getParent() == node) { - writer.write("digraph \"" + node.toNodeString() + "\" { " + System.lineSeparator()); - } + try { + if (node.getParent() == null || node.getParent() == node) { + writer.write("digraph \"" + node.toNodeString() + "\" { " + System.lineSeparator()); + writer.flush(); + } - // Generate "currentNode -> Child" lines + // Generate "currentNode -> Child" lines - List children = node.getChildren(); + List children = node.getChildren(); - for (DependencyNode child : children) { - writer.println("\t\"" + node.toNodeString() + "\" -> \"" + child.toNodeString() + "\" ; "); + for (DependencyNode child : children) { + writer.write("\t\"" + node.toNodeString() + "\" -> \"" + child.toNodeString() + "\" ; " + + System.lineSeparator()); + } + writer.flush(); + } catch (IOException e) { + throw new UncheckedIOException("Failed to write DOT format output", e); } return true; @@ -66,8 +76,13 @@ public boolean visit(DependencyNode node) { */ @Override public boolean endVisit(DependencyNode node) { - if (node.getParent() == null || node.getParent() == node) { - writer.write(" } "); + try { + if (node.getParent() == null || node.getParent() == node) { + writer.write(" } " + System.lineSeparator()); + writer.flush(); + } + } catch (IOException e) { + throw new UncheckedIOException("Failed to write DOT format output", e); } return true; } diff --git a/src/main/java/org/apache/maven/plugins/dependency/tree/GraphmlDependencyNodeVisitor.java b/src/main/java/org/apache/maven/plugins/dependency/tree/GraphmlDependencyNodeVisitor.java index 11f75ff85..c81a81a61 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/tree/GraphmlDependencyNodeVisitor.java +++ b/src/main/java/org/apache/maven/plugins/dependency/tree/GraphmlDependencyNodeVisitor.java @@ -18,7 +18,10 @@ */ package org.apache.maven.plugins.dependency.tree; +import java.io.IOException; +import java.io.UncheckedIOException; import java.io.Writer; + import org.apache.maven.shared.dependency.graph.DependencyNode; import org.apache.maven.shared.dependency.graph.traversal.DependencyNodeVisitor; @@ -52,7 +55,7 @@ public class GraphmlDependencyNodeVisitor extends AbstractSerializingVisitor imp /** * Constructor. * - * @param writer the writer to write to. + * @param writer the writer to write to */ public GraphmlDependencyNodeVisitor(Writer writer) { super(writer); @@ -63,19 +66,24 @@ public GraphmlDependencyNodeVisitor(Writer writer) { */ @Override public boolean endVisit(DependencyNode node) { - if (node.getParent() == null || node.getParent() == node) { - writer.write(GRAPHML_FOOTER); - } else { - DependencyNode p = node.getParent(); - writer.print(""); - if (node.getArtifact().getScope() != null) { - // add Edge label - writer.print("" - + node.getArtifact().getScope() + ""); + try { + if (node.getParent() == null || node.getParent() == node) { + writer.write(GRAPHML_FOOTER); + } else { + DependencyNode p = node.getParent(); + writer.write(""); + if (node.getArtifact().getScope() != null) { + // add Edge label + writer.write("" + + node.getArtifact().getScope() + ""); + } + writer.write("" + System.lineSeparator()); } - writer.println(""); + writer.flush(); + return true; + } catch (IOException e) { + throw new UncheckedIOException("Failed to write GraphML format output", e); } - return true; } /** @@ -83,16 +91,22 @@ public boolean endVisit(DependencyNode node) { */ @Override public boolean visit(DependencyNode node) { - if (node.getParent() == null || node.getParent() == node) { - writer.write(GRAPHML_HEADER); + try { + if (node.getParent() == null || node.getParent() == node) { + writer.write(GRAPHML_HEADER); + writer.flush(); + } + // write node + writer.write(""); + // add node label + writer.write("" + node.toNodeString() + + ""); + writer.write("" + System.lineSeparator()); + writer.flush(); + return true; + } catch (IOException e) { + throw new UncheckedIOException("Failed to write GraphML format output", e); } - // write node - writer.print(""); - // add node label - writer.print("" + node.toNodeString() - + ""); - writer.println(""); - return true; } /** @@ -101,8 +115,8 @@ public boolean visit(DependencyNode node) { * Current implementation is rather simple and uses hashcode. *

      * - * @param node the DependencyNode to use. - * @return the unique id. + * @param node the DependencyNode to use + * @return the unique id */ private static String generateId(DependencyNode node) { return String.valueOf(node.hashCode()); diff --git a/src/main/java/org/apache/maven/plugins/dependency/tree/JsonDependencyNodeVisitor.java b/src/main/java/org/apache/maven/plugins/dependency/tree/JsonDependencyNodeVisitor.java new file mode 100644 index 000000000..5faefbf1a --- /dev/null +++ b/src/main/java/org/apache/maven/plugins/dependency/tree/JsonDependencyNodeVisitor.java @@ -0,0 +1,212 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.maven.plugins.dependency.tree; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.io.Writer; +import java.util.HashSet; +import java.util.Set; + +import org.apache.maven.artifact.Artifact; +import org.apache.maven.shared.dependency.graph.DependencyNode; +import org.apache.maven.shared.dependency.graph.traversal.DependencyNodeVisitor; + +/** + * A dependency node visitor that serializes visited nodes to a writer using the JSON format. + */ +public class JsonDependencyNodeVisitor extends AbstractSerializingVisitor implements DependencyNodeVisitor { + + private String indentChar = " "; + + /** + * Creates a new instance of {@link JsonDependencyNodeVisitor}. The writer will be used to write the output. + * + * @param writer the writer to write to + */ + public JsonDependencyNodeVisitor(Writer writer) { + super(writer); + } + + @Override + public boolean visit(DependencyNode node) { + try { + if (node.getParent() == null || node.getParent() == node) { + writeRootNode(node); + } + return true; + } catch (IOException e) { + throw new UncheckedIOException("Failed to write JSON format output", e); + } + } + + /** + * Writes the node to the writer. This method is recursive and will write all children nodes. + * + * @param node the node to write + * @throws IOException if an I/O error occurs while writing + */ + private void writeRootNode(DependencyNode node) throws IOException { + Set visited = new HashSet<>(); + int indent = 2; + StringBuilder sb = new StringBuilder(); + sb.append("{").append(System.lineSeparator()); + writeNode(indent, node, sb, visited); + sb.append("}").append(System.lineSeparator()); + writer.write(sb.toString()); + writer.flush(); + } + /** + * Appends the node and its children to the string builder. + * + * @param indent the current indent level + * @param node the node to write + * @param sb the string builder to append to + */ + private void writeNode(int indent, DependencyNode node, StringBuilder sb, Set visited) { + if (visited.contains(node)) { + // Circular dependency detected + // Should an exception be thrown? + return; + } + visited.add(node); + appendNodeValues(sb, indent, node.getArtifact(), !node.getChildren().isEmpty()); + if (!node.getChildren().isEmpty()) { + writeChildren(indent, node, sb, visited); + } + } + /** + * Writes the children of the node to the string builder. Each child of each node will be written recursively. + * + * @param indent the current indent level + * @param node the node to write + * @param sb the string builder to append to + */ + private void writeChildren(int indent, DependencyNode node, StringBuilder sb, Set visited) { + sb.append(indent(indent)).append("\"children\": [").append(System.lineSeparator()); + indent += 2; + for (int i = 0; i < node.getChildren().size(); i++) { + DependencyNode child = node.getChildren().get(i); + sb.append(indent(indent)); + sb.append("{").append(System.lineSeparator()); + writeNode(indent + 2, child, sb, visited); + sb.append(indent(indent)).append("}"); + // we skip the comma for the last child + if (i != node.getChildren().size() - 1) { + sb.append(","); + } + sb.append(System.lineSeparator()); + } + sb.append(indent(indent)).append("]").append(System.lineSeparator()); + } + + @Override + public boolean endVisit(DependencyNode node) { + return true; + } + /** + * Appends the artifact values to the string builder. + * + * @param sb the string builder to append to + * @param indent the current indent level + * @param artifact the artifact to write + * @param hasChildren true if the artifact has children + */ + private void appendNodeValues(StringBuilder sb, int indent, Artifact artifact, boolean hasChildren) { + appendKeyValue(sb, indent, "groupId", artifact.getGroupId()); + appendKeyValue(sb, indent, "artifactId", artifact.getArtifactId()); + appendKeyValue(sb, indent, "version", artifact.getVersion()); + appendKeyValue(sb, indent, "type", artifact.getType()); + appendKeyValue(sb, indent, "scope", artifact.getScope()); + appendKeyValue(sb, indent, "classifier", artifact.getClassifier()); + if (hasChildren) { + appendKeyValue(sb, indent, "optional", String.valueOf(artifact.isOptional())); + } else { + appendKeyWithoutComma(sb, indent, "optional", String.valueOf(artifact.isOptional())); + } + } + /** + * Appends a key value pair to the string builder. + * + * @param sb the string builder to append to + * @param indent the current indent level + * @param key the key used as json key + * @param value the value used as json value + */ + private void appendKeyValue(StringBuilder sb, int indent, String key, String value) { + if (value == null) { + value = ""; + } + + sb.append(indent(indent)) + .append("\"") + .append(key) + .append("\"") + .append(":") + .append(indentChar) + .append("\"") + .append(value) + .append("\"") + .append(",") + .append(System.lineSeparator()); + } + /** + * Appends a key value pair to the string builder without a comma at the end. This is used for the last children of a node. + * + * @param sb the string builder to append to + * @param indent the current indent level + * @param key the key used as json key + * @param value the value used as json value + */ + private void appendKeyWithoutComma(StringBuilder sb, int indent, String key, String value) { + if (value == null) { + value = ""; + } + + sb.append(indent(indent)) + .append("\"") + .append(key) + .append("\"") + .append(":") + .append(indentChar) + .append("\"") + .append(value) + .append("\"") + .append(System.lineSeparator()); + } + + /** + * Returns a string of {@link #indentChar} for the indent level. + * + * @param indent the number of indent levels + * @return the string of indent characters + */ + private String indent(int indent) { + if (indent < 1) { + return ""; + } + + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < indent; i++) { + sb.append(indentChar); + } + + return sb.toString(); + } +} diff --git a/src/main/java/org/apache/maven/plugins/dependency/tree/TGFDependencyNodeVisitor.java b/src/main/java/org/apache/maven/plugins/dependency/tree/TGFDependencyNodeVisitor.java index c76fdb984..3dc3a3286 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/tree/TGFDependencyNodeVisitor.java +++ b/src/main/java/org/apache/maven/plugins/dependency/tree/TGFDependencyNodeVisitor.java @@ -18,9 +18,12 @@ */ package org.apache.maven.plugins.dependency.tree; +import java.io.IOException; +import java.io.UncheckedIOException; import java.io.Writer; import java.util.ArrayList; import java.util.List; + import org.apache.maven.shared.dependency.graph.DependencyNode; import org.apache.maven.shared.dependency.graph.traversal.DependencyNodeVisitor; @@ -34,7 +37,7 @@ public class TGFDependencyNodeVisitor extends AbstractSerializingVisitor implements DependencyNodeVisitor { /** - * Utiity class to write an Edge. + * Utility class to write an Edge. * * @author Jerome Creignou */ @@ -57,9 +60,9 @@ static final class EdgeAppender { /** * Build a new EdgeAppender. * - * @param from edge start. + * @param from edge start * @param to edge end - * @param label optional label. + * @param label optional label */ EdgeAppender(DependencyNode from, DependencyNode to, String label) { super(); @@ -69,7 +72,7 @@ static final class EdgeAppender { } /** - * build a string representing the edge. + * Build a string representing the edge. */ @Override public String toString() { @@ -90,7 +93,7 @@ public String toString() { /** * Constructor. * - * @param writer the writer to write to. + * @param writer the writer to write to */ public TGFDependencyNodeVisitor(Writer writer) { super(writer); @@ -101,18 +104,23 @@ public TGFDependencyNodeVisitor(Writer writer) { */ @Override public boolean endVisit(DependencyNode node) { - if (node.getParent() == null || node.getParent() == node) { - // dump edges on last node endVisit - writer.println("#"); - for (EdgeAppender edge : edges) { - writer.println(edge.toString()); + try { + if (node.getParent() == null || node.getParent() == node) { + // dump edges on last node endVisit + writer.write("#" + System.lineSeparator()); + for (EdgeAppender edge : edges) { + writer.write(edge.toString() + System.lineSeparator()); + } + writer.flush(); + } else { + DependencyNode parent = node.getParent(); + // using scope as edge label. + edges.add(new EdgeAppender(parent, node, node.getArtifact().getScope())); } - } else { - DependencyNode p = node.getParent(); - // using scope as edge label. - edges.add(new EdgeAppender(p, node, node.getArtifact().getScope())); + return true; + } catch (IOException e) { + throw new UncheckedIOException("Failed to write TGF format output", e); } - return true; } /** @@ -120,11 +128,17 @@ public boolean endVisit(DependencyNode node) { */ @Override public boolean visit(DependencyNode node) { - // write node - writer.write(generateId(node)); - writer.write(" "); - writer.println(node.toNodeString()); - return true; + try { + // Write node + writer.write(generateId(node)); + writer.write(" "); + writer.write(node.toNodeString()); + writer.write(System.lineSeparator()); + writer.flush(); + return true; + } catch (IOException e) { + throw new UncheckedIOException("Failed to write TGF format output", e); + } } /** @@ -133,8 +147,8 @@ public boolean visit(DependencyNode node) { * Current implementation is rather simple and uses hashcode. *

      * - * @param node the DependencyNode to use. - * @return the unique id. + * @param node the DependencyNode to use + * @return the unique id */ private static String generateId(DependencyNode node) { return String.valueOf(node.hashCode()); diff --git a/src/main/java/org/apache/maven/plugins/dependency/tree/TreeMojo.java b/src/main/java/org/apache/maven/plugins/dependency/tree/TreeMojo.java index ac1131242..a2e7d8e84 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/tree/TreeMojo.java +++ b/src/main/java/org/apache/maven/plugins/dependency/tree/TreeMojo.java @@ -18,24 +18,22 @@ */ package org.apache.maven.plugins.dependency.tree; +import javax.inject.Inject; + import java.io.File; import java.io.IOException; import java.io.StringWriter; import java.io.Writer; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import java.util.Objects; + import org.apache.maven.artifact.resolver.filter.ArtifactFilter; import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter; -import org.apache.maven.artifact.versioning.ArtifactVersion; -import org.apache.maven.artifact.versioning.Restriction; -import org.apache.maven.artifact.versioning.VersionRange; import org.apache.maven.execution.MavenSession; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; -import org.apache.maven.plugins.annotations.Component; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.plugins.annotations.ResolutionScope; @@ -59,15 +57,13 @@ import org.apache.maven.shared.dependency.graph.traversal.FilteringDependencyNodeVisitor; import org.apache.maven.shared.dependency.graph.traversal.SerializingDependencyNodeVisitor; import org.apache.maven.shared.dependency.graph.traversal.SerializingDependencyNodeVisitor.GraphTokens; -import org.eclipse.aether.RepositorySystem; -import org.eclipse.aether.RepositorySystemSession; -import org.eclipse.aether.repository.RemoteRepository; /** * Displays the dependency tree for this project. Multiple formats are supported: text (by default), but also * DOT, - * GraphML, and - * TGF. + * GraphML, + * TGF and + * JSON. * * @author Mark Hobson * @since 2.0-alpha-5 @@ -79,50 +75,22 @@ public class TreeMojo extends AbstractMojo { /** * The Maven project. */ - @Parameter(defaultValue = "${project}", readonly = true, required = true) - private MavenProject project; - - @Parameter(defaultValue = "${session}", readonly = true, required = true) - private MavenSession session; - - @Parameter(property = "outputEncoding", defaultValue = "${project.reporting.outputEncoding}") - private String outputEncoding; - - /** - * Contains the full list of projects in the reactor. - */ - @Parameter(defaultValue = "${reactorProjects}", readonly = true, required = true) - private List reactorProjects; - - @Component - private RepositorySystem repositorySystem; - - @Parameter(defaultValue = "${repositorySystem}") - RepositorySystem repositorySystemParam; - - /** - * The current repository/network configuration of Maven. - */ - @Parameter(defaultValue = "${repositorySystemSession}") - private RepositorySystemSession repoSession; + private final MavenProject project; - /** - * The project's remote repositories to use for the resolution of project dependencies. - */ - @Parameter(defaultValue = "${project.remoteProjectRepositories}") - private List projectRepos; + private final MavenSession session; /** * The dependency collector builder to use. */ - @Component(hint = "default") - private DependencyCollectorBuilder dependencyCollectorBuilder; + private final DependencyCollectorBuilder dependencyCollectorBuilder; /** * The dependency graph builder to use. */ - @Component(hint = "default") - private DependencyGraphBuilder dependencyGraphBuilder; + private final DependencyGraphBuilder dependencyGraphBuilder; + + @Parameter(property = "outputEncoding", defaultValue = "${project.reporting.outputEncoding}") + private String outputEncoding; /** * If specified, this parameter will cause the dependency tree to be written to the path specified, instead of @@ -135,7 +103,8 @@ public class TreeMojo extends AbstractMojo { /** * If specified, this parameter will cause the dependency tree to be written using the specified format. Currently - * supported format are: text (default), dot, graphml and tgf. + * supported formats are: text (default), dot, graphml, tgf + * and json (since 3.7.0). * These additional formats can be plotted to image files. * * @since 2.2 @@ -189,7 +158,7 @@ public class TreeMojo extends AbstractMojo { * @since 2.0-alpha-6 */ @Parameter(property = "includes") - private String includes; + private List includes; /** * A comma-separated list of artifacts to filter from the serialized dependency tree, or null not to @@ -210,7 +179,7 @@ public class TreeMojo extends AbstractMojo { * @since 2.0-alpha-6 */ @Parameter(property = "excludes") - private String excludes; + private List excludes; /** * The computed dependency tree root node of the Maven project. @@ -232,6 +201,19 @@ public class TreeMojo extends AbstractMojo { */ @Parameter(property = "skip", defaultValue = "false") private boolean skip; + + @Inject + public TreeMojo( + MavenProject project, + MavenSession session, + DependencyCollectorBuilder dependencyCollectorBuilder, + DependencyGraphBuilder dependencyGraphBuilder) { + this.project = project; + this.session = session; + this.dependencyCollectorBuilder = dependencyCollectorBuilder; + this.dependencyGraphBuilder = dependencyGraphBuilder; + } + // Mojo methods ----------------------------------------------------------- /* @@ -379,6 +361,8 @@ public DependencyNodeVisitor getSerializingDependencyNodeVisitor(Writer writer) return new TGFDependencyNodeVisitor(writer); } else if ("dot".equals(outputType)) { return new DOTDependencyNodeVisitor(writer); + } else if ("json".equals(outputType)) { + return new JsonDependencyNodeVisitor(writer); } else { return new SerializingDependencyNodeVisitor(writer, toGraphTokens(tokens)); } @@ -417,55 +401,23 @@ private DependencyNodeFilter createDependencyNodeFilter() { List filters = new ArrayList<>(); // filter includes - if (includes != null) { - List patterns = Arrays.asList(includes.split(",")); + if (includes != null && !includes.isEmpty()) { - getLog().debug("+ Filtering dependency tree by artifact include patterns: " + patterns); + getLog().debug("+ Filtering dependency tree by artifact include patterns: " + includes); - ArtifactFilter artifactFilter = new StrictPatternIncludesArtifactFilter(patterns); + ArtifactFilter artifactFilter = new StrictPatternIncludesArtifactFilter(includes); filters.add(new ArtifactDependencyNodeFilter(artifactFilter)); } // filter excludes - if (excludes != null) { - List patterns = Arrays.asList(excludes.split(",")); + if (excludes != null && !excludes.isEmpty()) { - getLog().debug("+ Filtering dependency tree by artifact exclude patterns: " + patterns); + getLog().debug("+ Filtering dependency tree by artifact exclude patterns: " + excludes); - ArtifactFilter artifactFilter = new StrictPatternExcludesArtifactFilter(patterns); + ArtifactFilter artifactFilter = new StrictPatternExcludesArtifactFilter(excludes); filters.add(new ArtifactDependencyNodeFilter(artifactFilter)); } return filters.isEmpty() ? null : new AndDependencyNodeFilter(filters); } - - // following is required because the version handling in maven code - // doesn't work properly. I ripped it out of the enforcer rules. - - /** - * Copied from Artifact.VersionRange. This is tweaked to handle singular ranges properly. Currently the default - * containsVersion method assumes a singular version means allow everything. This method assumes that "2.0.4" == - * "[2.0.4,)" - * - * @param allowedRange range of allowed versions. - * @param theVersion the version to be checked. - * @return true if the version is contained by the range. - * @deprecated This method is unused in this project and will be removed in the future. - */ - @Deprecated - public static boolean containsVersion(VersionRange allowedRange, ArtifactVersion theVersion) { - ArtifactVersion recommendedVersion = allowedRange.getRecommendedVersion(); - if (recommendedVersion == null) { - List restrictions = allowedRange.getRestrictions(); - for (Restriction restriction : restrictions) { - if (restriction.containsVersion(theVersion)) { - return true; - } - } - return false; - } else { - // only singular versions ever have a recommendedVersion - return recommendedVersion.compareTo(theVersion) <= 0; - } - } } diff --git a/src/main/java/org/apache/maven/plugins/dependency/utils/CopyUtil.java b/src/main/java/org/apache/maven/plugins/dependency/utils/CopyUtil.java new file mode 100644 index 000000000..d18fbd992 --- /dev/null +++ b/src/main/java/org/apache/maven/plugins/dependency/utils/CopyUtil.java @@ -0,0 +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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.maven.plugins.dependency.utils; + +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; + +import java.io.File; +import java.io.IOException; + +import org.apache.maven.artifact.Artifact; +import org.apache.maven.plugin.MojoExecutionException; +import org.codehaus.plexus.util.FileUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.sonatype.plexus.build.incremental.BuildContext; + +/** + * Provide a copyFile method in one place. + * + * @since 3.7.0 + */ +@Named +@Singleton +public class CopyUtil { + + private final BuildContext buildContext; + + private final Logger logger = LoggerFactory.getLogger(CopyUtil.class); + + @Inject + public CopyUtil(BuildContext buildContext) { + this.buildContext = buildContext; + } + + /** + * Copies the artifact (file) + * + * @param sourceArtifact the artifact (file) to copy + * @param destination file name of destination file + * @throws IOException if copy has failed + * @throws MojoExecutionException if artifact file is a directory (which has not been packaged yet) + * @since 3.7.0 + */ + public void copyArtifactFile(Artifact sourceArtifact, File destination) throws IOException, MojoExecutionException { + File source = sourceArtifact.getFile(); + if (source.isDirectory()) { + // usual case is a future jar packaging, but there are special cases: classifier and other packaging + throw new MojoExecutionException("Artifact '" + sourceArtifact + + "' has not been packaged yet (is a directory). When used on reactor artifact, " + + "copy should be executed after packaging: see MDEP-187."); + } + logger.debug("Copying artifact '{}' ({}) to {}", sourceArtifact.getId(), sourceArtifact.getFile(), destination); + FileUtils.copyFile(source, destination); + buildContext.refresh(destination); + } + + /** + * Copies a file to a destination and refreshes the build context for the new file. + * + * @param source the source file to copy + * @param destination the destination file + * @throws IOException if copy has failed + * @since 3.2.0 + */ + public void copyFile(File source, File destination) throws IOException { + logger.debug("Copying file '{}' to {}", source, destination); + FileUtils.copyFile(source, destination); + buildContext.refresh(destination); + } +} diff --git a/src/main/java/org/apache/maven/plugins/dependency/utils/DependencySilentLog.java b/src/main/java/org/apache/maven/plugins/dependency/utils/DependencySilentLog.java index 165a327d0..7e2106a2f 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/utils/DependencySilentLog.java +++ b/src/main/java/org/apache/maven/plugins/dependency/utils/DependencySilentLog.java @@ -19,14 +19,13 @@ package org.apache.maven.plugins.dependency.utils; import org.apache.maven.plugin.logging.Log; -import org.codehaus.plexus.logging.Logger; /** * This logger implements both types of logs currently in use and turns off logs. * * @author Brian Fox */ -public class DependencySilentLog implements Log, Logger { +public class DependencySilentLog implements Log { /** * @return false * @see org.apache.maven.plugin.logging.Log#isDebugEnabled() @@ -184,148 +183,4 @@ public void error(CharSequence content, Throwable error) { public void error(Throwable error) { // nop } - - /** - * By default, do nothing. - * - * @see org.codehaus.plexus.logging.Logger#debug(java.lang.String) - */ - @Override - public void debug(String message) { - // nop - } - - /** - * By default, do nothing. - * - * @see org.codehaus.plexus.logging.Logger#debug(java.lang.String, java.lang.Throwable) - */ - @Override - public void debug(String message, Throwable throwable) { - // nop - } - - /** - * By default, do nothing. - * - * @see org.codehaus.plexus.logging.Logger#info(java.lang.String) - */ - @Override - public void info(String message) { - // nop - } - - /** - * By default, do nothing. - * - * @see org.codehaus.plexus.logging.Logger#info(java.lang.String, java.lang.Throwable) - */ - @Override - public void info(String message, Throwable throwable) { - // nop - } - - /** - * By default, do nothing. - * - * @see org.codehaus.plexus.logging.Logger#warn(java.lang.String) - */ - @Override - public void warn(String message) { - // nop - } - - /** - * By default, do nothing. - * - * @see org.codehaus.plexus.logging.Logger#warn(java.lang.String, java.lang.Throwable) - */ - @Override - public void warn(String message, Throwable throwable) { - // nop - } - - /** - * By default, do nothing. - * - * @see org.codehaus.plexus.logging.Logger#error(java.lang.String) - */ - @Override - public void error(String message) { - // nop - } - - /** - * By default, do nothing. - * - * @see org.codehaus.plexus.logging.Logger#error(java.lang.String, java.lang.Throwable) - */ - @Override - public void error(String message, Throwable throwable) { - // nop - } - - /** - * By default, do nothing. - * - * @see org.codehaus.plexus.logging.Logger#fatalError(java.lang.String) - */ - @Override - public void fatalError(String message) { - // nop - } - - /** - * By default, do nothing. - * - * @see org.codehaus.plexus.logging.Logger#fatalError(java.lang.String, java.lang.Throwable) - */ - @Override - public void fatalError(String message, Throwable throwable) { - // nop - } - - /** - * @return false - * @see org.codehaus.plexus.logging.Logger#isFatalErrorEnabled() - */ - @Override - public boolean isFatalErrorEnabled() { - return false; - } - - /** - * @return null - * @see org.codehaus.plexus.logging.Logger#getChildLogger(java.lang.String) - */ - @Override - public Logger getChildLogger(String name) { - return null; - } - - /** - * @return 0 - * @see org.codehaus.plexus.logging.Logger#getThreshold() - */ - @Override - public int getThreshold() { - return 0; - } - - /** - * By default, do nothing - */ - @Override - public void setThreshold(int threshold) { - // nop - } - - /** - * @return null - * @see org.codehaus.plexus.logging.Logger#getName() - */ - @Override - public String getName() { - return null; - } } diff --git a/src/main/java/org/apache/maven/plugins/dependency/utils/DependencyStatusSets.java b/src/main/java/org/apache/maven/plugins/dependency/utils/DependencyStatusSets.java index 07c7fa3f1..4aed77fa6 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/utils/DependencyStatusSets.java +++ b/src/main/java/org/apache/maven/plugins/dependency/utils/DependencyStatusSets.java @@ -20,6 +20,7 @@ import java.util.LinkedHashSet; import java.util.Set; + import org.apache.maven.artifact.Artifact; /** @@ -55,14 +56,14 @@ public DependencyStatusSets(Set resolved, Set unResolved, Se } /** - * @return Returns the resolvedDependencies. + * @return returns the resolvedDependencies */ public Set getResolvedDependencies() { return this.resolvedDependencies; } /** - * @param resolvedDependencies The resolvedDependencies to set. + * @param resolvedDependencies the resolvedDependencies to set */ public void setResolvedDependencies(Set resolvedDependencies) { if (resolvedDependencies != null) { @@ -73,14 +74,14 @@ public void setResolvedDependencies(Set resolvedDependencies) { } /** - * @return Returns the skippedDependencies. + * @return returns the skippedDependencies */ public Set getSkippedDependencies() { return this.skippedDependencies; } /** - * @param skippedDependencies The skippedDependencies to set. + * @param skippedDependencies the skippedDependencies to set */ public void setSkippedDependencies(Set skippedDependencies) { if (skippedDependencies != null) { @@ -91,14 +92,14 @@ public void setSkippedDependencies(Set skippedDependencies) { } /** - * @return Returns the unResolvedDependencies. + * @return returns the unResolvedDependencies */ public Set getUnResolvedDependencies() { return this.unResolvedDependencies; } /** - * @param unResolvedDependencies The unResolvedDependencies to set. + * @param unResolvedDependencies the unResolvedDependencies to set */ public void setUnResolvedDependencies(Set unResolvedDependencies) { if (unResolvedDependencies != null) { diff --git a/src/main/java/org/apache/maven/plugins/dependency/utils/DependencyUtil.java b/src/main/java/org/apache/maven/plugins/dependency/utils/DependencyUtil.java index 2c7c2c2a0..11e8be21a 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/utils/DependencyUtil.java +++ b/src/main/java/org/apache/maven/plugins/dependency/utils/DependencyUtil.java @@ -20,16 +20,18 @@ import java.io.BufferedReader; import java.io.File; -import java.io.FileOutputStream; import java.io.IOException; -import java.io.OutputStreamWriter; import java.io.StringReader; import java.io.Writer; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.OpenOption; +import java.nio.file.StandardOpenOption; import java.util.Objects; + import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.ArtifactUtils; import org.apache.maven.plugin.logging.Log; -import org.codehaus.plexus.util.StringUtils; /** * Utility class with static helper methods. @@ -42,9 +44,9 @@ public final class DependencyUtil { * Builds the file name. If removeVersion is set, then the file name must be reconstructed from the artifactId, * Classifier (if used) and Type. Otherwise, this method returns the artifact file name. * - * @param artifact File to be formatted. - * @param removeVersion Specifies if the version should be removed from the file name. - * @return Formatted file name in the format artifactId-[version]-[classifier].[type] + * @param artifact file to be formatted + * @param removeVersion specifies if the version should be removed from the file name + * @return formatted file name in the format artifactId-[version]-[classifier].[type] * @see #getFormattedFileName(Artifact, boolean, boolean) */ public static String getFormattedFileName(Artifact artifact, boolean removeVersion) { @@ -56,10 +58,10 @@ public static String getFormattedFileName(Artifact artifact, boolean removeVersi * prependGroupId is true) artifactId, Classifier (if used) and Type. Otherwise, this method returns the * artifact file name. * - * @param artifact File to be formatted. - * @param removeVersion Specifies if the version should be removed from the file name. - * @param prependGroupId Specifies if the groupId should be prepended to the file name. - * @return Formatted file name in the format [groupId].artifactId-[version]-[classifier].[type] + * @param artifact file to be formatted + * @param removeVersion specifies if the version should be removed from the file name + * @param prependGroupId specifies if the groupId should be prepended to the file name + * @return formatted file name in the format [groupId].artifactId-[version]-[classifier].[type] */ public static String getFormattedFileName(Artifact artifact, boolean removeVersion, boolean prependGroupId) { return getFormattedFileName(artifact, removeVersion, prependGroupId, false); @@ -71,10 +73,10 @@ public static String getFormattedFileName(Artifact artifact, boolean removeVersi * artifact file name. * * @param artifact file to be formatted - * @param removeVersion Specifies if the version should be removed from the file name - * @param prependGroupId Specifies if the groupId should be prepended to the file name - * @param useBaseVersion Specifies if the baseVersion of the artifact should be used instead of the version - * @return Formatted file name in the format [groupId].artifactId-[version]-[classifier].[type] + * @param removeVersion specifies if the version should be removed from the file name + * @param prependGroupId specifies if the groupId should be prepended to the file name + * @param useBaseVersion specifies if the baseVersion of the artifact should be used instead of the version + * @return formatted file name in the format [groupId].artifactId-[version]-[classifier].[type] */ public static String getFormattedFileName( Artifact artifact, boolean removeVersion, boolean prependGroupId, boolean useBaseVersion) { @@ -86,12 +88,12 @@ public static String getFormattedFileName( * prependGroupId is true) artifactId, Classifier (if used) and Type. Otherwise, this method returns the * artifact file name. * - * @param artifact File to be formatted. - * @param removeVersion Specifies if the version should be removed from the file name. - * @param prependGroupId Specifies if the groupId should be prepended to the file name. - * @param useBaseVersion Specifies if the baseVersion of the artifact should be used instead of the version. - * @param removeClassifier Specifies if the classifier of the artifact should be remved from the file name. - * @return Formatted file name in the format [groupId].artifactId-[version]-[classifier].[type] + * @param artifact file to be formatted + * @param removeVersion specifies if the version should be removed from the file name + * @param prependGroupId specifies if the groupId should be prepended to the file name + * @param useBaseVersion specifies if the baseVersion of the artifact should be used instead of the version + * @param removeClassifier specifies if the classifier of the artifact should be remved from the file name + * @return formatted file name in the format [groupId].artifactId-[version]-[classifier].[type] */ public static String getFormattedFileName( Artifact artifact, @@ -105,20 +107,20 @@ public static String getFormattedFileName( destFileName.append(artifact.getGroupId()).append("."); } - String versionString; + String versionString = ""; if (!removeVersion) { if (useBaseVersion) { versionString = "-" + ArtifactUtils.toSnapshotVersion(artifact.getVersion()); } else { versionString = "-" + artifact.getVersion(); } - } else { - versionString = ""; } String classifierString = ""; - if (!removeClassifier && StringUtils.isNotEmpty(artifact.getClassifier())) { + if (!removeClassifier + && artifact.getClassifier() != null + && !artifact.getClassifier().isEmpty()) { classifierString = "-" + artifact.getClassifier(); } destFileName.append(artifact.getArtifactId()).append(versionString); @@ -131,16 +133,16 @@ public static String getFormattedFileName( /** * Formats the outputDirectory based on type. * - * @param useSubdirsPerScope if a new sub directory should be used for each scope. - * @param useSubdirsPerType if a new sub directory should be used for each type. - * @param useSubdirPerArtifact if a new sub directory should be used for each artifact. - * @param useRepositoryLayout if dependencies must be moved into a Maven repository layout, if set, other settings - * will be ignored. + * @param useSubdirsPerScope if a new subdirectory should be used for each scope + * @param useSubdirsPerType if a new subdirectory should be used for each type + * @param useSubdirPerArtifact if a new subdirectory should be used for each artifact + * @param useRepositoryLayout if dependencies must be moved into a Maven repository layout. + * If set, other settings will be ignored. * @param removeVersion if the version must not be mentioned in the filename * @param removeType if the type must not be mentioned in the filename - * @param outputDirectory base outputDirectory. - * @param artifact information about the artifact. - * @return a formatted File object to use for output. + * @param outputDirectory base outputDirectory + * @param artifact information about the artifact + * @return a formatted File object to use for output */ public static File getFormattedOutputDirectory( boolean useSubdirsPerScope, @@ -184,7 +186,7 @@ private static String getDependencyId(Artifact artifact, boolean removeVersion, sb.append(artifact.getVersion()); } - if (StringUtils.isNotEmpty(artifact.getClassifier())) { + if (artifact.getClassifier() != null && !artifact.getClassifier().isEmpty()) { sb.append("-"); sb.append(artifact.getClassifier()); } @@ -226,40 +228,35 @@ public static synchronized void write(String string, File file, boolean append, */ public static synchronized void write(String string, File file, boolean append, String encoding) throws IOException { - file.getParentFile().mkdirs(); + Files.createDirectories(file.getParentFile().toPath()); + + OpenOption appendOption = append ? StandardOpenOption.APPEND : StandardOpenOption.TRUNCATE_EXISTING; - try (Writer writer = new OutputStreamWriter(new FileOutputStream(file, append), encoding)) { + try (Writer writer = Files.newBufferedWriter( + file.toPath(), + Charset.forName(encoding), + appendOption, + StandardOpenOption.CREATE, + StandardOpenOption.WRITE)) { writer.write(string); } } /** - * Writes the specified string to the log at info level. + * Writes each line in the specified string to the log at info level. + * The difference between calling + * {@code DependencyUtil.log(s, log)} and {@code log.info(s)} is that the latter + * will put "[INFO]" in front of each line in the string whereas the former only + * outputs it once at the front of the string. * * @param string the string to write * @param log where to log information * @throws IOException if an I/O error occurs */ public static synchronized void log(String string, Log log) throws IOException { - BufferedReader reader = new BufferedReader(new StringReader(string)); - - String line; - - while ((line = reader.readLine()) != null) { - log.info(line); + try (BufferedReader reader = new BufferedReader(new StringReader(string))) { + reader.lines().forEach(log::info); } - - reader.close(); - } - - /** - * Mainly used to parse excludes, includes configuration. - * - * @param str the string to split - * @return the result items - */ - public static String[] tokenizer(String str) { - return StringUtils.split(cleanToBeTokenizedString(str), ","); } /** @@ -270,9 +267,9 @@ public static String[] tokenizer(String str) { */ public static String cleanToBeTokenizedString(String str) { String ret = ""; - if (!StringUtils.isEmpty(str)) { + if (!(str == null || str.isEmpty())) { // remove initial and ending spaces, plus all spaces next to commas - ret = str.trim().replaceAll("[\\s]*,[\\s]*", ","); + ret = str.trim().replaceAll("\\s*,\\s*", ","); } return ret; diff --git a/src/main/java/org/apache/maven/plugins/dependency/utils/ParamArtifact.java b/src/main/java/org/apache/maven/plugins/dependency/utils/ParamArtifact.java new file mode 100644 index 000000000..ace152ef7 --- /dev/null +++ b/src/main/java/org/apache/maven/plugins/dependency/utils/ParamArtifact.java @@ -0,0 +1,91 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.maven.plugins.dependency.utils; + +/** + * Represent artifact data collected from Mojo parameters. + */ +public class ParamArtifact { + private String groupId; + + private String artifactId; + + private String version; + + private String classifier; + + private String packaging; + + private String artifact; + + public String getGroupId() { + return groupId; + } + + public String getArtifactId() { + return artifactId; + } + + public String getVersion() { + return version; + } + + public String getClassifier() { + return classifier; + } + + public String getPackaging() { + return packaging; + } + + public String getArtifact() { + return artifact; + } + + public void setGroupId(String groupId) { + this.groupId = groupId; + } + + public void setArtifactId(String artifactId) { + this.artifactId = artifactId; + } + + public void setVersion(String version) { + this.version = version; + } + + public void setClassifier(String classifier) { + this.classifier = classifier; + } + + public void setPackaging(String packaging) { + this.packaging = packaging; + } + + public void setArtifact(String artifact) { + this.artifact = artifact; + } + + /** + * Determinate if all needed data is set. + */ + public boolean isDataSet() { + return artifact != null || (groupId != null && artifactId != null && version != null); + } +} diff --git a/src/main/java/org/apache/maven/plugins/dependency/utils/ResolverUtil.java b/src/main/java/org/apache/maven/plugins/dependency/utils/ResolverUtil.java new file mode 100644 index 000000000..3976abaa3 --- /dev/null +++ b/src/main/java/org/apache/maven/plugins/dependency/utils/ResolverUtil.java @@ -0,0 +1,391 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.maven.plugins.dependency.utils; + +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Provider; +import javax.inject.Singleton; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.stream.Collectors; + +import org.apache.maven.RepositoryUtils; +import org.apache.maven.execution.MavenSession; +import org.apache.maven.model.ModelBase; +import org.apache.maven.model.Plugin; +import org.apache.maven.model.PluginContainer; +import org.apache.maven.model.ReportPlugin; +import org.apache.maven.model.Reporting; +import org.apache.maven.project.MavenProject; +import org.eclipse.aether.RepositorySystem; +import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.artifact.Artifact; +import org.eclipse.aether.artifact.ArtifactType; +import org.eclipse.aether.artifact.ArtifactTypeRegistry; +import org.eclipse.aether.artifact.DefaultArtifact; +import org.eclipse.aether.collection.CollectRequest; +import org.eclipse.aether.collection.CollectResult; +import org.eclipse.aether.collection.DependencyCollectionException; +import org.eclipse.aether.graph.Dependency; +import org.eclipse.aether.repository.RemoteRepository; +import org.eclipse.aether.repository.RepositoryPolicy; +import org.eclipse.aether.resolution.ArtifactRequest; +import org.eclipse.aether.resolution.ArtifactResolutionException; +import org.eclipse.aether.resolution.ArtifactResult; +import org.eclipse.aether.resolution.DependencyRequest; +import org.eclipse.aether.resolution.DependencyResolutionException; +import org.eclipse.aether.resolution.DependencyResult; +import org.eclipse.aether.util.graph.visitor.PreorderNodeListGenerator; + +/** + * Helper class for using Resolver API. + */ +@Named +@Singleton +public class ResolverUtil { + + private final RepositorySystem repositorySystem; + + private final Provider mavenSessionProvider; + + @Inject + public ResolverUtil(RepositorySystem repositorySystem, Provider mavenSessionProvider) { + this.repositorySystem = repositorySystem; + this.mavenSessionProvider = mavenSessionProvider; + } + + /** + * Collects the transitive dependencies. + * + * @param root a root dependency for collections + * @return a resolved dependencies collections + */ + public Collection collectDependencies(Dependency root) throws DependencyCollectionException { + + MavenSession session = mavenSessionProvider.get(); + + CollectRequest request = + new CollectRequest(root, session.getCurrentProject().getRemoteProjectRepositories()); + CollectResult result = repositorySystem.collectDependencies(session.getRepositorySession(), request); + + PreorderNodeListGenerator nodeListGenerator = new PreorderNodeListGenerator(); + result.getRoot().accept(nodeListGenerator); + return nodeListGenerator.getDependencies(true); + } + + /** + * Resolve given artifact. + * + * @param artifact an artifact to resolve + * @param repositories remote repositories list + * @return resolved artifact + * @throws ArtifactResolutionException if the artifact could not be resolved + */ + public Artifact resolveArtifact(Artifact artifact, List repositories) + throws ArtifactResolutionException { + MavenSession session = mavenSessionProvider.get(); + ArtifactRequest request = new ArtifactRequest(artifact, repositories, null); + ArtifactResult result = repositorySystem.resolveArtifact(session.getRepositorySession(), request); + return result.getArtifact(); + } + + /** + * Resolve given plugin artifact. + * + * @param plugin a plugin to resolve + * @return resolved artifact + * @throws ArtifactResolutionException if the artifact could not be resolved + */ + public Artifact resolvePlugin(Plugin plugin) throws ArtifactResolutionException { + MavenSession session = mavenSessionProvider.get(); + Artifact artifact = toArtifact(plugin); + return resolveArtifact(artifact, session.getCurrentProject().getRemotePluginRepositories()); + } + + /** + * Resolve transitive dependencies for artifact. + * + * @param artifact an artifact to resolve + * @param repositories remote repositories list + * @return list of transitive dependencies for artifact + * @throws DependencyResolutionException if the dependency tree could not be built or any dependency artifact could + * not be resolved + */ + public List resolveDependencies(Artifact artifact, List repositories) + throws DependencyResolutionException { + return resolveDependencies(artifact, null, repositories); + } + + /** + * Resolve transitive dependencies for artifact. + * + * @param artifact an artifact to resolve + * @param dependencies a list of additional dependencies for artifact + * @param repositories remote repositories list + * @return list of transitive dependencies for artifact + * @throws DependencyResolutionException if the dependency tree could not be built or any dependency artifact could + * not be resolved + */ + public List resolveDependencies( + Artifact artifact, List dependencies, List repositories) + throws DependencyResolutionException { + MavenSession session = mavenSessionProvider.get(); + + CollectRequest collectRequest = new CollectRequest(new Dependency(artifact, null), dependencies, repositories); + DependencyRequest request = new DependencyRequest(collectRequest, null); + + DependencyResult result = repositorySystem.resolveDependencies(session.getRepositorySession(), request); + return result.getArtifactResults().stream() + .map(ArtifactResult::getArtifact) + .collect(Collectors.toList()); + } + + /** + * Resolve transitive dependencies for artifact with managed dependencies. + * + * @param rootArtifact a root artifact to resolve + * @param dependencies a list of dependencies for artifact + * @param managedDependencies a list of managed dependencies for artifact + * @param remoteProjectRepositories remote repositories list + * @return Resolved dependencies + * @throws DependencyResolutionException if the dependency tree could not be built or any dependency artifact could + * not be resolved + */ + public List resolveDependenciesForArtifact( + Artifact rootArtifact, + List dependencies, + List managedDependencies, + List remoteProjectRepositories) + throws DependencyResolutionException { + MavenSession session = mavenSessionProvider.get(); + + CollectRequest collectRequest = + new CollectRequest(dependencies, managedDependencies, remoteProjectRepositories); + collectRequest.setRootArtifact(rootArtifact); + DependencyRequest request = new DependencyRequest(collectRequest, null); + DependencyResult result = repositorySystem.resolveDependencies(session.getRepositorySession(), request); + return result.getArtifactResults().stream() + .map(ArtifactResult::getArtifact) + .collect(Collectors.toList()); + } + + /** + * Resolve transitive dependencies for plugin. + * + * @param plugin aa plugin to resolve + * @return list of transitive dependencies for plugin + * @throws DependencyResolutionException if the dependency tree could not be built or any dependency artifact could + * not be resolved + */ + public List resolveDependencies(final Plugin plugin) throws DependencyResolutionException { + + MavenSession session = mavenSessionProvider.get(); + + org.eclipse.aether.artifact.Artifact artifact = toArtifact(plugin); + List pluginDependencies = plugin.getDependencies().stream() + .map(d -> RepositoryUtils.toDependency( + d, session.getRepositorySession().getArtifactTypeRegistry())) + .collect(Collectors.toList()); + + return resolveDependencies( + artifact, pluginDependencies, session.getCurrentProject().getRemoteProjectRepositories()); + } + + private Artifact toArtifact(Plugin plugin) { + MavenSession session = mavenSessionProvider.get(); + return new DefaultArtifact( + plugin.getGroupId(), + plugin.getArtifactId(), + null, + "jar", + plugin.getVersion(), + session.getRepositorySession().getArtifactTypeRegistry().get("maven-plugin")); + } + + /** + * Prepare a remote repositories list for given descriptions. + * + * @param repositories remote repositories descriptions + * @return a list of remote repositories + */ + public List remoteRepositories(List repositories) { + MavenSession mavenSession = mavenSessionProvider.get(); + List projectRepositories = + mavenSession.getCurrentProject().getRemoteProjectRepositories(); + if (repositories == null || repositories.isEmpty()) { + return projectRepositories; + } + + List repositoriesList = + repositories.stream().map(this::prepareRemoteRepository).collect(Collectors.toList()); + repositoriesList = + repositorySystem.newResolutionRepositories(mavenSession.getRepositorySession(), repositoriesList); + + List result = new ArrayList<>(projectRepositories); + result.addAll(repositoriesList); + return result; + } + + // protected for testing purpose + protected RemoteRepository prepareRemoteRepository(String repository) { + String[] items = Objects.requireNonNull(repository, "repository must be not null") + .split("::"); + String id = "temp"; + String type = null; + String url; + switch (items.length) { + case 3: + id = items[0]; + type = items[1]; + url = items[2]; + break; + case 2: + id = items[0]; + url = items[1]; + break; + case 1: + url = items[0]; + break; + default: + throw new IllegalArgumentException("Invalid repository: " + repository); + } + + if (type == null || type.isEmpty()) { + type = "default"; + } + + MavenSession mavenSession = mavenSessionProvider.get(); + RepositorySystemSession repositorySession = mavenSession.getRepositorySession(); + + String checksumPolicy = repositorySession.getChecksumPolicy(); + if (checksumPolicy == null) { + checksumPolicy = RepositoryPolicy.CHECKSUM_POLICY_WARN; + } + String updatePolicy = + mavenSession.getRequest().isUpdateSnapshots() ? RepositoryPolicy.UPDATE_POLICY_ALWAYS : null; + RepositoryPolicy repositoryPolicy = new RepositoryPolicy(true, updatePolicy, checksumPolicy); + + RemoteRepository.Builder builder = new RemoteRepository.Builder(id, type, url); + builder.setReleasePolicy(repositoryPolicy); + builder.setSnapshotPolicy(repositoryPolicy); + + return builder.build(); + } + + /** + * Create an artifact based on configuration from Mojo. + * + * @param paramArtifact an artifact configuration + * @return new artifact + */ + public Artifact createArtifactFromParams(ParamArtifact paramArtifact) { + Objects.requireNonNull(paramArtifact); + if (paramArtifact.getArtifact() != null) { + return createArtifactFromString(paramArtifact.getArtifact()); + } else { + ArtifactType artifactType = getArtifactType(paramArtifact.getPackaging()); + return new DefaultArtifact( + paramArtifact.getGroupId(), + paramArtifact.getArtifactId(), + paramArtifact.getClassifier(), + artifactType.getExtension(), + paramArtifact.getVersion(), + artifactType); + } + } + + private Artifact createArtifactFromString(String artifact) { + // groupId:artifactId:version[:packaging[:classifier]]. + String[] items = artifact.split(":"); + if (items.length < 3) { + throw new IllegalArgumentException("Invalid artifact format: " + artifact); + } + + ArtifactType artifactType = getArtifactType(items.length > 3 ? items[3] : null); + String classifier = items.length > 4 ? items[4] : null; + + return new DefaultArtifact(items[0], items[1], classifier, artifactType.getExtension(), items[2], artifactType); + } + + private ArtifactType getArtifactType(String packaging) { + ArtifactTypeRegistry artifactTypeRegistry = + mavenSessionProvider.get().getRepositorySession().getArtifactTypeRegistry(); + return artifactTypeRegistry.get(packaging != null ? packaging : "jar"); + } + + /** + * Retrieve all plugins used in project either in build or reporting section. + * + * @param project a maven project + * @return a collection of plugins + */ + public Collection getProjectPlugins(MavenProject project) { + List reportPlugins = Optional.ofNullable(project.getModel()) + .map(ModelBase::getReporting) + .map(Reporting::getPlugins) + .orElse(Collections.emptyList()) + .stream() + .map(p -> toPlugin(p, project)) + .collect(Collectors.toList()); + + List projectPlugins = project.getBuild().getPlugins(); + + LinkedHashSet result = new LinkedHashSet<>(reportPlugins.size() + projectPlugins.size()); + result.addAll(reportPlugins); + result.addAll(projectPlugins); + return result; + } + + private Plugin toPlugin(ReportPlugin reportPlugin, MavenProject project) { + // first look in the pluginManagement section + Plugin plugin = Optional.ofNullable(project.getBuild().getPluginManagement()) + .map(PluginContainer::getPluginsAsMap) + .orElseGet(Collections::emptyMap) + .get(reportPlugin.getKey()); + + if (plugin == null) { + plugin = project.getBuild().getPluginsAsMap().get(reportPlugin.getKey()); + } + + if (plugin == null) { + plugin = new Plugin(); + plugin.setGroupId(reportPlugin.getGroupId()); + plugin.setArtifactId(reportPlugin.getArtifactId()); + plugin.setVersion(reportPlugin.getVersion()); + } else { + // override the version with the one from the report plugin if specified + if (reportPlugin.getVersion() != null) { + plugin.setVersion(reportPlugin.getVersion()); + } + } + + if (plugin.getVersion() == null) { + plugin.setVersion("RELEASE"); + } + + return plugin; + } +} diff --git a/src/main/java/org/apache/maven/plugins/dependency/utils/UnpackUtil.java b/src/main/java/org/apache/maven/plugins/dependency/utils/UnpackUtil.java new file mode 100644 index 000000000..0d6cd7164 --- /dev/null +++ b/src/main/java/org/apache/maven/plugins/dependency/utils/UnpackUtil.java @@ -0,0 +1,187 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.maven.plugins.dependency.utils; + +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; + +import java.io.File; + +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.logging.Log; +import org.codehaus.plexus.archiver.ArchiverException; +import org.codehaus.plexus.archiver.UnArchiver; +import org.codehaus.plexus.archiver.manager.ArchiverManager; +import org.codehaus.plexus.archiver.manager.NoSuchArchiverException; +import org.codehaus.plexus.archiver.zip.ZipUnArchiver; +import org.codehaus.plexus.components.io.filemappers.FileMapper; +import org.codehaus.plexus.components.io.fileselectors.IncludeExcludeFileSelector; +import org.sonatype.plexus.build.incremental.BuildContext; + +/** + * Provide unpack method in one place for {@link org.apache.maven.plugins.dependency.fromConfiguration.UnpackMojo} + * and {@link org.apache.maven.plugins.dependency.fromDependencies.UnpackDependenciesMojo} + */ +@Named +@Singleton +public class UnpackUtil { + + /** + * To look up Archiver/UnArchiver implementations. + */ + private final ArchiverManager archiverManager; + + /** + * For IDE build support. + */ + private final BuildContext buildContext; + + /** + * Default constructor. + * + * @param archiverManager an archiver {@link ArchiverManager} to use + * @param buildContext a build context + */ + @Inject + public UnpackUtil(ArchiverManager archiverManager, BuildContext buildContext) { + this.archiverManager = archiverManager; + this.buildContext = buildContext; + } + + /** + * @param file file to unpack + * @param type file / artifact type + * @param location the location + * @param includes includes list + * @param excludes excludes list + * @param encoding the encoding + * @param ignorePermissions ignore permissions + * @param fileMappers {@link FileMapper}s to be used for rewriting each target path, or {@code null} if no + * rewriting + * shall happen + * @param logger a Mojo logger + * @throws MojoExecutionException in case of an error + */ + public void unpack( + File file, + String type, + File location, + String includes, + String excludes, + String encoding, + boolean ignorePermissions, + FileMapper[] fileMappers, + Log logger) + throws MojoExecutionException { + try { + logUnpack(logger, file, location, includes, excludes); + + location.mkdirs(); + if (!location.exists()) { + throw new MojoExecutionException( + "Location to write unpacked files to could not be created: " + location); + } + + if (file.isDirectory()) { + // usual case is a future jar packaging, but there are special cases: classifier and other packaging + throw new MojoExecutionException("Artifact has not been packaged yet. When used on reactor artifact, " + + "unpack should be executed after packaging: see MDEP-98."); + } + + UnArchiver unArchiver; + + try { + unArchiver = archiverManager.getUnArchiver(type); + logger.debug("Found unArchiver: " + unArchiver.getClass().getName() + " by type: " + type); + } catch (NoSuchArchiverException e) { + unArchiver = archiverManager.getUnArchiver(file); + logger.debug("Found unArchiver: " + unArchiver.getClass().getName() + " by file extension: " + file); + } + + if (encoding != null && unArchiver instanceof ZipUnArchiver) { + ((ZipUnArchiver) unArchiver).setEncoding(encoding); + logger.info("Unpacks '" + type + "' with encoding '" + encoding + "'."); + } + + unArchiver.setIgnorePermissions(ignorePermissions); + + unArchiver.setSourceFile(file); + + unArchiver.setDestDirectory(location); + + if ((excludes != null && !excludes.isEmpty()) || (includes != null && !includes.isEmpty())) { + // Create the selectors that will filter + // based on include/exclude parameters + // MDEP-47 + IncludeExcludeFileSelector[] selectors = + new IncludeExcludeFileSelector[] {new IncludeExcludeFileSelector()}; + + if (excludes != null && !excludes.isEmpty()) { + selectors[0].setExcludes(excludes.split(",")); + } + + if (includes != null && !includes.isEmpty()) { + selectors[0].setIncludes(includes.split(",")); + } + + unArchiver.setFileSelectors(selectors); + } + + unArchiver.setFileMappers(fileMappers); + + unArchiver.extract(); + } catch (NoSuchArchiverException e) { + throw new MojoExecutionException("Unknown archiver type", e); + } catch (ArchiverException e) { + throw new MojoExecutionException("Error unpacking file: " + file + " to: " + location, e); + } + buildContext.refresh(location); + } + + private void logUnpack(Log logger, File file, File location, String includes, String excludes) { + if (logger.isInfoEnabled()) { + return; + } + + StringBuilder msg = new StringBuilder(); + msg.append("Unpacking "); + msg.append(file); + msg.append(" to "); + msg.append(location); + + if (includes != null && excludes != null) { + msg.append(" with includes \""); + msg.append(includes); + msg.append("\" and excludes \""); + msg.append(excludes); + msg.append("\""); + } else if (includes != null) { + msg.append(" with includes \""); + msg.append(includes); + msg.append("\""); + } else if (excludes != null) { + msg.append(" with excludes \""); + msg.append(excludes); + msg.append("\""); + } + + logger.info(msg.toString()); + } +} diff --git a/src/main/java/org/apache/maven/plugins/dependency/utils/filters/ArtifactItemFilter.java b/src/main/java/org/apache/maven/plugins/dependency/utils/filters/ArtifactItemFilter.java index a6880e626..9b2135639 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/utils/filters/ArtifactItemFilter.java +++ b/src/main/java/org/apache/maven/plugins/dependency/utils/filters/ArtifactItemFilter.java @@ -28,8 +28,8 @@ public interface ArtifactItemFilter { /** * @param item {@link ArtifactItem} - * @return true/false. - * @throws ArtifactFilterException in case of an error. + * @return true/false + * @throws ArtifactFilterException in case of an error */ boolean isArtifactIncluded(ArtifactItem item) throws ArtifactFilterException; } diff --git a/src/main/java/org/apache/maven/plugins/dependency/utils/filters/DestFileFilter.java b/src/main/java/org/apache/maven/plugins/dependency/utils/filters/DestFileFilter.java index 4c4bbbfdc..3d04a537e 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/utils/filters/DestFileFilter.java +++ b/src/main/java/org/apache/maven/plugins/dependency/utils/filters/DestFileFilter.java @@ -23,12 +23,12 @@ import java.nio.file.Files; import java.util.LinkedHashSet; import java.util.Set; + import org.apache.maven.artifact.Artifact; import org.apache.maven.plugins.dependency.fromConfiguration.ArtifactItem; import org.apache.maven.plugins.dependency.utils.DependencyUtil; import org.apache.maven.shared.artifact.filter.collection.AbstractArtifactsFilter; import org.apache.maven.shared.artifact.filter.collection.ArtifactFilterException; -import org.codehaus.plexus.util.StringUtils; /** * @author Brian Fox @@ -61,24 +61,24 @@ public class DestFileFilter extends AbstractArtifactsFilter implements ArtifactI private File outputFileDirectory; /** - * @param outputFileDirectory the output directory. + * @param outputFileDirectory the output directory */ public DestFileFilter(File outputFileDirectory) { this(false, false, false, false, false, false, false, false, false, false, outputFileDirectory); } /** - * @param overWriteReleases true/false. - * @param overWriteSnapshots true/false. - * @param overWriteIfNewer true/false. - * @param useSubDirectoryPerArtifact true/false. - * @param useSubDirectoryPerType true/false. - * @param useSubDirectoryPerScope true/false. - * @param useRepositoryLayout true/false. - * @param removeVersion true/false. - * @param prependGroupId true/false. - * @param useBaseVersion true/false. - * @param outputFileDirectory the output directory. + * @param overWriteReleases true/false + * @param overWriteSnapshots true/false + * @param overWriteIfNewer true/false + * @param useSubDirectoryPerArtifact true/false + * @param useSubDirectoryPerType true/false + * @param useSubDirectoryPerScope true/false + * @param useRepositoryLayout true/false + * @param removeVersion true/false + * @param prependGroupId true/false + * @param useBaseVersion true/false + * @param outputFileDirectory the output directory */ public DestFileFilter( boolean overWriteReleases, @@ -123,133 +123,133 @@ public Set filter(Set artifacts) throws ArtifactFilterExcept } /** - * @return Returns the overWriteReleases. + * @return returns the overWriteReleases */ public boolean isOverWriteReleases() { return this.overWriteReleases; } /** - * @param overWriteReleases The overWriteReleases to set. + * @param overWriteReleases the overWriteReleases to set */ public void setOverWriteReleases(boolean overWriteReleases) { this.overWriteReleases = overWriteReleases; } /** - * @return Returns the overWriteSnapshots. + * @return returns the overWriteSnapshots */ public boolean isOverWriteSnapshots() { return this.overWriteSnapshots; } /** - * @param overWriteSnapshots The overWriteSnapshots to set. + * @param overWriteSnapshots the overWriteSnapshots to set */ public void setOverWriteSnapshots(boolean overWriteSnapshots) { this.overWriteSnapshots = overWriteSnapshots; } /** - * @return Returns the overWriteIfNewer. + * @return returns the overWriteIfNewer */ public boolean isOverWriteIfNewer() { return this.overWriteIfNewer; } /** - * @param overWriteIfNewer The overWriteIfNewer to set. + * @param overWriteIfNewer the overWriteIfNewer to set */ public void setOverWriteIfNewer(boolean overWriteIfNewer) { this.overWriteIfNewer = overWriteIfNewer; } /** - * @return Returns the outputFileDirectory. + * @return returns the outputFileDirectory */ public File getOutputFileDirectory() { return this.outputFileDirectory; } /** - * @param outputFileDirectory The outputFileDirectory to set. + * @param outputFileDirectory the outputFileDirectory to set */ public void setOutputFileDirectory(File outputFileDirectory) { this.outputFileDirectory = outputFileDirectory; } /** - * @return Returns the removeVersion. + * @return returns the removeVersion */ public boolean isRemoveVersion() { return this.removeVersion; } /** - * @param removeType The removeType to set. + * @param removeType the removeType to set */ public void setRemoveType(boolean removeType) { this.removeType = removeType; } /** - * @return Returns the removeType. + * @return returns the removeType */ public boolean isRemoveType() { return this.removeType; } /** - * @param removeVersion The removeVersion to set. + * @param removeVersion the removeVersion to set */ public void setRemoveVersion(boolean removeVersion) { this.removeVersion = removeVersion; } /** - * @return Returns the removeClassifier. + * @return returns the removeClassifier */ public boolean isRemoveClassifier() { return this.removeClassifier; } /** - * @param removeClassifier The removeClassifier to set. + * @param removeClassifier the removeClassifier to set */ public void setRemoveClassifier(boolean removeClassifier) { this.removeClassifier = removeClassifier; } /** - * @return Returns the useSubDirectoryPerArtifact. + * @return returns the useSubDirectoryPerArtifact */ public boolean isUseSubDirectoryPerArtifact() { return this.useSubDirectoryPerArtifact; } /** - * @param useSubDirectoryPerArtifact The useSubDirectoryPerArtifact to set. + * @param useSubDirectoryPerArtifact the useSubDirectoryPerArtifact to set */ public void setUseSubDirectoryPerArtifact(boolean useSubDirectoryPerArtifact) { this.useSubDirectoryPerArtifact = useSubDirectoryPerArtifact; } /** - * @return Returns the useSubDirectoryPerType. + * @return returns the useSubDirectoryPerType */ public boolean isUseSubDirectoryPerType() { return this.useSubDirectoryPerType; } /** - * @param useSubDirectoryPerType The useSubDirectoryPerType to set. + * @param useSubDirectoryPerType the useSubDirectoryPerType to set */ public void setUseSubDirectoryPerType(boolean useSubDirectoryPerType) { this.useSubDirectoryPerType = useSubDirectoryPerType; } /** - * @return Returns the useRepositoryLayout + * @return returns the useRepositoryLayout */ public boolean isUseRepositoryLayout() { return useRepositoryLayout; @@ -283,7 +283,7 @@ public boolean isArtifactIncluded(ArtifactItem item) throws ArtifactFilterExcept } File destFile; - if (StringUtils.isEmpty(item.getDestFileName())) { + if (item.getDestFileName() == null || item.getDestFileName().isEmpty()) { String formattedFileName = DependencyUtil.getFormattedFileName( artifact, removeVersion, prependGroupId, useBaseVersion, removeClassifier); destFile = new File(destFolder, formattedFileName); @@ -297,13 +297,13 @@ public boolean isArtifactIncluded(ArtifactItem item) throws ArtifactFilterExcept } /** - * Using simply {@code File.getLastModified} will return sometimes a wrong value see JDK bug for details. - * - * https://bugs.openjdk.java.net/browse/JDK-8177809 + * {@code File.getLastModified} sometimes returns a wrong value. See JDK bug for details. + *

      + * https://bugs.openjdk.java.net/browse/JDK-8177809. * * @param file {@link File} - * @return the last modification time in milliseconds. - * @throws ArtifactFilterException in case of a IO Exception. + * @return the last modification time in milliseconds + * @throws ArtifactFilterException in case of an IOException */ private long getLastModified(File file) throws ArtifactFilterException { try { diff --git a/src/main/java/org/apache/maven/plugins/dependency/utils/filters/MarkerFileFilter.java b/src/main/java/org/apache/maven/plugins/dependency/utils/filters/MarkerFileFilter.java index 51fe65fe3..2a3bd5566 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/utils/filters/MarkerFileFilter.java +++ b/src/main/java/org/apache/maven/plugins/dependency/utils/filters/MarkerFileFilter.java @@ -20,6 +20,7 @@ import java.util.LinkedHashSet; import java.util.Set; + import org.apache.maven.artifact.Artifact; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugins.dependency.fromConfiguration.ArtifactItem; @@ -44,9 +45,9 @@ public class MarkerFileFilter extends AbstractArtifactsFilter implements Artifac protected final MarkerHandler handler; /** - * @param overWriteReleases true/false. - * @param overWriteSnapshots true/false. - * @param overWriteIfNewer true/false. + * @param overWriteReleases true/false + * @param overWriteSnapshots true/false + * @param overWriteIfNewer true/false * @param handler {@link MarkerHandler} */ public MarkerFileFilter( @@ -92,42 +93,42 @@ public boolean isArtifactIncluded(ArtifactItem item) throws ArtifactFilterExcept } /** - * @return Returns the overWriteReleases. + * @return returns the overWriteReleases */ public boolean isOverWriteReleases() { return this.overWriteReleases; } /** - * @param overWriteReleases The overWriteReleases to set. + * @param overWriteReleases the overWriteReleases to set */ public void setOverWriteReleases(boolean overWriteReleases) { this.overWriteReleases = overWriteReleases; } /** - * @return Returns the overWriteSnapshots. + * @return returns the overWriteSnapshots */ public boolean isOverWriteSnapshots() { return this.overWriteSnapshots; } /** - * @param overWriteSnapshots The overWriteSnapshots to set. + * @param overWriteSnapshots the overWriteSnapshots to set */ public void setOverWriteSnapshots(boolean overWriteSnapshots) { this.overWriteSnapshots = overWriteSnapshots; } /** - * @return Returns the overWriteIfNewer. + * @return returns the overWriteIfNewer */ public boolean isOverWriteIfNewer() { return this.overWriteIfNewer; } /** - * @param overWriteIfNewer The overWriteIfNewer to set. + * @param overWriteIfNewer the overWriteIfNewer to set */ public void setOverWriteIfNewer(boolean overWriteIfNewer) { this.overWriteIfNewer = overWriteIfNewer; diff --git a/src/main/java/org/apache/maven/plugins/dependency/utils/markers/DefaultFileMarkerHandler.java b/src/main/java/org/apache/maven/plugins/dependency/utils/markers/DefaultFileMarkerHandler.java index a8600efef..bd9a54b28 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/utils/markers/DefaultFileMarkerHandler.java +++ b/src/main/java/org/apache/maven/plugins/dependency/utils/markers/DefaultFileMarkerHandler.java @@ -20,6 +20,7 @@ import java.io.File; import java.io.IOException; + import org.apache.maven.artifact.Artifact; import org.apache.maven.plugin.MojoExecutionException; @@ -38,7 +39,7 @@ public class DefaultFileMarkerHandler implements MarkerHandler { protected File markerFilesDirectory; /** - * @param theMarkerFilesDirectory The marker directory. + * @param theMarkerFilesDirectory the marker directory */ public DefaultFileMarkerHandler(File theMarkerFilesDirectory) { this.markerFilesDirectory = theMarkerFilesDirectory; @@ -46,7 +47,7 @@ public DefaultFileMarkerHandler(File theMarkerFilesDirectory) { /** * @param theArtifact {@link Artifact} - * @param theMarkerFilesDirectory The marker directory. + * @param theMarkerFilesDirectory the marker directory */ public DefaultFileMarkerHandler(Artifact theArtifact, File theMarkerFilesDirectory) { this.artifact = theArtifact; @@ -54,9 +55,9 @@ public DefaultFileMarkerHandler(Artifact theArtifact, File theMarkerFilesDirecto } /** - * Returns properly formatted File + * Returns properly formatted File. * - * @return File object for marker. The file is not guaranteed to exist. + * @return file object for marker. The file is not guaranteed to exist. */ protected File getMarkerFile() { return new File(this.markerFilesDirectory, this.artifact.getId().replace(':', '-') + ".marker"); @@ -67,7 +68,7 @@ protected File getMarkerFile() { * * @return true if and only if the file or directory denoted by this abstract pathname exists; * false otherwise - * @throws SecurityException If a security manager exists and its {@link + * @throws SecurityException if a security manager exists and its {@link * java.lang.SecurityManager#checkRead(java.lang.String)} method denies read access to the file or * directory */ @@ -127,7 +128,7 @@ public void setMarker() throws MojoExecutionException { * * @return true if and only if the file or directory is successfully deleted; false * otherwise - * @throws SecurityException If a security manager exists and its {@link + * @throws SecurityException if a security manager exists and its {@link * java.lang.SecurityManager#checkDelete} method denies delete access to the file */ @Override @@ -137,14 +138,14 @@ public boolean clearMarker() throws MojoExecutionException { } /** - * @return Returns the artifact. + * @return returns the artifact */ public Artifact getArtifact() { return this.artifact; } /** - * @param artifact The artifact to set. + * @param artifact the artifact to set */ @Override public void setArtifact(Artifact artifact) { @@ -152,14 +153,14 @@ public void setArtifact(Artifact artifact) { } /** - * @return Returns the markerFilesDirectory. + * @return returns the markerFilesDirectory */ public File getMarkerFilesDirectory() { return this.markerFilesDirectory; } /** - * @param markerFilesDirectory The markerFilesDirectory to set. + * @param markerFilesDirectory the markerFilesDirectory to set */ public void setMarkerFilesDirectory(File markerFilesDirectory) { this.markerFilesDirectory = markerFilesDirectory; diff --git a/src/main/java/org/apache/maven/plugins/dependency/utils/markers/MarkerHandler.java b/src/main/java/org/apache/maven/plugins/dependency/utils/markers/MarkerHandler.java index a56aee647..541e9b070 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/utils/markers/MarkerHandler.java +++ b/src/main/java/org/apache/maven/plugins/dependency/utils/markers/MarkerHandler.java @@ -26,26 +26,26 @@ */ public interface MarkerHandler { /** - * @return true/false. - * @throws MojoExecutionException in case of an error. + * @return true/false + * @throws MojoExecutionException in case of an error */ boolean isMarkerSet() throws MojoExecutionException; /** - * @throws MojoExecutionException in case of an error. + * @throws MojoExecutionException in case of an error */ void setMarker() throws MojoExecutionException; /** - * @return true/false. - * @throws MojoExecutionException in case of an error. + * @return true/false + * @throws MojoExecutionException in case of an error */ boolean clearMarker() throws MojoExecutionException; /** * @param artifact {@link Artifact} - * @return true/false. - * @throws MojoExecutionException in case of an error. + * @return true/false + * @throws MojoExecutionException in case of an error */ boolean isMarkerOlder(Artifact artifact) throws MojoExecutionException; diff --git a/src/main/java/org/apache/maven/plugins/dependency/utils/markers/SourcesFileMarkerHandler.java b/src/main/java/org/apache/maven/plugins/dependency/utils/markers/SourcesFileMarkerHandler.java index 4b0d41f31..7cd9cef93 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/utils/markers/SourcesFileMarkerHandler.java +++ b/src/main/java/org/apache/maven/plugins/dependency/utils/markers/SourcesFileMarkerHandler.java @@ -20,6 +20,7 @@ import java.io.File; import java.io.IOException; + import org.apache.maven.artifact.Artifact; import org.apache.maven.plugin.MojoExecutionException; @@ -31,7 +32,7 @@ public class SourcesFileMarkerHandler extends DefaultFileMarkerHandler { boolean resolved; /** - * @param markerFilesDirectory the marker files directory. + * @param markerFilesDirectory the marker files directory */ public SourcesFileMarkerHandler(File markerFilesDirectory) { super(markerFilesDirectory); @@ -39,8 +40,8 @@ public SourcesFileMarkerHandler(File markerFilesDirectory) { /** * @param artifact {@link Artifact} - * @param markerFilesDirectory marker files directory. - * @param isResolved true/false. + * @param markerFilesDirectory marker files directory + * @param isResolved true/false */ public SourcesFileMarkerHandler(Artifact artifact, File markerFilesDirectory, boolean isResolved) { super(artifact, markerFilesDirectory); @@ -48,9 +49,9 @@ public SourcesFileMarkerHandler(Artifact artifact, File markerFilesDirectory, bo } /** - * Returns properly formatted File + * Returns properly formatted File. * - * @return File object for marker. The file is not guaranteed to exist. + * @return file object for marker. The file is not guaranteed to exist. */ @Override public File getMarkerFile() { @@ -58,10 +59,10 @@ public File getMarkerFile() { } /** - * Get MarkerFile, exposed for unit testing purposes + * Get MarkerFile, exposed for unit testing purposes. * - * @param res resolved or not. - * @return marker file for this artifact. + * @param res resolved or not + * @return marker file for this artifact */ protected File getMarkerFile(boolean res) { String suffix; @@ -79,7 +80,7 @@ protected File getMarkerFile(boolean res) { * * @return true if and only if the file or directory denoted by this abstract pathname exists; * false otherwise - * @throws MojoExecutionException If a security manager exists and its {@link + * @throws MojoExecutionException if a security manager exists and its {@link * java.lang.SecurityManager#checkRead(java.lang.String)} method denies read access to the file or * directory */ @@ -141,7 +142,7 @@ public void setMarker() throws MojoExecutionException { * * @return true if and only if the file or directory is successfully deleted; false * otherwise - * @throws SecurityException If a security manager exists and its {@link + * @throws SecurityException if a security manager exists and its {@link * java.lang.SecurityManager#checkDelete} method denies delete access to the file */ @Override @@ -154,14 +155,14 @@ public boolean clearMarker() throws MojoExecutionException { } /** - * @return Returns the resolved. + * @return returns the resolved */ public boolean isResolved() { return this.resolved; } /** - * @param isResolved The resolved to set. + * @param isResolved the resolved to set */ public void setResolved(boolean isResolved) { this.resolved = isResolved; diff --git a/src/main/java/org/apache/maven/plugins/dependency/utils/markers/UnpackFileMarkerHandler.java b/src/main/java/org/apache/maven/plugins/dependency/utils/markers/UnpackFileMarkerHandler.java index 9dadf452e..cae50ab7e 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/utils/markers/UnpackFileMarkerHandler.java +++ b/src/main/java/org/apache/maven/plugins/dependency/utils/markers/UnpackFileMarkerHandler.java @@ -19,8 +19,8 @@ package org.apache.maven.plugins.dependency.utils.markers; import java.io.File; + import org.apache.maven.plugins.dependency.fromConfiguration.ArtifactItem; -import org.codehaus.plexus.util.StringUtils; /** * @author Damian Bradicich @@ -32,7 +32,7 @@ public class UnpackFileMarkerHandler extends DefaultFileMarkerHandler { protected ArtifactItem artifactItem; /** - * @param markerFilesDirectory The marker files directory. + * @param markerFilesDirectory the marker files directory */ public UnpackFileMarkerHandler(File markerFilesDirectory) { super(markerFilesDirectory); @@ -40,7 +40,7 @@ public UnpackFileMarkerHandler(File markerFilesDirectory) { /** * @param artifactItem {@link ArtifactItem} - * @param markerFilesDirectory the marker files directory. + * @param markerFilesDirectory the marker files directory */ public UnpackFileMarkerHandler(ArtifactItem artifactItem, File markerFilesDirectory) { this(markerFilesDirectory); @@ -49,24 +49,24 @@ public UnpackFileMarkerHandler(ArtifactItem artifactItem, File markerFilesDirect @Override protected File getMarkerFile() { - /** + /* * Build a hash of all include/exclude strings, to determine if an artifactItem has been unpacked using the - * include/exclude parameters, this will allow an artifact to be included multiple times with different - * include/exclude parameters + * include/exclude parameters. This allows an artifact to be included multiple times with different + * include/exclude parameters. */ File markerFile; if (this.artifactItem == null - || (StringUtils.isEmpty(this.artifactItem.getIncludes()) - && StringUtils.isEmpty(this.artifactItem.getExcludes()))) { + || this.artifactItem.getIncludes().isEmpty() + && this.artifactItem.getExcludes().isEmpty()) { markerFile = super.getMarkerFile(); } else { int includeExcludeHash = 0; - if (StringUtils.isNotEmpty(this.artifactItem.getIncludes())) { + if (!this.artifactItem.getIncludes().isEmpty()) { includeExcludeHash += this.artifactItem.getIncludes().hashCode(); } - if (StringUtils.isNotEmpty(this.artifactItem.getExcludes())) { + if (!this.artifactItem.getExcludes().isEmpty()) { includeExcludeHash += this.artifactItem.getExcludes().hashCode(); } diff --git a/src/main/java/org/apache/maven/plugins/dependency/utils/translators/ArtifactTranslator.java b/src/main/java/org/apache/maven/plugins/dependency/utils/translators/ArtifactTranslator.java index aeefae1e9..d2dbd2901 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/utils/translators/ArtifactTranslator.java +++ b/src/main/java/org/apache/maven/plugins/dependency/utils/translators/ArtifactTranslator.java @@ -19,18 +19,18 @@ package org.apache.maven.plugins.dependency.utils.translators; import java.util.Set; + import org.apache.maven.artifact.Artifact; import org.apache.maven.plugin.logging.Log; -import org.apache.maven.shared.transfer.artifact.ArtifactCoordinate; /** * @author Brian Fox */ public interface ArtifactTranslator { /** - * @param artifacts set of {@link Artifact}s. + * @param artifacts set of {@link Artifact}s * @param log {@link Log} - * @return {@link ArtifactCoordinate} + * @return set of {@link org.eclipse.aether.artifact.Artifact} */ - Set translate(Set artifacts, Log log); + Set translate(Set artifacts, Log log); } diff --git a/src/main/java/org/apache/maven/plugins/dependency/utils/translators/ClassifierTypeTranslator.java b/src/main/java/org/apache/maven/plugins/dependency/utils/translators/ClassifierTypeTranslator.java index d9cf3caff..188f6f3fd 100644 --- a/src/main/java/org/apache/maven/plugins/dependency/utils/translators/ClassifierTypeTranslator.java +++ b/src/main/java/org/apache/maven/plugins/dependency/utils/translators/ClassifierTypeTranslator.java @@ -20,13 +20,13 @@ import java.util.LinkedHashSet; import java.util.Set; + +import org.apache.maven.RepositoryUtils; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.handler.ArtifactHandler; import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager; import org.apache.maven.plugin.logging.Log; -import org.apache.maven.shared.transfer.artifact.ArtifactCoordinate; -import org.apache.maven.shared.transfer.artifact.DefaultArtifactCoordinate; -import org.codehaus.plexus.util.StringUtils; +import org.eclipse.aether.util.artifact.SubArtifact; /** * @author Brian Fox @@ -39,13 +39,13 @@ public class ClassifierTypeTranslator implements ArtifactTranslator { private String type; /** - * @param artifactHanderManager {@link ArtifactHandlerManager}. - * @param theClassifier The classifier to use. - * @param theType The type. + * @param artifactHandlerManager {@link ArtifactHandlerManager} + * @param theClassifier the classifier to use + * @param theType the type */ public ClassifierTypeTranslator( - ArtifactHandlerManager artifactHanderManager, String theClassifier, String theType) { - this.artifactHandlerManager = artifactHanderManager; + ArtifactHandlerManager artifactHandlerManager, String theClassifier, String theType) { + this.artifactHandlerManager = artifactHandlerManager; this.classifier = theClassifier; this.type = theType; } @@ -56,8 +56,8 @@ public ClassifierTypeTranslator( * org.apache.maven.plugin.logging.Log) */ @Override - public Set translate(Set artifacts, Log log) { - Set results; + public Set translate(Set artifacts, Log log) { + Set results; log.debug("Translating Artifacts using Classifier: " + this.classifier + " and Type: " + this.type); results = new LinkedHashSet<>(); @@ -66,7 +66,7 @@ public Set translate(Set artifacts, Log log) { // will use the // base artifact value if null comes in final String useType; - if (StringUtils.isNotEmpty(this.type)) { + if (this.type != null && !this.type.isEmpty()) { useType = this.type; } else { useType = artifact.getType(); @@ -82,64 +82,41 @@ public Set translate(Set artifacts, Log log) { } String useClassifier; - if (StringUtils.isNotEmpty(this.classifier)) { + if (this.classifier != null && !this.classifier.isEmpty()) { useClassifier = this.classifier; } else { useClassifier = artifact.getClassifier(); } - DefaultArtifactCoordinate coordinate = new DefaultArtifactCoordinate(); - coordinate.setGroupId(artifact.getGroupId()); - coordinate.setArtifactId(artifact.getArtifactId()); - coordinate.setVersion(artifact.getVersion()); - coordinate.setClassifier(useClassifier); - coordinate.setExtension(extension); - - // // Create a new artifact - // Artifact newArtifact = factory.createArtifactWithClassifier( artifact.getGroupId(), artifact - // .getArtifactId(), artifact.getVersion(), useType, useClassifier ); - // - // // note the new artifacts will always have the scope set to null. We - // // should - // // reset it here so that it will pass other filters if needed - // newArtifact.setScope( artifact.getScope() ); - // - // if ( Artifact.SCOPE_SYSTEM.equals( newArtifact.getScope() ) ) - // { - // File baseDir = repositoryManager.getLocalRepositoryBasedir( buildingRequest ); - // String path = repositoryManager.getPathForLocalArtifact( buildingRequest, newArtifact ); - // newArtifact.setFile( new File( baseDir, path ) ); - // } - - results.add(coordinate); + results.add(new SubArtifact(RepositoryUtils.toArtifact(artifact), useClassifier, extension)); } return results; } /** - * @return Returns the type. + * @return returns the type */ public String getType() { return this.type; } /** - * @param theType The type to set. + * @param theType the type to set */ public void setType(String theType) { this.type = theType; } /** - * @return Returns the classifier. + * @return returns the classifier */ public String getClassifier() { return this.classifier; } /** - * @param theClassifier The classifier to set. + * @param theClassifier the classifier to set */ public void setClassifier(String theClassifier) { this.classifier = theClassifier; diff --git a/src/main/resources/META-INF/plexus/components.xml b/src/main/resources/META-INF/plexus/components.xml deleted file mode 100644 index 91ef15de7..000000000 --- a/src/main/resources/META-INF/plexus/components.xml +++ /dev/null @@ -1,104 +0,0 @@ - - - - - - org.codehaus.plexus.archiver.UnArchiver - zip - org.codehaus.plexus.archiver.zip.ZipUnArchiver - per-lookup - - - org.codehaus.plexus.archiver.UnArchiver - jar - - org.codehaus.plexus.archiver.zip.ZipUnArchiver - per-lookup - - - org.codehaus.plexus.archiver.UnArchiver - war - - org.codehaus.plexus.archiver.zip.ZipUnArchiver - per-lookup - - - org.codehaus.plexus.archiver.UnArchiver - ear - - org.codehaus.plexus.archiver.zip.ZipUnArchiver - per-lookup - - - org.codehaus.plexus.archiver.UnArchiver - swc - - org.codehaus.plexus.archiver.zip.ZipUnArchiver - per-lookup - - - org.codehaus.plexus.archiver.UnArchiver - nar - - org.codehaus.plexus.archiver.zip.ZipUnArchiver - per-lookup - - - org.codehaus.plexus.archiver.UnArchiver - esb - - org.codehaus.plexus.archiver.zip.ZipUnArchiver - per-lookup - - - org.codehaus.plexus.archiver.UnArchiver - sar - - org.codehaus.plexus.archiver.zip.ZipUnArchiver - per-lookup - - - org.codehaus.plexus.archiver.UnArchiver - car - - org.codehaus.plexus.archiver.zip.ZipUnArchiver - per-lookup - - - org.codehaus.plexus.archiver.UnArchiver - par - - org.codehaus.plexus.archiver.zip.ZipUnArchiver - per-lookup - - - org.codehaus.plexus.archiver.UnArchiver - rar - - org.codehaus.plexus.archiver.zip.ZipUnArchiver - per-lookup - - - org.apache.maven.shared.dependency.analyzer.ProjectDependencyAnalyzer - org.apache.maven.shared.dependency.analyzer.DefaultProjectDependencyAnalyzer - - - - diff --git a/src/main/resources/analyze-report.properties b/src/main/resources/analyze-report.properties index 588f287c8..a2848b5d8 100644 --- a/src/main/resources/analyze-report.properties +++ b/src/main/resources/analyze-report.properties @@ -15,11 +15,11 @@ # specific language governing permissions and limitations # under the License. -analyze.report.name=Dependency Analysis -analyze.report.description=Dependency analysis of the project (used declared, used undeclared, unused declared) -analyze.report.header=Dependencies Report -analyze.report.mainTitle=Dependency Analysis -analyze.report.noDependency=None -analyze.report.UsedDeclaredDependencies=Used and declared dependencies -analyze.report.UsedUndeclaredDependencies=Used but undeclared dependencies -analyze.report.UnusedDeclaredDependencies=Unused but declared dependencies +report.analyze.name=Dependency Analysis +report.analyze.description=Dependency analysis of the project (used declared, used undeclared, unused declared) +report.analyze.title=Dependency Analysis +report.analyze.noDependencyProblems=No dependency problems found +report.analyze.UsedDeclaredDependencies=Used and Declared Dependencies +report.analyze.UsedUndeclaredDependencies=Used but Undeclared Dependencies +report.analyze.UnusedDeclaredDependencies=Unused but Declared Dependencies +report.analyze.CompileScopeTestOnlyDependencies=Compile Scoped Test Dependencies diff --git a/src/main/resources/analyze-report_de.properties b/src/main/resources/analyze-report_de.properties index 9f18ae7af..e284ece71 100644 --- a/src/main/resources/analyze-report_de.properties +++ b/src/main/resources/analyze-report_de.properties @@ -15,11 +15,10 @@ # specific language governing permissions and limitations # under the License. -analyze.report.name=Abhängigkeitsanalyse -analyze.report.description=Eine Analysebericht der Projektabhängigkeiten (verwendet und deklariert, verwendet aber nicht deklariert, unverwendet aber deklariert) -analyze.report.header=Abhängigkeitsanalyse -analyze.report.mainTitle=Abhängigkeitsanalyse -analyze.report.noDependency=Keine -analyze.report.UsedDeclaredDependencies=Verwendete und deklarierte Abhängigkeiten -analyze.report.UsedUndeclaredDependencies=Verwendete aber undeklarierte Abhängigkeiten -analyze.report.UnusedDeclaredDependencies=Unverwendete aber deklarierte Abhängigkeiten +report.analyze.name=Abhängigkeitsanalyse +report.analyze.description=Eine Analysebericht der Projektabhängigkeiten (verwendet und deklariert, verwendet aber nicht deklariert, unverwendet aber deklariert) +report.analyze.title=Abhängigkeitsanalyse +report.analyze.noDependencyProblems=Keine Abhängigkeitsprobleme gefunden +report.analyze.UsedDeclaredDependencies=Verwendete und deklarierte Abhängigkeiten +report.analyze.UsedUndeclaredDependencies=Verwendete aber undeklarierte Abhängigkeiten +report.analyze.UnusedDeclaredDependencies=Unverwendete aber deklarierte Abhängigkeiten diff --git a/src/main/resources/analyze-report_pt_BR.properties b/src/main/resources/analyze-report_pt_BR.properties index c84642347..324fd0e43 100644 --- a/src/main/resources/analyze-report_pt_BR.properties +++ b/src/main/resources/analyze-report_pt_BR.properties @@ -15,11 +15,9 @@ # specific language governing permissions and limitations # under the License. -analyze.report.name=An\u00e1lise de Depend\u00eancias -analyze.report.description=An\u00e1lise de Depend\u00eancias do projeto (usadas e declaradas, usadas e n\u00e3o declaradas, n\u00e3o usadas e declaradas) -analyze.report.header=Relat\u00f3rio de Depend\u00eancias -analyze.report.mainTitle=An\u00e1lise de Depend\u00eancias -analyze.report.noDependency=Nenhuma -analyze.report.UsedDeclaredDependencies=Depend\u00eancias usadas e declaradas -analyze.report.UsedUndeclaredDependencies=Depend\u00eancias usadas mas n\u00e3o declaradas -analyze.report.UnusedDeclaredDependencies=Depend\u00eancias n\u00e3o usadas mas declaradas +report.analyze.name=An\u00e1lise de Depend\u00eancias +report.analyze.description=An\u00e1lise de Depend\u00eancias do projeto (usadas e declaradas, usadas e n\u00e3o declaradas, n\u00e3o usadas e declaradas) +report.analyze.title=An\u00e1lise de Depend\u00eancias +report.analyze.UsedDeclaredDependencies=Depend\u00eancias usadas e declaradas +report.analyze.UsedUndeclaredDependencies=Depend\u00eancias usadas mas n\u00e3o declaradas +report.analyze.UnusedDeclaredDependencies=Depend\u00eancias n\u00e3o usadas mas declaradas diff --git a/src/main/resources/analyze-report_sv.properties b/src/main/resources/analyze-report_sv.properties index 81760118b..9f80758a0 100644 --- a/src/main/resources/analyze-report_sv.properties +++ b/src/main/resources/analyze-report_sv.properties @@ -15,11 +15,9 @@ # specific language governing permissions and limitations # under the License. -analyze.report.name=Beroendeanalys -analyze.report.description=Beroendeanalys av projektet (anv\u00e4nda deklarerade, anv\u00e4nda odeklarerade, oanv\u00e4nda deklarerade) -analyze.report.header=Beroenderapport -analyze.report.mainTitle=Beroendeanalys -analyze.report.noDependency=Inga -analyze.report.UsedDeclaredDependencies=Anv\u00e4nda och deklarerade beroenden -analyze.report.UsedUndeclaredDependencies=Anv\u00e4nda men odeklarerade beroenden -analyze.report.UnusedDeclaredDependencies=Oanv\u00e4nda men deklarerade beroenden +report.analyze.name=Beroendeanalys +report.analyze.description=Beroendeanalys av projektet (anv\u00e4nda deklarerade, anv\u00e4nda odeklarerade, oanv\u00e4nda deklarerade) +report.analyze.title=Beroendeanalys +report.analyze.UsedDeclaredDependencies=Anv\u00e4nda och deklarerade beroenden +report.analyze.UsedUndeclaredDependencies=Anv\u00e4nda men odeklarerade beroenden +report.analyze.UnusedDeclaredDependencies=Oanv\u00e4nda men deklarerade beroenden diff --git a/src/site/apt/examples/exclude-dependencies-from-dependency-analysis.apt.vm b/src/site/apt/examples/exclude-dependencies-from-dependency-analysis.apt.vm index 706127f14..4514937df 100644 --- a/src/site/apt/examples/exclude-dependencies-from-dependency-analysis.apt.vm +++ b/src/site/apt/examples/exclude-dependencies-from-dependency-analysis.apt.vm @@ -28,16 +28,18 @@ Exclude dependencies from dependency analysis A project's dependencies can be analyzed as part of the build process by binding the <<>> goal to the lifecycle. By default, the analysis will be performed during the <<>> lifecycle phase. - In rare cases it is possible to have dependencies that are - legitimate on the classpath but cause either "Declared but unused" - or "Undeclared but used" warnings. The most common case is with jars - that contain annotations and the byte code analysis is unable to - determine whether a jar is actually required or not. + It is possible to have necessary dependencies on the classpath that + cause either "Declared but unused" or "Undeclared but used" warnings. + One common cause of byte code analysis being unable to + determine whether a jar is required are annotations with + source retention. Another common cause is + a class that is loaded by reflection at runtime. - The plugin can then be configured to ignore dependencies that are - "declared but unused", "undeclared but used", and "non-test scoped" - in selected list or in all simultaneously. + The dependency plugin does not warn about a few common dependencies + where its analysis is known to be unreliable, most notably SLF4J. + If you encounter other false positives, you can configure the plugin to ignore particular + dependencies that are "declared but unused", "undeclared but used", and "non-test scoped". See the following POM configuration for an example: +---+ diff --git a/src/site/apt/examples/render-dependencies.apt.vm b/src/site/apt/examples/render-dependencies.apt.vm new file mode 100644 index 000000000..9e2aaae62 --- /dev/null +++ b/src/site/apt/examples/render-dependencies.apt.vm @@ -0,0 +1,77 @@ +~~ Licensed to the Apache Software Foundation (ASF) under one +~~ or more contributor license agreements. See the NOTICE file +~~ distributed with this work for additional information +~~ regarding copyright ownership. The ASF licenses this file +~~ to you under the Apache License, Version 2.0 (the +~~ "License"); you may not use this file except in compliance +~~ with the License. You may obtain a copy of the License at +~~ +~~ http://www.apache.org/licenses/LICENSE-2.0 +~~ +~~ Unless required by applicable law or agreed to in writing, +~~ software distributed under the License is distributed on an +~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +~~ KIND, either express or implied. See the License for the +~~ specific language governing permissions and limitations +~~ under the License. + + ------ + Render a Velocity template + ------ + Allan Ramirez + Brian Fox + Stephen Connolly + ------ + 2025-09-17 + ------ + +Render a Velocity template + + You can use <<>> mojo to a render a velocity template, + with the <> (dependencies) as context: + ++---+ + + [...] + + + + org.apache.maven.plugins + maven-dependency-plugin + ${project.version} + + + copy + process-resources + + render-dependencies + + + + + + + + + + [...] + ++---+ + + Then after executing <<>>, the template will be rendered. + By default it is printed in the console but you can set <> to store it somewhere. + + The resolution uses exactly the same mechanism than for <> mojo. diff --git a/src/site/apt/examples/tree-mojo.apt.vm b/src/site/apt/examples/tree-mojo.apt.vm new file mode 100644 index 000000000..5c5a6ba32 --- /dev/null +++ b/src/site/apt/examples/tree-mojo.apt.vm @@ -0,0 +1,304 @@ +~~ Licensed to the Apache Software Foundation (ASF) under one +~~ or more contributor license agreements. See the NOTICE file +~~ distributed with this work for additional information +~~ regarding copyright ownership. The ASF licenses this file +~~ to you under the Apache License, Version 2.0 (the +~~ "License"); you may not use this file except in compliance +~~ with the License. You may obtain a copy of the License at +~~ +~~ http://www.apache.org/licenses/LICENSE-2.0 +~~ +~~ Unless required by applicable law or agreed to in writing, +~~ software distributed under the License is distributed on an +~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +~~ KIND, either express or implied. See the License for the +~~ specific language governing permissions and limitations +~~ under the License. + + ------ + Dependency Tree Output Formats + ------ + Tayebwa Noah + ------ + 2025-06-04 + ------ + +Dependency Tree Output Formats + + The <<>> goal of the Maven Dependency Plugin generates a representation + of a project's dependency tree. The <<>> parameter allows you to specify + the output format, which can be written to a file using the <<>> parameter + or printed to the console. Supported formats are <<>>, <<>>, <<>>, + and <<>>. This section describes each format, its structure, and example usage. + +* Usage + + To <> the dependency tree in a specific format, use the following command: + ++---+ +mvn dependency:tree -DoutputType= -DoutputFile= ++---+ + + * <<>>: One of <<>>, <<>>, <<>>, or <<>>. If omitted, + the default is a text-based tree printed to the console. + + * <<>>: The file to write the output to (e.g., <<>>). + If omitted, the output is printed to the console. + + Example: + ++---+ +mvn dependency:tree -DoutputType=json -DoutputFile=dependency-tree.json ++---+ + + <>: Ensure you are using Maven Dependency Plugin version 3.7.0 or later + (latest is 3.8.1 as of June 2025) to access these output formats. + +* Output Formats + +{JSON (outputType=json)} + + <>: The JSON format represents the dependency tree as a hierarchical JSON + object. The root node describes the project's artifact, and its dependencies are listed + in a <<>> array, with nested dependencies recursively included. + + <>: + + * <>: + + * <<>>: The group ID of the project or dependency (e.g., <<>>). + + * <<>>: The artifact ID (e.g., <<>>). + + * <<>>: The version (e.g., <<<1.2.1-SNAPSHOT>>>). + + * <<>>: The artifact type (e.g., <<>>). + + * <<>>: The dependency scope (e.g., <<>>, <<>>, or empty for the project itself). + + * <<>>: The classifier, if any (e.g., empty string if none). + + * <<>>: Whether the dependency is optional (<<>> or <<>>). + + * <<>>: An array of dependency objects with the same structure, representing transitive dependencies. + + * <>: Each dependency in the <<>> array follows the same + structure, allowing for recursive representation of the dependency tree. + + + <>: + ++---+ +{ + "groupId": "org.apache.maven.extensions", + "artifactId": "maven-build-cache-extension", + "version": "1.2.1-SNAPSHOT", + "type": "jar", + "scope": "", + "classifier": "", + "optional": "false", + "children": [ + { + "groupId": "net.openhft", + "artifactId": "zero-allocation-hashing", + "version": "0.27ea0", + "type": "jar", + "scope": "compile", + "classifier": "", + "optional": "false" + }, + { + "groupId": "org.apache.maven.wagon", + "artifactId": "wagon-webdav-jackrabbit", + "version": "3.5.3", + "type": "jar", + "scope": "compile", + "classifier": "", + "optional": "false", + "children": [ + { + "groupId": "org.apache.jackrabbit", + "artifactId": "jackrabbit-webdav", + "version": "2.14.4", + "type": "jar", + "scope": "compile", + "classifier": "", + "optional": "false", + "children": [ + { + "groupId": "commons-codec", + "artifactId": "commons-codec", + "version": "1.10", + "type": "jar", + "scope": "compile", + "classifier": "", + "optional": "false" + } + ] + } + ] + } + ] +} ++---+ + + <>: + ++---+ +mvn dependency:tree -DoutputType=json -DoutputFile=dependency-tree.json ++---+ + + <>: Parse the JSON output programmatically for dependency analysis or integration + with other tools. + +{DOT (outputType=dot)} + + <>: The DOT format is a plain-text graph description language used by Graphviz. + It represents the dependency tree as a directed graph (<<>>), with nodes for + artifacts and directed edges for dependencies, labeled with their scope (e.g., <<>>). + + <>: + + * <>: Starts with <<::::">>>. + + * <>: Represented implicitly by their identifiers in edge definitions + (e.g., <<<"org.apache.maven.extensions:maven-build-cache-extension:jar:1.2.1-SNAPSHOT:">>>). + + * <>: Defined as <<<"source" -> "target">>>, where <<>> is the parent artifact + and <<>> is the dependency, optionally labeled with the scope. + + <>: + ++---+ +digraph "org.apache.maven.extensions:maven-build-cache-extension:jar:1.2.1-SNAPSHOT:" { + "org.apache.maven.extensions:maven-build-cache-extension:jar:1.2.1-SNAPSHOT:" -> "net.openhft:zero-allocation-hashing:jar:0.27ea0:compile"; + "org.apache.maven.extensions:maven-build-cache-extension:jar:1.2.1-SNAPSHOT:" -> "org.apache.maven.wagon:wagon-webdav-jackrabbit:jar:3.5.3:compile"; + "org.apache.maven.wagon:wagon-webdav-jackrabbit:jar:3.5.3:compile" -> "org.apache.jackrabbit:jackrabbit-webdav:jar:2.14.4:compile"; + "org.apache.jackrabbit:jackrabbit-webdav:jar:2.14.4:compile" -> "commons-codec:commons-codec:jar:1.10:compile"; +} ++---+ + + <>: + ++---+ +mvn dependency:tree -DoutputType=dot -DoutputFile=dependency-tree.dot ++---+ + + <>: Convert the DOT file to an image using Graphviz: + ++---+ +dot -Tpng dependency-tree.dot -o dependency-tree.png ++---+ + + <>: Visualize the dependency graph using tools like Graphviz for presentations + or analysis. + +{GraphML (outputType=graphml)} + + <>: GraphML is an XML-based format for representing graphs, compatible with + tools like yEd or Gephi. It represents the dependency tree as a directed graph with nodes + for artifacts and edges for dependencies, including scope information. + + <>: + + * <>: Contains namespace declarations and keys for node and edge graphics + (using <<>> extensions). + + * <>: Defined with <<>>. + + * <>: Each node has an <<>> (a unique number) and a <<>> with a + <<>> containing the artifact coordinates (e.g., <<>>). + + * <>: Defined with <<>> and <<>> node IDs, with a <<>> + containing a <<>> for the scope (e.g., <<>>). + + <>: + ++---+ + + + + + + org.apache.maven.extensions:maven-build-cache-extension:jar:1.2.1-SNAPSHOT: + net.openhft:zero-allocation-hashing:jar:0.27ea0:compile + compile + org.apache.maven.wagon:wagon-webdav-jackrabbit:jar:3.5.3:compile + org.apache.jackrabbit:jackrabbit-webdav:jar:2.14.4:compile + compile + + ++---+ + + <>: + ++---+ +mvn dependency:tree -DoutputType=graphml -DoutputFile=dependency-tree.graphml ++---+ + + <>: Open the GraphML file in yEd or Gephi to visualize the dependency graph. + + <>: Analyze complex dependency structures using graph visualization tools. + +{TGF (outputType=tgf)} + + <>: The Trivial Graph Format (TGF) is a simple text-based format for representing + graphs. It lists nodes followed by edges, with each node and edge described on a single line. + + <>: + + * <>: Each line contains a unique node ID (a number) followed by the artifact + coordinates (e.g., <<>>). + + * <>: A line containing <<<#>>> separates nodes from edges. + + * <>: Each line contains the source node ID, target node ID, and the scope + (e.g., <<>>). + + <>: + ++---+ +1474640235 org.apache.maven.extensions:maven-build-cache-extension:jar:1.2.1-SNAPSHOT: +788877168 net.openhft:zero-allocation-hashing:jar:0.27ea0:compile +1662807313 org.apache.maven.wagon:wagon-webdav-jackrabbit:jar:3.5.3:compile +1655562261 org.apache.jackrabbit:jackrabbit-webdav:jar:2.14.4:compile +1894638973 commons-codec:commons-codec:jar:1.10:compile +# +1474640235 788877168 compile +1474640235 1662807313 compile +1662807313 1655562261 compile +1655562261 1894638973 compile ++---+ + + <>: + ++---+ +mvn dependency:tree -DoutputType=tgf -DoutputFile=dependency-tree.tgf ++---+ + + <>: Convert TGF to other formats (e.g., DOT) using tools like <<>> or + custom scripts for visualization. + + <>: Lightweight format for simple graph processing or conversion to other graph formats. + +* Notes + + * <>: The <<>>, <<>>, <<>>, and <<>> output formats are + available starting with Maven Dependency Plugin version 3.7.0. Always use the latest version + (3.8.1 as of June 2025) for the most stable experience. + + * <>: + + * <>: Parse with any JSON-compatible tool (e.g., Python's <<>> module, JavaScript's <<>>). + + * <>: Use Graphviz (<<>> command) to generate PNG, SVG, or other visual formats. + + * <>: Use yEd, Gephi, or other GraphML-compatible tools for visualization. + + * <>: Use tools supporting TGF or convert to DOT/GraphML for visualization. + + * <>: If you encounter issues or want to improve this documentation, contribute to + the Maven Dependency Plugin repository at + {{{https://github.com/apache/maven-dependency-plugin}https://github.com/apache/maven-dependency-plugin}}. + See the + {{{https://maven.apache.org/guides/development/guide-helping.html}guide to helping with Maven}}. diff --git a/src/site/apt/index.apt.vm b/src/site/apt/index.apt.vm index 07e678e26..b44c07f56 100644 --- a/src/site/apt/index.apt.vm +++ b/src/site/apt/index.apt.vm @@ -37,9 +37,11 @@ ${project.name} *{{{./analyze-mojo.html}dependency:analyze}} analyzes the dependencies of this project and determines which are: used and declared; used and undeclared; unused and declared. - *{{{./analyze-dep-mgt-mojo.html}dependency:analyze-dep-mgt}} analyzes your projects dependencies and lists mismatches + *{{{./analyze-dep-mgt-mojo.html}dependency:analyze-dep-mgt}} analyzes the project's dependencies and lists mismatches between resolved dependencies and those listed in your dependencyManagement section. + *{{{./analyze-exclusions-mojo.html}dependency:analyze-exclusions}} analyzes the exclusions on dependencies and checks if the artifact actually brings in the given dependency. + *{{{./analyze-only-mojo.html}dependency:analyze-only}} is the same as analyze, but is meant to be bound in a pom. It does not fork the build and execute test-compile. @@ -53,6 +55,10 @@ ${project.name} Maven to output the path of the dependencies from the local repository in a classpath format to be used in java -cp. The classpath file may also be attached and installed/deployed along with the main artifact. + *{{{./collect-mojo.html}dependency:collect}} collects the project dependencies from the repository. + It lists the groupId:artifactId:version information by downloading the pom files without downloading the actual + artifacts such as jar files. + *{{{./copy-mojo.html}dependency:copy}} takes a list of artifacts defined in the plugin configuration section and copies them to a specified location, renaming them or stripping the version if desired. This goal can resolve the artifacts from remote repositories if they don't exist in either the local repository or the reactor. @@ -61,7 +67,7 @@ ${project.name} optionally transitive dependencies and copies them to a specified location, stripping the version if desired. This goal can also be run from the command line. - *{{{./display-ancestors-mojo.html}dependency:display-ancestors}} displays all ancestor POMs of the project. + *{{{./display-ancestors-mojo.html}dependency:display-ancestors}} displays all ancestor POMs of the project. This may be useful in a continuous integration system where you want to know all parent poms of the project. This goal can also be run from the command line. @@ -74,10 +80,11 @@ ${project.name} *{{{./list-classes-mojo.html}dependency:list-classes}} displays the fully package-qualified names of all classes found in a specified artifact. - *{{{./list-repositories-mojo.html}dependency:list-repositories}} displays all project dependencies and then lists the repositories used. + *{{{./list-repositories-mojo.html}dependency:list-repositories}} collects all project dependencies and then lists the repositories + used by the build and by the transitive dependencies. - *{{{./properties-mojo.html}dependency:properties}} set a property for each project dependency containing the - to the artifact on the file system. + *{{{./properties-mojo.html}dependency:properties}} sets a property for each project dependency containing the + artifact on the file system. *{{{./purge-local-repository-mojo.html}dependency:purge-local-repository}} tells Maven to clear dependency artifact files out of the local repository, and optionally re-resolve them. @@ -87,9 +94,11 @@ ${project.name} *{{{./resolve-plugins-mojo.html}dependency:resolve-plugins}} tells Maven to resolve plugins and their dependencies. - *{{{./sources-mojo.html}dependency:sources}} tells Maven to resolve all dependencies and their source attachments, + *{{{./resolve-sources-mojo.html}dependency:resolve-sources}} tells Maven to resolve all dependencies and their source attachments, and displays the version. + *{{{./sources-mojo.html}dependency:sources}} has been deprecated for removal in favor of {{{./resolve-sources-mojo.html}dependency:resolve-sources}}. + *{{{./tree-mojo.html}dependency:tree}} displays the dependency tree for this project. *{{{./unpack-mojo.html}dependency:unpack}} like copy but unpacks. @@ -97,25 +106,28 @@ ${project.name} *{{{./unpack-dependencies-mojo.html}dependency:unpack-dependencies}} like copy-dependencies but unpacks. + *{{{./render-dependencies-mojo.html}dependency:render-dependencies}} like + build-classpath but with a custom Velocity template. + [] * Usage General instructions on how to use the Dependency Plugin can be found on the {{{./usage.html}usage page}}. Some more - specific use cases are described in the examples given below. + specific use cases are described in the following examples. - In case you still have questions regarding the plugin's usage, please have a look at the {{{./faq.html}FAQ}} and feel + If you have questions regarding the plugin's usage, please have a look at the {{{./faq.html}FAQ}} and feel free to contact the {{{./mailing-lists.html}user mailing list}}. The posts to the mailing list are archived and could already contain the answer to your question as part of an older thread. Hence, it is also worth browsing/searching the {{{./mailing-lists.html}mail archive}}. - If you feel like the plugin is missing a feature or has a defect, you can file a feature request or bug report in our + If you think the plugin is missing a feature or has a defect, you can file a feature request or bug report in the {{{./issue-management.html}issue tracker}}. When creating a new issue, please provide a comprehensive description of your concern. Especially for fixing bugs it is crucial that the developers can reproduce your problem. For this reason, entire debug logs, POMs or most preferably little demo projects attached to the issue are very much appreciated. Of course, patches are welcome, too. Contributors can check out the project from our {{{./scm.html}source repository}} and will find supplementary information in the - {{{http://maven.apache.org/guides/development/guide-helping.html}guide to helping with Maven}}. + {{{https://maven.apache.org/guides/development/guide-helping.html}guide to helping with Maven}}. * Examples @@ -139,10 +151,12 @@ ${project.name} * {{{./examples/filtering-the-dependency-tree.html}Filtering the Dependency Tree}} - * {{{./examples/resolving-conflicts-using-the-dependency-tree.html}Resolving Conflicts Using the Dependency Tree}} - * {{{./examples/purging-local-repository.html}Purging the local repository}} + * {{{./examples/tree-mojo.html}Tree Mojo}} + + * {{{./examples/render-dependencies.html}Render Dependencies}} + [] * Resources diff --git a/src/site/apt/usage.apt.vm b/src/site/apt/usage.apt.vm index a67381c74..dc5ded5ad 100644 --- a/src/site/apt/usage.apt.vm +++ b/src/site/apt/usage.apt.vm @@ -13,8 +13,8 @@ ~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ~~ KIND, either express or implied. See the License for the ~~ specific language governing permissions and limitations -~~ under the License. - +~~ under the License. + ------ Usage ------ @@ -25,11 +25,11 @@ ------ Usage - - Brief examples on how to use the dependency goals: + + Brief examples of how to use the dependency goals: %{toc|fromDepth=2} - + * <<>> This goal is meant to be bound to a lifecycle phase and configured in your @@ -37,8 +37,8 @@ Usage in the specified location. Multiple artifacts can be defined in a single execution. A default output directory is specified but can be overridden for each ArtifactItem by setting the optional outputDirectory field. An - optional new name can be set to rename or the version stripped while copying. - + optional new name can be set to rename or the version stripped while copying. + The artifact version is optional. If not set, the plugin will attempt to resolve it from the project dependencies and then the dependencyManagement section. @@ -87,12 +87,12 @@ Usage [...] +---+ - + If you intend to configure this goal for execution on the command line using: -+---+ +--- mvn dependency:copy -+---+ +--- you must not put the configuration inside the tag. Your configuration should look like this: @@ -128,41 +128,41 @@ mvn dependency:copy +---+ - - * By default, artifacts are copied into using - Maven artifact file name convention ( ie ). + + * By default, artifacts are copied into using the + Maven artifact file name convention (that is, ). Use the following rules to override the default convention: - - * Use to override the default file name. - + + * Use to override the default file name. + * Use to remove from default file name. This field is ignored when is set. - - * Use to override the plugin's configuration + + * Use to override the plugin's configuration per . - + [] - + [] * <<>> This goal can be bound to a lifecycle phase and configured in your <<>>. It will resolve the dependencies (including transitive dependencies) from - the repository and place a copy in the specified location. + the repository and place a copy in the specified location. The artifacts can be placed in subfolders based on type. For example: - \outputDirectory + /outputDirectory - \outputDirectory\jars + /outputDirectory/jars - \outputDirectory\wars + /outputDirectory/wars The artifacts can be placed in a subfolder per artifact. For example: - \outputDirectory\junit-junit-3.8.1\ + /outputDirectory/junit-junit-3.8.1/ This feature also works with the subfolders per type. For example: - \outputDirectory\jars\junit-junit-3.8.1\ + /outputDirectory/jars/junit-junit-3.8.1/ Artifacts can also be resolved by specifying the classifier and optionally type. Type is only used with the classifier and defaults to java-sources. @@ -171,9 +171,9 @@ mvn dependency:copy <<>> will try to find the sources for all dependencies and copy them. - Also included is the ability to include or exclude by type (war, jar etc), scope (runtime, test, etc), classifier (jdk14, sources, etc), groupId, artifactId, or a combination of them. + Also included is the ability to include or exclude by type (war, jar, etc.), scope (runtime, test, etc.), classifier (jdk14, sources, etc.), groupId, artifactId, or a combination of them. - <> As of 2.0-alpha-5, you may mix includes and excludes of the same category (ie scope). Includes are processed before excludes. + <> You may mix includes and excludes of the same category (e.g. scope). Includes are processed before excludes. See the {{{#Overwrite_Rules}Overwrite Rules}} section for rules about how overwriting is handled. @@ -216,18 +216,18 @@ mvn dependency:copy It will resolve the artifact from the repository and place a copy in the specified location. Multiple artifacts can be defined in a single execution. A default outputDirectory is specified but can be overridden for each - ArtifactItem by setting the optional outputDirectory field. - + ArtifactItem by setting the optional outputDirectory field. + A single artifact can be unpacked multiple times if different include/exclude parameters - are defined for each artifactItem + are defined for each artifact item. See the {{{#Overwrite_Rules}Overwrite Rules}} section for rules about how overwriting is handled. The artifact version is optional. If not set, the plugin will attempt to resolve it from the project dependencies and then the dependencyManagement section. - + Configure the plugin something like this if you intend to bind it to execute along with your build: - + +---+ [...] @@ -258,9 +258,9 @@ mvn dependency:copy If you intend to configure this goal for execution on the command line using: -+---+ +--- mvn dependency:unpack -+---+ +--- you must not put the configuration inside the tag. Your configuration should look like this: @@ -311,16 +311,16 @@ mvn dependency:unpack The artifacts can be unpacked in subfolders based on type. For example: - \outputDirectory + /outputDirectory - \outputDirectory\jars + /outputDirectory/jars - \outputDirectory\wars + /outputDirectory/wars The artifacts can be placed in a subfolder per artifact. For example: - \outputDirectory\junit-junit-3.8.1\ + /outputDirectory/junit-junit-3.8.1/ This feature also works with the subfolders per type. For example: - \outputDirectory\jars\junit-junit-3.8.1\ + /outputDirectory/jars/junit-junit-3.8.1/ Artifacts can also be resolved by specifying the classifier and optionally type. Type is only used with the classifier and defaults to java-sources. @@ -328,15 +328,15 @@ mvn dependency:unpack resolve artifacts with the classifier and type. For example: <<>> will try to find the sources for all dependencies and unpack them. - - Filters can be applied to include or exclude certain file or filesets as necessary - - Also included is the ability to include or exclude by type (war, jar etc), scope (runtime, test, etc), classifier (jdk14, sources, etc), groupId, artifactId, or a combination of them. - <> As of 2.0-alpha-5, you may mix includes and excludes of the same category (ie scope). Includes are processed before excludes. + Filters can be applied to include or exclude files or filesets as necessary + + Also included is the ability to include or exclude by type (war, jar, etc.), scope (runtime, test, etc.), classifier (jdk14, sources, etc.), groupId, artifactId, or a combination of them. + + <> You can mix includes and excludes of the same category (e.g. scope). Includes are processed before excludes. See the {{{#Overwrite_Rules}Overwrite Rules}} section for rules about how overwriting is handled. - + The goal can also be launched from the command line like: <<>> @@ -373,61 +373,61 @@ mvn dependency:unpack Artifacts are copied or unpacked using the following rules: * If the artifact doesn't exist in the destination, then copy/unpack it. - + Otherwise: - + * For copy/unpack goal only: if <<>> or <<>> is true, then it will force an overwrite. - + * Releases check the <<>> value (default = false). If true, then it will force an overwrite. * Snapshots check the <<>> value (default = false). If true, then it will force an overwrite. - + * If none of the above is set to true, then it defaults to the <<>> value (default = true). This value, if true, causes the plugin to only copy if the source is newer than the destination (or it doesn't exist in the destination). (for unpack, this checks the existence of the marker file, created in the <<>> path. To avoid unexpected behavior after <<>>, this path should normally be contained within the <<>> hierarchy.) - + Examples: - + * Using the default settings (<<>> = false, <<>> = false, <<>> = true), then a release or snapshot artifact will only over write the destination if the source is newer than the destination (or marker file if unpacking). - - * If <<>> = true, then a release artifact (ie <<>>) will always overwrite. - - * If <<>> = true, then a snapshot artifact (ie <<>>) will always overwrite. - - * If all of the values are false, then a copy/unpack will only occur if it doesn't exist in the destination (or <<>> if unpacking). - - + + * If <<>> = true, then a release artifact (e.g. <<>>) will always overwrite. + + * If <<>> = true, then a snapshot artifact (e.g. <<>>) will always overwrite. + + * If all of the values are false, then a copy/unpack will only occur if the artifact doesn't exist in the destination (or <<>> if unpacking). + + * <<>> Resolve is intended to be used from the command line like: <<>> - This goal simply tells maven to resolve all test scope (includes compile) - dependencies and then displays the resolved versions. This is intended to - help ensure all dependencies are downloaded to the local repository. This is + This goal resolves all test and compile scoped + dependencies and then displays the resolved versions. This + ensures all dependencies are downloaded to the local repository. This is useful when troubleshooting or during intermittent remote repository - failures when repeatedly building multiproject modules is undersirable and + failures when repeatedly building multiproject modules is undesirable and the build is failing on dependency resolution. It can also be used to quickly determine how versions are being resolved. - Artifacts can also be resolved by specifying the classifer and optionally + Artifacts can also be resolved by specifying the classifier and optionally type. Type is only used with the classifier and defaults to java-sources. When the classifier is set, the list of dependencies is used as the base to - resolve artifacts with the classifer and type. For example: - <<>> will try to find the + resolve artifacts with the classifier and type. For example: + <<>> will try to find the test-jar for all dependencies resolve them to the local repository. -* <<>> +* <<>> - Sources is intended to be used from the command line like: - <<>> + Resolve-sources is intended to be used from the command line like: + <<>> This is the same as the resolve goal except it includes the source attachments if they exist. This is useful when you want to download source - attachments to your local repository. - + attachments to your local repository. + You can also define the <<>> either in the pom or settings to be a common location for all projects. This allows the system to resolve sources faster for dependencies that don't have the sources published. The plugin will store a marker file to describe if the sources were resolved or not. By placing @@ -452,23 +452,23 @@ mvn dependency:unpack (or projects, in the case of a multimodule build) from the local repository. Purges can be run with a variety of limiting parameters, including artifact exclusions, limiting to direct dependencies only, and different levels of - depth for deletion. By default, deleted artifacts can be re-resolved + depth for deletion. By default, deleted artifacts can be re-resolved afterwards; you can disable this by specifying <<<-DreResolve=false>>>. In its simplest form, the goal can be called like this: -+---+ +--- mvn dependency:purge-local-repository -+---+ +--- To add the restriction that the <<>> artifact not be deleted, we can modify the command to this: -+---+ +--- mvn dependency:purge-local-repository -Dexclude=org.apache.maven:maven-plugin-api -+---+ +--- - <> The <<>> parameter is a comma-delimited list of + <> The <<>> parameter is a comma-delimited list of groupId:artifactId pairs. It has a corresponding List-based parameter - <<>> - for convenient use inside the POM. @@ -497,9 +497,9 @@ mvn dependency:purge-local-repository -Dexclude=org.apache.maven:maven-plugin-ap (in order to verify proper artifact resolution, for example), simply use this command: -+---+ +--- mvn dependency:purge-local-repository -DresolutionFuzziness=artifactId -+---+ +--- Finally, it's possible to bind this goal to the build lifecycle. One reason for this might be to clean out all dependencies when the build is initialized, to verify @@ -513,9 +513,9 @@ mvn dependency:purge-local-repository -DresolutionFuzziness=artifactId This goal can be executed from the command line: -+---+ +--- mvn dependency:analyze -+---+ +--- Sample output: @@ -529,20 +529,15 @@ mvn dependency:analyze * <<>> - This goal looks at the dependencies after final resolution and looks for mismatches in your dependencyManagement section. - In versions of maven prior to 2.0.6, it was possible to inherit versions that didn't match your dependencyManagement. See {{{https://issues.apache.org/jira/browse/MNG-1577}MNG-1577}} for more info. - - If this goal detects issues, you should attempt to resolve the discrepancies before upgrading to 2.0.6 to avoid any surprises. This can be done by upgrading or downgrading the version in dependencyManagement to match what is actually - being included at runtime, or you can specify a dependency in your project to override what is being included. You can check the results by rerunning this goal. - If you decide to override by using a dependency, be sure to note it so you can remove it later after upgrading to 2.0.6. You could also use the dependency:analyze goal to uncover this unused direct dependency. + This goal looks at the dependencies after final resolution and looks for mismatches in your dependencyManagement section. - This goal is also useful for just detecting projects that override the dependencyManagement directly. Set ignoreDirect to false to detect these otherwise normal conditions. + This goal is useful for detecting projects that override the dependencyManagement directly. Set ignoreDirect to false to detect these otherwise normal conditions. This goal can be executed from the command line: -+---+ +--- mvn dependency:analyze-dep-mgt -+---+ +--- Sample output: @@ -559,7 +554,7 @@ mvn dependency:analyze-dep-mgt [INFO] Resolved: 2.4 [WARNING] Potential problems found in Dependency Management +---+ - + * <<>> @@ -593,15 +588,15 @@ mvn dependency:analyze-dep-mgt This goal can be executed from the command line: -+-----+ +--- mvn dependency:tree -+-----+ +--- Optionally, the <<>> parameter can be specified to divert the output to a file: -+-----+ +--- mvn dependency:tree -DoutputFile=/path/to/file -+-----+ +--- Also, the <<>> parameter can be used to generate different formats of output. The following formats are currently supported: @@ -616,42 +611,40 @@ mvn dependency:tree -DoutputFile=/path/to/file [] -+-----+ +--- mvn dependency:tree -DoutputFile=/path/to/file.graphml -DoutputType=graphml -+-----+ +--- * <<>> - Since: 2.0-alpha-2 - This goal will output a classpath string of dependencies from the local repository to a file or log and optionally attach and deploy the file. For instance, the file would contain a classpath string like this: -+---+ +--- /home/foo/.m2/repository/org/java/utils/util/util-1.0.jar:/home/foo/.m2/ .... -+---+ +--- The resulting file could then be used like this: - -+---+ + +--- java -cp `cat resultFile` MyClass -+---+ +--- In its simplest form, to output the classpath to the log, the goal can be called like this: -+---+ +--- mvn dependency:build-classpath -+---+ +--- - or to write the classpath to cp.txt.: + or to write the classpath to cp.txt: -+---+ +--- mvn dependency:build-classpath -Dmdep.outputFile=cp.txt -+---+ +--- The goal can also be bound to a lifecycle phase with the following configuration: - -+---+ + ++---+ [...] @@ -682,16 +675,37 @@ mvn dependency:build-classpath -Dmdep.outputFile=cp.txt * <<>> - This goal is used to list all the repositories that this build depends upon. It will show repositories defined in your settings, - poms and declared in transitive dependency poms. + This goal lists all the repositories that this build depends upon. It shows repositories defined in your settings, + poms, and declared in transitive dependency poms. * <<>> - This goal is used to fetch an artifact and (optionally) its dependencies from remote repositories using its Maven coordinates. + This goal resolves an artifact and (optionally) its dependencies from remote repositories using its Maven coordinates. + The Maven Central repository are always consider during resolving. + +--- +mvn dependency:get -DgroupId=org.apache.maven -DartifactId=maven-core -Dversion=2.2.1 -Dpackaging=jar -Dclassifier=sources +mvn dependency:get -DgroupId=org.apache.maven -DartifactId=maven-core -Dversion=2.2.1 -Dpackaging=jar -Dclassifier=sources -DremoteRepositories=https://myrepo.com/maven2 +--- -+-----+ -mvn dependency:get -DgroupId=org.apache.maven -DartifactId=maven-core -Dversion=2.2.1 -Dpackaging=jar -Dclassifier=sources -DremoteRepositories=central::default::https://repo.maven.apache.org/maven2,myrepo::::http://myrepo.com/maven2 -mvn dependency:get -DgroupId=org.apache.maven -DartifactId=maven-core -Dversion=2.2.1 -Dpackaging=jar -Dclassifier=sources -DremoteRepositories=https://repo.maven.apache.org/maven2 -mvn dependency:get -Dartifact=org.apache.maven:maven-core:2.2.1:jar:sources -DremoteRepositories=https://repo.maven.apache.org/maven2 -Ddest=/tmp/myfile.jar -+-----+ + +* <<>> + + This goal checks exclusions on dependencies and checks if the artifact actually brings in the given dependency. + For instance, given dependency a:b:1.0 transitively includes x:y:1.0 which you do not want for some reason and exclude it. + Later a:b:2.0 has removed the unwanted dependency and you upgrade. This goal will inform you that the exclusion is no + longer required. + +--- +mvn dependency:analyze-exclusions +--- + + Sample output: + ++---+ +[WARNING] The following dependencies defines unnecessary excludes +[WARNING] org.apache.maven:maven-artifact: +[WARNING] - javax.annotation:javax.annotation-api +[WARNING] - javax.activation:javax.activation-api ++---+ diff --git a/src/site/site.xml b/src/site/site.xml index 8d192c97a..969c6875a 100644 --- a/src/site/site.xml +++ b/src/site/site.xml @@ -19,16 +19,16 @@ specific language governing permissions and limitations under the License. --> - +

      - + - + @@ -42,9 +42,11 @@ under the License. + + - + diff --git a/src/site/xdoc/download.xml.vm b/src/site/xdoc/download.xml.vm index 3f710359a..8f28f053a 100644 --- a/src/site/xdoc/download.xml.vm +++ b/src/site/xdoc/download.xml.vm @@ -23,102 +23,51 @@ under the License. Download ${project.name} Source +
      -

      ${project.name} ${project.version} is distributed in source format. Use a source archive if you intend to build - ${project.name} yourself. Otherwise, simply use the ready-made binary artifacts from central repository.

      - -

      You will be prompted for a mirror - if the file is not found on yours, please be patient, as it may take 24 - hours to reach all mirrors.

      - -

      In order to guard against corrupted downloads/installations, it is highly recommended to - verify the signature - of the release bundles against the public KEYS used by the Apache Maven - developers.

      +

      ${project.name} ${project.version} is distributed in source format.

      -

      ${project.name} is distributed under the Apache License, version 2.0.

      +

      Use a source archive if you intend to build ${project.name} yourself.

      -

      We strongly encourage our users to configure a Maven repository mirror closer to their location, please read How to Use Mirrors for Repositories.

      - - - - -

      - [if-any logo] - - logo - - [end] - The currently selected mirror is - [preferred]. - If you encounter a problem with this mirror, - please select another mirror. - If all mirrors are failing, there are - backup - mirrors - (at the end of the mirrors list) that should be available. -

      +

      Otherwise, simply use the ready-made binary artifacts from central repository.

      -
      - Other mirrors: - - -
      +

      ${project.name} is distributed under the Apache License, version 2.0.

      -

      - You may also consult the - complete list of - mirrors. + + +

      This is the current stable version of ${project.name}.

      + + + + + + + + + + + + + + + + + + +
      LinkChecksumSignature
      ${project.name} ${project.version} (Source zip)${project.artifactId}-${project.version}-source-release.zip${project.artifactId}-${project.version}-source-release.zip.sha512${project.artifactId}-${project.version}-source-release.zip.asc
      + +

      It is essential that you verify the integrity of the downloaded file + using the checksum (.sha512 file) + or using the signature (.asc file) against the public KEYS used by the Apache Maven developers.

      - - - -

      This is the current stable version of ${project.name}.

      - - - - - - - - - - - - - - - - - - -
      LinkChecksumSignature
      ${project.name} ${project.version} (Source zip)maven/plugins/${project.artifactId}-${project.version}-source-release.zipmaven/plugins/${project.artifactId}-${project.version}-source-release.zip.sha512maven/plugins/${project.artifactId}-${project.version}-source-release.zip.asc
      -
      - -

      Older non-recommended releases can be found on our archive site.

      - +

      It is strongly recommended to use the latest release version of ${project.name} to take advantage of the newest features and bug fixes.

      +

      Older non-recommended releases can be found on our archive site.

      diff --git a/src/test/java/org/apache/maven/plugins/dependency/AbstractDependencyMojoTest.java b/src/test/java/org/apache/maven/plugins/dependency/AbstractDependencyMojoTest.java index 8fc1e29a6..6d45e86e1 100644 --- a/src/test/java/org/apache/maven/plugins/dependency/AbstractDependencyMojoTest.java +++ b/src/test/java/org/apache/maven/plugins/dependency/AbstractDependencyMojoTest.java @@ -18,18 +18,17 @@ */ package org.apache.maven.plugins.dependency; -import static org.apache.maven.plugins.dependency.AbstractDependencyMojoTest.ConcreteDependencyMojo.createConcreteDependencyMojoWithArtifactRepositories; -import static org.apache.maven.plugins.dependency.AbstractDependencyMojoTest.ConcreteDependencyMojo.createConcreteDependencyMojoWithPluginRepositories; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import java.lang.reflect.Field; import java.util.ArrayList; -import java.util.List; + import junit.framework.TestCase; import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.execution.MavenSession; +import org.apache.maven.project.MavenProject; import org.apache.maven.project.ProjectBuildingRequest; +import org.sonatype.plexus.build.incremental.BuildContext; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; public class AbstractDependencyMojoTest extends TestCase { private MavenSession session = mock(MavenSession.class); @@ -41,30 +40,9 @@ public class AbstractDependencyMojoTest extends TestCase { private ArrayList pluginRepos = new ArrayList<>(); static class ConcreteDependencyMojo extends AbstractDependencyMojo { - static ConcreteDependencyMojo createConcreteDependencyMojoWithArtifactRepositories( - MavenSession mavenSession, List artifactRepos) - throws NoSuchFieldException, IllegalAccessException { - ConcreteDependencyMojo cdm = new ConcreteDependencyMojo(); - cdm.session = mavenSession; - Field par = AbstractDependencyMojo.class.getDeclaredField("remoteRepositories"); - par.setAccessible(true); - par.set(cdm, artifactRepos); - - return cdm; - } - - static ConcreteDependencyMojo createConcreteDependencyMojoWithPluginRepositories( - MavenSession mavenSession, List pluginRepos) - throws NoSuchFieldException, IllegalAccessException { - ConcreteDependencyMojo cdm = new ConcreteDependencyMojo(); - cdm.session = mavenSession; - - Field par = AbstractDependencyMojo.class.getDeclaredField("remotePluginRepositories"); - par.setAccessible(true); - par.set(cdm, pluginRepos); - - return cdm; + protected ConcreteDependencyMojo(MavenSession session, BuildContext buildContext, MavenProject project) { + super(session, buildContext, project); } @Override @@ -80,6 +58,7 @@ protected void setUp() throws Exception { artifactRepos.add(newRepositoryWithId("ar-snapshots")); artifactRepos.add(newRepositoryWithId("ar-staging")); + when(buildingRequest.getRepositoryMerging()).thenReturn(ProjectBuildingRequest.RepositoryMerging.POM_DOMINANT); when(session.getProjectBuildingRequest()).thenReturn(buildingRequest); } @@ -88,47 +67,4 @@ private static ArtifactRepository newRepositoryWithId(String id) { when(repo.getId()).thenReturn(id); return repo; } - - public void testNewResolveArtifactProjectBuildingRequestRemoteRepositoriesSize() - throws NoSuchFieldException, IllegalAccessException { - AbstractDependencyMojo mojo = createConcreteDependencyMojoWithArtifactRepositories(session, artifactRepos); - - ProjectBuildingRequest pbr = mojo.newResolveArtifactProjectBuildingRequest(); - List rrepos = pbr.getRemoteRepositories(); - - assertEquals(3, rrepos.size()); - } - - public void testNewResolveArtifactProjectBuildingRequestRemoteRepositoriesContents() - throws NoSuchFieldException, IllegalAccessException { - AbstractDependencyMojo mojo = createConcreteDependencyMojoWithArtifactRepositories(session, artifactRepos); - - ProjectBuildingRequest pbr = mojo.newResolveArtifactProjectBuildingRequest(); - List rrepos = pbr.getRemoteRepositories(); - - assertEquals("ar-central", rrepos.get(0).getId()); - assertEquals("ar-snapshots", rrepos.get(1).getId()); - assertEquals("ar-staging", rrepos.get(2).getId()); - } - - public void testNewResolvePluginProjectBuildingRequestRemoteRepositoriesSize() - throws NoSuchFieldException, IllegalAccessException { - AbstractDependencyMojo mojo = createConcreteDependencyMojoWithPluginRepositories(session, pluginRepos); - - ProjectBuildingRequest pbr = mojo.newResolvePluginProjectBuildingRequest(); - List rrepos = pbr.getRemoteRepositories(); - - assertEquals(2, rrepos.size()); - } - - public void testNewResolvePluginProjectBuildingRequestRemoteRepositoriesContents() - throws NoSuchFieldException, IllegalAccessException { - AbstractDependencyMojo mojo = createConcreteDependencyMojoWithPluginRepositories(session, pluginRepos); - - ProjectBuildingRequest pbr = mojo.newResolvePluginProjectBuildingRequest(); - List rrepos = pbr.getRemoteRepositories(); - - assertEquals("pr-central", rrepos.get(0).getId()); - assertEquals("pr-plugins", rrepos.get(1).getId()); - } } diff --git a/src/test/java/org/apache/maven/plugins/dependency/AbstractDependencyMojoTestCase.java b/src/test/java/org/apache/maven/plugins/dependency/AbstractDependencyMojoTestCase.java index 89ef23129..7e1006770 100644 --- a/src/test/java/org/apache/maven/plugins/dependency/AbstractDependencyMojoTestCase.java +++ b/src/test/java/org/apache/maven/plugins/dependency/AbstractDependencyMojoTestCase.java @@ -20,16 +20,22 @@ import java.io.File; import java.io.IOException; +import java.nio.file.Files; + import org.apache.commons.io.FileUtils; +import org.apache.maven.artifact.Artifact; import org.apache.maven.plugin.LegacySupport; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.testing.AbstractMojoTestCase; import org.apache.maven.plugins.dependency.testUtils.DependencyArtifactStubFactory; +import org.apache.maven.plugins.dependency.utils.CopyUtil; import org.codehaus.plexus.component.repository.exception.ComponentLookupException; import org.eclipse.aether.DefaultRepositorySystemSession; import org.eclipse.aether.RepositorySystem; +import org.eclipse.aether.RepositorySystemSession; import org.eclipse.aether.repository.LocalRepository; import org.eclipse.aether.repository.LocalRepositoryManager; +import org.sonatype.plexus.build.incremental.DefaultBuildContext; public abstract class AbstractDependencyMojoTestCase extends AbstractMojoTestCase { @@ -37,36 +43,68 @@ public abstract class AbstractDependencyMojoTestCase extends AbstractMojoTestCas protected DependencyArtifactStubFactory stubFactory; - protected void setUp(String testDirStr, boolean createFiles) throws Exception { - setUp(testDirStr, createFiles, true); + /** + * Initializes the test environment by creating a temporary directory and setting up the stub factory. + * Subclasses must call super.setUp() in their own setUp method to ensure proper initialization. + * To customize the test directory name, file creation, or path structure, override getTestDirectoryName(), + * shouldCreateFiles(), and shouldUseFlattenedPath() respectively. + * + * @throws Exception if setup fails + */ + protected void setUp() throws Exception { + // Required for mojo lookups to work + super.setUp(); + + testDir = Files.createTempDirectory(getTestDirectoryName()).toFile(); + testDir.deleteOnExit(); + + stubFactory = new DependencyArtifactStubFactory(testDir, shouldCreateFiles(), shouldUseFlattenedPath()); } - protected void setUp(String testDirStr, boolean createFiles, boolean flattenedPath) throws Exception { - // required for mojo lookups to work - super.setUp(); - testDir = new File( - getBasedir(), - "target" + File.separatorChar + "unit-tests" + File.separatorChar + testDirStr + File.separatorChar); - FileUtils.deleteDirectory(testDir); - assertFalse(testDir.exists()); + /** + * Returns the name of the temporary test directory. Subclasses can override to customize. + * + * @return the test directory name + */ + protected String getTestDirectoryName() { + return "test-dir"; + } + + /** + * Determines whether files should be created by the stub factory. Subclasses can override to customize. + * + * @return true if files should be created, false otherwise + */ + protected boolean shouldCreateFiles() { + return true; + } - stubFactory = new DependencyArtifactStubFactory(this.testDir, createFiles, flattenedPath); + /** + * Determines whether the stub factory should use flattened paths. Subclasses can override to customize. + * + * @return true if flattened paths should be used, false otherwise + */ + protected boolean shouldUseFlattenedPath() { + return true; } - protected void tearDown() { + /** + * Cleans up the test environment by deleting the temporary directory. + * Subclasses must call super.tearDown() in their own tearDown method to ensure proper cleanup. + * + * @throws Exception if cleanup fails + */ + @Override + protected void tearDown() throws Exception { if (testDir != null) { - try { - FileUtils.deleteDirectory(testDir); - } catch (IOException e) { - e.printStackTrace(); - fail("Trying to remove directory:" + testDir + System.lineSeparator() + e.toString()); - } - assertFalse(testDir.exists()); + FileUtils.deleteDirectory(testDir); + assertFalse("Test directory should not exist after cleanup", testDir.exists()); } + super.tearDown(); } - protected void copyFile(AbstractDependencyMojo mojo, File artifact, File destFile) throws MojoExecutionException { - mojo.copyFile(artifact, destFile); + protected void copyArtifactFile(Artifact sourceArtifact, File destFile) throws MojoExecutionException, IOException { + new CopyUtil(new DefaultBuildContext()).copyArtifactFile(sourceArtifact, destFile); } protected void installLocalRepository(LegacySupport legacySupport) throws ComponentLookupException { @@ -78,4 +116,12 @@ protected void installLocalRepository(LegacySupport legacySupport) throws Compon LocalRepositoryManager manager = system.newLocalRepositoryManager(repoSession, localRepository); repoSession.setLocalRepositoryManager(manager); } + + protected void installLocalRepository(RepositorySystemSession repoSession) throws ComponentLookupException { + RepositorySystem system = lookup(RepositorySystem.class); + String directory = stubFactory.getWorkingDir().toString(); + LocalRepository localRepository = new LocalRepository(directory); + LocalRepositoryManager manager = system.newLocalRepositoryManager(repoSession, localRepository); + ((DefaultRepositorySystemSession) repoSession).setLocalRepositoryManager(manager); + } } diff --git a/src/test/java/org/apache/maven/plugins/dependency/TestCollectMojo.java b/src/test/java/org/apache/maven/plugins/dependency/TestCollectMojo.java index 8c3045a83..f93ee2cef 100644 --- a/src/test/java/org/apache/maven/plugins/dependency/TestCollectMojo.java +++ b/src/test/java/org/apache/maven/plugins/dependency/TestCollectMojo.java @@ -20,17 +20,38 @@ import java.io.File; import java.util.Set; + import org.apache.maven.artifact.Artifact; -import org.apache.maven.plugin.testing.SilentLog; +import org.apache.maven.execution.MavenSession; import org.apache.maven.plugins.dependency.resolvers.CollectDependenciesMojo; +import org.apache.maven.plugins.dependency.resolvers.ResolveDependenciesMojo; +import org.apache.maven.plugins.dependency.testUtils.stubs.DependencyProjectStub; +import org.apache.maven.plugins.dependency.utils.DependencySilentLog; import org.apache.maven.plugins.dependency.utils.DependencyStatusSets; import org.apache.maven.project.MavenProject; public class TestCollectMojo extends AbstractDependencyMojoTestCase { + @Override + protected String getTestDirectoryName() { + return "markers"; + } + + @Override + protected boolean shouldCreateFiles() { + return false; + } + + @Override protected void setUp() throws Exception { // required for mojo lookups to work - super.setUp("markers", false); + super.setUp(); + + MavenProject project = new DependencyProjectStub(); + getContainer().addComponent(project, MavenProject.class.getName()); + + MavenSession session = newMavenSession(project); + getContainer().addComponent(session, MavenSession.class.getName()); } /** @@ -46,7 +67,6 @@ public void testCollectTestEnvironment() throws Exception { assertNotNull(mojo.getProject()); MavenProject project = mojo.getProject(); - mojo.setSilent(true); Set artifacts = this.stubFactory.getScopedArtifacts(); Set directArtifacts = this.stubFactory.getReleaseAndSnapshotArtifacts(); artifacts.addAll(directArtifacts); @@ -65,7 +85,7 @@ public void testCollectTestEnvironment() throws Exception { * * @throws Exception if a problem occurs */ - public void testCollectTestEnvironment_excludeTransitive() throws Exception { + public void testCollectTestEnvironmentExcludeTransitive() throws Exception { File testPom = new File(getBasedir(), "target/test-classes/unit/collect-test/plugin-config.xml"); CollectDependenciesMojo mojo = (CollectDependenciesMojo) lookupMojo("collect", testPom); @@ -73,7 +93,6 @@ public void testCollectTestEnvironment_excludeTransitive() throws Exception { assertNotNull(mojo.getProject()); MavenProject project = mojo.getProject(); - mojo.setSilent(true); Set artifacts = this.stubFactory.getScopedArtifacts(); Set directArtifacts = this.stubFactory.getReleaseAndSnapshotArtifacts(); artifacts.addAll(directArtifacts); @@ -90,10 +109,15 @@ public void testCollectTestEnvironment_excludeTransitive() throws Exception { } public void testSilent() throws Exception { - File testPom = new File(getBasedir(), "target/test-classes/unit/collect-test/plugin-config.xml"); - CollectDependenciesMojo mojo = (CollectDependenciesMojo) lookupMojo("collect", testPom); - mojo.setSilent(false); + File testPom = new File(getBasedir(), "target/test-classes/unit/resolve-test/plugin-config.xml"); + ResolveDependenciesMojo mojo = (ResolveDependenciesMojo) lookupMojo("resolve", testPom); - assertFalse(mojo.getLog() instanceof SilentLog); + assertFalse(mojo.getLog() instanceof DependencySilentLog); + + mojo.setSilent(true); + assertTrue(mojo.getLog() instanceof DependencySilentLog); + + mojo.setSilent(false); + assertFalse(mojo.getLog() instanceof DependencySilentLog); } // TODO: Test skipping artifacts. } diff --git a/src/test/java/org/apache/maven/plugins/dependency/TestGetMojo.java b/src/test/java/org/apache/maven/plugins/dependency/TestGetMojo.java index 4996b6974..ae793392d 100644 --- a/src/test/java/org/apache/maven/plugins/dependency/TestGetMojo.java +++ b/src/test/java/org/apache/maven/plugins/dependency/TestGetMojo.java @@ -23,13 +23,15 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.Collections; + import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy; import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout; import org.apache.maven.execution.MavenSession; import org.apache.maven.plugin.LegacySupport; import org.apache.maven.plugin.MojoFailureException; -import org.apache.maven.plugin.testing.stubs.MavenProjectStub; +import org.apache.maven.plugins.dependency.testUtils.stubs.DependencyProjectStub; +import org.apache.maven.project.MavenProject; import org.apache.maven.settings.Server; import org.apache.maven.settings.Settings; import org.eclipse.jetty.security.ConstraintMapping; @@ -45,9 +47,25 @@ public class TestGetMojo extends AbstractDependencyMojoTestCase { private GetMojo mojo; + @Override + protected String getTestDirectoryName() { + return "markers"; + } + + @Override + protected boolean shouldCreateFiles() { + return false; + } + + @Override protected void setUp() throws Exception { // required for mojo lookups to work - super.setUp("markers", false); + super.setUp(); + MavenProject project = new DependencyProjectStub(); + getContainer().addComponent(project, MavenProject.class.getName()); + + MavenSession session = newMavenSession(project); + getContainer().addComponent(session, MavenSession.class.getName()); File testPom = new File(getBasedir(), "target/test-classes/unit/get-test/plugin-config.xml"); mojo = (GetMojo) lookupMojo("get", testPom); @@ -55,14 +73,13 @@ protected void setUp() throws Exception { assertNotNull(mojo); LegacySupport legacySupport = lookup(LegacySupport.class); - MavenSession mavenSession = newMavenSession(new MavenProjectStub()); - Settings settings = mavenSession.getSettings(); + Settings settings = session.getSettings(); Server server = new Server(); server.setId("myserver"); server.setUsername("foo"); server.setPassword("bar"); settings.addServer(server); - legacySupport.setSession(mavenSession); + legacySupport.setSession(session); installLocalRepository(legacySupport); diff --git a/src/test/java/org/apache/maven/plugins/dependency/TestListClassesMojo.java b/src/test/java/org/apache/maven/plugins/dependency/TestListClassesMojo.java index 88cc4c16f..1569b9173 100644 --- a/src/test/java/org/apache/maven/plugins/dependency/TestListClassesMojo.java +++ b/src/test/java/org/apache/maven/plugins/dependency/TestListClassesMojo.java @@ -22,13 +22,15 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.Arrays; import java.util.List; + import org.apache.maven.execution.MavenSession; -import org.apache.maven.plugin.LegacySupport; import org.apache.maven.plugin.logging.Log; -import org.apache.maven.plugin.testing.stubs.MavenProjectStub; -import org.apache.maven.settings.Server; -import org.apache.maven.settings.Settings; +import org.apache.maven.plugins.dependency.testUtils.stubs.DependencyProjectStub; +import org.apache.maven.plugins.dependency.utils.ResolverUtil; +import org.apache.maven.project.MavenProject; +import org.eclipse.aether.RepositorySystem; import org.junit.Assert; import org.mockito.ArgumentCaptor; import org.mockito.Mockito; @@ -36,8 +38,31 @@ public class TestListClassesMojo extends AbstractDependencyMojoTestCase { private ListClassesMojo mojo; + @Override + protected String getTestDirectoryName() { + return "markers"; + } + + @Override + protected boolean shouldCreateFiles() { + return false; + } + + @Override protected void setUp() throws Exception { - super.setUp("markers", false); + super.setUp(); + + MavenProject project = new DependencyProjectStub(); + getContainer().addComponent(project, MavenProject.class.getName()); + + MavenSession session = newMavenSession(project); + + RepositorySystem repositorySystem = lookup(RepositorySystem.class); + ResolverUtil resolverUtil = new ResolverUtil(repositorySystem, () -> session); + getContainer().addComponent(resolverUtil, ResolverUtil.class.getName()); + + getContainer().addComponent(session, MavenSession.class.getName()); + File testPom = new File(getBasedir(), "target/test-classes/unit/get-test/plugin-config.xml"); assertTrue(testPom.exists()); @@ -45,22 +70,34 @@ protected void setUp() throws Exception { assertNotNull(mojo); - LegacySupport legacySupport = lookup(LegacySupport.class); - MavenSession session = newMavenSession(new MavenProjectStub()); - Settings settings = session.getSettings(); - Server server = new Server(); - server.setId("myserver"); - server.setUsername("foo"); - server.setPassword("bar"); - settings.addServer(server); - legacySupport.setSession(session); + installLocalRepository(session.getRepositorySession()); + } - installLocalRepository(legacySupport); + public void testListClassesNotTransitive() throws Exception { + Path path = Paths.get("src/test/resources/unit/list-test/testListClassesNotTransitive.txt"); + List expectedLogArgs = Files.readAllLines(path); + ArgumentCaptor infoArgsCaptor = ArgumentCaptor.forClass(String.class); + + setVariableValueToObject( + mojo, + "remoteRepositories", + Arrays.asList( + "central::default::https://repo.maven.apache.org/maven2", + "central::::https://repo.maven.apache.org/maven2", + "https://repo.maven.apache.org/maven2")); + mojo.setArtifact("org.apache.commons:commons-lang3:3.6"); + setVariableValueToObject(mojo, "transitive", Boolean.FALSE); + + Log log = Mockito.mock(Log.class); + mojo.setLog(log); + + mojo.execute(); - setVariableValueToObject(mojo, "session", legacySupport.getSession()); + Mockito.verify(log, Mockito.times(expectedLogArgs.size())).info(infoArgsCaptor.capture()); + Assert.assertEquals(expectedLogArgs, infoArgsCaptor.getAllValues()); } - public void testListClassesNotTransitive() throws Exception { + public void testListClassesNotTransitiveByGAV() throws Exception { Path path = Paths.get("src/test/resources/unit/list-test/testListClassesNotTransitive.txt"); List expectedLogArgs = Files.readAllLines(path); ArgumentCaptor infoArgsCaptor = ArgumentCaptor.forClass(String.class); @@ -68,9 +105,15 @@ public void testListClassesNotTransitive() throws Exception { setVariableValueToObject( mojo, "remoteRepositories", - "central::default::https://repo.maven.apache.org/maven2," - + "central::::https://repo.maven.apache.org/maven2," + "https://repo.maven.apache.org/maven2"); - setVariableValueToObject(mojo, "artifact", "org.apache.commons:commons-lang3:3.6"); + Arrays.asList( + "central1::default::https://repo.maven.apache.org/maven2", + "central2::::https://repo.maven.apache.org/maven2", + "https://repo.maven.apache.org/maven2")); + + mojo.setGroupId("org.apache.commons"); + mojo.setArtifactId("commons-lang3"); + mojo.setVersion("3.6"); + setVariableValueToObject(mojo, "transitive", Boolean.FALSE); Log log = Mockito.mock(Log.class); @@ -90,9 +133,38 @@ public void testListClassesTransitive() throws Exception { setVariableValueToObject( mojo, "remoteRepositories", - "central::default::https://repo.maven.apache.org/maven2," - + "central::::https://repo.maven.apache.org/maven2," + "https://repo.maven.apache.org/maven2"); - setVariableValueToObject(mojo, "artifact", "org.apache.commons:commons-lang3:3.6"); + Arrays.asList( + "central::default::https://repo.maven.apache.org/maven2", + "central::::https://repo.maven.apache.org/maven2", + "https://repo.maven.apache.org/maven2")); + + mojo.setArtifact("org.apache.commons:commons-lang3:3.6"); + setVariableValueToObject(mojo, "transitive", Boolean.TRUE); + + Log log = Mockito.mock(Log.class); + mojo.setLog(log); + + mojo.execute(); + + Mockito.verify(log, Mockito.times(expectedLogArgs.size())).info(infoArgsCaptor.capture()); + Assert.assertEquals(expectedLogArgs, infoArgsCaptor.getAllValues()); + } + + public void testListClassesTransitiveByGAV() throws Exception { + Path path = Paths.get("src/test/resources/unit/list-test/testListClassesTransitive.txt"); + List expectedLogArgs = Files.readAllLines(path); + ArgumentCaptor infoArgsCaptor = ArgumentCaptor.forClass(String.class); + + setVariableValueToObject( + mojo, + "remoteRepositories", + Arrays.asList( + "central::default::https://repo.maven.apache.org/maven2", + "central::::https://repo.maven.apache.org/maven2", + "https://repo.maven.apache.org/maven2")); + mojo.setGroupId("org.apache.commons"); + mojo.setArtifactId("commons-lang3"); + mojo.setVersion("3.6"); setVariableValueToObject(mojo, "transitive", Boolean.TRUE); Log log = Mockito.mock(Log.class); diff --git a/src/test/java/org/apache/maven/plugins/dependency/TestPropertiesMojo.java b/src/test/java/org/apache/maven/plugins/dependency/TestPropertiesMojo.java index 8f7b7af4a..2e3db085f 100644 --- a/src/test/java/org/apache/maven/plugins/dependency/TestPropertiesMojo.java +++ b/src/test/java/org/apache/maven/plugins/dependency/TestPropertiesMojo.java @@ -20,13 +20,34 @@ import java.io.File; import java.util.Set; + import org.apache.maven.artifact.Artifact; +import org.apache.maven.execution.MavenSession; +import org.apache.maven.plugins.dependency.testUtils.stubs.DependencyProjectStub; import org.apache.maven.project.MavenProject; public class TestPropertiesMojo extends AbstractDependencyMojoTestCase { + + @Override + protected String getTestDirectoryName() { + return "markers"; + } + + @Override + protected boolean shouldCreateFiles() { + return true; + } + + @Override protected void setUp() throws Exception { // required for mojo lookups to work - super.setUp("markers", true); + super.setUp(); + + MavenProject project = new DependencyProjectStub(); + getContainer().addComponent(project, MavenProject.class.getName()); + + MavenSession session = newMavenSession(project); + getContainer().addComponent(session, MavenSession.class.getName()); } /** @@ -47,9 +68,7 @@ public void testSetProperties() throws Exception { artifacts.addAll(directArtifacts); project.setArtifacts(artifacts); - project.setDependencyArtifacts(directArtifacts); - // this.assertNull( project.getProperties().getProperty( "org.apacha ) ) mojo.execute(); for (Artifact artifact : artifacts) { diff --git a/src/test/java/org/apache/maven/plugins/dependency/TestSkip.java b/src/test/java/org/apache/maven/plugins/dependency/TestSkip.java index 156ac83f1..1fbcacb08 100644 --- a/src/test/java/org/apache/maven/plugins/dependency/TestSkip.java +++ b/src/test/java/org/apache/maven/plugins/dependency/TestSkip.java @@ -18,16 +18,35 @@ */ package org.apache.maven.plugins.dependency; -import static org.mockito.Mockito.atLeastOnce; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - import java.io.File; + +import org.apache.maven.execution.MavenSession; +import org.apache.maven.model.Plugin; import org.apache.maven.plugin.Mojo; +import org.apache.maven.plugin.MojoExecution; +import org.apache.maven.plugin.descriptor.MojoDescriptor; +import org.apache.maven.plugin.descriptor.PluginDescriptor; import org.apache.maven.plugin.logging.Log; +import org.apache.maven.plugins.dependency.testUtils.stubs.DependencyProjectStub; +import org.apache.maven.project.MavenProject; import org.mockito.ArgumentCaptor; +import static org.mockito.Mockito.atLeastOnce; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + public class TestSkip extends AbstractDependencyMojoTestCase { + + @Override + protected void setUp() throws Exception { + super.setUp(); + MavenProject project = new DependencyProjectStub(); + getContainer().addComponent(project, MavenProject.class.getName()); + + MavenSession session = newMavenSession(project); + getContainer().addComponent(session, MavenSession.class.getName()); + } + public void testSkipAnalyze() throws Exception { doTest("analyze"); } @@ -41,7 +60,7 @@ public void testSkipAnalyzeOnly() throws Exception { } public void testSkipAnalyzeReport() throws Exception { - doSpecialTest("analyze-report"); + doSpecialTest("analyze-report", true); } public void testSkipAnalyzeDuplicate() throws Exception { @@ -109,19 +128,55 @@ protected void doTest(String mojoName) throws Exception { } protected void doSpecialTest(String mojoName) throws Exception { - doConfigTest(mojoName, "plugin-" + mojoName + "-config.xml"); + doConfigTest(mojoName, "plugin-" + mojoName + "-config.xml", false); + } + + protected void doSpecialTest(String mojoName, boolean addMojoExecution) throws Exception { + doConfigTest(mojoName, "plugin-" + mojoName + "-config.xml", addMojoExecution); } private void doConfigTest(String mojoName, String configFile) throws Exception { + doConfigTest(mojoName, configFile, false); + } + + private void doConfigTest(String mojoName, String configFile, boolean addMojoExecution) throws Exception { File testPom = new File(getBasedir(), "target/test-classes/unit/skip-test/" + configFile); Mojo mojo = lookupMojo(mojoName, testPom); - assertNotNull(mojo); + assertNotNull("Mojo not found.", mojo); + + if (addMojoExecution) { + setVariableValueToObject(mojo, "mojoExecution", getMockMojoExecution(mojoName)); + } Log log = mock(Log.class); mojo.setLog(log); mojo.execute(); ArgumentCaptor captor = ArgumentCaptor.forClass(String.class); verify(log, atLeastOnce()).info(captor.capture()); - assertTrue(captor.getValue().contains("Skipping plugin execution")); + String skipMessage; + if (addMojoExecution) { + MojoExecution me = getMockMojoExecution(mojoName); + String reportMojoInfo = me.getPlugin().getId() + ":" + me.getGoal(); + skipMessage = "Skipping " + reportMojoInfo + " report goal"; + } else { + skipMessage = "Skipping plugin execution"; + } + assertTrue(captor.getValue().contains(skipMessage)); + } + + private MojoExecution getMockMojoExecution(String goal) { + MojoDescriptor md = new MojoDescriptor(); + md.setGoal(goal); + + MojoExecution me = new MojoExecution(md); + + PluginDescriptor pd = new PluginDescriptor(); + Plugin p = new Plugin(); + p.setGroupId("org.apache.maven.plugins"); + p.setArtifactId("maven-dependency-plugin"); + pd.setPlugin(p); + md.setPluginDescriptor(pd); + + return me; } } diff --git a/src/test/java/org/apache/maven/plugins/dependency/analyze/TestAnalyzeDepMgt.java b/src/test/java/org/apache/maven/plugins/dependency/analyze/TestAnalyzeDepMgt.java index 7d351437e..32c0919c6 100644 --- a/src/test/java/org/apache/maven/plugins/dependency/analyze/TestAnalyzeDepMgt.java +++ b/src/test/java/org/apache/maven/plugins/dependency/analyze/TestAnalyzeDepMgt.java @@ -18,8 +18,6 @@ */ package org.apache.maven.plugins.dependency.analyze; -import static org.junit.Assert.assertNotEquals; - import java.io.File; import java.io.IOException; import java.util.ArrayList; @@ -27,6 +25,7 @@ import java.util.List; import java.util.Map; import java.util.Set; + import junit.framework.TestCase; import org.apache.maven.artifact.Artifact; import org.apache.maven.model.Dependency; @@ -38,6 +37,8 @@ import org.apache.maven.plugins.dependency.testUtils.stubs.DependencyProjectStub; import org.apache.maven.project.MavenProject; +import static org.junit.Assert.assertNotEquals; + public class TestAnalyzeDepMgt extends TestCase { AnalyzeDepMgt mojo; @@ -48,23 +49,20 @@ public class TestAnalyzeDepMgt extends TestCase { Exclusion ex; - Artifact exclusionArtifact; - DependencyManagement depMgt; - DependencyManagement depMgtNoExclusions; - + @Override protected void setUp() throws Exception { - mojo = new AnalyzeDepMgt(); MavenProject project = new DependencyProjectStub(); + mojo = new AnalyzeDepMgt(project); stubFactory = new DependencyArtifactStubFactory(new File(""), false); Set allArtifacts = stubFactory.getMixedArtifacts(); Set directArtifacts = stubFactory.getClassifiedArtifacts(); - exclusionArtifact = stubFactory.getReleaseArtifact(); + Artifact exclusionArtifact = stubFactory.getReleaseArtifact(); directArtifacts.add(exclusionArtifact); ex = new Exclusion(); ex.setArtifactId(exclusionArtifact.getArtifactId()); @@ -86,8 +84,6 @@ protected void setUp() throws Exception { project.setArtifacts(allArtifacts); project.setDependencyArtifacts(directArtifacts); - - mojo.setProject(project); } public void testGetManagementKey() throws IOException { @@ -110,32 +106,41 @@ public void testGetManagementKey() throws IOException { // sure it's ok before // testing the next one dep.setType("t"); + dep.clearManagementKey(); assertNotEquals(dep.getManagementKey(), mojo.getArtifactManagementKey(artifact)); dep.setType("type"); + dep.clearManagementKey(); assertEquals(dep.getManagementKey(), mojo.getArtifactManagementKey(artifact)); dep.setArtifactId("a"); + dep.clearManagementKey(); assertNotEquals(dep.getManagementKey(), mojo.getArtifactManagementKey(artifact)); dep.setArtifactId("artifact"); + dep.clearManagementKey(); assertEquals(dep.getManagementKey(), mojo.getArtifactManagementKey(artifact)); dep.setClassifier("c"); + dep.clearManagementKey(); assertNotEquals(dep.getManagementKey(), mojo.getArtifactManagementKey(artifact)); dep.setClassifier("class"); + dep.clearManagementKey(); assertEquals(dep.getManagementKey(), mojo.getArtifactManagementKey(artifact)); dep.setGroupId("g"); + dep.clearManagementKey(); assertNotEquals(dep.getManagementKey(), mojo.getArtifactManagementKey(artifact)); dep.setGroupId("group"); dep.setClassifier(null); + dep.clearManagementKey(); artifact = stubFactory.createArtifact("group", "artifact", "1.0", Artifact.SCOPE_COMPILE, "type", null); assertEquals(dep.getManagementKey(), mojo.getArtifactManagementKey(artifact)); dep.setClassifier(""); + dep.clearManagementKey(); artifact = stubFactory.createArtifact("group", "artifact", "1.0", Artifact.SCOPE_COMPILE, "type", ""); assertEquals(dep.getManagementKey(), mojo.getArtifactManagementKey(artifact)); } diff --git a/src/test/java/org/apache/maven/plugins/dependency/analyze/TestAnalyzeDuplicateMojo.java b/src/test/java/org/apache/maven/plugins/dependency/analyze/TestAnalyzeDuplicateMojo.java index 1c9750f9f..b0b758092 100644 --- a/src/test/java/org/apache/maven/plugins/dependency/analyze/TestAnalyzeDuplicateMojo.java +++ b/src/test/java/org/apache/maven/plugins/dependency/analyze/TestAnalyzeDuplicateMojo.java @@ -21,8 +21,13 @@ import java.io.File; import java.io.PrintWriter; import java.io.StringWriter; + +import org.apache.maven.execution.MavenSession; import org.apache.maven.plugin.logging.Log; import org.apache.maven.plugins.dependency.AbstractDependencyMojoTestCase; +import org.apache.maven.plugins.dependency.testUtils.stubs.DuplicateDependencies2ProjectStub; +import org.apache.maven.plugins.dependency.testUtils.stubs.DuplicateDependenciesProjectStub; +import org.apache.maven.project.MavenProject; /** * @author Vincent Siveton @@ -30,6 +35,12 @@ */ public class TestAnalyzeDuplicateMojo extends AbstractDependencyMojoTestCase { public void testDuplicate() throws Exception { + MavenProject project = new DuplicateDependenciesProjectStub(); + getContainer().addComponent(project, MavenProject.class.getName()); + + MavenSession session = newMavenSession(project); + getContainer().addComponent(session, MavenSession.class.getName()); + File testPom = new File(getBasedir(), "target/test-classes/unit/duplicate-dependencies/plugin-config.xml"); AnalyzeDuplicateMojo mojo = (AnalyzeDuplicateMojo) lookupMojo("analyze-duplicate", testPom); assertNotNull(mojo); @@ -43,6 +54,12 @@ public void testDuplicate() throws Exception { } public void testDuplicate2() throws Exception { + MavenProject project = new DuplicateDependencies2ProjectStub(); + getContainer().addComponent(project, MavenProject.class.getName()); + + MavenSession session = newMavenSession(project); + getContainer().addComponent(session, MavenSession.class.getName()); + File testPom = new File(getBasedir(), "target/test-classes/unit/duplicate-dependencies/plugin-config2.xml"); AnalyzeDuplicateMojo mojo = (AnalyzeDuplicateMojo) lookupMojo("analyze-duplicate", testPom); assertNotNull(mojo); @@ -55,93 +72,106 @@ public void testDuplicate2() throws Exception { assertTrue(log.getContent().contains("junit:junit:jar")); } - class DuplicateLog implements Log { + static class DuplicateLog implements Log { StringBuilder sb = new StringBuilder(); /** {@inheritDoc} */ + @Override public void debug(CharSequence content) { print("debug", content); } /** {@inheritDoc} */ + @Override public void debug(CharSequence content, Throwable error) { print("debug", content, error); } /** {@inheritDoc} */ + @Override public void debug(Throwable error) { print("debug", error); } /** {@inheritDoc} */ + @Override public void info(CharSequence content) { print("info", content); } /** {@inheritDoc} */ + @Override public void info(CharSequence content, Throwable error) { print("info", content, error); } /** {@inheritDoc} */ + @Override public void info(Throwable error) { print("info", error); } /** {@inheritDoc} */ + @Override public void warn(CharSequence content) { print("warn", content); } /** {@inheritDoc} */ + @Override public void warn(CharSequence content, Throwable error) { print("warn", content, error); } /** {@inheritDoc} */ + @Override public void warn(Throwable error) { print("warn", error); } /** {@inheritDoc} */ + @Override public void error(CharSequence content) { System.err.println("[error] " + content.toString()); } /** {@inheritDoc} */ + @Override public void error(CharSequence content, Throwable error) { StringWriter sWriter = new StringWriter(); PrintWriter pWriter = new PrintWriter(sWriter); error.printStackTrace(pWriter); - System.err.println("[error] " + content.toString() + System.lineSeparator() + System.lineSeparator() - + sWriter.toString()); + System.err.println( + "[error] " + content.toString() + System.lineSeparator() + System.lineSeparator() + sWriter); } /** * @see org.apache.maven.plugin.logging.Log#error(java.lang.Throwable) */ + @Override public void error(Throwable error) { StringWriter sWriter = new StringWriter(); PrintWriter pWriter = new PrintWriter(sWriter); error.printStackTrace(pWriter); - System.err.println("[error] " + sWriter.toString()); + System.err.println("[error] " + sWriter); } /** * @see org.apache.maven.plugin.logging.Log#isDebugEnabled() */ + @Override public boolean isDebugEnabled() { - // TODO: Not sure how best to set these for this implementation... return false; } /** * @see org.apache.maven.plugin.logging.Log#isInfoEnabled() */ + @Override public boolean isInfoEnabled() { return true; } @@ -149,6 +179,7 @@ public boolean isInfoEnabled() { /** * @see org.apache.maven.plugin.logging.Log#isWarnEnabled() */ + @Override public boolean isWarnEnabled() { return true; } @@ -156,6 +187,7 @@ public boolean isWarnEnabled() { /** * @see org.apache.maven.plugin.logging.Log#isErrorEnabled() */ + @Override public boolean isErrorEnabled() { return true; } @@ -174,11 +206,7 @@ private void print(String prefix, Throwable error) { error.printStackTrace(pWriter); - sb.append("[") - .append(prefix) - .append("] ") - .append(sWriter.toString()) - .append(System.lineSeparator()); + sb.append("[").append(prefix).append("] ").append(sWriter).append(System.lineSeparator()); } private void print(String prefix, CharSequence content, Throwable error) { @@ -193,7 +221,7 @@ private void print(String prefix, CharSequence content, Throwable error) { .append(content.toString()) .append(System.lineSeparator()) .append(System.lineSeparator()); - sb.append(sWriter.toString()).append(System.lineSeparator()); + sb.append(sWriter).append(System.lineSeparator()); } protected String getContent() { diff --git a/src/test/java/org/apache/maven/plugins/dependency/exclusion/AnalyzeExclusionsMojoTest.java b/src/test/java/org/apache/maven/plugins/dependency/exclusion/AnalyzeExclusionsMojoTest.java new file mode 100644 index 000000000..d0da7947a --- /dev/null +++ b/src/test/java/org/apache/maven/plugins/dependency/exclusion/AnalyzeExclusionsMojoTest.java @@ -0,0 +1,416 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.maven.plugins.dependency.exclusion; + +import java.io.File; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; + +import org.apache.maven.RepositoryUtils; +import org.apache.maven.artifact.Artifact; +import org.apache.maven.execution.MavenSession; +import org.apache.maven.model.Dependency; +import org.apache.maven.model.Exclusion; +import org.apache.maven.model.InputLocation; +import org.apache.maven.model.InputSource; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.logging.Log; +import org.apache.maven.plugins.dependency.AbstractDependencyMojoTestCase; +import org.apache.maven.plugins.dependency.testUtils.stubs.DependencyProjectStub; +import org.apache.maven.plugins.dependency.utils.ResolverUtil; +import org.apache.maven.project.MavenProject; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class AnalyzeExclusionsMojoTest extends AbstractDependencyMojoTestCase { + + private AnalyzeExclusionsMojo mojo; + + private MavenProject project; + + private TestLog testLog; + + private ResolverUtil resolverUtil; + + @Override + protected String getTestDirectoryName() { + return "analyze-exclusions"; + } + + @Override + protected boolean shouldCreateFiles() { + return true; + } + + @Override + protected boolean shouldUseFlattenedPath() { + return false; + } + + @Override + protected void setUp() throws Exception { + // required for mojo lookups to work + super.setUp(); + + project = new DependencyProjectStub(); + project.setName("projectName"); + project.setGroupId("testGroupId"); + project.setArtifactId("testArtifactId"); + project.setVersion("1.0.0"); + + getContainer().addComponent(project, MavenProject.class.getName()); + + MavenSession session = newMavenSession(project); + getContainer().addComponent(session, MavenSession.class.getName()); + + resolverUtil = mock(ResolverUtil.class); + getContainer().addComponent(resolverUtil, ResolverUtil.class.getName()); + + File testPom = new File(getBasedir(), "target/test-classes/unit/analyze-exclusions/plugin-config.xml"); + mojo = (AnalyzeExclusionsMojo) lookupMojo("analyze-exclusions", testPom); + assertNotNull(mojo); + + testLog = new TestLog(); + mojo.setLog(testLog); + } + + public void testShallThrowExceptionWhenFailOnWarning() throws Exception { + List dependencies = new ArrayList<>(); + Dependency withInvalidExclusion = dependency("a", "b"); + withInvalidExclusion.addExclusion(exclusion("invalid", "invalid")); + dependencies.add(withInvalidExclusion); + project.setDependencies(dependencies); + Artifact artifact = stubFactory.createArtifact("a", "b", "1.0"); + project.setArtifacts(new HashSet<>(Collections.singletonList(artifact))); + setVariableValueToObject(mojo, "exclusionFail", true); + + assertThatThrownBy(() -> mojo.execute()) + .isInstanceOf(MojoExecutionException.class) + .hasMessageContaining("Invalid exclusions found"); + + assertThat(testLog.getContent()).startsWith("[error]"); + } + + public void testShallLogWarningWhenFailOnWarningIsFalse() throws Exception { + List dependencies = new ArrayList<>(); + Dependency withInvalidExclusion = dependency("a", "b"); + withInvalidExclusion.addExclusion(exclusion("invalid", "invalid")); + dependencies.add(withInvalidExclusion); + project.setDependencies(dependencies); + Artifact artifact = stubFactory.createArtifact("a", "b", "1.0"); + project.setArtifacts(new HashSet<>(Collections.singletonList(artifact))); + setVariableValueToObject(mojo, "exclusionFail", false); + + mojo.execute(); + + assertThat(testLog.getContent()).startsWith("[warn]"); + } + + public void testShallExitWithoutAnalyzeWhenNoDependencyHasExclusion() throws Exception { + List dependencies = new ArrayList<>(); + dependencies.add(dependency("a", "c")); + project.setDependencies(dependencies); + mojo.execute(); + assertThat(testLog.getContent()).startsWith("[debug] No dependencies defined with exclusions - exiting"); + } + + public void testShallNotReportInvalidExclusionForWildcardGroupIdAndArtifactId() throws Exception { + Dependency dependencyWithWildcardExclusion = dependency("a", "b"); + dependencyWithWildcardExclusion.addExclusion(exclusion("*", "*")); + project.setDependencies(Collections.singletonList(dependencyWithWildcardExclusion)); + Artifact artifact = stubFactory.createArtifact("a", "b", "1.0"); + project.setArtifacts(new HashSet<>(Collections.singletonList(artifact))); + + when(resolverUtil.collectDependencies(any())) + .thenReturn(Collections.singletonList(new org.eclipse.aether.graph.Dependency( + RepositoryUtils.toArtifact(stubFactory.createArtifact("whatever", "ok", "1.0")), ""))); + + mojo.execute(); + + assertThat(testLog.getContent()).doesNotContain("[warn] a:b:", "[warn] - *:*"); + } + + public void testCanResolveMultipleArtifactsWithEqualGroupIdAndArtifactId() throws Exception { + Dependency dependency1 = dependency("a", "b"); + Dependency dependency2 = dependency("a", "b", "compile", "native"); + dependency1.addExclusion(exclusion("c", "d")); + dependency2.addExclusion(exclusion("c", "d")); + project.setDependencies(Arrays.asList(dependency1, dependency2)); + Artifact artifact1 = stubFactory.createArtifact("a", "b", "1.0"); + Artifact artifact2 = stubFactory.createArtifact("a", "b", "1.0", "compile", "jar", "native"); + project.setArtifacts(new HashSet<>(Arrays.asList(artifact1, artifact2))); + + assertThatCode(() -> mojo.execute()).doesNotThrowAnyException(); + } + + public void testShallNotLogWhenExclusionIsValid() throws Exception { + List dependencies = new ArrayList<>(); + Dependency dependency = dependency("a", "b"); + dependency.addExclusion(exclusion("ok", "ok")); + dependencies.add(dependency); + project.setDependencies(dependencies); + Artifact artifact = stubFactory.createArtifact("a", "b", "1.0"); + + project.setArtifacts(new HashSet<>(Collections.singletonList(artifact))); + setVariableValueToObject(mojo, "exclusionFail", true); + + when(resolverUtil.collectDependencies(any())) + .thenReturn(Collections.singletonList(new org.eclipse.aether.graph.Dependency( + RepositoryUtils.toArtifact(stubFactory.createArtifact("ok", "ok", "1.0")), ""))); + + assertThatCode(() -> mojo.execute()).doesNotThrowAnyException(); + } + + public void testThatLogContainProjectName() throws Exception { + List dependencies = new ArrayList<>(); + Dependency withInvalidExclusion = dependency("a", "b"); + withInvalidExclusion.addExclusion(exclusion("invalid", "invalid")); + dependencies.add(withInvalidExclusion); + project.setDependencies(dependencies); + Artifact artifact = stubFactory.createArtifact("a", "b", "1.0"); + project.setArtifacts(new HashSet<>(Collections.singletonList(artifact))); + + mojo.execute(); + + assertThat(testLog.getContent()).contains("[warn] projectName defines following unnecessary excludes"); + } + + private Dependency dependency(String groupId, String artifactId) { + Dependency dependency = new Dependency(); + dependency.setGroupId(groupId); + dependency.setArtifactId(artifactId); + dependency.setVersion("1.0"); + dependency.setScope("compile"); + dependency.setType("jar"); + dependency.setClassifier(""); + dependency.setLocation("", new InputLocation(1, 1)); + return dependency; + } + + private Dependency dependency(String groupId, String artifactId, String scope, String classifier) { + Dependency dependency = new Dependency(); + dependency.setGroupId(groupId); + dependency.setArtifactId(artifactId); + dependency.setVersion("1.0"); + dependency.setScope(scope); + dependency.setType("jar"); + dependency.setClassifier(classifier); + dependency.setLocation("", new InputLocation(1, 1)); + return dependency; + } + + private Exclusion exclusion(String groupId, String artifactId) { + Exclusion exclusion = new Exclusion(); + exclusion.setGroupId(groupId); + exclusion.setArtifactId(artifactId); + InputSource inputSource = new InputSource(); + inputSource.setModelId("testGroupId:testArtifactId:1.0.0"); + exclusion.setLocation("", new InputLocation(1, 1, inputSource)); + return exclusion; + } + + static class TestLog implements Log { + StringBuilder sb = new StringBuilder(); + + /** + * {@inheritDoc} + */ + @Override + public void debug(CharSequence content) { + print("debug", content); + } + + /** + * {@inheritDoc} + */ + @Override + public void debug(CharSequence content, Throwable error) { + print("debug", content, error); + } + + /** + * {@inheritDoc} + */ + @Override + public void debug(Throwable error) { + print("debug", error); + } + + /** + * {@inheritDoc} + */ + @Override + public void info(CharSequence content) { + print("info", content); + } + + /** + * {@inheritDoc} + */ + @Override + public void info(CharSequence content, Throwable error) { + print("info", content, error); + } + + /** + * {@inheritDoc} + */ + @Override + public void info(Throwable error) { + print("info", error); + } + + /** + * {@inheritDoc} + */ + @Override + public void warn(CharSequence content) { + print("warn", content); + } + + /** + * {@inheritDoc} + */ + @Override + public void warn(CharSequence content, Throwable error) { + print("warn", content, error); + } + + /** + * {@inheritDoc} + */ + @Override + public void warn(Throwable error) { + print("warn", error); + } + + /** + * {@inheritDoc} + */ + @Override + public void error(CharSequence content) { + print("error", content); + } + + /** + * {@inheritDoc} + */ + @Override + public void error(CharSequence content, Throwable error) { + StringWriter sWriter = new StringWriter(); + PrintWriter pWriter = new PrintWriter(sWriter); + + error.printStackTrace(pWriter); + + System.err.println( + "[error] " + content.toString() + System.lineSeparator() + System.lineSeparator() + sWriter); + } + + /** + * @see org.apache.maven.plugin.logging.Log#error(java.lang.Throwable) + */ + @Override + public void error(Throwable error) { + StringWriter sWriter = new StringWriter(); + PrintWriter pWriter = new PrintWriter(sWriter); + + error.printStackTrace(pWriter); + + System.err.println("[error] " + sWriter); + } + + /** + * @see org.apache.maven.plugin.logging.Log#isDebugEnabled() + */ + @Override + public boolean isDebugEnabled() { + return false; + } + + /** + * @see org.apache.maven.plugin.logging.Log#isInfoEnabled() + */ + @Override + public boolean isInfoEnabled() { + return true; + } + + /** + * @see org.apache.maven.plugin.logging.Log#isWarnEnabled() + */ + @Override + public boolean isWarnEnabled() { + return true; + } + + /** + * @see org.apache.maven.plugin.logging.Log#isErrorEnabled() + */ + @Override + public boolean isErrorEnabled() { + return true; + } + + private void print(String prefix, CharSequence content) { + sb.append("[") + .append(prefix) + .append("] ") + .append(content.toString()) + .append(System.lineSeparator()); + } + + private void print(String prefix, Throwable error) { + StringWriter sWriter = new StringWriter(); + PrintWriter pWriter = new PrintWriter(sWriter); + + error.printStackTrace(pWriter); + + sb.append("[").append(prefix).append("] ").append(sWriter).append(System.lineSeparator()); + } + + private void print(String prefix, CharSequence content, Throwable error) { + StringWriter sWriter = new StringWriter(); + PrintWriter pWriter = new PrintWriter(sWriter); + + error.printStackTrace(pWriter); + + sb.append("[") + .append(prefix) + .append("] ") + .append(content.toString()) + .append(System.lineSeparator()) + .append(System.lineSeparator()); + sb.append(sWriter).append(System.lineSeparator()); + } + + protected String getContent() { + return sb.toString(); + } + } +} diff --git a/src/test/java/org/apache/maven/plugins/dependency/exclusion/ExclusionCheckerTest.java b/src/test/java/org/apache/maven/plugins/dependency/exclusion/ExclusionCheckerTest.java new file mode 100644 index 000000000..ad97c810c --- /dev/null +++ b/src/test/java/org/apache/maven/plugins/dependency/exclusion/ExclusionCheckerTest.java @@ -0,0 +1,102 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.maven.plugins.dependency.exclusion; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import org.junit.Before; +import org.junit.Test; + +import static org.apache.maven.plugins.dependency.exclusion.Coordinates.coordinates; +import static org.assertj.core.api.Assertions.assertThat; + +public class ExclusionCheckerTest { + + private ExclusionChecker checker; + + @Before + public void setUp() throws Exception { + checker = new ExclusionChecker(); + } + + @Test + public void shallReportInvalidExclusions() { + Coordinates artifact = coordinates("com.current", "artifact"); + Set excludes = new HashSet<>(Arrays.asList( + coordinates("com.example", "one"), + coordinates("com.example", "two"), + coordinates("com.example", "three"), + coordinates("com.example", "four"))); + + Set actualDependencies = + new HashSet<>(Arrays.asList(coordinates("com.example", "one"), coordinates("com.example", "four"))); + + checker.check(artifact, excludes, actualDependencies); + + assertThat(checker.getViolations()) + .containsEntry( + artifact, + Arrays.asList(coordinates("com.example", "three"), coordinates("com.example", "two"))); + } + + @Test + public void noViolationsWhenEmptyExclusions() { + checker.check(coordinates("a", "b"), new HashSet<>(), new HashSet<>()); + assertThat(checker.getViolations()).isEmpty(); + } + + @Test + public void shallReportInvalidExclusionsWhenNoDependencies() { + Coordinates artifact = coordinates("a", "b"); + HashSet actualDependencies = new HashSet<>(); + checker.check(artifact, new HashSet<>(Collections.singletonList(coordinates("p", "m"))), actualDependencies); + assertThat(checker.getViolations()).containsEntry(artifact, Collections.singletonList(coordinates("p", "m"))); + } + + @Test + public void shallHandleWildcardExclusions() { + Coordinates artifact = coordinates("com.current", "artifact"); + Set excludes = new HashSet<>(Collections.singletonList(coordinates("*", "*"))); + + Set actualDependencies = + new HashSet<>(Arrays.asList(coordinates("com.example", "one"), coordinates("com.example", "four"))); + + checker.check(artifact, excludes, actualDependencies); + + assertThat(checker.getViolations()).isEmpty(); + } + + @Test + public void shallHandleWildcardGroupIdExclusion() { + Coordinates artifact = coordinates("com.current", "artifact"); + Set excludes = new HashSet<>(Collections.singletonList(coordinates("javax", "*"))); + + Set actualDependencies = new HashSet<>(Arrays.asList( + coordinates("com.example", "one"), + coordinates("com.example", "four"), + coordinates("javax", "whatever"))); + + checker.check(artifact, excludes, actualDependencies); + + assertThat(checker.getViolations()).isEmpty(); + } +} diff --git a/src/test/java/org/apache/maven/plugins/dependency/fromConfiguration/TestArtifactItem.java b/src/test/java/org/apache/maven/plugins/dependency/fromConfiguration/TestArtifactItem.java index 34ed4ac85..63fefb1de 100644 --- a/src/test/java/org/apache/maven/plugins/dependency/fromConfiguration/TestArtifactItem.java +++ b/src/test/java/org/apache/maven/plugins/dependency/fromConfiguration/TestArtifactItem.java @@ -19,13 +19,26 @@ package org.apache.maven.plugins.dependency.fromConfiguration; import java.io.IOException; + import org.apache.maven.artifact.Artifact; import org.apache.maven.plugins.dependency.AbstractDependencyMojoTestCase; public class TestArtifactItem extends AbstractDependencyMojoTestCase { + @Override + protected String getTestDirectoryName() { + return "artifactItems"; + } + + @Override + protected boolean shouldCreateFiles() { + return false; + } + + @Override protected void setUp() throws Exception { - setUp("artifactItems", false); + // required for mojo lookups to work + super.setUp(); } public void testArtifactItemConstructor() throws IOException { diff --git a/src/test/java/org/apache/maven/plugins/dependency/fromConfiguration/TestCopyMojo.java b/src/test/java/org/apache/maven/plugins/dependency/fromConfiguration/TestCopyMojo.java index 1a8eee21d..a619d7750 100644 --- a/src/test/java/org/apache/maven/plugins/dependency/fromConfiguration/TestCopyMojo.java +++ b/src/test/java/org/apache/maven/plugins/dependency/fromConfiguration/TestCopyMojo.java @@ -23,36 +23,54 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; + import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.versioning.VersionRange; import org.apache.maven.execution.MavenSession; import org.apache.maven.model.Dependency; -import org.apache.maven.plugin.LegacySupport; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugins.dependency.AbstractDependencyMojoTestCase; +import org.apache.maven.plugins.dependency.testUtils.stubs.DependencyProjectStub; import org.apache.maven.plugins.dependency.utils.DependencyUtil; import org.apache.maven.project.MavenProject; public class TestCopyMojo extends AbstractDependencyMojoTestCase { private CopyMojo mojo; + @Override + protected String getTestDirectoryName() { + return "copy"; + } + + @Override + protected boolean shouldCreateFiles() { + return false; + } + + @Override + protected boolean shouldUseFlattenedPath() { + return false; + } + + @Override protected void setUp() throws Exception { - super.setUp("copy", false, false); + // required for mojo lookups to work + super.setUp(); + + MavenProject project = new DependencyProjectStub(); + getContainer().addComponent(project, MavenProject.class.getName()); + + MavenSession session = newMavenSession(project); + getContainer().addComponent(session, MavenSession.class.getName()); File testPom = new File(getBasedir(), "target/test-classes/unit/copy-test/plugin-config.xml"); mojo = (CopyMojo) lookupMojo("copy", testPom); mojo.setOutputDirectory(new File(this.testDir, "outputDirectory")); - mojo.setSilent(true); assertNotNull(mojo); assertNotNull(mojo.getProject()); - MavenSession session = newMavenSession(mojo.getProject()); - setVariableValueToObject(mojo, "session", session); - - LegacySupport legacySupport = lookup(LegacySupport.class); - legacySupport.setSession(session); - installLocalRepository(legacySupport); + installLocalRepository(session.getRepositorySession()); } private ArtifactItem getSingleArtifactItem(boolean removeVersion, boolean useBaseVersion) @@ -126,11 +144,11 @@ public void assertFileExists(ArtifactItem item, boolean exist) { } public void testMojoDefaults() { - CopyMojo themojo = new CopyMojo(); + CopyMojo theMojo = new CopyMojo(null, null, null, null, null, null); - assertFalse(themojo.isStripVersion()); - assertFalse(themojo.isSkip()); - assertFalse(themojo.isStripClassifier()); + assertFalse(theMojo.isStripVersion()); + assertFalse(theMojo.isSkip()); + assertFalse(theMojo.isStripClassifier()); } public void testCopyFile() throws Exception { @@ -143,7 +161,11 @@ public void testCopyFile() throws Exception { assertFilesExist(list, true); } - public void testCopyFileWithBaseVersion() throws Exception { + /** + * New version of resolver on classpath does not support timestamp version lookups in local repository. + * TODO move to an integration test ... + */ + public void skipTestCopyFileWithBaseVersion() throws Exception { List list = stubFactory.getArtifactItems(stubFactory.getClassifiedArtifacts()); ArtifactItem item = new ArtifactItem(); @@ -486,14 +508,6 @@ public void testMissingVersionFromDependencyMgtWithClassifier() throws Exception } public void testArtifactNotFound() throws Exception { - dotestArtifactExceptions(false, true); - } - - public void testArtifactResolutionException() throws Exception { - dotestArtifactExceptions(true, false); - } - - public void dotestArtifactExceptions(boolean are, boolean anfe) throws Exception { ArtifactItem item = new ArtifactItem(); item.setArtifactId("artifactId"); diff --git a/src/test/java/org/apache/maven/plugins/dependency/fromConfiguration/TestIncludeExcludeUnpackMojo.java b/src/test/java/org/apache/maven/plugins/dependency/fromConfiguration/TestIncludeExcludeUnpackMojo.java index 335b76be7..f42e42aed 100644 --- a/src/test/java/org/apache/maven/plugins/dependency/fromConfiguration/TestIncludeExcludeUnpackMojo.java +++ b/src/test/java/org/apache/maven/plugins/dependency/fromConfiguration/TestIncludeExcludeUnpackMojo.java @@ -22,37 +22,58 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; + import org.apache.maven.artifact.Artifact; import org.apache.maven.execution.MavenSession; import org.apache.maven.plugin.LegacySupport; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugins.dependency.AbstractDependencyMojoTestCase; +import org.apache.maven.plugins.dependency.testUtils.stubs.DependencyProjectStub; import org.apache.maven.plugins.dependency.utils.markers.UnpackFileMarkerHandler; -import org.codehaus.plexus.archiver.manager.ArchiverManager; +import org.apache.maven.project.MavenProject; public class TestIncludeExcludeUnpackMojo extends AbstractDependencyMojoTestCase { - private final String PACKED_FILE = "test.zip"; + private static final String PACKED_FILE = "test.zip"; - private final String UNPACKED_FILE_PREFIX = "test"; + private static final String UNPACKED_FILE_PREFIX = "test"; - private final String UNPACKED_FILE_SUFFIX = ".txt"; + private static final String UNPACKED_FILE_SUFFIX = ".txt"; - private final String PACKED_FILE_PATH = "target/test-classes/unit/unpack-dependencies-test/" + PACKED_FILE; + private static final String PACKED_FILE_PATH = "target/test-classes/unit/unpack-dependencies-test/" + PACKED_FILE; private UnpackMojo mojo; + @Override + protected String getTestDirectoryName() { + return "unpack"; + } + + @Override + protected boolean shouldCreateFiles() { + return true; + } + + @Override + protected boolean shouldUseFlattenedPath() { + return false; + } + + @Override protected void setUp() throws Exception { // required for mojo lookups to work - super.setUp("unpack", true, false); + super.setUp(); + + MavenProject project = new DependencyProjectStub(); + getContainer().addComponent(project, MavenProject.class.getName()); + + MavenSession session = newMavenSession(project); + getContainer().addComponent(session, MavenSession.class.getName()); File testPom = new File(getBasedir(), "target/test-classes/unit/unpack-test/plugin-config.xml"); mojo = (UnpackMojo) lookupMojo("unpack", testPom); mojo.setOutputDirectory(new File(this.testDir, "outputDirectory")); - // mojo.silent = true; - // it needs to get the archivermanager - // stubFactory.setUnpackableFile( mojo.getArchiverManager() ); - // i'm using one file repeatedly to archive so I can test the name + // I'm using one file repeatedly to archive so I can test the name // programmatically. stubFactory.setSrcFile(new File(getBasedir() + File.separatorChar + PACKED_FILE_PATH)); Artifact artifact = stubFactory.createArtifact("test", "test", "1.0", Artifact.SCOPE_COMPILE, "jar", null); @@ -62,26 +83,14 @@ protected void setUp() throws Exception { assertNotNull(mojo); assertNotNull(mojo.getProject()); - mojo.setArchiverManager(lookup(ArchiverManager.class)); - mojo.setMarkersDirectory(new File(this.testDir, "markers")); mojo.setArtifactItems(list); - MavenSession session = newMavenSession(mojo.getProject()); - setVariableValueToObject(mojo, "session", session); - LegacySupport legacySupport = lookup(LegacySupport.class); legacySupport.setSession(session); installLocalRepository(legacySupport); } - protected void tearDown() { - super.tearDown(); - - mojo = null; - System.gc(); - } - public void assertMarkerFiles(Collection items, boolean exist) { for (ArtifactItem item : items) { assertMarkerFile(exist, item); diff --git a/src/test/java/org/apache/maven/plugins/dependency/fromConfiguration/TestUnpackMojo.java b/src/test/java/org/apache/maven/plugins/dependency/fromConfiguration/TestUnpackMojo.java index fa147079e..4346ed946 100644 --- a/src/test/java/org/apache/maven/plugins/dependency/fromConfiguration/TestUnpackMojo.java +++ b/src/test/java/org/apache/maven/plugins/dependency/fromConfiguration/TestUnpackMojo.java @@ -25,50 +25,68 @@ import java.util.Collection; import java.util.Collections; import java.util.List; + import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.versioning.VersionRange; import org.apache.maven.execution.MavenSession; import org.apache.maven.model.Dependency; -import org.apache.maven.plugin.LegacySupport; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugins.dependency.AbstractDependencyMojoTestCase; import org.apache.maven.plugins.dependency.testUtils.DependencyArtifactStubFactory; +import org.apache.maven.plugins.dependency.testUtils.stubs.DependencyProjectStub; import org.apache.maven.plugins.dependency.utils.markers.UnpackFileMarkerHandler; import org.apache.maven.project.MavenProject; +import org.codehaus.plexus.archiver.manager.ArchiverManager; + +import static org.junit.Assert.assertNotEquals; public class TestUnpackMojo extends AbstractDependencyMojoTestCase { UnpackMojo mojo; + @Override + protected String getTestDirectoryName() { + return "unpack"; + } + + @Override + protected boolean shouldCreateFiles() { + return true; + } + + @Override + protected boolean shouldUseFlattenedPath() { + return false; + } + + @Override protected void setUp() throws Exception { - super.setUp("unpack", true, false); + // required for mojo lookups to work + super.setUp(); + + MavenProject project = new DependencyProjectStub(); + getContainer().addComponent(project, MavenProject.class.getName()); + + MavenSession session = newMavenSession(project); + getContainer().addComponent(session, MavenSession.class.getName()); File testPom = new File(getBasedir(), "target/test-classes/unit/unpack-test/plugin-config.xml"); mojo = (UnpackMojo) lookupMojo("unpack", testPom); mojo.setOutputDirectory(new File(this.testDir, "outputDirectory")); mojo.setMarkersDirectory(new File(this.testDir, "markers")); - mojo.setSilent(true); assertNotNull(mojo); assertNotNull(mojo.getProject()); // MavenProject project = mojo.getProject(); // init classifier things // it needs to get the archivermanager - stubFactory.setUnpackableFile(mojo.getArchiverManager()); + stubFactory.setUnpackableFile(lookup(ArchiverManager.class)); // i'm using one file repeatedly to archive so I can test the name // programmatically. stubFactory.setSrcFile(new File( getBasedir() + File.separatorChar + "target/test-classes/unit/unpack-dependencies-test/test.txt")); - mojo.setUseJvmChmod(true); - - MavenSession session = newMavenSession(mojo.getProject()); - setVariableValueToObject(mojo, "session", session); - - LegacySupport legacySupport = lookup(LegacySupport.class); - - legacySupport.setSession(session); - installLocalRepository(legacySupport); + installLocalRepository(session.getRepositorySession()); } public ArtifactItem getSingleArtifactItem(boolean removeVersion) throws MojoExecutionException { @@ -352,14 +370,6 @@ public void testMissingVersionFromDependencyMgtWithClassifier() throws Exception } public void testArtifactNotFound() throws Exception { - dotestArtifactExceptions(false, true); - } - - public void testArtifactResolutionException() throws Exception { - dotestArtifactExceptions(true, false); - } - - public void dotestArtifactExceptions(boolean are, boolean anfe) throws Exception { ArtifactItem item = new ArtifactItem(); item.setArtifactId("artifactId"); @@ -471,7 +481,6 @@ public void testUnpackOverWriteSnapshot() throws Exception { public void testUnpackOverWriteIfNewer() throws Exception { final long now = System.currentTimeMillis(); - mojo.setSilent(false); stubFactory.setCreateFiles(true); Artifact artifact = stubFactory.getSnapshotArtifact(); assertTrue(artifact.getFile().setLastModified(now - 20000)); @@ -487,13 +496,13 @@ public void testUnpackOverWriteIfNewer() throws Exception { // round down to the last second long time = now; time = time - (time % 1000); - // go back 10 more seconds for linux - time -= 10000; + // go back 30 more seconds for linux + time -= 30000; // set to known value assertTrue(unpackedFile.setLastModified(time)); // set source to be newer about some seconds, - // especially on macOS it shouldn't be smaller than 8s in order to mitigate flapping test - assertTrue(artifact.getFile().setLastModified(time + 8000)); + // especially on macOS it shouldn't be smaller than 16s in order to mitigate flapping test + assertTrue(artifact.getFile().setLastModified(time + 16000)); // manually set markerfile (must match getMarkerFile in DefaultMarkerFileHandler) File marker = new File(mojo.getMarkersDirectory(), artifact.getId().replace(':', '-') + ".marker"); @@ -506,10 +515,11 @@ public void testUnpackOverWriteIfNewer() throws Exception { long unpackedFileLastModifiedMillis = Files.getLastModifiedTime(unpackedFile.toPath()).toMillis(); - assertTrue( + assertNotEquals( "unpackedFile '" + unpackedFile + "' lastModified() == " + markerLastModifiedMillis + ": should be different", - markerLastModifiedMillis != unpackedFileLastModifiedMillis); + markerLastModifiedMillis, + unpackedFileLastModifiedMillis); } public void assertUnpacked(ArtifactItem item, boolean overWrite) throws Exception { @@ -526,7 +536,7 @@ public void assertUnpacked(ArtifactItem item, boolean overWrite) throws Exceptio mojo.execute(); if (overWrite) { - assertTrue(time != unpackedFile.lastModified()); + assertNotEquals(time, unpackedFile.lastModified()); } else { assertEquals(time, unpackedFile.lastModified()); } diff --git a/src/test/java/org/apache/maven/plugins/dependency/fromDependencies/TestBuildClasspathMojo.java b/src/test/java/org/apache/maven/plugins/dependency/fromDependencies/TestBuildClasspathMojo.java index 871e668e0..86856c633 100644 --- a/src/test/java/org/apache/maven/plugins/dependency/fromDependencies/TestBuildClasspathMojo.java +++ b/src/test/java/org/apache/maven/plugins/dependency/fromDependencies/TestBuildClasspathMojo.java @@ -20,10 +20,12 @@ import java.io.File; import java.util.Set; + import org.apache.maven.artifact.Artifact; import org.apache.maven.execution.MavenSession; import org.apache.maven.plugin.LegacySupport; import org.apache.maven.plugins.dependency.AbstractDependencyMojoTestCase; +import org.apache.maven.plugins.dependency.testUtils.stubs.DependencyProjectStub; import org.apache.maven.plugins.dependency.utils.DependencyUtil; import org.apache.maven.project.MavenProject; @@ -31,9 +33,26 @@ public class TestBuildClasspathMojo extends AbstractDependencyMojoTestCase { private BuildClasspathMojo mojo; + @Override + protected String getTestDirectoryName() { + return "build-classpath"; + } + + @Override + protected boolean shouldCreateFiles() { + return true; + } + + @Override protected void setUp() throws Exception { // required for mojo lookups to work - super.setUp("build-classpath", true); + super.setUp(); + + MavenProject project = new DependencyProjectStub(); + getContainer().addComponent(project, MavenProject.class.getName()); + + MavenSession session = newMavenSession(project); + getContainer().addComponent(session, MavenSession.class.getName()); File testPom = new File(getBasedir(), "target/test-classes/unit/build-classpath-test/plugin-config.xml"); mojo = (BuildClasspathMojo) lookupMojo("build-classpath", testPom); @@ -48,7 +67,6 @@ protected void setUp() throws Exception { public void testEnvironment() throws Exception { MavenProject project = mojo.getProject(); - // mojo.silent = true; Set artifacts = this.stubFactory.getScopedArtifacts(); Set directArtifacts = this.stubFactory.getReleaseAndSnapshotArtifacts(); artifacts.addAll(directArtifacts); @@ -70,7 +88,7 @@ public void testEnvironment() throws Exception { String file = mojo.readClasspathFile(); assertNotNull(file); - assertTrue(file.length() > 0); + assertFalse(file.isEmpty()); assertTrue(file.contains(File.pathSeparator)); assertTrue(file.contains(File.separator)); @@ -84,7 +102,7 @@ public void testEnvironment() throws Exception { file = mojo.readClasspathFile(); assertNotNull(file); - assertTrue(file.length() > 0); + assertFalse(file.isEmpty()); assertFalse(file.contains(File.pathSeparator)); assertFalse(file.contains(File.separator)); @@ -100,11 +118,9 @@ public void testEnvironment() throws Exception { } public void testPath() throws Exception { - MavenSession session = newMavenSession(mojo.getProject()); - setVariableValueToObject(mojo, "session", session); LegacySupport legacySupport = lookup(LegacySupport.class); - legacySupport.setSession(session); + legacySupport.setSession(lookup(MavenSession.class)); installLocalRepository(legacySupport); Artifact artifact = stubFactory.getReleaseArtifact(); diff --git a/src/test/java/org/apache/maven/plugins/dependency/fromDependencies/TestCopyDependenciesMojo.java b/src/test/java/org/apache/maven/plugins/dependency/fromDependencies/TestCopyDependenciesMojo.java index bb92b2f63..bd5043bd8 100644 --- a/src/test/java/org/apache/maven/plugins/dependency/fromDependencies/TestCopyDependenciesMojo.java +++ b/src/test/java/org/apache/maven/plugins/dependency/fromDependencies/TestCopyDependenciesMojo.java @@ -22,6 +22,7 @@ import java.io.IOException; import java.util.HashSet; import java.util.Set; + import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager; import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter; @@ -29,32 +30,55 @@ import org.apache.maven.plugin.LegacySupport; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugin.testing.stubs.ArtifactStub; import org.apache.maven.plugins.dependency.AbstractDependencyMojoTestCase; +import org.apache.maven.plugins.dependency.testUtils.stubs.DependencyProjectStub; import org.apache.maven.plugins.dependency.utils.DependencyUtil; +import org.apache.maven.plugins.dependency.utils.ResolverUtil; import org.apache.maven.plugins.dependency.utils.markers.DefaultFileMarkerHandler; import org.apache.maven.project.MavenProject; -import org.codehaus.plexus.util.StringUtils; +import org.eclipse.aether.RepositorySystem; public class TestCopyDependenciesMojo extends AbstractDependencyMojoTestCase { CopyDependenciesMojo mojo; + @Override + protected String getTestDirectoryName() { + return "copy-dependencies"; + } + + @Override + protected boolean shouldCreateFiles() { + return true; + } + + @Override + protected boolean shouldUseFlattenedPath() { + return false; + } + @Override protected void setUp() throws Exception { // required for mojo lookups to work - super.setUp("copy-dependencies", true, false); + super.setUp(); + + MavenProject project = new DependencyProjectStub(); + getContainer().addComponent(project, MavenProject.class.getName()); + + MavenSession session = newMavenSession(project); + getContainer().addComponent(session, MavenSession.class.getName()); + + RepositorySystem repositorySystem = lookup(RepositorySystem.class); + ResolverUtil resolverUtil = new ResolverUtil(repositorySystem, () -> session); + getContainer().addComponent(resolverUtil, ResolverUtil.class.getName()); File testPom = new File(getBasedir(), "target/test-classes/unit/copy-dependencies-test/plugin-config.xml"); mojo = (CopyDependenciesMojo) lookupMojo("copy-dependencies", testPom); mojo.outputDirectory = new File(this.testDir, "outputDirectory"); - // mojo.silent = true; assertNotNull(mojo); assertNotNull(mojo.getProject()); - MavenProject project = mojo.getProject(); - - MavenSession session = newMavenSession(project); - setVariableValueToObject(mojo, "session", session); LegacySupport legacySupport = lookup(LegacySupport.class); legacySupport.setSession(session); @@ -65,7 +89,6 @@ protected void setUp() throws Exception { artifacts.addAll(directArtifacts); project.setArtifacts(artifacts); - project.setDependencyArtifacts(directArtifacts); mojo.markersDirectory = new File(this.testDir, "markers"); ArtifactHandlerManager manager = lookup(ArtifactHandlerManager.class); @@ -77,17 +100,82 @@ public void assertNoMarkerFile(Artifact artifact) throws MojoExecutionException assertFalse(handle.isMarkerSet()); } - public void testCopyFile() throws MojoExecutionException, IOException { + public void testCopyArtifactFile() throws Exception { + final Artifact srcArtifact = new ArtifactStub(); + srcArtifact.setGroupId("org.apache.maven.plugins"); + srcArtifact.setArtifactId("maven-dependency-plugin-dummy"); + srcArtifact.setVersion("1.0"); File src = File.createTempFile("copy", null); + srcArtifact.setFile(src); File dest = new File(mojo.outputDirectory, "toMe.jar"); assertFalse(dest.exists()); - copyFile(mojo, src, dest); + copyArtifactFile(srcArtifact, dest); assertTrue(dest.exists()); } + /** + * Tests the copying of signature files associated with artifacts. + * + * @throws Exception if an error occurs during the test + */ + public void testCopySignatureFiles() throws Exception { + // Enable the copySignatures parameter + mojo.copySignatures = true; + + if (!mojo.outputDirectory.exists()) { + assertTrue("Failed to create output directory", mojo.outputDirectory.mkdirs()); + } + + File sourceDirectory = + new File(System.getProperty("java.io.tmpdir"), "test-source-" + System.currentTimeMillis()); + if (!sourceDirectory.exists()) { + assertTrue("Failed to create source directory", sourceDirectory.mkdirs()); + } + + File artifactFile = new File(sourceDirectory, "maven-dependency-plugin-1.0.jar"); + if (!artifactFile.getParentFile().exists()) { + assertTrue( + "Failed to create parent directory", + artifactFile.getParentFile().mkdirs()); + } + if (artifactFile.exists()) { + assertTrue("Failed to delete existing artifact file", artifactFile.delete()); + } + assertTrue("Failed to create artifact file", artifactFile.createNewFile()); + + File signatureFile = new File(sourceDirectory, "maven-dependency-plugin-1.0.jar.asc"); + if (!signatureFile.getParentFile().exists()) { + assertTrue( + "Failed to create parent directory", + signatureFile.getParentFile().mkdirs()); + } + if (signatureFile.exists()) { + assertTrue("Failed to delete existing signature file", signatureFile.delete()); + } + assertTrue("Failed to create signature file", signatureFile.createNewFile()); + + Artifact artifact = stubFactory.createArtifact( + "org.apache.maven.plugins", "maven-dependency-plugin", "1.0", Artifact.SCOPE_COMPILE); + artifact.setFile(artifactFile); + + Set artifacts = new HashSet<>(); + artifacts.add(artifact); + mojo.getProject().setArtifacts(artifacts); + + mojo.execute(); + + File copiedSignatureFile = new File(mojo.outputDirectory, "maven-dependency-plugin-1.0.jar.asc"); + assertTrue("Signature file was not copied", copiedSignatureFile.exists()); + + // Clean up + artifactFile.delete(); + signatureFile.delete(); + sourceDirectory.delete(); + } + /** * Tests the proper discovery and configuration of the mojo. * @@ -146,7 +234,7 @@ public void testNoTransitive() throws Exception { mojo.excludeTransitive = true; mojo.execute(); - Set artifacts = mojo.getProject().getDependencyArtifacts(); + Set artifacts = mojo.getProject().getArtifacts(); for (Artifact artifact : artifacts) { String fileName = DependencyUtil.getFormattedFileName(artifact, false); File file = new File(mojo.outputDirectory, fileName); @@ -156,7 +244,7 @@ public void testNoTransitive() throws Exception { public void testExcludeType() throws Exception { mojo.getProject().setArtifacts(stubFactory.getTypedArtifacts()); - mojo.getProject().setDependencyArtifacts(new HashSet()); + mojo.excludeTypes = "jar"; mojo.execute(); @@ -170,7 +258,6 @@ public void testExcludeType() throws Exception { public void testIncludeType() throws Exception { mojo.getProject().setArtifacts(stubFactory.getTypedArtifacts()); - mojo.getProject().setDependencyArtifacts(new HashSet()); mojo.includeTypes = "jar"; mojo.excludeTypes = "jar"; @@ -198,7 +285,6 @@ public void testIncludeType() throws Exception { public void testExcludeArtifactId() throws Exception { mojo.getProject().setArtifacts(stubFactory.getArtifactArtifacts()); - mojo.getProject().setDependencyArtifacts(new HashSet()); mojo.excludeArtifactIds = "one"; mojo.execute(); @@ -212,7 +298,6 @@ public void testExcludeArtifactId() throws Exception { public void testIncludeArtifactId() throws Exception { mojo.getProject().setArtifacts(stubFactory.getArtifactArtifacts()); - mojo.getProject().setDependencyArtifacts(new HashSet()); mojo.includeArtifactIds = "one"; mojo.excludeArtifactIds = "one"; @@ -240,7 +325,7 @@ public void testIncludeArtifactId() throws Exception { public void testIncludeGroupId() throws Exception { mojo.getProject().setArtifacts(stubFactory.getGroupIdArtifacts()); - mojo.getProject().setDependencyArtifacts(new HashSet()); + mojo.includeGroupIds = "one"; mojo.excludeGroupIds = "one"; // shouldn't get anything @@ -267,7 +352,7 @@ public void testIncludeGroupId() throws Exception { public void testExcludeGroupId() throws Exception { mojo.getProject().setArtifacts(stubFactory.getGroupIdArtifacts()); - mojo.getProject().setDependencyArtifacts(new HashSet()); + mojo.excludeGroupIds = "one"; mojo.execute(); @@ -282,7 +367,7 @@ public void testExcludeGroupId() throws Exception { public void testExcludeMultipleGroupIds() throws Exception { mojo.getProject().setArtifacts(stubFactory.getGroupIdArtifacts()); - mojo.getProject().setDependencyArtifacts(new HashSet()); + mojo.excludeGroupIds = "one,two"; mojo.execute(); @@ -298,7 +383,7 @@ public void testExcludeMultipleGroupIds() throws Exception { public void testExcludeClassifier() throws Exception { mojo.getProject().setArtifacts(stubFactory.getClassifiedArtifacts()); - mojo.getProject().setDependencyArtifacts(new HashSet()); + mojo.excludeClassifiers = "one"; mojo.execute(); @@ -312,7 +397,6 @@ public void testExcludeClassifier() throws Exception { public void testIncludeClassifier() throws Exception { mojo.getProject().setArtifacts(stubFactory.getClassifiedArtifacts()); - mojo.getProject().setDependencyArtifacts(new HashSet()); mojo.includeClassifiers = "one"; mojo.excludeClassifiers = "one"; @@ -340,7 +424,7 @@ public void testIncludeClassifier() throws Exception { public void testSubPerType() throws Exception { mojo.getProject().setArtifacts(stubFactory.getTypedArtifacts()); - mojo.getProject().setDependencyArtifacts(new HashSet()); + mojo.useSubDirectoryPerType = true; mojo.execute(); @@ -389,10 +473,10 @@ public void dotestClassifierType(String testClassifier, String testType) throws String useClassifier = artifact.getClassifier(); String useType = artifact.getType(); - if (StringUtils.isNotEmpty(testClassifier)) { + if (testClassifier != null && !testClassifier.isEmpty()) { useClassifier = "-" + testClassifier; // type is only used if classifier is used. - if (StringUtils.isNotEmpty(testType)) { + if (testType != null && !testType.isEmpty()) { useType = testType; } } @@ -414,6 +498,7 @@ public void testArtifactResolutionException() throws MojoFailureException { public void dotestArtifactExceptions() throws MojoFailureException { mojo.classifier = "jdk"; + mojo.failOnMissingClassifierArtifact = true; mojo.type = "java-sources"; try { @@ -440,7 +525,6 @@ public void testDontOverWriteRelease() artifacts.add(release); mojo.getProject().setArtifacts(artifacts); - mojo.getProject().setDependencyArtifacts(artifacts); mojo.overWriteIfNewer = false; @@ -471,7 +555,6 @@ public void testOverWriteRelease() throws MojoExecutionException, IOException, M artifacts.add(release); mojo.getProject().setArtifacts(artifacts); - mojo.getProject().setDependencyArtifacts(artifacts); mojo.overWriteReleases = true; mojo.overWriteIfNewer = false; @@ -499,7 +582,6 @@ public void testDontOverWriteSnap() throws MojoExecutionException, IOException, artifacts.add(snap); mojo.getProject().setArtifacts(artifacts); - mojo.getProject().setDependencyArtifacts(artifacts); mojo.overWriteReleases = false; mojo.overWriteSnapshots = false; @@ -548,16 +630,14 @@ public void testOverWriteSnap() throws MojoExecutionException, IOException, Mojo } public void testGetDependencies() throws MojoExecutionException { - assertEquals( - mojo.getResolvedDependencies(true).toString(), - mojo.getDependencySets(true).getResolvedDependencies().toString()); + assertTrue(mojo.getResolvedDependencies(true) + .containsAll(mojo.getDependencySets(true).getResolvedDependencies())); } public void testExcludeProvidedScope() throws Exception { mojo.getProject().setArtifacts(stubFactory.getScopedArtifacts()); - mojo.getProject().setDependencyArtifacts(new HashSet()); + mojo.excludeScope = "provided"; - // mojo.silent = false; mojo.execute(); @@ -573,9 +653,8 @@ public void testExcludeProvidedScope() throws Exception { public void testExcludeSystemScope() throws Exception { mojo.getProject().setArtifacts(stubFactory.getScopedArtifacts()); - mojo.getProject().setDependencyArtifacts(new HashSet()); + mojo.excludeScope = "system"; - // mojo.silent = false; mojo.execute(); @@ -591,7 +670,7 @@ public void testExcludeSystemScope() throws Exception { public void testExcludeCompileScope() throws Exception { mojo.getProject().setArtifacts(stubFactory.getScopedArtifacts()); - mojo.getProject().setDependencyArtifacts(new HashSet()); + mojo.excludeScope = "compile"; mojo.execute(); ScopeArtifactFilter saf = new ScopeArtifactFilter(mojo.excludeScope); @@ -607,7 +686,7 @@ public void testExcludeCompileScope() throws Exception { public void testExcludeTestScope() throws IOException, MojoFailureException { mojo.getProject().setArtifacts(stubFactory.getScopedArtifacts()); - mojo.getProject().setDependencyArtifacts(new HashSet()); + mojo.excludeScope = "test"; try { @@ -620,7 +699,7 @@ public void testExcludeTestScope() throws IOException, MojoFailureException { public void testExcludeRuntimeScope() throws Exception { mojo.getProject().setArtifacts(stubFactory.getScopedArtifacts()); - mojo.getProject().setDependencyArtifacts(new HashSet()); + mojo.excludeScope = "runtime"; mojo.execute(); ScopeArtifactFilter saf = new ScopeArtifactFilter(mojo.excludeScope); diff --git a/src/test/java/org/apache/maven/plugins/dependency/fromDependencies/TestCopyDependenciesMojo2.java b/src/test/java/org/apache/maven/plugins/dependency/fromDependencies/TestCopyDependenciesMojo2.java index 5ef9062e8..ae53378fb 100644 --- a/src/test/java/org/apache/maven/plugins/dependency/fromDependencies/TestCopyDependenciesMojo2.java +++ b/src/test/java/org/apache/maven/plugins/dependency/fromDependencies/TestCopyDependenciesMojo2.java @@ -24,10 +24,9 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.Collection; -import java.util.HashSet; import java.util.Set; + import org.apache.maven.artifact.Artifact; -import org.apache.maven.artifact.factory.ArtifactFactory; import org.apache.maven.artifact.metadata.ArtifactMetadata; import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy; @@ -42,46 +41,61 @@ import org.apache.maven.execution.MavenSession; import org.apache.maven.plugin.LegacySupport; import org.apache.maven.plugins.dependency.AbstractDependencyMojoTestCase; +import org.apache.maven.plugins.dependency.testUtils.stubs.DependencyProjectStub; import org.apache.maven.plugins.dependency.utils.DependencyUtil; +import org.apache.maven.plugins.dependency.utils.ResolverUtil; import org.apache.maven.project.MavenProject; -import org.codehaus.plexus.util.StringUtils; +import org.eclipse.aether.RepositorySystem; public class TestCopyDependenciesMojo2 extends AbstractDependencyMojoTestCase { private CopyDependenciesMojo mojo; + @Override + protected String getTestDirectoryName() { + return "copy-dependencies"; + } + + @Override + protected boolean shouldCreateFiles() { + return true; + } + + @Override protected void setUp() throws Exception { // required for mojo lookups to work - super.setUp("copy-dependencies", true); + super.setUp(); + MavenProject project = new DependencyProjectStub(); + getContainer().addComponent(project, MavenProject.class.getName()); + + MavenSession session = newMavenSession(project); + getContainer().addComponent(session, MavenSession.class.getName()); + + RepositorySystem repositorySystem = lookup(RepositorySystem.class); + ResolverUtil resolverUtil = new ResolverUtil(repositorySystem, () -> session); + getContainer().addComponent(resolverUtil, ResolverUtil.class.getName()); File testPom = new File(getBasedir(), "target/test-classes/unit/copy-dependencies-test/plugin-config.xml"); mojo = (CopyDependenciesMojo) lookupMojo("copy-dependencies", testPom); mojo.outputDirectory = new File(this.testDir, "outputDirectory"); - // mojo.silent = true; assertNotNull(mojo); assertNotNull(mojo.getProject()); - MavenProject project = mojo.getProject(); Set artifacts = this.stubFactory.getScopedArtifacts(); Set directArtifacts = this.stubFactory.getReleaseAndSnapshotArtifacts(); artifacts.addAll(directArtifacts); project.setArtifacts(artifacts); - project.setDependencyArtifacts(directArtifacts); mojo.markersDirectory = new File(this.testDir, "markers"); LegacySupport legacySupport = lookup(LegacySupport.class); - MavenSession session = newMavenSession(project); - setVariableValueToObject(mojo, "session", session); - legacySupport.setSession(session); installLocalRepository(legacySupport); } public void testCopyDependenciesMojoIncludeCompileScope() throws Exception { mojo.getProject().setArtifacts(stubFactory.getScopedArtifacts()); - mojo.getProject().setDependencyArtifacts(new HashSet()); mojo.includeScope = "compile"; mojo.execute(); @@ -99,7 +113,6 @@ public void testCopyDependenciesMojoIncludeCompileScope() throws Exception { public void testCopyDependenciesMojoIncludeTestScope() throws Exception { mojo.getProject().setArtifacts(stubFactory.getScopedArtifacts()); - mojo.getProject().setDependencyArtifacts(new HashSet()); mojo.includeScope = "test"; mojo.execute(); @@ -117,7 +130,6 @@ public void testCopyDependenciesMojoIncludeTestScope() throws Exception { public void testCopyDependenciesMojoIncludeRuntimeScope() throws Exception { mojo.getProject().setArtifacts(stubFactory.getScopedArtifacts()); - mojo.getProject().setDependencyArtifacts(new HashSet()); mojo.includeScope = "runtime"; mojo.execute(); @@ -135,7 +147,6 @@ public void testCopyDependenciesMojoIncludeRuntimeScope() throws Exception { public void testCopyDependenciesMojoIncludeprovidedScope() throws Exception { mojo.getProject().setArtifacts(stubFactory.getScopedArtifacts()); - mojo.getProject().setDependencyArtifacts(new HashSet()); mojo.includeScope = "provided"; mojo.execute(); @@ -151,7 +162,6 @@ public void testCopyDependenciesMojoIncludeprovidedScope() throws Exception { public void testCopyDependenciesMojoIncludesystemScope() throws Exception { mojo.getProject().setArtifacts(stubFactory.getScopedArtifacts()); - mojo.getProject().setDependencyArtifacts(new HashSet()); mojo.includeScope = "system"; mojo.execute(); @@ -182,7 +192,6 @@ public void testSubPerArtifact() throws Exception { public void testSubPerArtifactAndType() throws Exception { mojo.getProject().setArtifacts(stubFactory.getTypedArtifacts()); - mojo.getProject().setDependencyArtifacts(new HashSet()); mojo.useSubDirectoryPerArtifact = true; mojo.useSubDirectoryPerType = true; @@ -200,7 +209,6 @@ public void testSubPerArtifactAndType() throws Exception { public void testSubPerArtifactAndScope() throws Exception { mojo.getProject().setArtifacts(stubFactory.getTypedArtifacts()); - mojo.getProject().setDependencyArtifacts(new HashSet()); mojo.useSubDirectoryPerArtifact = true; mojo.useSubDirectoryPerScope = true; @@ -225,18 +233,14 @@ public void testRepositoryLayout() throws Exception { createExpandedVersionArtifact(baseVersion, groupId, artifactId, "compile", "jar", null); mojo.getProject().getArtifacts().add(expandedSnapshot); - mojo.getProject().getDependencyArtifacts().add(expandedSnapshot); Artifact pomExpandedSnapshot = createExpandedVersionArtifact(baseVersion, groupId, artifactId, "compile", "pom", null); mojo.getProject().getArtifacts().add(pomExpandedSnapshot); - mojo.getProject().getDependencyArtifacts().add(pomExpandedSnapshot); mojo.useRepositoryLayout = true; mojo.execute(); - ArtifactFactory artifactFactory = lookup(ArtifactFactory.class); - File outputDirectory = mojo.outputDirectory; ArtifactRepository targetRepository = new MavenArtifactRepository( "local", @@ -249,11 +253,12 @@ public void testRepositoryLayout() throws Exception { File baseDirectory = Paths.get(targetRepository.getBasedir()).toFile(); assertTrue(baseDirectory.isDirectory()); + org.apache.maven.repository.RepositorySystem repositorySystem = + lookup(org.apache.maven.repository.RepositorySystem.class); for (Artifact artifact : artifacts) { assertArtifactExists(artifact, targetRepository); - if (!artifact.getBaseVersion().equals(artifact.getVersion())) { - Artifact baseArtifact = artifactFactory.createArtifact( + Artifact baseArtifact = repositorySystem.createArtifact( artifact.getGroupId(), artifact.getArtifactId(), artifact.getBaseVersion(), @@ -275,7 +280,7 @@ private Artifact createExpandedVersionArtifact( snapshot.setBuildNumber(1); RepositoryMetadata metadata = new SnapshotArtifactRepositoryMetadata(expandedSnapshot, snapshot); String newVersion = snapshot.getTimestamp() + "-" + snapshot.getBuildNumber(); - expandedSnapshot.setResolvedVersion(StringUtils.replace(baseVersion, Artifact.SNAPSHOT_VERSION, newVersion)); + expandedSnapshot.setResolvedVersion(baseVersion.replace(Artifact.SNAPSHOT_VERSION, newVersion)); expandedSnapshot.addMetadata(metadata); return expandedSnapshot; } @@ -321,7 +326,6 @@ public void testSubPerArtifactRemoveVersion() throws Exception { public void testSubPerArtifactAndTypeRemoveVersion() throws Exception { mojo.getProject().setArtifacts(stubFactory.getTypedArtifacts()); - mojo.getProject().setDependencyArtifacts(new HashSet()); mojo.useSubDirectoryPerArtifact = true; mojo.useSubDirectoryPerType = true; mojo.stripVersion = true; @@ -356,7 +360,6 @@ public void testSubPerArtifactRemoveType() throws Exception { public void testSubPerArtifactAndTypeRemoveType() throws Exception { mojo.getProject().setArtifacts(stubFactory.getTypedArtifacts()); - mojo.getProject().setDependencyArtifacts(new HashSet()); mojo.useSubDirectoryPerArtifact = true; mojo.useSubDirectoryPerType = true; mojo.stripType = true; diff --git a/src/test/java/org/apache/maven/plugins/dependency/fromDependencies/TestIncludeExcludeUnpackDependenciesMojo.java b/src/test/java/org/apache/maven/plugins/dependency/fromDependencies/TestIncludeExcludeUnpackDependenciesMojo.java index 377a557d0..eeb093818 100644 --- a/src/test/java/org/apache/maven/plugins/dependency/fromDependencies/TestIncludeExcludeUnpackDependenciesMojo.java +++ b/src/test/java/org/apache/maven/plugins/dependency/fromDependencies/TestIncludeExcludeUnpackDependenciesMojo.java @@ -20,39 +20,57 @@ import java.io.File; import java.util.Set; + import org.apache.maven.artifact.Artifact; +import org.apache.maven.execution.MavenSession; import org.apache.maven.plugins.dependency.AbstractDependencyMojoTestCase; +import org.apache.maven.plugins.dependency.testUtils.stubs.DependencyProjectStub; import org.apache.maven.project.MavenProject; public class TestIncludeExcludeUnpackDependenciesMojo extends AbstractDependencyMojoTestCase { - private final String PACKED_FILE = "test.zip"; + private static final String PACKED_FILE = "test.zip"; - private final String UNPACKED_FILE_PREFIX = "test"; + private static final String UNPACKED_FILE_PREFIX = "test"; - private final String UNPACKED_FILE_SUFFIX = ".txt"; + private static final String UNPACKED_FILE_SUFFIX = ".txt"; - private final String PACKED_FILE_PATH = "target/test-classes/unit/unpack-dependencies-test/" + PACKED_FILE; + private static final String PACKED_FILE_PATH = "target/test-classes/unit/unpack-dependencies-test/" + PACKED_FILE; private UnpackDependenciesMojo mojo; + @Override + protected String getTestDirectoryName() { + return "unpack-dependencies"; + } + + @Override + protected boolean shouldCreateFiles() { + return true; + } + + @Override protected void setUp() throws Exception { // required for mojo lookups to work - super.setUp("unpack-dependencies", true); + super.setUp(); + + MavenProject project = new DependencyProjectStub(); + getContainer().addComponent(project, MavenProject.class.getName()); + + MavenSession session = newMavenSession(project); + getContainer().addComponent(session, MavenSession.class.getName()); File testPom = new File(getBasedir(), "target/test-classes/unit/unpack-dependencies-test/plugin-config.xml"); mojo = (UnpackDependenciesMojo) lookupMojo("unpack-dependencies", testPom); mojo.outputDirectory = new File(this.testDir, "outputDirectory"); - // mojo.silent = true; // it needs to get the archivermanager // stubFactory.setUnpackableFile( mojo.getArchiverManager() ); - // i'm using one file repeatedly to archive so I can test the name + // I'm using one file repeatedly to archive so I can test the name // programmatically. stubFactory.setSrcFile(new File(getBasedir() + File.separatorChar + PACKED_FILE_PATH)); assertNotNull(mojo); assertNotNull(mojo.getProject()); - MavenProject project = mojo.getProject(); Set artifacts = this.stubFactory.getScopedArtifacts(); Set directArtifacts = this.stubFactory.getReleaseAndSnapshotArtifacts(); @@ -63,13 +81,6 @@ protected void setUp() throws Exception { mojo.markersDirectory = new File(this.testDir, "markers"); } - protected void tearDown() { - super.tearDown(); - - mojo = null; - System.gc(); - } - private void assertUnpacked(boolean unpacked, String fileName) { File destFile = new File(mojo.getOutputDirectory().getAbsolutePath(), fileName); assertEquals(unpacked, destFile.exists()); diff --git a/src/test/java/org/apache/maven/plugins/dependency/fromDependencies/TestRenderDependenciesMojo.java b/src/test/java/org/apache/maven/plugins/dependency/fromDependencies/TestRenderDependenciesMojo.java new file mode 100644 index 000000000..c42da77d8 --- /dev/null +++ b/src/test/java/org/apache/maven/plugins/dependency/fromDependencies/TestRenderDependenciesMojo.java @@ -0,0 +1,153 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.maven.plugins.dependency.fromDependencies; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.util.Set; + +import org.apache.maven.artifact.Artifact; +import org.apache.maven.execution.MavenSession; +import org.apache.maven.plugins.dependency.AbstractDependencyMojoTestCase; +import org.apache.maven.plugins.dependency.testUtils.stubs.DependencyProjectStub; +import org.apache.maven.project.MavenProject; + +import static org.assertj.core.api.Assertions.assertThat; + +public class TestRenderDependenciesMojo extends AbstractDependencyMojoTestCase { + private RenderDependenciesMojo mojo; + + @Override + protected String getTestDirectoryName() { + return "render-dependencies"; + } + + @Override + protected boolean shouldCreateFiles() { + return true; + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + + final MavenProject project = new DependencyProjectStub(); + getContainer().addComponent(project, MavenProject.class.getName()); + + final MavenSession session = newMavenSession(project); + getContainer().addComponent(session, MavenSession.class.getName()); + + final File testPom = new File( + getBasedir(), "target/test-classes/unit/" + getTestDirectoryName() + "-test/plugin-config.xml"); + mojo = (RenderDependenciesMojo) lookupMojo(getTestDirectoryName(), testPom); + } + + /** + * Tests the rendering. + * Note that this is a real life example of using the mojo to generate a CRD for a SparkApplication. + * It is useful when combined with JIB for example since several versions of the CRD do not support wildcard for + * the classpath(s). + */ + public void testRender() throws Exception { + final File rendered = new File(testDir, "render-dependencies.testRender.txt"); + + setupProject(); + + mojo.setTemplate("deps:\n" + + " jars:\n" + + "#foreach($dep in $sorter.sort($artifacts, [\"artifactId:asc\"]))\n" + + "#set($type = $dep.type)\n" + + "#if(!$type || $type.trim().isEmpty())\n" + + " #set($type = \"jar\")\n" + + "#end\n" + + "#set($classifierSuffix = \"\")\n" + + "#if($dep.classifier && !$dep.classifier.trim().isEmpty())\n" + + " #set($classifierSuffix = \"-$dep.classifier\")\n" + + "#end\n" + + " - local:///opt/test/libs/$dep.artifactId-$dep.baseVersion$classifierSuffix.$type\n" + + "#end"); + mojo.setOutputFile(rendered); + mojo.execute(); + + assertThat(rendered) + .content() + .isEqualTo("deps:\n" + + " jars:\n" + + " - local:///opt/test/libs/compile-1.0.jar\n" + + " - local:///opt/test/libs/provided-1.0.jar\n" + + " - local:///opt/test/libs/release-1.0.jar\n" + + " - local:///opt/test/libs/runtime-1.0.jar\n" + + " - local:///opt/test/libs/snapshot-2.0-SNAPSHOT.jar\n" + + " - local:///opt/test/libs/system-1.0.jar\n" + + " - local:///opt/test/libs/test-1.0.jar\n"); + } + + /** + * Tests the rendering with a file template. + */ + public void testRenderFromFile() throws Exception { + final File rendered = new File(testDir, "render-dependencies.testRenderFromFile.txt"); + final File template = new File(testDir, "render-dependencies.testRenderFromFile.template.vm"); + Files.write( + template.toPath(), + ("deps:\n" + + " jars:\n" + + "#foreach($dep in $sorter.sort($artifacts, [\"artifactId:asc\"]))\n" + + "#set($type = $dep.type)\n" + + "#if(!$type || $type.trim().isEmpty())\n" + + " #set($type = \"jar\")\n" + + "#end\n" + + "#set($classifierSuffix = \"\")\n" + + "#if($dep.classifier && !$dep.classifier.trim().isEmpty())\n" + + " #set($classifierSuffix = \"-$dep.classifier\")\n" + + "#end\n" + + " - local:///opt/test/libs/$dep.artifactId-$dep.baseVersion$classifierSuffix.$type\n" + + "#end") + .getBytes(StandardCharsets.UTF_8)); + + setupProject(); + + mojo.setTemplate(template.getAbsolutePath()); + mojo.setOutputFile(rendered); + mojo.execute(); + + assertThat(rendered) + .content() + .isEqualTo("deps:\n" + + " jars:\n" + + " - local:///opt/test/libs/compile-1.0.jar\n" + + " - local:///opt/test/libs/provided-1.0.jar\n" + + " - local:///opt/test/libs/release-1.0.jar\n" + + " - local:///opt/test/libs/runtime-1.0.jar\n" + + " - local:///opt/test/libs/snapshot-2.0-SNAPSHOT.jar\n" + + " - local:///opt/test/libs/system-1.0.jar\n" + + " - local:///opt/test/libs/test-1.0.jar\n"); + } + + private void setupProject() throws IOException { + final MavenProject project = mojo.getProject(); + final Set artifacts = stubFactory.getScopedArtifacts(); + final Set directArtifacts = stubFactory.getReleaseAndSnapshotArtifacts(); + artifacts.addAll(directArtifacts); + project.setArtifacts(artifacts); + project.setDependencyArtifacts(directArtifacts); + } +} diff --git a/src/test/java/org/apache/maven/plugins/dependency/fromDependencies/TestUnpackDependenciesMojo.java b/src/test/java/org/apache/maven/plugins/dependency/fromDependencies/TestUnpackDependenciesMojo.java index 708832b12..98ddc8135 100644 --- a/src/test/java/org/apache/maven/plugins/dependency/fromDependencies/TestUnpackDependenciesMojo.java +++ b/src/test/java/org/apache/maven/plugins/dependency/fromDependencies/TestUnpackDependenciesMojo.java @@ -20,9 +20,9 @@ import java.io.File; import java.io.IOException; -import java.util.HashSet; import java.util.Iterator; import java.util.Set; + import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager; import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter; @@ -33,41 +33,65 @@ import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugins.dependency.AbstractDependencyMojoTestCase; import org.apache.maven.plugins.dependency.testUtils.DependencyArtifactStubFactory; +import org.apache.maven.plugins.dependency.testUtils.stubs.DependencyProjectStub; import org.apache.maven.plugins.dependency.utils.DependencyUtil; +import org.apache.maven.plugins.dependency.utils.ResolverUtil; import org.apache.maven.plugins.dependency.utils.markers.DefaultFileMarkerHandler; import org.apache.maven.project.MavenProject; -import org.codehaus.plexus.util.StringUtils; +import org.codehaus.plexus.archiver.manager.ArchiverManager; +import org.eclipse.aether.RepositorySystem; public class TestUnpackDependenciesMojo extends AbstractDependencyMojoTestCase { - private final String UNPACKABLE_FILE = "test.txt"; + private static final String UNPACKABLE_FILE = "test.txt"; - private final String UNPACKABLE_FILE_PATH = "target/test-classes/unit/unpack-dependencies-test/" + UNPACKABLE_FILE; + private static final String UNPACKABLE_FILE_PATH = + "target/test-classes/unit/unpack-dependencies-test/" + UNPACKABLE_FILE; UnpackDependenciesMojo mojo; + @Override + protected String getTestDirectoryName() { + return "unpack-dependencies"; + } + + @Override + protected boolean shouldCreateFiles() { + return true; + } + + @Override + protected boolean shouldUseFlattenedPath() { + return false; + } + + @Override protected void setUp() throws Exception { // required for mojo lookups to work - super.setUp("unpack-dependencies", true, false); + super.setUp(); + + MavenProject project = new DependencyProjectStub(); + getContainer().addComponent(project, MavenProject.class.getName()); + + MavenSession session = newMavenSession(project); + getContainer().addComponent(session, MavenSession.class.getName()); + + RepositorySystem repositorySystem = lookup(RepositorySystem.class); + ResolverUtil resolverUtil = new ResolverUtil(repositorySystem, () -> session); + getContainer().addComponent(resolverUtil, ResolverUtil.class.getName()); File testPom = new File(getBasedir(), "target/test-classes/unit/unpack-dependencies-test/plugin-config.xml"); mojo = (UnpackDependenciesMojo) lookupMojo("unpack-dependencies", testPom); mojo.outputDirectory = new File(this.testDir, "outputDirectory"); - mojo.setUseJvmChmod(true); - // mojo.silent = true; // it needs to get the archivermanager - stubFactory.setUnpackableFile(mojo.getArchiverManager()); + stubFactory.setUnpackableFile(lookup(ArchiverManager.class)); // i'm using one file repeatedly to archive so I can test the name // programmatically. stubFactory.setSrcFile(new File(getBasedir() + File.separatorChar + UNPACKABLE_FILE_PATH)); assertNotNull(mojo); assertNotNull(mojo.getProject()); - MavenProject project = mojo.getProject(); - - MavenSession session = newMavenSession(project); - setVariableValueToObject(mojo, "session", session); LegacySupport legacySupport = lookup(LegacySupport.class); legacySupport.setSession(session); @@ -78,20 +102,12 @@ protected void setUp() throws Exception { artifacts.addAll(directArtifacts); project.setArtifacts(artifacts); - project.setDependencyArtifacts(directArtifacts); mojo.markersDirectory = new File(this.testDir, "markers"); ArtifactHandlerManager manager = lookup(ArtifactHandlerManager.class); setVariableValueToObject(mojo, "artifactHandlerManager", manager); } - protected void tearDown() { - super.tearDown(); - - mojo = null; - System.gc(); - } - public void assertUnpacked(Artifact artifact) { assertUnpacked(true, artifact); } @@ -124,7 +140,7 @@ public void assertMarkerFile(boolean val, Artifact artifact) { public void testMojo() throws Exception { mojo.execute(); - for (Artifact artifact : (Iterable) mojo.getProject().getArtifacts()) { + for (Artifact artifact : mojo.getProject().getArtifacts()) { assertUnpacked(artifact); } } @@ -132,63 +148,56 @@ public void testMojo() throws Exception { public void testNoTransitive() throws Exception { mojo.excludeTransitive = true; mojo.execute(); - for (Artifact artifact : (Iterable) mojo.getProject().getDependencyArtifacts()) { + for (Artifact artifact : mojo.getProject().getArtifacts()) { assertUnpacked(artifact); } } public void testExcludeType() throws Exception { mojo.getProject().setArtifacts(stubFactory.getTypedArchiveArtifacts()); - mojo.getProject().setDependencyArtifacts(new HashSet()); mojo.excludeTypes = "jar"; mojo.execute(); - for (Artifact artifact : (Iterable) mojo.getProject().getArtifacts()) { + for (Artifact artifact : mojo.getProject().getArtifacts()) { assertUnpacked(!artifact.getType().equalsIgnoreCase("jar"), artifact); } } public void testExcludeProvidedScope() throws Exception { mojo.getProject().setArtifacts(stubFactory.getScopedArtifacts()); - mojo.getProject().setDependencyArtifacts(new HashSet()); mojo.excludeScope = "provided"; - // mojo.silent = false; mojo.execute(); - for (Artifact artifact : (Iterable) mojo.getProject().getArtifacts()) { + for (Artifact artifact : mojo.getProject().getArtifacts()) { assertUnpacked(!artifact.getScope().equals("provided"), artifact); } } public void testExcludeSystemScope() throws Exception { mojo.getProject().setArtifacts(stubFactory.getScopedArtifacts()); - mojo.getProject().setDependencyArtifacts(new HashSet()); mojo.excludeScope = "system"; - // mojo.silent = false; mojo.execute(); - for (Artifact artifact : (Iterable) mojo.getProject().getArtifacts()) { + for (Artifact artifact : mojo.getProject().getArtifacts()) { assertUnpacked(!artifact.getScope().equals("system"), artifact); } } public void testExcludeCompileScope() throws Exception { mojo.getProject().setArtifacts(stubFactory.getScopedArtifacts()); - mojo.getProject().setDependencyArtifacts(new HashSet()); mojo.excludeScope = "compile"; mojo.execute(); ScopeArtifactFilter saf = new ScopeArtifactFilter(mojo.excludeScope); - for (Artifact artifact : (Iterable) mojo.getProject().getArtifacts()) { + for (Artifact artifact : mojo.getProject().getArtifacts()) { assertUnpacked(!saf.include(artifact), artifact); } } public void testExcludeTestScope() throws IOException, MojoFailureException { mojo.getProject().setArtifacts(stubFactory.getScopedArtifacts()); - mojo.getProject().setDependencyArtifacts(new HashSet()); mojo.excludeScope = "test"; try { @@ -201,19 +210,17 @@ public void testExcludeTestScope() throws IOException, MojoFailureException { public void testExcludeRuntimeScope() throws Exception { mojo.getProject().setArtifacts(stubFactory.getScopedArtifacts()); - mojo.getProject().setDependencyArtifacts(new HashSet()); mojo.excludeScope = "runtime"; mojo.execute(); ScopeArtifactFilter saf = new ScopeArtifactFilter(mojo.excludeScope); - for (Artifact artifact : (Iterable) mojo.getProject().getArtifacts()) { + for (Artifact artifact : mojo.getProject().getArtifacts()) { assertUnpacked(!saf.include(artifact), artifact); } } public void testIncludeType() throws Exception { mojo.getProject().setArtifacts(stubFactory.getTypedArchiveArtifacts()); - mojo.getProject().setDependencyArtifacts(new HashSet()); mojo.includeTypes = "jar"; mojo.excludeTypes = "jar"; @@ -241,11 +248,10 @@ public void testIncludeType() throws Exception { public void testSubPerType() throws Exception { mojo.getProject().setArtifacts(stubFactory.getTypedArchiveArtifacts()); - mojo.getProject().setDependencyArtifacts(new HashSet()); mojo.useSubDirectoryPerType = true; mojo.execute(); - for (Artifact artifact : (Iterable) mojo.getProject().getArtifacts()) { + for (Artifact artifact : mojo.getProject().getArtifacts()) { assertUnpacked(artifact); } } @@ -254,19 +260,18 @@ public void testSubPerArtifact() throws Exception { mojo.useSubDirectoryPerArtifact = true; mojo.execute(); - for (Artifact artifact : (Iterable) mojo.getProject().getArtifacts()) { + for (Artifact artifact : mojo.getProject().getArtifacts()) { assertUnpacked(artifact); } } public void testSubPerArtifactAndType() throws Exception { mojo.getProject().setArtifacts(stubFactory.getTypedArchiveArtifacts()); - mojo.getProject().setDependencyArtifacts(new HashSet()); mojo.useSubDirectoryPerArtifact = true; mojo.useSubDirectoryPerType = true; mojo.execute(); - for (Artifact artifact : (Iterable) mojo.getProject().getArtifacts()) { + for (Artifact artifact : mojo.getProject().getArtifacts()) { assertUnpacked(artifact); } } @@ -276,87 +281,80 @@ public void testSubPerArtifactRemoveVersion() throws Exception { mojo.stripVersion = true; mojo.execute(); - for (Artifact artifact : (Iterable) mojo.getProject().getArtifacts()) { + for (Artifact artifact : mojo.getProject().getArtifacts()) { assertUnpacked(artifact); } } public void testSubPerArtifactAndTypeRemoveVersion() throws Exception { mojo.getProject().setArtifacts(stubFactory.getTypedArchiveArtifacts()); - mojo.getProject().setDependencyArtifacts(new HashSet()); mojo.useSubDirectoryPerArtifact = true; mojo.useSubDirectoryPerType = true; mojo.stripVersion = true; mojo.execute(); - for (Artifact artifact : (Iterable) mojo.getProject().getArtifacts()) { + for (Artifact artifact : mojo.getProject().getArtifacts()) { assertUnpacked(artifact); } } public void testIncludeCompileScope() throws Exception { mojo.getProject().setArtifacts(stubFactory.getScopedArtifacts()); - mojo.getProject().setDependencyArtifacts(new HashSet()); mojo.includeScope = "compile"; mojo.execute(); ScopeArtifactFilter saf = new ScopeArtifactFilter(mojo.includeScope); - for (Artifact artifact : (Iterable) mojo.getProject().getArtifacts()) { + for (Artifact artifact : mojo.getProject().getArtifacts()) { assertUnpacked(saf.include(artifact), artifact); } } public void testIncludeTestScope() throws Exception { mojo.getProject().setArtifacts(stubFactory.getScopedArtifacts()); - mojo.getProject().setDependencyArtifacts(new HashSet()); mojo.includeScope = "test"; mojo.execute(); ScopeArtifactFilter saf = new ScopeArtifactFilter(mojo.includeScope); - for (Artifact artifact : (Iterable) mojo.getProject().getArtifacts()) { + for (Artifact artifact : mojo.getProject().getArtifacts()) { assertUnpacked(saf.include(artifact), artifact); } } public void testIncludeRuntimeScope() throws Exception { mojo.getProject().setArtifacts(stubFactory.getScopedArtifacts()); - mojo.getProject().setDependencyArtifacts(new HashSet()); mojo.includeScope = "runtime"; mojo.execute(); ScopeArtifactFilter saf = new ScopeArtifactFilter(mojo.includeScope); - for (Artifact artifact : (Iterable) mojo.getProject().getArtifacts()) { + for (Artifact artifact : mojo.getProject().getArtifacts()) { assertUnpacked(saf.include(artifact), artifact); } } public void testIncludeprovidedScope() throws Exception { mojo.getProject().setArtifacts(stubFactory.getScopedArtifacts()); - mojo.getProject().setDependencyArtifacts(new HashSet()); mojo.includeScope = "provided"; mojo.execute(); - for (Artifact artifact : (Iterable) mojo.getProject().getArtifacts()) { + for (Artifact artifact : mojo.getProject().getArtifacts()) { assertUnpacked(Artifact.SCOPE_PROVIDED.equals(artifact.getScope()), artifact); } } public void testIncludesystemScope() throws Exception { mojo.getProject().setArtifacts(stubFactory.getScopedArtifacts()); - mojo.getProject().setDependencyArtifacts(new HashSet()); mojo.includeScope = "system"; mojo.execute(); - for (Artifact artifact : (Iterable) mojo.getProject().getArtifacts()) { + for (Artifact artifact : mojo.getProject().getArtifacts()) { assertUnpacked(Artifact.SCOPE_SYSTEM.equals(artifact.getScope()), artifact); } } public void testIncludeArtifactId() throws Exception { mojo.getProject().setArtifacts(stubFactory.getArtifactArtifacts()); - mojo.getProject().setDependencyArtifacts(new HashSet()); mojo.includeArtifactIds = "one"; mojo.excludeArtifactIds = "one"; @@ -380,32 +378,29 @@ public void testIncludeArtifactId() throws Exception { public void testExcludeArtifactId() throws Exception { mojo.getProject().setArtifacts(stubFactory.getArtifactArtifacts()); - mojo.getProject().setDependencyArtifacts(new HashSet()); mojo.excludeArtifactIds = "one"; mojo.execute(); // test - get all direct dependencies and verify that they exist if they // do not have a classifier of "one" // then delete the file and at the end, verify the folder is empty. - for (Artifact artifact : (Iterable) mojo.getProject().getArtifacts()) { + for (Artifact artifact : mojo.getProject().getArtifacts()) { assertUnpacked(!artifact.getArtifactId().equals("one"), artifact); } } public void testExcludeGroupId() throws Exception { mojo.getProject().setArtifacts(stubFactory.getGroupIdArtifacts()); - mojo.getProject().setDependencyArtifacts(new HashSet()); mojo.excludeGroupIds = "one"; mojo.execute(); - for (Artifact artifact : (Iterable) mojo.getProject().getArtifacts()) { + for (Artifact artifact : mojo.getProject().getArtifacts()) { assertUnpacked(!artifact.getGroupId().equals("one"), artifact); } } public void testIncludeGroupId() throws Exception { mojo.getProject().setArtifacts(stubFactory.getGroupIdArtifacts()); - mojo.getProject().setDependencyArtifacts(new HashSet()); mojo.includeGroupIds = "one"; mojo.excludeGroupIds = "one"; // shouldn't get anything @@ -464,10 +459,10 @@ public void dotestClassifierType(String testClassifier, String testType) throws String useClassifier = artifact.getClassifier(); String useType = artifact.getType(); - if (StringUtils.isNotEmpty(testClassifier)) { + if (testClassifier != null && !testClassifier.isEmpty()) { useClassifier = testClassifier; // type is only used if classifier is used. - if (StringUtils.isNotEmpty(testType)) { + if (testType != null && !testType.isEmpty()) { useType = testType; } } @@ -482,16 +477,13 @@ public void dotestClassifierType(String testClassifier, String testType) throws } } - public void testArtifactNotFound() throws Exception { - dotestArtifactExceptions(false, true); - } - - public void testArtifactResolutionException() throws Exception { - dotestArtifactExceptions(true, false); + public void testArtifactResolutionException() throws MojoFailureException { + dotestArtifactExceptions(); } - public void dotestArtifactExceptions(boolean are, boolean anfe) throws Exception { + public void dotestArtifactExceptions() throws MojoFailureException { mojo.classifier = "jdk"; + mojo.failOnMissingClassifierArtifact = true; mojo.type = "java-sources"; try { diff --git a/src/test/java/org/apache/maven/plugins/dependency/fromDependencies/TestUnpackDependenciesMojo2.java b/src/test/java/org/apache/maven/plugins/dependency/fromDependencies/TestUnpackDependenciesMojo2.java index e841643f5..932dbb564 100644 --- a/src/test/java/org/apache/maven/plugins/dependency/fromDependencies/TestUnpackDependenciesMojo2.java +++ b/src/test/java/org/apache/maven/plugins/dependency/fromDependencies/TestUnpackDependenciesMojo2.java @@ -22,58 +22,71 @@ import java.io.IOException; import java.util.HashSet; import java.util.Set; + import org.apache.maven.artifact.Artifact; +import org.apache.maven.execution.MavenSession; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugins.dependency.AbstractDependencyMojoTestCase; import org.apache.maven.plugins.dependency.testUtils.DependencyArtifactStubFactory; +import org.apache.maven.plugins.dependency.testUtils.stubs.DependencyProjectStub; import org.apache.maven.plugins.dependency.utils.DependencyUtil; import org.apache.maven.project.MavenProject; +import org.codehaus.plexus.archiver.manager.ArchiverManager; + +import static org.junit.Assert.assertNotEquals; public class TestUnpackDependenciesMojo2 extends AbstractDependencyMojoTestCase { - private final String UNPACKABLE_FILE = "test.txt"; + private static final String UNPACKABLE_FILE = "test.txt"; - private final String UNPACKABLE_FILE_PATH = "target/test-classes/unit/unpack-dependencies-test/" + UNPACKABLE_FILE; + private static final String UNPACKABLE_FILE_PATH = + "target/test-classes/unit/unpack-dependencies-test/" + UNPACKABLE_FILE; private UnpackDependenciesMojo mojo; + @Override + protected String getTestDirectoryName() { + return "unpack-dependencies"; + } + + @Override + protected boolean shouldCreateFiles() { + return true; + } + + @Override protected void setUp() throws Exception { // required for mojo lookups to work - super.setUp("unpack-dependencies", true); + super.setUp(); + + MavenProject project = new DependencyProjectStub(); + getContainer().addComponent(project, MavenProject.class.getName()); + + MavenSession session = newMavenSession(project); + getContainer().addComponent(session, MavenSession.class.getName()); File testPom = new File(getBasedir(), "target/test-classes/unit/unpack-dependencies-test/plugin-config.xml"); mojo = (UnpackDependenciesMojo) lookupMojo("unpack-dependencies", testPom); mojo.outputDirectory = new File(this.testDir, "outputDirectory"); - mojo.setUseJvmChmod(true); - // mojo.silent = true; // it needs to get the archivermanager - stubFactory.setUnpackableFile(mojo.getArchiverManager()); + stubFactory.setUnpackableFile(lookup(ArchiverManager.class)); // i'm using one file repeatedly to archive so I can test the name // programmatically. stubFactory.setSrcFile(new File(getBasedir() + File.separatorChar + UNPACKABLE_FILE_PATH)); assertNotNull(mojo); assertNotNull(mojo.getProject()); - MavenProject project = mojo.getProject(); Set artifacts = this.stubFactory.getScopedArtifacts(); Set directArtifacts = this.stubFactory.getReleaseAndSnapshotArtifacts(); artifacts.addAll(directArtifacts); project.setArtifacts(artifacts); - project.setDependencyArtifacts(directArtifacts); mojo.markersDirectory = new File(this.testDir, "markers"); } - protected void tearDown() { - super.tearDown(); - - mojo = null; - System.gc(); - } - public File getUnpackedFile(Artifact artifact) { File destDir = DependencyUtil.getFormattedOutputDirectory( mojo.isUseSubDirectoryPerScope(), @@ -99,7 +112,6 @@ public void testDontOverWriteRelease() artifacts.add(release); mojo.getProject().setArtifacts(artifacts); - mojo.getProject().setDependencyArtifacts(artifacts); mojo.overWriteIfNewer = false; @@ -118,7 +130,6 @@ public void testOverWriteRelease() artifacts.add(release); mojo.getProject().setArtifacts(artifacts); - mojo.getProject().setDependencyArtifacts(artifacts); mojo.overWriteReleases = true; mojo.overWriteIfNewer = false; @@ -138,7 +149,6 @@ public void testDontOverWriteSnap() artifacts.add(snap); mojo.getProject().setArtifacts(artifacts); - mojo.getProject().setDependencyArtifacts(artifacts); mojo.overWriteReleases = false; mojo.overWriteSnapshots = false; @@ -159,7 +169,6 @@ public void testOverWriteSnap() artifacts.add(snap); mojo.getProject().setArtifacts(artifacts); - mojo.getProject().setDependencyArtifacts(artifacts); mojo.overWriteReleases = false; mojo.overWriteSnapshots = true; @@ -180,7 +189,6 @@ public void testOverWriteIfNewer() artifacts.add(snap); mojo.getProject().setArtifacts(artifacts); - mojo.getProject().setDependencyArtifacts(artifacts); mojo.overWriteReleases = false; mojo.overWriteSnapshots = false; @@ -202,7 +210,7 @@ public void testOverWriteIfNewer() assertEquals(time, unpackedFile.lastModified()); mojo.execute(); - System.gc(); + // make sure it didn't overwrite assertEquals(time, unpackedFile.lastModified()); @@ -210,9 +218,7 @@ public void testOverWriteIfNewer() mojo.execute(); - assertTrue(time != unpackedFile.lastModified()); - - System.gc(); + assertNotEquals(time, unpackedFile.lastModified()); } public void assertUnpacked(Artifact artifact, boolean overWrite) @@ -232,7 +238,7 @@ public void assertUnpacked(Artifact artifact, boolean overWrite) mojo.execute(); if (overWrite) { - assertTrue(time != unpackedFile.lastModified()); + assertNotEquals(time, unpackedFile.lastModified()); } else { assertEquals(time, unpackedFile.lastModified()); } diff --git a/src/test/java/org/apache/maven/plugins/dependency/resolvers/ExcludeReactorProjectsArtifactFilterTest.java b/src/test/java/org/apache/maven/plugins/dependency/resolvers/ExcludeReactorProjectsArtifactFilterTest.java index 699a2c151..203d76546 100644 --- a/src/test/java/org/apache/maven/plugins/dependency/resolvers/ExcludeReactorProjectsArtifactFilterTest.java +++ b/src/test/java/org/apache/maven/plugins/dependency/resolvers/ExcludeReactorProjectsArtifactFilterTest.java @@ -18,16 +18,9 @@ */ package org.apache.maven.plugins.dependency.resolvers; -import static java.util.Collections.singleton; -import static java.util.Collections.singletonList; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - import java.util.HashSet; import java.util.Set; + import org.apache.maven.artifact.Artifact; import org.apache.maven.plugin.logging.Log; import org.apache.maven.plugin.testing.stubs.ArtifactStub; @@ -37,6 +30,14 @@ import org.apache.maven.shared.artifact.filter.collection.ArtifactFilterException; import org.mockito.ArgumentCaptor; +import static java.util.Collections.singleton; +import static java.util.Collections.singletonList; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + public class ExcludeReactorProjectsArtifactFilterTest extends AbstractDependencyMojoTestCase { public void testFilter() throws ArtifactFilterException { diff --git a/src/test/java/org/apache/maven/plugins/dependency/resolvers/ExcludeReactorProjectsDependencyFilterTest.java b/src/test/java/org/apache/maven/plugins/dependency/resolvers/ExcludeReactorProjectsDependencyFilterTest.java index e4f0e65d6..e1460e317 100644 --- a/src/test/java/org/apache/maven/plugins/dependency/resolvers/ExcludeReactorProjectsDependencyFilterTest.java +++ b/src/test/java/org/apache/maven/plugins/dependency/resolvers/ExcludeReactorProjectsDependencyFilterTest.java @@ -18,23 +18,14 @@ */ package org.apache.maven.plugins.dependency.resolvers; -import static java.util.Collections.singletonList; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; import org.apache.maven.artifact.Artifact; import org.apache.maven.model.Dependency; -import org.apache.maven.plugin.logging.Log; import org.apache.maven.plugin.testing.stubs.ArtifactStub; import org.apache.maven.plugin.testing.stubs.MavenProjectStub; import org.apache.maven.plugins.dependency.AbstractDependencyMojoTestCase; import org.apache.maven.project.MavenProject; -import org.apache.maven.shared.artifact.filter.resolve.Node; -import org.mockito.ArgumentCaptor; + +import static java.util.Collections.singletonList; public class ExcludeReactorProjectsDependencyFilterTest extends AbstractDependencyMojoTestCase { public void testReject() { @@ -48,73 +39,18 @@ public void testReject() { artifact2.setArtifactId("maven-dependency-plugin-other-dummy"); artifact2.setVersion("1.0"); - Set artifacts = new HashSet<>(); - artifacts.add(artifact1); - artifacts.add(artifact2); - MavenProject project = new MavenProjectStub(); project.setArtifact(artifact1); - Log log = mock(Log.class); - when(log.isDebugEnabled()).thenReturn(false); - ExcludeReactorProjectsDependencyFilter filter = - new ExcludeReactorProjectsDependencyFilter(singletonList(project), log); + new ExcludeReactorProjectsDependencyFilter(singletonList(project)); - Node node = new Node() { - @Override - public Dependency getDependency() { - final Dependency result = new Dependency(); - result.setGroupId(artifact1.getGroupId()); - result.setArtifactId(artifact1.getArtifactId()); - result.setVersion(artifact1.getVersion()); - return result; - } - }; + Dependency dependency = new Dependency(); + dependency.setGroupId(artifact1.getGroupId()); + dependency.setArtifactId(artifact1.getArtifactId()); + dependency.setVersion(artifact1.getVersion()); - assertFalse(filter.accept(node, Collections.emptyList())); - } - - public void testRejectWithLogging() { - final Artifact artifact1 = new ArtifactStub(); - artifact1.setGroupId("org.apache.maven.plugins"); - artifact1.setArtifactId("maven-dependency-plugin-dummy"); - artifact1.setVersion("1.0"); - - Artifact artifact2 = new ArtifactStub(); - artifact2.setGroupId("org.apache.maven.plugins"); - artifact2.setArtifactId("maven-dependency-plugin-other-dummy"); - artifact2.setVersion("1.0"); - - Set artifacts = new HashSet<>(); - artifacts.add(artifact1); - artifacts.add(artifact2); - - MavenProject project = new MavenProjectStub(); - project.setArtifact(artifact1); - - Log log = mock(Log.class); - when(log.isDebugEnabled()).thenReturn(true); - - ExcludeReactorProjectsDependencyFilter filter = - new ExcludeReactorProjectsDependencyFilter(singletonList(project), log); - - Node node = new Node() { - @Override - public Dependency getDependency() { - final Dependency result = new Dependency(); - result.setGroupId(artifact1.getGroupId()); - result.setArtifactId(artifact1.getArtifactId()); - result.setVersion(artifact1.getVersion()); - return result; - } - }; - - filter.accept(node, Collections.emptyList()); - - ArgumentCaptor captor = ArgumentCaptor.forClass(String.class); - verify(log).debug(captor.capture()); - assertTrue(captor.getValue().contains("Skipped dependency")); + assertFalse(filter.test(dependency)); } public void testAccept() { @@ -128,30 +64,17 @@ public void testAccept() { artifact2.setArtifactId("maven-dependency-plugin-other-dummy"); artifact2.setVersion("1.0"); - Set artifacts = new HashSet<>(); - artifacts.add(artifact1); - artifacts.add(artifact2); - MavenProject project = new MavenProjectStub(); project.setArtifact(artifact1); - Log log = mock(Log.class); - when(log.isDebugEnabled()).thenReturn(false); - ExcludeReactorProjectsDependencyFilter filter = - new ExcludeReactorProjectsDependencyFilter(singletonList(project), log); + new ExcludeReactorProjectsDependencyFilter(singletonList(project)); - Node node = new Node() { - @Override - public Dependency getDependency() { - final Dependency result = new Dependency(); - result.setGroupId("something-else"); - result.setArtifactId(artifact1.getArtifactId()); - result.setVersion(artifact1.getVersion()); - return result; - } - }; + Dependency dependency = new Dependency(); + dependency.setGroupId("something-else"); + dependency.setArtifactId(artifact1.getArtifactId()); + dependency.setVersion(artifact1.getVersion()); - assertTrue(filter.accept(node, Collections.emptyList())); + assertTrue(filter.test(dependency)); } } diff --git a/src/test/java/org/apache/maven/plugins/dependency/resolvers/GoOfflineMojoTest.java b/src/test/java/org/apache/maven/plugins/dependency/resolvers/GoOfflineMojoTest.java new file mode 100644 index 000000000..9c48d72c8 --- /dev/null +++ b/src/test/java/org/apache/maven/plugins/dependency/resolvers/GoOfflineMojoTest.java @@ -0,0 +1,416 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.maven.plugins.dependency.resolvers; + +import java.io.File; +import java.util.HashSet; +import java.util.Set; + +import org.apache.maven.artifact.Artifact; +import org.apache.maven.execution.MavenSession; +import org.apache.maven.plugin.testing.stubs.ArtifactStub; +import org.apache.maven.plugins.dependency.AbstractDependencyMojoTestCase; +import org.apache.maven.plugins.dependency.testUtils.stubs.DependencyProjectStub; +import org.apache.maven.project.MavenProject; +import org.apache.maven.shared.artifact.filter.collection.FilterArtifacts; +import org.junit.jupiter.api.Disabled; + +public class GoOfflineMojoTest extends AbstractDependencyMojoTestCase { + private GoOfflineMojo subject; + + @Override + protected String getTestDirectoryName() { + return "go-offline"; + } + + @Override + protected boolean shouldCreateFiles() { + return true; + } + + @Override + protected void setUp() throws Exception { + // required for mojo lookups to work + super.setUp(); + MavenProject project = new DependencyProjectStub(); + getContainer().addComponent(project, MavenProject.class.getName()); + + MavenSession session = newMavenSession(project); + getContainer().addComponent(session, MavenSession.class.getName()); + } + + private static final String GROUP_EXCLUDE_PREFIX = "skip.this.groupid"; + + private static final String ARTIFACT_EXCLUDE_PREFIX = "skip-this-artifact"; + + private static final String CLASSIFIER_EXCLUDE_PREFIX = "skipThisClassifier"; + + private static final String DUMMY_ARTIFACT_NAME = "dummy-artifact"; + + private static final String STUB_ARTIFACT_VERSION = "3.14"; + + private static final String VALID_GROUP = "org.junit.jupiter"; + + public void testExcludeGroupIds() throws Exception { + File testPom = new File(getBasedir(), "target/test-classes/unit/go-offline-test/exclude-plugin-config.xml"); + + subject = (GoOfflineMojo) lookupMojo("go-offline", testPom); + assertNotNull(subject); + + Artifact artifact1 = new ArtifactStub(); + artifact1.setGroupId(GROUP_EXCLUDE_PREFIX); + artifact1.setArtifactId(DUMMY_ARTIFACT_NAME); + artifact1.setVersion(STUB_ARTIFACT_VERSION); + + Artifact artifact2 = new ArtifactStub(); + artifact2.setGroupId(GROUP_EXCLUDE_PREFIX + ".too"); + artifact2.setArtifactId(DUMMY_ARTIFACT_NAME); + artifact2.setVersion(STUB_ARTIFACT_VERSION + "-SNAPSHOT"); + + Artifact artifact3 = new ArtifactStub(); + artifact3.setGroupId("dont.skip.me"); + artifact3.setArtifactId(DUMMY_ARTIFACT_NAME); + artifact3.setVersion("1.0"); + + Set artifacts = new HashSet<>(); + artifacts.add(artifact1); + artifacts.add(artifact2); + artifacts.add(artifact3); + + assertEquals(3, artifacts.size()); + FilterArtifacts filter = subject.getArtifactsFilter(); + artifacts = filter.filter(artifacts); + assertEquals(1, artifacts.size()); + assertTrue(artifacts.contains(artifact3)); + assertFalse(artifacts.contains(artifact1)); + assertFalse(artifacts.contains(artifact2)); + } + + public void testExcludeArtifactIds() throws Exception { + File testPom = new File(getBasedir(), "target/test-classes/unit/go-offline-test/exclude-plugin-config.xml"); + + subject = (GoOfflineMojo) lookupMojo("go-offline", testPom); + assertNotNull(subject); + + Artifact artifact1 = new ArtifactStub(); + artifact1.setGroupId(VALID_GROUP); + artifact1.setArtifactId(ARTIFACT_EXCLUDE_PREFIX); + artifact1.setVersion(STUB_ARTIFACT_VERSION + "-SNAPSHOT"); + + Artifact artifact2 = new ArtifactStub(); + artifact2.setGroupId(VALID_GROUP); + artifact2.setArtifactId(ARTIFACT_EXCLUDE_PREFIX + "-too"); + artifact2.setVersion(STUB_ARTIFACT_VERSION); + + Artifact artifact3 = new ArtifactStub(); + artifact3.setGroupId("dont.skip.me"); + artifact3.setArtifactId("dummy-artifact"); + artifact3.setVersion("1.0"); + + Set artifacts = new HashSet<>(); + artifacts.add(artifact1); + artifacts.add(artifact2); + artifacts.add(artifact3); + + assertEquals(3, artifacts.size()); + FilterArtifacts filter = subject.getArtifactsFilter(); + artifacts = filter.filter(artifacts); + assertEquals(1, artifacts.size()); + assertTrue(artifacts.contains(artifact3)); + assertFalse(artifacts.contains(artifact1)); + assertFalse(artifacts.contains(artifact2)); + } + + public void testExcludeScope() throws Exception { + File testPom = new File(getBasedir(), "target/test-classes/unit/go-offline-test/exclude-plugin-config.xml"); + + subject = (GoOfflineMojo) lookupMojo("go-offline", testPom); + assertNotNull(subject); + + Artifact artifact1 = new ArtifactStub(); + artifact1.setGroupId(VALID_GROUP); + artifact1.setArtifactId(DUMMY_ARTIFACT_NAME); + artifact1.setVersion(STUB_ARTIFACT_VERSION + "-SNAPSHOT"); + + Artifact artifact2 = new ArtifactStub(); + artifact2.setGroupId(VALID_GROUP); + artifact2.setArtifactId(DUMMY_ARTIFACT_NAME + "-too"); + artifact2.setVersion(STUB_ARTIFACT_VERSION); + artifact2.setScope("system"); + + Artifact artifact3 = new ArtifactStub(); + artifact3.setGroupId(VALID_GROUP); + artifact3.setArtifactId(DUMMY_ARTIFACT_NAME); + artifact3.setVersion(STUB_ARTIFACT_VERSION); + + Set artifacts = new HashSet<>(); + artifacts.add(artifact1); + artifacts.add(artifact2); + artifacts.add(artifact3); + + assertEquals(3, artifacts.size()); + FilterArtifacts filter = subject.getArtifactsFilter(); + artifacts = filter.filter(artifacts); + assertEquals(2, artifacts.size()); + assertTrue(artifacts.contains(artifact3)); + assertTrue(artifacts.contains(artifact1)); + assertFalse(artifacts.contains(artifact2)); + } + + public void testExcludeTypes() throws Exception { + File testPom = new File(getBasedir(), "target/test-classes/unit/go-offline-test/exclude-plugin-config.xml"); + + subject = (GoOfflineMojo) lookupMojo("go-offline", testPom); + assertNotNull(subject); + + ArtifactStub artifact1 = new ArtifactStub(); + artifact1.setGroupId(VALID_GROUP); + artifact1.setArtifactId(DUMMY_ARTIFACT_NAME); + artifact1.setVersion(STUB_ARTIFACT_VERSION + "-SNAPSHOT"); + artifact1.setType("ear"); + + ArtifactStub artifact2 = new ArtifactStub(); + artifact2.setGroupId(VALID_GROUP); + artifact2.setArtifactId(DUMMY_ARTIFACT_NAME + "-too"); + artifact2.setVersion(STUB_ARTIFACT_VERSION); + artifact2.setType("war"); + + ArtifactStub artifact3 = new ArtifactStub(); + artifact3.setGroupId(VALID_GROUP); + artifact3.setArtifactId(DUMMY_ARTIFACT_NAME); + artifact3.setVersion(STUB_ARTIFACT_VERSION); + artifact3.setType("pom"); + + Set artifacts = new HashSet<>(); + artifacts.add(artifact1); + artifacts.add(artifact2); + artifacts.add(artifact3); + + assertEquals(3, artifacts.size()); + FilterArtifacts filter = subject.getArtifactsFilter(); + artifacts = filter.filter(artifacts); + assertEquals(1, artifacts.size()); + assertFalse(artifacts.contains(artifact3)); + assertTrue(artifacts.contains(artifact2)); + assertFalse(artifacts.contains(artifact1)); + } + + /** + * Can't set a classifier on the ArtifactStub as of maven-plugin-testing-harness-3.3.0, there is a getter but no + * setter. If that ever gets implemented, comment in these two lines to support unit testing for this case, rename + * xtest to test and remove the Junit 5 Disabled annotation + * + * @throws Exception + */ + @Disabled("Requires update to maven-plugin-test-harness to support this test") + public void xtestExcludeClassifiers() throws Exception { + File testPom = new File(getBasedir(), "target/test-classes/unit/go-offline-test/exclude-plugin-config.xml"); + + subject = (GoOfflineMojo) lookupMojo("go-offline", testPom); + assertNotNull(subject); + + ArtifactStub artifact1 = new ArtifactStub(); + artifact1.setGroupId(VALID_GROUP); + artifact1.setArtifactId(DUMMY_ARTIFACT_NAME); + artifact1.setVersion(STUB_ARTIFACT_VERSION + "-SNAPSHOT"); + // artifact1.setClassifier(CLASSIFIER_EXCLUDE_PREFIX); + + ArtifactStub artifact2 = new ArtifactStub(); + artifact2.setGroupId(VALID_GROUP); + artifact2.setArtifactId(DUMMY_ARTIFACT_NAME + "-too"); + artifact2.setVersion(STUB_ARTIFACT_VERSION); + // artifact2.setClassifier(CLASSIFIER_EXCLUDE_PREFIX + "Too"); + + ArtifactStub artifact3 = new ArtifactStub(); + artifact3.setGroupId(VALID_GROUP); + artifact3.setArtifactId(DUMMY_ARTIFACT_NAME); + artifact3.setVersion(STUB_ARTIFACT_VERSION); + + Set artifacts = new HashSet<>(); + artifacts.add(artifact1); + artifacts.add(artifact2); + artifacts.add(artifact3); + + assertEquals(3, artifacts.size()); + FilterArtifacts filter = subject.getArtifactsFilter(); + artifacts = filter.filter(artifacts); + assertEquals(1, artifacts.size()); + assertFalse(artifacts.contains(artifact1)); + assertFalse(artifacts.contains(artifact2)); + assertTrue(artifacts.contains(artifact3)); + } + + private static final String GROUP_INCLUDE_PREFIX = "include.this.groupid"; + + private static final String ARTIFACT_INCLUDE_PREFIX = "include-this-artifact"; + + private static final String CLASSIFIER_INCLUDE_PREFIX = "includeThisClassifier"; + + public void testIncludeGroupIds() throws Exception { + File testPom = new File(getBasedir(), "target/test-classes/unit/go-offline-test/include-gid-plugin-config.xml"); + + subject = (GoOfflineMojo) lookupMojo("go-offline", testPom); + assertNotNull(subject); + + Artifact artifact1 = new ArtifactStub(); + artifact1.setGroupId(GROUP_INCLUDE_PREFIX); + artifact1.setArtifactId(DUMMY_ARTIFACT_NAME); + artifact1.setVersion(STUB_ARTIFACT_VERSION); + + Artifact artifact2 = new ArtifactStub(); + artifact2.setGroupId(GROUP_INCLUDE_PREFIX + ".too"); + artifact2.setArtifactId(DUMMY_ARTIFACT_NAME); + artifact2.setVersion(STUB_ARTIFACT_VERSION + "-SNAPSHOT"); + + Artifact artifact3 = new ArtifactStub(); + artifact3.setGroupId("skip.me"); + artifact3.setArtifactId(DUMMY_ARTIFACT_NAME); + artifact3.setVersion("1.0"); + + Set artifacts = new HashSet<>(); + artifacts.add(artifact1); + artifacts.add(artifact2); + artifacts.add(artifact3); + + assertEquals(3, artifacts.size()); + FilterArtifacts filter = subject.getArtifactsFilter(); + artifacts = filter.filter(artifacts); + + assertEquals(2, artifacts.size()); + assertFalse(artifacts.contains(artifact3)); + assertTrue(artifacts.contains(artifact1)); + assertTrue(artifacts.contains(artifact2)); + } + + public void testIncludeArtifactIds() throws Exception { + File testPom = new File(getBasedir(), "target/test-classes/unit/go-offline-test/include-aid-plugin-config.xml"); + + subject = (GoOfflineMojo) lookupMojo("go-offline", testPom); + assertNotNull(subject); + + Artifact artifact1 = new ArtifactStub(); + artifact1.setGroupId(VALID_GROUP); + artifact1.setArtifactId(ARTIFACT_INCLUDE_PREFIX); + artifact1.setVersion(STUB_ARTIFACT_VERSION); + + Artifact artifact2 = new ArtifactStub(); + artifact2.setGroupId(VALID_GROUP); + artifact2.setArtifactId(ARTIFACT_INCLUDE_PREFIX + "-too"); + artifact2.setVersion(STUB_ARTIFACT_VERSION + "-SNAPSHOT"); + + Artifact artifact3 = new ArtifactStub(); + artifact3.setGroupId(VALID_GROUP); + artifact3.setArtifactId(DUMMY_ARTIFACT_NAME); + artifact3.setVersion("1.0"); + + Set artifacts = new HashSet<>(); + artifacts.add(artifact1); + artifacts.add(artifact2); + artifacts.add(artifact3); + + assertEquals(3, artifacts.size()); + FilterArtifacts filter = subject.getArtifactsFilter(); + artifacts = filter.filter(artifacts); + + assertEquals(2, artifacts.size()); + assertFalse(artifacts.contains(artifact3)); + assertTrue(artifacts.contains(artifact1)); + assertTrue(artifacts.contains(artifact2)); + } + + public void testIncludeScope() throws Exception { + File testPom = + new File(getBasedir(), "target/test-classes/unit/go-offline-test/include-scope-plugin-config.xml"); + + subject = (GoOfflineMojo) lookupMojo("go-offline", testPom); + assertNotNull(subject); + + Artifact artifact1 = new ArtifactStub(); + artifact1.setGroupId(VALID_GROUP); + artifact1.setArtifactId(DUMMY_ARTIFACT_NAME); + artifact1.setVersion(STUB_ARTIFACT_VERSION + "-SNAPSHOT"); + artifact1.setScope("provided"); + + Artifact artifact2 = new ArtifactStub(); + artifact2.setGroupId(VALID_GROUP); + artifact2.setArtifactId(DUMMY_ARTIFACT_NAME + "-too"); + artifact2.setVersion(STUB_ARTIFACT_VERSION); + artifact2.setScope("system"); + + Artifact artifact3 = new ArtifactStub(); + artifact3.setGroupId(VALID_GROUP); + artifact3.setArtifactId(DUMMY_ARTIFACT_NAME); + artifact3.setVersion(STUB_ARTIFACT_VERSION); + artifact3.setScope("test"); + + Set artifacts = new HashSet<>(); + artifacts.add(artifact1); + artifacts.add(artifact2); + artifacts.add(artifact3); + + assertEquals(3, artifacts.size()); + FilterArtifacts filter = subject.getArtifactsFilter(); + artifacts = filter.filter(artifacts); + assertEquals(1, artifacts.size()); + + assertTrue(artifacts.contains(artifact1)); + assertFalse(artifacts.contains(artifact2)); + assertFalse(artifacts.contains(artifact3)); + } + + public void testIncludeTypes() throws Exception { + File testPom = + new File(getBasedir(), "target/test-classes/unit/go-offline-test/include-types-plugin-config.xml"); + + subject = (GoOfflineMojo) lookupMojo("go-offline", testPom); + assertNotNull(subject); + + ArtifactStub artifact1 = new ArtifactStub(); + artifact1.setGroupId(VALID_GROUP); + artifact1.setArtifactId(DUMMY_ARTIFACT_NAME); + artifact1.setVersion(STUB_ARTIFACT_VERSION + "-SNAPSHOT"); + artifact1.setType("ear"); + + ArtifactStub artifact2 = new ArtifactStub(); + artifact2.setGroupId(VALID_GROUP); + artifact2.setArtifactId(DUMMY_ARTIFACT_NAME + "-too"); + artifact2.setVersion(STUB_ARTIFACT_VERSION); + artifact2.setType("pom"); + + ArtifactStub artifact3 = new ArtifactStub(); + artifact3.setGroupId(VALID_GROUP); + artifact3.setArtifactId(DUMMY_ARTIFACT_NAME); + artifact3.setVersion(STUB_ARTIFACT_VERSION + "-SNAPSHOT"); + artifact3.setType("war"); + + Set artifacts = new HashSet<>(); + artifacts.add(artifact1); + artifacts.add(artifact2); + artifacts.add(artifact3); + + assertEquals(3, artifacts.size()); + FilterArtifacts filter = subject.getArtifactsFilter(); + artifacts = filter.filter(artifacts); + assertEquals(2, artifacts.size()); + + assertTrue(artifacts.contains(artifact1)); + assertTrue(artifacts.contains(artifact2)); + assertFalse(artifacts.contains(artifact3)); + } +} diff --git a/src/test/java/org/apache/maven/plugins/dependency/resolvers/ResolveDependenciesMojoTest.java b/src/test/java/org/apache/maven/plugins/dependency/resolvers/ResolveDependenciesMojoTest.java index 3685035e5..2af967760 100644 --- a/src/test/java/org/apache/maven/plugins/dependency/resolvers/ResolveDependenciesMojoTest.java +++ b/src/test/java/org/apache/maven/plugins/dependency/resolvers/ResolveDependenciesMojoTest.java @@ -21,15 +21,28 @@ import java.io.IOException; import java.util.HashSet; import java.util.Set; + import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.versioning.VersionRange; import org.apache.maven.plugins.dependency.AbstractDependencyMojoTestCase; import org.apache.maven.plugins.dependency.utils.DependencyStatusSets; public class ResolveDependenciesMojoTest extends AbstractDependencyMojoTestCase { + + @Override + protected String getTestDirectoryName() { + return "dss"; + } + + @Override + protected boolean shouldCreateFiles() { + return true; + } + + @Override protected void setUp() throws Exception { // required for mojo lookups to work - super.setUp("dss", true); + super.setUp(); } public void testDependencyStatusLog() throws IOException { @@ -44,7 +57,7 @@ public void testDependencyStatusLogNullFiles() throws IOException { } public void testDependencyStatusEmptySet() { - doTestDependencyStatusLog(new HashSet()); + doTestDependencyStatusLog(new HashSet<>()); } public void testOptionalDependencyFormatting() throws IOException { @@ -59,8 +72,7 @@ public void testOptionalDependencyFormatting() throws IOException { assertTrue(output.contains("g:a:jar:1.0:test (optional)" + System.lineSeparator())); } - public void doTestDependencyStatusLog(Set artifacts) { - // TODO: implement logger to check correct output + private void doTestDependencyStatusLog(Set artifacts) { // this test is just looking for unexpected exceptions. ResolveDependenciesMojo mojo = newMojo(new DependencyStatusSets()); @@ -99,7 +111,7 @@ public void doTestDependencyStatusLog(Set artifacts) { } private ResolveDependenciesMojo newMojo(final DependencyStatusSets dss) { - ResolveDependenciesMojo mojo = new ResolveDependenciesMojo(); + ResolveDependenciesMojo mojo = new ResolveDependenciesMojo(null, null, null, null, null, null); mojo.results = dss; return mojo; } diff --git a/src/test/java/org/apache/maven/plugins/dependency/resolvers/TestResolveMojo.java b/src/test/java/org/apache/maven/plugins/dependency/resolvers/TestResolveMojo.java index 2d38335f9..2a5d2d843 100644 --- a/src/test/java/org/apache/maven/plugins/dependency/resolvers/TestResolveMojo.java +++ b/src/test/java/org/apache/maven/plugins/dependency/resolvers/TestResolveMojo.java @@ -20,17 +20,37 @@ import java.io.File; import java.util.Set; + import org.apache.maven.artifact.Artifact; -import org.apache.maven.plugin.testing.SilentLog; +import org.apache.maven.execution.MavenSession; import org.apache.maven.plugins.dependency.AbstractDependencyMojoTestCase; +import org.apache.maven.plugins.dependency.testUtils.stubs.DependencyProjectStub; +import org.apache.maven.plugins.dependency.utils.DependencySilentLog; import org.apache.maven.plugins.dependency.utils.DependencyStatusSets; import org.apache.maven.project.MavenProject; public class TestResolveMojo extends AbstractDependencyMojoTestCase { + @Override + protected String getTestDirectoryName() { + return "markers"; + } + + @Override + protected boolean shouldCreateFiles() { + return false; + } + + @Override protected void setUp() throws Exception { // required for mojo lookups to work - super.setUp("markers", false); + super.setUp(); + + MavenProject project = new DependencyProjectStub(); + getContainer().addComponent(project, MavenProject.class.getName()); + + MavenSession session = newMavenSession(project); + getContainer().addComponent(session, MavenSession.class.getName()); } /** @@ -38,7 +58,7 @@ protected void setUp() throws Exception { * * @throws Exception in case of errors. */ - public void testresolveTestEnvironment() throws Exception { + public void testResolveTestEnvironment() throws Exception { File testPom = new File(getBasedir(), "target/test-classes/unit/resolve-test/plugin-config.xml"); ResolveDependenciesMojo mojo = (ResolveDependenciesMojo) lookupMojo("resolve", testPom); @@ -46,7 +66,6 @@ public void testresolveTestEnvironment() throws Exception { assertNotNull(mojo.getProject()); MavenProject project = mojo.getProject(); - mojo.setSilent(true); Set artifacts = this.stubFactory.getScopedArtifacts(); Set directArtifacts = this.stubFactory.getReleaseAndSnapshotArtifacts(); artifacts.addAll(directArtifacts); @@ -70,8 +89,13 @@ public void testresolveTestEnvironment() throws Exception { public void testSilent() throws Exception { File testPom = new File(getBasedir(), "target/test-classes/unit/resolve-test/plugin-config.xml"); ResolveDependenciesMojo mojo = (ResolveDependenciesMojo) lookupMojo("resolve", testPom); - mojo.setSilent(false); - assertFalse(mojo.getLog() instanceof SilentLog); + assertFalse(mojo.getLog() instanceof DependencySilentLog); + + mojo.setSilent(true); + assertTrue(mojo.getLog() instanceof DependencySilentLog); + + mojo.setSilent(false); + assertFalse(mojo.getLog() instanceof DependencySilentLog); } // TODO: Test skipping artifacts. } diff --git a/src/test/java/org/apache/maven/plugins/dependency/testUtils/DependencyArtifactStubFactory.java b/src/test/java/org/apache/maven/plugins/dependency/testUtils/DependencyArtifactStubFactory.java index 7c49e44a3..05a52ef97 100644 --- a/src/test/java/org/apache/maven/plugins/dependency/testUtils/DependencyArtifactStubFactory.java +++ b/src/test/java/org/apache/maven/plugins/dependency/testUtils/DependencyArtifactStubFactory.java @@ -23,6 +23,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; + import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.ArtifactUtils; import org.apache.maven.artifact.versioning.VersionRange; @@ -52,8 +53,7 @@ public DependencyArtifactStubFactory(File theWorkingDir, boolean theCreateFiles) } public ArtifactItem getArtifactItem(Artifact artifact) { - ArtifactItem item = new ArtifactItem(artifact); - return item; + return new ArtifactItem(artifact); } public List getArtifactItems(Collection artifacts) { @@ -119,9 +119,7 @@ public void createUnpackableFile(Artifact artifact, File destFile) if (archiver instanceof WarArchiver) { WarArchiver war = (WarArchiver) archiver; - // the use of this is counter-intuitive: - // http://jira.codehaus.org/browse/PLX-286 - war.setIgnoreWebxml(false); + war.setExpectWebXml(false); } archiver.createArchive(); } diff --git a/src/test/java/org/apache/maven/plugins/dependency/testUtils/stubs/DependencyProjectStub.java b/src/test/java/org/apache/maven/plugins/dependency/testUtils/stubs/DependencyProjectStub.java index a3a26f24e..9edcfb354 100644 --- a/src/test/java/org/apache/maven/plugins/dependency/testUtils/stubs/DependencyProjectStub.java +++ b/src/test/java/org/apache/maven/plugins/dependency/testUtils/stubs/DependencyProjectStub.java @@ -19,16 +19,15 @@ package org.apache.maven.plugins.dependency.testUtils.stubs; import java.io.File; -import java.io.IOException; import java.io.Writer; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; + import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.DefaultArtifact; -import org.apache.maven.artifact.DependencyResolutionRequiredException; import org.apache.maven.artifact.factory.ArtifactFactory; import org.apache.maven.artifact.handler.ArtifactHandler; import org.apache.maven.artifact.repository.ArtifactRepository; @@ -58,9 +57,9 @@ import org.apache.maven.model.Scm; import org.apache.maven.plugin.testing.stubs.DefaultArtifactHandlerStub; import org.apache.maven.project.MavenProject; -import org.apache.maven.project.artifact.InvalidDependencyVersionException; import org.codehaus.plexus.PlexusTestCase; import org.codehaus.plexus.util.xml.Xpp3Dom; +import org.eclipse.aether.repository.RemoteRepository; /** * very simple stub of maven project, going to take a lot of work to make it useful as a stub though @@ -160,10 +159,13 @@ public DependencyProjectStub(MavenProject project) { super((Model) null); } - public String getModulePathAdjustment(MavenProject mavenProject) throws IOException { + @Override + @Deprecated + public String getModulePathAdjustment(MavenProject mavenProject) { return ""; } + @Override public Artifact getArtifact() { if (artifact == null) { ArtifactHandler ah = new DefaultArtifactHandlerStub("jar", null); @@ -175,48 +177,65 @@ public Artifact getArtifact() { return artifact; } + @Override public void setArtifact(Artifact artifact) { this.artifact = artifact; } + @Override public Model getModel() { return model; } + @Override public MavenProject getParent() { return parent; } + @Override public void setParent(MavenProject mavenProject) { this.parent = mavenProject; } + @Override public void setRemoteArtifactRepositories(List list) {} + @Override public List getRemoteArtifactRepositories() { return Collections.emptyList(); } + @Override + public List getRemoteProjectRepositories() { + return Collections.emptyList(); + } + + @Override public boolean hasParent() { return (parent != null); } + @Override public File getFile() { return file; } + @Override public void setFile(File file) { this.file = file; } + @Override public File getBasedir() { return new File(PlexusTestCase.getBasedir()); } + @Override public void setDependencies(List list) { dependencies = list; } + @Override public List getDependencies() { if (dependencies == null) { dependencies = Collections.emptyList(); @@ -228,6 +247,7 @@ public void setDependencyManagement(DependencyManagement depMgt) { this.dependencyManagement = depMgt; } + @Override public DependencyManagement getDependencyManagement() { if (dependencyManagement == null) { dependencyManagement = new DependencyManagement(); @@ -236,6 +256,7 @@ public DependencyManagement getDependencyManagement() { return dependencyManagement; } + @Override public void addCompileSourceRoot(String string) { if (compileSourceRoots == null) { compileSourceRoots = Collections.singletonList(string); @@ -244,6 +265,8 @@ public void addCompileSourceRoot(String string) { } } + @Override + @Deprecated public void addScriptSourceRoot(String string) { if (scriptSourceRoots == null) { scriptSourceRoots = Collections.singletonList(string); @@ -252,6 +275,7 @@ public void addScriptSourceRoot(String string) { } } + @Override public void addTestCompileSourceRoot(String string) { if (testCompileSourceRoots == null) { testCompileSourceRoots = Collections.singletonList(string); @@ -260,236 +284,253 @@ public void addTestCompileSourceRoot(String string) { } } + @Override public List getCompileSourceRoots() { return compileSourceRoots; } + @Override + @Deprecated public List getScriptSourceRoots() { return scriptSourceRoots; } + @Override public List getTestCompileSourceRoots() { return testCompileSourceRoots; } - public List getCompileClasspathElements() throws DependencyResolutionRequiredException { + @Override + public List getCompileClasspathElements() { return compileSourceRoots; } - public void setCompileArtifacts(List compileArtifacts) { - this.compileArtifacts = compileArtifacts; - } - + @Override + @Deprecated public List getCompileArtifacts() { return compileArtifacts; } + @Override + @Deprecated public List getCompileDependencies() { return compileDependencies; } - public List getTestClasspathElements() throws DependencyResolutionRequiredException { + @Override + public List getTestClasspathElements() { return testClasspathElements; } + @Override + @Deprecated public List getTestArtifacts() { return testArtifacts; } + @Override + @Deprecated public List getTestDependencies() { return testDependencies; } - public List getRuntimeClasspathElements() throws DependencyResolutionRequiredException { + @Override + public List getRuntimeClasspathElements() { return runtimeClasspathElements; } + @Override + @Deprecated public List getRuntimeArtifacts() { return runtimeArtifacts; } + @Override + @Deprecated public List getRuntimeDependencies() { return runtimeDependencies; } - public List getSystemClasspathElements() throws DependencyResolutionRequiredException { + @Override + @Deprecated + public List getSystemClasspathElements() { return systemClasspathElements; } + @Override + @Deprecated public List getSystemArtifacts() { return systemArtifacts; } - public void setRuntimeClasspathElements(List runtimeClasspathElements) { - this.runtimeClasspathElements = runtimeClasspathElements; - } - + @Override public void setAttachedArtifacts(List attachedArtifacts) { this.attachedArtifacts = attachedArtifacts; } + @Override public void setCompileSourceRoots(List compileSourceRoots) { this.compileSourceRoots = compileSourceRoots; } + @Override public void setTestCompileSourceRoots(List testCompileSourceRoots) { this.testCompileSourceRoots = testCompileSourceRoots; } + @Override + @Deprecated public void setScriptSourceRoots(List scriptSourceRoots) { this.scriptSourceRoots = scriptSourceRoots; } - public void setCompileDependencies(List compileDependencies) { - this.compileDependencies = compileDependencies; - } - - public void setSystemDependencies(List systemDependencies) { - this.systemDependencies = systemDependencies; - } - - public void setTestClasspathElements(List testClasspathElements) { - this.testClasspathElements = testClasspathElements; - } - - public void setTestDependencies(List testDependencies) { - this.testDependencies = testDependencies; - } - - public void setSystemClasspathElements(List systemClasspathElements) { - this.systemClasspathElements = systemClasspathElements; - } - - public void setSystemArtifacts(List systemArtifacts) { - this.systemArtifacts = systemArtifacts; - } - - public void setTestArtifacts(List testArtifacts) { - this.testArtifacts = testArtifacts; - } - - public void setRuntimeArtifacts(List runtimeArtifacts) { - this.runtimeArtifacts = runtimeArtifacts; - } - - public void setRuntimeDependencies(List runtimeDependencies) { - this.runtimeDependencies = runtimeDependencies; - } - + @Override public void setModel(Model model) { this.model = model; } + @Override + @Deprecated public List getSystemDependencies() { return systemDependencies; } + @Override public void setModelVersion(String string) { this.modelVersion = string; } + @Override public String getModelVersion() { return modelVersion; } + @Override public String getId() { return ""; } + @Override public void setGroupId(String string) { this.groupId = string; } + @Override public String getGroupId() { return groupId; } + @Override public void setArtifactId(String string) { this.artifactId = string; } + @Override public String getArtifactId() { return artifactId; } + @Override public void setName(String string) { this.name = string; } + @Override public String getName() { return name; } + @Override public void setVersion(String string) { this.version = string; } + @Override public String getVersion() { return version; } + @Override public String getPackaging() { return packaging; } + @Override public void setPackaging(String string) { this.packaging = string; } + @Override public void setInceptionYear(String string) { this.inceptionYear = string; } + @Override public String getInceptionYear() { return inceptionYear; } + @Override public void setUrl(String string) { this.url = string; } + @Override public String getUrl() { return url; } + @Override public Prerequisites getPrerequisites() { return null; } + @Override public void setIssueManagement(IssueManagement issueManagement) {} + @Override public CiManagement getCiManagement() { return null; } + @Override public void setCiManagement(CiManagement ciManagement) {} + @Override public IssueManagement getIssueManagement() { return null; } + @Override public void setDistributionManagement(DistributionManagement distributionManagement) {} + @Override public DistributionManagement getDistributionManagement() { return null; } + @Override public void setDescription(String string) { this.description = string; } + @Override public String getDescription() { return description; } + @Override public void setOrganization(Organization organization) {} + @Override public Organization getOrganization() { return null; } + @Override public void setScm(Scm scm) {} + @Override public Scm getScm() { return null; } @@ -497,65 +538,87 @@ public Scm getScm() { @Override public void setMailingLists(List list) {} + @Override public List getMailingLists() { return Collections.emptyList(); } + @Override public void addMailingList(MailingList mailingList) {} @Override public void setDevelopers(List list) {} + @Override public List getDevelopers() { return Collections.emptyList(); } + @Override public void addDeveloper(Developer developer) {} + @Override public void setContributors(List list) {} + @Override public List getContributors() { return Collections.emptyList(); } + @Override public void addContributor(Contributor contributor) {} + @Override public void setBuild(Build build) {} + @Override public Build getBuild() { return null; } + @Override public List getResources() { return Collections.emptyList(); } + @Override public List getTestResources() { return Collections.emptyList(); } + @Override public void addResource(Resource resource) {} + @Override public void addTestResource(Resource resource) {} + @Override + @Deprecated public void setReporting(Reporting reporting) {} + @Override + @Deprecated public Reporting getReporting() { return null; } + @Override public void setLicenses(List list) {} + @Override public List getLicenses() { return Collections.emptyList(); } + @Override public void addLicense(License license) {} + @Override public void setArtifacts(Set set) { this.artifacts = set; } + @Override public Set getArtifacts() { if (artifacts == null) { return Collections.emptySet(); @@ -564,102 +627,130 @@ public Set getArtifacts() { } } + @Override public Map getArtifactMap() { return Collections.emptyMap(); } + @Override public void setPluginArtifacts(Set set) {} + @Override public Set getPluginArtifacts() { return Collections.emptySet(); } + @Override public Map getPluginArtifactMap() { return Collections.emptyMap(); } + @Override + @Deprecated public void setReportArtifacts(Set set) {} + @Override + @Deprecated public Set getReportArtifacts() { return Collections.emptySet(); } + @Override public Map getReportArtifactMap() { return Collections.emptyMap(); } + @Override + @Deprecated public void setExtensionArtifacts(Set set) {} + @Override + @Deprecated public Set getExtensionArtifacts() { return Collections.emptySet(); } + @Override + @Deprecated public Map getExtensionArtifactMap() { return Collections.emptyMap(); } + @Override public void setParentArtifact(Artifact artifact) {} + @Override public Artifact getParentArtifact() { return null; } + @Override public List getRepositories() { return Collections.emptyList(); } + @Override + @Deprecated public List getReportPlugins() { return Collections.emptyList(); } + @Override public List getBuildPlugins() { return Collections.emptyList(); } + @Override public List getModules() { return Collections.singletonList(""); } + @Override public PluginManagement getPluginManagement() { return null; } - public void addPlugin(Plugin plugin) {} - - public void injectPluginManagementInfo(Plugin plugin) {} - + @Override public List getCollectedProjects() { return collectedProjects; } + @Override public void setCollectedProjects(List list) { this.collectedProjects = list; } + @Override public void setPluginArtifactRepositories(List list) { this.pluginArtifactRepositories = list; } + @Override public List getPluginArtifactRepositories() { return pluginArtifactRepositories; } + @Override public ArtifactRepository getDistributionManagementArtifactRepository() { return null; } + @Override public List getPluginRepositories() { return Collections.emptyList(); } + @Override public void setActiveProfiles(List list) { activeProfiles = list; } + @Override public List getActiveProfiles() { return activeProfiles; } + @Override public void addAttachedArtifact(Artifact theArtifact) { if (attachedArtifacts == null) { this.attachedArtifacts = Collections.singletonList(theArtifact); @@ -668,66 +759,88 @@ public void addAttachedArtifact(Artifact theArtifact) { } } + @Override public List getAttachedArtifacts() { return attachedArtifacts; } + @Override public Xpp3Dom getGoalConfiguration(String string, String string1, String string2, String string3) { return null; } + @Override + @Deprecated public Xpp3Dom getReportConfiguration(String string, String string1, String string2) { return null; } + @Override public MavenProject getExecutionProject() { return null; } + @Override public void setExecutionProject(MavenProject mavenProject) {} - public void writeModel(Writer writer) throws IOException {} + @Override + @Deprecated + public void writeModel(Writer writer) {} - public void writeOriginalModel(Writer writer) throws IOException {} + @Override + @Deprecated + public void writeOriginalModel(Writer writer) {} + @Override public Set getDependencyArtifacts() { return dependencyArtifacts; } + @Override public void setDependencyArtifacts(Set set) { this.dependencyArtifacts = set; } + @Override public void setReleaseArtifactRepository(ArtifactRepository artifactRepository) { // this.releaseArtifactRepository = artifactRepository; } + @Override public void setSnapshotArtifactRepository(ArtifactRepository artifactRepository) { // this.snapshotArtifactRepository = artifactRepository; } + @Override public void setOriginalModel(Model model) { this.originalModel = model; } + @Override public Model getOriginalModel() { return originalModel; } + @Override public List getBuildExtensions() { return Collections.emptyList(); } @Override - public Set createArtifacts(ArtifactFactory artifactFactory, String string, ArtifactFilter artifactFilter) - throws InvalidDependencyVersionException { + @Deprecated + public Set createArtifacts( + ArtifactFactory artifactFactory, String string, ArtifactFilter artifactFilter) { return Collections.emptySet(); } + @Override public void addProjectReference(MavenProject mavenProject) {} + @Override + @Deprecated public void attachArtifact(String string, String string1, File theFile) {} + @Override public Properties getProperties() { if (properties == null) { properties = new Properties(); @@ -735,26 +848,33 @@ public Properties getProperties() { return properties; } + @Override public List getFilters() { return Collections.singletonList(""); } + @Override public Map getProjectReferences() { return Collections.emptyMap(); } + @Override public boolean isExecutionRoot() { return executionRoot; } + @Override public void setExecutionRoot(boolean b) { this.executionRoot = b; } + @Override public String getDefaultGoal() { return defaultGoal; } + @Override + @Deprecated public Artifact replaceWithActiveArtifact(Artifact theArtifact) { return null; } diff --git a/src/test/java/org/apache/maven/plugins/dependency/testUtils/stubs/DuplicateDependencies2ProjectStub.java b/src/test/java/org/apache/maven/plugins/dependency/testUtils/stubs/DuplicateDependencies2ProjectStub.java index e4e779b58..a9c528382 100644 --- a/src/test/java/org/apache/maven/plugins/dependency/testUtils/stubs/DuplicateDependencies2ProjectStub.java +++ b/src/test/java/org/apache/maven/plugins/dependency/testUtils/stubs/DuplicateDependencies2ProjectStub.java @@ -21,6 +21,7 @@ import java.io.File; import java.io.FileInputStream; import java.io.IOException; + import org.apache.maven.model.Model; import org.apache.maven.model.io.xpp3.MavenXpp3Reader; import org.apache.maven.plugin.testing.stubs.MavenProjectStub; diff --git a/src/test/java/org/apache/maven/plugins/dependency/testUtils/stubs/DuplicateDependenciesProjectStub.java b/src/test/java/org/apache/maven/plugins/dependency/testUtils/stubs/DuplicateDependenciesProjectStub.java index 9c0c5af5a..662248dd7 100644 --- a/src/test/java/org/apache/maven/plugins/dependency/testUtils/stubs/DuplicateDependenciesProjectStub.java +++ b/src/test/java/org/apache/maven/plugins/dependency/testUtils/stubs/DuplicateDependenciesProjectStub.java @@ -21,6 +21,7 @@ import java.io.File; import java.io.FileInputStream; import java.io.IOException; + import org.apache.maven.model.Model; import org.apache.maven.model.io.xpp3.MavenXpp3Reader; import org.apache.maven.plugin.testing.stubs.MavenProjectStub; diff --git a/src/test/java/org/apache/maven/plugins/dependency/testUtils/stubs/StubDefaultFileMarkerHandler.java b/src/test/java/org/apache/maven/plugins/dependency/testUtils/stubs/StubDefaultFileMarkerHandler.java index 199664fab..038ad5bca 100644 --- a/src/test/java/org/apache/maven/plugins/dependency/testUtils/stubs/StubDefaultFileMarkerHandler.java +++ b/src/test/java/org/apache/maven/plugins/dependency/testUtils/stubs/StubDefaultFileMarkerHandler.java @@ -19,6 +19,7 @@ package org.apache.maven.plugins.dependency.testUtils.stubs; import java.io.File; + import org.apache.maven.artifact.Artifact; import org.apache.maven.plugins.dependency.utils.markers.DefaultFileMarkerHandler; diff --git a/src/test/java/org/apache/maven/plugins/dependency/testUtils/stubs/StubSourcesFileMarkerHandler.java b/src/test/java/org/apache/maven/plugins/dependency/testUtils/stubs/StubSourcesFileMarkerHandler.java index 22ab432cc..8d41c8d47 100644 --- a/src/test/java/org/apache/maven/plugins/dependency/testUtils/stubs/StubSourcesFileMarkerHandler.java +++ b/src/test/java/org/apache/maven/plugins/dependency/testUtils/stubs/StubSourcesFileMarkerHandler.java @@ -19,6 +19,7 @@ package org.apache.maven.plugins.dependency.testUtils.stubs; import java.io.File; + import org.apache.maven.artifact.Artifact; import org.apache.maven.plugins.dependency.utils.markers.SourcesFileMarkerHandler; diff --git a/src/test/java/org/apache/maven/plugins/dependency/testUtils/stubs/StubUnpackFileMarkerHandler.java b/src/test/java/org/apache/maven/plugins/dependency/testUtils/stubs/StubUnpackFileMarkerHandler.java index dab1ebec8..cbb49f8f7 100644 --- a/src/test/java/org/apache/maven/plugins/dependency/testUtils/stubs/StubUnpackFileMarkerHandler.java +++ b/src/test/java/org/apache/maven/plugins/dependency/testUtils/stubs/StubUnpackFileMarkerHandler.java @@ -19,30 +19,31 @@ package org.apache.maven.plugins.dependency.testUtils.stubs; import java.io.File; + import org.apache.maven.plugins.dependency.fromConfiguration.ArtifactItem; import org.apache.maven.plugins.dependency.utils.markers.UnpackFileMarkerHandler; -import org.codehaus.plexus.util.StringUtils; public class StubUnpackFileMarkerHandler extends UnpackFileMarkerHandler { public StubUnpackFileMarkerHandler(ArtifactItem artifactItem, File markerFilesDirectory) { super(artifactItem, markerFilesDirectory); } + @Override protected File getMarkerFile() { File markerFile; if (this.artifactItem == null - || (StringUtils.isEmpty(this.artifactItem.getIncludes()) - && StringUtils.isEmpty(this.artifactItem.getExcludes()))) { + || this.artifactItem.getIncludes().isEmpty() + && this.artifactItem.getExcludes().isEmpty()) { markerFile = new StubMarkerFile( this.markerFilesDirectory, this.artifact.getId().replace(':', '-') + ".marker"); } else { int includeExcludeHash = 0; - if (StringUtils.isNotEmpty(this.artifactItem.getIncludes())) { + if (!this.artifactItem.getIncludes().isEmpty()) { includeExcludeHash += this.artifactItem.getIncludes().hashCode(); } - if (StringUtils.isNotEmpty(this.artifactItem.getExcludes())) { + if (!this.artifactItem.getExcludes().isEmpty()) { includeExcludeHash += this.artifactItem.getExcludes().hashCode(); } diff --git a/src/test/java/org/apache/maven/plugins/dependency/tree/TestTreeMojo.java b/src/test/java/org/apache/maven/plugins/dependency/tree/TestTreeMojo.java index 95d4f7da9..b34fa55b4 100644 --- a/src/test/java/org/apache/maven/plugins/dependency/tree/TestTreeMojo.java +++ b/src/test/java/org/apache/maven/plugins/dependency/tree/TestTreeMojo.java @@ -18,16 +18,33 @@ */ package org.apache.maven.plugins.dependency.tree; -import java.io.BufferedReader; import java.io.File; -import java.io.FileReader; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.StringReader; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; import java.util.List; import java.util.Set; +import java.util.stream.Collectors; + +import jakarta.json.Json; +import jakarta.json.JsonArray; +import jakarta.json.JsonObject; +import jakarta.json.JsonReader; import org.apache.maven.artifact.Artifact; +import org.apache.maven.execution.MavenSession; +import org.apache.maven.plugin.LegacySupport; +import org.apache.maven.plugin.testing.stubs.MavenProjectStub; import org.apache.maven.plugins.dependency.AbstractDependencyMojoTestCase; import org.apache.maven.project.MavenProject; import org.apache.maven.shared.dependency.graph.DependencyNode; +import org.apache.maven.shared.dependency.graph.internal.DefaultDependencyNode; /** * Tests TreeMojo. @@ -39,26 +56,43 @@ public class TestTreeMojo extends AbstractDependencyMojoTestCase { // TestCase methods ------------------------------------------------------- + @Override + protected String getTestDirectoryName() { + return "tree"; + } + + @Override + protected boolean shouldUseFlattenedPath() { + return false; + } + /* * @see org.apache.maven.plugin.testing.AbstractMojoTestCase#setUp() */ + @Override protected void setUp() throws Exception { // required for mojo lookups to work - super.setUp("tree", false); - } + super.setUp(); - // tests ------------------------------------------------------------------ + MavenProject project = new MavenProjectStub(); + getContainer().addComponent(project, MavenProject.class.getName()); + + MavenSession session = newMavenSession(project); + getContainer().addComponent(session, MavenSession.class.getName()); - public void testVoid() { - // TODO: tests disabled during MDEP-339 work, to be reactivated + LegacySupport legacySupport = lookup(LegacySupport.class); + legacySupport.setSession(session); + installLocalRepository(legacySupport); } + // tests ------------------------------------------------------------------ + /** * Tests the proper discovery and configuration of the mojo. * * @throws Exception in case of an error. */ - public void _testTreeTestEnvironment() throws Exception { + public void testTreeTestEnvironment() throws Exception { File testPom = new File(getBasedir(), "target/test-classes/unit/tree-test/plugin-config.xml"); TreeMojo mojo = (TreeMojo) lookupMojo("tree", testPom); @@ -79,8 +113,14 @@ public void _testTreeTestEnvironment() throws Exception { DependencyNode rootNode = mojo.getDependencyGraph(); assertNodeEquals("testGroupId:project:jar:1.0:compile", rootNode); assertEquals(2, rootNode.getChildren().size()); - assertChildNodeEquals("testGroupId:snapshot:jar:2.0-SNAPSHOT:compile", rootNode, 0); - assertChildNodeEquals("testGroupId:release:jar:1.0:compile", rootNode, 1); + + List actualNodes = Arrays.asList( + createArtifactCoordinateString(rootNode.getChildren().get(0)), + createArtifactCoordinateString(rootNode.getChildren().get(1))); + List expectedNodes = + Arrays.asList("testGroupId:release:jar:1.0:compile", "testGroupId:snapshot:jar:2.0-SNAPSHOT:compile"); + + assertTrue(expectedNodes.containsAll(actualNodes)); } /** @@ -88,7 +128,7 @@ public void _testTreeTestEnvironment() throws Exception { * * @throws Exception in case of an error. */ - public void _testTreeDotSerializing() throws Exception { + public void testTreeDotSerializing() throws Exception { List contents = runTreeMojo("tree1.dot", "dot"); assertTrue(findString(contents, "digraph \"testGroupId:project:jar:1.0:compile\" {")); assertTrue(findString( @@ -103,7 +143,7 @@ public void _testTreeDotSerializing() throws Exception { * * @throws Exception in case of an error. */ - public void _testTreeGraphMLSerializing() throws Exception { + public void testTreeGraphMLSerializing() throws Exception { List contents = runTreeMojo("tree1.graphml", "graphml"); assertTrue(findString(contents, "")); @@ -119,13 +159,87 @@ public void _testTreeGraphMLSerializing() throws Exception { * * @throws Exception in case of an error. */ - public void _testTreeTGFSerializing() throws Exception { + public void testTreeTGFSerializing() throws Exception { List contents = runTreeMojo("tree1.tgf", "tgf"); assertTrue(findString(contents, "testGroupId:project:jar:1.0:compile")); assertTrue(findString(contents, "testGroupId:snapshot:jar:2.0-SNAPSHOT:compile")); assertTrue(findString(contents, "testGroupId:release:jar:1.0:compile")); } + /** + * Test the JSON format serialization on DependencyNodes with circular dependence + */ + public void testTreeJsonCircularDependency() throws IOException { + String outputFileName = testDir.getAbsolutePath() + File.separator + "tree1.json"; + File outputFile = new File(outputFileName); + Files.createDirectories(outputFile.getParentFile().toPath()); + outputFile.createNewFile(); + + Artifact artifact1 = this.stubFactory.createArtifact("testGroupId", "project1", "1.0"); + Artifact artifact2 = this.stubFactory.createArtifact("testGroupId", "project2", "1.0"); + DefaultDependencyNode node1 = new DefaultDependencyNode(artifact1); + DefaultDependencyNode node2 = new DefaultDependencyNode(artifact2); + + node1.setChildren(new ArrayList()); + node2.setChildren(new ArrayList()); + + node1.getChildren().add(node2); + node2.getChildren().add(node1); + + try (OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream(outputFile))) { + JsonDependencyNodeVisitor jsonDependencyNodeVisitor = new JsonDependencyNodeVisitor(outputStreamWriter); + + jsonDependencyNodeVisitor.visit(node1); + } + } + + /* + * Test parsing of Json output and verify all key-value pairs + */ + public void testTreeJsonParsing() throws Exception { + List contents = runTreeMojo("tree2.json", "json"); + + System.setProperty("jakarta.json.provider", "org.glassfish.json.JsonProviderImpl"); + try (JsonReader reader = Json.createReader(new StringReader(String.join(System.lineSeparator(), contents)))) { + JsonObject root = reader.readObject(); + + assertEquals(root.getString("groupId"), "testGroupId"); + assertEquals(root.getString("artifactId"), "project"); + assertEquals(root.getString("version"), "1.0"); + assertEquals(root.getString("type"), "jar"); + assertEquals(root.getString("scope"), "compile"); + assertEquals(root.getString("classifier"), ""); + assertEquals(root.getString("optional"), "false"); + + JsonArray children = root.getJsonArray("children"); + assertEquals(children.size(), 2); + + List sortedChildren = children.stream() + .map(JsonObject.class::cast) + .sorted(Comparator.comparing(child -> child.getString("artifactId"))) + .collect(Collectors.toList()); + + // Now that children are sorted, we can assert their values in a fixed order + JsonObject child0 = sortedChildren.get(0); + assertEquals(child0.getString("groupId"), "testGroupId"); + assertEquals(child0.getString("artifactId"), "release"); + assertEquals(child0.getString("version"), "1.0"); + assertEquals(child0.getString("type"), "jar"); + assertEquals(child0.getString("scope"), "compile"); + assertEquals(child0.getString("classifier"), ""); + assertEquals(child0.getString("optional"), "false"); + + JsonObject child1 = sortedChildren.get(1); + assertEquals(child1.getString("groupId"), "testGroupId"); + assertEquals(child1.getString("artifactId"), "snapshot"); + assertEquals(child1.getString("version"), "2.0-SNAPSHOT"); + assertEquals(child1.getString("type"), "jar"); + assertEquals(child1.getString("scope"), "compile"); + assertEquals(child1.getString("classifier"), ""); + assertEquals(child1.getString("optional"), "false"); + } + } + /** * Help finding content in the given list of string * @@ -136,10 +250,11 @@ public void _testTreeTGFSerializing() throws Exception { */ private List runTreeMojo(String outputFile, String format) throws Exception { File testPom = new File(getBasedir(), "target/test-classes/unit/tree-test/plugin-config.xml"); - String outputFileName = testDir.getAbsolutePath() + outputFile; + Path outputFilePath = Paths.get(testDir.getAbsolutePath(), outputFile); TreeMojo mojo = (TreeMojo) lookupMojo("tree", testPom); + setVariableValueToObject(mojo, "outputEncoding", "UTF-8"); setVariableValueToObject(mojo, "outputType", format); - setVariableValueToObject(mojo, "outputFile", new File(outputFileName)); + setVariableValueToObject(mojo, "outputFile", outputFilePath.toFile()); assertNotNull(mojo); assertNotNull(mojo.getProject()); @@ -155,14 +270,7 @@ private List runTreeMojo(String outputFile, String format) throws Except mojo.execute(); - BufferedReader fp1 = new BufferedReader(new FileReader(outputFileName)); - List contents = new ArrayList<>(); - - String line; - while ((line = fp1.readLine()) != null) { - contents.add(line); - } - fp1.close(); + List contents = Files.readAllLines(outputFilePath); return contents; } @@ -187,12 +295,6 @@ private boolean findString(List contents, String str) { // private methods -------------------------------------------------------- - private void assertChildNodeEquals(String expectedNode, DependencyNode actualParentNode, int actualChildIndex) { - DependencyNode actualNode = actualParentNode.getChildren().get(actualChildIndex); - - assertNodeEquals(expectedNode, actualNode); - } - private void assertNodeEquals(String expectedNode, DependencyNode actualNode) { String[] tokens = expectedNode.split(":"); @@ -214,4 +316,12 @@ private void assertNodeEquals( assertEquals("version", expectedVersion, actualArtifact.getVersion()); assertEquals("scope", expectedScope, actualArtifact.getScope()); } + + private String createArtifactCoordinateString(DependencyNode actualNode) { + return actualNode.getArtifact().getGroupId() + ":" + + actualNode.getArtifact().getArtifactId() + ":" + + actualNode.getArtifact().getType() + ":" + + actualNode.getArtifact().getVersion() + ":" + + actualNode.getArtifact().getScope(); + } } diff --git a/src/test/java/org/apache/maven/plugins/dependency/tree/TestTreeMojo_ContainsVersion.java b/src/test/java/org/apache/maven/plugins/dependency/tree/TestTreeMojo_ContainsVersion.java deleted file mode 100644 index ff90ca33a..000000000 --- a/src/test/java/org/apache/maven/plugins/dependency/tree/TestTreeMojo_ContainsVersion.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.maven.plugins.dependency.tree; - -import static org.apache.maven.plugins.dependency.tree.TreeMojo.containsVersion; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import java.util.Collections; -import junit.framework.TestCase; -import org.apache.maven.artifact.versioning.ArtifactVersion; -import org.apache.maven.artifact.versioning.Restriction; -import org.apache.maven.artifact.versioning.VersionRange; - -/** - * Tests TreeMojo.containsVersion. - */ -public class TestTreeMojo_ContainsVersion extends TestCase { - private VersionRange range = mock(VersionRange.class); - - private ArtifactVersion version = mock(ArtifactVersion.class); - - public void testWhenRecommendedVersionIsNullAndNoRestrictions() { - when(range.getRecommendedVersion()).thenReturn(null); - when(range.getRestrictions()).thenReturn(Collections.emptyList()); - - @SuppressWarnings("deprecation") - boolean doesItContain = containsVersion(range, version); - - assertFalse(doesItContain); - } -} diff --git a/src/test/java/org/apache/maven/plugins/dependency/utils/ResolverUtilTest.java b/src/test/java/org/apache/maven/plugins/dependency/utils/ResolverUtilTest.java new file mode 100644 index 000000000..4359c6949 --- /dev/null +++ b/src/test/java/org/apache/maven/plugins/dependency/utils/ResolverUtilTest.java @@ -0,0 +1,108 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.maven.plugins.dependency.utils; + +import javax.inject.Provider; + +import java.util.stream.Stream; + +import org.apache.maven.execution.MavenExecutionRequest; +import org.apache.maven.execution.MavenSession; +import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.repository.RemoteRepository; +import org.eclipse.aether.repository.RepositoryPolicy; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.junit.jupiter.params.provider.Arguments.of; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +class ResolverUtilTest { + + @Mock + private MavenExecutionRequest executionRequest; + + @Mock + private RepositorySystemSession repositorySystemSession; + + @Mock + private MavenSession mavenSession; + + @Mock + private Provider sessionProvider; + + @InjectMocks + private ResolverUtil resolverUtil; + + public static Stream prepareRepositoryTest() { + + return Stream.of( + of("", "temp", "default", ""), + of("https://repo.maven.apache.org", "temp", "default", "https://repo.maven.apache.org"), + of("central::https://repo.maven.apache.org", "central", "default", "https://repo.maven.apache.org"), + of("central::::https://repo.maven.apache.org", "central", "default", "https://repo.maven.apache.org"), + of( + "central::layout2::https://repo.maven.apache.org", + "central", + "layout2", + "https://repo.maven.apache.org")); + } + + @ParameterizedTest + @MethodSource + void prepareRepositoryTest(String repository, String id, String type, String url) { + when(sessionProvider.get()).thenReturn(mavenSession); + when(mavenSession.getRepositorySession()).thenReturn(repositorySystemSession); + when(mavenSession.getRequest()).thenReturn(executionRequest); + when(executionRequest.isUpdateSnapshots()).thenReturn(true); + + RemoteRepository remoteRepository = resolverUtil.prepareRemoteRepository(repository); + + assertThat(remoteRepository).isNotNull(); + assertThat(remoteRepository.getId()).isEqualTo(id); + assertThat(remoteRepository.getContentType()).isEqualTo(type); + assertThat(remoteRepository.getUrl()).isEqualTo(url); + + RepositoryPolicy snapshotPolicy = remoteRepository.getPolicy(true); + assertThat(snapshotPolicy).isNotNull(); + assertThat(snapshotPolicy.getUpdatePolicy()).isEqualTo(RepositoryPolicy.UPDATE_POLICY_ALWAYS); + assertThat(snapshotPolicy.getChecksumPolicy()).isEqualTo(RepositoryPolicy.CHECKSUM_POLICY_WARN); + + RepositoryPolicy releasePolicy = remoteRepository.getPolicy(true); + assertThat(releasePolicy).isNotNull(); + assertThat(releasePolicy.getUpdatePolicy()).isEqualTo(RepositoryPolicy.UPDATE_POLICY_ALWAYS); + assertThat(releasePolicy.getChecksumPolicy()).isEqualTo(RepositoryPolicy.CHECKSUM_POLICY_WARN); + } + + @Test + void prepareRepositoryWithNull() { + assertThatCode(() -> resolverUtil.prepareRemoteRepository(null)) + .isExactlyInstanceOf(NullPointerException.class) + .hasMessage("repository must be not null"); + } +} diff --git a/src/test/java/org/apache/maven/plugins/dependency/utils/TestDependencyStatusSets.java b/src/test/java/org/apache/maven/plugins/dependency/utils/TestDependencyStatusSets.java index 7da3810f7..58b33a84a 100644 --- a/src/test/java/org/apache/maven/plugins/dependency/utils/TestDependencyStatusSets.java +++ b/src/test/java/org/apache/maven/plugins/dependency/utils/TestDependencyStatusSets.java @@ -22,9 +22,20 @@ public class TestDependencyStatusSets extends AbstractDependencyMojoTestCase { + @Override + protected String getTestDirectoryName() { + return "dss"; + } + + @Override + protected boolean shouldCreateFiles() { + return true; + } + + @Override protected void setUp() throws Exception { // required for mojo lookups to work - super.setUp("dss", true); + super.setUp(); } public void testDependencyStatusSettersGetters() { diff --git a/src/test/java/org/apache/maven/plugins/dependency/utils/TestDependencyUtil.java b/src/test/java/org/apache/maven/plugins/dependency/utils/TestDependencyUtil.java index 8302b70f5..8de8ce0d4 100644 --- a/src/test/java/org/apache/maven/plugins/dependency/utils/TestDependencyUtil.java +++ b/src/test/java/org/apache/maven/plugins/dependency/utils/TestDependencyUtil.java @@ -19,28 +19,31 @@ package org.apache.maven.plugins.dependency.utils; import java.io.File; -import java.util.ArrayList; -import java.util.List; -import java.util.Random; -import junit.framework.TestCase; +import java.io.IOException; + import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.DefaultArtifact; import org.apache.maven.artifact.handler.ArtifactHandler; import org.apache.maven.artifact.versioning.VersionRange; -import org.apache.maven.plugin.logging.Log; -import org.apache.maven.plugin.testing.SilentLog; import org.apache.maven.plugin.testing.stubs.DefaultArtifactHandlerStub; -import org.codehaus.plexus.util.StringUtils; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; /** * @author brianf */ -public class TestDependencyUtil extends TestCase { - List artifacts = new ArrayList<>(); +class TestDependencyUtil { - Log log = new SilentLog(); + private static final String TEST_CONTENT = + "Test line 1" + System.lineSeparator() + "Test line 2" + System.lineSeparator(); - File outputFolder; + @TempDir + File temDir; Artifact snap; @@ -50,40 +53,31 @@ public class TestDependencyUtil extends TestCase { Artifact sources; - @Override - protected void setUp() throws Exception { - super.setUp(); + @BeforeEach + protected void setUp() { ArtifactHandler ah = new DefaultArtifactHandlerStub("jar", null); VersionRange vr = VersionRange.createFromVersion("1.1"); release = new DefaultArtifact("test", "one", vr, Artifact.SCOPE_COMPILE, "jar", "sources", ah, false); - artifacts.add(release); ah = new DefaultArtifactHandlerStub("war", null); vr = VersionRange.createFromVersion("1.1-SNAPSHOT"); snap = new DefaultArtifact("test", "two", vr, Artifact.SCOPE_PROVIDED, "war", null, ah, false); - artifacts.add(snap); ah = new DefaultArtifactHandlerStub("war", null); vr = VersionRange.createFromVersion("1.1-SNAPSHOT"); snapResolvedVersion = new DefaultArtifact("test", "three", vr, Artifact.SCOPE_PROVIDED, "war", null, ah, false); snapResolvedVersion.setResolvedVersion("1.1-20121003.035531-117"); - artifacts.add(snapResolvedVersion); ah = new DefaultArtifactHandlerStub("war", null); vr = VersionRange.createFromVersion("1.1-SNAPSHOT"); sources = new DefaultArtifact("test", "two", vr, Artifact.SCOPE_PROVIDED, "sources", "sources", ah, false); - - // pick random output location - Random a = new Random(); - outputFolder = new File("target/copy" + a.nextLong() + "/"); - outputFolder.delete(); - assertFalse(outputFolder.exists()); } - public void testDirectoryName() { + @Test + void testDirectoryName() { File folder = new File("target/a"); - final Artifact artifact = artifacts.get(0); + final Artifact artifact = release; File name = DependencyUtil.getFormattedOutputDirectory(false, false, false, false, false, false, folder, artifact); // object is the same. @@ -153,9 +147,10 @@ public void testDirectoryName() { assertEquals(expectedResult, name.getAbsolutePath()); } - public void testDirectoryName2() { + @Test + void testDirectoryName2() { File folder = new File("target/a"); - final Artifact artifact = artifacts.get(1); + final Artifact artifact = snap; File name = DependencyUtil.getFormattedOutputDirectory(false, false, false, false, false, false, folder, artifact); // object is the same. @@ -205,7 +200,8 @@ public void testDirectoryName2() { assertEquals(expectedResult, name.getAbsolutePath()); } - public void testDirectoryNameSources() { + @Test + void testDirectoryNameSources() { File folder = new File("target/a"); File name = DependencyUtil.getFormattedOutputDirectory(false, false, true, false, true, false, folder, sources); String expectedResult = folder.getAbsolutePath() + File.separatorChar + "two-sources"; @@ -224,8 +220,9 @@ public void testDirectoryNameSources() { assertEquals(expectedResult, name.getAbsolutePath()); } - public void testFileName() { - Artifact artifact = artifacts.get(0); + @Test + void testFileName() { + Artifact artifact = release; String name = DependencyUtil.getFormattedFileName(artifact, false); String expectedResult = "one-1.1-sources.jar"; @@ -235,7 +232,8 @@ public void testFileName() { assertEquals(expectedResult, name); } - public void testFileNameUseBaseVersion() { + @Test + void testFileNameUseBaseVersion() { Artifact artifact = snapResolvedVersion; String name = DependencyUtil.getFormattedFileName(artifact, false, false, true); @@ -246,7 +244,8 @@ public void testFileNameUseBaseVersion() { assertEquals(expectedResult, name); } - public void testTestJar() { + @Test + void testTestJar() { ArtifactHandler ah = new DefaultArtifactHandlerStub("test-jar", null); VersionRange vr = VersionRange.createFromVersion("1.1-SNAPSHOT"); Artifact artifact = @@ -257,7 +256,8 @@ public void testTestJar() { assertEquals(expectedResult, name); } - public void testFileNameClassifier() { + @Test + void testFileNameClassifier() { ArtifactHandler ah = new DefaultArtifactHandlerStub("jar", "sources"); VersionRange vr = VersionRange.createFromVersion("1.1-SNAPSHOT"); Artifact artifact = @@ -282,7 +282,8 @@ public void testFileNameClassifier() { assertEquals(expectedResult, name); } - public void testFileNameClassifierWithFile() { + @Test + void testFileNameClassifierWithFile() { // specifically testing the default operation that getFormattedFileName // returns // the actual name of the file if available unless remove version is @@ -319,22 +320,27 @@ public void testFileNameClassifierWithFile() { assertEquals(expectedResult, name); } - public void testTokenizer() { - String[] tokens = DependencyUtil.tokenizer(" alpha,bravo, charlie , delta kappa, theta"); - String[] expected = new String[] {"alpha", "bravo", "charlie", "delta kappa", "theta"}; - // easier to see in the JUnit reports - assertEquals(StringUtils.join(expected, ", "), StringUtils.join(tokens, ", ")); - assertEquals(expected.length, tokens.length); + @Test + void outputFileShouldBeOverridden() throws IOException { + File file = new File(temDir, "file1.out"); + assertThat(file).doesNotExist(); + + DependencyUtil.write(TEST_CONTENT, file, false, "UTF-8"); + assertThat(file).hasContent(TEST_CONTENT); + + DependencyUtil.write(TEST_CONTENT, file, false, "UTF-8"); + assertThat(file).hasContent(TEST_CONTENT); + } - tokens = DependencyUtil.tokenizer(" \r\n a, \t \n \r b \t \n \r"); - assertEquals(2, tokens.length); - assertEquals("a", tokens[0]); - assertEquals("b", tokens[1]); + @Test + void outputFileShouldBeAppended() throws IOException { + File file = new File(temDir, "file2.out"); + assertThat(file).doesNotExist(); - tokens = DependencyUtil.tokenizer(null); - assertEquals(0, tokens.length); + DependencyUtil.write(TEST_CONTENT, file, true, "UTF-8"); + assertThat(file).hasContent(TEST_CONTENT); - tokens = DependencyUtil.tokenizer(" "); - assertEquals(0, tokens.length); + DependencyUtil.write(TEST_CONTENT, file, true, "UTF-8"); + assertThat(file).hasContent(TEST_CONTENT + TEST_CONTENT); } } diff --git a/src/test/java/org/apache/maven/plugins/dependency/utils/TestSilentLog.java b/src/test/java/org/apache/maven/plugins/dependency/utils/TestSilentLog.java index 231419ea3..025e42338 100644 --- a/src/test/java/org/apache/maven/plugins/dependency/utils/TestSilentLog.java +++ b/src/test/java/org/apache/maven/plugins/dependency/utils/TestSilentLog.java @@ -18,12 +18,13 @@ */ package org.apache.maven.plugins.dependency.utils; -import junit.framework.TestCase; import org.apache.maven.plugin.logging.Log; -import org.codehaus.plexus.logging.Logger; +import org.junit.Assert; +import org.junit.Test; -public class TestSilentLog extends TestCase { +public class TestSilentLog { + @Test public void testLog() { Log log = new DependencySilentLog(); String text = "Text"; @@ -40,35 +41,9 @@ public void testLog() { log.error(text); log.error(text, e); log.error(e); - log.isDebugEnabled(); - log.isErrorEnabled(); - log.isWarnEnabled(); - log.isInfoEnabled(); - } - - public void testLogger() { - Logger log = new DependencySilentLog(); - String text = "Text"; - Throwable e = new RuntimeException(); - - log.debug(text); - log.debug(text, e); - log.error(text); - log.error(text, e); - log.warn(text); - log.warn(text, e); - log.info(text); - log.info(text, e); - - log.fatalError(text); - log.fatalError(text, e); - log.getChildLogger(text); - log.getName(); - log.getThreshold(); - log.isDebugEnabled(); - log.isErrorEnabled(); - log.isFatalErrorEnabled(); - log.isInfoEnabled(); - log.isWarnEnabled(); + Assert.assertFalse(log.isDebugEnabled()); + Assert.assertFalse(log.isErrorEnabled()); + Assert.assertFalse(log.isWarnEnabled()); + Assert.assertFalse(log.isInfoEnabled()); } } diff --git a/src/test/java/org/apache/maven/plugins/dependency/utils/filters/TestDestFileFilter.java b/src/test/java/org/apache/maven/plugins/dependency/utils/filters/TestDestFileFilter.java index b3e627c34..b97f83fa0 100644 --- a/src/test/java/org/apache/maven/plugins/dependency/utils/filters/TestDestFileFilter.java +++ b/src/test/java/org/apache/maven/plugins/dependency/utils/filters/TestDestFileFilter.java @@ -22,45 +22,40 @@ import java.io.IOException; import java.util.HashSet; import java.util.Set; -import junit.framework.TestCase; -import org.apache.commons.io.FileUtils; + import org.apache.maven.artifact.Artifact; import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugin.logging.Log; -import org.apache.maven.plugin.testing.SilentLog; import org.apache.maven.plugins.dependency.testUtils.DependencyArtifactStubFactory; import org.apache.maven.plugins.dependency.utils.DependencyUtil; import org.apache.maven.shared.artifact.filter.collection.ArtifactFilterException; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertTrue; /** * @author brianf */ -public class TestDestFileFilter extends TestCase { +public class TestDestFileFilter { Set artifacts = new HashSet<>(); - Log log = new SilentLog(); - + @TempDir File outputFolder; DependencyArtifactStubFactory fact; + @BeforeEach protected void setUp() throws Exception { - super.setUp(); - - outputFolder = new File("target/markers/"); - FileUtils.deleteDirectory(outputFolder); - assertFalse(outputFolder.exists()); - this.fact = new DependencyArtifactStubFactory(outputFolder, false); artifacts = fact.getReleaseAndSnapshotArtifacts(); } - protected void tearDown() throws IOException { - FileUtils.deleteDirectory(outputFolder); - } - - public File createFile(Artifact artifact) throws IOException { - return createFile(artifact, false, false, false); + public void createFile(Artifact artifact) throws IOException { + createFile(artifact, false, false, false); } public File createFile( @@ -90,6 +85,7 @@ public File createFile( return destFile; } + @Test public void testDestFileRelease() throws IOException, ArtifactFilterException { DestFileFilter filter = new DestFileFilter(outputFolder); Artifact artifact = fact.getReleaseArtifact(); @@ -102,6 +98,7 @@ public void testDestFileRelease() throws IOException, ArtifactFilterException { assertTrue(filter.isArtifactIncluded(artifact)); } + @Test public void testDestFileSnapshot() throws IOException, ArtifactFilterException { DestFileFilter filter = new DestFileFilter(outputFolder); Artifact artifact = fact.getSnapshotArtifact(); @@ -114,6 +111,7 @@ public void testDestFileSnapshot() throws IOException, ArtifactFilterException { assertTrue(filter.isArtifactIncluded(artifact)); } + @Test public void testDestFileStripVersion() throws IOException, ArtifactFilterException { DestFileFilter filter = new DestFileFilter(outputFolder); Artifact artifact = fact.getSnapshotArtifact(); @@ -127,6 +125,7 @@ public void testDestFileStripVersion() throws IOException, ArtifactFilterExcepti assertTrue(filter.isArtifactIncluded(artifact)); } + @Test public void testDestFileStripClassifier() throws IOException, ArtifactFilterException { DestFileFilter filter = new DestFileFilter(outputFolder); Artifact artifact = fact.getSnapshotArtifact(); @@ -140,6 +139,7 @@ public void testDestFileStripClassifier() throws IOException, ArtifactFilterExce assertTrue(filter.isArtifactIncluded(artifact)); } + @Test public void testDestFileSubPerArtifact() throws IOException, ArtifactFilterException { DestFileFilter filter = new DestFileFilter(outputFolder); Artifact artifact = fact.getSnapshotArtifact(); @@ -153,6 +153,7 @@ public void testDestFileSubPerArtifact() throws IOException, ArtifactFilterExcep assertTrue(filter.isArtifactIncluded(artifact)); } + @Test public void testDestFileSubPerType() throws MojoExecutionException, IOException, ArtifactFilterException { DestFileFilter filter = new DestFileFilter(outputFolder); Artifact artifact = fact.getSnapshotArtifact(); @@ -166,6 +167,7 @@ public void testDestFileSubPerType() throws MojoExecutionException, IOException, assertTrue(filter.isArtifactIncluded(artifact)); } + @Test public void testDestFileOverwriteIfNewer() throws MojoExecutionException, IOException, ArtifactFilterException { DestFileFilter filter = new DestFileFilter(outputFolder); @@ -191,6 +193,7 @@ public void testDestFileOverwriteIfNewer() throws MojoExecutionException, IOExce assertFalse(filter.isArtifactIncluded(artifact)); } + @Test public void testGettersSetters() { DestFileFilter filter = new DestFileFilter(null); assertNull(filter.getOutputFileDirectory()); diff --git a/src/test/java/org/apache/maven/plugins/dependency/utils/filters/TestMarkerFileFilter.java b/src/test/java/org/apache/maven/plugins/dependency/utils/filters/TestMarkerFileFilter.java index 31b05e8ae..448279da1 100644 --- a/src/test/java/org/apache/maven/plugins/dependency/utils/filters/TestMarkerFileFilter.java +++ b/src/test/java/org/apache/maven/plugins/dependency/utils/filters/TestMarkerFileFilter.java @@ -22,45 +22,39 @@ import java.io.IOException; import java.util.HashSet; import java.util.Set; -import junit.framework.TestCase; -import org.apache.commons.io.FileUtils; + import org.apache.maven.artifact.Artifact; import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugin.logging.Log; -import org.apache.maven.plugin.testing.SilentLog; import org.apache.maven.plugins.dependency.testUtils.DependencyArtifactStubFactory; import org.apache.maven.plugins.dependency.utils.markers.DefaultFileMarkerHandler; import org.apache.maven.shared.artifact.filter.collection.ArtifactFilterException; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; /** * @author brianf */ -public class TestMarkerFileFilter extends TestCase { +public class TestMarkerFileFilter { Set artifacts = new HashSet<>(); - Log log = new SilentLog(); - + @TempDir File outputFolder; DependencyArtifactStubFactory fact; + @BeforeEach protected void setUp() throws Exception { - super.setUp(); - - outputFolder = new File("target/markers/"); - FileUtils.deleteDirectory(outputFolder); - assertFalse(outputFolder.exists()); - this.fact = new DependencyArtifactStubFactory(outputFolder, false); artifacts = fact.getReleaseAndSnapshotArtifacts(); } - protected void tearDown() throws IOException { - FileUtils.deleteDirectory(outputFolder); - } - + @Test public void testMarkerFile() throws ArtifactFilterException { - MarkerFileFilter filter = new MarkerFileFilter(true, true, false, new DefaultFileMarkerHandler(outputFolder)); Set result = filter.filter(artifacts); assertEquals(2, result.size()); @@ -71,8 +65,8 @@ public void testMarkerFile() throws ArtifactFilterException { assertEquals(2, result.size()); } + @Test public void testMarkerSnapshots() throws ArtifactFilterException, MojoExecutionException, IOException { - DefaultFileMarkerHandler handler = new DefaultFileMarkerHandler(fact.getSnapshotArtifact(), outputFolder); handler.setMarker(); @@ -84,10 +78,9 @@ public void testMarkerSnapshots() throws ArtifactFilterException, MojoExecutionE result = filter.filter(artifacts); assertEquals(2, result.size()); assertTrue(handler.clearMarker()); - FileUtils.deleteDirectory(outputFolder); - assertFalse(outputFolder.exists()); } + @Test public void testMarkerRelease() throws IOException, ArtifactFilterException, MojoExecutionException { DefaultFileMarkerHandler handler = new DefaultFileMarkerHandler(fact.getReleaseArtifact(), outputFolder); handler.setMarker(); @@ -101,10 +94,9 @@ public void testMarkerRelease() throws IOException, ArtifactFilterException, Moj assertEquals(2, result.size()); assertTrue(handler.clearMarker()); - FileUtils.deleteDirectory(outputFolder); - assertFalse(outputFolder.exists()); } + @Test public void testMarkerTimestamp() throws IOException, MojoExecutionException, ArtifactFilterException { // filter includes release artifact because no marker present // filter includes snapshot artifact because it is newer than marker @@ -136,10 +128,9 @@ public void testMarkerTimestamp() throws IOException, MojoExecutionException, Ar assertFalse(handler.isMarkerSet()); snap.getFile().delete(); release.getFile().delete(); - FileUtils.deleteDirectory(outputFolder); - assertFalse(outputFolder.exists()); } + @Test public void testGettersSetters() { MarkerFileFilter filter = new MarkerFileFilter(true, false, true, new DefaultFileMarkerHandler(outputFolder)); assertTrue(filter.isOverWriteReleases()); diff --git a/src/test/java/org/apache/maven/plugins/dependency/utils/filters/TestResolveMarkerFileFilter.java b/src/test/java/org/apache/maven/plugins/dependency/utils/filters/TestResolveMarkerFileFilter.java index 8b4ac4078..10bce1a31 100644 --- a/src/test/java/org/apache/maven/plugins/dependency/utils/filters/TestResolveMarkerFileFilter.java +++ b/src/test/java/org/apache/maven/plugins/dependency/utils/filters/TestResolveMarkerFileFilter.java @@ -18,50 +18,38 @@ */ package org.apache.maven.plugins.dependency.utils.filters; -/** - * - */ import java.io.File; import java.io.IOException; -import java.util.HashSet; -import java.util.Set; -import junit.framework.TestCase; -import org.apache.commons.io.FileUtils; + import org.apache.maven.artifact.Artifact; import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugin.logging.Log; -import org.apache.maven.plugin.testing.SilentLog; import org.apache.maven.plugins.dependency.testUtils.DependencyArtifactStubFactory; import org.apache.maven.plugins.dependency.utils.markers.SourcesFileMarkerHandler; import org.apache.maven.shared.artifact.filter.collection.ArtifactFilterException; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; /** * @author brianf */ -public class TestResolveMarkerFileFilter extends TestCase { - Set artifacts = new HashSet<>(); - - Log log = new SilentLog(); +public class TestResolveMarkerFileFilter { + @TempDir File outputFolder; DependencyArtifactStubFactory fact; - protected void setUp() throws Exception { - super.setUp(); - - outputFolder = new File("target/markers/"); - FileUtils.deleteDirectory(outputFolder); - assertFalse(outputFolder.exists()); - - this.fact = new DependencyArtifactStubFactory(outputFolder, false); - artifacts = fact.getReleaseAndSnapshotArtifacts(); - } - - protected void tearDown() throws IOException { - FileUtils.deleteDirectory(outputFolder); + @BeforeEach + protected void setUp() throws IOException { + fact = new DependencyArtifactStubFactory(outputFolder, false); + fact.getReleaseAndSnapshotArtifacts(); } + @Test public void testResolveFile() throws IOException, ArtifactFilterException, MojoExecutionException { SourcesFileMarkerHandler handler = new SourcesFileMarkerHandler(outputFolder); diff --git a/src/test/java/org/apache/maven/plugins/dependency/utils/markers/TestDefaultMarkerFileHandler.java b/src/test/java/org/apache/maven/plugins/dependency/utils/markers/TestDefaultMarkerFileHandler.java index 7d793e17f..7828759e5 100644 --- a/src/test/java/org/apache/maven/plugins/dependency/utils/markers/TestDefaultMarkerFileHandler.java +++ b/src/test/java/org/apache/maven/plugins/dependency/utils/markers/TestDefaultMarkerFileHandler.java @@ -22,31 +22,35 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; -import junit.framework.TestCase; -import org.apache.commons.io.FileUtils; + import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.DefaultArtifact; import org.apache.maven.artifact.handler.ArtifactHandler; import org.apache.maven.artifact.handler.DefaultArtifactHandler; import org.apache.maven.artifact.versioning.VersionRange; import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugin.logging.Log; -import org.apache.maven.plugin.testing.SilentLog; import org.apache.maven.plugins.dependency.testUtils.stubs.StubDefaultFileMarkerHandler; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; /** * @author brianf */ -public class TestDefaultMarkerFileHandler extends TestCase { +public class TestDefaultMarkerFileHandler { List artifacts = new ArrayList<>(); - Log log = new SilentLog(); - + @TempDir File outputFolder; + @BeforeEach protected void setUp() throws Exception { - super.setUp(); - ArtifactHandler ah = new DefaultArtifactHandler(); VersionRange vr = VersionRange.createFromVersion("1.1"); Artifact artifact = new DefaultArtifact("test", "1", vr, Artifact.SCOPE_COMPILE, "jar", "", ah, false); @@ -57,16 +61,9 @@ protected void setUp() throws Exception { artifacts.add(artifact); artifact = new DefaultArtifact("test", "4", vr, Artifact.SCOPE_RUNTIME, "zip", "", ah, false); artifacts.add(artifact); - - outputFolder = new File("target/markers/"); - FileUtils.deleteDirectory(this.outputFolder); - assertFalse(outputFolder.exists()); - } - - protected void tearDown() throws IOException { - FileUtils.deleteDirectory(this.outputFolder); } + @Test public void testSetMarker() throws MojoExecutionException { DefaultFileMarkerHandler handler = new DefaultFileMarkerHandler(artifacts.get(0), this.outputFolder); assertFalse(handler.isMarkerSet()); @@ -86,6 +83,7 @@ public void testSetMarker() throws MojoExecutionException { assertFalse(handler.isMarkerSet()); } + @Test public void testMarkerFile() throws MojoExecutionException, IOException { DefaultFileMarkerHandler handler = new DefaultFileMarkerHandler(artifacts.get(0), this.outputFolder); @@ -107,6 +105,7 @@ public void testMarkerFile() throws MojoExecutionException, IOException { assertFalse(handle.exists()); } + @Test public void testMarkerTimeStamp() throws MojoExecutionException, IOException, InterruptedException { File theFile = new File(outputFolder, "theFile.jar"); outputFolder.mkdirs(); @@ -129,6 +128,7 @@ public void testMarkerTimeStamp() throws MojoExecutionException, IOException, In assertFalse(handler.isMarkerSet()); } + @Test public void testMarkerFileException() { // this stub wraps the file with an object to throw exceptions StubDefaultFileMarkerHandler handler = new StubDefaultFileMarkerHandler(artifacts.get(0), this.outputFolder); @@ -140,6 +140,7 @@ public void testMarkerFileException() { } } + @Test public void testGetterSetter() { DefaultFileMarkerHandler handler = new DefaultFileMarkerHandler(null, null); assertNull(handler.getArtifact()); @@ -151,6 +152,7 @@ public void testGetterSetter() { assertSame(outputFolder, handler.getMarkerFilesDirectory()); } + @Test public void testNullParent() throws MojoExecutionException { // the parent isn't set so this will create the marker in the local // folder. We must clear the diff --git a/src/test/java/org/apache/maven/plugins/dependency/utils/markers/TestSourcesMarkerFileHandler.java b/src/test/java/org/apache/maven/plugins/dependency/utils/markers/TestSourcesMarkerFileHandler.java index 9024b1237..0a498e3a4 100644 --- a/src/test/java/org/apache/maven/plugins/dependency/utils/markers/TestSourcesMarkerFileHandler.java +++ b/src/test/java/org/apache/maven/plugins/dependency/utils/markers/TestSourcesMarkerFileHandler.java @@ -23,6 +23,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Random; + import junit.framework.TestCase; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.DefaultArtifact; diff --git a/src/test/java/org/apache/maven/plugins/dependency/utils/markers/TestUnpackMarkerFileHandler.java b/src/test/java/org/apache/maven/plugins/dependency/utils/markers/TestUnpackMarkerFileHandler.java index 0038d2a2b..af165728f 100644 --- a/src/test/java/org/apache/maven/plugins/dependency/utils/markers/TestUnpackMarkerFileHandler.java +++ b/src/test/java/org/apache/maven/plugins/dependency/utils/markers/TestUnpackMarkerFileHandler.java @@ -22,37 +22,33 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; -import org.apache.commons.io.FileUtils; + import org.apache.maven.artifact.Artifact; import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugin.logging.Log; import org.apache.maven.plugin.testing.AbstractMojoTestCase; -import org.apache.maven.plugin.testing.SilentLog; import org.apache.maven.plugins.dependency.fromConfiguration.ArtifactItem; import org.apache.maven.plugins.dependency.testUtils.DependencyArtifactStubFactory; import org.apache.maven.plugins.dependency.testUtils.stubs.StubUnpackFileMarkerHandler; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; public class TestUnpackMarkerFileHandler extends AbstractMojoTestCase { List artifactItems = new ArrayList<>(); - Log log = new SilentLog(); - + @TempDir File outputFolder; + @TempDir protected File testDir; protected DependencyArtifactStubFactory stubFactory; + @Override + @BeforeEach protected void setUp() throws Exception { super.setUp(); - testDir = new File( - getBasedir(), - "target" + File.separatorChar + "unit-tests" + File.separatorChar + "unpack-markers" - + File.separatorChar); - FileUtils.deleteDirectory(testDir); - assertFalse(testDir.exists()); - stubFactory = new DependencyArtifactStubFactory(this.testDir, false); Artifact artifact = stubFactory.createArtifact("test", "test", "1"); ArtifactItem artifactItem; @@ -71,14 +67,6 @@ protected void setUp() throws Exception { artifactItem.setIncludes("**/*.xml"); artifactItem.setExcludes("**/*.class"); artifactItems.add(artifactItem); - - outputFolder = new File("target/markers/"); - FileUtils.deleteDirectory(this.outputFolder); - assertFalse(outputFolder.exists()); - } - - protected void tearDown() throws IOException { - FileUtils.deleteDirectory(this.outputFolder); } /** @@ -86,6 +74,7 @@ protected void tearDown() throws IOException { * * @throws MojoExecutionException in case of an error. */ + @Test public void testSetMarker() throws MojoExecutionException { UnpackFileMarkerHandler handler = new UnpackFileMarkerHandler(artifactItems.get(0), this.outputFolder); assertFalse(handler.isMarkerSet()); @@ -105,6 +94,7 @@ public void testSetMarker() throws MojoExecutionException { assertFalse(handler.isMarkerSet()); } + @Test public void testMarkerFile() throws MojoExecutionException, IOException { UnpackFileMarkerHandler handler = new UnpackFileMarkerHandler(artifactItems.get(0), this.outputFolder); @@ -126,9 +116,9 @@ public void testMarkerFile() throws MojoExecutionException, IOException { assertFalse(handle.exists()); } + @Test public void testMarkerTimeStamp() throws MojoExecutionException, IOException, InterruptedException { File theFile = new File(outputFolder, "theFile.jar"); - outputFolder.mkdirs(); theFile.createNewFile(); ArtifactItem theArtifactItem = artifactItems.get(0); Artifact theArtifact = theArtifactItem.getArtifact(); @@ -149,6 +139,7 @@ public void testMarkerTimeStamp() throws MojoExecutionException, IOException, In assertFalse(handler.isMarkerSet()); } + @Test public void testMarkerFileException() { // this stub wraps the file with an object to throw exceptions StubUnpackFileMarkerHandler handler = new StubUnpackFileMarkerHandler(artifactItems.get(0), this.outputFolder); @@ -160,6 +151,7 @@ public void testMarkerFileException() { } } + @Test public void testGetterSetter() { UnpackFileMarkerHandler handler = new UnpackFileMarkerHandler(null, null); assertNull(handler.getArtifactItem()); @@ -173,6 +165,7 @@ public void testGetterSetter() { assertSame(outputFolder, handler.getMarkerFilesDirectory()); } + @Test public void testNullParent() throws MojoExecutionException { // the parent isn't set so this will create the marker in the local // folder. We must clear the @@ -185,6 +178,7 @@ public void testNullParent() throws MojoExecutionException { assertFalse(handler.isMarkerSet()); } + @Test public void testIncludesMarker() throws MojoExecutionException, IOException { UnpackFileMarkerHandler handler = new UnpackFileMarkerHandler(artifactItems.get(1), outputFolder); File handle = handler.getMarkerFile(); @@ -207,6 +201,7 @@ public void testIncludesMarker() throws MojoExecutionException, IOException { assertFalse(handle.exists()); } + @Test public void testExcludesMarker() throws MojoExecutionException, IOException { UnpackFileMarkerHandler handler = new UnpackFileMarkerHandler(artifactItems.get(2), outputFolder); File handle = handler.getMarkerFile(); @@ -229,6 +224,7 @@ public void testExcludesMarker() throws MojoExecutionException, IOException { assertFalse(handle.exists()); } + @Test public void testIncludesExcludesMarker() throws MojoExecutionException, IOException { UnpackFileMarkerHandler handler = new UnpackFileMarkerHandler(artifactItems.get(3), outputFolder); File handle = handler.getMarkerFile(); diff --git a/src/test/java/org/apache/maven/plugins/dependency/utils/translators/TestClassifierTypeTranslator.java b/src/test/java/org/apache/maven/plugins/dependency/utils/translators/TestClassifierTypeTranslator.java index 4fa377f23..1ffea9631 100644 --- a/src/test/java/org/apache/maven/plugins/dependency/utils/translators/TestClassifierTypeTranslator.java +++ b/src/test/java/org/apache/maven/plugins/dependency/utils/translators/TestClassifierTypeTranslator.java @@ -22,21 +22,14 @@ import java.util.HashSet; import java.util.Iterator; import java.util.Set; + import org.apache.maven.artifact.Artifact; -import org.apache.maven.artifact.factory.ArtifactFactory; -import org.apache.maven.artifact.factory.DefaultArtifactFactory; import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager; import org.apache.maven.artifact.handler.manager.DefaultArtifactHandlerManager; -import org.apache.maven.artifact.repository.ArtifactRepository; -import org.apache.maven.execution.MavenSession; -import org.apache.maven.plugin.LegacySupport; import org.apache.maven.plugin.logging.Log; import org.apache.maven.plugin.testing.SilentLog; -import org.apache.maven.plugin.testing.stubs.MavenProjectStub; -import org.apache.maven.plugin.testing.stubs.StubArtifactRepository; import org.apache.maven.plugins.dependency.AbstractDependencyMojoTestCase; import org.apache.maven.plugins.dependency.testUtils.DependencyArtifactStubFactory; -import org.apache.maven.shared.transfer.artifact.ArtifactCoordinate; /** * @author brianf @@ -44,34 +37,29 @@ public class TestClassifierTypeTranslator extends AbstractDependencyMojoTestCase { Set artifacts = new HashSet<>(); - ArtifactFactory artifactFactory; - - ArtifactRepository artifactRepository; - Log log = new SilentLog(); private ArtifactHandlerManager artifactHandlerManager; + @Override + protected String getTestDirectoryName() { + return "classifiertype-translator"; + } + + @Override + protected boolean shouldUseFlattenedPath() { + return false; + } + @Override protected void setUp() throws Exception { - super.setUp("classifiertype-translator", false); + super.setUp(); artifactHandlerManager = new DefaultArtifactHandlerManager(); this.setVariableValueToObject(artifactHandlerManager, "artifactHandlers", new HashMap<>()); - artifactFactory = new DefaultArtifactFactory(); - this.setVariableValueToObject(artifactFactory, "artifactHandlerManager", artifactHandlerManager); - - artifactRepository = new StubArtifactRepository(null); - DependencyArtifactStubFactory factory = new DependencyArtifactStubFactory(null, false); artifacts = factory.getMixedArtifacts(); - - LegacySupport legacySupport = lookup(LegacySupport.class); - MavenSession session = newMavenSession(new MavenProjectStub()); - legacySupport.setSession(session); - - installLocalRepository(legacySupport); } public void testNullClassifier() { @@ -86,18 +74,18 @@ public void doTestNullEmptyClassifier(String classifier) { String type = "zip"; ArtifactTranslator at = new ClassifierTypeTranslator(artifactHandlerManager, classifier, type); - Set results = at.translate(artifacts, log); + Set results = at.translate(artifacts, log); for (Artifact artifact : artifacts) { - Iterator resultIter = results.iterator(); + Iterator resultIter = results.iterator(); boolean found = false; while (resultIter.hasNext()) { - ArtifactCoordinate translatedArtifact = resultIter.next(); + org.eclipse.aether.artifact.Artifact translatedArtifact = resultIter.next(); if (artifact.getArtifactId().equals(translatedArtifact.getArtifactId()) && artifact.getGroupId().equals(translatedArtifact.getGroupId()) /* && artifact.getScope().equals(translatedArtifact.getScope()) */ ) { - // classifier is null, should be the same as the artifact - assertEquals(artifact.getClassifier(), translatedArtifact.getClassifier()); + // classifier is always empty for Resolver sub artifact + assertEquals("", translatedArtifact.getClassifier()); assertEquals(type, translatedArtifact.getExtension()); found = true; @@ -120,13 +108,13 @@ public void doTestNullEmptyType(String type) { String classifier = "jdk5"; ArtifactTranslator at = new ClassifierTypeTranslator(artifactHandlerManager, classifier, type); - Set results = at.translate(artifacts, log); + Set results = at.translate(artifacts, log); for (Artifact artifact : artifacts) { - Iterator resultIter = results.iterator(); + Iterator resultIter = results.iterator(); boolean found = false; while (!found && resultIter.hasNext()) { - ArtifactCoordinate translatedArtifact = resultIter.next(); + org.eclipse.aether.artifact.Artifact translatedArtifact = resultIter.next(); if (artifact.getArtifactId() == translatedArtifact.getArtifactId() && artifact.getGroupId() == translatedArtifact.getGroupId() /* && artifact.getScope() == translatedArtifact.getScope() */ ) { @@ -146,13 +134,13 @@ public void testClassifierAndType() { String classifier = "jdk14"; String type = "sources"; ArtifactTranslator at = new ClassifierTypeTranslator(artifactHandlerManager, classifier, type); - Set results = at.translate(artifacts, log); + Set results = at.translate(artifacts, log); for (Artifact artifact : artifacts) { - Iterator resultIter = results.iterator(); + Iterator resultIter = results.iterator(); boolean found = false; while (!found && resultIter.hasNext()) { - ArtifactCoordinate translatedArtifact = resultIter.next(); + org.eclipse.aether.artifact.Artifact translatedArtifact = resultIter.next(); if (artifact.getArtifactId() == translatedArtifact.getArtifactId() && artifact.getGroupId() == translatedArtifact.getGroupId()) { assertEquals(translatedArtifact.getClassifier(), classifier); diff --git a/src/test/resources/unit/analyze-exclusions/plugin-config.xml b/src/test/resources/unit/analyze-exclusions/plugin-config.xml new file mode 100644 index 000000000..ccf9ebde4 --- /dev/null +++ b/src/test/resources/unit/analyze-exclusions/plugin-config.xml @@ -0,0 +1,43 @@ + + + + + + maven-dependency-plugin + + + + + + + + org.apache.maven + maven-artifact + 2.0.4 + + + javax.inject + javax.inject + + + + + \ No newline at end of file diff --git a/src/test/resources/unit/build-classpath-test/plugin-config.xml b/src/test/resources/unit/build-classpath-test/plugin-config.xml index df85345b4..1a046caeb 100644 --- a/src/test/resources/unit/build-classpath-test/plugin-config.xml +++ b/src/test/resources/unit/build-classpath-test/plugin-config.xml @@ -23,7 +23,6 @@ maven-dependency-plugin - diff --git a/src/test/resources/unit/collect-test/plugin-config.xml b/src/test/resources/unit/collect-test/plugin-config.xml index 664fb38e9..3d1210a58 100644 --- a/src/test/resources/unit/collect-test/plugin-config.xml +++ b/src/test/resources/unit/collect-test/plugin-config.xml @@ -23,7 +23,6 @@ maven-dependency-plugin - diff --git a/src/test/resources/unit/copy-dependencies-test/plugin-config.xml b/src/test/resources/unit/copy-dependencies-test/plugin-config.xml index 726aa2109..d2eb2b561 100644 --- a/src/test/resources/unit/copy-dependencies-test/plugin-config.xml +++ b/src/test/resources/unit/copy-dependencies-test/plugin-config.xml @@ -23,7 +23,6 @@ maven-dependency-plugin - true diff --git a/src/test/resources/unit/copy-test/plugin-config.xml b/src/test/resources/unit/copy-test/plugin-config.xml index df85345b4..1a046caeb 100644 --- a/src/test/resources/unit/copy-test/plugin-config.xml +++ b/src/test/resources/unit/copy-test/plugin-config.xml @@ -23,7 +23,6 @@ maven-dependency-plugin - diff --git a/src/test/resources/unit/duplicate-dependencies/plugin-config.xml b/src/test/resources/unit/duplicate-dependencies/plugin-config.xml index acbbe93ca..0cd446369 100644 --- a/src/test/resources/unit/duplicate-dependencies/plugin-config.xml +++ b/src/test/resources/unit/duplicate-dependencies/plugin-config.xml @@ -55,7 +55,6 @@ maven-dependency-plugin - diff --git a/src/test/resources/unit/duplicate-dependencies/plugin-config2.xml b/src/test/resources/unit/duplicate-dependencies/plugin-config2.xml index 282080592..908226dbd 100644 --- a/src/test/resources/unit/duplicate-dependencies/plugin-config2.xml +++ b/src/test/resources/unit/duplicate-dependencies/plugin-config2.xml @@ -67,7 +67,6 @@ maven-dependency-plugin - diff --git a/src/test/resources/unit/go-offline-test/exclude-plugin-config.xml b/src/test/resources/unit/go-offline-test/exclude-plugin-config.xml new file mode 100644 index 000000000..c80cf3433 --- /dev/null +++ b/src/test/resources/unit/go-offline-test/exclude-plugin-config.xml @@ -0,0 +1,35 @@ + + + + + + maven-dependency-plugin + @project.version@ + + skip.this.groupid,skip.this.groupid.too + + skip-this-artifact,skip-this-artifact-too + + + + system + ear,pom + skipThisClassifier,skipThisClassifierToo + + + + + + diff --git a/src/test/resources/unit/go-offline-test/include-aid-plugin-config.xml b/src/test/resources/unit/go-offline-test/include-aid-plugin-config.xml new file mode 100644 index 000000000..cd792ec85 --- /dev/null +++ b/src/test/resources/unit/go-offline-test/include-aid-plugin-config.xml @@ -0,0 +1,25 @@ + + + + + + maven-dependency-plugin + @project.version@ + + include-this-artifact,include-this-artifact-too + + + + + + \ No newline at end of file diff --git a/src/test/resources/unit/go-offline-test/include-gid-plugin-config.xml b/src/test/resources/unit/go-offline-test/include-gid-plugin-config.xml new file mode 100644 index 000000000..8d2c425a0 --- /dev/null +++ b/src/test/resources/unit/go-offline-test/include-gid-plugin-config.xml @@ -0,0 +1,24 @@ + + + + + + maven-dependency-plugin + @project.version@ + + include.this.groupid,include.this.groupid.too + + + + + \ No newline at end of file diff --git a/src/test/resources/unit/go-offline-test/include-scope-plugin-config.xml b/src/test/resources/unit/go-offline-test/include-scope-plugin-config.xml new file mode 100644 index 000000000..2230d2a8b --- /dev/null +++ b/src/test/resources/unit/go-offline-test/include-scope-plugin-config.xml @@ -0,0 +1,24 @@ + + + + + + maven-dependency-plugin + @project.version@ + + provided + + + + + \ No newline at end of file diff --git a/src/test/resources/unit/go-offline-test/include-types-plugin-config.xml b/src/test/resources/unit/go-offline-test/include-types-plugin-config.xml new file mode 100644 index 000000000..e7e2365ff --- /dev/null +++ b/src/test/resources/unit/go-offline-test/include-types-plugin-config.xml @@ -0,0 +1,24 @@ + + + + + + maven-dependency-plugin + @project.version@ + + pom,ear + + + + + \ No newline at end of file diff --git a/src/test/resources/unit/properties-test/plugin-config.xml b/src/test/resources/unit/properties-test/plugin-config.xml old mode 100755 new mode 100644 index 60ef26f5d..e7edfc507 --- a/src/test/resources/unit/properties-test/plugin-config.xml +++ b/src/test/resources/unit/properties-test/plugin-config.xml @@ -23,7 +23,6 @@ maven-dependency-plugin - diff --git a/src/test/resources/unit/render-dependencies-test/plugin-config.xml b/src/test/resources/unit/render-dependencies-test/plugin-config.xml new file mode 100644 index 000000000..1a046caeb --- /dev/null +++ b/src/test/resources/unit/render-dependencies-test/plugin-config.xml @@ -0,0 +1,37 @@ + + + + + + maven-dependency-plugin + + + + + + + + org.apache.maven + maven-artifact + 2.0.4 + + + \ No newline at end of file diff --git a/src/test/resources/unit/resolve-test/plugin-config.xml b/src/test/resources/unit/resolve-test/plugin-config.xml index df85345b4..1a046caeb 100644 --- a/src/test/resources/unit/resolve-test/plugin-config.xml +++ b/src/test/resources/unit/resolve-test/plugin-config.xml @@ -23,7 +23,6 @@ maven-dependency-plugin - diff --git a/src/test/resources/unit/skip-test/plugin-analyze-report-config.xml b/src/test/resources/unit/skip-test/plugin-analyze-report-config.xml index 33d7c2f8d..ac324dd00 100644 --- a/src/test/resources/unit/skip-test/plugin-analyze-report-config.xml +++ b/src/test/resources/unit/skip-test/plugin-analyze-report-config.xml @@ -36,7 +36,6 @@ maven-dependency-plugin - true target/unit-tests/skip-test diff --git a/src/test/resources/unit/skip-test/plugin-config.xml b/src/test/resources/unit/skip-test/plugin-config.xml index 3c6076504..0006e2729 100644 --- a/src/test/resources/unit/skip-test/plugin-config.xml +++ b/src/test/resources/unit/skip-test/plugin-config.xml @@ -36,7 +36,6 @@ maven-dependency-plugin - true diff --git a/src/test/resources/unit/skip-test/plugin-purge-local-repository-config.xml b/src/test/resources/unit/skip-test/plugin-purge-local-repository-config.xml index 707b9dfa0..0006e2729 100644 --- a/src/test/resources/unit/skip-test/plugin-purge-local-repository-config.xml +++ b/src/test/resources/unit/skip-test/plugin-purge-local-repository-config.xml @@ -36,10 +36,6 @@ maven-dependency-plugin - - - - true diff --git a/src/test/resources/unit/tree-test/plugin-config.xml b/src/test/resources/unit/tree-test/plugin-config.xml index 5d61ca75a..511d1147c 100644 --- a/src/test/resources/unit/tree-test/plugin-config.xml +++ b/src/test/resources/unit/tree-test/plugin-config.xml @@ -23,7 +23,6 @@ maven-dependency-plugin - diff --git a/src/test/resources/unit/unpack-dependencies-test/plugin-config.xml b/src/test/resources/unit/unpack-dependencies-test/plugin-config.xml index 01a1f1904..30d2867c3 100644 --- a/src/test/resources/unit/unpack-dependencies-test/plugin-config.xml +++ b/src/test/resources/unit/unpack-dependencies-test/plugin-config.xml @@ -23,9 +23,7 @@ maven-dependency-plugin - true - true diff --git a/src/test/resources/unit/unpack-dependencies-test/test.txt b/src/test/resources/unit/unpack-dependencies-test/test.txt index 4ee425451..d2eb2b561 100644 --- a/src/test/resources/unit/unpack-dependencies-test/test.txt +++ b/src/test/resources/unit/unpack-dependencies-test/test.txt @@ -23,7 +23,6 @@ maven-dependency-plugin - true diff --git a/src/test/resources/unit/unpack-test/plugin-config.xml b/src/test/resources/unit/unpack-test/plugin-config.xml index df85345b4..1a046caeb 100644 --- a/src/test/resources/unit/unpack-test/plugin-config.xml +++ b/src/test/resources/unit/unpack-test/plugin-config.xml @@ -23,7 +23,6 @@ maven-dependency-plugin -