mirror of
https://github.com/rife2/bld
synced 2026-03-25 03:24:09 +01:00
Compare commits
343 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7b542ac5d0 | ||
|
|
aa10006ce2 | ||
|
|
4de8d3c629 | ||
|
|
44144ce095 | ||
|
|
3160161299 | ||
|
|
b22257ed43 | ||
|
|
25c77ed5df | ||
|
|
21ed5912f0 | ||
|
|
737927da26 | ||
|
|
6fd3948f04 | ||
|
|
c537b584f2 | ||
|
|
7a419ed197 | ||
|
|
9c5928f9b1 | ||
|
|
26ff495b79 | ||
|
|
585325dd46 | ||
|
|
793fde47dc | ||
|
|
fea026a9c6 | ||
|
|
c71a98c6ee | ||
|
|
8ad5414d67 | ||
|
|
684c697896 | ||
|
|
affa9e1dac | ||
|
|
1c70337afb | ||
|
|
25bf0d3595 | ||
|
|
0ec366e90b | ||
|
|
8559696a6a | ||
|
|
6f54789dd9 | ||
|
|
82fe6a3aa4 | ||
|
|
52e8a6ce6a | ||
|
|
f33108a3f0 | ||
|
|
f4db05581b | ||
|
|
ba1dad4eb3 | ||
|
|
82705b952b | ||
|
|
5efbc8c064 | ||
|
|
22752668b7 | ||
|
|
9bea6d47c7 | ||
|
|
b0596911ed | ||
|
|
e9906c0df7 | ||
|
|
d3d7614e7c | ||
|
|
91a621dfea | ||
|
|
5af8ca7b2e | ||
|
|
d6d3c0fc1d | ||
|
|
9158e7296f | ||
|
|
b1b5c89c78 | ||
|
|
4b6cac6ace | ||
|
|
9362a60c52 | ||
|
|
ca7fa0c4b8 | ||
|
|
f9f20e62ef | ||
|
|
4b762796e0 | ||
|
|
03a15433ff | ||
|
|
625055bbb6 | ||
|
|
72d214b3b6 | ||
|
|
f753f87a79 | ||
|
|
fec4f68027 | ||
|
|
92c8cd3033 | ||
|
|
da0b92fb8e | ||
|
|
2dd53ace3d | ||
|
|
3d86aa8c8d | ||
|
|
32052deaa3 | ||
|
|
b27cc78fb7 | ||
|
|
a7efd01697 | ||
|
|
92fc85bd9c | ||
|
|
34667b5402 | ||
|
|
66f7d180b9 | ||
|
|
6c2a9acf1c | ||
|
|
c6c9d32c35 | ||
|
|
3e9b252c51 | ||
|
|
3f60ed78ef | ||
|
|
762e099988 | ||
|
|
9941fc0d10 | ||
|
|
f51add49f0 | ||
|
|
3dce798d52 | ||
|
|
d5e65ec9e8 | ||
|
|
4083f95bc8 | ||
|
|
622ca99c7b | ||
|
|
a8f43864bf | ||
|
|
df173c4cfc | ||
|
|
a07db3f94e | ||
|
|
5da9e4b3a5 | ||
|
|
c7ca0e263d | ||
|
|
22952cf189 | ||
|
|
4fe40dadd7 | ||
|
|
47d463e6aa | ||
|
|
5ab77194e0 | ||
|
|
df680a4846 | ||
|
|
406b83bd82 | ||
|
|
b4801b5b07 | ||
|
|
28e548954f | ||
|
|
f15a8d2df2 | ||
|
|
d68905b944 | ||
|
|
c15a8d3bcf | ||
|
|
9deb570bf4 | ||
|
|
b8a63dd79c | ||
|
|
22add235e3 | ||
|
|
0b9581cf12 | ||
|
|
2b827a9a6f | ||
|
|
fd1429f2d3 | ||
|
|
5821022fee | ||
|
|
a4300b37d1 | ||
|
|
9f9e8a95db | ||
|
|
126daecd21 | ||
|
|
c70b4f1c43 | ||
|
|
673ebbdeb0 | ||
|
|
a7c29080f5 | ||
|
|
a616a8a8f6 | ||
|
|
0797e39dd6 | ||
|
|
3bd17e224b | ||
|
|
7cd547f8b6 | ||
|
|
c59d61f8c1 | ||
|
|
0382444c0c | ||
|
|
d72e6ebc2e | ||
|
|
d42d2d6fa0 | ||
|
|
a06ce8eaaa | ||
|
|
7f8120e3e3 | ||
|
|
67c727e062 | ||
|
|
62a324068f | ||
|
|
e32e17403f | ||
|
|
750758993d | ||
|
|
1d615a501c | ||
|
|
91640e68ce | ||
|
|
d029bb9b87 | ||
|
|
7a946b17d8 | ||
|
|
f6aa5258ef | ||
|
|
94225dfb7a | ||
|
|
8118f42285 | ||
|
|
c38594a173 | ||
|
|
0204cdff19 | ||
|
|
b94b23af56 | ||
|
|
e2cc7a6782 | ||
|
|
002844861b | ||
|
|
0ad964ea4d | ||
|
|
d69956cf91 | ||
|
|
0aa93b708a | ||
|
|
7fcbccd565 | ||
|
|
683f5dfb3a | ||
|
|
547b20a242 | ||
|
|
aeecd957c6 | ||
|
|
a3a753f70a | ||
|
|
cec3d4ebbf | ||
|
|
bd93c6659b | ||
|
|
d96ce65cbb | ||
|
|
97a153f955 | ||
|
|
78368fdecc | ||
|
|
89820f5262 | ||
|
|
e5337f6ed7 | ||
|
|
fbaaa4ae3e | ||
|
|
ba7e314e6e | ||
|
|
fa5929a778 | ||
|
|
bd5d8ef355 | ||
|
|
ad8a866dc3 | ||
|
|
586aec0eae | ||
|
|
c7ebaa7d87 | ||
|
|
0e4e171a81 | ||
|
|
3ec2cc68ce | ||
|
|
d24e9d223c | ||
|
|
d605ac1242 | ||
|
|
fa0ac43828 | ||
|
|
4913519eb4 | ||
|
|
3ee8f81317 | ||
|
|
19991e84c4 | ||
|
|
0f65e1d232 | ||
|
|
98e9035c5e | ||
|
|
15be3a2cd7 | ||
|
|
42ced8e340 | ||
|
|
fcd5d01e86 | ||
|
|
522b8b95d7 | ||
|
|
f86b7fb40c | ||
|
|
8c42052e2e | ||
|
|
a33e373367 | ||
|
|
e731b00287 | ||
|
|
fb4ce1197a | ||
|
|
a3830dbdc0 | ||
|
|
bb4c980e66 | ||
|
|
454c51db12 | ||
|
|
9614bd8014 | ||
|
|
604f5ba424 | ||
|
|
b0a75b22b7 | ||
|
|
0ed48f9eed | ||
|
|
a02e78820e | ||
|
|
d904fd22b7 | ||
|
|
8e02a3ac7e | ||
|
|
48c43a05ed | ||
|
|
bb6052250e | ||
|
|
23d9e26856 | ||
|
|
30f456e47a | ||
|
|
fd38de9644 | ||
|
|
8928955fb1 | ||
|
|
a222bec47c | ||
|
|
feed8a8eb5 | ||
|
|
ad15ff5095 | ||
|
|
5ced931f7e | ||
|
|
1d38c914e0 | ||
|
|
8b75f74a1d | ||
|
|
bc13bad49f | ||
|
|
b9ac76b5b5 | ||
|
|
c912e4396e | ||
|
|
793efb27ce | ||
|
|
177a2e39af | ||
|
|
7f74bb015b | ||
|
|
9338768415 | ||
|
|
4f20fb2cc7 | ||
|
|
e65668a8be | ||
|
|
ecb9289001 | ||
|
|
a30b290c0d | ||
|
|
abf84256a5 | ||
|
|
b25f332f3b | ||
|
|
e491f6d664 | ||
|
|
aca7aa41a9 | ||
|
|
57c4b20de8 | ||
|
|
f0129e7ba1 | ||
|
|
b5655ca346 | ||
|
|
921a1f11b5 | ||
|
|
60c332d750 | ||
|
|
4d841a7c72 | ||
|
|
accf27c4db | ||
|
|
917d6bbe93 | ||
|
|
708304235b | ||
|
|
392ca23bd3 | ||
|
|
31f9dc3373 | ||
|
|
1e04c3d530 | ||
|
|
52fc588795 | ||
|
|
e6feeff0da | ||
|
|
30101af0ab | ||
|
|
183097c4f9 | ||
|
|
9d769a9d29 | ||
|
|
d8c0170dc0 | ||
|
|
86d81c9c51 | ||
|
|
aeb3369fe0 | ||
|
|
8b4055c1a3 | ||
|
|
7e44493866 | ||
|
|
2de4d7f4db | ||
|
|
e7633b4723 | ||
|
|
9fc422da21 | ||
|
|
81ce5cefed | ||
|
|
dfeb6d634b | ||
|
|
7d54edc4d9 | ||
|
|
72344ede79 | ||
|
|
5e681a4400 | ||
|
|
c9bcbc0bb7 | ||
|
|
f6d2265623 | ||
|
|
12458bc149 | ||
|
|
72fe2d5a5d | ||
|
|
317e77bfd1 | ||
|
|
af6525acfa | ||
|
|
6ffd6260b1 | ||
|
|
0e6f988181 | ||
|
|
a66285ce95 | ||
|
|
b1f28c62ec | ||
|
|
7406d7a0af | ||
|
|
942cd28468 | ||
|
|
84a2bb337d | ||
|
|
6230db68af | ||
|
|
85f2c8fd7b | ||
|
|
1a243efb66 | ||
|
|
e6be211d73 | ||
|
|
76186c78db | ||
|
|
f53c73c9d5 | ||
|
|
400bb13532 | ||
|
|
95858f0c29 | ||
|
|
0beedb6918 | ||
|
|
f2b1d4228f | ||
|
|
de4c4743b5 | ||
|
|
f65ce504e3 | ||
|
|
e1489b9847 | ||
|
|
bb6726ec1f | ||
|
|
96efbd260c | ||
|
|
5519ff3f1c | ||
|
|
7face792f2 | ||
|
|
35887e7d06 | ||
|
|
844b2b390d | ||
|
|
4e64675bdb | ||
|
|
7ceb6e3c27 | ||
|
|
f00418b4c2 | ||
|
|
4ac6490dec | ||
|
|
e7c7144c84 | ||
|
|
cac57b3e4b | ||
|
|
0b9f29a175 | ||
|
|
2a5437de0c | ||
|
|
7c2d0221b8 | ||
|
|
a6aadf8e60 | ||
|
|
5fb6fa16b7 | ||
|
|
0994f184f2 | ||
|
|
3eb5795cf2 | ||
|
|
77ceceb122 | ||
|
|
3452a404fc | ||
|
|
c4b5748239 | ||
|
|
d52551f3b7 | ||
|
|
ec01a626ae | ||
|
|
87735bb88e | ||
|
|
1ab53f5bad | ||
|
|
76cba6ed7a | ||
|
|
261b5d456a | ||
|
|
f6cb944565 | ||
|
|
7009e54c71 | ||
|
|
89eb658d73 | ||
|
|
60deb1906a | ||
|
|
102d3d3586 | ||
|
|
762a63b12f | ||
|
|
e69f4fe554 | ||
|
|
6d082c1bac | ||
|
|
8c21c2f909 | ||
|
|
a5c89dfd2d | ||
|
|
dfc402a9ee | ||
|
|
743efa69e6 | ||
|
|
88aa78f3b5 | ||
|
|
80a89b7343 | ||
|
|
6b0455e9c5 | ||
|
|
d35166d53d | ||
|
|
f71f92bfa9 | ||
|
|
278e1ff8dd | ||
|
|
6830c8c44c | ||
|
|
b7963ba6ca | ||
|
|
c75626efa4 | ||
|
|
29b4e267f8 | ||
|
|
4058482cf7 | ||
|
|
8014d5d58e | ||
|
|
6e77f5a2f3 | ||
|
|
6ad3f992ac | ||
|
|
d00471dd02 | ||
|
|
8d707a75ae | ||
|
|
c635b25b6f | ||
|
|
ba28294730 | ||
|
|
57fbaefda7 | ||
|
|
bbdf89845a | ||
|
|
5f619ce188 | ||
|
|
912ba87c12 | ||
|
|
82ead98c5d | ||
|
|
c933f16e0f | ||
|
|
49243568c6 | ||
|
|
5de491e5c6 | ||
|
|
17548f787c | ||
|
|
b81743896a | ||
|
|
262b500bc1 | ||
|
|
ecb72b6a7d | ||
|
|
c0418bb60a | ||
|
|
061a194322 | ||
|
|
cdaea733b2 | ||
|
|
d95a26e8d6 | ||
|
|
950b47a383 | ||
|
|
39f1456d12 | ||
|
|
2ed5b4b388 | ||
|
|
502dd2231c | ||
|
|
c1531b58e4 | ||
|
|
978e50e827 |
12
.devcontainer/devcontainer.json
Normal file
12
.devcontainer/devcontainer.json
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"name": "Java",
|
||||||
|
"image": "mcr.microsoft.com/devcontainers/java:1-21",
|
||||||
|
|
||||||
|
"features": {
|
||||||
|
"ghcr.io/devcontainers/features/java:1": {
|
||||||
|
"version": "none",
|
||||||
|
"installMaven": "false",
|
||||||
|
"installGradle": "false"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
104
.github/workflows/bld.yml
vendored
104
.github/workflows/bld.yml
vendored
|
|
@ -2,8 +2,11 @@ name: bld-ci
|
||||||
|
|
||||||
on: [push, pull_request, workflow_dispatch]
|
on: [push, pull_request, workflow_dispatch]
|
||||||
|
|
||||||
|
env:
|
||||||
|
REPORTS_DIR: "build/test-results/test/"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-bld-project:
|
build-linux:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
services:
|
services:
|
||||||
|
|
@ -87,24 +90,113 @@ jobs:
|
||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
java-version: [ 17, 19 ]
|
java-version: [ 17, 20, 21, 22, 23, 24, 25 ]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout source repository
|
- name: Checkout source repository
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
|
clean: true
|
||||||
submodules: 'true'
|
submodules: 'true'
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Set up JDK ${{ matrix.java-version }}
|
- name: Set up JDK ${{ matrix.java-version }}
|
||||||
uses: actions/setup-java@v3
|
uses: actions/setup-java@v4
|
||||||
with:
|
with:
|
||||||
distribution: 'temurin'
|
distribution: 'corretto'
|
||||||
java-version: ${{ matrix.java-version }}
|
java-version: ${{ matrix.java-version }}
|
||||||
|
check-latest: true
|
||||||
|
|
||||||
|
- name: Download dependencies
|
||||||
|
run: ./bld clean download
|
||||||
|
|
||||||
|
- name: Compile source
|
||||||
|
run: ./bld compile
|
||||||
|
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
|
id: tests
|
||||||
run: >-
|
run: >-
|
||||||
./bld download compile test
|
./bld test
|
||||||
-Dtest.postgres=true -Dtest.mysql=true -Dtest.mariadb=true -Dtest.oracle=true -Dtest.oracle-free=true
|
-Dtest.postgres=true -Dtest.mysql=true -Dtest.mariadb=true -Dtest.oracle=true -Dtest.oracle-free=true
|
||||||
-DtestsBadgeUrl=https://rife2.com/tests-badge/update/com.uwyn.rife2/bld
|
-DtestsBadgeUrl=https://rife2.com/tests-badge/update/com.uwyn.rife2/bld
|
||||||
-DtestsBadgeApiKey=${{ secrets.TESTS_BADGE_API_KEY }}
|
-DtestsBadgeApiKey=${{ secrets.TESTS_BADGE_API_KEY }}
|
||||||
|
--reports-dir=${{ env.REPORTS_DIR }}
|
||||||
|
|
||||||
|
- name: Run reporter
|
||||||
|
if: always() && steps.tests.outcome == 'failure'
|
||||||
|
run: ./bld reporter --all
|
||||||
|
|
||||||
|
build-macos:
|
||||||
|
runs-on: macos-latest
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
java-version: [ 17, 20, 21, 22, 23, 24, 25 ]
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout source repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
clean: true
|
||||||
|
submodules: 'true'
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Set up JDK ${{ matrix.java-version }}
|
||||||
|
uses: actions/setup-java@v4
|
||||||
|
with:
|
||||||
|
distribution: 'corretto'
|
||||||
|
java-version: ${{ matrix.java-version }}
|
||||||
|
check-latest: true
|
||||||
|
|
||||||
|
- name: Download dependencies
|
||||||
|
run: ./bld clean download
|
||||||
|
|
||||||
|
- name: Compile source
|
||||||
|
run: ./bld compile
|
||||||
|
|
||||||
|
- name: Run tests
|
||||||
|
id: tests
|
||||||
|
run: ./bld test --reports-dir=${{ env.REPORTS_DIR }}
|
||||||
|
|
||||||
|
- name: Run reporter
|
||||||
|
if: always() && steps.tests.outcome == 'failure'
|
||||||
|
run: ./bld reporter --all
|
||||||
|
|
||||||
|
build-windows:
|
||||||
|
runs-on: windows-latest
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
java-version: [ 17, 20, 21, 22, 23, 24, 25 ]
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Configure git line endings
|
||||||
|
run: git config --global core.autocrlf input
|
||||||
|
|
||||||
|
- name: Checkout source repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
clean: true
|
||||||
|
submodules: 'true'
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Set up JDK ${{ matrix.java-version }}
|
||||||
|
uses: actions/setup-java@v4
|
||||||
|
with:
|
||||||
|
distribution: 'corretto'
|
||||||
|
java-version: ${{ matrix.java-version }}
|
||||||
|
check-latest: true
|
||||||
|
|
||||||
|
- name: Download dependencies
|
||||||
|
run: .\bld.bat clean download
|
||||||
|
|
||||||
|
- name: Compile source
|
||||||
|
run: .\bld.bat compile
|
||||||
|
|
||||||
|
- name: Run tests
|
||||||
|
id: tests
|
||||||
|
run: .\bld.bat test --reports-dir=${{ env.REPORTS_DIR }}
|
||||||
|
|
||||||
|
- name: Run reporter
|
||||||
|
if: always() && steps.tests.outcome == 'failure'
|
||||||
|
run: .\bld.bat reporter --all
|
||||||
|
|
|
||||||
15
.github/workflows/pages.yml
vendored
15
.github/workflows/pages.yml
vendored
|
|
@ -30,29 +30,30 @@ jobs:
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout source repository
|
- name: Checkout source repository
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
|
clean: true
|
||||||
submodules: 'true'
|
submodules: 'true'
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Set up JDK 17
|
- name: Set up JDK 17
|
||||||
uses: actions/setup-java@v3
|
uses: actions/setup-java@v4
|
||||||
with:
|
with:
|
||||||
distribution: 'zulu'
|
distribution: 'corretto'
|
||||||
java-version: 17
|
java-version: 17
|
||||||
|
|
||||||
- name: Build Javadocs
|
- name: Build Javadocs
|
||||||
run: ./bld download clean compile javadoc
|
run: ./bld clean download clean compile javadoc
|
||||||
|
|
||||||
- name: Setup Pages
|
- name: Setup Pages
|
||||||
uses: actions/configure-pages@v3
|
uses: actions/configure-pages@v5
|
||||||
|
|
||||||
- name: Upload artifact
|
- name: Upload artifact
|
||||||
uses: actions/upload-pages-artifact@v1
|
uses: actions/upload-pages-artifact@v3
|
||||||
with:
|
with:
|
||||||
# Upload generated Javadocs repository
|
# Upload generated Javadocs repository
|
||||||
path: 'build/javadoc/'
|
path: 'build/javadoc/'
|
||||||
|
|
||||||
- name: Deploy to GitHub Pages
|
- name: Deploy to GitHub Pages
|
||||||
id: deployment
|
id: deployment
|
||||||
uses: actions/deploy-pages@v1
|
uses: actions/deploy-pages@v4
|
||||||
|
|
@ -10,8 +10,8 @@
|
||||||
<sourceFolder url="file://$MODULE_DIR$/build/generated" isTestSource="false" generated="true" />
|
<sourceFolder url="file://$MODULE_DIR$/build/generated" isTestSource="false" generated="true" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/core/src/main/java" isTestSource="false" />
|
<sourceFolder url="file://$MODULE_DIR$/core/src/main/java" isTestSource="false" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/core/src/test/java" isTestSource="true" />
|
<sourceFolder url="file://$MODULE_DIR$/core/src/test/java" isTestSource="true" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/core/src/main/resources/templates" />
|
<sourceFolder url="file://$MODULE_DIR$/core/src/main/resources" type="java-resource" relativeOutputPath="resources" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/src/main/resources/templates" />
|
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" relativeOutputPath="resources" />
|
||||||
</content>
|
</content>
|
||||||
<orderEntry type="inheritedJdk" />
|
<orderEntry type="inheritedJdk" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
|
@ -27,6 +27,5 @@
|
||||||
<orderEntry type="library" name="compile" level="project" />
|
<orderEntry type="library" name="compile" level="project" />
|
||||||
<orderEntry type="library" scope="RUNTIME" name="runtime" level="project" />
|
<orderEntry type="library" scope="RUNTIME" name="runtime" level="project" />
|
||||||
<orderEntry type="library" scope="TEST" name="test" level="project" />
|
<orderEntry type="library" scope="TEST" name="test" level="project" />
|
||||||
<orderEntry type="module" module-name="bld" />
|
|
||||||
</component>
|
</component>
|
||||||
</module>
|
</module>
|
||||||
8
.idea/bld.xml
Normal file
8
.idea/bld.xml
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="BldConfiguration">
|
||||||
|
<events>
|
||||||
|
<executeOn event="beforeCompilation" command="generate-grammar" />
|
||||||
|
</events>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
6
.idea/inspectionProfiles/Project_Default.xml
Normal file
6
.idea/inspectionProfiles/Project_Default.xml
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<profile version="1.0">
|
||||||
|
<option name="myName" value="Project Default" />
|
||||||
|
<inspection_tool class="OctalLiteral" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
|
</profile>
|
||||||
|
</component>
|
||||||
|
|
@ -2,11 +2,12 @@
|
||||||
<library name="bld">
|
<library name="bld">
|
||||||
<CLASSES>
|
<CLASSES>
|
||||||
<root url="file://$PROJECT_DIR$/lib/bld" />
|
<root url="file://$PROJECT_DIR$/lib/bld" />
|
||||||
<root url="jar://$USER_HOME$/.bld/dist/bld-1.7.0.jar!/" />
|
<root url="jar://$USER_HOME$/.bld/dist/bld-2.3.0.jar!/" />
|
||||||
</CLASSES>
|
</CLASSES>
|
||||||
<JAVADOC />
|
<JAVADOC />
|
||||||
<SOURCES>
|
<SOURCES>
|
||||||
<root url="jar://$USER_HOME$/.bld/dist/bld-1.7.0-sources.jar!/" />
|
<root url="file://$PROJECT_DIR$/lib/bld" />
|
||||||
|
<root url="jar://$USER_HOME$/.bld/dist/bld-2.3.0-sources.jar!/" />
|
||||||
</SOURCES>
|
</SOURCES>
|
||||||
<excluded>
|
<excluded>
|
||||||
<root url="jar://$PROJECT_DIR$/lib/bld/bld-wrapper.jar!/" />
|
<root url="jar://$PROJECT_DIR$/lib/bld/bld-wrapper.jar!/" />
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,16 @@
|
||||||
<library name="compile">
|
<library name="compile">
|
||||||
<CLASSES>
|
<CLASSES>
|
||||||
<root url="file://$PROJECT_DIR$/lib/compile" />
|
<root url="file://$PROJECT_DIR$/lib/compile" />
|
||||||
|
<root url="file://$PROJECT_DIR$/lib/provided" />
|
||||||
</CLASSES>
|
</CLASSES>
|
||||||
<JAVADOC />
|
<JAVADOC />
|
||||||
<SOURCES>
|
<SOURCES>
|
||||||
<root url="file://$PROJECT_DIR$/lib/compile" />
|
<root url="file://$PROJECT_DIR$/lib/compile" />
|
||||||
|
<root url="file://$PROJECT_DIR$/lib/provided" />
|
||||||
</SOURCES>
|
</SOURCES>
|
||||||
<jarDirectory url="file://$PROJECT_DIR$/lib/compile" recursive="false" />
|
<jarDirectory url="file://$PROJECT_DIR$/lib/compile" recursive="true" />
|
||||||
<jarDirectory url="file://$PROJECT_DIR$/lib/compile" recursive="false" type="SOURCES" />
|
<jarDirectory url="file://$PROJECT_DIR$/lib/compile" recursive="true" type="SOURCES" />
|
||||||
|
<jarDirectory url="file://$PROJECT_DIR$/lib/provided" recursive="true" />
|
||||||
|
<jarDirectory url="file://$PROJECT_DIR$/lib/provided" recursive="true" type="SOURCES" />
|
||||||
</library>
|
</library>
|
||||||
</component>
|
</component>
|
||||||
|
|
@ -3,12 +3,13 @@
|
||||||
<CLASSES>
|
<CLASSES>
|
||||||
<root url="file://$PROJECT_DIR$/lib/runtime" />
|
<root url="file://$PROJECT_DIR$/lib/runtime" />
|
||||||
<root url="file://$PROJECT_DIR$/src/main/resources" />
|
<root url="file://$PROJECT_DIR$/src/main/resources" />
|
||||||
|
<root url="file://$PROJECT_DIR$/core/src/main/resources" />
|
||||||
</CLASSES>
|
</CLASSES>
|
||||||
<JAVADOC />
|
<JAVADOC />
|
||||||
<SOURCES>
|
<SOURCES>
|
||||||
<root url="file://$PROJECT_DIR$/lib/runtime" />
|
<root url="file://$PROJECT_DIR$/lib/runtime" />
|
||||||
</SOURCES>
|
</SOURCES>
|
||||||
<jarDirectory url="file://$PROJECT_DIR$/lib/runtime" recursive="false" />
|
<jarDirectory url="file://$PROJECT_DIR$/lib/runtime" recursive="true" />
|
||||||
<jarDirectory url="file://$PROJECT_DIR$/lib/runtime" recursive="false" type="SOURCES" />
|
<jarDirectory url="file://$PROJECT_DIR$/lib/runtime" recursive="true" type="SOURCES" />
|
||||||
</library>
|
</library>
|
||||||
</component>
|
</component>
|
||||||
|
|
@ -2,14 +2,18 @@
|
||||||
<library name="test">
|
<library name="test">
|
||||||
<CLASSES>
|
<CLASSES>
|
||||||
<root url="file://$PROJECT_DIR$/lib/test" />
|
<root url="file://$PROJECT_DIR$/lib/test" />
|
||||||
|
<root url="file://$PROJECT_DIR$/lib/provided" />
|
||||||
<root url="file://$PROJECT_DIR$/src/test/resources" />
|
<root url="file://$PROJECT_DIR$/src/test/resources" />
|
||||||
<root url="file://$PROJECT_DIR$/core/src/test/resources" />
|
<root url="file://$PROJECT_DIR$/core/src/test/resources" />
|
||||||
</CLASSES>
|
</CLASSES>
|
||||||
<JAVADOC />
|
<JAVADOC />
|
||||||
<SOURCES>
|
<SOURCES>
|
||||||
<root url="file://$PROJECT_DIR$/lib/test" />
|
<root url="file://$PROJECT_DIR$/lib/test" />
|
||||||
|
<root url="file://$PROJECT_DIR$/lib/provided" />
|
||||||
</SOURCES>
|
</SOURCES>
|
||||||
<jarDirectory url="file://$PROJECT_DIR$/lib/test" recursive="false" />
|
<jarDirectory url="file://$PROJECT_DIR$/lib/provided" recursive="true" />
|
||||||
<jarDirectory url="file://$PROJECT_DIR$/lib/test" recursive="false" type="SOURCES" />
|
<jarDirectory url="file://$PROJECT_DIR$/lib/test" recursive="true" />
|
||||||
|
<jarDirectory url="file://$PROJECT_DIR$/lib/provided" recursive="true" type="SOURCES" />
|
||||||
|
<jarDirectory url="file://$PROJECT_DIR$/lib/test" recursive="true" type="SOURCES" />
|
||||||
</library>
|
</library>
|
||||||
</component>
|
</component>
|
||||||
|
|
@ -1,9 +1,30 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
|
<component name="EntryPointsManager">
|
||||||
|
<entry_points version="2.0">
|
||||||
|
<entry_point TYPE="field" FQNAME="rife.bld.operations.JpackageOptions.PackageType APP_IMAGE" />
|
||||||
|
<entry_point TYPE="field" FQNAME="rife.bld.operations.JpackageOptions.PackageType DMG" />
|
||||||
|
<entry_point TYPE="field" FQNAME="rife.bld.operations.JpackageOptions.PackageType MSI" />
|
||||||
|
<entry_point TYPE="field" FQNAME="rife.bld.operations.JpackageOptions.PackageType PKG" />
|
||||||
|
<entry_point TYPE="field" FQNAME="rife.bld.operations.JpackageOptions.PackageType RPM" />
|
||||||
|
<entry_point TYPE="field" FQNAME="rife.bld.operations.JlinkOptions.CompressionLevel CONSTANT_STRING_SHARING" />
|
||||||
|
<entry_point TYPE="field" FQNAME="rife.bld.operations.JlinkOptions.CompressionLevel NO_COMPRESSION" />
|
||||||
|
<entry_point TYPE="field" FQNAME="rife.bld.operations.JlinkOptions.Endian LITTLE" />
|
||||||
|
<entry_point TYPE="field" FQNAME="rife.bld.operations.JmodOperation.OperationMode EXTRACT" />
|
||||||
|
<entry_point TYPE="field" FQNAME="rife.bld.operations.JmodOperation.OperationMode HASH" />
|
||||||
|
<entry_point TYPE="field" FQNAME="rife.bld.operations.JmodOptions.ResolvedReason DEPRECATED_FOR_REMOVAL" />
|
||||||
|
<entry_point TYPE="field" FQNAME="rife.bld.operations.JmodOptions.ResolvedReason INCUBATING" />
|
||||||
|
</entry_points>
|
||||||
|
<pattern value="rife.bld.operations.JpackageOptions.PackageType" />
|
||||||
|
<pattern value="rife.bld.operations.JlinkOptions.CompressionLevel" />
|
||||||
|
<pattern value="rife.bld.operations.JlinkOptions.Endian" />
|
||||||
|
<pattern value="rife.bld.operations.JmodOperation.OperationMode" />
|
||||||
|
<pattern value="rife.bld.operations.JmodOptions.ResolvedReason" />
|
||||||
|
</component>
|
||||||
<component name="PDMPlugin">
|
<component name="PDMPlugin">
|
||||||
<option name="skipTestSources" value="false" />
|
<option name="skipTestSources" value="false" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" project-jdk-name="19" project-jdk-type="JavaSDK">
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" project-jdk-name="17" project-jdk-type="JavaSDK">
|
||||||
<output url="file://$PROJECT_DIR$/build" />
|
<output url="file://$PROJECT_DIR$/build" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
<component name="ProjectRunConfigurationManager">
|
<component name="ProjectRunConfigurationManager">
|
||||||
<configuration default="false" name="Run Tests" type="JUnit" factoryName="JUnit">
|
<configuration default="false" name="Run all tests" type="JUnit" factoryName="JUnit">
|
||||||
<module name="app" />
|
<module name="app" />
|
||||||
|
<useClassPathOnly />
|
||||||
<option name="PACKAGE_NAME" value="rife" />
|
<option name="PACKAGE_NAME" value="rife" />
|
||||||
<option name="MAIN_CLASS_NAME" value="" />
|
<option name="MAIN_CLASS_NAME" value="" />
|
||||||
<option name="METHOD_NAME" value="" />
|
<option name="METHOD_NAME" value="" />
|
||||||
20
.idea/runConfigurations/Run_bld_tests.xml
Normal file
20
.idea/runConfigurations/Run_bld_tests.xml
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
<component name="ProjectRunConfigurationManager">
|
||||||
|
<configuration default="false" name="Run bld tests" type="JUnit" factoryName="JUnit">
|
||||||
|
<module name="app" />
|
||||||
|
<useClassPathOnly />
|
||||||
|
<extension name="coverage">
|
||||||
|
<pattern>
|
||||||
|
<option name="PATTERN" value="rife.bld.*" />
|
||||||
|
<option name="ENABLED" value="true" />
|
||||||
|
</pattern>
|
||||||
|
</extension>
|
||||||
|
<option name="PACKAGE_NAME" value="rife.bld" />
|
||||||
|
<option name="MAIN_CLASS_NAME" value="" />
|
||||||
|
<option name="METHOD_NAME" value="" />
|
||||||
|
<option name="TEST_OBJECT" value="package" />
|
||||||
|
<dir value="$PROJECT_DIR$/src/test/java" />
|
||||||
|
<method v="2">
|
||||||
|
<option name="Make" enabled="true" />
|
||||||
|
</method>
|
||||||
|
</configuration>
|
||||||
|
</component>
|
||||||
6
.idea/scala_compiler.xml
Normal file
6
.idea/scala_compiler.xml
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ScalaCompilerConfiguration">
|
||||||
|
<option name="separateProdTestSources" value="false" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
20
CONTRIBUTING.md
Normal file
20
CONTRIBUTING.md
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
# Contributing
|
||||||
|
|
||||||
|
If you want to contribute to `bld` or customize it, all you have to do is clone the GitHub
|
||||||
|
repository and update the [RIFE2/core](https://github.com/rife2/rife2-core) submodule:
|
||||||
|
|
||||||
|
```console
|
||||||
|
git clone git@github.com:rife2/bld.git
|
||||||
|
cd bld
|
||||||
|
git submodule init
|
||||||
|
git submodule update
|
||||||
|
```
|
||||||
|
|
||||||
|
Then use `bld` to build itself:
|
||||||
|
|
||||||
|
```console
|
||||||
|
./bld compile
|
||||||
|
```
|
||||||
|
|
||||||
|
The project has an IntelliJ IDEA project structure. You can just open it after all
|
||||||
|
the dependencies were downloaded and peruse the code.
|
||||||
73
README.md
73
README.md
|
|
@ -1,8 +1,9 @@
|
||||||
[](https://opensource.org/licenses/Apache-2.0)
|
[](https://opensource.org/licenses/Apache-2.0)
|
||||||
[](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html)
|
[](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html)
|
||||||
|
[](https://rife2.com/bld)
|
||||||
[](https://github.com/rife2/bld/releases/latest)
|
[](https://github.com/rife2/bld/releases/latest)
|
||||||
[](https://maven-badges.herokuapp.com/maven-central/com.uwyn.rife2/bld)
|
[](https://maven-badges.herokuapp.com/maven-central/com.uwyn.rife2/bld)
|
||||||
[](https://s01.oss.sonatype.org/content/repositories/snapshots/com/uwyn/rife2/bld/)
|
[](https://github.com/rife2/bld/packages/2214741/versions)
|
||||||
[](https://github.com/rife2/bld/actions/workflows/bld.yml)
|
[](https://github.com/rife2/bld/actions/workflows/bld.yml)
|
||||||
[](https://github.com/rife2/rife2/actions/workflows/bld.yml)
|
[](https://github.com/rife2/rife2/actions/workflows/bld.yml)
|
||||||
|
|
||||||
|
|
@ -33,7 +34,8 @@ bld relies on Java 17 and leverages many of the features that this version of
|
||||||
Java provides. Thanks to the modern language constructs, your Java build logic
|
Java provides. Thanks to the modern language constructs, your Java build logic
|
||||||
ends up looking very concise, is easily readable and understood by any IDE.
|
ends up looking very concise, is easily readable and understood by any IDE.
|
||||||
You automatically get support for auto-completion and javadoc documentation,
|
You automatically get support for auto-completion and javadoc documentation,
|
||||||
and you can split your build logic into multiple files and classes when you outgrow a single file.
|
and you can split your build logic into multiple files and classes when you
|
||||||
|
outgrow a single file.
|
||||||
|
|
||||||
Here is a complete bld file for a Java application using JUnit 5 for its tests.
|
Here is a complete bld file for a Java application using JUnit 5 for its tests.
|
||||||
Nothing else is needed to be able to run it, test it and distribute it:
|
Nothing else is needed to be able to run it, test it and distribute it:
|
||||||
|
|
@ -46,34 +48,29 @@ import java.util.List;
|
||||||
import static rife.bld.dependencies.Repository.*;
|
import static rife.bld.dependencies.Repository.*;
|
||||||
import static rife.bld.dependencies.Scope.*;
|
import static rife.bld.dependencies.Scope.*;
|
||||||
|
|
||||||
public class MyappBuild extends Project {
|
public class MyAppBuild extends Project {
|
||||||
public MyappBuild() {
|
public MyAppBuild() {
|
||||||
pkg = "com.example";
|
pkg = "com.example";
|
||||||
name = "Myapp";
|
name = "my-app";
|
||||||
mainClass = "com.example.MyappMain";
|
mainClass = "com.example.MyApp";
|
||||||
version = version(0,1,0);
|
version = version(0,1,0);
|
||||||
|
|
||||||
downloadSources = true;
|
downloadSources = true;
|
||||||
repositories = List.of(MAVEN_CENTRAL, RIFE2_RELEASES);
|
repositories = List.of(MAVEN_CENTRAL, RIFE2_RELEASES);
|
||||||
scope(test)
|
scope(test)
|
||||||
.include(dependency("org.junit.jupiter",
|
.include(dependency("org.junit.jupiter", "junit-jupiter", version(5,11,4)))
|
||||||
"junit-jupiter",
|
.include(dependency("org.junit.platform", "junit-platform-console-standalone", version(1,11,4)));
|
||||||
version(5,9,2)))
|
|
||||||
.include(dependency("org.junit.platform",
|
|
||||||
"junit-platform-console-standalone",
|
|
||||||
version(1,9,2)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
new MyappBuild().start(args);
|
new MyAppBuild().start(args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
> **NOTE:** `bld` supports different ways to describe dependencies,
|
> **NOTE:** `bld` supports different ways to describe dependencies,
|
||||||
> `dependency("com.uwyn.rife2", "rife2", version(1,6,3))` can for instance also
|
> `dependency("org.junit.jupiter", "junit-jupiter", version(5,11,4))` can for instance also
|
||||||
> be written as `dependency("com.uwyn.rife2:rife2:1.6.3")`. Which format you use,
|
> be written as `dependency("org.junit.jupiter:junit-jupiter:5.11.4")`. Which format you use,
|
||||||
> is a matter of personal taste.
|
> is a matter of personal taste.
|
||||||
|
|
||||||
# Where does `bld` fit?
|
# Where does `bld` fit?
|
||||||
|
|
@ -94,15 +91,47 @@ significantly reduces the cognitive load, and taking actions immediately
|
||||||
without having to mentally construct a described plan, makes it easier to
|
without having to mentally construct a described plan, makes it easier to
|
||||||
reason about your build.
|
reason about your build.
|
||||||
|
|
||||||
|
# IDE support
|
||||||
|
|
||||||
|
<img src="https://rife2.com/images/bld-idea.png" style="width: 100%">
|
||||||
|
|
||||||
|
Since version 2.0, bld comes with its own [IntelliJ IDEA plugin](https://github.com/rife2/bld-idea):
|
||||||
|
|
||||||
|
* detect `bld` projects and find their main Java class
|
||||||
|
* quick access to open and edit the main Java class and wrapper properties of `bld` projects
|
||||||
|
* list all the commands in `bld` projects in a side panel
|
||||||
|
* execute one or multiple commands in the order they were selected
|
||||||
|
* reload the commands in the `bld` project
|
||||||
|
* terminate currently running `bld` commands
|
||||||
|
* `bld` console panel for command output with source code hyperlinking
|
||||||
|
* display the `bld` dependency tree
|
||||||
|
* toggle to run `bld` in offline or online mode
|
||||||
|
* auto-save all open files before executing a `bld` command
|
||||||
|
* convenient `bld` one-click cache invalidation
|
||||||
|
* set `bld` commands to run before or after IDEA compilation
|
||||||
|
* create custom `bld` command run configuration with options, JVM arguments, and before launch tasks
|
||||||
|
* assign keyboard shortcuts to `bld` commands
|
||||||
|
|
||||||
# Find out more
|
# Find out more
|
||||||
|
|
||||||
`bld` lets your build logic get out of the way so that you can focus on writing
|
`bld` lets your build logic get out of the way so that you can focus on writing
|
||||||
applications.
|
applications.
|
||||||
|
|
||||||
If you have any questions, suggestions, ideas or just want to chat, feel free
|
Get started immediately by [installing](https://github.com/rife2/bld/wiki/Installation) `bld`
|
||||||
to post on the [forums](https://github.com/rife2/bld/discussions), to join
|
through Homebrew, SDKMAN!, JBang, zip archive, or run it directly from its jar file.
|
||||||
me on [Discord](https://discord.gg/DZRYPtkb6J) or to connect with me on
|
|
||||||
[Mastodon](https://uwyn.net/@gbevin).
|
|
||||||
|
|
||||||
**Read more in the [full documentation](https://github.com/rife2/bld/wiki)
|
If you merely want to create a new project, `bld` can also be used by executing this one-liner:
|
||||||
and [bld Javadocs](https://rife2.github.io/bld/).**
|
|
||||||
|
```console
|
||||||
|
bash -c "$(curl -fsSL https://rife2.com/bld/create.sh)"
|
||||||
|
```
|
||||||
|
|
||||||
|
If you have any questions, suggestions, ideas or just want to chat, feel free
|
||||||
|
to post on the [forums](https://forum.uwyn.com) or to join us on [Discord](https://discord.gg/zDG6anEXQX).
|
||||||
|
|
||||||
|
Read more in the [full documentation](https://github.com/rife2/bld/wiki) and [bld Javadocs](https://rife2.github.io/bld/).
|
||||||
|
|
||||||
|
# Contributing
|
||||||
|
|
||||||
|
See [CONTIBUTING.md](https://github.com/rife2/bld?tab=contributing-ov-file#readme) for information about
|
||||||
|
contributing to this project.
|
||||||
|
|
|
||||||
2
core
2
core
|
|
@ -1 +1 @@
|
||||||
Subproject commit 31b722572483047afe80cb05bc0eef6d571a18a4
|
Subproject commit fa567721c00d99626ed439db4f0340eadff0ec03
|
||||||
Binary file not shown.
|
|
@ -1,9 +1,12 @@
|
||||||
bld.downloadExtensionJavadoc=false
|
bld.downloadExtensionJavadoc=false
|
||||||
bld.downloadExtensionSources=true
|
bld.downloadExtensionSources=true
|
||||||
bld.extension-antlr=com.uwyn.rife2:bld-antlr4:1.2.0
|
|
||||||
bld.extension-archive=com.uwyn.rife2:bld-archive:0.4.0
|
|
||||||
bld.extension-tests=com.uwyn.rife2:bld-tests-badge:1.4.0
|
|
||||||
bld.repositories=MAVEN_CENTRAL,RIFE2_RELEASES
|
|
||||||
bld.downloadLocation=
|
bld.downloadLocation=
|
||||||
|
bld.extension-antlr=com.uwyn.rife2:bld-antlr4:1.4.3
|
||||||
|
bld.extension-archive=com.uwyn.rife2:bld-archive:0.6.3
|
||||||
|
bld.extension-reporter=com.uwyn.rife2:bld-junit-reporter:0.9.2
|
||||||
|
bld.extension-tests=com.uwyn.rife2:bld-tests-badge:1.6.3
|
||||||
|
bld.javaOptions=
|
||||||
|
bld.javacOptions=
|
||||||
|
bld.repositories=MAVEN_CENTRAL,RIFE2_RELEASES
|
||||||
bld.sourceDirectories=core/src/bld/java
|
bld.sourceDirectories=core/src/bld/java
|
||||||
bld.version=1.7.0
|
bld.version=2.3.0
|
||||||
1
local.properties
Normal file
1
local.properties
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
bld.repo.github=https://maven.pkg.github.com/rife2/bld
|
||||||
|
|
@ -6,6 +6,8 @@ package rife;
|
||||||
|
|
||||||
import rife.bld.BuildCommand;
|
import rife.bld.BuildCommand;
|
||||||
import rife.bld.Cli;
|
import rife.bld.Cli;
|
||||||
|
import rife.bld.dependencies.VersionNumber;
|
||||||
|
import rife.bld.extension.JUnitReporterOperation;
|
||||||
import rife.bld.extension.ZipOperation;
|
import rife.bld.extension.ZipOperation;
|
||||||
import rife.bld.operations.*;
|
import rife.bld.operations.*;
|
||||||
import rife.bld.publish.*;
|
import rife.bld.publish.*;
|
||||||
|
|
@ -28,39 +30,42 @@ public class BldBuild extends AbstractRife2Build {
|
||||||
throws Exception {
|
throws Exception {
|
||||||
name = "bld";
|
name = "bld";
|
||||||
mainClass = "rife.bld.Cli";
|
mainClass = "rife.bld.Cli";
|
||||||
version = version(FileUtils.readString(new File(srcMainResourcesDirectory(), "BLD_VERSION")));
|
version = VersionNumber.parse(FileUtils.readString(new File(srcMainResourcesDirectory(), "BLD_VERSION")));
|
||||||
|
|
||||||
repositories = List.of(MAVEN_CENTRAL, RIFE2_RELEASES);
|
repositories = List.of(MAVEN_CENTRAL, RIFE2_RELEASES);
|
||||||
scope(test)
|
scope(test)
|
||||||
.include(dependency("org.json", "json", version(20230227)));
|
.include(dependency("org.json", "json", version(20250517)));
|
||||||
|
|
||||||
var core_directory = new File(workDirectory(), "core");
|
var core_dir = new File(workDirectory(), "core");
|
||||||
var core_src_directory = new File(core_directory, "src");
|
var core_src_dir = new File(core_dir, "src");
|
||||||
var core_src_main_directory = new File(core_src_directory, "main");
|
var core_src_main_dir = new File(core_src_dir, "main");
|
||||||
var core_src_main_java_directory = new File(core_src_main_directory, "java");
|
|
||||||
var core_src_main_resources_directory = new File(core_src_main_directory, "resources");
|
|
||||||
var core_src_test_directory = new File(core_src_directory, "test");
|
|
||||||
var core_src_test_java_directory = new File(core_src_test_directory, "java");
|
|
||||||
var core_src_test_resources_directory = new File(core_src_test_directory, "resources");
|
|
||||||
var core_src_main_resources_templates_directory = new File(core_src_main_resources_directory, "templates");
|
|
||||||
|
|
||||||
antlr4Operation
|
antlr4Operation
|
||||||
.sourceDirectories(List.of(new File(core_src_main_directory, "antlr")))
|
.sourceDirectories(List.of(new File(core_src_main_dir, "antlr")));
|
||||||
.outputDirectory(new File(buildDirectory(), "generated/rife/template/antlr"));
|
|
||||||
|
|
||||||
precompileOperation()
|
var core_src_test_dir = new File(core_src_dir, "test");
|
||||||
.sourceDirectories(core_src_main_resources_templates_directory)
|
var core_src_test_java_dir = new File(core_src_test_dir, "java");
|
||||||
.templateTypes(HTML, XML, SQL, TXT, JSON);
|
var core_src_main_java_dir = new File(core_src_main_dir, "java");
|
||||||
|
|
||||||
compileOperation()
|
compileOperation()
|
||||||
.mainSourceDirectories(antlr4Operation.outputDirectory(), core_src_main_java_directory)
|
.mainSourceDirectories(antlr4Operation.outputDirectory(), core_src_main_java_dir)
|
||||||
.testSourceDirectories(core_src_test_java_directory)
|
.testSourceDirectories(core_src_test_java_dir)
|
||||||
.compileOptions()
|
.compileOptions()
|
||||||
.debuggingInfo(JavacOptions.DebuggingInfo.ALL);
|
.debuggingInfo(JavacOptions.DebuggingInfo.ALL)
|
||||||
|
.addAll(List.of("-encoding", "UTF-8"));
|
||||||
|
|
||||||
|
var core_src_main_resources_dir = new File(core_src_main_dir, "resources");
|
||||||
|
var core_src_main_resources_templates_dir = new File(core_src_main_resources_dir, "templates");
|
||||||
|
|
||||||
|
precompileOperation()
|
||||||
|
.sourceDirectories(core_src_main_resources_templates_dir)
|
||||||
|
.templateTypes(HTML, XML, SQL, TXT, JSON);
|
||||||
|
|
||||||
|
var core_src_test_resources_dir = new File(core_src_test_dir, "resources");
|
||||||
|
|
||||||
jarOperation()
|
jarOperation()
|
||||||
.sourceDirectories(core_src_main_resources_directory)
|
.sourceDirectories(core_src_main_resources_dir)
|
||||||
.excluded(Pattern.compile("^\\Q" + core_src_main_resources_templates_directory.getAbsolutePath() + "\\E.*"))
|
.excluded(Pattern.compile("^\\Q" + core_src_main_resources_templates_dir.getAbsolutePath() + "\\E.*"))
|
||||||
.manifestAttribute(Attributes.Name.MAIN_CLASS, mainClass());
|
.manifestAttribute(Attributes.Name.MAIN_CLASS, mainClass());
|
||||||
|
|
||||||
zipBldOperation
|
zipBldOperation
|
||||||
|
|
@ -68,18 +73,22 @@ public class BldBuild extends AbstractRife2Build {
|
||||||
.destinationFileName("bld-" + version() + ".zip");
|
.destinationFileName("bld-" + version() + ".zip");
|
||||||
|
|
||||||
testsBadgeOperation
|
testsBadgeOperation
|
||||||
.classpath(core_src_main_resources_directory.getAbsolutePath())
|
.classpath(core_src_main_resources_dir.getAbsolutePath())
|
||||||
.classpath(core_src_test_resources_directory.getAbsolutePath());
|
.classpath(core_src_test_resources_dir.getAbsolutePath());
|
||||||
|
|
||||||
javadocOperation()
|
javadocOperation()
|
||||||
.sourceFiles(FileUtils.getJavaFileList(core_src_main_java_directory))
|
.sourceFiles(FileUtils.getJavaFileList(core_src_main_java_dir))
|
||||||
.javadocOptions()
|
.javadocOptions()
|
||||||
.docTitle("<a href=\"https://rife2.com/bld\">bld</a> " + version())
|
.docTitle("<a href=\"https://rife2.com/bld\">bld</a> " + version())
|
||||||
.overview(new File(srcMainJavaDirectory(), "overview.html"));
|
.overview(new File(srcMainJavaDirectory(), "overview.html"))
|
||||||
|
.addAll(List.of("--allow-script-in-comments",
|
||||||
|
"-group", "bld", "rife.bld*",
|
||||||
|
"-group", "RIFE2/core", "rife:rife.cmf*:rife.config*:rife.database*:rife.datastructures*:rife.engine*:rife.forms*:rife.instrument*:rife.ioc*:rife.resources*:rife.selector*:rife.template*:rife.tools*:rife.validation*:rife.xml*"));
|
||||||
|
|
||||||
publishOperation()
|
publishOperation()
|
||||||
.repository(version.isSnapshot() ? repository("rife2-snapshots") : repository("rife2-releases"))
|
.repository(version.isSnapshot() ? repository("rife2-snapshots") : repository("rife2-releases"))
|
||||||
.repository(version.isSnapshot() ? repository("sonatype-snapshots") : repository("sonatype-releases"))
|
.repository(version.isSnapshot() ? repository("central-snapshots") : repository("central-releases"))
|
||||||
|
.repository(repository("github"))
|
||||||
.info(new PublishInfo()
|
.info(new PublishInfo()
|
||||||
.groupId("com.uwyn.rife2")
|
.groupId("com.uwyn.rife2")
|
||||||
.artifactId("bld")
|
.artifactId("bld")
|
||||||
|
|
@ -104,7 +113,6 @@ public class BldBuild extends AbstractRife2Build {
|
||||||
new PublishArtifact(zipBldOperation.destinationFile(), "", "zip"));
|
new PublishArtifact(zipBldOperation.destinationFile(), "", "zip"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
final ZipOperation zipBldOperation = new ZipOperation();
|
final ZipOperation zipBldOperation = new ZipOperation();
|
||||||
@BuildCommand(value = "zip-bld", summary = "Creates the bld zip archive")
|
@BuildCommand(value = "zip-bld", summary = "Creates the bld zip archive")
|
||||||
public void zipBld()
|
public void zipBld()
|
||||||
|
|
@ -132,11 +140,9 @@ public class BldBuild extends AbstractRife2Build {
|
||||||
f.perms(0755);
|
f.perms(0755);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
b.dir("lib", l -> {
|
b.dir("lib", l -> l.file("bld-wrapper.jar", f -> f.move(path(tmp, "lib", "bld", "bld-wrapper.jar"))));
|
||||||
l.file("bld-wrapper.jar", f -> f.move(path(tmp, "lib", "bld", "bld-wrapper.jar")));
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
t.dir("lib", l -> l.delete());
|
t.dir("lib", DirBuilder::delete);
|
||||||
});
|
});
|
||||||
|
|
||||||
zipBldOperation
|
zipBldOperation
|
||||||
|
|
@ -156,6 +162,14 @@ public class BldBuild extends AbstractRife2Build {
|
||||||
zipBld();
|
zipBld();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@BuildCommand(summary = "Runs the JUnit reporter")
|
||||||
|
public void reporter() throws Exception {
|
||||||
|
new JUnitReporterOperation()
|
||||||
|
.fromProject(this)
|
||||||
|
.failOnSummary(true)
|
||||||
|
.execute();
|
||||||
|
}
|
||||||
|
|
||||||
public void publish()
|
public void publish()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
all();
|
all();
|
||||||
|
|
|
||||||
58
src/main/java/module-info.java
Normal file
58
src/main/java/module-info.java
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
/**
|
||||||
|
* bld is a new build system that allows you to write your build logic in pure Java.
|
||||||
|
* <p>
|
||||||
|
* More information can be found on the <a href="https://rife2.com/bld"><code>bld</code> website</a>.
|
||||||
|
* <p>
|
||||||
|
* Note that bld builds on top of the foundation that RIFE2 provides and includes the features
|
||||||
|
* of <a href="https://github.com/rife2/rife2-core">RIFE2/core</a>.
|
||||||
|
*
|
||||||
|
* @since 2.1.0
|
||||||
|
*/
|
||||||
|
module rife.bld {
|
||||||
|
requires java.compiler;
|
||||||
|
requires java.desktop;
|
||||||
|
requires java.logging;
|
||||||
|
requires java.net.http;
|
||||||
|
requires java.prefs;
|
||||||
|
requires static java.sql;
|
||||||
|
requires java.xml;
|
||||||
|
|
||||||
|
exports rife.bld;
|
||||||
|
exports rife.bld.blueprints;
|
||||||
|
exports rife.bld.dependencies;
|
||||||
|
exports rife.bld.dependencies.exceptions;
|
||||||
|
exports rife.bld.help;
|
||||||
|
exports rife.bld.instrument;
|
||||||
|
exports rife.bld.operations;
|
||||||
|
exports rife.bld.operations.exceptions;
|
||||||
|
exports rife.bld.publish;
|
||||||
|
|
||||||
|
exports rife;
|
||||||
|
exports rife.cmf;
|
||||||
|
exports rife.cmf.transform;
|
||||||
|
exports rife.config;
|
||||||
|
exports rife.config.exceptions;
|
||||||
|
exports rife.database;
|
||||||
|
exports rife.database.exceptions;
|
||||||
|
exports rife.database.queries;
|
||||||
|
exports rife.database.querymanagers.generic;
|
||||||
|
exports rife.database.querymanagers.generic.exceptions;
|
||||||
|
exports rife.database.types;
|
||||||
|
exports rife.datastructures;
|
||||||
|
exports rife.engine;
|
||||||
|
exports rife.forms;
|
||||||
|
exports rife.ioc;
|
||||||
|
exports rife.ioc.exceptions;
|
||||||
|
exports rife.resources;
|
||||||
|
exports rife.resources.exceptions;
|
||||||
|
exports rife.selector;
|
||||||
|
exports rife.template;
|
||||||
|
exports rife.template.exceptions;
|
||||||
|
exports rife.tools;
|
||||||
|
exports rife.tools.exceptions;
|
||||||
|
exports rife.validation;
|
||||||
|
exports rife.validation.annotations;
|
||||||
|
exports rife.validation.exceptions;
|
||||||
|
exports rife.xml;
|
||||||
|
exports rife.xml.exceptions;
|
||||||
|
}
|
||||||
24
src/main/java/overview.html
Normal file
24
src/main/java/overview.html
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<p><code>bld</code> is a new build system that allows you to write your build logic in pure Java.</p>
|
||||||
|
|
||||||
|
<p><code>bld</code>'s website is <a href="https://rife2.com/bld">https://rife2.com/bld</a>.</p>
|
||||||
|
<p>The GitHub project is at <a href="https://github.com/rife2/bld">https://github.com/rife2/bld</a></p>
|
||||||
|
<p>The documentation is available at <a href="https://github.com/rife2/bld/wiki">https://github.com/rife2/bld/wiki</a></p>
|
||||||
|
|
||||||
|
<p>Note that bld builds on top of the foundation that RIFE2 provides and includes the features of
|
||||||
|
<a href="https://github.com/rife2/rife2-core">RIFE2/core</a>.</p>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
window.onload = function () {
|
||||||
|
show('all-packages-table', 'all-packages-table-tab1', 2);
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
#all-packages-table-tab0 {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -5,20 +5,17 @@
|
||||||
package rife.bld;
|
package rife.bld;
|
||||||
|
|
||||||
import rife.bld.dependencies.*;
|
import rife.bld.dependencies.*;
|
||||||
|
import rife.bld.dependencies.Module;
|
||||||
import rife.bld.help.*;
|
import rife.bld.help.*;
|
||||||
import rife.bld.operations.*;
|
import rife.bld.operations.*;
|
||||||
import rife.tools.FileUtils;
|
import rife.tools.FileUtils;
|
||||||
import rife.tools.StringUtils;
|
|
||||||
import rife.tools.exceptions.FileUtilsErrorException;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.security.MessageDigest;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import static rife.bld.dependencies.Scope.runtime;
|
import static rife.bld.dependencies.Scope.runtime;
|
||||||
|
import static rife.bld.dependencies.VersionNumber.SNAPSHOT_QUALIFIER;
|
||||||
import static rife.tools.FileUtils.JAR_FILE_PATTERN;
|
import static rife.tools.FileUtils.JAR_FILE_PATTERN;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -58,12 +55,19 @@ public class BaseProject extends BuildExecutor {
|
||||||
*/
|
*/
|
||||||
protected VersionNumber version = null;
|
protected VersionNumber version = null;
|
||||||
/**
|
/**
|
||||||
* The project's main class.
|
* The project's main class to execute.
|
||||||
*
|
*
|
||||||
* @see #mainClass()
|
* @see #mainClass()
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
protected String mainClass = null;
|
protected String mainClass = null;
|
||||||
|
/**
|
||||||
|
* The project's module to execute.
|
||||||
|
*
|
||||||
|
* @see #module()
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
protected String module = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The project's repositories for dependency resolution.
|
* The project's repositories for dependency resolution.
|
||||||
|
|
@ -249,6 +253,27 @@ public class BaseProject extends BuildExecutor {
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
protected File libCompileDirectory = null;
|
protected File libCompileDirectory = null;
|
||||||
|
/**
|
||||||
|
* The modules compile scope lib directory.
|
||||||
|
*
|
||||||
|
* @see #libCompileModulesDirectory()
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
protected File libCompileModulesDirectory = null;
|
||||||
|
/**
|
||||||
|
* The provided scope lib directory.
|
||||||
|
*
|
||||||
|
* @see #libProvidedDirectory()
|
||||||
|
* @since 1.8
|
||||||
|
*/
|
||||||
|
protected File libProvidedDirectory = null;
|
||||||
|
/**
|
||||||
|
* The modules provided scope lib directory.
|
||||||
|
*
|
||||||
|
* @see #libProvidedModulesDirectory()
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
protected File libProvidedModulesDirectory = null;
|
||||||
/**
|
/**
|
||||||
* The runtime scope lib directory.
|
* The runtime scope lib directory.
|
||||||
*
|
*
|
||||||
|
|
@ -256,6 +281,13 @@ public class BaseProject extends BuildExecutor {
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
protected File libRuntimeDirectory = null;
|
protected File libRuntimeDirectory = null;
|
||||||
|
/**
|
||||||
|
* The modules runtime scope lib directory.
|
||||||
|
*
|
||||||
|
* @see #libRuntimeModulesDirectory()
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
protected File libRuntimeModulesDirectory = null;
|
||||||
/**
|
/**
|
||||||
* The standalone scope lib directory.
|
* The standalone scope lib directory.
|
||||||
*
|
*
|
||||||
|
|
@ -264,12 +296,26 @@ public class BaseProject extends BuildExecutor {
|
||||||
*/
|
*/
|
||||||
protected File libStandaloneDirectory = null;
|
protected File libStandaloneDirectory = null;
|
||||||
/**
|
/**
|
||||||
* The standalone scope lib directory.
|
* The modules standalone scope lib directory.
|
||||||
|
*
|
||||||
|
* @see #libStandaloneModulesDirectory()
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
protected File libStandaloneModulesDirectory = null;
|
||||||
|
/**
|
||||||
|
* The test scope lib directory.
|
||||||
*
|
*
|
||||||
* @see #libTestDirectory()
|
* @see #libTestDirectory()
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
protected File libTestDirectory = null;
|
protected File libTestDirectory = null;
|
||||||
|
/**
|
||||||
|
* The modules test scope lib directory.
|
||||||
|
*
|
||||||
|
* @see #libTestModulesDirectory()
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
protected File libTestModulesDirectory = null;
|
||||||
/**
|
/**
|
||||||
* The build directory.
|
* The build directory.
|
||||||
*
|
*
|
||||||
|
|
@ -680,8 +726,44 @@ public class BaseProject extends BuildExecutor {
|
||||||
* {@link VersionNumber#UNKNOWN} if the description couldn't be parsed
|
* {@link VersionNumber#UNKNOWN} if the description couldn't be parsed
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
public VersionNumber version(String description) {
|
public Version version(String description) {
|
||||||
return VersionNumber.parse(description);
|
return Version.parse(description);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new snapshot version instance.
|
||||||
|
*
|
||||||
|
* @param major the major component of the snapshot version number
|
||||||
|
* @return a newly created snapshot {@code VersionNumber} instance
|
||||||
|
* @since 1.7.4
|
||||||
|
*/
|
||||||
|
public VersionNumber snapshot(int major) {
|
||||||
|
return new VersionNumber(major, null, null, SNAPSHOT_QUALIFIER);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new snapshot version instance.
|
||||||
|
*
|
||||||
|
* @param major the major component of the snapshot version number
|
||||||
|
* @param minor the minor component of the snapshot version number
|
||||||
|
* @return a newly created snapshot {@code VersionNumber} instance
|
||||||
|
* @since 1.7.4
|
||||||
|
*/
|
||||||
|
public VersionNumber snapshot(int major, int minor) {
|
||||||
|
return new VersionNumber(major, minor, null, SNAPSHOT_QUALIFIER);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new snapshot version instance.
|
||||||
|
*
|
||||||
|
* @param major the major component of the snapshot version number
|
||||||
|
* @param minor the minor component of the snapshot version number
|
||||||
|
* @param revision the revision component of the snapshot version number
|
||||||
|
* @return a newly created snapshot {@code VersionNumber} instance
|
||||||
|
* @since 1.7.4
|
||||||
|
*/
|
||||||
|
public VersionNumber snapshot(int major, int minor, int revision) {
|
||||||
|
return new VersionNumber(major, minor, revision, SNAPSHOT_QUALIFIER);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -759,7 +841,7 @@ public class BaseProject extends BuildExecutor {
|
||||||
* @return a newly created {@code Dependency} instance
|
* @return a newly created {@code Dependency} instance
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
public Dependency dependency(String groupId, String artifactId, VersionNumber version) {
|
public Dependency dependency(String groupId, String artifactId, Version version) {
|
||||||
return new Dependency(groupId, artifactId, version);
|
return new Dependency(groupId, artifactId, version);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -773,7 +855,7 @@ public class BaseProject extends BuildExecutor {
|
||||||
* @return a newly created {@code Dependency} instance
|
* @return a newly created {@code Dependency} instance
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
public Dependency dependency(String groupId, String artifactId, VersionNumber version, String classifier) {
|
public Dependency dependency(String groupId, String artifactId, Version version, String classifier) {
|
||||||
return new Dependency(groupId, artifactId, version, classifier);
|
return new Dependency(groupId, artifactId, version, classifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -788,7 +870,7 @@ public class BaseProject extends BuildExecutor {
|
||||||
* @return a newly created {@code Dependency} instance
|
* @return a newly created {@code Dependency} instance
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
public Dependency dependency(String groupId, String artifactId, VersionNumber version, String classifier, String type) {
|
public Dependency dependency(String groupId, String artifactId, Version version, String classifier, String type) {
|
||||||
return new Dependency(groupId, artifactId, version, classifier, type);
|
return new Dependency(groupId, artifactId, version, classifier, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -821,6 +903,101 @@ public class BaseProject extends BuildExecutor {
|
||||||
return new LocalDependency(path);
|
return new LocalDependency(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new module instance.
|
||||||
|
*
|
||||||
|
* @param groupId the module group identifier
|
||||||
|
* @param artifactId the module artifact identifier
|
||||||
|
* @return a newly created {@code Module} instance
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public Module module(String groupId, String artifactId) {
|
||||||
|
return new Module(groupId, artifactId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new module instance.
|
||||||
|
*
|
||||||
|
* @param groupId the module group identifier
|
||||||
|
* @param artifactId the module artifact identifier
|
||||||
|
* @param version the module version
|
||||||
|
* @return a newly created {@code Module} instance
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public Module module(String groupId, String artifactId, String version) {
|
||||||
|
return new Module(groupId, artifactId, version(version));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new module instance.
|
||||||
|
*
|
||||||
|
* @param groupId the module group identifier
|
||||||
|
* @param artifactId the module artifact identifier
|
||||||
|
* @param version the module version
|
||||||
|
* @param classifier the module classifier
|
||||||
|
* @return a newly created {@code Module} instance
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public Module module(String groupId, String artifactId, String version, String classifier) {
|
||||||
|
return new Module(groupId, artifactId, version(version), classifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new module instance.
|
||||||
|
*
|
||||||
|
* @param groupId the module group identifier
|
||||||
|
* @param artifactId the module artifact identifier
|
||||||
|
* @param version the module version
|
||||||
|
* @return a newly created {@code Module} instance
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public Module module(String groupId, String artifactId, Version version) {
|
||||||
|
return new Module(groupId, artifactId, version);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new module instance.
|
||||||
|
*
|
||||||
|
* @param groupId the module group identifier
|
||||||
|
* @param artifactId the module artifact identifier
|
||||||
|
* @param version the module version
|
||||||
|
* @param classifier the module classifier
|
||||||
|
* @return a newly created {@code Module} instance
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public Module module(String groupId, String artifactId, Version version, String classifier) {
|
||||||
|
return new Module(groupId, artifactId, version, classifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new module instance from a string representation.
|
||||||
|
* The format is {@code groupId:artifactId:version:classifier}.
|
||||||
|
* The {@code version} and {@code classifier} are optional.
|
||||||
|
* <p>
|
||||||
|
* If the string can't be successfully parsed, {@code null} will be returned.
|
||||||
|
*
|
||||||
|
* @param description the module string to parse
|
||||||
|
* @return a parsed instance of {@code Module}; or
|
||||||
|
* {@code null} when the string couldn't be parsed
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public Module module(String description) {
|
||||||
|
return Module.parse(description);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a local module instance.
|
||||||
|
* <p>
|
||||||
|
* If the local module points to a directory, it will be scanned for jar files.
|
||||||
|
*
|
||||||
|
* @param path the file system path of the local module
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
|
||||||
|
public LocalModule localModule(String path) {
|
||||||
|
return new LocalModule(path);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Project directories
|
* Project directories
|
||||||
*/
|
*/
|
||||||
|
|
@ -973,6 +1150,36 @@ public class BaseProject extends BuildExecutor {
|
||||||
return Objects.requireNonNullElseGet(libCompileDirectory, () -> new File(libDirectory(), "compile"));
|
return Objects.requireNonNullElseGet(libCompileDirectory, () -> new File(libDirectory(), "compile"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the project modules compile scope lib directory.
|
||||||
|
* Defaults to {@code "modules"} relative to {@link #libCompileDirectory()}.
|
||||||
|
*
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public File libCompileModulesDirectory() {
|
||||||
|
return Objects.requireNonNullElseGet(libCompileModulesDirectory, () -> new File(libCompileDirectory(), "modules"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the project provided scope lib directory.
|
||||||
|
* Defaults to {@code "provided"} relative to {@link #libDirectory()}.
|
||||||
|
*
|
||||||
|
* @since 1.8
|
||||||
|
*/
|
||||||
|
public File libProvidedDirectory() {
|
||||||
|
return Objects.requireNonNullElseGet(libProvidedDirectory, () -> new File(libDirectory(), "provided"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the project modules provided scope lib directory.
|
||||||
|
* Defaults to {@code "modules"} relative to {@link #libProvidedDirectory()}.
|
||||||
|
*
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public File libProvidedModulesDirectory() {
|
||||||
|
return Objects.requireNonNullElseGet(libProvidedModulesDirectory, () -> new File(libProvidedDirectory(), "modules"));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the project runtime scope lib directory.
|
* Returns the project runtime scope lib directory.
|
||||||
* Defaults to {@code "runtime"} relative to {@link #libDirectory()}.
|
* Defaults to {@code "runtime"} relative to {@link #libDirectory()}.
|
||||||
|
|
@ -983,6 +1190,16 @@ public class BaseProject extends BuildExecutor {
|
||||||
return Objects.requireNonNullElseGet(libRuntimeDirectory, () -> new File(libDirectory(), "runtime"));
|
return Objects.requireNonNullElseGet(libRuntimeDirectory, () -> new File(libDirectory(), "runtime"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the project modules runtime scope lib directory.
|
||||||
|
* Defaults to {@code "modules"} relative to {@link #libRuntimeDirectory()}.
|
||||||
|
*
|
||||||
|
* @since 1.5
|
||||||
|
*/
|
||||||
|
public File libRuntimeModulesDirectory() {
|
||||||
|
return Objects.requireNonNullElseGet(libRuntimeModulesDirectory, () -> new File(libRuntimeDirectory(), "modules"));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the project standalone scope lib directory.
|
* Returns the project standalone scope lib directory.
|
||||||
* Defaults to {@code null}.
|
* Defaults to {@code null}.
|
||||||
|
|
@ -990,7 +1207,17 @@ public class BaseProject extends BuildExecutor {
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
public File libStandaloneDirectory() {
|
public File libStandaloneDirectory() {
|
||||||
return null;
|
return libStandaloneDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the project standalone scope lib directory.
|
||||||
|
* Defaults to {@code null}.
|
||||||
|
*
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public File libStandaloneModulesDirectory() {
|
||||||
|
return libStandaloneModulesDirectory;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1003,6 +1230,16 @@ public class BaseProject extends BuildExecutor {
|
||||||
return Objects.requireNonNullElseGet(libTestDirectory, () -> new File(libDirectory(), "test"));
|
return Objects.requireNonNullElseGet(libTestDirectory, () -> new File(libDirectory(), "test"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the project modules test scope lib directory.
|
||||||
|
* Defaults to {@code "modules"} relative to {@link #libTestDirectory()}.
|
||||||
|
*
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public File libTestModulesDirectory() {
|
||||||
|
return Objects.requireNonNullElseGet(libTestModulesDirectory, () -> new File(libTestDirectory(), "modules"));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the project build directory.
|
* Returns the project build directory.
|
||||||
* Defaults to {@code "build"} relative to {@link #workDirectory()}.
|
* Defaults to {@code "build"} relative to {@link #workDirectory()}.
|
||||||
|
|
@ -1093,11 +1330,19 @@ public class BaseProject extends BuildExecutor {
|
||||||
libDirectory().mkdirs();
|
libDirectory().mkdirs();
|
||||||
libBldDirectory().mkdirs();
|
libBldDirectory().mkdirs();
|
||||||
libCompileDirectory().mkdirs();
|
libCompileDirectory().mkdirs();
|
||||||
|
libCompileModulesDirectory().mkdirs();
|
||||||
|
libProvidedDirectory().mkdirs();
|
||||||
|
libProvidedModulesDirectory().mkdirs();
|
||||||
libRuntimeDirectory().mkdirs();
|
libRuntimeDirectory().mkdirs();
|
||||||
|
libRuntimeModulesDirectory().mkdirs();
|
||||||
if (libStandaloneDirectory() != null) {
|
if (libStandaloneDirectory() != null) {
|
||||||
libStandaloneDirectory().mkdirs();
|
libStandaloneDirectory().mkdirs();
|
||||||
}
|
}
|
||||||
|
if (libStandaloneModulesDirectory() != null) {
|
||||||
|
libStandaloneModulesDirectory().mkdirs();
|
||||||
|
}
|
||||||
libTestDirectory().mkdirs();
|
libTestDirectory().mkdirs();
|
||||||
|
libTestModulesDirectory().mkdirs();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1131,6 +1376,17 @@ public class BaseProject extends BuildExecutor {
|
||||||
return pkg;
|
return pkg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether this project's package was set.
|
||||||
|
*
|
||||||
|
* @return {@code true} if the package was set; or
|
||||||
|
* {@code false} otherwise
|
||||||
|
* @since 2.2.1
|
||||||
|
*/
|
||||||
|
public boolean hasPkg() {
|
||||||
|
return pkg != null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the project's name.
|
* Returns the project's name.
|
||||||
*
|
*
|
||||||
|
|
@ -1143,6 +1399,17 @@ public class BaseProject extends BuildExecutor {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether this project's name was set.
|
||||||
|
*
|
||||||
|
* @return {@code true} if the name was set; or
|
||||||
|
* {@code false} otherwise
|
||||||
|
* @since 2.2.1
|
||||||
|
*/
|
||||||
|
public boolean hasName() {
|
||||||
|
return name != null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the project's version.
|
* Returns the project's version.
|
||||||
*
|
*
|
||||||
|
|
@ -1156,17 +1423,34 @@ public class BaseProject extends BuildExecutor {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the project's main class.
|
* Returns whether this project's version was set.
|
||||||
|
*
|
||||||
|
* @return {@code true} if the version was set; or
|
||||||
|
* {@code false} otherwise
|
||||||
|
* @since 2.2.1
|
||||||
|
*/
|
||||||
|
public boolean hasVersion() {
|
||||||
|
return version != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the project's main class to execute.
|
||||||
*
|
*
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
public String mainClass() {
|
public String mainClass() {
|
||||||
if (mainClass == null) {
|
|
||||||
throw new IllegalStateException("The mainClass variable has to be set.");
|
|
||||||
}
|
|
||||||
return mainClass;
|
return mainClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the project's module to execute.
|
||||||
|
*
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public String module() {
|
||||||
|
return module;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the list of repositories for this project.
|
* Returns the list of repositories for this project.
|
||||||
* <p>
|
* <p>
|
||||||
|
|
@ -1282,7 +1566,14 @@ public class BaseProject extends BuildExecutor {
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
public String uberJarMainClass() {
|
public String uberJarMainClass() {
|
||||||
return Objects.requireNonNullElseGet(uberJarMainClass, this::mainClass);
|
if (uberJarMainClass != null) {
|
||||||
|
return uberJarMainClass;
|
||||||
|
}
|
||||||
|
if (mainClass() != null) {
|
||||||
|
return mainClass();
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new IllegalStateException("The mainClass variable has to be set.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1362,10 +1653,66 @@ public class BaseProject extends BuildExecutor {
|
||||||
// build the compilation classpath
|
// build the compilation classpath
|
||||||
var classpath = new ArrayList<>(jar_files.stream().map(file -> new File(dir_abs, file)).toList());
|
var classpath = new ArrayList<>(jar_files.stream().map(file -> new File(dir_abs, file)).toList());
|
||||||
addLocalDependencies(classpath, Scope.compile);
|
addLocalDependencies(classpath, Scope.compile);
|
||||||
|
return classpath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all the jar files that are in the compile scope module path.
|
||||||
|
* <p>
|
||||||
|
* By default, this collects all the jar files in the {@link #libCompileModulesDirectory()}
|
||||||
|
* and adds all the jar files from the compile scope local modules.
|
||||||
|
*
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public List<File> compileModulePathJars() {
|
||||||
|
// detect the jar files in the modules compile lib directory
|
||||||
|
var dir_abs = libCompileModulesDirectory().getAbsoluteFile();
|
||||||
|
var jar_files = FileUtils.getFileList(dir_abs, INCLUDED_JARS, EXCLUDED_JARS);
|
||||||
|
|
||||||
|
// build the compilation module path
|
||||||
|
var module_path = new ArrayList<>(jar_files.stream().map(file -> new File(dir_abs, file)).toList());
|
||||||
|
addLocalModules(module_path, Scope.compile);
|
||||||
|
return module_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all the jar files that are in the provided scope classpath.
|
||||||
|
* <p>
|
||||||
|
* By default, this collects all the jar files in the {@link #libProvidedDirectory()}
|
||||||
|
* and adds all the jar files from the provided scope local dependencies.
|
||||||
|
*
|
||||||
|
* @since 1.8
|
||||||
|
*/
|
||||||
|
public List<File> providedClasspathJars() {
|
||||||
|
// detect the jar files in the provided lib directory
|
||||||
|
var dir_abs = libProvidedDirectory().getAbsoluteFile();
|
||||||
|
var jar_files = FileUtils.getFileList(dir_abs, INCLUDED_JARS, EXCLUDED_JARS);
|
||||||
|
|
||||||
|
// build the provided classpath
|
||||||
|
var classpath = new ArrayList<>(jar_files.stream().map(file -> new File(dir_abs, file)).toList());
|
||||||
addLocalDependencies(classpath, Scope.provided);
|
addLocalDependencies(classpath, Scope.provided);
|
||||||
return classpath;
|
return classpath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all the jar files that are in the provided scope module path.
|
||||||
|
* <p>
|
||||||
|
* By default, this collects all the jar files in the {@link #libProvidedModulesDirectory()}
|
||||||
|
* and adds all the jar files from the provided scope local modules.
|
||||||
|
*
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public List<File> providedModulePathJars() {
|
||||||
|
// detect the jar files in the modules provided lib directory
|
||||||
|
var dir_abs = libProvidedModulesDirectory().getAbsoluteFile();
|
||||||
|
var jar_files = FileUtils.getFileList(dir_abs, INCLUDED_JARS, EXCLUDED_JARS);
|
||||||
|
|
||||||
|
// build the provided module path
|
||||||
|
var module_path = new ArrayList<>(jar_files.stream().map(file -> new File(dir_abs, file)).toList());
|
||||||
|
addLocalModules(module_path, Scope.provided);
|
||||||
|
return module_path;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns all the jar files that are in the runtime scope classpath.
|
* Returns all the jar files that are in the runtime scope classpath.
|
||||||
* <p>
|
* <p>
|
||||||
|
|
@ -1385,6 +1732,25 @@ public class BaseProject extends BuildExecutor {
|
||||||
return classpath;
|
return classpath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all the jar files that are in the runtime scope module path.
|
||||||
|
* <p>
|
||||||
|
* By default, this collects all the jar files in the {@link #libRuntimeModulesDirectory()}
|
||||||
|
* and adds all the jar files from the runtime scope local modules.
|
||||||
|
*
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public List<File> runtimeModulePathJars() {
|
||||||
|
// detect the jar files in the modules runtime lib directory
|
||||||
|
var dir_abs = libRuntimeModulesDirectory().getAbsoluteFile();
|
||||||
|
var jar_files = FileUtils.getFileList(dir_abs, INCLUDED_JARS, EXCLUDED_JARS);
|
||||||
|
|
||||||
|
// build the runtime module path
|
||||||
|
var module_path = new ArrayList<>(jar_files.stream().map(file -> new File(dir_abs, file)).toList());
|
||||||
|
addLocalModules(module_path, Scope.runtime);
|
||||||
|
return module_path;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns all the jar files that are in the standalone scope classpath.
|
* Returns all the jar files that are in the standalone scope classpath.
|
||||||
* <p>
|
* <p>
|
||||||
|
|
@ -1409,6 +1775,30 @@ public class BaseProject extends BuildExecutor {
|
||||||
return classpath;
|
return classpath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all the jar files that are in the standalone scope module path.
|
||||||
|
* <p>
|
||||||
|
* By default, this collects all the jar files in the {@link #libStandaloneModulesDirectory()}
|
||||||
|
* and adds all the jar files from the standalone scope local modules.
|
||||||
|
*
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public List<File> standaloneModulePathJars() {
|
||||||
|
// build the standalone classpath
|
||||||
|
List<File> module_path;
|
||||||
|
if (libStandaloneModulesDirectory() == null) {
|
||||||
|
module_path = new ArrayList<>();
|
||||||
|
} else {
|
||||||
|
// detect the jar files in the modules standalone lib directory
|
||||||
|
var dir_abs = libStandaloneModulesDirectory().getAbsoluteFile();
|
||||||
|
var jar_files = FileUtils.getFileList(dir_abs, INCLUDED_JARS, EXCLUDED_JARS);
|
||||||
|
|
||||||
|
module_path = new ArrayList<>(jar_files.stream().map(file -> new File(dir_abs, file)).toList());
|
||||||
|
}
|
||||||
|
addLocalModules(module_path, Scope.standalone);
|
||||||
|
return module_path;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns all the jar files that are in the test scope classpath.
|
* Returns all the jar files that are in the test scope classpath.
|
||||||
* <p>
|
* <p>
|
||||||
|
|
@ -1428,20 +1818,51 @@ public class BaseProject extends BuildExecutor {
|
||||||
return classpath;
|
return classpath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all the jar files that are in the test scope module path.
|
||||||
|
* <p>
|
||||||
|
* By default, this collects all the jar files in the {@link #libTestModulesDirectory()}
|
||||||
|
* and adds all the jar files from the test scope local modules.
|
||||||
|
*
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public List<File> testModulePathJars() {
|
||||||
|
// detect the jar files in the test lib directory
|
||||||
|
var dir_abs = libTestModulesDirectory().getAbsoluteFile();
|
||||||
|
var jar_files = FileUtils.getFileList(dir_abs, INCLUDED_JARS, EXCLUDED_JARS);
|
||||||
|
|
||||||
|
// build the test module path
|
||||||
|
var module_path = new ArrayList<>(jar_files.stream().map(file -> new File(dir_abs, file)).toList());
|
||||||
|
addLocalModules(module_path, Scope.test);
|
||||||
|
return module_path;
|
||||||
|
}
|
||||||
|
|
||||||
private void addLocalDependencies(List<File> classpath, Scope scope) {
|
private void addLocalDependencies(List<File> classpath, Scope scope) {
|
||||||
if (dependencies.get(scope) == null) {
|
if (dependencies.get(scope) == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var dependency : dependencies.get(scope).localDependencies()) {
|
for (var dependency : dependencies.get(scope).localDependencies()) {
|
||||||
var local_file = new File(workDirectory(), dependency.path());
|
addLocalJars(classpath, dependency.path());
|
||||||
if (local_file.exists()) {
|
}
|
||||||
if (local_file.isDirectory()) {
|
}
|
||||||
var local_jar_files = FileUtils.getFileList(local_file.getAbsoluteFile(), INCLUDED_JARS, EXCLUDED_JARS);
|
|
||||||
classpath.addAll(new ArrayList<>(local_jar_files.stream().map(file -> new File(local_file, file)).toList()));
|
private void addLocalModules(List<File> classpath, Scope scope) {
|
||||||
} else {
|
if (dependencies.get(scope) == null) {
|
||||||
classpath.add(local_file);
|
return;
|
||||||
}
|
}
|
||||||
|
for (var module : dependencies.get(scope).localModules()) {
|
||||||
|
addLocalJars(classpath, module.path());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addLocalJars(List<File> jars, String path) {
|
||||||
|
var local_file = new File(workDirectory(), path);
|
||||||
|
if (local_file.exists()) {
|
||||||
|
if (local_file.isDirectory()) {
|
||||||
|
var local_jar_files = FileUtils.getFileList(local_file.getAbsoluteFile(), INCLUDED_JARS, EXCLUDED_JARS);
|
||||||
|
jars.addAll(new ArrayList<>(local_jar_files.stream().map(file -> new File(local_file, file)).toList()));
|
||||||
|
} else {
|
||||||
|
jars.add(local_file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1449,18 +1870,29 @@ public class BaseProject extends BuildExecutor {
|
||||||
/**
|
/**
|
||||||
* Returns all the classpath entries for compiling the main sources.
|
* Returns all the classpath entries for compiling the main sources.
|
||||||
* <p>
|
* <p>
|
||||||
* By default, this converts the files from {@link #compileClasspathJars()} to absolute paths.
|
* By default, this converts the files from {@link #compileClasspathJars()} and {@link #providedClasspathJars()} to absolute paths.
|
||||||
*
|
*
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
public List<String> compileMainClasspath() {
|
public List<String> compileMainClasspath() {
|
||||||
return FileUtils.combineToAbsolutePaths(compileClasspathJars());
|
return FileUtils.combineToAbsolutePaths(compileClasspathJars(), providedClasspathJars());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all the module path entries for compiling the main sources.
|
||||||
|
* <p>
|
||||||
|
* By default, this converts the files from {@link #compileModulePathJars()} and {@link #providedModulePathJars()} to absolute paths.
|
||||||
|
*
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public List<String> compileMainModulePath() {
|
||||||
|
return FileUtils.combineToAbsolutePaths(compileModulePathJars(), providedModulePathJars());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns all the classpath entries for compiling the test sources.
|
* Returns all the classpath entries for compiling the test sources.
|
||||||
* <p>
|
* <p>
|
||||||
* By default, this converts the files from {@link #compileClasspathJars()} and
|
* By default, this converts the files from {@link #compileClasspathJars()}, {@link #providedClasspathJars()} and
|
||||||
* {@link #testClasspathJars()} to absolute paths, as well as the {@link #buildMainDirectory()}
|
* {@link #testClasspathJars()} to absolute paths, as well as the {@link #buildMainDirectory()}
|
||||||
*
|
*
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
|
|
@ -1468,10 +1900,22 @@ public class BaseProject extends BuildExecutor {
|
||||||
public List<String> compileTestClasspath() {
|
public List<String> compileTestClasspath() {
|
||||||
var paths = new ArrayList<String>();
|
var paths = new ArrayList<String>();
|
||||||
paths.add(buildMainDirectory().getAbsolutePath());
|
paths.add(buildMainDirectory().getAbsolutePath());
|
||||||
paths.addAll(FileUtils.combineToAbsolutePaths(compileClasspathJars(), testClasspathJars()));
|
paths.addAll(FileUtils.combineToAbsolutePaths(compileClasspathJars(), providedClasspathJars(), testClasspathJars()));
|
||||||
return paths;
|
return paths;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all the module path entries for compiling the test sources.
|
||||||
|
* <p>
|
||||||
|
* By default, this converts the files from {@link #compileModulePathJars()}, {@link #providedModulePathJars()} and
|
||||||
|
* {@link #testModulePathJars()} to absolute paths.
|
||||||
|
*
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public List<String> compileTestModulePath() {
|
||||||
|
return FileUtils.combineToAbsolutePaths(compileModulePathJars(), providedModulePathJars(), testModulePathJars());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns all the classpath entries for running the application.
|
* Returns all the classpath entries for running the application.
|
||||||
* <p>
|
* <p>
|
||||||
|
|
@ -1489,10 +1933,22 @@ public class BaseProject extends BuildExecutor {
|
||||||
return paths;
|
return paths;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all the module path entries for running the application.
|
||||||
|
* <p>
|
||||||
|
* By default, this converts the files from {@link #compileModulePathJars()},
|
||||||
|
* {@link #runtimeModulePathJars()} and {@link #standaloneModulePathJars()} to absolute paths.
|
||||||
|
*
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public List<String> runModulePath() {
|
||||||
|
return FileUtils.combineToAbsolutePaths(compileModulePathJars(), runtimeModulePathJars(), standaloneModulePathJars());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns all the classpath entries for testing the application.
|
* Returns all the classpath entries for testing the application.
|
||||||
* <p>
|
* <p>
|
||||||
* By default, this converts the files from {@link #compileClasspathJars()},
|
* By default, this converts the files from {@link #compileClasspathJars()}, {@link #providedClasspathJars()},
|
||||||
* {@link #runtimeClasspathJars()} and {@link #testClasspathJars()}
|
* {@link #runtimeClasspathJars()} and {@link #testClasspathJars()}
|
||||||
* to absolute paths, as well as the {@link #srcMainResourcesDirectory()},
|
* to absolute paths, as well as the {@link #srcMainResourcesDirectory()},
|
||||||
* {@link #buildMainDirectory()} and {@link #buildTestDirectory()}
|
* {@link #buildMainDirectory()} and {@link #buildTestDirectory()}
|
||||||
|
|
@ -1505,10 +1961,23 @@ public class BaseProject extends BuildExecutor {
|
||||||
paths.add(srcTestResourcesDirectory().getAbsolutePath());
|
paths.add(srcTestResourcesDirectory().getAbsolutePath());
|
||||||
paths.add(buildMainDirectory().getAbsolutePath());
|
paths.add(buildMainDirectory().getAbsolutePath());
|
||||||
paths.add(buildTestDirectory().getAbsolutePath());
|
paths.add(buildTestDirectory().getAbsolutePath());
|
||||||
paths.addAll(FileUtils.combineToAbsolutePaths(compileClasspathJars(), runtimeClasspathJars(), standaloneClasspathJars(), testClasspathJars()));
|
paths.addAll(FileUtils.combineToAbsolutePaths(compileClasspathJars(), providedClasspathJars(), runtimeClasspathJars(), standaloneClasspathJars(), testClasspathJars()));
|
||||||
return paths;
|
return paths;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all the module path entries for testing the application.
|
||||||
|
* <p>
|
||||||
|
* By default, this converts the files from {@link #compileModulePathJars()}, {@link #providedModulePathJars()},
|
||||||
|
* {@link #runtimeModulePathJars()} and {@link #testModulePathJars()}
|
||||||
|
* to absolute paths.
|
||||||
|
*
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public List<String> testModulePath() {
|
||||||
|
return FileUtils.combineToAbsolutePaths(compileModulePathJars(), providedModulePathJars(), runtimeModulePathJars(), standaloneModulePathJars(), testModulePathJars());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes download and purge commands automatically when the
|
* Executes download and purge commands automatically when the
|
||||||
* {@code autoDownloadPurge} flag is set and changes have been detected.
|
* {@code autoDownloadPurge} flag is set and changes have been detected.
|
||||||
|
|
@ -1522,84 +1991,28 @@ public class BaseProject extends BuildExecutor {
|
||||||
purge();
|
purge();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String BLD_BUILD_HASH = "bld-build.hash";
|
|
||||||
|
|
||||||
private void performAutoDownloadPurge() {
|
private void performAutoDownloadPurge() {
|
||||||
// verify and update the fingerprint hash file,
|
var resolution = new VersionResolution(properties());
|
||||||
// don't download and purge if the hash is identical
|
var cache = new BldCache(libBldDirectory(), resolution);
|
||||||
var hash_file = new File(libBldDirectory(), BLD_BUILD_HASH);
|
cache.cacheDependenciesHash(repositories(), dependencies());
|
||||||
var hash = createHash();
|
cache.cacheDependenciesDownloads(downloadSources(), downloadJavadoc());
|
||||||
if (validateHash(hash_file, hash)) {
|
if (cache.isDependenciesCacheValid()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
executeAutoDownloadPurge();
|
executeAutoDownloadPurge();
|
||||||
|
|
||||||
writeHash(hash_file, hash);
|
cache.writeCache();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String createHash() {
|
|
||||||
var finger_print = new StringBuilder();
|
|
||||||
for (var repository : repositories()) {
|
|
||||||
finger_print.append(repository.toString());
|
|
||||||
finger_print.append("\n");
|
|
||||||
}
|
|
||||||
for (var entry : dependencies().entrySet()) {
|
|
||||||
finger_print.append(entry.getKey());
|
|
||||||
finger_print.append("\n");
|
|
||||||
if (entry.getValue() != null) {
|
|
||||||
for (var dependency : entry.getValue()) {
|
|
||||||
finger_print.append(dependency.toString());
|
|
||||||
finger_print.append("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finger_print.append(downloadSources());
|
|
||||||
finger_print.append("\n");
|
|
||||||
finger_print.append(downloadJavadoc());
|
|
||||||
finger_print.append("\n");
|
|
||||||
|
|
||||||
try {
|
|
||||||
var digest = MessageDigest.getInstance("SHA-1");
|
|
||||||
digest.update(finger_print.toString().getBytes(StandardCharsets.UTF_8));
|
|
||||||
return StringUtils.encodeHexLower(digest.digest());
|
|
||||||
} catch (NoSuchAlgorithmException e) {
|
|
||||||
// should not happen
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean validateHash(File hashFile, String hash) {
|
|
||||||
try {
|
|
||||||
if (hashFile.exists()) {
|
|
||||||
var current_hash = FileUtils.readString(hashFile);
|
|
||||||
if (current_hash.equals(hash)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
hashFile.delete();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
} catch (FileUtilsErrorException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void writeHash(File hashFile, String hash) {
|
|
||||||
try {
|
|
||||||
hashFile.getParentFile().mkdirs();
|
|
||||||
FileUtils.writeString(hash, hashFile);
|
|
||||||
} catch (FileUtilsErrorException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int execute(String[] arguments) {
|
public int execute(String[] arguments) {
|
||||||
if (autoDownloadPurge()) {
|
if (!offline() &&
|
||||||
|
autoDownloadPurge()) {
|
||||||
performAutoDownloadPurge();
|
performAutoDownloadPurge();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
561
src/main/java/rife/bld/BldCache.java
Normal file
561
src/main/java/rife/bld/BldCache.java
Normal file
|
|
@ -0,0 +1,561 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||||
|
*/
|
||||||
|
package rife.bld;
|
||||||
|
|
||||||
|
import rife.bld.dependencies.DependencyScopes;
|
||||||
|
import rife.bld.dependencies.Repository;
|
||||||
|
import rife.bld.dependencies.VersionResolution;
|
||||||
|
import rife.bld.wrapper.Wrapper;
|
||||||
|
import rife.tools.StringUtils;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides functionalities related to dependency hashing and caching.
|
||||||
|
*
|
||||||
|
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public class BldCache {
|
||||||
|
/**
|
||||||
|
* Represents the name of a cache file used by bld.
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public static final String BLD_CACHE = "bld.cache";
|
||||||
|
|
||||||
|
private static final String PROPERTY_SUFFIX_HASH = ".hash";
|
||||||
|
private static final String PROPERTY_SUFFIX_LOCAL = ".local";
|
||||||
|
private static final String PROPERTY_SUFFIX_DOWNLOAD_SOURCES = ".download.sources";
|
||||||
|
private static final String PROPERTY_SUFFIX_DOWNLOAD_JAVADOC = ".download.javadoc";
|
||||||
|
private static final String PROPERTY_SUFFIX_DEPENDENCY_TREE = ".dependency.tree";
|
||||||
|
|
||||||
|
private static final String WRAPPER_PROPERTIES_HASH = Wrapper.WRAPPER_PROPERTIES + PROPERTY_SUFFIX_HASH;
|
||||||
|
private static final String BLD_BUILD_HASH = "bld-build" + PROPERTY_SUFFIX_HASH;
|
||||||
|
|
||||||
|
private static final String PROPERTY_EXTENSIONS_PREFIX = "bld.extensions";
|
||||||
|
private static final String PROPERTY_EXTENSIONS_HASH = PROPERTY_EXTENSIONS_PREFIX + PROPERTY_SUFFIX_HASH;
|
||||||
|
private static final String PROPERTY_EXTENSIONS_LOCAL = PROPERTY_EXTENSIONS_PREFIX + PROPERTY_SUFFIX_LOCAL;
|
||||||
|
private static final String PROPERTY_EXTENSIONS_DOWNLOAD_SOURCES = PROPERTY_EXTENSIONS_PREFIX + PROPERTY_SUFFIX_DOWNLOAD_SOURCES;
|
||||||
|
private static final String PROPERTY_EXTENSIONS_DOWNLOAD_JAVADOC = PROPERTY_EXTENSIONS_PREFIX + PROPERTY_SUFFIX_DOWNLOAD_JAVADOC;
|
||||||
|
private static final String PROPERTY_EXTENSIONS_DEPENDENCY_TREE = PROPERTY_EXTENSIONS_PREFIX + PROPERTY_SUFFIX_DEPENDENCY_TREE;
|
||||||
|
|
||||||
|
private static final String PROPERTY_DEPENDENCIES_PREFIX = "bld.dependencies";
|
||||||
|
private static final String PROPERTY_DEPENDENCIES_HASH = PROPERTY_DEPENDENCIES_PREFIX + PROPERTY_SUFFIX_HASH;
|
||||||
|
private static final String PROPERTY_DEPENDENCIES_DOWNLOAD_SOURCES = PROPERTY_DEPENDENCIES_PREFIX + PROPERTY_SUFFIX_DOWNLOAD_SOURCES;
|
||||||
|
private static final String PROPERTY_DEPENDENCIES_DOWNLOAD_JAVADOC = PROPERTY_DEPENDENCIES_PREFIX + PROPERTY_SUFFIX_DOWNLOAD_JAVADOC;
|
||||||
|
private static final String PROPERTY_DEPENDENCIES_COMPILE_DEPENDENCY_TREE = PROPERTY_DEPENDENCIES_PREFIX + ".compile" + PROPERTY_SUFFIX_DEPENDENCY_TREE;
|
||||||
|
private static final String PROPERTY_DEPENDENCIES_PROVIDED_DEPENDENCY_TREE = PROPERTY_DEPENDENCIES_PREFIX + ".provided" + PROPERTY_SUFFIX_DEPENDENCY_TREE;
|
||||||
|
private static final String PROPERTY_DEPENDENCIES_RUNTIME_DEPENDENCY_TREE = PROPERTY_DEPENDENCIES_PREFIX + ".runtime" + PROPERTY_SUFFIX_DEPENDENCY_TREE;
|
||||||
|
private static final String PROPERTY_DEPENDENCIES_TEST_DEPENDENCY_TREE = PROPERTY_DEPENDENCIES_PREFIX + ".test" + PROPERTY_SUFFIX_DEPENDENCY_TREE;
|
||||||
|
|
||||||
|
private final File cacheDir_;
|
||||||
|
private final VersionResolution resolution_;
|
||||||
|
private String extensionsHash_;
|
||||||
|
private Boolean extensionsDownloadSources_;
|
||||||
|
private Boolean extensionsDownloadJavadocs_;
|
||||||
|
private List<File> extensionsLocalArtifacts_;
|
||||||
|
private String extensionsDependencyTree_;
|
||||||
|
private String dependenciesHash_;
|
||||||
|
private Boolean dependenciesDownloadSources_;
|
||||||
|
private Boolean dependenciesDownloadJavadocs_;
|
||||||
|
private String dependenciesCompileDependencyTree_;
|
||||||
|
private String dependenciesProvidedDependencyTree_;
|
||||||
|
private String dependenciesRuntimeDependencyTree_;
|
||||||
|
private String dependenciesTestDependencyTree_;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new {@code BldCache} instance.
|
||||||
|
*
|
||||||
|
* @param cacheDir the directory where the bld cache file is stored
|
||||||
|
* @param resolution the version resolution that should be used when needed during the cache operations
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public BldCache(File cacheDir, VersionResolution resolution) {
|
||||||
|
cacheDir_ = cacheDir;
|
||||||
|
resolution_ = resolution;
|
||||||
|
|
||||||
|
new File(cacheDir, WRAPPER_PROPERTIES_HASH).delete();
|
||||||
|
new File(cacheDir, BLD_BUILD_HASH).delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the hash that corresponds to the provided repositories and extensions.
|
||||||
|
* <p>
|
||||||
|
* This will be stored with this instance of {@code BldCache}, using {@link #writeCache()} is required to store it to disk.
|
||||||
|
*
|
||||||
|
* @param repositories the repositories to include into the hash
|
||||||
|
* @param extensions the extensions to include into the hash
|
||||||
|
* @since 2.0
|
||||||
|
* @see #isExtensionsHashValid()
|
||||||
|
* @see #isExtensionsCacheValid()
|
||||||
|
* @see #writeCache()
|
||||||
|
*/
|
||||||
|
public void cacheExtensionsHash(Collection<String> repositories, Collection<String> extensions) {
|
||||||
|
try {
|
||||||
|
var overrides_fp = String.join("\n", resolution_.versionOverrides().entrySet().stream().map(e -> e.getKey() + ":" + e.getValue()).toList());
|
||||||
|
var repositories_fp = String.join("\n", repositories);
|
||||||
|
var extensions_fp = String.join("\n", extensions);
|
||||||
|
var fingerprint = overrides_fp + "\n" + repositories_fp + "\n" + extensions_fp + "\n";
|
||||||
|
var digest = MessageDigest.getInstance("SHA-1");
|
||||||
|
digest.update(fingerprint.getBytes(StandardCharsets.UTF_8));
|
||||||
|
|
||||||
|
extensionsHash_ = StringUtils.encodeHexLower(digest.digest());
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
// should not happen
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determined whether the extensions hash stored in this {@code BldCache} instance is the same as the one stored
|
||||||
|
* in the cache on disk.
|
||||||
|
*
|
||||||
|
* @return {@code true} is the extensions hash is the same; or {@code false} otherwise
|
||||||
|
* @since 2.0
|
||||||
|
* @see #cacheExtensionsHash
|
||||||
|
* @see #isExtensionsCacheValid
|
||||||
|
*/
|
||||||
|
public boolean isExtensionsHashValid() {
|
||||||
|
return validateExtensionsHash(extensionsHash_);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets which other artifacts should be downloaded besides main jars for the extensions.
|
||||||
|
* <p>
|
||||||
|
* This will be stored with this instance of {@code BldCache}, using {@link #writeCache()} is required to store it to disk.
|
||||||
|
*
|
||||||
|
* @param downloadSources whether the extensions sources should be downloaded or not
|
||||||
|
* @param downloadJavadoc whether the extensions javadocs should be downloaded or not
|
||||||
|
* @since 2.0
|
||||||
|
* @see #isExtensionsCacheValid()
|
||||||
|
* @see #writeCache()
|
||||||
|
*/
|
||||||
|
public void cacheExtensionsDownloads(boolean downloadSources, boolean downloadJavadoc) {
|
||||||
|
extensionsDownloadSources_ = downloadSources;
|
||||||
|
extensionsDownloadJavadocs_ = downloadJavadoc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets which local artifacts were used by the transfer of the extensions into the project.
|
||||||
|
* <p>
|
||||||
|
* This will be stored with this instance of {@code BldCache}, using {@link #writeCache()} is required to store it to disk.
|
||||||
|
*
|
||||||
|
* @param extensionsLocalArtifacts the list of extension files that were pulled from local storage
|
||||||
|
* @since 2.0
|
||||||
|
* @see #isExtensionsCacheValid()
|
||||||
|
* @see #writeCache()
|
||||||
|
*/
|
||||||
|
public void cacheExtensionsLocalArtifacts(List<File> extensionsLocalArtifacts) {
|
||||||
|
extensionsLocalArtifacts_ = extensionsLocalArtifacts;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the textual presentation of the extensions dependency tree.
|
||||||
|
* <p>
|
||||||
|
* This will be stored with this instance of {@code BldCache}, using {@link #writeCache()} is required to store it to disk.
|
||||||
|
*
|
||||||
|
* @param dependencyTree the textual presentation of the extensions dependency tree
|
||||||
|
* @since 2.0
|
||||||
|
* @see #getCachedExtensionsDependencyTree
|
||||||
|
* @see #writeCache()
|
||||||
|
*/
|
||||||
|
public void cacheExtensionsDependencyTree(String dependencyTree) {
|
||||||
|
extensionsDependencyTree_ = dependencyTree;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the textual presentation of the extensions dependency tree from the cache state on disk.
|
||||||
|
*
|
||||||
|
* @return the cached textual presentation of the extensions dependency tree; or {@code null} of this dependency
|
||||||
|
* tree wasn't found in the stored cache
|
||||||
|
* @since 2.0
|
||||||
|
* @see #cacheExtensionsDependencyTree
|
||||||
|
*/
|
||||||
|
public String getCachedExtensionsDependencyTree() {
|
||||||
|
return hashProperties().getProperty(PROPERTY_EXTENSIONS_DEPENDENCY_TREE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines whether the extensions state stored in this {@code BldCache} instance is the same as the state of the cache on disk.
|
||||||
|
*
|
||||||
|
* @return {@code true} if state is identical; or {@code false} otherwise
|
||||||
|
* @since 2.0
|
||||||
|
* @see #cacheExtensionsHash
|
||||||
|
* @see #cacheExtensionsDownloads
|
||||||
|
* @see #cacheExtensionsLocalArtifacts
|
||||||
|
*/
|
||||||
|
public boolean isExtensionsCacheValid() {
|
||||||
|
var properties = hashProperties();
|
||||||
|
if (properties.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (extensionsDownloadSources_ != Boolean.parseBoolean(properties.getProperty(PROPERTY_EXTENSIONS_DOWNLOAD_SOURCES))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (extensionsDownloadJavadocs_ != Boolean.parseBoolean(properties.getProperty(PROPERTY_EXTENSIONS_DOWNLOAD_JAVADOC))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return validateExtensionsHash(extensionsHash_);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean validateExtensionsHash(String hash) {
|
||||||
|
var properties = hashProperties();
|
||||||
|
if (properties.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hash.equals(properties.getProperty(PROPERTY_EXTENSIONS_HASH))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var local_files = properties.getProperty(PROPERTY_EXTENSIONS_LOCAL);
|
||||||
|
if (local_files != null && !local_files.isEmpty()) {
|
||||||
|
var lines = StringUtils.split(local_files, "\n");
|
||||||
|
if (!lines.isEmpty()) {
|
||||||
|
// other lines are last modified timestamps of local files
|
||||||
|
// that were dependency artifacts
|
||||||
|
while (!lines.isEmpty()) {
|
||||||
|
var line = lines.get(0);
|
||||||
|
var parts = line.split(":", 2);
|
||||||
|
// verify that the local file has the same modified timestamp still
|
||||||
|
if (parts.length == 2) {
|
||||||
|
var file = new File(parts[1]);
|
||||||
|
if (!file.exists() || !file.canRead() || file.lastModified() != Long.parseLong(parts[0])) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
lines.remove(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// there were no invalid lines, so the hash file contents are valid
|
||||||
|
return lines.isEmpty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the hash that corresponds to the provided repositories and dependencies.
|
||||||
|
* <p>
|
||||||
|
* This will be stored with this instance of {@code BldCache}, using {@link #writeCache()} is required to store it to disk.
|
||||||
|
*
|
||||||
|
* @param repositories the repositories to include into the hash
|
||||||
|
* @param dependencies the dependencies to include into the hash
|
||||||
|
* @since 2.0
|
||||||
|
* @see #isDependenciesHashValid()
|
||||||
|
* @see #isDependenciesCacheValid()
|
||||||
|
* @see #writeCache()
|
||||||
|
*/
|
||||||
|
public void cacheDependenciesHash(List<Repository> repositories, DependencyScopes dependencies) {
|
||||||
|
var finger_print = new StringBuilder();
|
||||||
|
finger_print.append(String.join("\n", resolution_.versionOverrides().entrySet().stream().map(e -> e.getKey() + ":" + e.getValue()).toList()));
|
||||||
|
for (var repository : repositories) {
|
||||||
|
finger_print.append(repository.toString());
|
||||||
|
finger_print.append('\n');
|
||||||
|
}
|
||||||
|
for (var entry : dependencies.entrySet()) {
|
||||||
|
finger_print.append(entry.getKey());
|
||||||
|
finger_print.append('\n');
|
||||||
|
if (entry.getValue() != null) {
|
||||||
|
for (var dependency : entry.getValue()) {
|
||||||
|
finger_print.append(dependency.toString());
|
||||||
|
finger_print.append('\n');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
var digest = MessageDigest.getInstance("SHA-1");
|
||||||
|
digest.update(finger_print.toString().getBytes(StandardCharsets.UTF_8));
|
||||||
|
dependenciesHash_ = StringUtils.encodeHexLower(digest.digest());
|
||||||
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
// should not happen
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determined whether the dependencies hash stored in this {@code BldCache} instance is the same as the one stored
|
||||||
|
* in the cache on disk.
|
||||||
|
*
|
||||||
|
* @return {@code true} is the dependencies hash is the same; or {@code false} otherwise
|
||||||
|
* @since 2.0
|
||||||
|
* @see #cacheDependenciesHash
|
||||||
|
* @see #isDependenciesCacheValid
|
||||||
|
*/
|
||||||
|
public boolean isDependenciesHashValid() {
|
||||||
|
return validateDependenciesHash(dependenciesHash_);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets which other artifacts should be downloaded besides main jars for the dependencies.
|
||||||
|
* <p>
|
||||||
|
* This will be stored with this instance of {@code BldCache}, using {@link #writeCache()} is required to store it to disk.
|
||||||
|
*
|
||||||
|
* @param downloadSources whether the dependencies sources should be downloaded or not
|
||||||
|
* @param downloadJavadoc whether the dependencies javadocs should be downloaded or not
|
||||||
|
* @since 2.0
|
||||||
|
* @see #isDependenciesCacheValid()
|
||||||
|
* @see #writeCache()
|
||||||
|
*/
|
||||||
|
public void cacheDependenciesDownloads(boolean downloadSources, boolean downloadJavadoc) {
|
||||||
|
dependenciesDownloadSources_ = downloadSources;
|
||||||
|
dependenciesDownloadJavadocs_ = downloadJavadoc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the textual presentation of the compile scope dependency tree.
|
||||||
|
* <p>
|
||||||
|
* This will be stored with this instance of {@code BldCache}, using {@link #writeCache()} is required to store it to disk.
|
||||||
|
*
|
||||||
|
* @param compileTree the textual presentation of the compile scope dependency tree
|
||||||
|
* @since 2.0
|
||||||
|
* @see #getCachedDependenciesCompileDependencyTree
|
||||||
|
* @see #writeCache()
|
||||||
|
*/
|
||||||
|
public void cacheDependenciesCompileDependencyTree(String compileTree) {
|
||||||
|
dependenciesCompileDependencyTree_ = compileTree;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the textual presentation of the compile scope dependency tree from the cache state on disk.
|
||||||
|
*
|
||||||
|
* @return the cached textual presentation of the compile scope dependency tree; or {@code null} of this dependency
|
||||||
|
* tree wasn't found in the stored cache
|
||||||
|
* @since 2.0
|
||||||
|
* @see #cacheDependenciesCompileDependencyTree
|
||||||
|
*/
|
||||||
|
public String getCachedDependenciesCompileDependencyTree() {
|
||||||
|
return hashProperties().getProperty(PROPERTY_DEPENDENCIES_COMPILE_DEPENDENCY_TREE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the textual presentation of the provided scope dependency tree.
|
||||||
|
* <p>
|
||||||
|
* This will be stored with this instance of {@code BldCache}, using {@link #writeCache()} is required to store it to disk.
|
||||||
|
*
|
||||||
|
* @param providedTree the textual presentation of the provided scope dependency tree
|
||||||
|
* @since 2.0
|
||||||
|
* @see #getCachedDependenciesProvidedDependencyTree
|
||||||
|
* @see #writeCache()
|
||||||
|
*/
|
||||||
|
public void cacheDependenciesProvidedDependencyTree(String providedTree) {
|
||||||
|
dependenciesProvidedDependencyTree_ = providedTree;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the textual presentation of the provided scope dependency tree from the cache state on disk.
|
||||||
|
*
|
||||||
|
* @return the cached textual presentation of the provided scope dependency tree; or {@code null} of this dependency
|
||||||
|
* tree wasn't found in the stored cache
|
||||||
|
* @since 2.0
|
||||||
|
* @see #cacheDependenciesProvidedDependencyTree
|
||||||
|
*/
|
||||||
|
public String getCachedDependenciesProvidedDependencyTree() {
|
||||||
|
return hashProperties().getProperty(PROPERTY_DEPENDENCIES_PROVIDED_DEPENDENCY_TREE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the textual presentation of the runtime scope dependency tree.
|
||||||
|
* <p>
|
||||||
|
* This will be stored with this instance of {@code BldCache}, using {@link #writeCache()} is required to store it to disk.
|
||||||
|
*
|
||||||
|
* @param runtimeTree the textual presentation of the runtime scope dependency tree
|
||||||
|
* @since 2.0
|
||||||
|
* @see #getCachedDependenciesRuntimeDependencyTree
|
||||||
|
* @see #writeCache()
|
||||||
|
*/
|
||||||
|
public void cacheDependenciesRuntimeDependencyTree(String runtimeTree) {
|
||||||
|
dependenciesRuntimeDependencyTree_ = runtimeTree;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the textual presentation of the runtime scope dependency tree from the cache state on disk.
|
||||||
|
*
|
||||||
|
* @return the cached textual presentation of the runtime scope dependency tree; or {@code null} of this dependency
|
||||||
|
* tree wasn't found in the stored cache
|
||||||
|
* @since 2.0
|
||||||
|
* @see #cacheDependenciesRuntimeDependencyTree
|
||||||
|
*/
|
||||||
|
public String getCachedDependenciesRuntimeDependencyTree() {
|
||||||
|
return hashProperties().getProperty(PROPERTY_DEPENDENCIES_RUNTIME_DEPENDENCY_TREE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the textual presentation of the test scope dependency tree.
|
||||||
|
* <p>
|
||||||
|
* This will be stored with this instance of {@code BldCache}, using {@link #writeCache()} is required to store it to disk.
|
||||||
|
*
|
||||||
|
* @param testTree the textual presentation of the test scope dependency tree
|
||||||
|
* @since 2.0
|
||||||
|
* @see #getCachedDependenciesTestDependencyTree
|
||||||
|
* @see #writeCache()
|
||||||
|
*/
|
||||||
|
public void cacheDependenciesTestDependencyTree(String testTree) {
|
||||||
|
dependenciesTestDependencyTree_ = testTree;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the textual presentation of the test scope dependency tree from the cache state on disk.
|
||||||
|
*
|
||||||
|
* @return the cached textual presentation of the test scope dependency tree; or {@code null} of this dependency
|
||||||
|
* tree wasn't found in the stored cache
|
||||||
|
* @since 2.0
|
||||||
|
* @see #cacheDependenciesTestDependencyTree
|
||||||
|
*/
|
||||||
|
public String getCachedDependenciesTestDependencyTree() {
|
||||||
|
return hashProperties().getProperty(PROPERTY_DEPENDENCIES_TEST_DEPENDENCY_TREE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines whether the dependencies state stored in this {@code BldCache} instance is the same as the state of the cache on disk.
|
||||||
|
*
|
||||||
|
* @return {@code true} if state is identical; or {@code false} otherwise
|
||||||
|
* @since 2.0
|
||||||
|
* @see #cacheDependenciesHash
|
||||||
|
* @see #cacheDependenciesDownloads
|
||||||
|
*/
|
||||||
|
public boolean isDependenciesCacheValid() {
|
||||||
|
var properties = hashProperties();
|
||||||
|
if (properties.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dependenciesDownloadSources_ != Boolean.parseBoolean(properties.getProperty(PROPERTY_DEPENDENCIES_DOWNLOAD_SOURCES))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dependenciesDownloadJavadocs_ != Boolean.parseBoolean(properties.getProperty(PROPERTY_DEPENDENCIES_DOWNLOAD_JAVADOC))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return validateDependenciesHash(dependenciesHash_);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean validateDependenciesHash(String hash) {
|
||||||
|
var properties = hashProperties();
|
||||||
|
if (properties.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hash.equals(properties.getProperty(PROPERTY_DEPENDENCIES_HASH));
|
||||||
|
}
|
||||||
|
|
||||||
|
private File getCacheFile() {
|
||||||
|
return new File(cacheDir_, BLD_CACHE);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Properties hashProperties() {
|
||||||
|
var properties = new Properties();
|
||||||
|
if (getCacheFile().exists()) {
|
||||||
|
try {
|
||||||
|
try (var reader = new BufferedReader(new FileReader(getCacheFile()))) {
|
||||||
|
properties.load(reader);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
// no-op, we'll store a new properties file when we're writing the cache
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes the state of this {@code BldCache} instance to disk.
|
||||||
|
*
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public void writeCache() {
|
||||||
|
var properties = hashProperties();
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (extensionsHash_ != null) {
|
||||||
|
if (!extensionsHash_.equals(properties.get(PROPERTY_EXTENSIONS_HASH))) {
|
||||||
|
properties.put(PROPERTY_EXTENSIONS_HASH, extensionsHash_);
|
||||||
|
properties.remove(PROPERTY_EXTENSIONS_DEPENDENCY_TREE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (extensionsDependencyTree_ != null) {
|
||||||
|
properties.put(PROPERTY_EXTENSIONS_DEPENDENCY_TREE, extensionsDependencyTree_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (extensionsDownloadSources_ != null) {
|
||||||
|
properties.put(PROPERTY_EXTENSIONS_DOWNLOAD_SOURCES, String.valueOf(extensionsDownloadSources_));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (extensionsDownloadJavadocs_ != null) {
|
||||||
|
properties.put(PROPERTY_EXTENSIONS_DOWNLOAD_JAVADOC, String.valueOf(extensionsDownloadJavadocs_));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (extensionsLocalArtifacts_ != null) {
|
||||||
|
var extensions_local = new StringBuilder();
|
||||||
|
for (var file : extensionsLocalArtifacts_) {
|
||||||
|
if (file.exists() && file.canRead()) {
|
||||||
|
if (!extensions_local.isEmpty()) {
|
||||||
|
extensions_local.append("\n");
|
||||||
|
}
|
||||||
|
extensions_local.append(file.lastModified()).append(':').append(file.getAbsolutePath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
properties.put(PROPERTY_EXTENSIONS_LOCAL, extensions_local.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dependenciesHash_ != null) {
|
||||||
|
if (!dependenciesHash_.equals(properties.get(PROPERTY_DEPENDENCIES_HASH))) {
|
||||||
|
properties.put(PROPERTY_DEPENDENCIES_HASH, dependenciesHash_);
|
||||||
|
properties.remove(PROPERTY_DEPENDENCIES_COMPILE_DEPENDENCY_TREE);
|
||||||
|
properties.remove(PROPERTY_DEPENDENCIES_PROVIDED_DEPENDENCY_TREE);
|
||||||
|
properties.remove(PROPERTY_DEPENDENCIES_RUNTIME_DEPENDENCY_TREE);
|
||||||
|
properties.remove(PROPERTY_DEPENDENCIES_TEST_DEPENDENCY_TREE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dependenciesCompileDependencyTree_ != null) {
|
||||||
|
properties.put(PROPERTY_DEPENDENCIES_COMPILE_DEPENDENCY_TREE, dependenciesCompileDependencyTree_);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dependenciesProvidedDependencyTree_ != null) {
|
||||||
|
properties.put(PROPERTY_DEPENDENCIES_PROVIDED_DEPENDENCY_TREE, dependenciesProvidedDependencyTree_);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dependenciesRuntimeDependencyTree_ != null) {
|
||||||
|
properties.put(PROPERTY_DEPENDENCIES_RUNTIME_DEPENDENCY_TREE, dependenciesRuntimeDependencyTree_);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dependenciesTestDependencyTree_ != null) {
|
||||||
|
properties.put(PROPERTY_DEPENDENCIES_TEST_DEPENDENCY_TREE, dependenciesTestDependencyTree_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dependenciesDownloadSources_ != null) {
|
||||||
|
properties.put(PROPERTY_DEPENDENCIES_DOWNLOAD_SOURCES, String.valueOf(dependenciesDownloadSources_));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dependenciesDownloadJavadocs_ != null) {
|
||||||
|
properties.put(PROPERTY_DEPENDENCIES_DOWNLOAD_JAVADOC, String.valueOf(dependenciesDownloadJavadocs_));
|
||||||
|
}
|
||||||
|
|
||||||
|
cacheDir_.mkdirs();
|
||||||
|
|
||||||
|
try (var writer = new BufferedWriter(new FileWriter(getCacheFile()))) {
|
||||||
|
properties.store(writer, null);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -25,6 +25,15 @@ public @interface BuildCommand {
|
||||||
*/
|
*/
|
||||||
String value() default "";
|
String value() default "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When provided, specifies an alias for the build command that can be
|
||||||
|
* different from the method name.
|
||||||
|
*
|
||||||
|
* @return a string representing an alias for the build command
|
||||||
|
* @since 1.9
|
||||||
|
*/
|
||||||
|
String alias() default "";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When provided, specifies a short description about the command.
|
* When provided, specifies a short description about the command.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -11,9 +11,7 @@ import rife.bld.operations.exceptions.ExitStatusException;
|
||||||
import rife.ioc.HierarchicalProperties;
|
import rife.ioc.HierarchicalProperties;
|
||||||
import rife.tools.ExceptionUtils;
|
import rife.tools.ExceptionUtils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.*;
|
||||||
import java.io.FileReader;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
@ -33,6 +31,7 @@ public class BuildExecutor {
|
||||||
public static final String BLD_PROPERTIES = "bld.properties";
|
public static final String BLD_PROPERTIES = "bld.properties";
|
||||||
public static final String LOCAL_PROPERTIES = "local.properties";
|
public static final String LOCAL_PROPERTIES = "local.properties";
|
||||||
|
|
||||||
|
private static final String ARG_OFFLINE = "--offline";
|
||||||
private static final String ARG_HELP1 = "--help";
|
private static final String ARG_HELP1 = "--help";
|
||||||
private static final String ARG_HELP2 = "-h";
|
private static final String ARG_HELP2 = "-h";
|
||||||
private static final String ARG_HELP3 = "-?";
|
private static final String ARG_HELP3 = "-?";
|
||||||
|
|
@ -41,7 +40,9 @@ public class BuildExecutor {
|
||||||
|
|
||||||
private final HierarchicalProperties properties_;
|
private final HierarchicalProperties properties_;
|
||||||
private List<String> arguments_ = Collections.emptyList();
|
private List<String> arguments_ = Collections.emptyList();
|
||||||
|
private boolean offline_ = false;
|
||||||
private Map<String, CommandDefinition> buildCommands_ = null;
|
private Map<String, CommandDefinition> buildCommands_ = null;
|
||||||
|
private Map<String, String> buildAliases_ = null;
|
||||||
private final AtomicReference<String> currentCommandName_ = new AtomicReference<>();
|
private final AtomicReference<String> currentCommandName_ = new AtomicReference<>();
|
||||||
private final AtomicReference<CommandDefinition> currentCommandDefinition_ = new AtomicReference<>();
|
private final AtomicReference<CommandDefinition> currentCommandDefinition_ = new AtomicReference<>();
|
||||||
private int exitStatus_ = 0;
|
private int exitStatus_ = 0;
|
||||||
|
|
@ -124,7 +125,18 @@ public class BuildExecutor {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the properties uses by this conversation.
|
* Returns whether the bld execution is intended to be offline.
|
||||||
|
*
|
||||||
|
* @return {@code true} if the execution is intended to be offline;
|
||||||
|
* or {@code false} otherwise
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public boolean offline() {
|
||||||
|
return offline_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the properties uses for bld execution.
|
||||||
*
|
*
|
||||||
* @return the instance of {@code HierarchicalProperties} that is used
|
* @return the instance of {@code HierarchicalProperties} that is used
|
||||||
* by this build executor
|
* by this build executor
|
||||||
|
|
@ -214,13 +226,16 @@ public class BuildExecutor {
|
||||||
|
|
||||||
var show_help = false;
|
var show_help = false;
|
||||||
show_help |= arguments_.removeAll(List.of(ARG_HELP1, ARG_HELP2, ARG_HELP3));
|
show_help |= arguments_.removeAll(List.of(ARG_HELP1, ARG_HELP2, ARG_HELP3));
|
||||||
showStacktrace |= arguments_.removeAll(List.of(ARG_STACKTRACE1, ARG_STACKTRACE2));
|
showStacktrace = arguments_.removeAll(List.of(ARG_STACKTRACE1, ARG_STACKTRACE2));
|
||||||
show_help |= arguments_.isEmpty();
|
|
||||||
|
|
||||||
if (show_help) {
|
if (show_help) {
|
||||||
new HelpOperation(this, Collections.emptyList()).execute();
|
new HelpOperation(this, Collections.emptyList()).execute();
|
||||||
return exitStatus_;
|
return exitStatus_;
|
||||||
}
|
}
|
||||||
|
else if (arguments_.isEmpty()) {
|
||||||
|
showBldHelp();
|
||||||
|
return exitStatus_;
|
||||||
|
}
|
||||||
|
|
||||||
while (!arguments_.isEmpty()) {
|
while (!arguments_.isEmpty()) {
|
||||||
var command = arguments_.remove(0);
|
var command = arguments_.remove(0);
|
||||||
|
|
@ -230,37 +245,40 @@ public class BuildExecutor {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
exitStatus(1);
|
exitStatus(ExitStatusException.EXIT_FAILURE);
|
||||||
|
outputCommandExecutionException(e);
|
||||||
System.err.println();
|
break;
|
||||||
|
|
||||||
if (showStacktrace) {
|
|
||||||
System.err.println(ExceptionUtils.getExceptionStackTrace(e));
|
|
||||||
} else {
|
|
||||||
boolean first = true;
|
|
||||||
var e2 = e;
|
|
||||||
while (e2 != null) {
|
|
||||||
if (e2.getMessage() != null) {
|
|
||||||
if (!first) {
|
|
||||||
System.err.print("> ");
|
|
||||||
}
|
|
||||||
System.err.println(e2.getMessage());
|
|
||||||
first = false;
|
|
||||||
}
|
|
||||||
e2 = e2.getCause();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (first) {
|
|
||||||
System.err.println(ExceptionUtils.getExceptionStackTrace(e));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return exitStatus_;
|
return exitStatus_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void outputCommandExecutionException(Throwable e) {
|
||||||
|
System.err.println();
|
||||||
|
|
||||||
|
if (showStacktrace) {
|
||||||
|
System.err.println(ExceptionUtils.getExceptionStackTrace(e));
|
||||||
|
} else {
|
||||||
|
boolean first_exception = true;
|
||||||
|
var e2 = e;
|
||||||
|
while (e2 != null) {
|
||||||
|
if (e2.getMessage() != null) {
|
||||||
|
if (!first_exception) {
|
||||||
|
System.err.print("> ");
|
||||||
|
}
|
||||||
|
System.err.println(e2.getMessage());
|
||||||
|
first_exception = false;
|
||||||
|
}
|
||||||
|
e2 = e2.getCause();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (first_exception) {
|
||||||
|
System.err.println(ExceptionUtils.getExceptionStackTrace(e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts the execution of the build. This method will call
|
* Starts the execution of the build. This method will call
|
||||||
* System.exit() when done with the appropriate exit status.
|
* System.exit() when done with the appropriate exit status.
|
||||||
|
|
@ -270,6 +288,11 @@ public class BuildExecutor {
|
||||||
* @since 1.5.1
|
* @since 1.5.1
|
||||||
*/
|
*/
|
||||||
public void start(String[] arguments) {
|
public void start(String[] arguments) {
|
||||||
|
if (arguments.length > 0 && arguments[0].equals(ARG_OFFLINE)) {
|
||||||
|
offline_ = true;
|
||||||
|
arguments = Arrays.copyOfRange(arguments, 1, arguments.length);
|
||||||
|
}
|
||||||
|
|
||||||
System.exit(execute(arguments));
|
System.exit(execute(arguments));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -294,6 +317,7 @@ public class BuildExecutor {
|
||||||
public Map<String, CommandDefinition> buildCommands() {
|
public Map<String, CommandDefinition> buildCommands() {
|
||||||
if (buildCommands_ == null) {
|
if (buildCommands_ == null) {
|
||||||
var build_commands = new TreeMap<String, CommandDefinition>();
|
var build_commands = new TreeMap<String, CommandDefinition>();
|
||||||
|
var build_aliases = new HashMap<String, String>();
|
||||||
|
|
||||||
Class<?> klass = getClass();
|
Class<?> klass = getClass();
|
||||||
|
|
||||||
|
|
@ -311,6 +335,11 @@ public class BuildExecutor {
|
||||||
name = annotation_name;
|
name = annotation_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var annotation_alias = annotation.alias();
|
||||||
|
if (annotation_alias != null && !annotation_alias.isEmpty()) {
|
||||||
|
build_aliases.put(annotation_alias, name);
|
||||||
|
}
|
||||||
|
|
||||||
if (!build_commands.containsKey(name)) {
|
if (!build_commands.containsKey(name)) {
|
||||||
var build_help = annotation.help();
|
var build_help = annotation.help();
|
||||||
CommandHelp command_help = null;
|
CommandHelp command_help = null;
|
||||||
|
|
@ -343,11 +372,27 @@ public class BuildExecutor {
|
||||||
}
|
}
|
||||||
|
|
||||||
buildCommands_ = build_commands;
|
buildCommands_ = build_commands;
|
||||||
|
buildAliases_ = build_aliases;
|
||||||
}
|
}
|
||||||
|
|
||||||
return buildCommands_;
|
return buildCommands_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the command aliases that can be executed by this {@code BuildExecutor}.
|
||||||
|
*
|
||||||
|
* @return a map containing the alias and the associated name of the build command
|
||||||
|
* @see BuildCommand
|
||||||
|
* @since 1.9
|
||||||
|
*/
|
||||||
|
public Map<String, String> buildAliases() {
|
||||||
|
if (buildAliases_ == null) {
|
||||||
|
buildCommands();
|
||||||
|
}
|
||||||
|
|
||||||
|
return buildAliases_;
|
||||||
|
}
|
||||||
|
|
||||||
private static class AnnotatedCommandHelp implements CommandHelp {
|
private static class AnnotatedCommandHelp implements CommandHelp {
|
||||||
private final String summary_;
|
private final String summary_;
|
||||||
private final String description_;
|
private final String description_;
|
||||||
|
|
@ -383,6 +428,15 @@ public class BuildExecutor {
|
||||||
var matched_command = command;
|
var matched_command = command;
|
||||||
var definition = buildCommands().get(command);
|
var definition = buildCommands().get(command);
|
||||||
|
|
||||||
|
// try to find an alias
|
||||||
|
if (definition == null) {
|
||||||
|
var aliased_command = buildAliases().get(command);
|
||||||
|
if (aliased_command != null) {
|
||||||
|
matched_command = aliased_command;
|
||||||
|
definition = buildCommands().get(aliased_command);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// try to find a match for the provided command amongst
|
// try to find a match for the provided command amongst
|
||||||
// the ones that are known
|
// the ones that are known
|
||||||
if (definition == null) {
|
if (definition == null) {
|
||||||
|
|
@ -399,7 +453,7 @@ public class BuildExecutor {
|
||||||
fuzzy_regexp.append(ch);
|
fuzzy_regexp.append(ch);
|
||||||
fuzzy_regexp.append("\\E.*");
|
fuzzy_regexp.append("\\E.*");
|
||||||
}
|
}
|
||||||
fuzzy_regexp.append("$");
|
fuzzy_regexp.append('$');
|
||||||
var fuzzy_pattern = Pattern.compile(fuzzy_regexp.toString());
|
var fuzzy_pattern = Pattern.compile(fuzzy_regexp.toString());
|
||||||
matches.addAll(buildCommands().keySet().stream()
|
matches.addAll(buildCommands().keySet().stream()
|
||||||
.filter(c -> fuzzy_pattern.matcher(c.toLowerCase()).matches())
|
.filter(c -> fuzzy_pattern.matcher(c.toLowerCase()).matches())
|
||||||
|
|
@ -416,9 +470,9 @@ public class BuildExecutor {
|
||||||
|
|
||||||
// execute the command if we found one
|
// execute the command if we found one
|
||||||
if (definition != null) {
|
if (definition != null) {
|
||||||
|
currentCommandName_.set(matched_command);
|
||||||
|
currentCommandDefinition_.set(definition);
|
||||||
try {
|
try {
|
||||||
currentCommandName_.set(matched_command);
|
|
||||||
currentCommandDefinition_.set(definition);
|
|
||||||
definition.execute();
|
definition.execute();
|
||||||
} catch (ExitStatusException e) {
|
} catch (ExitStatusException e) {
|
||||||
exitStatus(e.getExitStatus());
|
exitStatus(e.getExitStatus());
|
||||||
|
|
@ -428,14 +482,25 @@ public class BuildExecutor {
|
||||||
currentCommandName_.set(null);
|
currentCommandName_.set(null);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
new HelpOperation(this, arguments()).executePrintOverviewHelp();
|
var message = "Unknown command '" + command + "'";
|
||||||
System.err.println();
|
showBldHelp();
|
||||||
System.err.println("ERROR: unknown command '" + command + "'");
|
System.err.println("ERROR: " + message);
|
||||||
|
exitStatus(ExitStatusException.EXIT_FAILURE);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void showBldHelp() {
|
||||||
|
var help = new HelpOperation(this, arguments());
|
||||||
|
help.executePrintWelcome();
|
||||||
|
System.err.println("""
|
||||||
|
The bld CLI provides its features through a series of commands that
|
||||||
|
perform specific tasks.""");
|
||||||
|
help.executePrintCommands();
|
||||||
|
help.executePrintBldArguments();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the name of the currently executing command.
|
* Retrieves the name of the currently executing command.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ import rife.bld.operations.*;
|
||||||
public class Cli extends BuildExecutor {
|
public class Cli extends BuildExecutor {
|
||||||
private final CreateOperation createOperation_ = new CreateOperation();
|
private final CreateOperation createOperation_ = new CreateOperation();
|
||||||
private final CreateBaseOperation createBaseOperation_ = new CreateBaseOperation();
|
private final CreateBaseOperation createBaseOperation_ = new CreateBaseOperation();
|
||||||
private final CreateBlankOperation createBlankOperation_ = new CreateBlankOperation();
|
private final CreateAppOperation createAppOperation_ = new CreateAppOperation();
|
||||||
private final CreateLibOperation createLibOperation_ = new CreateLibOperation();
|
private final CreateLibOperation createLibOperation_ = new CreateLibOperation();
|
||||||
private final CreateRife2Operation createRife2Operation_ = new CreateRife2Operation();
|
private final CreateRife2Operation createRife2Operation_ = new CreateRife2Operation();
|
||||||
private final UpgradeOperation upgradeOperation_ = new UpgradeOperation();
|
private final UpgradeOperation upgradeOperation_ = new UpgradeOperation();
|
||||||
|
|
@ -36,15 +36,15 @@ public class Cli extends BuildExecutor {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The standard {@code create-blank} command.
|
* The standard {@code create-app} command.
|
||||||
*
|
*
|
||||||
* @throws Exception when an error occurred during the creation process
|
* @throws Exception when an error occurred during the creation process
|
||||||
* @since 1.5
|
* @since 1.9
|
||||||
*/
|
*/
|
||||||
@BuildCommand(value = "create-blank", help = CreateBlankHelp.class)
|
@BuildCommand(value = "create-app", alias = "create-blank", help = CreateAppHelp.class)
|
||||||
public void createBlank()
|
public void createApp()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
createBlankOperation_.executeOnce(() -> createBlankOperation_.fromArguments(arguments()));
|
createAppOperation_.executeOnce(() -> createAppOperation_.fromArguments(arguments()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -108,6 +108,11 @@ public class WebProject extends Project {
|
||||||
return Objects.requireNonNullElseGet(libStandaloneDirectory, () -> new File(libDirectory(), "standalone"));
|
return Objects.requireNonNullElseGet(libStandaloneDirectory, () -> new File(libDirectory(), "standalone"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public File libStandaloneModulesDirectory() {
|
||||||
|
return Objects.requireNonNullElseGet(libStandaloneModulesDirectory, () -> new File(libStandaloneDirectory(), "modules"));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the project main webapp directory.
|
* Returns the project main webapp directory.
|
||||||
* Defaults to {@code "webapp"} relative to {@link #srcMainDirectory()}.
|
* Defaults to {@code "webapp"} relative to {@link #srcMainDirectory()}.
|
||||||
|
|
|
||||||
|
|
@ -16,28 +16,28 @@ import static rife.bld.dependencies.Repository.SONATYPE_SNAPSHOTS;
|
||||||
import static rife.bld.dependencies.Scope.test;
|
import static rife.bld.dependencies.Scope.test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the dependency information required to create a new blank project.
|
* Provides the dependency information required to create a new app project.
|
||||||
*
|
*
|
||||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||||
* @since 1.5
|
* @since 1.9
|
||||||
*/
|
*/
|
||||||
public class BlankProjectBlueprint extends Project {
|
public class AppProjectBlueprint extends Project {
|
||||||
public BlankProjectBlueprint(File work, String packageName, String projectName) {
|
public AppProjectBlueprint(File work, String packageName, String projectName, String baseName) {
|
||||||
this(work, packageName, projectName, new VersionNumber(0,0,1));
|
this(work, packageName, projectName, baseName, new VersionNumber(0,0,1));
|
||||||
}
|
}
|
||||||
|
|
||||||
public BlankProjectBlueprint(File work, String packageName, String projectName, VersionNumber versionNumber) {
|
public AppProjectBlueprint(File work, String packageName, String projectName, String baseName, VersionNumber versionNumber) {
|
||||||
workDirectory = work;
|
workDirectory = work;
|
||||||
|
|
||||||
pkg = packageName;
|
pkg = packageName;
|
||||||
name = projectName;
|
name = projectName;
|
||||||
mainClass = packageName + "." + StringUtils.capitalize(projectName) + "Main";
|
mainClass = packageName + "." + baseName;
|
||||||
version = versionNumber;
|
version = versionNumber;
|
||||||
|
|
||||||
downloadSources = true;
|
downloadSources = true;
|
||||||
repositories = List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS);
|
repositories = List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS);
|
||||||
scope(test)
|
scope(test)
|
||||||
.include(dependency("org.junit.jupiter", "junit-jupiter", version(5,9,3)))
|
.include(dependency("org.junit.jupiter", "junit-jupiter", version(5,11,4)))
|
||||||
.include(dependency("org.junit.platform", "junit-platform-console-standalone", version(1,9,3)));
|
.include(dependency("org.junit.platform", "junit-platform-console-standalone", version(1,11,4)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -13,7 +13,6 @@ import java.util.List;
|
||||||
|
|
||||||
import static rife.bld.dependencies.Repository.MAVEN_CENTRAL;
|
import static rife.bld.dependencies.Repository.MAVEN_CENTRAL;
|
||||||
import static rife.bld.dependencies.Repository.SONATYPE_SNAPSHOTS;
|
import static rife.bld.dependencies.Repository.SONATYPE_SNAPSHOTS;
|
||||||
import static rife.bld.dependencies.Scope.test;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the dependency information required to create a new base project.
|
* Provides the dependency information required to create a new base project.
|
||||||
|
|
@ -22,16 +21,16 @@ import static rife.bld.dependencies.Scope.test;
|
||||||
* @since 1.5.20
|
* @since 1.5.20
|
||||||
*/
|
*/
|
||||||
public class BaseProjectBlueprint extends Project {
|
public class BaseProjectBlueprint extends Project {
|
||||||
public BaseProjectBlueprint(File work, String packageName, String projectName) {
|
public BaseProjectBlueprint(File work, String packageName, String projectName, String baseName) {
|
||||||
this(work, packageName, projectName, new VersionNumber(0,0,1));
|
this(work, packageName, projectName, baseName, new VersionNumber(0,0,1));
|
||||||
}
|
}
|
||||||
|
|
||||||
public BaseProjectBlueprint(File work, String packageName, String projectName, VersionNumber versionNumber) {
|
public BaseProjectBlueprint(File work, String packageName, String projectName, String baseName, VersionNumber versionNumber) {
|
||||||
workDirectory = work;
|
workDirectory = work;
|
||||||
|
|
||||||
pkg = packageName;
|
pkg = packageName;
|
||||||
name = projectName;
|
name = projectName;
|
||||||
mainClass = packageName + "." + StringUtils.capitalize(projectName) + "Main";
|
mainClass = packageName + "." + baseName;
|
||||||
version = versionNumber;
|
version = versionNumber;
|
||||||
|
|
||||||
downloadSources = true;
|
downloadSources = true;
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import java.util.List;
|
||||||
|
|
||||||
import static rife.bld.dependencies.Repository.MAVEN_CENTRAL;
|
import static rife.bld.dependencies.Repository.MAVEN_CENTRAL;
|
||||||
import static rife.bld.dependencies.Repository.SONATYPE_SNAPSHOTS;
|
import static rife.bld.dependencies.Repository.SONATYPE_SNAPSHOTS;
|
||||||
|
import static rife.bld.dependencies.Scope.test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the dependency information required to create a new lib project.
|
* Provides the dependency information required to create a new lib project.
|
||||||
|
|
@ -21,19 +22,22 @@ import static rife.bld.dependencies.Repository.SONATYPE_SNAPSHOTS;
|
||||||
* @since 1.6
|
* @since 1.6
|
||||||
*/
|
*/
|
||||||
public class LibProjectBlueprint extends Project {
|
public class LibProjectBlueprint extends Project {
|
||||||
public LibProjectBlueprint(File work, String packageName, String projectName) {
|
public LibProjectBlueprint(File work, String packageName, String projectName, String baseName) {
|
||||||
this(work, packageName, projectName, new VersionNumber(0,0,1));
|
this(work, packageName, projectName, baseName, new VersionNumber(0,0,1));
|
||||||
}
|
}
|
||||||
|
|
||||||
public LibProjectBlueprint(File work, String packageName, String projectName, VersionNumber versionNumber) {
|
public LibProjectBlueprint(File work, String packageName, String projectName, String baseName, VersionNumber versionNumber) {
|
||||||
workDirectory = work;
|
workDirectory = work;
|
||||||
|
|
||||||
pkg = packageName;
|
pkg = packageName;
|
||||||
name = projectName;
|
name = projectName;
|
||||||
mainClass = packageName + "." + StringUtils.capitalize(projectName) + "Lib";
|
mainClass = packageName + "." + baseName;
|
||||||
version = versionNumber;
|
version = versionNumber;
|
||||||
|
|
||||||
downloadSources = true;
|
downloadSources = true;
|
||||||
repositories = List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS);
|
repositories = List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS);
|
||||||
|
scope(test)
|
||||||
|
.include(dependency("org.junit.jupiter", "junit-jupiter", version(5,11,4)))
|
||||||
|
.include(dependency("org.junit.platform", "junit-platform-console-standalone", version(1,11,4)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -23,30 +23,31 @@ import static rife.bld.dependencies.Scope.*;
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
public class Rife2ProjectBlueprint extends WebProject {
|
public class Rife2ProjectBlueprint extends WebProject {
|
||||||
public Rife2ProjectBlueprint(File work, String packageName, String projectName) {
|
public Rife2ProjectBlueprint(File work, String packageName, String projectName, String baseName) {
|
||||||
this(work, packageName, projectName, new VersionNumber(0,0,1));
|
this(work, packageName, projectName, baseName, new VersionNumber(0,0,1));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Rife2ProjectBlueprint(File work, String packageName, String projectName, VersionNumber versionNumber) {
|
public Rife2ProjectBlueprint(File work, String packageName, String projectName, String baseName, VersionNumber versionNumber) {
|
||||||
workDirectory = work;
|
workDirectory = work;
|
||||||
|
|
||||||
pkg = packageName;
|
pkg = packageName;
|
||||||
name = projectName;
|
name = projectName;
|
||||||
mainClass = packageName + "." + StringUtils.capitalize(projectName) + "Site";
|
mainClass = packageName + "." + baseName + "Site";
|
||||||
|
uberJarMainClass = mainClass + "Uber";
|
||||||
version = versionNumber;
|
version = versionNumber;
|
||||||
|
|
||||||
downloadSources = true;
|
downloadSources = true;
|
||||||
repositories = List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS);
|
repositories = List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS);
|
||||||
scope(compile)
|
scope(compile)
|
||||||
.include(dependency("com.uwyn.rife2", "rife2", version(1,6,3)));
|
.include(dependency("com.uwyn.rife2", "rife2", version(1,9,1)));
|
||||||
scope(test)
|
scope(test)
|
||||||
.include(dependency("org.jsoup", "jsoup", version(1,16,1)))
|
.include(dependency("org.jsoup", "jsoup", version(1,18,3)))
|
||||||
.include(dependency("org.junit.jupiter", "junit-jupiter", version(5,9,3)))
|
.include(dependency("org.junit.jupiter", "junit-jupiter", version(5,11,4)))
|
||||||
.include(dependency("org.junit.platform", "junit-platform-console-standalone", version(1,9,3)));
|
.include(dependency("org.junit.platform", "junit-platform-console-standalone", version(1,11,4)));
|
||||||
scope(standalone)
|
scope(standalone)
|
||||||
.include(dependency("org.eclipse.jetty", "jetty-server", version(11,0,15)))
|
.include(dependency("org.eclipse.jetty.ee10", "jetty-ee10", version(12,0,16)))
|
||||||
.include(dependency("org.eclipse.jetty", "jetty-servlet", version(11,0,15)))
|
.include(dependency("org.eclipse.jetty.ee10", "jetty-ee10-servlet", version(12,0,16)))
|
||||||
.include(dependency("org.slf4j", "slf4j-simple", version(2,0,7)));
|
.include(dependency("org.slf4j", "slf4j-simple", version(2,0,16)));
|
||||||
|
|
||||||
precompileOperation().templateTypes(TemplateType.HTML);
|
precompileOperation().templateTypes(TemplateType.HTML);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,54 +4,87 @@
|
||||||
*/
|
*/
|
||||||
package rife.bld.dependencies;
|
package rife.bld.dependencies;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains the information required to describe an url dependency in the build system.
|
* Contains the information required to describe a dependency in the build system.
|
||||||
*
|
*
|
||||||
* @param groupId the dependency group identifier
|
|
||||||
* @param artifactId the dependency url identifier
|
|
||||||
* @param version the dependency version
|
|
||||||
* @param classifier the dependency classier
|
|
||||||
* @param type the dependency type
|
|
||||||
* @param exclusions the dependency exclusions for transitive resolution
|
|
||||||
* @param parent the parent dependency that created this dependency (only for information purposes)
|
|
||||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
public record Dependency(String groupId, String artifactId, VersionNumber version, String classifier, String type, ExclusionSet exclusions, Dependency parent) {
|
public class Dependency {
|
||||||
public static final String CLASSIFIER_SOURCES = "sources";
|
public static final String CLASSIFIER_SOURCES = "sources";
|
||||||
public static final String CLASSIFIER_JAVADOC = "javadoc";
|
public static final String CLASSIFIER_JAVADOC = "javadoc";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The dependency type name for a JAR file that can be placed either on the class-path or on the module-path.
|
||||||
|
*
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public static final String TYPE_JAR = "jar";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The dependency type name for a JAR file to unconditionally place on the class-path.
|
||||||
|
*
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public static final String TYPE_CLASSPATH_JAR = "classpath-jar";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The dependency type name for a JAR file to unconditionally place on the module-path.
|
||||||
|
*
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
// see https://github.com/apache/maven/blob/maven-4.0.0-beta-3/api/maven-api-core/src/main/java/org/apache/maven/api/Type.java
|
||||||
|
public static final String TYPE_MODULAR_JAR = "modular-jar";
|
||||||
|
|
||||||
|
private final String groupId_;
|
||||||
|
private final String artifactId_;
|
||||||
|
private final Version version_;
|
||||||
|
private final String classifier_;
|
||||||
|
private final String type_;
|
||||||
|
private final ExclusionSet exclusions_;
|
||||||
|
private final Dependency parent_;
|
||||||
|
private final HashSet<String> excludedClassifiers_;
|
||||||
|
|
||||||
public Dependency(String groupId, String artifactId) {
|
public Dependency(String groupId, String artifactId) {
|
||||||
this(groupId, artifactId, null, null, null);
|
this(groupId, artifactId, null, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Dependency(String groupId, String artifactId, VersionNumber version) {
|
public Dependency(String groupId, String artifactId, Version version) {
|
||||||
this(groupId, artifactId, version, null, null);
|
this(groupId, artifactId, version, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Dependency(String groupId, String artifactId, VersionNumber version, String classifier) {
|
public Dependency(String groupId, String artifactId, Version version, String classifier) {
|
||||||
this(groupId, artifactId, version, classifier, null);
|
this(groupId, artifactId, version, classifier, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Dependency(String groupId, String artifactId, VersionNumber version, String classifier, String type) {
|
public Dependency(String groupId, String artifactId, Version version, String classifier, String type) {
|
||||||
this(groupId, artifactId, version, classifier, type, null);
|
this(groupId, artifactId, version, classifier, type, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Dependency(String groupId, String artifactId, VersionNumber version, String classifier, String type, ExclusionSet exclusions) {
|
public Dependency(String groupId, String artifactId, Version version, String classifier, String type, ExclusionSet exclusions) {
|
||||||
this(groupId, artifactId, version, classifier, type, null, null);
|
this(groupId, artifactId, version, classifier, type, exclusions, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Dependency(String groupId, String artifactId, VersionNumber version, String classifier, String type, ExclusionSet exclusions, Dependency parent) {
|
public Dependency(String groupId, String artifactId, Version version, String classifier, String type, ExclusionSet exclusions, Dependency parent) {
|
||||||
this.groupId = groupId;
|
if (type == null) {
|
||||||
this.artifactId = artifactId;
|
type = TYPE_JAR;
|
||||||
this.version = (version == null ? VersionNumber.UNKNOWN : version);
|
}
|
||||||
this.classifier = (classifier == null ? "" : classifier);
|
if (parent != null && parent.isModularJar() && TYPE_JAR.equals(type)) {
|
||||||
this.type = (type == null ? "jar" : type);
|
type = TYPE_MODULAR_JAR;
|
||||||
this.exclusions = (exclusions == null ? new ExclusionSet() : exclusions);
|
}
|
||||||
this.parent = parent;
|
|
||||||
|
this.groupId_ = groupId;
|
||||||
|
this.artifactId_ = artifactId;
|
||||||
|
this.version_ = (version == null ? VersionNumber.UNKNOWN : version);
|
||||||
|
this.classifier_ = (classifier == null ? "" : classifier);
|
||||||
|
this.type_ = type;
|
||||||
|
this.exclusions_ = (exclusions == null ? new ExclusionSet() : exclusions);
|
||||||
|
this.parent_ = parent;
|
||||||
|
this.excludedClassifiers_ = new HashSet<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Pattern DEPENDENCY_PATTERN = Pattern.compile("^(?<groupId>[^:@]+):(?<artifactId>[^:@]+)(?::(?<version>[^:@]+)(?::(?<classifier>[^:@]+))?)?(?:@(?<type>[^:@]+))?$");
|
private static final Pattern DEPENDENCY_PATTERN = Pattern.compile("^(?<groupId>[^:@]+):(?<artifactId>[^:@]+)(?::(?<version>[^:@]+)(?::(?<classifier>[^:@]+))?)?(?:@(?<type>[^:@]+))?$");
|
||||||
|
|
@ -80,7 +113,7 @@ public record Dependency(String groupId, String artifactId, VersionNumber versio
|
||||||
|
|
||||||
var groupId = matcher.group("groupId");
|
var groupId = matcher.group("groupId");
|
||||||
var artifactId = matcher.group("artifactId");
|
var artifactId = matcher.group("artifactId");
|
||||||
var version = VersionNumber.parse(matcher.group("version"));
|
var version = Version.parse(matcher.group("version"));
|
||||||
var classifier = matcher.group("classifier");
|
var classifier = matcher.group("classifier");
|
||||||
var type = matcher.group("type");
|
var type = matcher.group("type");
|
||||||
|
|
||||||
|
|
@ -95,7 +128,7 @@ public record Dependency(String groupId, String artifactId, VersionNumber versio
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
public Dependency baseDependency() {
|
public Dependency baseDependency() {
|
||||||
return new Dependency(groupId, artifactId, VersionNumber.UNKNOWN, classifier, type);
|
return new Dependency(groupId_, artifactId_, VersionNumber.UNKNOWN, classifier_, type_);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -107,7 +140,7 @@ public record Dependency(String groupId, String artifactId, VersionNumber versio
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
public Dependency exclude(String groupId, String artifactId) {
|
public Dependency exclude(String groupId, String artifactId) {
|
||||||
exclusions.add(new DependencyExclusion(groupId, artifactId));
|
exclusions_.add(new DependencyExclusion(groupId, artifactId));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -119,7 +152,29 @@ public record Dependency(String groupId, String artifactId, VersionNumber versio
|
||||||
* @since 1.5.6
|
* @since 1.5.6
|
||||||
*/
|
*/
|
||||||
public Dependency withClassifier(String classifier) {
|
public Dependency withClassifier(String classifier) {
|
||||||
return new Dependency(groupId, artifactId, version, classifier, type);
|
return new Dependency(groupId_, artifactId_, version_, classifier, type_);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exclude the sources artifact from download operations.
|
||||||
|
*
|
||||||
|
* @return this dependency instance
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public Dependency excludeSources() {
|
||||||
|
excludedClassifiers_.add(CLASSIFIER_SOURCES);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exclude the javadoc artifact from download operations.
|
||||||
|
*
|
||||||
|
* @return this dependency instance
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public Dependency excludeJavadoc() {
|
||||||
|
excludedClassifiers_.add(CLASSIFIER_JAVADOC);
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -130,40 +185,150 @@ public record Dependency(String groupId, String artifactId, VersionNumber versio
|
||||||
*/
|
*/
|
||||||
public String toFileName() {
|
public String toFileName() {
|
||||||
var result = new StringBuilder(artifactId());
|
var result = new StringBuilder(artifactId());
|
||||||
result.append("-").append(version());
|
result.append('-').append(version());
|
||||||
if (!classifier().isEmpty()) {
|
if (!classifier().isEmpty()) {
|
||||||
result.append("-").append(classifier());
|
result.append('-').append(classifier());
|
||||||
}
|
}
|
||||||
result.append(".").append(type());
|
result.append('.').append(type());
|
||||||
return result.toString();
|
return result.toString();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a string representation of the dependency in the format "groupId:artifactId".
|
||||||
|
*
|
||||||
|
* @return the string representation of the dependency
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public String toArtifactString() {
|
||||||
|
return groupId_ + ':' + artifactId_;
|
||||||
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
var result = new StringBuilder(groupId).append(":").append(artifactId);
|
var result = new StringBuilder(groupId_).append(':').append(artifactId_);
|
||||||
if (!version.equals(VersionNumber.UNKNOWN)) {
|
if (!version_.equals(VersionNumber.UNKNOWN)) {
|
||||||
result.append(":").append(version);
|
result.append(':').append(version_);
|
||||||
}
|
}
|
||||||
if (!classifier.isEmpty()) {
|
if (!classifier_.isEmpty()) {
|
||||||
result.append(":").append(classifier);
|
result.append(':').append(classifier_);
|
||||||
}
|
}
|
||||||
if (!type.isEmpty() && !type.equals("jar")) {
|
if (!type_.isEmpty() && !TYPE_JAR.equals(type_)) {
|
||||||
result.append("@").append(type);
|
result.append('@').append(type_);
|
||||||
}
|
}
|
||||||
return result.toString();
|
return result.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns this dependency's {@code groupId}.
|
||||||
|
*
|
||||||
|
* @return the {@code groupId} of this dependency
|
||||||
|
* @since 1.5
|
||||||
|
*/
|
||||||
|
public String groupId() {
|
||||||
|
return groupId_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns this dependency's {@code artifactId}.
|
||||||
|
*
|
||||||
|
* @return the {@code artifactId} of this dependency
|
||||||
|
* @since 1.5
|
||||||
|
*/
|
||||||
|
public String artifactId() {
|
||||||
|
return artifactId_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns this dependency's {@code version}.
|
||||||
|
*
|
||||||
|
* @return the {@code version} of this dependency
|
||||||
|
* @since 1.5
|
||||||
|
*/
|
||||||
|
public Version version() {
|
||||||
|
return version_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns this dependency's {@code classifier}.
|
||||||
|
*
|
||||||
|
* @return the {@code classifier} of this dependency
|
||||||
|
* @since 1.5
|
||||||
|
*/
|
||||||
|
public String classifier() {
|
||||||
|
return classifier_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns this dependency's {@code type}.
|
||||||
|
*
|
||||||
|
* @return the {@code type} of this dependency
|
||||||
|
* @since 1.5
|
||||||
|
*/
|
||||||
|
public String type() {
|
||||||
|
return type_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns this dependency's {@code exclusions} for transitive resolution.
|
||||||
|
*
|
||||||
|
* @return the {@code exclusions} of this dependency
|
||||||
|
* @since 1.5
|
||||||
|
*/
|
||||||
|
public ExclusionSet exclusions() {
|
||||||
|
return exclusions_;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HashSet<String> excludedClassifiers() {
|
||||||
|
return excludedClassifiers_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns this dependency's {@code parent} dependency that created this
|
||||||
|
* dependency (only for information purposes).
|
||||||
|
*
|
||||||
|
* @return the {@code parent} of this dependency
|
||||||
|
* @since 1.5
|
||||||
|
*/
|
||||||
|
public Dependency parent() {
|
||||||
|
return parent_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether this dependency specifically is a classpath jar or not.
|
||||||
|
*
|
||||||
|
* @return {@code true} when this dependency specifically is a classpath jar; or {@code false} otherwise
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public boolean isClasspathJar() {
|
||||||
|
return Module.TYPE_CLASSPATH_JAR.equals(type_);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether this dependency is a modular jar or not.
|
||||||
|
*
|
||||||
|
* @return {@code true} when this dependency is a modular jar; or {@code false} otherwise
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public boolean isModularJar() {
|
||||||
|
return Module.TYPE_MODULAR_JAR.equals(type_);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String normalizedJarType(String type) {
|
||||||
|
if (TYPE_JAR.equals(type) || TYPE_MODULAR_JAR.equals(type) || TYPE_CLASSPATH_JAR.equals(type)) {
|
||||||
|
return TYPE_JAR;
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
}
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (!(o instanceof Dependency that)) return false;
|
||||||
var that = (Dependency) o;
|
return groupId_.equals(that.groupId_) &&
|
||||||
return groupId.equals(that.groupId) &&
|
artifactId_.equals(that.artifactId_) &&
|
||||||
artifactId.equals(that.artifactId) &&
|
classifier_.equals(that.classifier_) &&
|
||||||
classifier.equals(that.classifier) &&
|
normalizedJarType(type_).equals(normalizedJarType(that.type_));
|
||||||
type.equals(that.type);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(groupId, artifactId, classifier, type);
|
return Objects.hash(groupId_, artifactId_, classifier_, normalizedJarType(type_));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,10 +25,10 @@ public record DependencyExclusion(String groupId, String artifactId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean matches(PomDependency dependency) {
|
boolean matches(PomDependency dependency) {
|
||||||
return (groupId().equals("*") && artifactId().equals("*")) ||
|
return ("*".equals(groupId()) && "*".equals(artifactId())) ||
|
||||||
(groupId().equals("*") && artifactId().equals(dependency.artifactId())) ||
|
("*".equals(groupId()) && artifactId().equals(dependency.artifactId())) ||
|
||||||
(groupId().equals(dependency.groupId()) && artifactId().equals("*")) ||
|
(groupId().equals(dependency.groupId()) && "*".equals(artifactId())) ||
|
||||||
(groupId().equals(dependency.groupId()) && artifactId().equals(dependency.artifactId()));
|
(groupId().equals(dependency.groupId()) && dependency.artifactId().equals(artifactId()));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,8 @@ import java.io.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static rife.bld.dependencies.Dependency.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolves a dependency within a list of Maven-compatible repositories.
|
* Resolves a dependency within a list of Maven-compatible repositories.
|
||||||
*
|
*
|
||||||
|
|
@ -18,6 +20,7 @@ import java.util.stream.Collectors;
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
public class DependencyResolver {
|
public class DependencyResolver {
|
||||||
|
private final VersionResolution resolution_;
|
||||||
private final ArtifactRetriever retriever_;
|
private final ArtifactRetriever retriever_;
|
||||||
private final List<Repository> repositories_;
|
private final List<Repository> repositories_;
|
||||||
private final Dependency dependency_;
|
private final Dependency dependency_;
|
||||||
|
|
@ -30,12 +33,14 @@ public class DependencyResolver {
|
||||||
* <p>
|
* <p>
|
||||||
* The repositories will be checked in the order they're listed.
|
* The repositories will be checked in the order they're listed.
|
||||||
*
|
*
|
||||||
|
* @param resolution the version resolution state that can be cached
|
||||||
* @param retriever the retriever to use to get artifacts
|
* @param retriever the retriever to use to get artifacts
|
||||||
* @param repositories the repositories to use for the resolution
|
* @param repositories the repositories to use for the resolution
|
||||||
* @param dependency the dependency to resolve
|
* @param dependency the dependency to resolve
|
||||||
* @since 1.5.18
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
public DependencyResolver(ArtifactRetriever retriever, List<Repository> repositories, Dependency dependency) {
|
public DependencyResolver(VersionResolution resolution, ArtifactRetriever retriever, List<Repository> repositories, Dependency dependency) {
|
||||||
|
resolution_ = resolution;
|
||||||
retriever_ = retriever;
|
retriever_ = retriever;
|
||||||
if (repositories == null) {
|
if (repositories == null) {
|
||||||
repositories = Collections.emptyList();
|
repositories = Collections.emptyList();
|
||||||
|
|
@ -64,7 +69,6 @@ public class DependencyResolver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolves the dependency version in the provided repositories.
|
* Resolves the dependency version in the provided repositories.
|
||||||
* <p>
|
* <p>
|
||||||
|
|
@ -76,8 +80,8 @@ public class DependencyResolver {
|
||||||
* @return the resolved version
|
* @return the resolved version
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
public VersionNumber resolveVersion() {
|
public Version resolveVersion() {
|
||||||
var version = dependency_.version();
|
var version = resolution_.overrideVersion(dependency_);
|
||||||
if (version.equals(VersionNumber.UNKNOWN)) {
|
if (version.equals(VersionNumber.UNKNOWN)) {
|
||||||
return latestVersion();
|
return latestVersion();
|
||||||
}
|
}
|
||||||
|
|
@ -98,7 +102,7 @@ public class DependencyResolver {
|
||||||
var pom_dependencies = getMavenPom(dependency_).getDependencies(scopes);
|
var pom_dependencies = getMavenPom(dependency_).getDependencies(scopes);
|
||||||
var result = new DependencySet();
|
var result = new DependencySet();
|
||||||
for (var dependency : pom_dependencies) {
|
for (var dependency : pom_dependencies) {
|
||||||
result.add(dependency.convertToDependency());
|
result.add(resolution_.overrideDependency(dependency.convertToDependency()));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
@ -118,11 +122,12 @@ public class DependencyResolver {
|
||||||
*/
|
*/
|
||||||
public DependencySet getAllDependencies(Scope... scopes) {
|
public DependencySet getAllDependencies(Scope... scopes) {
|
||||||
var result = new DependencySet();
|
var result = new DependencySet();
|
||||||
result.add(dependency_);
|
var overridden = resolution_.overrideDependency(dependency_);
|
||||||
|
result.add(overridden);
|
||||||
|
|
||||||
var dependency_queue = new ArrayList<PomDependency>();
|
var dependency_queue = new ArrayList<PomDependency>();
|
||||||
|
|
||||||
var parent = dependency_;
|
var parent = overridden;
|
||||||
var next_dependencies = getMavenPom(parent).getDependencies(scopes);
|
var next_dependencies = getMavenPom(parent).getDependencies(scopes);
|
||||||
|
|
||||||
while (parent != null && next_dependencies != null) {
|
while (parent != null && next_dependencies != null) {
|
||||||
|
|
@ -142,7 +147,7 @@ public class DependencyResolver {
|
||||||
// part of the results yet
|
// part of the results yet
|
||||||
while (!dependency_queue.isEmpty()) {
|
while (!dependency_queue.isEmpty()) {
|
||||||
var candidate = dependency_queue.remove(0);
|
var candidate = dependency_queue.remove(0);
|
||||||
var dependency = candidate.convertToDependency();
|
var dependency = resolution_.overrideDependency(candidate.convertToDependency());
|
||||||
if (!result.contains(dependency)) {
|
if (!result.contains(dependency)) {
|
||||||
result.add(dependency);
|
result.add(dependency);
|
||||||
|
|
||||||
|
|
@ -150,7 +155,7 @@ public class DependencyResolver {
|
||||||
// dependencies so that they can be added to the queue after
|
// dependencies so that they can be added to the queue after
|
||||||
// filtering
|
// filtering
|
||||||
parent = dependency;
|
parent = dependency;
|
||||||
next_dependencies = new DependencyResolver(retriever_, repositories_, dependency).getMavenPom(parent).getDependencies(scopes);
|
next_dependencies = new DependencyResolver(resolution_, retriever_, repositories_, dependency).getMavenPom(parent).getDependencies(scopes);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -188,7 +193,7 @@ public class DependencyResolver {
|
||||||
* couldn't be found in the provided repositories
|
* couldn't be found in the provided repositories
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
public List<VersionNumber> listVersions() {
|
public List<Version> listVersions() {
|
||||||
return getMavenMetadata().getVersions();
|
return getMavenMetadata().getVersions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -199,7 +204,7 @@ public class DependencyResolver {
|
||||||
* if the dependency couldn't be found in the provided repositories
|
* if the dependency couldn't be found in the provided repositories
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
public VersionNumber latestVersion() {
|
public Version latestVersion() {
|
||||||
return getMavenMetadata().getLatest();
|
return getMavenMetadata().getLatest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -210,7 +215,7 @@ public class DependencyResolver {
|
||||||
* if the dependency couldn't be found in the provided repositories
|
* if the dependency couldn't be found in the provided repositories
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
public VersionNumber releaseVersion() {
|
public Version releaseVersion() {
|
||||||
return getMavenMetadata().getRelease();
|
return getMavenMetadata().getRelease();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -258,6 +263,16 @@ public class DependencyResolver {
|
||||||
return dependency_;
|
return dependency_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the version resolution state that can be cached.
|
||||||
|
*
|
||||||
|
* @return the version resolution state
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public VersionResolution resolution() {
|
||||||
|
return resolution_;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves all the potential locations for the dependency
|
* Retrieves all the potential locations for the dependency
|
||||||
* within the provided repositories.
|
* within the provided repositories.
|
||||||
|
|
@ -305,7 +320,7 @@ public class DependencyResolver {
|
||||||
|
|
||||||
private List<RepositoryArtifact> getTransferArtifacts() {
|
private List<RepositoryArtifact> getTransferArtifacts() {
|
||||||
final var version = resolveVersion();
|
final var version = resolveVersion();
|
||||||
final VersionNumber pom_version;
|
final Version pom_version;
|
||||||
if (version.isSnapshot()) {
|
if (version.isSnapshot()) {
|
||||||
var metadata = getSnapshotMavenMetadata();
|
var metadata = getSnapshotMavenMetadata();
|
||||||
pom_version = metadata.getSnapshot();
|
pom_version = metadata.getSnapshot();
|
||||||
|
|
@ -315,15 +330,15 @@ public class DependencyResolver {
|
||||||
|
|
||||||
return getArtifactLocations().stream().map(a -> {
|
return getArtifactLocations().stream().map(a -> {
|
||||||
var result = new StringBuilder();
|
var result = new StringBuilder();
|
||||||
result.append(version).append("/").append(dependency_.artifactId()).append("-").append(pom_version);
|
result.append(version).append('/').append(dependency_.artifactId()).append('-').append(pom_version);
|
||||||
if (!dependency_.classifier().isEmpty()) {
|
if (!dependency_.classifier().isEmpty()) {
|
||||||
result.append("-").append(dependency_.classifier());
|
result.append('-').append(dependency_.classifier());
|
||||||
}
|
}
|
||||||
var type = dependency_.type();
|
var type = dependency_.type();
|
||||||
if (type == null) {
|
if (type == null || TYPE_JAR.equals(type) || TYPE_MODULAR_JAR.equals(type) || TYPE_CLASSPATH_JAR.equals(type)) {
|
||||||
type = "jar";
|
type = "jar";
|
||||||
}
|
}
|
||||||
result.append(".").append(type);
|
result.append('.').append(type);
|
||||||
|
|
||||||
return a.appendPath(result.toString());
|
return a.appendPath(result.toString());
|
||||||
}).toList();
|
}).toList();
|
||||||
|
|
@ -365,7 +380,16 @@ public class DependencyResolver {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (metadata == null) {
|
if (metadata == null) {
|
||||||
throw new ArtifactNotFoundException(dependency_, artifacts.stream().map(RepositoryArtifact::location).collect(Collectors.joining(", ")));
|
var location = artifacts.stream().map(RepositoryArtifact::location).collect(Collectors.joining(", "));
|
||||||
|
if (location.isEmpty()) {
|
||||||
|
if (repositories_.isEmpty()) {
|
||||||
|
location = "[no repositories defined]";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
location = "[no metadata locations defined]";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new ArtifactNotFoundException(dependency_, location);
|
||||||
}
|
}
|
||||||
|
|
||||||
var xml = new Xml2MavenMetadata();
|
var xml = new Xml2MavenMetadata();
|
||||||
|
|
@ -378,7 +402,7 @@ public class DependencyResolver {
|
||||||
|
|
||||||
private List<RepositoryArtifact> getPomLocations() {
|
private List<RepositoryArtifact> getPomLocations() {
|
||||||
final var version = resolveVersion();
|
final var version = resolveVersion();
|
||||||
final VersionNumber pom_version;
|
final Version pom_version;
|
||||||
if (version.isSnapshot()) {
|
if (version.isSnapshot()) {
|
||||||
var metadata = getSnapshotMavenMetadata();
|
var metadata = getSnapshotMavenMetadata();
|
||||||
pom_version = metadata.getSnapshot();
|
pom_version = metadata.getSnapshot();
|
||||||
|
|
@ -414,10 +438,24 @@ public class DependencyResolver {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pom == null) {
|
if (pom == null) {
|
||||||
throw new ArtifactNotFoundException(dependency_, artifacts.stream().map(RepositoryArtifact::location).collect(Collectors.joining(", ")));
|
var location = artifacts.stream().map(RepositoryArtifact::location).collect(Collectors.joining(", "));
|
||||||
|
if (location.isEmpty()) {
|
||||||
|
if (repositories_.isEmpty()) {
|
||||||
|
location = "[no repositories defined]";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
location = "[no pom locations defined]";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new ArtifactNotFoundException(dependency_, location);
|
||||||
}
|
}
|
||||||
|
|
||||||
var xml = new Xml2MavenPom(parent, retriever_, repositories_);
|
var xml = new Xml2MavenPom(parent, resolution_, retriever_, repositories_);
|
||||||
|
// first pass only extracts the properties from the pom
|
||||||
|
if (!xml.processXml(pom)) {
|
||||||
|
throw new DependencyXmlParsingErrorException(dependency_, retrieved_artifact.location(), xml.getErrors());
|
||||||
|
}
|
||||||
|
// second pass parses all the rest so that the properties are available anywhere
|
||||||
if (!xml.processXml(pom)) {
|
if (!xml.processXml(pom)) {
|
||||||
throw new DependencyXmlParsingErrorException(dependency_, retrieved_artifact.location(), xml.getErrors());
|
throw new DependencyXmlParsingErrorException(dependency_, retrieved_artifact.location(), xml.getErrors());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,8 @@
|
||||||
*/
|
*/
|
||||||
package rife.bld.dependencies;
|
package rife.bld.dependencies;
|
||||||
|
|
||||||
|
import rife.ioc.HierarchicalProperties;
|
||||||
|
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
|
@ -66,43 +68,62 @@ public class DependencyScopes extends LinkedHashMap<Scope, DependencySet> {
|
||||||
/**
|
/**
|
||||||
* Returns the transitive set of dependencies that would be used for the compile scope in a project.
|
* Returns the transitive set of dependencies that would be used for the compile scope in a project.
|
||||||
*
|
*
|
||||||
|
* @param properties the properties to use to get artifacts
|
||||||
* @param retriever the retriever to use to get artifacts
|
* @param retriever the retriever to use to get artifacts
|
||||||
* @param repositories the repositories to use for the resolution
|
* @param repositories the repositories to use for the resolution
|
||||||
* @return the compile scope dependency set
|
* @return the compile scope dependency set
|
||||||
* @since 1.6
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
public DependencySet resolveCompileDependencies(ArtifactRetriever retriever, List<Repository> repositories) {
|
public DependencySet resolveCompileDependencies(HierarchicalProperties properties, ArtifactRetriever retriever, List<Repository> repositories) {
|
||||||
return resolveScopedDependencies(retriever, repositories,
|
return resolveScopedDependencies(properties, retriever, repositories,
|
||||||
new Scope[]{Scope.provided, Scope.compile},
|
|
||||||
new Scope[]{Scope.compile},
|
new Scope[]{Scope.compile},
|
||||||
|
new Scope[]{Scope.compile},
|
||||||
|
null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the transitive set of dependencies that would be used for the provided scope in a project.
|
||||||
|
*
|
||||||
|
* @param properties the properties to use to get artifacts
|
||||||
|
* @param retriever the retriever to use to get artifacts
|
||||||
|
* @param repositories the repositories to use for the resolution
|
||||||
|
* @return the provided scope dependency set
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public DependencySet resolveProvidedDependencies(HierarchicalProperties properties, ArtifactRetriever retriever, List<Repository> repositories) {
|
||||||
|
return resolveScopedDependencies(properties, retriever, repositories,
|
||||||
|
new Scope[]{Scope.provided},
|
||||||
|
new Scope[]{Scope.compile, Scope.runtime},
|
||||||
null);
|
null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the transitive set of dependencies that would be used for the runtime scope in a project.
|
* Returns the transitive set of dependencies that would be used for the runtime scope in a project.
|
||||||
*
|
*
|
||||||
|
* @param properties the properties to use to get artifacts
|
||||||
* @param retriever the retriever to use to get artifacts
|
* @param retriever the retriever to use to get artifacts
|
||||||
* @param repositories the repositories to use for the resolution
|
* @param repositories the repositories to use for the resolution
|
||||||
* @return the runtime scope dependency set
|
* @return the runtime scope dependency set
|
||||||
* @since 1.6
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
public DependencySet resolveRuntimeDependencies(ArtifactRetriever retriever, List<Repository> repositories) {
|
public DependencySet resolveRuntimeDependencies(HierarchicalProperties properties, ArtifactRetriever retriever, List<Repository> repositories) {
|
||||||
return resolveScopedDependencies(retriever, repositories,
|
return resolveScopedDependencies(properties, retriever, repositories,
|
||||||
new Scope[]{Scope.provided, Scope.compile, Scope.runtime},
|
|
||||||
new Scope[]{Scope.compile, Scope.runtime},
|
new Scope[]{Scope.compile, Scope.runtime},
|
||||||
resolveCompileDependencies(retriever, repositories));
|
new Scope[]{Scope.compile, Scope.runtime},
|
||||||
|
resolveCompileDependencies(properties, retriever, repositories));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the transitive set of dependencies that would be used for the standalone scope in a project.
|
* Returns the transitive set of dependencies that would be used for the standalone scope in a project.
|
||||||
*
|
*
|
||||||
|
* @param properties the properties to use to get artifacts
|
||||||
* @param retriever the retriever to use to get artifacts
|
* @param retriever the retriever to use to get artifacts
|
||||||
* @param repositories the repositories to use for the resolution
|
* @param repositories the repositories to use for the resolution
|
||||||
* @return the standalone scope dependency set
|
* @return the standalone scope dependency set
|
||||||
* @since 1.6
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
public DependencySet resolveStandaloneDependencies(ArtifactRetriever retriever, List<Repository> repositories) {
|
public DependencySet resolveStandaloneDependencies(HierarchicalProperties properties, ArtifactRetriever retriever, List<Repository> repositories) {
|
||||||
return resolveScopedDependencies(retriever, repositories,
|
return resolveScopedDependencies(properties, retriever, repositories,
|
||||||
new Scope[]{Scope.standalone},
|
new Scope[]{Scope.standalone},
|
||||||
new Scope[]{Scope.compile, Scope.runtime},
|
new Scope[]{Scope.compile, Scope.runtime},
|
||||||
null);
|
null);
|
||||||
|
|
@ -111,25 +132,27 @@ public class DependencyScopes extends LinkedHashMap<Scope, DependencySet> {
|
||||||
/**
|
/**
|
||||||
* Returns the transitive set of dependencies that would be used for the test scope in a project.
|
* Returns the transitive set of dependencies that would be used for the test scope in a project.
|
||||||
*
|
*
|
||||||
|
* @param properties the properties to use to get artifacts
|
||||||
* @param retriever the retriever to use to get artifacts
|
* @param retriever the retriever to use to get artifacts
|
||||||
* @param repositories the repositories to use for the resolution
|
* @param repositories the repositories to use for the resolution
|
||||||
* @return the test scope dependency set
|
* @return the test scope dependency set
|
||||||
* @since 1.6
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
public DependencySet resolveTestDependencies(ArtifactRetriever retriever, List<Repository> repositories) {
|
public DependencySet resolveTestDependencies(HierarchicalProperties properties, ArtifactRetriever retriever, List<Repository> repositories) {
|
||||||
return resolveScopedDependencies(retriever, repositories,
|
return resolveScopedDependencies(properties, retriever, repositories,
|
||||||
new Scope[]{Scope.test},
|
new Scope[]{Scope.test},
|
||||||
new Scope[]{Scope.compile, Scope.runtime},
|
new Scope[]{Scope.compile, Scope.runtime},
|
||||||
null);
|
null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private DependencySet resolveScopedDependencies(ArtifactRetriever retriever, List<Repository> repositories, Scope[] resolvedScopes, Scope[] transitiveScopes, DependencySet excluded) {
|
private DependencySet resolveScopedDependencies(HierarchicalProperties properties, ArtifactRetriever retriever, List<Repository> repositories, Scope[] resolvedScopes, Scope[] transitiveScopes, DependencySet excluded) {
|
||||||
|
var resolution = new VersionResolution(properties);
|
||||||
var dependencies = new DependencySet();
|
var dependencies = new DependencySet();
|
||||||
for (var scope : resolvedScopes) {
|
for (var scope : resolvedScopes) {
|
||||||
var scoped_dependencies = get(scope);
|
var scoped_dependencies = get(scope);
|
||||||
if (scoped_dependencies != null) {
|
if (scoped_dependencies != null) {
|
||||||
for (var dependency : scoped_dependencies) {
|
for (var dependency : scoped_dependencies) {
|
||||||
dependencies.addAll(new DependencyResolver(retriever, repositories, dependency).getAllDependencies(transitiveScopes));
|
dependencies.addAll(new DependencyResolver(resolution, retriever, repositories, dependency).getAllDependencies(transitiveScopes));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ import java.util.*;
|
||||||
public class DependencySet extends AbstractSet<Dependency> implements Set<Dependency> {
|
public class DependencySet extends AbstractSet<Dependency> implements Set<Dependency> {
|
||||||
private final Map<Dependency, Dependency> dependencies_ = new LinkedHashMap<>();
|
private final Map<Dependency, Dependency> dependencies_ = new LinkedHashMap<>();
|
||||||
private final Set<LocalDependency> localDependencies_ = new LinkedHashSet<>();
|
private final Set<LocalDependency> localDependencies_ = new LinkedHashSet<>();
|
||||||
|
private final Set<LocalModule> localModules_ = new LinkedHashSet<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an empty dependency set.
|
* Creates an empty dependency set.
|
||||||
|
|
@ -79,48 +80,94 @@ public class DependencySet extends AbstractSet<Dependency> implements Set<Depend
|
||||||
return localDependencies_;
|
return localDependencies_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Includes a local module into the dependency set.
|
||||||
|
* <p>
|
||||||
|
* Local modules aren't resolved and point to a location on
|
||||||
|
* the file system.
|
||||||
|
*
|
||||||
|
* @param module the module to include
|
||||||
|
* @return this dependency set instance
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public DependencySet include(LocalModule module) {
|
||||||
|
localModules_.add(module);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the local modules.
|
||||||
|
*
|
||||||
|
* @return the set of local modules
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public Set<LocalModule> localModules() {
|
||||||
|
return localModules_;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transfers the artifacts for the dependencies into the provided directory.
|
* Transfers the artifacts for the dependencies into the provided directory.
|
||||||
* <p>
|
* <p>
|
||||||
* The destination directory must exist and be writable.
|
* The destination directory must exist and be writable.
|
||||||
*
|
*
|
||||||
* @param retriever the retriever to use to get artifacts
|
* @param resolution the version resolution state that can be cached
|
||||||
* @param repositories the repositories to use for the transfer
|
* @param retriever the retriever to use to get artifacts
|
||||||
* @param directory the directory to transfer the artifacts into
|
* @param repositories the repositories to use for the transfer
|
||||||
|
* @param directory the directory to transfer the artifacts into
|
||||||
|
* @param modulesDirectory the directory to download the modules into
|
||||||
* @return the list of artifacts that were transferred successfully
|
* @return the list of artifacts that were transferred successfully
|
||||||
* @throws DependencyTransferException when an error occurred during the transfer
|
* @throws DependencyTransferException when an error occurred during the transfer
|
||||||
* @since 1.5.10
|
* @since 2.1
|
||||||
*/
|
*/
|
||||||
public List<RepositoryArtifact> transferIntoDirectory(ArtifactRetriever retriever, List<Repository> repositories, File directory) {
|
public List<RepositoryArtifact> transferIntoDirectory(VersionResolution resolution, ArtifactRetriever retriever, List<Repository> repositories, File directory, File modulesDirectory) {
|
||||||
return transferIntoDirectory(retriever, repositories, directory, (String[]) null);
|
return transferIntoDirectory(resolution, retriever, repositories, directory, modulesDirectory, (String[]) null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transfers the artifacts for the dependencies into the provided directory,
|
* Transfers the artifacts for the dependencies into the provided directories,
|
||||||
* including other classifiers.
|
* including other classifiers.
|
||||||
* <p>
|
* <p>
|
||||||
* The destination directory must exist and be writable.
|
* The destination directory must exist and be writable.
|
||||||
*
|
*
|
||||||
* @param retriever the retriever to use to get artifacts
|
* @param resolution the version resolution state that can be cached
|
||||||
* @param repositories the repositories to use for the download
|
* @param retriever the retriever to use to get artifacts
|
||||||
* @param directory the directory to download the artifacts into
|
* @param repositories the repositories to use for the download
|
||||||
* @param classifiers the additional classifiers to transfer
|
* @param directory the directory to download the artifacts into
|
||||||
|
* @param modulesDirectory the directory to download the modules into
|
||||||
|
* @param classifiers the additional classifiers to transfer
|
||||||
* @return the list of artifacts that were transferred successfully
|
* @return the list of artifacts that were transferred successfully
|
||||||
* @throws DependencyTransferException when an error occurred during the transfer
|
* @throws DependencyTransferException when an error occurred during the transfer
|
||||||
* @since 1.5.10
|
* @since 2.1
|
||||||
*/
|
*/
|
||||||
public List<RepositoryArtifact> transferIntoDirectory(ArtifactRetriever retriever, List<Repository> repositories, File directory, String... classifiers) {
|
public List<RepositoryArtifact> transferIntoDirectory(VersionResolution resolution, ArtifactRetriever retriever, List<Repository> repositories, File directory, File modulesDirectory, String... classifiers) {
|
||||||
var result = new ArrayList<RepositoryArtifact>();
|
var result = new ArrayList<RepositoryArtifact>();
|
||||||
for (var dependency : this) {
|
for (var dependency : this) {
|
||||||
var artifact = new DependencyResolver(retriever, repositories, dependency).transferIntoDirectory(directory);
|
var transfer_directory = directory;
|
||||||
|
if (dependency.isModularJar()) {
|
||||||
|
if (modulesDirectory == null) {
|
||||||
|
throw new DependencyTransferException(dependency, "modules directory is not provided");
|
||||||
|
}
|
||||||
|
transfer_directory = modulesDirectory;
|
||||||
|
}
|
||||||
|
else if (directory == null) {
|
||||||
|
throw new DependencyTransferException(dependency, "artifacts directory is not provided");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!transfer_directory.exists()) {
|
||||||
|
if (!transfer_directory.mkdirs()) {
|
||||||
|
throw new DependencyTransferException(dependency, transfer_directory, "couldn't create directory");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var artifact = new DependencyResolver(resolution, retriever, repositories, dependency).transferIntoDirectory(transfer_directory);
|
||||||
if (artifact != null) {
|
if (artifact != null) {
|
||||||
result.add(artifact);
|
result.add(artifact);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (classifiers != null) {
|
if (classifiers != null) {
|
||||||
for (var classifier : classifiers) {
|
for (var classifier : classifiers) {
|
||||||
if (classifier != null) {
|
if (classifier != null && !dependency.excludedClassifiers().contains(classifier)) {
|
||||||
var classifier_artifact = new DependencyResolver(retriever, repositories, dependency.withClassifier(classifier)).transferIntoDirectory(directory);
|
var classifier_artifact = new DependencyResolver(resolution, retriever, repositories, dependency.withClassifier(classifier)).transferIntoDirectory(transfer_directory);
|
||||||
if (classifier_artifact != null) {
|
if (classifier_artifact != null) {
|
||||||
result.add(classifier_artifact);
|
result.add(classifier_artifact);
|
||||||
}
|
}
|
||||||
|
|
@ -150,17 +197,18 @@ public class DependencySet extends AbstractSet<Dependency> implements Set<Depend
|
||||||
* Generates the string description of the transitive hierarchical tree of
|
* Generates the string description of the transitive hierarchical tree of
|
||||||
* dependencies for a particular scope.
|
* dependencies for a particular scope.
|
||||||
*
|
*
|
||||||
|
* @param resolution the version resolution state that can be cached
|
||||||
* @param retriever the retriever to use to get artifacts
|
* @param retriever the retriever to use to get artifacts
|
||||||
* @param repositories the repositories to look for dependencies in
|
* @param repositories the repositories to look for dependencies in
|
||||||
* @param scopes the scopes to return the transitive dependencies for
|
* @param scopes the scopes to return the transitive dependencies for
|
||||||
* @return the generated tree description string; or an empty string if
|
* @return the generated tree description string; or an empty string if
|
||||||
* there were no dependencies to describe
|
* there were no dependencies to describe
|
||||||
* @since 1.5.21
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
public String generateTransitiveDependencyTree(ArtifactRetriever retriever, List<Repository> repositories, Scope... scopes) {
|
public String generateTransitiveDependencyTree(VersionResolution resolution, ArtifactRetriever retriever, List<Repository> repositories, Scope... scopes) {
|
||||||
var compile_dependencies = new DependencySet();
|
var compile_dependencies = new DependencySet();
|
||||||
for (var dependency : this) {
|
for (var dependency : this) {
|
||||||
compile_dependencies.addAll(new DependencyResolver(retriever, repositories, dependency).getAllDependencies(scopes));
|
compile_dependencies.addAll(new DependencyResolver(resolution, retriever, repositories, dependency).getAllDependencies(scopes));
|
||||||
}
|
}
|
||||||
return compile_dependencies.generateDependencyTree();
|
return compile_dependencies.generateDependencyTree();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
17
src/main/java/rife/bld/dependencies/LocalModule.java
Normal file
17
src/main/java/rife/bld/dependencies/LocalModule.java
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2001-2024 Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||||
|
*/
|
||||||
|
package rife.bld.dependencies;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains the information required to describe a local module for the build system.
|
||||||
|
* <p>
|
||||||
|
* If the local module points to a directory, it will be scanned for jar files.
|
||||||
|
*
|
||||||
|
* @param path the file system path of the local module
|
||||||
|
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public record LocalModule(String path) {
|
||||||
|
}
|
||||||
|
|
@ -14,28 +14,28 @@ import java.util.List;
|
||||||
*/
|
*/
|
||||||
public interface MavenMetadata {
|
public interface MavenMetadata {
|
||||||
/**
|
/**
|
||||||
* Returns latest version number in the metadata.
|
* Returns latest version in the metadata.
|
||||||
*
|
*
|
||||||
* @return the latest version number
|
* @return the latest version
|
||||||
* @since 1.5.8
|
* @since 1.5.8
|
||||||
*/
|
*/
|
||||||
VersionNumber getLatest();
|
Version getLatest();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns release version number in the metadata.
|
* Returns release version in the metadata.
|
||||||
*
|
*
|
||||||
* @return the release version number
|
* @return the release version
|
||||||
* @since 1.5.8
|
* @since 1.5.8
|
||||||
*/
|
*/
|
||||||
VersionNumber getRelease();
|
Version getRelease();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns snapshot version number in the metadata.
|
* Returns snapshot version in the metadata.
|
||||||
*
|
*
|
||||||
* @return the snapshot version number
|
* @return the snapshot version
|
||||||
* @since 1.5.8
|
* @since 1.5.8
|
||||||
*/
|
*/
|
||||||
VersionNumber getSnapshot();
|
Version getSnapshot();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns snapshot timestamp in the metadata.
|
* Returns snapshot timestamp in the metadata.
|
||||||
|
|
@ -56,8 +56,8 @@ public interface MavenMetadata {
|
||||||
/**
|
/**
|
||||||
* Returns all the release or snapshot versions in the metadata.
|
* Returns all the release or snapshot versions in the metadata.
|
||||||
*
|
*
|
||||||
* @return the version number list
|
* @return the version list
|
||||||
* @since 1.5.8
|
* @since 1.5.8
|
||||||
*/
|
*/
|
||||||
List<VersionNumber> getVersions();
|
List<Version> getVersions();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
67
src/main/java/rife/bld/dependencies/Module.java
Normal file
67
src/main/java/rife/bld/dependencies/Module.java
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2001-2024 Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||||
|
*/
|
||||||
|
package rife.bld.dependencies;
|
||||||
|
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains the information required to describe a Java module dependency in the build system.
|
||||||
|
*
|
||||||
|
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public class Module extends Dependency {
|
||||||
|
public Module(String groupId, String artifactId) {
|
||||||
|
this(groupId, artifactId, null, null, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Module(String groupId, String artifactId, Version version) {
|
||||||
|
this(groupId, artifactId, version, null, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Module(String groupId, String artifactId, Version version, String classifier) {
|
||||||
|
this(groupId, artifactId, version, classifier, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Module(String groupId, String artifactId, Version version, String classifier, ExclusionSet exclusions) {
|
||||||
|
this(groupId, artifactId, version, classifier, exclusions, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Module(String groupId, String artifactId, Version version, String classifier, ExclusionSet exclusions, Dependency parent) {
|
||||||
|
super(groupId, artifactId, version, classifier, TYPE_MODULAR_JAR, exclusions, parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Pattern MODULE_PATTERN = Pattern.compile("^(?<groupId>[^:@]+):(?<artifactId>[^:@]+)(?::(?<version>[^:@]+)(?::(?<classifier>[^:@]+))?)?(?:@modular-jar)?$");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses a module from a string representation.
|
||||||
|
* The format is {@code groupId:artifactId:version:classifier}.
|
||||||
|
* The {@code version} and {@code classifier} are optional.
|
||||||
|
* <p>
|
||||||
|
* If the string can't be successfully parsed, {@code null} will be returned.
|
||||||
|
*
|
||||||
|
* @param module the module string to parse
|
||||||
|
* @return a parsed instance of {@code Module}; or
|
||||||
|
* {@code null} when the string couldn't be parsed
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public static Module parse(String module) {
|
||||||
|
if (module == null || module.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var matcher = MODULE_PATTERN.matcher(module);
|
||||||
|
if (!matcher.matches()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var groupId = matcher.group("groupId");
|
||||||
|
var artifactId = matcher.group("artifactId");
|
||||||
|
var version = Version.parse(matcher.group("version"));
|
||||||
|
var classifier = matcher.group("classifier");
|
||||||
|
|
||||||
|
return new Module(groupId, artifactId, version, classifier);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -34,7 +34,7 @@ public record PomDependency(String groupId, String artifactId, String version, S
|
||||||
return new Dependency(
|
return new Dependency(
|
||||||
groupId(),
|
groupId(),
|
||||||
artifactId(),
|
artifactId(),
|
||||||
VersionNumber.parse(version()),
|
Version.parse(version()),
|
||||||
classifier(),
|
classifier(),
|
||||||
type(),
|
type(),
|
||||||
exclusions(),
|
exclusions(),
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,10 @@ package rife.bld.dependencies;
|
||||||
import rife.ioc.HierarchicalProperties;
|
import rife.ioc.HierarchicalProperties;
|
||||||
import rife.tools.StringEncryptor;
|
import rife.tools.StringEncryptor;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains the information required to locate a Maven-compatible repository.
|
* Contains the information required to locate a Maven-compatible repository.
|
||||||
|
|
@ -21,11 +23,18 @@ import java.security.NoSuchAlgorithmException;
|
||||||
*/
|
*/
|
||||||
public record Repository(String location, String username, String password) {
|
public record Repository(String location, String username, String password) {
|
||||||
public static Repository MAVEN_LOCAL = null;
|
public static Repository MAVEN_LOCAL = null;
|
||||||
|
public static final Repository APACHE = new Repository("https://repo.maven.apache.org/maven2/");
|
||||||
|
public static final Repository GOOGLE = new Repository("https://maven.google.com/");
|
||||||
public static final Repository MAVEN_CENTRAL = new Repository("https://repo1.maven.org/maven2/");
|
public static final Repository MAVEN_CENTRAL = new Repository("https://repo1.maven.org/maven2/");
|
||||||
|
public static final Repository SECURECHAIN_REBUILT = new Repository("https://nexus-repo.corp.cloudlinux.com/repository/tuxcare_rebuilt");
|
||||||
|
public static final Repository SECURECHAIN_VETTED = new Repository("https://nexus-repo.corp.cloudlinux.com/repository/tuxcare_vetted");
|
||||||
public static final Repository SONATYPE_RELEASES = new Repository("https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/");
|
public static final Repository SONATYPE_RELEASES = new Repository("https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/");
|
||||||
|
public static final Repository SONATYPE_RELEASES_LEGACY = new Repository("https://oss.sonatype.org/service/local/staging/deploy/maven2/");
|
||||||
public static final Repository SONATYPE_SNAPSHOTS = new Repository("https://s01.oss.sonatype.org/content/repositories/snapshots/");
|
public static final Repository SONATYPE_SNAPSHOTS = new Repository("https://s01.oss.sonatype.org/content/repositories/snapshots/");
|
||||||
public static final Repository SONATYPE_SNAPSHOTS_LEGACY = new Repository("https://oss.sonatype.org/content/repositories/snapshots/");
|
public static final Repository SONATYPE_SNAPSHOTS_LEGACY = new Repository("https://oss.sonatype.org/content/repositories/snapshots/");
|
||||||
public static final Repository APACHE = new Repository("https://repo.maven.apache.org/maven2/");
|
public static final String OSSRH_STAGING_API_DOMAIN = "ossrh-staging-api.central.sonatype.com";
|
||||||
|
public static final Repository CENTRAL_RELEASES = new Repository("https://" + OSSRH_STAGING_API_DOMAIN + "/service/local/staging/deploy/maven2/");
|
||||||
|
public static final Repository CENTRAL_SNAPSHOTS = new Repository("https://central.sonatype.com/repository/maven-snapshots/");
|
||||||
public static final Repository RIFE2_RELEASES = new Repository("https://repo.rife2.com/releases/");
|
public static final Repository RIFE2_RELEASES = new Repository("https://repo.rife2.com/releases/");
|
||||||
public static final Repository RIFE2_SNAPSHOTS = new Repository("https://repo.rife2.com/snapshots/");
|
public static final Repository RIFE2_SNAPSHOTS = new Repository("https://repo.rife2.com/snapshots/");
|
||||||
|
|
||||||
|
|
@ -80,14 +89,20 @@ public record Repository(String location, String username, String password) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return switch (locationOrName) {
|
return switch (locationOrName) {
|
||||||
case "MAVEN_LOCAL" -> Repository.MAVEN_LOCAL;
|
|
||||||
case "MAVEN_CENTRAL" -> Repository.MAVEN_CENTRAL;
|
|
||||||
case "SONATYPE_RELEASES" -> Repository.SONATYPE_RELEASES;
|
|
||||||
case "SONATYPE_SNAPSHOTS" -> Repository.SONATYPE_SNAPSHOTS;
|
|
||||||
case "SONATYPE_SNAPSHOTS_LEGACY" -> Repository.SONATYPE_SNAPSHOTS_LEGACY;
|
|
||||||
case "APACHE" -> Repository.APACHE;
|
case "APACHE" -> Repository.APACHE;
|
||||||
|
case "GOOGLE" -> Repository.GOOGLE;
|
||||||
|
case "MAVEN_CENTRAL" -> Repository.MAVEN_CENTRAL;
|
||||||
|
case "MAVEN_LOCAL" -> Repository.MAVEN_LOCAL;
|
||||||
case "RIFE2_RELEASES" -> Repository.RIFE2_RELEASES;
|
case "RIFE2_RELEASES" -> Repository.RIFE2_RELEASES;
|
||||||
case "RIFE2_SNAPSHOTS" -> Repository.RIFE2_SNAPSHOTS;
|
case "RIFE2_SNAPSHOTS" -> Repository.RIFE2_SNAPSHOTS;
|
||||||
|
case "SECURECHAIN_REBUILT" -> SECURECHAIN_REBUILT;
|
||||||
|
case "SECURECHAIN_VETTED" -> SECURECHAIN_VETTED;
|
||||||
|
case "SONATYPE_RELEASES" -> Repository.SONATYPE_RELEASES;
|
||||||
|
case "SONATYPE_RELEASES_LEGACY" -> Repository.SONATYPE_RELEASES_LEGACY;
|
||||||
|
case "SONATYPE_SNAPSHOTS" -> Repository.SONATYPE_SNAPSHOTS;
|
||||||
|
case "SONATYPE_SNAPSHOTS_LEGACY" -> Repository.SONATYPE_SNAPSHOTS_LEGACY;
|
||||||
|
case "CENTRAL_RELEASES" -> Repository.CENTRAL_RELEASES;
|
||||||
|
case "CENTRAL_SNAPSHOTS" -> Repository.CENTRAL_SNAPSHOTS;
|
||||||
default -> new Repository(locationOrName);
|
default -> new Repository(locationOrName);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -102,6 +117,12 @@ public record Repository(String location, String username, String password) {
|
||||||
this(location, null, null);
|
this(location, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final static Pattern WINDOWS_ABSOLUTE_PATH = Pattern.compile("^\\p{L}:\\\\");
|
||||||
|
|
||||||
|
private boolean isWindowsLocation() {
|
||||||
|
return WINDOWS_ABSOLUTE_PATH.matcher(location()).find();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates whether this repository is local.
|
* Indicates whether this repository is local.
|
||||||
*
|
*
|
||||||
|
|
@ -110,7 +131,7 @@ public record Repository(String location, String username, String password) {
|
||||||
* @since 1.5.10
|
* @since 1.5.10
|
||||||
*/
|
*/
|
||||||
public boolean isLocal() {
|
public boolean isLocal() {
|
||||||
return location().startsWith("/") || location().startsWith("file:");
|
return location().startsWith("/") || location().startsWith("file:") || isWindowsLocation();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -146,9 +167,12 @@ public record Repository(String location, String username, String password) {
|
||||||
* @since 1.5.10
|
* @since 1.5.10
|
||||||
*/
|
*/
|
||||||
public String getArtifactLocation(String groupId, String artifactId) {
|
public String getArtifactLocation(String groupId, String artifactId) {
|
||||||
var group_path = groupId.replace(".", "/");
|
var separator = "/";
|
||||||
var result = new StringBuilder();
|
var result = new StringBuilder();
|
||||||
if (isLocal()) {
|
if (isLocal()) {
|
||||||
|
if (isWindowsLocation()) {
|
||||||
|
separator = File.separator;
|
||||||
|
}
|
||||||
if (location().startsWith("file://")) {
|
if (location().startsWith("file://")) {
|
||||||
result.append(location().substring("file://".length()));
|
result.append(location().substring("file://".length()));
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -157,10 +181,11 @@ public record Repository(String location, String username, String password) {
|
||||||
} else {
|
} else {
|
||||||
result.append(location());
|
result.append(location());
|
||||||
}
|
}
|
||||||
if (!location().endsWith("/")) {
|
if (!location().endsWith(separator)) {
|
||||||
result.append("/");
|
result.append(separator);
|
||||||
}
|
}
|
||||||
return result.append(group_path).append("/").append(artifactId).append("/").toString();
|
var group_path = groupId.replace(".", separator);
|
||||||
|
return result.append(group_path).append(separator).append(artifactId).append(separator).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -180,11 +205,11 @@ public record Repository(String location, String username, String password) {
|
||||||
public String toString() {
|
public String toString() {
|
||||||
var result = new StringBuilder(location);
|
var result = new StringBuilder(location);
|
||||||
if (username() != null) {
|
if (username() != null) {
|
||||||
result.append(":");
|
result.append(':');
|
||||||
try {
|
try {
|
||||||
result.append(StringEncryptor.MD5HLO.performEncryption(username(), null));
|
result.append(StringEncryptor.MD5HLO.performEncryption(username(), null));
|
||||||
if (password() != null) {
|
if (password() != null) {
|
||||||
result.append(":");
|
result.append(':');
|
||||||
result.append(StringEncryptor.MD5HLO.performEncryption(password(), null));
|
result.append(StringEncryptor.MD5HLO.performEncryption(password(), null));
|
||||||
}
|
}
|
||||||
} catch (NoSuchAlgorithmException e) {
|
} catch (NoSuchAlgorithmException e) {
|
||||||
|
|
|
||||||
79
src/main/java/rife/bld/dependencies/Version.java
Normal file
79
src/main/java/rife/bld/dependencies/Version.java
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||||
|
*/
|
||||||
|
package rife.bld.dependencies;
|
||||||
|
|
||||||
|
import static rife.bld.dependencies.VersionNumber.parseOrNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents the basic functionality of a dependency version.
|
||||||
|
*
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public interface Version extends Comparable<Version> {
|
||||||
|
/**
|
||||||
|
* Parses a version from a string representation.
|
||||||
|
* <p>
|
||||||
|
* If the string can't be successfully parsed as a semantic {@link VersionNumber},
|
||||||
|
* it will be parsed as a {@link VersionGeneric}.
|
||||||
|
*
|
||||||
|
* @param version the version string to parse
|
||||||
|
* @return the parsed version instance
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
static Version parse(String version) {
|
||||||
|
if (version == null || version.isEmpty()) {
|
||||||
|
return VersionNumber.UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = parseOrNull(version);
|
||||||
|
if (result != null) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// bld doesn't support version ranges at this time
|
||||||
|
if (version.startsWith("[") || version.startsWith("(")) {
|
||||||
|
return VersionNumber.UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new VersionGeneric(version);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the qualifier of the version.
|
||||||
|
*
|
||||||
|
* @return this version's qualifier
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
String qualifier();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the version number with a different qualifier.
|
||||||
|
*
|
||||||
|
* @return this version number with a different qualifier
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
Version withQualifier(String qualifier);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether this is a snapshot version.
|
||||||
|
*
|
||||||
|
* @return {@code true} if this is a snapshot version; or
|
||||||
|
* {@code false} otherwise
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
boolean isSnapshot();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
int compareTo(Version other);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
String toString();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
boolean equals(Object other);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
int hashCode();
|
||||||
|
}
|
||||||
373
src/main/java/rife/bld/dependencies/VersionGeneric.java
Normal file
373
src/main/java/rife/bld/dependencies/VersionGeneric.java
Normal file
|
|
@ -0,0 +1,373 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||||
|
*/
|
||||||
|
package rife.bld.dependencies;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import static java.util.Objects.requireNonNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic version implementation based on the Maven implementation.
|
||||||
|
*
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
// https://github.com/apache/maven-resolver/blob/98126539f3c66fc4ab50b178c2eb4b8fd169fd72/maven-resolver-util/src/main/java/org/eclipse/aether/util/version/GenericVersion.java
|
||||||
|
public class VersionGeneric implements Version {
|
||||||
|
private final String version_;
|
||||||
|
private final List<Item> items_;
|
||||||
|
private final int hash_;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String qualifier() {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Version withQualifier(String qualifier) {
|
||||||
|
return new VersionGeneric(version_);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSnapshot() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a generic version from the specified string.
|
||||||
|
*
|
||||||
|
* @param version The version string, must not be {@code null}.
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public VersionGeneric(String version) {
|
||||||
|
version_ = requireNonNull(version, "version cannot be null");
|
||||||
|
items_ = parse(version);
|
||||||
|
hash_ = items_.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Visible for testing.
|
||||||
|
*/
|
||||||
|
List<Item> asItems() {
|
||||||
|
return items_;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<Item> parse(String version) {
|
||||||
|
var items = new ArrayList<Item>();
|
||||||
|
|
||||||
|
for (var tokenizer = new Tokenizer(version); tokenizer.next(); ) {
|
||||||
|
var item = tokenizer.toItem();
|
||||||
|
items.add(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
trimPadding(items);
|
||||||
|
|
||||||
|
return Collections.unmodifiableList(items);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Visible for testing.
|
||||||
|
*/
|
||||||
|
static void trimPadding(List<Item> items) {
|
||||||
|
Boolean number = null;
|
||||||
|
var end = items.size() - 1;
|
||||||
|
for (var i = end; i > 0; i--) {
|
||||||
|
var item = items.get(i);
|
||||||
|
if (!Boolean.valueOf(item.isNumber()).equals(number)) {
|
||||||
|
end = i;
|
||||||
|
number = item.isNumber();
|
||||||
|
}
|
||||||
|
if (end == i
|
||||||
|
&& (i == items.size() - 1 || items.get(i - 1).isNumber() == item.isNumber())
|
||||||
|
&& item.compareTo(null) == 0) {
|
||||||
|
items.remove(i);
|
||||||
|
end--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(Version other) {
|
||||||
|
VersionGeneric generic;
|
||||||
|
if (other instanceof VersionGeneric) {
|
||||||
|
generic = (VersionGeneric)other;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
generic = new VersionGeneric(other.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
final var these = items_;
|
||||||
|
final var those = generic.items_;
|
||||||
|
|
||||||
|
var number = true;
|
||||||
|
|
||||||
|
for (var index = 0; ; index++) {
|
||||||
|
if (index >= these.size() && index >= those.size()) {
|
||||||
|
return 0;
|
||||||
|
} else if (index >= these.size()) {
|
||||||
|
return -comparePadding(those, index, null);
|
||||||
|
} else if (index >= those.size()) {
|
||||||
|
return comparePadding(these, index, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
var thisItem = these.get(index);
|
||||||
|
var thatItem = those.get(index);
|
||||||
|
|
||||||
|
if (thisItem.isNumber() != thatItem.isNumber()) {
|
||||||
|
if (index == 0) {
|
||||||
|
return thisItem.compareTo(thatItem);
|
||||||
|
}
|
||||||
|
if (number == thisItem.isNumber()) {
|
||||||
|
return comparePadding(these, index, number);
|
||||||
|
} else {
|
||||||
|
return -comparePadding(those, index, number);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var rel = thisItem.compareTo(thatItem);
|
||||||
|
if (rel != 0) {
|
||||||
|
return rel;
|
||||||
|
}
|
||||||
|
number = thisItem.isNumber();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int comparePadding(List<Item> items, int index, Boolean number) {
|
||||||
|
var rel = 0;
|
||||||
|
for (var i = index; i < items.size(); i++) {
|
||||||
|
var item = items.get(i);
|
||||||
|
if (number != null && number != item.isNumber()) {
|
||||||
|
// do not stop here, but continue, skipping non-number members
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
rel = item.compareTo(null);
|
||||||
|
if (rel != 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rel;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
return (obj instanceof VersionGeneric) && compareTo((VersionGeneric) obj) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return hash_;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return version_;
|
||||||
|
}
|
||||||
|
|
||||||
|
static final class Tokenizer {
|
||||||
|
private static final Integer QUALIFIER_ALPHA = -5;
|
||||||
|
private static final Integer QUALIFIER_BETA = -4;
|
||||||
|
private static final Integer QUALIFIER_MILESTONE = -3;
|
||||||
|
private static final Map<String, Integer> QUALIFIERS;
|
||||||
|
|
||||||
|
static {
|
||||||
|
QUALIFIERS = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
|
||||||
|
QUALIFIERS.put("alpha", QUALIFIER_ALPHA);
|
||||||
|
QUALIFIERS.put("beta", QUALIFIER_BETA);
|
||||||
|
QUALIFIERS.put("milestone", QUALIFIER_MILESTONE);
|
||||||
|
QUALIFIERS.put("cr", -2);
|
||||||
|
QUALIFIERS.put("rc", -2);
|
||||||
|
QUALIFIERS.put("snapshot", -1);
|
||||||
|
QUALIFIERS.put("ga", 0);
|
||||||
|
QUALIFIERS.put("final", 0);
|
||||||
|
QUALIFIERS.put("release", 0);
|
||||||
|
QUALIFIERS.put("", 0);
|
||||||
|
QUALIFIERS.put("sp", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final String version_;
|
||||||
|
private final int versionLength_;
|
||||||
|
private int index_;
|
||||||
|
private String token_;
|
||||||
|
private boolean number_;
|
||||||
|
private boolean terminatedByNumber_;
|
||||||
|
|
||||||
|
Tokenizer(String version) {
|
||||||
|
version_ = (!version.isEmpty()) ? version : "0";
|
||||||
|
versionLength_ = this.version_.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean next() {
|
||||||
|
if (index_ >= versionLength_) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var state = -2;
|
||||||
|
|
||||||
|
var start = index_;
|
||||||
|
var end = versionLength_;
|
||||||
|
terminatedByNumber_ = false;
|
||||||
|
|
||||||
|
for (; index_ < versionLength_; index_++) {
|
||||||
|
var c = version_.charAt(index_);
|
||||||
|
|
||||||
|
if (c == '.' || c == '-' || c == '_') {
|
||||||
|
end = index_;
|
||||||
|
index_++;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
var digit = Character.digit(c, 10);
|
||||||
|
if (digit >= 0) {
|
||||||
|
if (state == -1) {
|
||||||
|
end = index_;
|
||||||
|
terminatedByNumber_ = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (state == 0) {
|
||||||
|
// normalize numbers and strip leading zeros (prereq for Integer/BigInteger handling)
|
||||||
|
start++;
|
||||||
|
}
|
||||||
|
state = (state > 0 || digit > 0) ? 1 : 0;
|
||||||
|
} else {
|
||||||
|
if (state >= 0) {
|
||||||
|
end = index_;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
state = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (end - start > 0) {
|
||||||
|
token_ = version_.substring(start, end);
|
||||||
|
number_ = state >= 0;
|
||||||
|
} else {
|
||||||
|
token_ = "0";
|
||||||
|
number_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return String.valueOf(token_);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Item toItem() {
|
||||||
|
if (number_) {
|
||||||
|
try {
|
||||||
|
if (token_.length() < 10) {
|
||||||
|
return new Item(Item.KIND_INT, Integer.parseInt(token_));
|
||||||
|
} else {
|
||||||
|
return new Item(Item.KIND_BIGINT, new BigInteger(token_));
|
||||||
|
}
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
throw new IllegalStateException(e);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (index_ >= version_.length()) {
|
||||||
|
if ("min".equalsIgnoreCase(token_)) {
|
||||||
|
return Item.MIN;
|
||||||
|
} else if ("max".equalsIgnoreCase(token_)) {
|
||||||
|
return Item.MAX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (terminatedByNumber_ && token_.length() == 1) {
|
||||||
|
switch (token_.charAt(0)) {
|
||||||
|
case 'a':
|
||||||
|
case 'A':
|
||||||
|
return new Item(Item.KIND_QUALIFIER, QUALIFIER_ALPHA);
|
||||||
|
case 'b':
|
||||||
|
case 'B':
|
||||||
|
return new Item(Item.KIND_QUALIFIER, QUALIFIER_BETA);
|
||||||
|
case 'm':
|
||||||
|
case 'M':
|
||||||
|
return new Item(Item.KIND_QUALIFIER, QUALIFIER_MILESTONE);
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var qualifier = QUALIFIERS.get(token_);
|
||||||
|
if (qualifier != null) {
|
||||||
|
return new Item(Item.KIND_QUALIFIER, qualifier);
|
||||||
|
} else {
|
||||||
|
return new Item(Item.KIND_STRING, token_.toLowerCase(Locale.ENGLISH));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static final class Item {
|
||||||
|
static final int KIND_MAX = 8;
|
||||||
|
static final int KIND_BIGINT = 5;
|
||||||
|
static final int KIND_INT = 4;
|
||||||
|
static final int KIND_STRING = 3;
|
||||||
|
static final int KIND_QUALIFIER = 2;
|
||||||
|
static final int KIND_MIN = 0;
|
||||||
|
static final Item MAX = new Item(KIND_MAX, "max");
|
||||||
|
static final Item MIN = new Item(KIND_MIN, "min");
|
||||||
|
|
||||||
|
private final int kind_;
|
||||||
|
private final Object value_;
|
||||||
|
|
||||||
|
Item(int kind, Object value) {
|
||||||
|
kind_ = kind;
|
||||||
|
value_ = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isNumber() {
|
||||||
|
return (kind_ & KIND_QUALIFIER) == 0; // i.e. kind != string/qualifier
|
||||||
|
}
|
||||||
|
|
||||||
|
public int compareTo(Item that) {
|
||||||
|
int rel;
|
||||||
|
if (that == null) {
|
||||||
|
// null in this context denotes the pad item (0 or "ga")
|
||||||
|
rel = switch (kind_) {
|
||||||
|
case KIND_MIN -> -1;
|
||||||
|
case KIND_MAX, KIND_BIGINT, KIND_STRING -> 1;
|
||||||
|
case KIND_INT, KIND_QUALIFIER -> (Integer) value_;
|
||||||
|
default -> throw new IllegalStateException("unknown version item kind " + kind_);
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
rel = kind_ - that.kind_;
|
||||||
|
if (rel == 0) {
|
||||||
|
switch (kind_) {
|
||||||
|
case KIND_MAX:
|
||||||
|
case KIND_MIN:
|
||||||
|
break;
|
||||||
|
case KIND_BIGINT:
|
||||||
|
rel = ((BigInteger) value_).compareTo((BigInteger) that.value_);
|
||||||
|
break;
|
||||||
|
case KIND_INT:
|
||||||
|
case KIND_QUALIFIER:
|
||||||
|
rel = ((Integer) value_).compareTo((Integer) that.value_);
|
||||||
|
break;
|
||||||
|
case KIND_STRING:
|
||||||
|
rel = ((String) value_).compareToIgnoreCase((String) that.value_);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalStateException("unknown version item kind " + kind_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rel;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
return (obj instanceof Item) && compareTo((Item) obj) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return value_.hashCode() + kind_ * 31;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return String.valueOf(value_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -22,7 +22,7 @@ import java.util.regex.Pattern;
|
||||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
public record VersionNumber(Integer major, Integer minor, Integer revision, String qualifier, String separator) implements Comparable<VersionNumber> {
|
public record VersionNumber(Integer major, Integer minor, Integer revision, String qualifier, String separator) implements Version {
|
||||||
public static final String SNAPSHOT_QUALIFIER = "SNAPSHOT";
|
public static final String SNAPSHOT_QUALIFIER = "SNAPSHOT";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -32,12 +32,13 @@ public record VersionNumber(Integer major, Integer minor, Integer revision, Stri
|
||||||
*/
|
*/
|
||||||
public static final VersionNumber UNKNOWN = new VersionNumber(0, 0, 0, "");
|
public static final VersionNumber UNKNOWN = new VersionNumber(0, 0, 0, "");
|
||||||
|
|
||||||
private static final Pattern VERSION_PATTERN = Pattern.compile("^(?<major>\\d+)(?:\\.(?<minor>\\d+)(?:\\.(?<revision>\\d+))?)?(?:(?<separator>[.\\-])(?<qualifier>.*[^.\\-]))??$");
|
private static final Pattern VERSION_PATTERN = Pattern.compile("^(?<major>0|[1-9]\\d*)(?:\\.(?<minor>0|[1-9]\\d*)(?:\\.(?<revision>0|[1-9]\\d*))?)?(?:(?<separator>[.\\-])(?<qualifier>.*[^.\\-]))??$");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses a version number from a string representation.
|
* Parses a version number from a string representation.
|
||||||
* <p>
|
* <p>
|
||||||
* If the string can't be successfully parsed, {@link VersionNumber#UNKNOWN} will be returned.
|
* If the string can't be successfully parsed as a semantic version,
|
||||||
|
* {@link VersionNumber#UNKNOWN} will be returned.
|
||||||
*
|
*
|
||||||
* @param version the version string to parse
|
* @param version the version string to parse
|
||||||
* @return a parsed instance of {@code VersionNumber}; or
|
* @return a parsed instance of {@code VersionNumber}; or
|
||||||
|
|
@ -49,9 +50,22 @@ public record VersionNumber(Integer major, Integer minor, Integer revision, Stri
|
||||||
return UNKNOWN;
|
return UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var result = parseOrNull(version);
|
||||||
|
if (result == null) {
|
||||||
|
result = UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static VersionNumber parseOrNull(String version) {
|
||||||
|
if (version == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
var matcher = VERSION_PATTERN.matcher(version);
|
var matcher = VERSION_PATTERN.matcher(version);
|
||||||
if (!matcher.matches()) {
|
if (!matcher.matches()) {
|
||||||
return UNKNOWN;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var major = matcher.group("major");
|
var major = matcher.group("major");
|
||||||
|
|
@ -142,13 +156,8 @@ public record VersionNumber(Integer major, Integer minor, Integer revision, Stri
|
||||||
return new VersionNumber(major, minor, revision, null);
|
return new VersionNumber(major, minor, revision, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* Retrieves the version number with a different qualifier.
|
public Version withQualifier(String qualifier) {
|
||||||
*
|
|
||||||
* @return this version number with a different qualifier
|
|
||||||
* @since 1.5.8
|
|
||||||
*/
|
|
||||||
public VersionNumber withQualifier(String qualifier) {
|
|
||||||
return new VersionNumber(major, minor, revision, qualifier);
|
return new VersionNumber(major, minor, revision, qualifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -182,48 +191,46 @@ public record VersionNumber(Integer major, Integer minor, Integer revision, Stri
|
||||||
return revision == null ? 0 : revision;
|
return revision == null ? 0 : revision;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates whether this is a snapshot version.
|
|
||||||
*
|
|
||||||
* @return {@code true} if this is a snapshot version; or
|
|
||||||
* {@code false} otherwise
|
|
||||||
* @since 1.5.8
|
|
||||||
*/
|
|
||||||
public boolean isSnapshot() {
|
public boolean isSnapshot() {
|
||||||
return qualifier().toUpperCase().contains(SNAPSHOT_QUALIFIER);
|
return qualifier().toUpperCase().contains(SNAPSHOT_QUALIFIER);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int compareTo(VersionNumber other) {
|
@Override
|
||||||
if (majorInt() != other.majorInt()) {
|
public int compareTo(Version other) {
|
||||||
return majorInt() - other.majorInt();
|
if (other instanceof VersionNumber otherNumber) {
|
||||||
}
|
if (majorInt() != otherNumber.majorInt()) {
|
||||||
if (minorInt() != other.minorInt()) {
|
return majorInt() - otherNumber.majorInt();
|
||||||
return minorInt() - other.minorInt();
|
}
|
||||||
}
|
if (minorInt() != otherNumber.minorInt()) {
|
||||||
if (revisionInt() != other.revisionInt()) {
|
return minorInt() - otherNumber.minorInt();
|
||||||
return revisionInt() - other.revisionInt();
|
}
|
||||||
|
if (revisionInt() != otherNumber.revisionInt()) {
|
||||||
|
return revisionInt() - otherNumber.revisionInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (qualifier.equals(otherNumber.qualifier)) {
|
||||||
|
return 0;
|
||||||
|
} else if (qualifier.isEmpty()) {
|
||||||
|
return 1;
|
||||||
|
} else if (otherNumber.qualifier.isEmpty()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return qualifier.toLowerCase().compareTo(otherNumber.qualifier.toLowerCase());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qualifier.equals(other.qualifier)) {
|
return toString().compareTo(other.toString());
|
||||||
return 0;
|
|
||||||
} else if (qualifier.isEmpty()) {
|
|
||||||
return 1;
|
|
||||||
} else if (other.qualifier.isEmpty()) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return qualifier.toLowerCase().compareTo(other.qualifier.toLowerCase());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
var version = new StringBuilder();
|
var version = new StringBuilder();
|
||||||
version.append(majorInt());
|
version.append(majorInt());
|
||||||
if (minor != null || revision != null) {
|
if (minor != null || revision != null) {
|
||||||
version.append(".");
|
version.append('.');
|
||||||
version.append(minorInt());
|
version.append(minorInt());
|
||||||
}
|
}
|
||||||
if (revision != null) {
|
if (revision != null) {
|
||||||
version.append(".");
|
version.append('.');
|
||||||
version.append(revisionInt());
|
version.append(revisionInt());
|
||||||
}
|
}
|
||||||
if (qualifier != null && !qualifier.isEmpty()) {
|
if (qualifier != null && !qualifier.isEmpty()) {
|
||||||
|
|
@ -235,7 +242,7 @@ public record VersionNumber(Integer major, Integer minor, Integer revision, Stri
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object other) {
|
public boolean equals(Object other) {
|
||||||
return other instanceof VersionNumber && compareTo((VersionNumber) other) == 0;
|
return other instanceof Version && compareTo((Version) other) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
125
src/main/java/rife/bld/dependencies/VersionResolution.java
Normal file
125
src/main/java/rife/bld/dependencies/VersionResolution.java
Normal file
|
|
@ -0,0 +1,125 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2001-2024 Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||||
|
*/
|
||||||
|
package rife.bld.dependencies;
|
||||||
|
|
||||||
|
import rife.ioc.HierarchicalProperties;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is responsible for managing version overrides for dependencies.
|
||||||
|
* <p>
|
||||||
|
* It allows users to specify a property keys with the prefix "{@code bld.override}" where the values will be parsed as
|
||||||
|
* a comma-separated list of dependencies with the versions that should override any other versions that are encountered.
|
||||||
|
* <p>
|
||||||
|
* For instance:
|
||||||
|
* <pre>
|
||||||
|
* bld.override=com.uwyn.rife2:bld-tests-badge:1.4.7,com.h2database:h2:2.2.222
|
||||||
|
* </pre>
|
||||||
|
* <p>
|
||||||
|
* Multiple override properties can be used by simply adding differentiators behind the "{@code bld.override}" keys.
|
||||||
|
* <p>
|
||||||
|
* For instance:
|
||||||
|
* <pre>
|
||||||
|
* bld.override-tests=com.uwyn.rife2:bld-tests-badge:1.4.7
|
||||||
|
* bld.override-h2=com.h2database:h2:2.2.222
|
||||||
|
* </pre>
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public class VersionResolution {
|
||||||
|
/**
|
||||||
|
* The prefix for property keys used to override versions of dependencies.
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public static final String PROPERTY_OVERRIDE_PREFIX = "bld.override";
|
||||||
|
|
||||||
|
private final Map<String, Version> versionOverrides_ = new HashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a dummy {@code VersionResolution} instance that doesn't override anything.
|
||||||
|
*
|
||||||
|
* @return the dummy instance
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
static VersionResolution dummy() {
|
||||||
|
return new VersionResolution(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance of the {@code VersionResolution} class from hierarchical properties that
|
||||||
|
* are passed in.
|
||||||
|
* <p>
|
||||||
|
* The actual version overrides are determined at instantiation time and any future changes to the
|
||||||
|
* properties will not influence version resolution.
|
||||||
|
*
|
||||||
|
* @param properties the hierarchical properties that will be used to determine the version overrides
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public VersionResolution(HierarchicalProperties properties) {
|
||||||
|
if (properties != null) {
|
||||||
|
for (var name : properties.getNames()) {
|
||||||
|
if (name.startsWith(PROPERTY_OVERRIDE_PREFIX)) {
|
||||||
|
for (var override : properties.get(name).toString().split(",")) {
|
||||||
|
override = override.trim();
|
||||||
|
if (!override.isBlank()) {
|
||||||
|
var dependency = Dependency.parse(override);
|
||||||
|
if (dependency != null) {
|
||||||
|
versionOverrides_.put(dependency.toArtifactString(), dependency.version());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overrides the version of a given dependency with the corresponding overridden version.
|
||||||
|
*
|
||||||
|
* @param original the dependency for which the version needs to be overridden
|
||||||
|
* @return the overridden version if it is available; or the original version otherwise
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public Version overrideVersion(Dependency original) {
|
||||||
|
var overridden = versionOverrides_.get(original.toArtifactString());
|
||||||
|
if (overridden == null) {
|
||||||
|
return original.version();
|
||||||
|
}
|
||||||
|
return overridden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overrides the version of a given dependency with the corresponding overridden version and
|
||||||
|
* creates a new dependency object with the overridden version, if needed.
|
||||||
|
*
|
||||||
|
* @param original the dependency for which the version needs to be overridden
|
||||||
|
* @return the dependency with the overridden version if it's available; or the original dependency otherwise
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public Dependency overrideDependency(Dependency original) {
|
||||||
|
var overridden = versionOverrides_.get(original.toArtifactString());
|
||||||
|
if (overridden == null) {
|
||||||
|
return original;
|
||||||
|
}
|
||||||
|
return new Dependency(original.groupId(),
|
||||||
|
original.artifactId(),
|
||||||
|
overridden,
|
||||||
|
original.classifier(),
|
||||||
|
original.type(),
|
||||||
|
original.exclusions(),
|
||||||
|
original.parent());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the map of version overrides, where the key is the name of the dependency and the value is the overridden version.
|
||||||
|
*
|
||||||
|
* @return the map of version overrides
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public Map<String, Version> versionOverrides() {
|
||||||
|
return versionOverrides_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -18,13 +18,14 @@ import java.util.regex.Pattern;
|
||||||
* @since 1.5.8
|
* @since 1.5.8
|
||||||
*/
|
*/
|
||||||
public class Xml2MavenMetadata extends Xml2Data implements MavenMetadata {
|
public class Xml2MavenMetadata extends Xml2Data implements MavenMetadata {
|
||||||
private VersionNumber latest_ = VersionNumber.UNKNOWN;
|
private Version latest_ = VersionNumber.UNKNOWN;
|
||||||
private VersionNumber release_ = VersionNumber.UNKNOWN;
|
private Version release_ = VersionNumber.UNKNOWN;
|
||||||
private final List<VersionNumber> versions_;
|
private final List<Version> versions_;
|
||||||
private VersionNumber snapshot_ = VersionNumber.UNKNOWN;
|
private Version snapshot_ = VersionNumber.UNKNOWN;
|
||||||
|
|
||||||
private StringBuilder characterData_ = null;
|
private StringBuilder characterData_ = null;
|
||||||
|
|
||||||
|
private boolean isSnapshot_ = false;
|
||||||
private String snapshotTimestamp_ = null;
|
private String snapshotTimestamp_ = null;
|
||||||
private Integer snapshotBuildNumber_ = null;
|
private Integer snapshotBuildNumber_ = null;
|
||||||
|
|
||||||
|
|
@ -32,15 +33,15 @@ public class Xml2MavenMetadata extends Xml2Data implements MavenMetadata {
|
||||||
versions_ = new ArrayList<>();
|
versions_ = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public VersionNumber getLatest() {
|
public Version getLatest() {
|
||||||
return latest_;
|
return latest_;
|
||||||
}
|
}
|
||||||
|
|
||||||
public VersionNumber getRelease() {
|
public Version getRelease() {
|
||||||
return release_;
|
return release_;
|
||||||
}
|
}
|
||||||
|
|
||||||
public VersionNumber getSnapshot() {
|
public Version getSnapshot() {
|
||||||
return snapshot_;
|
return snapshot_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -52,7 +53,7 @@ public class Xml2MavenMetadata extends Xml2Data implements MavenMetadata {
|
||||||
return snapshotBuildNumber_;
|
return snapshotBuildNumber_;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<VersionNumber> getVersions() {
|
public List<Version> getVersions() {
|
||||||
return versions_;
|
return versions_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -62,21 +63,12 @@ public class Xml2MavenMetadata extends Xml2Data implements MavenMetadata {
|
||||||
|
|
||||||
public void endElement(String uri, String localName, String qName) {
|
public void endElement(String uri, String localName, String qName) {
|
||||||
switch (qName) {
|
switch (qName) {
|
||||||
case "latest" -> latest_ = VersionNumber.parse(characterData_.toString());
|
case "latest" -> latest_ = Version.parse(characterData_.toString());
|
||||||
case "release" -> release_ = VersionNumber.parse(characterData_.toString());
|
case "release" -> release_ = Version.parse(characterData_.toString());
|
||||||
case "version" -> versions_.add(VersionNumber.parse(characterData_.toString()));
|
case "version" -> versions_.add(Version.parse(characterData_.toString()));
|
||||||
case "timestamp" -> snapshotTimestamp_ = characterData_.toString();
|
case "timestamp" -> snapshotTimestamp_ = characterData_.toString();
|
||||||
case "buildNumber" -> snapshotBuildNumber_ = Integer.parseInt(characterData_.toString());
|
case "buildNumber" -> snapshotBuildNumber_ = Integer.parseInt(characterData_.toString());
|
||||||
case "snapshot" -> {
|
case "snapshot" -> isSnapshot_ = true;
|
||||||
if (!versions_.isEmpty()) {
|
|
||||||
var version = versions_.get(0);
|
|
||||||
var qualifier = VersionNumber.SNAPSHOT_QUALIFIER;
|
|
||||||
if (snapshotTimestamp_ != null && snapshotBuildNumber_ != null) {
|
|
||||||
qualifier = snapshotTimestamp_ + "-" + snapshotBuildNumber_;
|
|
||||||
}
|
|
||||||
snapshot_ = new VersionNumber(version.major(), version.minor(), version.revision(), qualifier);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
characterData_ = null;
|
characterData_ = null;
|
||||||
|
|
@ -88,21 +80,31 @@ public class Xml2MavenMetadata extends Xml2Data implements MavenMetadata {
|
||||||
|
|
||||||
public void endDocument()
|
public void endDocument()
|
||||||
throws SAXException {
|
throws SAXException {
|
||||||
|
if (isSnapshot_) {
|
||||||
|
if (!versions_.isEmpty()) {
|
||||||
|
var version = versions_.get(0);
|
||||||
|
var qualifier = VersionNumber.SNAPSHOT_QUALIFIER;
|
||||||
|
if (snapshotTimestamp_ != null && snapshotBuildNumber_ != null) {
|
||||||
|
qualifier = snapshotTimestamp_ + "-" + snapshotBuildNumber_;
|
||||||
|
}
|
||||||
|
snapshot_ = version.withQualifier(qualifier);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// determine latest stable version by removing pre-release qualifiers
|
// determine latest stable version by removing pre-release qualifiers
|
||||||
var filtered_versions = new TreeSet<VersionNumber>();
|
var filtered_versions = new TreeSet<>(versions_.stream()
|
||||||
filtered_versions.addAll(versions_.stream()
|
.filter(v -> {
|
||||||
.filter(v -> {
|
if (v.qualifier() == null) return true;
|
||||||
if (v.qualifier() == null) return true;
|
var q = v.qualifier().toLowerCase();
|
||||||
var q = v.qualifier().toLowerCase();
|
return !q.startsWith("rc") &&
|
||||||
return !q.startsWith("rc") &&
|
!q.startsWith("cr") &&
|
||||||
!q.startsWith("cr") &&
|
!q.contains("milestone") &&
|
||||||
!q.contains("milestone") &&
|
!MILESTONE.matcher(q).matches() &&
|
||||||
!MILESTONE.matcher(q).matches() &&
|
!q.contains("beta") &&
|
||||||
!q.contains("beta") &&
|
!BETA.matcher(q).matches() &&
|
||||||
!BETA.matcher(q).matches() &&
|
!q.contains("alpha") &&
|
||||||
!q.contains("alpha") &&
|
!ALPHA.matcher(q).matches();
|
||||||
!ALPHA.matcher(q).matches();
|
}).toList());
|
||||||
}).toList());
|
|
||||||
|
|
||||||
// only replace the stable version from the metadata when
|
// only replace the stable version from the metadata when
|
||||||
// something remained from the filtering, then use the
|
// something remained from the filtering, then use the
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,8 @@ import rife.xml.Xml2Data;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import static rife.bld.dependencies.Dependency.TYPE_JAR;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses an XML document to retrieve POM information, this is an internal class.
|
* Parses an XML document to retrieve POM information, this is an internal class.
|
||||||
*
|
*
|
||||||
|
|
@ -18,16 +20,18 @@ import java.util.regex.Pattern;
|
||||||
*/
|
*/
|
||||||
class Xml2MavenPom extends Xml2Data {
|
class Xml2MavenPom extends Xml2Data {
|
||||||
private final Dependency parent_;
|
private final Dependency parent_;
|
||||||
|
private final VersionResolution resolution_;
|
||||||
private final ArtifactRetriever retriever_;
|
private final ArtifactRetriever retriever_;
|
||||||
private final List<Repository> repositories_;
|
private final List<Repository> repositories_;
|
||||||
private Map<Scope, Set<PomDependency>> resolvedDependencies_ = null;
|
private Map<Scope, Set<PomDependency>> resolvedDependencies_ = null;
|
||||||
|
|
||||||
private final Map<PomDependency, PomDependency> dependencyManagement_ = new LinkedHashMap<>();
|
private final Map<PomDependency, PomDependency> dependencyManagement_ = new LinkedHashMap<>();
|
||||||
private final Set<PomDependency> dependencies_ = new LinkedHashSet<>();
|
private final Set<PomDependency> dependencies_ = new LinkedHashSet<>();
|
||||||
private final Map<String, String> properties_ = new HashMap<>();
|
private final Map<String, String> mavenProperties_ = new HashMap<>();
|
||||||
private final Stack<String> elementStack_ = new Stack<>();
|
private final Stack<String> elementStack_ = new Stack<>();
|
||||||
private ExclusionSet exclusions_ = null;
|
private ExclusionSet exclusions_ = null;
|
||||||
|
|
||||||
|
private boolean initialParse_ = true;
|
||||||
private boolean collectProperties_ = false;
|
private boolean collectProperties_ = false;
|
||||||
private boolean collectDependencyManagement_ = false;
|
private boolean collectDependencyManagement_ = false;
|
||||||
private boolean collectDependencies_ = false;
|
private boolean collectDependencies_ = false;
|
||||||
|
|
@ -45,8 +49,9 @@ class Xml2MavenPom extends Xml2Data {
|
||||||
private String lastExclusionGroupId_ = null;
|
private String lastExclusionGroupId_ = null;
|
||||||
private String lastExclusionArtifactId_ = null;
|
private String lastExclusionArtifactId_ = null;
|
||||||
|
|
||||||
Xml2MavenPom(Dependency parent, ArtifactRetriever retriever, List<Repository> repositories) {
|
Xml2MavenPom(Dependency parent, VersionResolution resolution, ArtifactRetriever retriever, List<Repository> repositories) {
|
||||||
parent_ = parent;
|
parent_ = parent;
|
||||||
|
resolution_ = resolution;
|
||||||
retriever_ = retriever;
|
retriever_ = retriever;
|
||||||
repositories_ = repositories;
|
repositories_ = repositories;
|
||||||
}
|
}
|
||||||
|
|
@ -85,22 +90,22 @@ class Xml2MavenPom extends Xml2Data {
|
||||||
if (dep_scope == null) {
|
if (dep_scope == null) {
|
||||||
dep_scope = "compile";
|
dep_scope = "compile";
|
||||||
}
|
}
|
||||||
optional = resolveProperties(optional);
|
optional = resolveMavenProperties(optional);
|
||||||
if ("true".equals(optional)) {
|
if ("true".equals(optional)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var resolved_dependency = new PomDependency(
|
var resolved_dependency = new PomDependency(
|
||||||
resolveProperties(dependency.groupId()),
|
resolveMavenProperties(dependency.groupId()),
|
||||||
resolveProperties(dependency.artifactId()),
|
resolveMavenProperties(dependency.artifactId()),
|
||||||
resolveProperties(version),
|
resolveMavenProperties(version),
|
||||||
resolveProperties(dependency.classifier()),
|
resolveMavenProperties(dependency.classifier()),
|
||||||
resolveProperties(dependency.type()),
|
resolveMavenProperties(dependency.type()),
|
||||||
dep_scope,
|
dep_scope,
|
||||||
"false",
|
"false",
|
||||||
exclusions,
|
exclusions,
|
||||||
dependency.parent());
|
dependency.parent());
|
||||||
if (resolved_dependency.type() == null || resolved_dependency.type().equals("jar")) {
|
if (resolved_dependency.type() == null || TYPE_JAR.equals(resolved_dependency.type())) {
|
||||||
var scope = Scope.valueOf(resolved_dependency.scope());
|
var scope = Scope.valueOf(resolved_dependency.scope());
|
||||||
if (scopes_list.contains(scope)) {
|
if (scopes_list.contains(scope)) {
|
||||||
var resolved_dependency_set = resolved_dependencies.computeIfAbsent(scope, k -> new LinkedHashSet<>());
|
var resolved_dependency_set = resolved_dependencies.computeIfAbsent(scope, k -> new LinkedHashSet<>());
|
||||||
|
|
@ -126,13 +131,13 @@ class Xml2MavenPom extends Xml2Data {
|
||||||
|
|
||||||
PomDependency resolveDependency(PomDependency dependency) {
|
PomDependency resolveDependency(PomDependency dependency) {
|
||||||
return new PomDependency(
|
return new PomDependency(
|
||||||
resolveProperties(dependency.groupId()),
|
resolveMavenProperties(dependency.groupId()),
|
||||||
resolveProperties(dependency.artifactId()),
|
resolveMavenProperties(dependency.artifactId()),
|
||||||
resolveProperties(dependency.version()),
|
resolveMavenProperties(dependency.version()),
|
||||||
resolveProperties(dependency.classifier()),
|
resolveMavenProperties(dependency.classifier()),
|
||||||
resolveProperties(dependency.type()),
|
resolveMavenProperties(dependency.type()),
|
||||||
dependency.scope(),
|
dependency.scope(),
|
||||||
resolveProperties(dependency.optional()),
|
resolveMavenProperties(dependency.optional()),
|
||||||
dependency.exclusions(),
|
dependency.exclusions(),
|
||||||
dependency.parent());
|
dependency.parent());
|
||||||
}
|
}
|
||||||
|
|
@ -140,32 +145,36 @@ class Xml2MavenPom extends Xml2Data {
|
||||||
public void startElement(String uri, String localName, String qName, Attributes attributes) {
|
public void startElement(String uri, String localName, String qName, Attributes attributes) {
|
||||||
characterData_ = new StringBuilder();
|
characterData_ = new StringBuilder();
|
||||||
|
|
||||||
switch (qName) {
|
if (initialParse_) {
|
||||||
case "parent" -> resetState();
|
if (qName.equals("properties")) {
|
||||||
case "properties" -> {
|
|
||||||
if (isChildOfProject()) {
|
if (isChildOfProject()) {
|
||||||
collectProperties_ = true;
|
collectProperties_ = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case "dependencyManagement" -> {
|
}
|
||||||
if (isChildOfProject()) {
|
else {
|
||||||
collectDependencyManagement_ = true;
|
switch (qName) {
|
||||||
|
case "parent" -> resetState();
|
||||||
|
case "dependencyManagement" -> {
|
||||||
|
if (isChildOfProject()) {
|
||||||
|
collectDependencyManagement_ = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
case "dependencies" -> {
|
||||||
case "dependencies" -> {
|
if (isChildOfProject()) {
|
||||||
if (isChildOfProject()) {
|
resetState();
|
||||||
resetState();
|
collectDependencies_ = true;
|
||||||
collectDependencies_ = true;
|
}
|
||||||
}
|
}
|
||||||
}
|
case "exclusions" -> {
|
||||||
case "exclusions" -> {
|
if (collectDependencyManagement_ || collectDependencies_) {
|
||||||
if (collectDependencyManagement_ || collectDependencies_) {
|
collectExclusions_ = true;
|
||||||
collectExclusions_ = true;
|
exclusions_ = new ExclusionSet();
|
||||||
exclusions_ = new ExclusionSet();
|
}
|
||||||
|
}
|
||||||
|
case "dependency" -> {
|
||||||
|
if (collectDependencies_) resetState();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
case "dependency" -> {
|
|
||||||
if (collectDependencies_) resetState();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -175,110 +184,126 @@ class Xml2MavenPom extends Xml2Data {
|
||||||
public void endElement(String uri, String localName, String qName) {
|
public void endElement(String uri, String localName, String qName) {
|
||||||
elementStack_.pop();
|
elementStack_.pop();
|
||||||
|
|
||||||
switch (qName) {
|
if (initialParse_) {
|
||||||
case "parent" -> {
|
switch (qName) {
|
||||||
if (isChildOfProject()) {
|
case "properties" -> collectProperties_ = false;
|
||||||
var parent_dependency = new Dependency(resolveProperties(lastGroupId_), resolveProperties(lastArtifactId_), VersionNumber.parse(resolveProperties(lastVersion_)));
|
case "project" -> initialParse_ = false;
|
||||||
var parent = new DependencyResolver(retriever_, repositories_, parent_dependency).getMavenPom(parent_);
|
default -> {
|
||||||
|
if (collectProperties_) {
|
||||||
|
mavenProperties_.put(qName, getCharacterData());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
switch (qName) {
|
||||||
|
case "parent" -> {
|
||||||
|
if (isChildOfProject()) {
|
||||||
|
var parent_dependency = new Dependency(resolveMavenProperties(lastGroupId_), resolveMavenProperties(lastArtifactId_), Version.parse(resolveMavenProperties(lastVersion_)));
|
||||||
|
var parent = new DependencyResolver(resolution_, retriever_, repositories_, parent_dependency).getMavenPom(parent_);
|
||||||
|
|
||||||
parent.properties_.keySet().removeAll(properties_.keySet());
|
parent.mavenProperties_.keySet().removeAll(mavenProperties_.keySet());
|
||||||
properties_.putAll(parent.properties_);
|
mavenProperties_.putAll(parent.mavenProperties_);
|
||||||
|
|
||||||
parent.dependencyManagement_.keySet().removeAll(dependencyManagement_.keySet());
|
parent.dependencyManagement_.keySet().removeAll(dependencyManagement_.keySet());
|
||||||
dependencyManagement_.putAll(parent.dependencyManagement_);
|
dependencyManagement_.putAll(parent.dependencyManagement_);
|
||||||
|
|
||||||
parent.dependencies_.removeAll(dependencies_);
|
parent.dependencies_.removeAll(dependencies_);
|
||||||
dependencies_.addAll(parent.dependencies_);
|
dependencies_.addAll(parent.dependencies_);
|
||||||
|
|
||||||
|
resetState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case "dependencyManagement" -> collectDependencyManagement_ = false;
|
||||||
|
case "dependencies" -> collectDependencies_ = false;
|
||||||
|
case "exclusions" -> collectExclusions_ = false;
|
||||||
|
case "exclusion" -> {
|
||||||
|
if (collectExclusions_) {
|
||||||
|
exclusions_.add(new DependencyExclusion(lastExclusionGroupId_, lastExclusionArtifactId_));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case "dependency" -> {
|
||||||
|
var dependency = new PomDependency(lastGroupId_, lastArtifactId_, lastVersion_, lastClassifier_, lastType_, lastScope_, lastOptional_, exclusions_, parent_);
|
||||||
|
if (collectDependencyManagement_) {
|
||||||
|
if (dependency.isPomImport()) {
|
||||||
|
var import_dependency = new Dependency(resolveMavenProperties(lastGroupId_), resolveMavenProperties(lastArtifactId_), Version.parse(resolveMavenProperties(lastVersion_)));
|
||||||
|
var imported_pom = new DependencyResolver(resolution_, retriever_, repositories_, import_dependency).getMavenPom(parent_);
|
||||||
|
imported_pom.dependencyManagement_.keySet().removeAll(dependencyManagement_.keySet());
|
||||||
|
var resolved_dependencies = new LinkedHashSet<PomDependency>();
|
||||||
|
for (var managed_dependency : imported_pom.dependencyManagement_.keySet()) {
|
||||||
|
resolved_dependencies.add(imported_pom.resolveDependency(managed_dependency));
|
||||||
|
}
|
||||||
|
|
||||||
|
resolved_dependencies.removeAll(dependencyManagement_.keySet());
|
||||||
|
for (var resolved_dependency : resolved_dependencies) {
|
||||||
|
dependencyManagement_.put(resolved_dependency, resolved_dependency);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dependencyManagement_.put(dependency, dependency);
|
||||||
|
}
|
||||||
|
} else if (collectDependencies_) {
|
||||||
|
dependencies_.add(dependency);
|
||||||
|
}
|
||||||
resetState();
|
resetState();
|
||||||
}
|
}
|
||||||
}
|
case "groupId" -> {
|
||||||
case "properties" -> collectProperties_ = false;
|
if (isChildOfProject()) {
|
||||||
case "dependencyManagement" -> collectDependencyManagement_ = false;
|
addProjectProperty(qName);
|
||||||
case "dependencies" -> collectDependencies_ = false;
|
} else if (isChildOfParent() || isChildOfDependency()) {
|
||||||
case "exclusions" -> collectExclusions_ = false;
|
if (isChildOfProjectParent()) {
|
||||||
case "exclusion" -> {
|
addProjectParentProperty(qName);
|
||||||
if (collectExclusions_) {
|
|
||||||
exclusions_.add(new DependencyExclusion(lastExclusionGroupId_, lastExclusionArtifactId_));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case "dependency" -> {
|
|
||||||
var dependency = new PomDependency(lastGroupId_, lastArtifactId_, lastVersion_, lastClassifier_, lastType_, lastScope_, lastOptional_, exclusions_, parent_);
|
|
||||||
if (collectDependencyManagement_) {
|
|
||||||
if (dependency.isPomImport()) {
|
|
||||||
var import_dependency = new Dependency(resolveProperties(lastGroupId_), resolveProperties(lastArtifactId_), VersionNumber.parse(resolveProperties(lastVersion_)));
|
|
||||||
var imported_pom = new DependencyResolver(retriever_, repositories_, import_dependency).getMavenPom(parent_);
|
|
||||||
imported_pom.dependencyManagement_.keySet().removeAll(dependencyManagement_.keySet());
|
|
||||||
var resolved_dependencies = new LinkedHashSet<PomDependency>();
|
|
||||||
for (var managed_dependency : imported_pom.dependencyManagement_.keySet()) {
|
|
||||||
resolved_dependencies.add(imported_pom.resolveDependency(managed_dependency));
|
|
||||||
}
|
}
|
||||||
|
lastGroupId_ = getCharacterData();
|
||||||
resolved_dependencies.removeAll(dependencyManagement_.keySet());
|
} else if (collectExclusions_ && isChildOfExclusion()) {
|
||||||
for (var resolved_dependency : resolved_dependencies) {
|
lastExclusionGroupId_ = getCharacterData();
|
||||||
dependencyManagement_.put(resolved_dependency, resolved_dependency);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dependencyManagement_.put(dependency, dependency);
|
|
||||||
}
|
}
|
||||||
} else if (collectDependencies_) {
|
|
||||||
dependencies_.add(dependency);
|
|
||||||
}
|
}
|
||||||
resetState();
|
case "artifactId" -> {
|
||||||
}
|
if (isChildOfProject()) {
|
||||||
case "groupId" -> {
|
addProjectProperty(qName);
|
||||||
if (isChildOfProject()) {
|
} else if (isChildOfParent() || isChildOfDependency()) {
|
||||||
addProjectProperty(qName);
|
if (isChildOfProjectParent()) {
|
||||||
} else if (isChildOfParent() || isChildOfDependency()) {
|
addProjectParentProperty(qName);
|
||||||
lastGroupId_ = getCharacterData();
|
}
|
||||||
} else if (collectExclusions_ && isChildOfExclusion()) {
|
lastArtifactId_ = getCharacterData();
|
||||||
lastExclusionGroupId_ = getCharacterData();
|
} else if (collectExclusions_ && isChildOfExclusion()) {
|
||||||
|
lastExclusionArtifactId_ = getCharacterData();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
case "version" -> {
|
||||||
case "artifactId" -> {
|
if (isChildOfProject()) {
|
||||||
if (isChildOfProject()) {
|
addProjectProperty(qName);
|
||||||
addProjectProperty(qName);
|
} else if (isChildOfParent() || isChildOfDependency()) {
|
||||||
} else if (isChildOfParent() || isChildOfDependency()) {
|
lastVersion_ = getCharacterData();
|
||||||
lastArtifactId_ = getCharacterData();
|
if (isChildOfProjectParent()) {
|
||||||
} else if (collectExclusions_ && isChildOfExclusion()) {
|
addProjectParentProperty(qName);
|
||||||
lastExclusionArtifactId_ = getCharacterData();
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
case "type" -> {
|
||||||
case "version" -> {
|
if (isChildOfDependency()) {
|
||||||
if (isChildOfProject()) {
|
lastType_ = getCharacterData();
|
||||||
addProjectProperty(qName);
|
}
|
||||||
} else if (isChildOfParent() || isChildOfDependency()) {
|
|
||||||
lastVersion_ = getCharacterData();
|
|
||||||
}
|
}
|
||||||
}
|
case "classifier" -> {
|
||||||
case "type" -> {
|
if (isChildOfDependency()) {
|
||||||
if (isChildOfDependency()) {
|
lastClassifier_ = getCharacterData();
|
||||||
lastType_ = getCharacterData();
|
}
|
||||||
}
|
}
|
||||||
}
|
case "scope" -> {
|
||||||
case "classifier" -> {
|
if (isChildOfDependency()) {
|
||||||
if (isChildOfDependency()) {
|
lastScope_ = getCharacterData();
|
||||||
lastClassifier_ = getCharacterData();
|
}
|
||||||
}
|
}
|
||||||
}
|
case "optional" -> {
|
||||||
case "scope" -> {
|
if (isChildOfDependency()) {
|
||||||
if (isChildOfDependency()) {
|
lastOptional_ = getCharacterData();
|
||||||
lastScope_ = getCharacterData();
|
}
|
||||||
}
|
}
|
||||||
}
|
case "packaging", "name", "description", "url", "inceptionYear" -> {
|
||||||
case "optional" -> {
|
if (isChildOfProject()) {
|
||||||
if (isChildOfDependency()) {
|
addProjectProperty(qName);
|
||||||
lastOptional_ = getCharacterData();
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
case "packaging", "name", "description", "url", "inceptionYear" -> {
|
|
||||||
if (isChildOfProject()) {
|
|
||||||
addProjectProperty(qName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default -> {
|
|
||||||
if (collectProperties_) {
|
|
||||||
properties_.put(qName, getCharacterData());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -287,23 +312,34 @@ class Xml2MavenPom extends Xml2Data {
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isChildOfProject() {
|
private boolean isChildOfProject() {
|
||||||
return elementStack_.peek().equals("project");
|
return "project".equals(elementStack_.peek());
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isChildOfProjectParent() {
|
||||||
|
if (elementStack_.size() < 2) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return "parent".equals(elementStack_.peek()) && "project".equals(elementStack_.elementAt(elementStack_.size() - 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isChildOfParent() {
|
private boolean isChildOfParent() {
|
||||||
return elementStack_.peek().equals("parent");
|
return "parent".equals(elementStack_.peek());
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isChildOfDependency() {
|
private boolean isChildOfDependency() {
|
||||||
return elementStack_.peek().equals("dependency");
|
return "dependency".equals(elementStack_.peek());
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isChildOfExclusion() {
|
private boolean isChildOfExclusion() {
|
||||||
return elementStack_.peek().equals("exclusion");
|
return "exclusion".equals(elementStack_.peek());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addProjectProperty(String name) {
|
private void addProjectProperty(String name) {
|
||||||
properties_.put("project." + name, getCharacterData());
|
mavenProperties_.put("project." + name, getCharacterData());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addProjectParentProperty(String name) {
|
||||||
|
mavenProperties_.put("project.parent." + name, getCharacterData());
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getCharacterData() {
|
private String getCharacterData() {
|
||||||
|
|
@ -320,7 +356,7 @@ class Xml2MavenPom extends Xml2Data {
|
||||||
|
|
||||||
private static final Pattern MAVEN_PROPERTY = Pattern.compile("\\$\\{([^<>{}]+)}");
|
private static final Pattern MAVEN_PROPERTY = Pattern.compile("\\$\\{([^<>{}]+)}");
|
||||||
|
|
||||||
private String resolveProperties(String data) {
|
private String resolveMavenProperties(String data) {
|
||||||
if (data == null) {
|
if (data == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
@ -335,9 +371,9 @@ class Xml2MavenPom extends Xml2Data {
|
||||||
while (matcher.find()) {
|
while (matcher.find()) {
|
||||||
if (matcher.groupCount() == 1) {
|
if (matcher.groupCount() == 1) {
|
||||||
var property = matcher.group(1);
|
var property = matcher.group(1);
|
||||||
if (properties_.containsKey(property)) {
|
if (mavenProperties_.containsKey(property)) {
|
||||||
processed_data.append(data, last_end, matcher.start());
|
processed_data.append(data, last_end, matcher.start());
|
||||||
processed_data.append(properties_.get(property));
|
processed_data.append(mavenProperties_.get(property));
|
||||||
last_end = matcher.end();
|
last_end = matcher.end();
|
||||||
|
|
||||||
replaced = true;
|
replaced = true;
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,22 @@ public class DependencyTransferException extends DependencyException {
|
||||||
destination_ = destination;
|
destination_ = destination;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DependencyTransferException(Dependency dependency, File destination, String message) {
|
||||||
|
super("Unable to transfer dependency '" + dependency + "' into '" + destination + "': " + message);
|
||||||
|
|
||||||
|
dependency_ = dependency;
|
||||||
|
location_ = null;
|
||||||
|
destination_ = destination;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DependencyTransferException(Dependency dependency, String message) {
|
||||||
|
super("Unable to transfer dependency '" + dependency + "': " + message);
|
||||||
|
|
||||||
|
dependency_ = dependency;
|
||||||
|
location_ = null;
|
||||||
|
destination_ = null;
|
||||||
|
}
|
||||||
|
|
||||||
public Dependency getDependency() {
|
public Dependency getDependency() {
|
||||||
return dependency_;
|
return dependency_;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,22 +8,23 @@ import rife.bld.CommandHelp;
|
||||||
import rife.tools.StringUtils;
|
import rife.tools.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides help for the create-blank command.
|
* Provides help for the create-app command.
|
||||||
*
|
*
|
||||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||||
* @since 1.5
|
* @since 1.9
|
||||||
*/
|
*/
|
||||||
public class CreateBlankHelp implements CommandHelp {
|
public class CreateAppHelp implements CommandHelp {
|
||||||
public String getSummary() {
|
public String getSummary() {
|
||||||
return "Creates a new blank Java project with standard commands";
|
return "Creates a new Java application project";
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDescription(String topic) {
|
public String getDescription(String topic) {
|
||||||
return StringUtils.replace("""
|
return StringUtils.replace("""
|
||||||
Creates a new blank Java project with standard commands.
|
Creates a new Java application project.
|
||||||
|
|
||||||
Usage : ${topic} <package> <name>
|
Usage : ${topic} <package> <name> <base>
|
||||||
package The package of the project to create
|
package The package of the project to create
|
||||||
name The name of the project to create""", "${topic}", topic);
|
name The name of the project to create
|
||||||
|
base The base name for generated project classes""", "${topic}", topic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -8,22 +8,23 @@ import rife.bld.CommandHelp;
|
||||||
import rife.tools.StringUtils;
|
import rife.tools.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides help for the create-blank command.
|
* Provides help for the create-base command.
|
||||||
*
|
*
|
||||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||||
* @since 1.5.20
|
* @since 1.5.20
|
||||||
*/
|
*/
|
||||||
public class CreateBaseHelp implements CommandHelp {
|
public class CreateBaseHelp implements CommandHelp {
|
||||||
public String getSummary() {
|
public String getSummary() {
|
||||||
return "Creates a new baseline Java project with minimal commands";
|
return "Creates a new Java baseline project";
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDescription(String topic) {
|
public String getDescription(String topic) {
|
||||||
return StringUtils.replace("""
|
return StringUtils.replace("""
|
||||||
Creates a new baseline Java project with minimal commands.
|
Creates a new Java baseline project.
|
||||||
|
|
||||||
Usage : ${topic} <package> <name>
|
Usage : ${topic} <package> <name> <base>
|
||||||
package The package of the project to create
|
package The package of the project to create
|
||||||
name The name of the project to create""", "${topic}", topic);
|
name The name of the project to create
|
||||||
|
base The base name for generated project classes""", "${topic}", topic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,16 +15,17 @@ import rife.tools.StringUtils;
|
||||||
*/
|
*/
|
||||||
public class CreateHelp implements CommandHelp {
|
public class CreateHelp implements CommandHelp {
|
||||||
public String getSummary() {
|
public String getSummary() {
|
||||||
return "Creates a new project";
|
return "Creates a new project from multiple choice";
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDescription(String topic) {
|
public String getDescription(String topic) {
|
||||||
return StringUtils.replace("""
|
return StringUtils.replace("""
|
||||||
Creates a new project.
|
Creates a new project from multiple choice.
|
||||||
|
|
||||||
Usage : ${topic} <type> <package> <name>
|
Usage : ${topic} <type> <package> <name> <base>
|
||||||
type The type of project to create (base, blank, lib, rife2)
|
type The type of project to create (app, base, lib, rife2)
|
||||||
package The package of the project to create
|
package The package of the project to create
|
||||||
name The name of the project to create""", "${topic}", topic);
|
name The name of the project to create
|
||||||
|
base The base name for generated project classes""", "${topic}", topic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,15 +15,16 @@ import rife.tools.StringUtils;
|
||||||
*/
|
*/
|
||||||
public class CreateLibHelp implements CommandHelp {
|
public class CreateLibHelp implements CommandHelp {
|
||||||
public String getSummary() {
|
public String getSummary() {
|
||||||
return "Creates a new Java library with minimal commands";
|
return "Creates a new Java library project";
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDescription(String topic) {
|
public String getDescription(String topic) {
|
||||||
return StringUtils.replace("""
|
return StringUtils.replace("""
|
||||||
Creates a new library Java project with minimal commands.
|
Creates a new Java library project.
|
||||||
|
|
||||||
Usage : ${topic} <package> <name>
|
Usage : ${topic} <package> <name> <base>
|
||||||
package The package of the project to create
|
package The package of the project to create
|
||||||
name The name of the project to create""", "${topic}", topic);
|
name The name of the project to create
|
||||||
|
base The base name for generated project classes""", "${topic}", topic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,15 +15,16 @@ import rife.tools.StringUtils;
|
||||||
*/
|
*/
|
||||||
public class CreateRife2Help implements CommandHelp {
|
public class CreateRife2Help implements CommandHelp {
|
||||||
public String getSummary() {
|
public String getSummary() {
|
||||||
return "Creates a new RIFE2 project";
|
return "Creates a new RIFE2 web application project";
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDescription(String topic) {
|
public String getDescription(String topic) {
|
||||||
return StringUtils.replace("""
|
return StringUtils.replace("""
|
||||||
Creates a new RIFE2 project.
|
Creates a new RIFE2 web application project.
|
||||||
|
|
||||||
Usage : ${topic} <package> <name>
|
Usage : ${topic} <package> <name> <base>
|
||||||
package The package of the project to create
|
package The package of the project to create
|
||||||
name The name of the project to create""", "${topic}", topic);
|
name The name of the project to create
|
||||||
|
base The base name for generated project classes""", "${topic}", topic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
package rife.bld.help;
|
package rife.bld.help;
|
||||||
|
|
||||||
import rife.bld.CommandHelp;
|
import rife.bld.CommandHelp;
|
||||||
import rife.tools.StringUtils;
|
import rife.bld.operations.RunOperation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides help for the run command.
|
* Provides help for the run command.
|
||||||
|
|
@ -15,13 +15,13 @@ import rife.tools.StringUtils;
|
||||||
*/
|
*/
|
||||||
public class RunHelp implements CommandHelp {
|
public class RunHelp implements CommandHelp {
|
||||||
public String getSummary() {
|
public String getSummary() {
|
||||||
return "Runs the project";
|
return "Runs the project (take option)";
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDescription(String topic) {
|
public String getDescription(String topic) {
|
||||||
return StringUtils.replace("""
|
return String.format("""
|
||||||
Runs the project.
|
Runs the project.
|
||||||
|
|
||||||
Usage : ${topic}""", "${topic}", topic);
|
Usage : %s [%sARG...]""", topic, RunOperation.ARGS_OPTION);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2001-2024 Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||||
|
*/
|
||||||
|
package rife.bld.instrument;
|
||||||
|
|
||||||
|
import rife.asm.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This utility class will modify a Java module {@code module-info.class} to add
|
||||||
|
* a module main class to its attributes.
|
||||||
|
*
|
||||||
|
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public class ModuleMainClassAdapter extends ClassVisitor implements Opcodes {
|
||||||
|
private final String mainClass_;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs the actual modification of the module info class's bytecode.
|
||||||
|
*
|
||||||
|
* @param origBytes the bytes of the module class that should be modified
|
||||||
|
* @param mainClass the main class of the module
|
||||||
|
* @return the modified bytes
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public static byte[] addModuleMainClassToBytes(byte[] origBytes, String mainClass) {
|
||||||
|
var cw = new ClassWriter(0);
|
||||||
|
new ClassReader(origBytes).accept(new ModuleMainClassAdapter(mainClass, cw), 0);
|
||||||
|
return cw.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ModuleMainClassAdapter(String mainClass, ClassVisitor writer) {
|
||||||
|
super(ASM9, writer);
|
||||||
|
mainClass_ = mainClass.replace('.', '/');
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ModuleVisitor visitModule(String name, int access, String version) {
|
||||||
|
var module_visitor = super.visitModule(name, access, version);
|
||||||
|
module_visitor.visitMainClass(mainClass_);
|
||||||
|
return module_visitor;
|
||||||
|
}
|
||||||
|
}
|
||||||
10
src/main/java/rife/bld/instrument/package-info.java
Normal file
10
src/main/java/rife/bld/instrument/package-info.java
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2001-2024 Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides functionalities for bytecode instrumentation.
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
package rife.bld.instrument;
|
||||||
|
|
@ -6,6 +6,7 @@ package rife.bld.operations;
|
||||||
|
|
||||||
import rife.bld.BldVersion;
|
import rife.bld.BldVersion;
|
||||||
import rife.bld.Project;
|
import rife.bld.Project;
|
||||||
|
import rife.bld.dependencies.VersionNumber;
|
||||||
import rife.bld.operations.exceptions.OperationOptionException;
|
import rife.bld.operations.exceptions.OperationOptionException;
|
||||||
import rife.bld.wrapper.Wrapper;
|
import rife.bld.wrapper.Wrapper;
|
||||||
import rife.template.TemplateFactory;
|
import rife.template.TemplateFactory;
|
||||||
|
|
@ -25,16 +26,17 @@ import java.util.List;
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractCreateOperation<T extends AbstractCreateOperation<T, P>, P extends Project> extends AbstractOperation<AbstractCreateOperation<T, P>> {
|
public abstract class AbstractCreateOperation<T extends AbstractCreateOperation<T, P>, P extends Project> extends AbstractOperation<AbstractCreateOperation<T, P>> {
|
||||||
|
private String packageName_;
|
||||||
|
private String projectName_;
|
||||||
|
private String baseName_;
|
||||||
|
|
||||||
final String templateBase_;
|
final String templateBase_;
|
||||||
|
|
||||||
File workDirectory_ = new File(System.getProperty("user.dir"));
|
File workDirectory_ = new File(System.getProperty("user.dir"));
|
||||||
String packageName_;
|
|
||||||
String projectName_;
|
|
||||||
boolean downloadDependencies_;
|
boolean downloadDependencies_;
|
||||||
|
|
||||||
P project_;
|
P project_;
|
||||||
|
|
||||||
String projectClassName_;
|
|
||||||
String projectBuildName_;
|
String projectBuildName_;
|
||||||
String projectMainName_;
|
String projectMainName_;
|
||||||
String projectMainUberName_;
|
String projectMainUberName_;
|
||||||
|
|
@ -96,11 +98,11 @@ public abstract class AbstractCreateOperation<T extends AbstractCreateOperation<
|
||||||
project_ = createProjectBlueprint();
|
project_ = createProjectBlueprint();
|
||||||
|
|
||||||
// standard names
|
// standard names
|
||||||
projectClassName_ = StringUtils.capitalize(project_.name());
|
var base_name = baseName();
|
||||||
projectBuildName_ = projectBuildClassName(projectClassName_);
|
projectBuildName_ = projectBuildClassName(base_name);
|
||||||
projectMainName_ = projectMainClassName(projectClassName_);
|
projectMainName_ = projectMainClassName(base_name);
|
||||||
projectMainUberName_ = projectMainUberClassName(projectClassName_);
|
projectMainUberName_ = projectMainUberClassName(base_name);
|
||||||
projectTestName_ = projectTestClassName(projectClassName_);
|
projectTestName_ = projectTestClassName(base_name);
|
||||||
|
|
||||||
// create the main project structure
|
// create the main project structure
|
||||||
ideaDirectory_ = new File(project_.workDirectory(), ".idea");
|
ideaDirectory_ = new File(project_.workDirectory(), ".idea");
|
||||||
|
|
@ -131,7 +133,7 @@ public abstract class AbstractCreateOperation<T extends AbstractCreateOperation<
|
||||||
* @since 1.6
|
* @since 1.6
|
||||||
*/
|
*/
|
||||||
protected String projectMainClassName(String projectClassName) {
|
protected String projectMainClassName(String projectClassName) {
|
||||||
return projectClassName + "Main";
|
return projectClassName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -141,7 +143,7 @@ public abstract class AbstractCreateOperation<T extends AbstractCreateOperation<
|
||||||
* @since 1.6
|
* @since 1.6
|
||||||
*/
|
*/
|
||||||
protected String projectMainUberClassName(String projectClassName) {
|
protected String projectMainUberClassName(String projectClassName) {
|
||||||
return projectClassName + "Main";
|
return projectClassName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -198,7 +200,7 @@ public abstract class AbstractCreateOperation<T extends AbstractCreateOperation<
|
||||||
test_template.setValue("projectTest", projectTestName_);
|
test_template.setValue("projectTest", projectTestName_);
|
||||||
test_template.setValue("projectMain", projectMainName_);
|
test_template.setValue("projectMain", projectMainName_);
|
||||||
if (test_template.hasValueId("project")) {
|
if (test_template.hasValueId("project")) {
|
||||||
test_template.setValue("project", projectClassName_);
|
test_template.setValue("project", project_.name());
|
||||||
}
|
}
|
||||||
var project_test_file = new File(testPackageDirectory_, projectTestName_ + ".java");
|
var project_test_file = new File(testPackageDirectory_, projectTestName_ + ".java");
|
||||||
FileUtils.writeString(test_template.getContent(), project_test_file);
|
FileUtils.writeString(test_template.getContent(), project_test_file);
|
||||||
|
|
@ -206,8 +208,12 @@ public abstract class AbstractCreateOperation<T extends AbstractCreateOperation<
|
||||||
// project build
|
// project build
|
||||||
var build_template = TemplateFactory.TXT.get(templateBase_ + "project_build");
|
var build_template = TemplateFactory.TXT.get(templateBase_ + "project_build");
|
||||||
build_template.setValue("projectBuild", projectBuildName_);
|
build_template.setValue("projectBuild", projectBuildName_);
|
||||||
build_template.setValue("package", project_.pkg());
|
if (build_template.hasValueId("package")) {
|
||||||
build_template.setValue("project", projectClassName_);
|
build_template.setValue("package", project_.pkg());
|
||||||
|
}
|
||||||
|
if (build_template.hasValueId("project")) {
|
||||||
|
build_template.setValue("project", project_.name());
|
||||||
|
}
|
||||||
if (build_template.hasValueId("projectMain")) {
|
if (build_template.hasValueId("projectMain")) {
|
||||||
build_template.setValue("projectMain", projectMainName_);
|
build_template.setValue("projectMain", projectMainName_);
|
||||||
}
|
}
|
||||||
|
|
@ -224,9 +230,15 @@ public abstract class AbstractCreateOperation<T extends AbstractCreateOperation<
|
||||||
build_template.setValue("groupId", dependency.groupId());
|
build_template.setValue("groupId", dependency.groupId());
|
||||||
build_template.setValue("artifactId", dependency.artifactId());
|
build_template.setValue("artifactId", dependency.artifactId());
|
||||||
var version = dependency.version();
|
var version = dependency.version();
|
||||||
var version_string = version.major() + "," + version.minor() + "," + version.revision();
|
var version_string = "";
|
||||||
if (!version.qualifier().isEmpty()) {
|
if (version instanceof VersionNumber versionNumber) {
|
||||||
version_string += ",\"" + version.qualifier() + "\"";
|
version_string = versionNumber.major() + "," + versionNumber.minor() + "," + versionNumber.revision();
|
||||||
|
if (!version.qualifier().isEmpty()) {
|
||||||
|
version_string += ",\"" + version.qualifier() + "\"";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
version_string = "\"" + version.toString() + "\"";
|
||||||
}
|
}
|
||||||
build_template.setValue("version", version_string);
|
build_template.setValue("version", version_string);
|
||||||
build_template.appendBlock("dependencies", "dependency");
|
build_template.appendBlock("dependencies", "dependency");
|
||||||
|
|
@ -364,32 +376,62 @@ public abstract class AbstractCreateOperation<T extends AbstractCreateOperation<
|
||||||
public T fromArguments(List<String> arguments) {
|
public T fromArguments(List<String> arguments) {
|
||||||
String package_name = null;
|
String package_name = null;
|
||||||
String project_name = null;
|
String project_name = null;
|
||||||
if (arguments.size() > 0) {
|
String base_name = null;
|
||||||
|
if (!arguments.isEmpty()) {
|
||||||
package_name = arguments.remove(0);
|
package_name = arguments.remove(0);
|
||||||
}
|
}
|
||||||
if (arguments.size() > 0) {
|
if (!arguments.isEmpty()) {
|
||||||
project_name = arguments.remove(0);
|
project_name = arguments.remove(0);
|
||||||
}
|
}
|
||||||
if ((package_name == null || project_name == null) && System.console() == null) {
|
if (!arguments.isEmpty()) {
|
||||||
throw new OperationOptionException("ERROR: Expecting the package and project names as the arguments.");
|
base_name = arguments.remove(0);
|
||||||
|
}
|
||||||
|
if ((package_name == null || project_name == null || base_name == null) && System.console() == null) {
|
||||||
|
throw new OperationOptionException("ERROR: Expecting the package, project and base names as the arguments.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (package_name == null || package_name.isEmpty()) {
|
if (package_name == null || package_name.isBlank()) {
|
||||||
System.out.println("Please enter a package name (for instance: com.example):");
|
System.out.println("Please enter a package name (for instance: com.example):");
|
||||||
package_name = System.console().readLine();
|
package_name = System.console().readLine();
|
||||||
|
if (package_name == null || package_name.isBlank()) {
|
||||||
|
throw new OperationOptionException("ERROR: package name is required.");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
System.out.println("Using package name: " + package_name);
|
System.out.println("Using package name: " + package_name);
|
||||||
}
|
}
|
||||||
if (project_name == null || project_name.isEmpty()) {
|
if (!ValidityChecks.checkJavaPackage(package_name)) {
|
||||||
System.out.println("Please enter a project name (for instance: myapp):");
|
throw new OperationOptionException("ERROR: package name is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (project_name == null || project_name.isBlank()) {
|
||||||
|
System.out.println("Please enter a project name (for instance: my-app):");
|
||||||
project_name = System.console().readLine();
|
project_name = System.console().readLine();
|
||||||
|
if (project_name == null || project_name.isBlank()) {
|
||||||
|
throw new OperationOptionException("ERROR: project name is required.");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
System.out.println("Using project name: " + project_name);
|
System.out.println("Using project name: " + project_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (base_name == null || base_name.isBlank()) {
|
||||||
|
var default_base_name = generateBaseName(project_name);
|
||||||
|
System.out.println("Please enter the base name for generated project classes (default: " + default_base_name + "):");
|
||||||
|
base_name = System.console().readLine();
|
||||||
|
if (base_name == null || base_name.isBlank()) {
|
||||||
|
base_name = default_base_name;
|
||||||
|
System.out.println("Using base name: " + base_name);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
System.out.println("Using base name: " + base_name);
|
||||||
|
}
|
||||||
|
if (!ValidityChecks.checkJavaIdentifier(base_name)) {
|
||||||
|
throw new OperationOptionException("ERROR: base name is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
return workDirectory(new File(System.getProperty("user.dir")))
|
return workDirectory(new File(System.getProperty("user.dir")))
|
||||||
.packageName(package_name)
|
.packageName(package_name)
|
||||||
.projectName(project_name)
|
.projectName(project_name)
|
||||||
|
.baseName(base_name)
|
||||||
.downloadDependencies(true);
|
.downloadDependencies(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -434,7 +476,6 @@ public abstract class AbstractCreateOperation<T extends AbstractCreateOperation<
|
||||||
throw new OperationOptionException("ERROR: The package name is invalid.");
|
throw new OperationOptionException("ERROR: The package name is invalid.");
|
||||||
}
|
}
|
||||||
|
|
||||||
packageName_ = name;
|
|
||||||
return (T) this;
|
return (T) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -451,10 +492,26 @@ public abstract class AbstractCreateOperation<T extends AbstractCreateOperation<
|
||||||
throw new OperationOptionException("ERROR: The project name should not be blank.");
|
throw new OperationOptionException("ERROR: The project name should not be blank.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ValidityChecks.checkJavaIdentifier(projectName_)) {
|
return (T) this;
|
||||||
throw new OperationOptionException("ERROR: The project name is invalid.");
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the base name for the project classes to generate.
|
||||||
|
*
|
||||||
|
* @param name the base name
|
||||||
|
* @return this operation instance
|
||||||
|
* @since 2.2
|
||||||
|
*/
|
||||||
|
public T baseName(String name) {
|
||||||
|
baseName_ = StringUtils.trim(name);
|
||||||
|
if (baseName_.isEmpty()) {
|
||||||
|
throw new OperationOptionException("ERROR: The base name should not be blank.");
|
||||||
}
|
}
|
||||||
projectName_ = name;
|
|
||||||
|
if (!ValidityChecks.checkJavaIdentifier(baseName_)) {
|
||||||
|
throw new OperationOptionException("ERROR: The base name is invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
return (T) this;
|
return (T) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -502,6 +559,30 @@ public abstract class AbstractCreateOperation<T extends AbstractCreateOperation<
|
||||||
return projectName_;
|
return projectName_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static String generateBaseName(String projectName) {
|
||||||
|
if (projectName != null) {
|
||||||
|
return StringUtils.filterAsIdentifier(projectName.trim(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the base name for the project classes to generate.
|
||||||
|
* <p>
|
||||||
|
* If no base name was provided, one will be generated from the project name.
|
||||||
|
*
|
||||||
|
* @return the base name
|
||||||
|
* @since 2.2
|
||||||
|
*/
|
||||||
|
public String baseName() {
|
||||||
|
if (baseName_ == null || baseName_.isEmpty()) {
|
||||||
|
return generateBaseName(projectName());
|
||||||
|
}
|
||||||
|
|
||||||
|
return baseName_;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves whether dependencies will be downloaded at project creation.
|
* Retrieves whether dependencies will be downloaded at project creation.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,7 @@ import rife.bld.operations.exceptions.OperationOptionException;
|
||||||
import rife.tools.exceptions.FileUtilsErrorException;
|
import rife.tools.exceptions.FileUtilsErrorException;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -24,10 +23,13 @@ public abstract class AbstractProcessOperation<T extends AbstractProcessOperatio
|
||||||
public static final String DEFAULT_JAVA_TOOL = "java";
|
public static final String DEFAULT_JAVA_TOOL = "java";
|
||||||
|
|
||||||
protected File workDirectory_ = new File(System.getProperty("user.dir"));
|
protected File workDirectory_ = new File(System.getProperty("user.dir"));
|
||||||
|
protected final Map<String, String> environment_ = new HashMap<>();
|
||||||
protected String javaTool_ = DEFAULT_JAVA_TOOL;
|
protected String javaTool_ = DEFAULT_JAVA_TOOL;
|
||||||
protected final JavaOptions javaOptions_ = new JavaOptions();
|
protected final JavaOptions javaOptions_ = new JavaOptions();
|
||||||
protected final List<String> classpath_ = new ArrayList<>();
|
protected final List<String> classpath_ = new ArrayList<>();
|
||||||
|
protected final List<String> modulePath_ = new ArrayList<>();
|
||||||
protected String mainClass_;
|
protected String mainClass_;
|
||||||
|
protected String module_;
|
||||||
protected Function<String, Boolean> outputProcessor_;
|
protected Function<String, Boolean> outputProcessor_;
|
||||||
protected Function<String, Boolean> errorProcessor_;
|
protected Function<String, Boolean> errorProcessor_;
|
||||||
protected Process process_;
|
protected Process process_;
|
||||||
|
|
@ -85,6 +87,12 @@ public abstract class AbstractProcessOperation<T extends AbstractProcessOperatio
|
||||||
var builder = new ProcessBuilder(executeConstructProcessCommandList());
|
var builder = new ProcessBuilder(executeConstructProcessCommandList());
|
||||||
builder.directory(workDirectory());
|
builder.directory(workDirectory());
|
||||||
|
|
||||||
|
if (!environment_.isEmpty()) {
|
||||||
|
builder.environment().putAll(environment_);
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.redirectInput(ProcessBuilder.Redirect.INHERIT);
|
||||||
|
|
||||||
final var output_processor = outputProcessor();
|
final var output_processor = outputProcessor();
|
||||||
if (output_processor == null) {
|
if (output_processor == null) {
|
||||||
builder.redirectOutput(ProcessBuilder.Redirect.INHERIT);
|
builder.redirectOutput(ProcessBuilder.Redirect.INHERIT);
|
||||||
|
|
@ -159,6 +167,31 @@ public abstract class AbstractProcessOperation<T extends AbstractProcessOperatio
|
||||||
return (T) this;
|
return (T) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides an environment variable to use for the operation.
|
||||||
|
*
|
||||||
|
* @param name the name of the environment variable
|
||||||
|
* @param value the value of the environment variable
|
||||||
|
* @return this operation instance
|
||||||
|
* @since 2.2.1
|
||||||
|
*/
|
||||||
|
public T environment(String name, String value) {
|
||||||
|
environment_.put(name, value);
|
||||||
|
return (T) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides environment variable entries to use for the operation.
|
||||||
|
*
|
||||||
|
* @param environment environment entries for the operation
|
||||||
|
* @return this operation instance
|
||||||
|
* @since 2.2.1
|
||||||
|
*/
|
||||||
|
public T environment(Map<String, String> environment) {
|
||||||
|
environment_.putAll(environment);
|
||||||
|
return (T) this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the name of the tool to use for {@code java} execution.
|
* Provides the name of the tool to use for {@code java} execution.
|
||||||
* <p>
|
* <p>
|
||||||
|
|
@ -197,6 +230,18 @@ public abstract class AbstractProcessOperation<T extends AbstractProcessOperatio
|
||||||
return (T) this;
|
return (T) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides classpath entries to use for the operation.
|
||||||
|
*
|
||||||
|
* @param classpath classpath entries for the operation
|
||||||
|
* @return this operation instance
|
||||||
|
* @since 2.3.1
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public T classpath(File... classpath) {
|
||||||
|
return classpath(List.of(classpath));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides a list of classpath entries to use for the operation.
|
* Provides a list of classpath entries to use for the operation.
|
||||||
* <p>
|
* <p>
|
||||||
|
|
@ -211,6 +256,71 @@ public abstract class AbstractProcessOperation<T extends AbstractProcessOperatio
|
||||||
return (T) this;
|
return (T) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides a list of classpath entries to use for the operation.
|
||||||
|
* <p>
|
||||||
|
* A copy will be created to allow this list to be independently modifiable.
|
||||||
|
*
|
||||||
|
* @param classpath a list of classpath entries for the operation
|
||||||
|
* @return this operation instance
|
||||||
|
* @since 2.3.1
|
||||||
|
*/
|
||||||
|
public T classpath(Collection<File> classpath) {
|
||||||
|
classpath_.addAll(classpath.stream().map(File::getAbsolutePath).toList());
|
||||||
|
return (T) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides module path entries to use for the operation.
|
||||||
|
*
|
||||||
|
* @param modulePath module path entries for the operation
|
||||||
|
* @return this operation instance
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public T modulePath(String... modulePath) {
|
||||||
|
modulePath_.addAll(List.of(modulePath));
|
||||||
|
return (T) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides module path entries to use for the operation.
|
||||||
|
*
|
||||||
|
* @param modulePath module path entries for the operation
|
||||||
|
* @return this operation instance
|
||||||
|
* @since 2.3.1
|
||||||
|
*/
|
||||||
|
public T modulePath(File... modulePath) {
|
||||||
|
return modulePath(List.of(modulePath));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides a list of module path entries to use for the operation.
|
||||||
|
* <p>
|
||||||
|
* A copy will be created to allow this list to be independently modifiable.
|
||||||
|
*
|
||||||
|
* @param modulePath a list of module path entries for the operation
|
||||||
|
* @return this operation instance
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public T modulePath(List<String> modulePath) {
|
||||||
|
modulePath_.addAll(modulePath);
|
||||||
|
return (T) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides a list of module path entries to use for the operation.
|
||||||
|
* <p>
|
||||||
|
* A copy will be created to allow this list to be independently modifiable.
|
||||||
|
*
|
||||||
|
* @param modulePath a list of module path entries for the operation
|
||||||
|
* @return this operation instance
|
||||||
|
* @since 2.3.1
|
||||||
|
*/
|
||||||
|
public T modulePath(Collection<File> modulePath) {
|
||||||
|
modulePath_.addAll(modulePath.stream().map(File::getAbsolutePath).toList());
|
||||||
|
return (T) this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the main class to launch with the java tool.
|
* Provides the main class to launch with the java tool.
|
||||||
*
|
*
|
||||||
|
|
@ -223,6 +333,18 @@ public abstract class AbstractProcessOperation<T extends AbstractProcessOperatio
|
||||||
return (T) this;
|
return (T) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the module to launch with the java tool.
|
||||||
|
*
|
||||||
|
* @param name the module to launch
|
||||||
|
* @return this operation instance
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public T module(String name) {
|
||||||
|
module_ = name;
|
||||||
|
return (T) this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the processor that will be used to handle the process output.
|
* Provides the processor that will be used to handle the process output.
|
||||||
* <p>
|
* <p>
|
||||||
|
|
@ -261,6 +383,18 @@ public abstract class AbstractProcessOperation<T extends AbstractProcessOperatio
|
||||||
return workDirectory_;
|
return workDirectory_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the environment to use for the operation.
|
||||||
|
* <p>
|
||||||
|
* This is a modifiable map that can be retrieved and changed.
|
||||||
|
*
|
||||||
|
* @return the operation's environment
|
||||||
|
* @since 2.2.1
|
||||||
|
*/
|
||||||
|
public Map<String, String> environment() {
|
||||||
|
return environment_;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* retrieves the name of the tool to use for {@code java} execution.
|
* retrieves the name of the tool to use for {@code java} execution.
|
||||||
*
|
*
|
||||||
|
|
@ -295,6 +429,18 @@ public abstract class AbstractProcessOperation<T extends AbstractProcessOperatio
|
||||||
return classpath_;
|
return classpath_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the module path to use for the operation.
|
||||||
|
* <p>
|
||||||
|
* This is a modifiable list that can be retrieved and changed.
|
||||||
|
*
|
||||||
|
* @return the operation's module path
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public List<String> modulePath() {
|
||||||
|
return modulePath_;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the main class to launch with the java tool.
|
* Retrieves the main class to launch with the java tool.
|
||||||
*
|
*
|
||||||
|
|
@ -305,6 +451,16 @@ public abstract class AbstractProcessOperation<T extends AbstractProcessOperatio
|
||||||
return mainClass_;
|
return mainClass_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the module to launch with the java tool.
|
||||||
|
*
|
||||||
|
* @return the module to launch
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public String module() {
|
||||||
|
return module_;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the processor that is used to handle the process output.
|
* Retrieves the processor that is used to handle the process output.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,283 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2024 Erik C. Thauvin (https://erik.thauvin.net/)
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||||
|
*/
|
||||||
|
package rife.bld.operations;
|
||||||
|
|
||||||
|
import rife.bld.operations.exceptions.ExitStatusException;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.spi.ToolProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides common features for tool providers.
|
||||||
|
*
|
||||||
|
* @author <a href="https://erik.thauvin.net/">Erik C. Thauvin</a>
|
||||||
|
* @since 2.1.0
|
||||||
|
*/
|
||||||
|
public abstract class AbstractToolProviderOperation<T extends AbstractToolProviderOperation<T>>
|
||||||
|
extends AbstractOperation<AbstractToolProviderOperation<T>> {
|
||||||
|
private final List<String> cmdFiles_ = new ArrayList<>();
|
||||||
|
private final List<String> toolArgs_ = new ArrayList<>();
|
||||||
|
private final String toolName_;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the name of the tool.
|
||||||
|
*
|
||||||
|
* @param toolName the tool name
|
||||||
|
*/
|
||||||
|
public AbstractToolProviderOperation(String toolName) {
|
||||||
|
toolName_ = toolName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read options and/or mode from file(s).
|
||||||
|
*
|
||||||
|
* @param files one or more files
|
||||||
|
* @return this operation instance
|
||||||
|
*/
|
||||||
|
public T cmdFiles(String... files) {
|
||||||
|
return cmdFilesStrings(List.of(files));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read options and/or mode from file(s).
|
||||||
|
*
|
||||||
|
* @param files one or more files
|
||||||
|
* @return this operation instance
|
||||||
|
*/
|
||||||
|
@SuppressWarnings({"unchecked"})
|
||||||
|
public T cmdFiles(List<File> files) {
|
||||||
|
cmdFiles_.addAll(files.stream().map(File::getAbsolutePath).toList());
|
||||||
|
return (T) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read options and/or mode from file(s).
|
||||||
|
*
|
||||||
|
* @param files one or more files
|
||||||
|
* @return this operation instance
|
||||||
|
*/
|
||||||
|
public T cmdFiles(File... files) {
|
||||||
|
return cmdFiles(List.of(files));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read options and/or mode from file(s).
|
||||||
|
*
|
||||||
|
* @param files one or more files
|
||||||
|
* @return this operation instance
|
||||||
|
*/
|
||||||
|
public T cmdFiles(Path... files) {
|
||||||
|
return cmdFilesPaths(List.of(files));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the list of files containing options or mode.
|
||||||
|
*
|
||||||
|
* @return the list of files
|
||||||
|
*/
|
||||||
|
public List<String> cmdFiles() {
|
||||||
|
return cmdFiles_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read options and/or mode from file(s).
|
||||||
|
*
|
||||||
|
* @param files one or more files
|
||||||
|
* @return this operation instance
|
||||||
|
*/
|
||||||
|
public T cmdFilesPaths(List<Path> files) {
|
||||||
|
return cmdFilesStrings(files.stream().map(Path::toFile).map(File::getAbsolutePath).toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read options and/or mode from file(s).
|
||||||
|
*
|
||||||
|
* @param files one or more files
|
||||||
|
* @return this operation instance
|
||||||
|
*/
|
||||||
|
@SuppressWarnings({"unchecked"})
|
||||||
|
public T cmdFilesStrings(List<String> files) {
|
||||||
|
cmdFiles_.addAll(files);
|
||||||
|
return (T) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs an instance of the tool.
|
||||||
|
* <p>
|
||||||
|
* On success, command line arguments are automatically cleared.
|
||||||
|
*
|
||||||
|
* @throws Exception if an error occurred
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void execute() throws Exception {
|
||||||
|
if (toolArgs_.isEmpty()) {
|
||||||
|
System.err.println("No " + toolName_ + " command line arguments specified.");
|
||||||
|
throw new ExitStatusException(ExitStatusException.EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
var tool = ToolProvider.findFirst(toolName_).orElseThrow(() ->
|
||||||
|
new IllegalStateException("No " + toolName_ + " tool found."));
|
||||||
|
|
||||||
|
var status = tool.run(System.out, System.err, toolArgs_.toArray(new String[0]));
|
||||||
|
if (status != 0) {
|
||||||
|
System.out.println(tool.name() + ' ' + String.join(" ", toolArgs_));
|
||||||
|
}
|
||||||
|
|
||||||
|
ExitStatusException.throwOnFailure(status);
|
||||||
|
|
||||||
|
toolArgs_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds arguments to pass to the tool.
|
||||||
|
*
|
||||||
|
* @param args tbe list of arguments
|
||||||
|
* @return this operation
|
||||||
|
*/
|
||||||
|
@SuppressWarnings({"unchecked"})
|
||||||
|
public T toolArgs(List<String> args) {
|
||||||
|
toolArgs_.addAll(args);
|
||||||
|
return (T) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds arguments to pass to the tool.
|
||||||
|
*
|
||||||
|
* @param args one or more arguments
|
||||||
|
* @return this operation
|
||||||
|
*/
|
||||||
|
public T toolArgs(String... args) {
|
||||||
|
return toolArgs(List.of(args));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the tool's arguments.
|
||||||
|
*
|
||||||
|
* @return the arguments
|
||||||
|
*/
|
||||||
|
public List<String> toolArgs() {
|
||||||
|
return toolArgs_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses arguments to pass to the tool from the {@link #cmdFiles() command files}.
|
||||||
|
*
|
||||||
|
* @throws FileNotFoundException if a file cannot be found
|
||||||
|
*/
|
||||||
|
protected void toolArgsFromFiles() throws IOException {
|
||||||
|
for (var file : cmdFiles_) {
|
||||||
|
try (var reader = Files.newBufferedReader(Paths.get(file), Charset.defaultCharset())) {
|
||||||
|
var tokenizer = new CommandLineTokenizer(reader);
|
||||||
|
String token;
|
||||||
|
while ((token = tokenizer.nextToken()) != null) {
|
||||||
|
toolArgs_.add(token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds arguments to pass to the tool.
|
||||||
|
*
|
||||||
|
* @param args the argument-value pairs to add
|
||||||
|
* @return this operation
|
||||||
|
*/
|
||||||
|
@SuppressWarnings({"unchecked", "UnusedReturnValue"})
|
||||||
|
protected T toolArgs(Map<String, String> args) {
|
||||||
|
args.forEach((k, v) -> {
|
||||||
|
toolArgs_.add(k);
|
||||||
|
if (v != null && !v.isEmpty()) {
|
||||||
|
toolArgs_.add(v);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return (T) this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tokenize command line arguments.
|
||||||
|
*
|
||||||
|
* <ul>
|
||||||
|
* <li>Arguments containing spaces should be quoted</li>
|
||||||
|
* <li>Escape sequences and comments are supported</li>
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
public static class CommandLineTokenizer {
|
||||||
|
private final StringBuilder buf_ = new StringBuilder();
|
||||||
|
private final Reader input_;
|
||||||
|
private int ch_;
|
||||||
|
|
||||||
|
public CommandLineTokenizer(Reader input) throws IOException {
|
||||||
|
input_ = input;
|
||||||
|
ch_ = input.read();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String nextToken() throws IOException {
|
||||||
|
trimWhitespaceOrComments();
|
||||||
|
if (ch_ == -1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf_.setLength(0); // reset buffer
|
||||||
|
|
||||||
|
char quote = 0;
|
||||||
|
while (ch_ != -1) {
|
||||||
|
if (ch_ == '\'' || ch_ == '"') { // quotes
|
||||||
|
if (quote == 0) { // begin quote
|
||||||
|
quote = (char) ch_;
|
||||||
|
} else if (quote == ch_) { // end quote
|
||||||
|
quote = 0;
|
||||||
|
} else {
|
||||||
|
buf_.append((char) ch_);
|
||||||
|
}
|
||||||
|
} else if (ch_ == '\\') { // escaped
|
||||||
|
ch_ = input_.read();
|
||||||
|
buf_.append(handleEscapeSequence());
|
||||||
|
} else if (quote == 0 && Character.isWhitespace(ch_)) { // whitespaces
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
buf_.append((char) ch_);
|
||||||
|
}
|
||||||
|
ch_ = input_.read();
|
||||||
|
}
|
||||||
|
return buf_.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private char handleEscapeSequence() {
|
||||||
|
return switch (ch_) {
|
||||||
|
case -1 -> '\\';
|
||||||
|
case 'n' -> '\n';
|
||||||
|
case 'r' -> '\r';
|
||||||
|
case 't' -> '\t';
|
||||||
|
case 'f' -> '\f';
|
||||||
|
default -> (char) ch_;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private void trimWhitespaceOrComments() throws IOException {
|
||||||
|
while (ch_ != -1) {
|
||||||
|
if (Character.isWhitespace(ch_)) { // Skip whitespaces
|
||||||
|
ch_ = input_.read();
|
||||||
|
} else if (ch_ == '#') {
|
||||||
|
// Skip the entire comment until a new line or end of input
|
||||||
|
do {
|
||||||
|
ch_ = input_.read();
|
||||||
|
} while (ch_ != -1 && ch_ != '\n' && ch_ != '\r');
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -5,7 +5,6 @@
|
||||||
package rife.bld.operations;
|
package rife.bld.operations;
|
||||||
|
|
||||||
import rife.bld.BaseProject;
|
import rife.bld.BaseProject;
|
||||||
import rife.bld.Project;
|
|
||||||
import rife.tools.FileUtils;
|
import rife.tools.FileUtils;
|
||||||
import rife.tools.exceptions.FileUtilsErrorException;
|
import rife.tools.exceptions.FileUtilsErrorException;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
package rife.bld.operations;
|
package rife.bld.operations;
|
||||||
|
|
||||||
import rife.bld.BaseProject;
|
import rife.bld.BaseProject;
|
||||||
import rife.bld.Project;
|
import rife.bld.instrument.ModuleMainClassAdapter;
|
||||||
import rife.bld.operations.exceptions.ExitStatusException;
|
import rife.bld.operations.exceptions.ExitStatusException;
|
||||||
import rife.tools.FileUtils;
|
import rife.tools.FileUtils;
|
||||||
|
|
||||||
|
|
@ -23,16 +23,26 @@ import java.util.List;
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
public class CompileOperation extends AbstractOperation<CompileOperation> {
|
public class CompileOperation extends AbstractOperation<CompileOperation> {
|
||||||
|
static final String COMPILE_OPTION_D = "-d";
|
||||||
|
static final String COMPILE_OPTION_CP = "-cp";
|
||||||
|
static final String COMPILE_OPTION_CLASS_PATH = "--class-path";
|
||||||
|
static final String COMPILE_OPTION_CLASSPATH = "--classpath";
|
||||||
|
static final String COMPILE_OPTION_P = "-p";
|
||||||
|
static final String COMPILE_OPTION_MODULE_PATH = "--module-path";
|
||||||
|
|
||||||
private File buildMainDirectory_;
|
private File buildMainDirectory_;
|
||||||
private File buildTestDirectory_;
|
private File buildTestDirectory_;
|
||||||
private final List<String> compileMainClasspath_ = new ArrayList<>();
|
private final List<String> compileMainClasspath_ = new ArrayList<>();
|
||||||
private final List<String> compileTestClasspath_ = new ArrayList<>();
|
private final List<String> compileTestClasspath_ = new ArrayList<>();
|
||||||
|
private final List<String> compileMainModulePath_ = new ArrayList<>();
|
||||||
|
private final List<String> compileTestModulePath_ = new ArrayList<>();
|
||||||
private final List<File> mainSourceFiles_ = new ArrayList<>();
|
private final List<File> mainSourceFiles_ = new ArrayList<>();
|
||||||
private final List<File> testSourceFiles_ = new ArrayList<>();
|
private final List<File> testSourceFiles_ = new ArrayList<>();
|
||||||
private final List<File> mainSourceDirectories_ = new ArrayList<>();
|
private final List<File> mainSourceDirectories_ = new ArrayList<>();
|
||||||
private final List<File> testSourceDirectories_ = new ArrayList<>();
|
private final List<File> testSourceDirectories_ = new ArrayList<>();
|
||||||
private final JavacOptions compileOptions_ = new JavacOptions();
|
private final JavacOptions compileOptions_ = new JavacOptions();
|
||||||
private final List<Diagnostic<? extends JavaFileObject>> diagnostics_ = new ArrayList<>();
|
private final List<Diagnostic<? extends JavaFileObject>> diagnostics_ = new ArrayList<>();
|
||||||
|
private String moduleMainClass_;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs the compile operation.
|
* Performs the compile operation.
|
||||||
|
|
@ -77,10 +87,18 @@ public class CompileOperation extends AbstractOperation<CompileOperation> {
|
||||||
for (var directory : mainSourceDirectories()) {
|
for (var directory : mainSourceDirectories()) {
|
||||||
sources.addAll(FileUtils.getJavaFileList(directory));
|
sources.addAll(FileUtils.getJavaFileList(directory));
|
||||||
}
|
}
|
||||||
executeBuildSources(
|
|
||||||
compileMainClasspath(),
|
if (sources.isEmpty()) {
|
||||||
sources,
|
if (!silent()) {
|
||||||
buildMainDirectory());
|
System.err.println("No main source files found.");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
executeBuildSources(
|
||||||
|
compileMainClasspath(),
|
||||||
|
compileMainModulePath(),
|
||||||
|
sources,
|
||||||
|
buildMainDirectory());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -94,21 +112,30 @@ public class CompileOperation extends AbstractOperation<CompileOperation> {
|
||||||
for (var directory : testSourceDirectories()) {
|
for (var directory : testSourceDirectories()) {
|
||||||
sources.addAll(FileUtils.getJavaFileList(directory));
|
sources.addAll(FileUtils.getJavaFileList(directory));
|
||||||
}
|
}
|
||||||
executeBuildSources(
|
|
||||||
compileTestClasspath(),
|
if (sources.isEmpty()) {
|
||||||
sources,
|
if (!silent()) {
|
||||||
buildTestDirectory());
|
System.err.println("No test source files found.");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
executeBuildSources(
|
||||||
|
compileTestClasspath(),
|
||||||
|
compileTestModulePath(),
|
||||||
|
sources,
|
||||||
|
buildTestDirectory());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Part of the {@link #execute} operation, build sources to a destination.
|
* Part of the {@link #execute} operation, build sources to a destination.
|
||||||
*
|
*
|
||||||
* @param classpath the classpath list used for the compilation
|
* @param classpath the classpath list used for the compilation
|
||||||
|
* @param modulePath the module path list used for the compilation
|
||||||
* @param sources the source files to compile
|
* @param sources the source files to compile
|
||||||
* @param destination the destination directory
|
* @param destination the destination directory
|
||||||
* @since 1.5
|
* @since 2.1
|
||||||
*/
|
*/
|
||||||
protected void executeBuildSources(List<String> classpath, List<File> sources, File destination)
|
protected void executeBuildSources(List<String> classpath, List<String> modulePath, List<File> sources, File destination)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
if (sources.isEmpty() || destination == null) {
|
if (sources.isEmpty() || destination == null) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -118,16 +145,52 @@ public class CompileOperation extends AbstractOperation<CompileOperation> {
|
||||||
try (var file_manager = compiler.getStandardFileManager(null, null, null)) {
|
try (var file_manager = compiler.getStandardFileManager(null, null, null)) {
|
||||||
var compilation_units = file_manager.getJavaFileObjectsFromFiles(sources);
|
var compilation_units = file_manager.getJavaFileObjectsFromFiles(sources);
|
||||||
var diagnostics = new DiagnosticCollector<JavaFileObject>();
|
var diagnostics = new DiagnosticCollector<JavaFileObject>();
|
||||||
var options = new ArrayList<>(List.of("-d", destination.getAbsolutePath(), "-cp", FileUtils.joinPaths(classpath)));
|
var options = new ArrayList<>(List.of(COMPILE_OPTION_D, destination.getAbsolutePath()));
|
||||||
|
|
||||||
|
if (!classpath.isEmpty()) {
|
||||||
|
var class_path = FileUtils.joinPaths(classpath);
|
||||||
|
class_path = removeAndAppendCompileOptionPath(class_path, COMPILE_OPTION_CP);
|
||||||
|
class_path = removeAndAppendCompileOptionPath(class_path, COMPILE_OPTION_CLASS_PATH);
|
||||||
|
class_path = removeAndAppendCompileOptionPath(class_path, COMPILE_OPTION_CLASSPATH);
|
||||||
|
|
||||||
|
options.addAll(List.of(COMPILE_OPTION_CP, class_path));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!modulePath.isEmpty()) {
|
||||||
|
var module_path = FileUtils.joinPaths(modulePath);
|
||||||
|
module_path = removeAndAppendCompileOptionPath(module_path, COMPILE_OPTION_P);
|
||||||
|
module_path = removeAndAppendCompileOptionPath(module_path, COMPILE_OPTION_MODULE_PATH);
|
||||||
|
|
||||||
|
options.addAll(List.of(COMPILE_OPTION_P, module_path));
|
||||||
|
}
|
||||||
|
|
||||||
options.addAll(compileOptions());
|
options.addAll(compileOptions());
|
||||||
|
|
||||||
var compilation_task = compiler.getTask(null, file_manager, diagnostics, options, null, compilation_units);
|
var compilation_task = compiler.getTask(null, file_manager, diagnostics, options, null, compilation_units);
|
||||||
if (!compilation_task.call()) {
|
if (!compilation_task.call()) {
|
||||||
diagnostics_.addAll(diagnostics.getDiagnostics());
|
diagnostics_.addAll(diagnostics.getDiagnostics());
|
||||||
executeProcessDiagnostics(diagnostics);
|
executeProcessDiagnostics(diagnostics);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var module_info_class = new File(destination, "module-info.class");
|
||||||
|
if (module_info_class.exists() && moduleMainClass() != null) {
|
||||||
|
var orig_bytes = FileUtils.readBytes(module_info_class);
|
||||||
|
var transformed_bytes = ModuleMainClassAdapter.addModuleMainClassToBytes(orig_bytes, moduleMainClass());
|
||||||
|
FileUtils.writeBytes(transformed_bytes, module_info_class);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String removeAndAppendCompileOptionPath(String basePath, String option) {
|
||||||
|
var index = compileOptions_.indexOf(option);
|
||||||
|
if (index != -1 && index + 1 < compileOptions_.size() - 1) {
|
||||||
|
compileOptions_.remove(index);
|
||||||
|
return basePath + File.pathSeparator + compileOptions_.remove(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
return basePath;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Part of the {@link #execute} operation, processes the compilation diagnostics.
|
* Part of the {@link #execute} operation, processes the compilation diagnostics.
|
||||||
*
|
*
|
||||||
|
|
@ -162,8 +225,11 @@ public class CompileOperation extends AbstractOperation<CompileOperation> {
|
||||||
.buildTestDirectory(project.buildTestDirectory())
|
.buildTestDirectory(project.buildTestDirectory())
|
||||||
.compileMainClasspath(project.compileMainClasspath())
|
.compileMainClasspath(project.compileMainClasspath())
|
||||||
.compileTestClasspath(project.compileTestClasspath())
|
.compileTestClasspath(project.compileTestClasspath())
|
||||||
|
.compileMainModulePath(project.compileMainModulePath())
|
||||||
|
.compileTestModulePath(project.compileTestModulePath())
|
||||||
.mainSourceFiles(project.mainSourceFiles())
|
.mainSourceFiles(project.mainSourceFiles())
|
||||||
.testSourceFiles(project.testSourceFiles());
|
.testSourceFiles(project.testSourceFiles())
|
||||||
|
.moduleMainClass(project.mainClass());
|
||||||
if (project.javaRelease() != null && !compileOptions().containsRelease()) {
|
if (project.javaRelease() != null && !compileOptions().containsRelease()) {
|
||||||
compileOptions().release(project.javaRelease());
|
compileOptions().release(project.javaRelease());
|
||||||
}
|
}
|
||||||
|
|
@ -246,6 +312,58 @@ public class CompileOperation extends AbstractOperation<CompileOperation> {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides entries for the main compilation module path.
|
||||||
|
*
|
||||||
|
* @param modulePath module path entries
|
||||||
|
* @return this operation instance
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public CompileOperation compileMainModulePath(String... modulePath) {
|
||||||
|
compileMainModulePath_.addAll(Arrays.asList(modulePath));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides a list of entries for the main compilation module path.
|
||||||
|
* <p>
|
||||||
|
* A copy will be created to allow this list to be independently modifiable.
|
||||||
|
*
|
||||||
|
* @param modulePath a list of module path entries
|
||||||
|
* @return this operation instance
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public CompileOperation compileMainModulePath(List<String> modulePath) {
|
||||||
|
compileMainModulePath_.addAll(modulePath);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides entries for the test compilation module path.
|
||||||
|
*
|
||||||
|
* @param modulePath module path entries
|
||||||
|
* @return this operation instance
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public CompileOperation compileTestModulePath(String... modulePath) {
|
||||||
|
compileTestModulePath_.addAll(Arrays.asList(modulePath));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides a list of entries for the test compilation module path.
|
||||||
|
* <p>
|
||||||
|
* A copy will be created to allow this list to be independently modifiable.
|
||||||
|
*
|
||||||
|
* @param modulePath a list of module path entries
|
||||||
|
* @return this operation instance
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public CompileOperation compileTestModulePath(List<String> modulePath) {
|
||||||
|
compileTestModulePath_.addAll(modulePath);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides main files that should be compiled.
|
* Provides main files that should be compiled.
|
||||||
*
|
*
|
||||||
|
|
@ -364,6 +482,18 @@ public class CompileOperation extends AbstractOperation<CompileOperation> {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the main class to use if this compilation includes @{code module-info.java}.
|
||||||
|
*
|
||||||
|
* @param name the main class of the module
|
||||||
|
* @return this operation instance
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public CompileOperation moduleMainClass(String name) {
|
||||||
|
moduleMainClass_ = name;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the main build destination directory.
|
* Retrieves the main build destination directory.
|
||||||
*
|
*
|
||||||
|
|
@ -408,6 +538,30 @@ public class CompileOperation extends AbstractOperation<CompileOperation> {
|
||||||
return compileTestClasspath_;
|
return compileTestClasspath_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the list of entries for the main compilation module path.
|
||||||
|
* <p>
|
||||||
|
* This is a modifiable list that can be retrieved and changed.
|
||||||
|
*
|
||||||
|
* @return the main compilation module path list
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public List<String> compileMainModulePath() {
|
||||||
|
return compileMainModulePath_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the list of entries for the test compilation module path.
|
||||||
|
* <p>
|
||||||
|
* This is a modifiable list that can be retrieved and changed.
|
||||||
|
*
|
||||||
|
* @return the test compilation module path list
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public List<String> compileTestModulePath() {
|
||||||
|
return compileTestModulePath_;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the list of main files that should be compiled.
|
* Retrieves the list of main files that should be compiled.
|
||||||
* <p>
|
* <p>
|
||||||
|
|
@ -477,4 +631,15 @@ public class CompileOperation extends AbstractOperation<CompileOperation> {
|
||||||
public List<Diagnostic<? extends JavaFileObject>> diagnostics() {
|
public List<Diagnostic<? extends JavaFileObject>> diagnostics() {
|
||||||
return diagnostics_;
|
return diagnostics_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the main class to use if this compilation includes @{code module-info.java}.
|
||||||
|
*
|
||||||
|
* @return the main class to use for the module
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public String moduleMainClass() {
|
||||||
|
return moduleMainClass_;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
26
src/main/java/rife/bld/operations/CreateAppOperation.java
Normal file
26
src/main/java/rife/bld/operations/CreateAppOperation.java
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||||
|
*/
|
||||||
|
package rife.bld.operations;
|
||||||
|
|
||||||
|
import rife.bld.Project;
|
||||||
|
import rife.bld.blueprints.AppProjectBlueprint;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new app project structure.
|
||||||
|
*
|
||||||
|
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||||
|
* @since 1.9
|
||||||
|
*/
|
||||||
|
public class CreateAppOperation extends AbstractCreateOperation<CreateAppOperation, Project> {
|
||||||
|
public CreateAppOperation() {
|
||||||
|
super("bld.app.");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Project createProjectBlueprint() {
|
||||||
|
return new AppProjectBlueprint(new File(workDirectory(), projectName()), packageName(), projectName(), baseName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -21,6 +21,6 @@ public class CreateBaseOperation extends AbstractCreateOperation<CreateBaseOpera
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Project createProjectBlueprint() {
|
protected Project createProjectBlueprint() {
|
||||||
return new BaseProjectBlueprint(new File(workDirectory(), projectName()), packageName(), projectName());
|
return new BaseProjectBlueprint(new File(workDirectory(), projectName()), packageName(), projectName(), baseName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License")
|
|
||||||
*/
|
|
||||||
package rife.bld.operations;
|
|
||||||
|
|
||||||
import rife.bld.Project;
|
|
||||||
import rife.bld.blueprints.BlankProjectBlueprint;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new blank project structure.
|
|
||||||
*
|
|
||||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
|
||||||
* @since 1.5
|
|
||||||
*/
|
|
||||||
public class CreateBlankOperation extends AbstractCreateOperation<CreateBlankOperation, Project> {
|
|
||||||
public CreateBlankOperation() {
|
|
||||||
super("bld.blank.");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Project createProjectBlueprint() {
|
|
||||||
return new BlankProjectBlueprint(new File(workDirectory(), projectName()), packageName(), projectName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -5,7 +5,6 @@
|
||||||
package rife.bld.operations;
|
package rife.bld.operations;
|
||||||
|
|
||||||
import rife.bld.Project;
|
import rife.bld.Project;
|
||||||
import rife.bld.blueprints.BaseProjectBlueprint;
|
|
||||||
import rife.bld.blueprints.LibProjectBlueprint;
|
import rife.bld.blueprints.LibProjectBlueprint;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
@ -22,11 +21,7 @@ public class CreateLibOperation extends AbstractCreateOperation<CreateLibOperati
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Project createProjectBlueprint() {
|
protected Project createProjectBlueprint() {
|
||||||
return new LibProjectBlueprint(new File(workDirectory(), projectName()), packageName(), projectName());
|
return new LibProjectBlueprint(new File(workDirectory(), projectName()), packageName(), projectName(), baseName());
|
||||||
}
|
|
||||||
|
|
||||||
protected String projectMainClassName(String projectClassName) {
|
|
||||||
return projectClassName + "Lib";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean createIdeaRunMain() {
|
protected boolean createIdeaRunMain() {
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ package rife.bld.operations;
|
||||||
import rife.bld.operations.exceptions.OperationOptionException;
|
import rife.bld.operations.exceptions.OperationOptionException;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -16,6 +17,12 @@ import java.util.List;
|
||||||
* @since 1.7
|
* @since 1.7
|
||||||
*/
|
*/
|
||||||
public class CreateOperation {
|
public class CreateOperation {
|
||||||
|
|
||||||
|
private static final String BASE = "base";
|
||||||
|
private static final String APP = "app";
|
||||||
|
private static final String LIB = "lib";
|
||||||
|
private static final String RIFE2 = "rife2";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configures a creation operation from command-line arguments.
|
* Configures a creation operation from command-line arguments.
|
||||||
*
|
*
|
||||||
|
|
@ -27,31 +34,40 @@ public class CreateOperation {
|
||||||
String type = null;
|
String type = null;
|
||||||
String package_name = null;
|
String package_name = null;
|
||||||
String project_name = null;
|
String project_name = null;
|
||||||
if (arguments.size() > 0) {
|
String base_name = null;
|
||||||
|
if (!arguments.isEmpty()) {
|
||||||
type = arguments.remove(0);
|
type = arguments.remove(0);
|
||||||
}
|
}
|
||||||
if (arguments.size() > 0) {
|
|
||||||
|
var create_operation_args = new ArrayList<String>();
|
||||||
|
if (!arguments.isEmpty()) {
|
||||||
package_name = arguments.remove(0);
|
package_name = arguments.remove(0);
|
||||||
|
create_operation_args.add(package_name);
|
||||||
}
|
}
|
||||||
if (arguments.size() > 0) {
|
if (!arguments.isEmpty()) {
|
||||||
project_name = arguments.remove(0);
|
project_name = arguments.remove(0);
|
||||||
|
create_operation_args.add(project_name);
|
||||||
}
|
}
|
||||||
if ((type == null || package_name == null || project_name == null) && System.console() == null) {
|
if (!arguments.isEmpty()) {
|
||||||
throw new OperationOptionException("ERROR: Expecting the type, package and project names as the arguments.");
|
base_name = arguments.remove(0);
|
||||||
|
create_operation_args.add(base_name);
|
||||||
|
}
|
||||||
|
if ((package_name == null || project_name == null || base_name == null) && System.console() == null) {
|
||||||
|
throw new OperationOptionException("ERROR: Expecting the package, project and base names as the arguments.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == null || type.isEmpty()) {
|
if (type == null || type.isBlank()) {
|
||||||
System.out.println("Please enter a number for the project type:");
|
System.out.println("Please enter a number for the project type:");
|
||||||
System.out.println(" 1: base");
|
System.out.printf(" 1: %s (Java baseline project)%n", BASE);
|
||||||
System.out.println(" 2: blank");
|
System.out.printf(" 2: %s (Java application project)%n", APP);
|
||||||
System.out.println(" 3: lib");
|
System.out.printf(" 3: %s (Java library project)%n", LIB);
|
||||||
System.out.println(" 4: rife2");
|
System.out.printf(" 4: %s (RIFE2 web application)%n", RIFE2);
|
||||||
var number = System.console().readLine();
|
var number = System.console().readLine();
|
||||||
switch (Integer.parseInt(number)) {
|
switch (Integer.parseInt(number)) {
|
||||||
case 1 -> type = "base";
|
case 1 -> type = BASE;
|
||||||
case 2 -> type = "blank";
|
case 2 -> type = APP;
|
||||||
case 3 -> type = "lib";
|
case 3 -> type = LIB;
|
||||||
case 4 -> type = "rife2";
|
case 4 -> type = RIFE2;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
System.out.println("Using project type: " + type);
|
System.out.println("Using project type: " + type);
|
||||||
|
|
@ -62,32 +78,15 @@ public class CreateOperation {
|
||||||
|
|
||||||
AbstractCreateOperation<?, ?> create_operation = null;
|
AbstractCreateOperation<?, ?> create_operation = null;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case "base" -> create_operation = new CreateBaseOperation();
|
case BASE -> create_operation = new CreateBaseOperation();
|
||||||
case "blank" -> create_operation = new CreateBlankOperation();
|
case APP -> create_operation = new CreateAppOperation();
|
||||||
case "lib" -> create_operation = new CreateLibOperation();
|
case LIB -> create_operation = new CreateLibOperation();
|
||||||
case "rife2" -> create_operation = new CreateRife2Operation();
|
case RIFE2 -> create_operation = new CreateRife2Operation();
|
||||||
}
|
}
|
||||||
if (create_operation == null) {
|
if (create_operation == null) {
|
||||||
throw new OperationOptionException("ERROR: Unsupported project type.");
|
throw new OperationOptionException("ERROR: Unsupported project type.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (package_name == null || package_name.isEmpty()) {
|
return create_operation.fromArguments(create_operation_args);
|
||||||
System.out.println("Please enter a package name (for instance: com.example):");
|
|
||||||
package_name = System.console().readLine();
|
|
||||||
} else {
|
|
||||||
System.out.println("Using package name: " + package_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (project_name == null || project_name.isEmpty()) {
|
|
||||||
System.out.println("Please enter a project name (for instance: myapp):");
|
|
||||||
project_name = System.console().readLine();
|
|
||||||
} else {
|
|
||||||
System.out.println("Using project name: " + project_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
return create_operation.workDirectory(new File(System.getProperty("user.dir")))
|
|
||||||
.packageName(package_name)
|
|
||||||
.projectName(project_name)
|
|
||||||
.downloadDependencies(true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ package rife.bld.operations;
|
||||||
import rife.bld.blueprints.Rife2ProjectBlueprint;
|
import rife.bld.blueprints.Rife2ProjectBlueprint;
|
||||||
import rife.template.TemplateFactory;
|
import rife.template.TemplateFactory;
|
||||||
import rife.tools.FileUtils;
|
import rife.tools.FileUtils;
|
||||||
|
import rife.tools.StringUtils;
|
||||||
import rife.tools.exceptions.FileUtilsErrorException;
|
import rife.tools.exceptions.FileUtilsErrorException;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
@ -27,14 +28,14 @@ public class CreateRife2Operation extends AbstractCreateOperation<CreateRife2Ope
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Rife2ProjectBlueprint createProjectBlueprint() {
|
protected Rife2ProjectBlueprint createProjectBlueprint() {
|
||||||
return new Rife2ProjectBlueprint(new File(workDirectory(), projectName()), packageName(), projectName());
|
return new Rife2ProjectBlueprint(new File(workDirectory(), projectName()), packageName(), projectName(), baseName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void executeConfigure() {
|
protected void executeConfigure() {
|
||||||
super.executeConfigure();
|
super.executeConfigure();
|
||||||
|
|
||||||
projectMainName_ = projectClassName_ + "Site";
|
projectMainName_ = baseName() + "Site";
|
||||||
projectMainUberName_ = projectMainName_ + "Uber";
|
projectMainUberName_ = projectMainName_ + "Uber";
|
||||||
srcMainWebappCssDirectory_ = new File(project_.srcMainWebappDirectory(), "css");
|
srcMainWebappCssDirectory_ = new File(project_.srcMainWebappDirectory(), "css");
|
||||||
srcMainWebappWebInfDirectory_ = new File(project_.srcMainWebappDirectory(), "WEB-INF");
|
srcMainWebappWebInfDirectory_ = new File(project_.srcMainWebappDirectory(), "WEB-INF");
|
||||||
|
|
@ -63,7 +64,7 @@ public class CreateRife2Operation extends AbstractCreateOperation<CreateRife2Ope
|
||||||
|
|
||||||
// project template
|
// project template
|
||||||
var template_template = TemplateFactory.HTML.get(templateBase_ + "project_template");
|
var template_template = TemplateFactory.HTML.get(templateBase_ + "project_template");
|
||||||
template_template.setValue("project", projectClassName_);
|
template_template.setValue("project", project_.name());
|
||||||
var project_template_file = new File(project_.srcMainResourcesTemplatesDirectory(), "hello.html");
|
var project_template_file = new File(project_.srcMainResourcesTemplatesDirectory(), "hello.html");
|
||||||
FileUtils.writeString(template_template.getContent(), project_template_file);
|
FileUtils.writeString(template_template.getContent(), project_template_file);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,13 +5,19 @@
|
||||||
package rife.bld.operations;
|
package rife.bld.operations;
|
||||||
|
|
||||||
import rife.bld.BaseProject;
|
import rife.bld.BaseProject;
|
||||||
|
import rife.bld.BldCache;
|
||||||
|
import rife.bld.BldVersion;
|
||||||
|
import rife.bld.BuildExecutor;
|
||||||
import rife.bld.dependencies.*;
|
import rife.bld.dependencies.*;
|
||||||
|
import rife.bld.wrapper.Wrapper;
|
||||||
|
import rife.ioc.HierarchicalProperties;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static rife.bld.dependencies.Scope.compile;
|
import static rife.bld.dependencies.Scope.*;
|
||||||
import static rife.bld.dependencies.Scope.runtime;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transitively generates a hierarchical tree of dependencies.
|
* Transitively generates a hierarchical tree of dependencies.
|
||||||
|
|
@ -20,10 +26,17 @@ import static rife.bld.dependencies.Scope.runtime;
|
||||||
* @since 1.5.21
|
* @since 1.5.21
|
||||||
*/
|
*/
|
||||||
public class DependencyTreeOperation extends AbstractOperation<DependencyTreeOperation> {
|
public class DependencyTreeOperation extends AbstractOperation<DependencyTreeOperation> {
|
||||||
|
private boolean offline_ = false;
|
||||||
|
private HierarchicalProperties properties_ = null;
|
||||||
|
private HierarchicalProperties extensionProperties_ = null;
|
||||||
private ArtifactRetriever retriever_ = null;
|
private ArtifactRetriever retriever_ = null;
|
||||||
private final List<Repository> repositories_ = new ArrayList<>();
|
private final List<Repository> repositories_ = new ArrayList<>();
|
||||||
private final DependencyScopes dependencies_ = new DependencyScopes();
|
private final DependencyScopes dependencies_ = new DependencyScopes();
|
||||||
|
private final List<Repository> extensionRepositories_ = new ArrayList<>();
|
||||||
|
private final DependencyScopes extensionDependencies_ = new DependencyScopes();
|
||||||
|
|
||||||
private final StringBuilder dependencyTree_ = new StringBuilder();
|
private final StringBuilder dependencyTree_ = new StringBuilder();
|
||||||
|
private File libBldDir_ = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs the dependency tree operation.
|
* Performs the dependency tree operation.
|
||||||
|
|
@ -31,16 +44,132 @@ public class DependencyTreeOperation extends AbstractOperation<DependencyTreeOpe
|
||||||
* @since 1.5.21
|
* @since 1.5.21
|
||||||
*/
|
*/
|
||||||
public void execute() {
|
public void execute() {
|
||||||
var compile_tree = executeGenerateCompileDependencies();
|
if (offline_) {
|
||||||
var runtime_tree = executeGenerateRuntimeDependencies();
|
System.out.println("Offline mode: dependency-tree is disabled");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate the dependency tree of the extensions, using the cache if possible
|
||||||
|
|
||||||
|
String extensions_tree = null;
|
||||||
|
BldCache extensions_cache = null;
|
||||||
|
if (libBldDir_ != null) {
|
||||||
|
extensions_cache = new BldCache(libBldDir_, new VersionResolution(extensionProperties()));
|
||||||
|
extensions_cache.cacheExtensionsHash(
|
||||||
|
extensionRepositories().stream().map(Repository::toString).toList(),
|
||||||
|
extensionDependencies().scope(compile).stream().map(Dependency::toString).toList());
|
||||||
|
if (extensions_cache.isExtensionsHashValid()) {
|
||||||
|
var cached_tree = extensions_cache.getCachedExtensionsDependencyTree();
|
||||||
|
if (cached_tree != null) {
|
||||||
|
extensions_tree = cached_tree;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (extensions_tree == null) {
|
||||||
|
extensions_tree = executeGenerateExtensionsDependencies();
|
||||||
|
if (extensions_cache != null) {
|
||||||
|
extensions_cache.cacheExtensionsDependencyTree(extensions_tree);
|
||||||
|
extensions_cache.writeCache();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate the dependency tree of the dependencies, using the cache if possible
|
||||||
|
|
||||||
|
String compile_tree = null;
|
||||||
|
String provided_tree = null;
|
||||||
|
String runtime_tree = null;
|
||||||
|
String test_tree = null;
|
||||||
|
BldCache dependencies_cache = null;
|
||||||
|
if (libBldDir_ != null) {
|
||||||
|
dependencies_cache = new BldCache(libBldDir_, new VersionResolution(properties()));
|
||||||
|
dependencies_cache.cacheDependenciesHash(repositories(), dependencies());
|
||||||
|
if (dependencies_cache.isDependenciesHashValid()) {
|
||||||
|
var cached_compile_tree = dependencies_cache.getCachedDependenciesCompileDependencyTree();
|
||||||
|
if (cached_compile_tree != null) {
|
||||||
|
compile_tree = cached_compile_tree;
|
||||||
|
}
|
||||||
|
var cached_provided_tree = dependencies_cache.getCachedDependenciesProvidedDependencyTree();
|
||||||
|
if (cached_provided_tree != null) {
|
||||||
|
provided_tree = cached_provided_tree;
|
||||||
|
}
|
||||||
|
var cached_runtime_tree = dependencies_cache.getCachedDependenciesRuntimeDependencyTree();
|
||||||
|
if (cached_runtime_tree != null) {
|
||||||
|
runtime_tree = cached_runtime_tree;
|
||||||
|
}
|
||||||
|
var cached_test_tree = dependencies_cache.getCachedDependenciesTestDependencyTree();
|
||||||
|
if (cached_test_tree != null) {
|
||||||
|
test_tree = cached_test_tree;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var write_dependencies_cache = false;
|
||||||
|
if (compile_tree == null) {
|
||||||
|
compile_tree = executeGenerateCompileDependencies();
|
||||||
|
if (dependencies_cache != null) {
|
||||||
|
dependencies_cache.cacheDependenciesCompileDependencyTree(compile_tree);
|
||||||
|
write_dependencies_cache = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (provided_tree == null) {
|
||||||
|
provided_tree = executeGenerateProvidedDependencies();
|
||||||
|
if (dependencies_cache != null) {
|
||||||
|
dependencies_cache.cacheDependenciesProvidedDependencyTree(provided_tree);
|
||||||
|
write_dependencies_cache = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (runtime_tree == null) {
|
||||||
|
runtime_tree = executeGenerateRuntimeDependencies();
|
||||||
|
if (dependencies_cache != null) {
|
||||||
|
dependencies_cache.cacheDependenciesRuntimeDependencyTree(runtime_tree);
|
||||||
|
write_dependencies_cache = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (test_tree == null) {
|
||||||
|
test_tree = executeGenerateTestDependencies();
|
||||||
|
if (dependencies_cache != null) {
|
||||||
|
dependencies_cache.cacheDependenciesTestDependencyTree(test_tree);
|
||||||
|
write_dependencies_cache = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (write_dependencies_cache) {
|
||||||
|
dependencies_cache.writeCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
// output the dependency trees
|
||||||
|
|
||||||
dependencyTree_.setLength(0);
|
dependencyTree_.setLength(0);
|
||||||
|
dependencyTree_.append(extensions_tree);
|
||||||
|
dependencyTree_.append(System.lineSeparator());
|
||||||
dependencyTree_.append(compile_tree);
|
dependencyTree_.append(compile_tree);
|
||||||
dependencyTree_.append(System.lineSeparator());
|
dependencyTree_.append(System.lineSeparator());
|
||||||
|
dependencyTree_.append(provided_tree);
|
||||||
|
dependencyTree_.append(System.lineSeparator());
|
||||||
dependencyTree_.append(runtime_tree);
|
dependencyTree_.append(runtime_tree);
|
||||||
dependencyTree_.append(System.lineSeparator());
|
dependencyTree_.append(System.lineSeparator());
|
||||||
|
dependencyTree_.append(test_tree);
|
||||||
|
dependencyTree_.append(System.lineSeparator());
|
||||||
|
|
||||||
|
System.out.println(extensions_tree);
|
||||||
System.out.println(compile_tree);
|
System.out.println(compile_tree);
|
||||||
|
System.out.println(provided_tree);
|
||||||
System.out.println(runtime_tree);
|
System.out.println(runtime_tree);
|
||||||
|
System.out.println(test_tree);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Part of the {@link #execute} operation, generates the tree for the extensions.
|
||||||
|
*
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
protected String executeGenerateExtensionsDependencies() {
|
||||||
|
var extensions_tree = extensionDependencies().scope(compile).generateTransitiveDependencyTree(new VersionResolution(extensionProperties()), artifactRetriever(), extensionRepositories(), compile, runtime);
|
||||||
|
if (extensions_tree.isEmpty()) {
|
||||||
|
extensions_tree = "no dependencies" + System.lineSeparator();
|
||||||
|
}
|
||||||
|
return "extensions:" + System.lineSeparator() + extensions_tree;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -49,26 +178,52 @@ public class DependencyTreeOperation extends AbstractOperation<DependencyTreeOpe
|
||||||
* @since 1.5.21
|
* @since 1.5.21
|
||||||
*/
|
*/
|
||||||
protected String executeGenerateCompileDependencies() {
|
protected String executeGenerateCompileDependencies() {
|
||||||
var compile_tree = dependencies().scope(compile).generateTransitiveDependencyTree(artifactRetriever(), repositories(), compile);
|
var compile_tree = dependencies().scope(compile).generateTransitiveDependencyTree(new VersionResolution(properties()), artifactRetriever(), repositories(), compile);
|
||||||
if (compile_tree.isEmpty()) {
|
if (compile_tree.isEmpty()) {
|
||||||
compile_tree = "no dependencies" + System.lineSeparator();
|
compile_tree = "no dependencies" + System.lineSeparator();
|
||||||
}
|
}
|
||||||
return "compile:" + System.lineSeparator() + compile_tree;
|
return "compile:" + System.lineSeparator() + compile_tree;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Part of the {@link #execute} operation, generates the tree for the provided scope.
|
||||||
|
*
|
||||||
|
* @since 1.7.3
|
||||||
|
*/
|
||||||
|
protected String executeGenerateProvidedDependencies() {
|
||||||
|
var provided_tree = dependencies().scope(provided).generateTransitiveDependencyTree(new VersionResolution(properties()), artifactRetriever(), repositories(), compile, runtime);
|
||||||
|
if (provided_tree.isEmpty()) {
|
||||||
|
provided_tree = "no dependencies" + System.lineSeparator();
|
||||||
|
}
|
||||||
|
return "provided:" + System.lineSeparator() + provided_tree;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Part of the {@link #execute} operation, generates the tree for the runtime scope.
|
* Part of the {@link #execute} operation, generates the tree for the runtime scope.
|
||||||
*
|
*
|
||||||
* @since 1.5.21
|
* @since 1.5.21
|
||||||
*/
|
*/
|
||||||
protected String executeGenerateRuntimeDependencies() {
|
protected String executeGenerateRuntimeDependencies() {
|
||||||
var runtime_tree = dependencies().scope(runtime).generateTransitiveDependencyTree(artifactRetriever(), repositories(), compile, runtime);
|
var runtime_tree = dependencies().scope(runtime).generateTransitiveDependencyTree(new VersionResolution(properties()), artifactRetriever(), repositories(), compile, runtime);
|
||||||
if (runtime_tree.isEmpty()) {
|
if (runtime_tree.isEmpty()) {
|
||||||
runtime_tree = "no dependencies" + System.lineSeparator();
|
runtime_tree = "no dependencies" + System.lineSeparator();
|
||||||
}
|
}
|
||||||
return "runtime:" + System.lineSeparator() + runtime_tree;
|
return "runtime:" + System.lineSeparator() + runtime_tree;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Part of the {@link #execute} operation, generates the tree for the test scope.
|
||||||
|
*
|
||||||
|
* @since 1.7.3
|
||||||
|
*/
|
||||||
|
protected String executeGenerateTestDependencies() {
|
||||||
|
var test_tree = dependencies().scope(test).generateTransitiveDependencyTree(new VersionResolution(properties()), artifactRetriever(), repositories(), compile, runtime);
|
||||||
|
if (test_tree.isEmpty()) {
|
||||||
|
test_tree = "no dependencies" + System.lineSeparator();
|
||||||
|
}
|
||||||
|
return "test:" + System.lineSeparator() + test_tree;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configures a dependency tree operation from a {@link BaseProject}.
|
* Configures a dependency tree operation from a {@link BaseProject}.
|
||||||
|
|
@ -77,11 +232,59 @@ public class DependencyTreeOperation extends AbstractOperation<DependencyTreeOpe
|
||||||
* @since 1.5.21
|
* @since 1.5.21
|
||||||
*/
|
*/
|
||||||
public DependencyTreeOperation fromProject(BaseProject project) {
|
public DependencyTreeOperation fromProject(BaseProject project) {
|
||||||
return artifactRetriever(project.artifactRetriever())
|
libBldDir_ = project.libBldDirectory();
|
||||||
|
|
||||||
|
// add the repositories and dependencies from the extensions
|
||||||
|
var wrapper = new Wrapper();
|
||||||
|
wrapper.currentDir(project.workDirectory());
|
||||||
|
try {
|
||||||
|
wrapper.initWrapperProperties(BldVersion.getVersion());
|
||||||
|
|
||||||
|
var extension_properties = BuildExecutor.setupProperties(project.workDirectory());
|
||||||
|
extension_properties = new HierarchicalProperties().parent(extension_properties);
|
||||||
|
extension_properties.putAll(wrapper.wrapperProperties());
|
||||||
|
extensionProperties(extension_properties);
|
||||||
|
|
||||||
|
for (var repository : wrapper.repositories()) {
|
||||||
|
extensionRepositories().add(Repository.resolveRepository(extensionProperties(), repository));
|
||||||
|
}
|
||||||
|
extensionDependencies().scope(compile).addAll(wrapper.extensions().stream().map(Dependency::parse).toList());
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// add the repositories and the dependencies from the project
|
||||||
|
return offline(project.offline())
|
||||||
|
.properties(project.properties())
|
||||||
|
.artifactRetriever(project.artifactRetriever())
|
||||||
.repositories(project.repositories())
|
.repositories(project.repositories())
|
||||||
.dependencies(project.dependencies());
|
.dependencies(project.dependencies());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether the operation has to run offline.
|
||||||
|
*
|
||||||
|
* @param flag {@code true} if the operation runs offline; or
|
||||||
|
* {@code false} otherwise
|
||||||
|
* @return this operation instance
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public DependencyTreeOperation offline(boolean flag) {
|
||||||
|
offline_ = flag;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the operation has to run offline.
|
||||||
|
*
|
||||||
|
* @return {@code true} if the operation runs offline; or
|
||||||
|
* {@code false} otherwise
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public boolean offline() {
|
||||||
|
return offline_;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides repositories to resolve the dependencies against.
|
* Provides repositories to resolve the dependencies against.
|
||||||
*
|
*
|
||||||
|
|
@ -120,6 +323,44 @@ public class DependencyTreeOperation extends AbstractOperation<DependencyTreeOpe
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides extension repositories to resolve the extension dependencies against.
|
||||||
|
*
|
||||||
|
* @param repositories extension repositories against which extension dependencies will be resolved
|
||||||
|
* @return this operation instance
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public DependencyTreeOperation extensionRepositories(Repository... repositories) {
|
||||||
|
extensionRepositories_.addAll(List.of(repositories));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides a list of extension repositories to resolve the extension dependencies against.
|
||||||
|
* <p>
|
||||||
|
* A copy will be created to allow this list to be independently modifiable.
|
||||||
|
*
|
||||||
|
* @param repositories a list of extension repositories against which extension dependencies will be resolved
|
||||||
|
* @return this operation instance
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public DependencyTreeOperation extensionRepositories(List<Repository> repositories) {
|
||||||
|
extensionRepositories_.addAll(repositories);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides scoped extension dependencies to generate a tree for.
|
||||||
|
*
|
||||||
|
* @param dependencies the extension dependencies that will be resolved for tree generation
|
||||||
|
* @return this operation instance
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public DependencyTreeOperation extensionDependencies(DependencyScopes dependencies) {
|
||||||
|
extensionDependencies_.include(dependencies);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the artifact retriever to use.
|
* Provides the artifact retriever to use.
|
||||||
*
|
*
|
||||||
|
|
@ -132,6 +373,30 @@ public class DependencyTreeOperation extends AbstractOperation<DependencyTreeOpe
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the hierarchical properties to use.
|
||||||
|
*
|
||||||
|
* @param properties the hierarchical properties
|
||||||
|
* @return this operation instance
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public DependencyTreeOperation properties(HierarchicalProperties properties) {
|
||||||
|
properties_ = properties;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the extension hierarchical properties to use.
|
||||||
|
*
|
||||||
|
* @param properties the extension hierarchical properties
|
||||||
|
* @return this operation instance
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public DependencyTreeOperation extensionProperties(HierarchicalProperties properties) {
|
||||||
|
extensionProperties_ = properties;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the repositories in which the dependencies will be resolved.
|
* Retrieves the repositories in which the dependencies will be resolved.
|
||||||
* <p>
|
* <p>
|
||||||
|
|
@ -156,6 +421,30 @@ public class DependencyTreeOperation extends AbstractOperation<DependencyTreeOpe
|
||||||
return dependencies_;
|
return dependencies_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the extension repositories in which the dependencies will be resolved.
|
||||||
|
* <p>
|
||||||
|
* This is a modifiable list that can be retrieved and changed.
|
||||||
|
*
|
||||||
|
* @return the extension repositories used for dependency resolution
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public List<Repository> extensionRepositories() {
|
||||||
|
return extensionRepositories_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the scoped extension dependencies that will be used for tree generation.
|
||||||
|
* <p>
|
||||||
|
* This is a modifiable structure that can be retrieved and changed.
|
||||||
|
*
|
||||||
|
* @return the scoped extension dependencies
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public DependencyScopes extensionDependencies() {
|
||||||
|
return extensionDependencies_;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the artifact retriever that is used.
|
* Returns the artifact retriever that is used.
|
||||||
*
|
*
|
||||||
|
|
@ -178,4 +467,30 @@ public class DependencyTreeOperation extends AbstractOperation<DependencyTreeOpe
|
||||||
public String dependencyTree() {
|
public String dependencyTree() {
|
||||||
return dependencyTree_.toString();
|
return dependencyTree_.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the hierarchical properties that are used.
|
||||||
|
*
|
||||||
|
* @return the hierarchical properties
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public HierarchicalProperties properties() {
|
||||||
|
if (properties_ == null) {
|
||||||
|
properties_ = new HierarchicalProperties();
|
||||||
|
}
|
||||||
|
return properties_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the extension hierarchical properties that are used.
|
||||||
|
*
|
||||||
|
* @return the extension hierarchical properties
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public HierarchicalProperties extensionProperties() {
|
||||||
|
if (extensionProperties_ == null) {
|
||||||
|
extensionProperties_ = new HierarchicalProperties();
|
||||||
|
}
|
||||||
|
return extensionProperties_;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ package rife.bld.operations;
|
||||||
|
|
||||||
import rife.bld.BaseProject;
|
import rife.bld.BaseProject;
|
||||||
import rife.bld.dependencies.*;
|
import rife.bld.dependencies.*;
|
||||||
|
import rife.ioc.HierarchicalProperties;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
@ -24,13 +25,21 @@ import static rife.bld.dependencies.Dependency.CLASSIFIER_SOURCES;
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
public class DownloadOperation extends AbstractOperation<DownloadOperation> {
|
public class DownloadOperation extends AbstractOperation<DownloadOperation> {
|
||||||
|
private boolean offline_ = false;
|
||||||
|
private HierarchicalProperties properties_ = null;
|
||||||
private ArtifactRetriever retriever_ = null;
|
private ArtifactRetriever retriever_ = null;
|
||||||
private final List<Repository> repositories_ = new ArrayList<>();
|
private final List<Repository> repositories_ = new ArrayList<>();
|
||||||
private final DependencyScopes dependencies_ = new DependencyScopes();
|
private final DependencyScopes dependencies_ = new DependencyScopes();
|
||||||
private File libCompileDirectory_;
|
private File libCompileDirectory_;
|
||||||
|
private File libCompileModulesDirectory_;
|
||||||
|
private File libProvidedDirectory_;
|
||||||
|
private File libProvidedModulesDirectory_;
|
||||||
private File libRuntimeDirectory_;
|
private File libRuntimeDirectory_;
|
||||||
|
private File libRuntimeModulesDirectory_;
|
||||||
private File libStandaloneDirectory_;
|
private File libStandaloneDirectory_;
|
||||||
|
private File libStandaloneModulesDirectory_;
|
||||||
private File libTestDirectory_;
|
private File libTestDirectory_;
|
||||||
|
private File libTestModulesDirectory_;
|
||||||
private boolean downloadSources_ = false;
|
private boolean downloadSources_ = false;
|
||||||
private boolean downloadJavadoc_ = false;
|
private boolean downloadJavadoc_ = false;
|
||||||
|
|
||||||
|
|
@ -40,7 +49,13 @@ public class DownloadOperation extends AbstractOperation<DownloadOperation> {
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
public void execute() {
|
public void execute() {
|
||||||
|
if (offline_) {
|
||||||
|
System.out.println("Offline mode: download is disabled");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
executeDownloadCompileDependencies();
|
executeDownloadCompileDependencies();
|
||||||
|
executeDownloadProvidedDependencies();
|
||||||
executeDownloadRuntimeDependencies();
|
executeDownloadRuntimeDependencies();
|
||||||
executeDownloadStandaloneDependencies();
|
executeDownloadStandaloneDependencies();
|
||||||
executeDownloadTestDependencies();
|
executeDownloadTestDependencies();
|
||||||
|
|
@ -55,7 +70,16 @@ public class DownloadOperation extends AbstractOperation<DownloadOperation> {
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
protected void executeDownloadCompileDependencies() {
|
protected void executeDownloadCompileDependencies() {
|
||||||
executeDownloadDependencies(libCompileDirectory(), dependencies().resolveCompileDependencies(artifactRetriever(), repositories()));
|
executeDownloadDependencies(libCompileDirectory(), libCompileModulesDirectory(), dependencies().resolveCompileDependencies(properties(), artifactRetriever(), repositories()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Part of the {@link #execute} operation, download the {@code provided} scope artifacts.
|
||||||
|
*
|
||||||
|
* @since 1.8
|
||||||
|
*/
|
||||||
|
protected void executeDownloadProvidedDependencies() {
|
||||||
|
executeDownloadDependencies(libProvidedDirectory(), libProvidedModulesDirectory(), dependencies().resolveProvidedDependencies(properties(), artifactRetriever(), repositories()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -64,7 +88,7 @@ public class DownloadOperation extends AbstractOperation<DownloadOperation> {
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
protected void executeDownloadRuntimeDependencies() {
|
protected void executeDownloadRuntimeDependencies() {
|
||||||
executeDownloadDependencies(libRuntimeDirectory(), dependencies().resolveRuntimeDependencies(artifactRetriever(), repositories()));
|
executeDownloadDependencies(libRuntimeDirectory(), libRuntimeModulesDirectory(), dependencies().resolveRuntimeDependencies(properties(), artifactRetriever(), repositories()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -73,7 +97,7 @@ public class DownloadOperation extends AbstractOperation<DownloadOperation> {
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
protected void executeDownloadStandaloneDependencies() {
|
protected void executeDownloadStandaloneDependencies() {
|
||||||
executeDownloadDependencies(libStandaloneDirectory(), dependencies().resolveStandaloneDependencies(artifactRetriever(), repositories()));
|
executeDownloadDependencies(libStandaloneDirectory(), libStandaloneModulesDirectory(), dependencies().resolveStandaloneDependencies(properties(), artifactRetriever(), repositories()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -82,23 +106,18 @@ public class DownloadOperation extends AbstractOperation<DownloadOperation> {
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
protected void executeDownloadTestDependencies() {
|
protected void executeDownloadTestDependencies() {
|
||||||
executeDownloadDependencies(libTestDirectory(), dependencies().resolveTestDependencies(artifactRetriever(), repositories()));
|
executeDownloadDependencies(libTestDirectory(), libTestModulesDirectory(), dependencies().resolveTestDependencies(properties(), artifactRetriever(), repositories()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Part of the {@link #execute} operation, download the artifacts for a particular dependency scope.
|
* Part of the {@link #execute} operation, download the artifacts for a particular dependency scope.
|
||||||
*
|
*
|
||||||
* @param destinationDirectory the directory in which the artifacts should be downloaded
|
* @param destinationDirectory the directory in which the artifacts should be downloaded
|
||||||
|
* @param modulesDirectory the directory in which the modules should be downloaded
|
||||||
* @param dependencies the dependencies to download
|
* @param dependencies the dependencies to download
|
||||||
* @since 1.6
|
* @since 2.1
|
||||||
*/
|
*/
|
||||||
protected void executeDownloadDependencies(File destinationDirectory, DependencySet dependencies) {
|
protected void executeDownloadDependencies(File destinationDirectory, File modulesDirectory, DependencySet dependencies) {
|
||||||
if (destinationDirectory == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
destinationDirectory.mkdirs();
|
|
||||||
|
|
||||||
var additional_classifiers = new String[0];
|
var additional_classifiers = new String[0];
|
||||||
|
|
||||||
if (downloadSources_ || downloadJavadoc_) {
|
if (downloadSources_ || downloadJavadoc_) {
|
||||||
|
|
@ -109,27 +128,60 @@ public class DownloadOperation extends AbstractOperation<DownloadOperation> {
|
||||||
additional_classifiers = classifiers.toArray(new String[0]);
|
additional_classifiers = classifiers.toArray(new String[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies.transferIntoDirectory(artifactRetriever(), repositories(), destinationDirectory, additional_classifiers);
|
dependencies.transferIntoDirectory(new VersionResolution(properties()), artifactRetriever(), repositories(), destinationDirectory, modulesDirectory, additional_classifiers);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configures a compile operation from a {@link BaseProject}.
|
* Configures a compile operation from a {@link BaseProject}.
|
||||||
*
|
*
|
||||||
* @param project the project to configure the compile operation from
|
* @param project the project to configure the compile operation from
|
||||||
|
* @return this operation instance
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
public DownloadOperation fromProject(BaseProject project) {
|
public DownloadOperation fromProject(BaseProject project) {
|
||||||
return artifactRetriever(project.artifactRetriever())
|
return offline(project.offline())
|
||||||
|
.properties(project.properties())
|
||||||
|
.artifactRetriever(project.artifactRetriever())
|
||||||
.repositories(project.repositories())
|
.repositories(project.repositories())
|
||||||
.dependencies(project.dependencies())
|
.dependencies(project.dependencies())
|
||||||
.libCompileDirectory(project.libCompileDirectory())
|
.libCompileDirectory(project.libCompileDirectory())
|
||||||
|
.libCompileModulesDirectory(project.libCompileModulesDirectory())
|
||||||
|
.libProvidedDirectory(project.libProvidedDirectory())
|
||||||
|
.libProvidedModulesDirectory(project.libProvidedModulesDirectory())
|
||||||
.libRuntimeDirectory(project.libRuntimeDirectory())
|
.libRuntimeDirectory(project.libRuntimeDirectory())
|
||||||
|
.libRuntimeModulesDirectory(project.libRuntimeModulesDirectory())
|
||||||
.libStandaloneDirectory(project.libStandaloneDirectory())
|
.libStandaloneDirectory(project.libStandaloneDirectory())
|
||||||
|
.libStandaloneModulesDirectory(project.libStandaloneModulesDirectory())
|
||||||
.libTestDirectory(project.libTestDirectory())
|
.libTestDirectory(project.libTestDirectory())
|
||||||
|
.libTestModulesDirectory(project.libTestModulesDirectory())
|
||||||
.downloadSources(project.downloadSources())
|
.downloadSources(project.downloadSources())
|
||||||
.downloadJavadoc(project.downloadJavadoc());
|
.downloadJavadoc(project.downloadJavadoc());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether the operation has to run offline.
|
||||||
|
*
|
||||||
|
* @param flag {@code true} if the operation runs offline; or
|
||||||
|
* {@code false} otherwise
|
||||||
|
* @return this operation instance
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public DownloadOperation offline(boolean flag) {
|
||||||
|
offline_ = flag;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the operation has to run offline.
|
||||||
|
*
|
||||||
|
* @return {@code true} if the operation runs offline; or
|
||||||
|
* {@code false} otherwise
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public boolean offline() {
|
||||||
|
return offline_;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides repositories to resolve the dependencies against.
|
* Provides repositories to resolve the dependencies against.
|
||||||
*
|
*
|
||||||
|
|
@ -180,6 +232,42 @@ public class DownloadOperation extends AbstractOperation<DownloadOperation> {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the {@code compile} scope modules download directory.
|
||||||
|
*
|
||||||
|
* @param directory the directory to download the {@code compile} scope modules into
|
||||||
|
* @return this operation instance
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public DownloadOperation libCompileModulesDirectory(File directory) {
|
||||||
|
libCompileModulesDirectory_ = directory;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the {@code provided} scope download directory.
|
||||||
|
*
|
||||||
|
* @param directory the directory to download the {@code provided} scope artifacts into
|
||||||
|
* @return this operation instance
|
||||||
|
* @since 1.8
|
||||||
|
*/
|
||||||
|
public DownloadOperation libProvidedDirectory(File directory) {
|
||||||
|
libProvidedDirectory_ = directory;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the {@code provided} scope modules download directory.
|
||||||
|
*
|
||||||
|
* @param directory the directory to download the {@code provided} scope modules into
|
||||||
|
* @return this operation instance
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public DownloadOperation libProvidedModulesDirectory(File directory) {
|
||||||
|
libProvidedModulesDirectory_ = directory;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the {@code runtime} scope download directory.
|
* Provides the {@code runtime} scope download directory.
|
||||||
*
|
*
|
||||||
|
|
@ -192,6 +280,18 @@ public class DownloadOperation extends AbstractOperation<DownloadOperation> {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the {@code runtime} scope modules download directory.
|
||||||
|
*
|
||||||
|
* @param directory the directory to download the {@code runtime} scope modules into
|
||||||
|
* @return this operation instance
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public DownloadOperation libRuntimeModulesDirectory(File directory) {
|
||||||
|
libRuntimeModulesDirectory_ = directory;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the {@code standalone} scope download directory.
|
* Provides the {@code standalone} scope download directory.
|
||||||
*
|
*
|
||||||
|
|
@ -204,6 +304,18 @@ public class DownloadOperation extends AbstractOperation<DownloadOperation> {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the {@code standalone} scope modules download directory.
|
||||||
|
*
|
||||||
|
* @param directory the directory to download the {@code standalone} scope modules into
|
||||||
|
* @return this operation instance
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public DownloadOperation libStandaloneModulesDirectory(File directory) {
|
||||||
|
libStandaloneModulesDirectory_ = directory;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the {@code test} scope download directory.
|
* Provides the {@code test} scope download directory.
|
||||||
*
|
*
|
||||||
|
|
@ -216,6 +328,18 @@ public class DownloadOperation extends AbstractOperation<DownloadOperation> {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the {@code test} scope modules download directory.
|
||||||
|
*
|
||||||
|
* @param directory the directory to download the {@code test} scope modules into
|
||||||
|
* @return this operation instance
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public DownloadOperation libTestModulesDirectory(File directory) {
|
||||||
|
libTestModulesDirectory_ = directory;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates whether the sources classifier should also be downloaded.
|
* Indicates whether the sources classifier should also be downloaded.
|
||||||
*
|
*
|
||||||
|
|
@ -254,6 +378,18 @@ public class DownloadOperation extends AbstractOperation<DownloadOperation> {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the hierarchical properties to use.
|
||||||
|
*
|
||||||
|
* @param properties the hierarchical properties
|
||||||
|
* @return this operation instance
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public DownloadOperation properties(HierarchicalProperties properties) {
|
||||||
|
properties_ = properties;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the repositories in which the dependencies will be resolved.
|
* Retrieves the repositories in which the dependencies will be resolved.
|
||||||
* <p>
|
* <p>
|
||||||
|
|
@ -288,6 +424,36 @@ public class DownloadOperation extends AbstractOperation<DownloadOperation> {
|
||||||
return libCompileDirectory_;
|
return libCompileDirectory_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the {@code compile} scope modules download directory.
|
||||||
|
*
|
||||||
|
* @return the {@code compile} scope modules download directory
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public File libCompileModulesDirectory() {
|
||||||
|
return libCompileModulesDirectory_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the {@code provided} scope download directory.
|
||||||
|
*
|
||||||
|
* @return the {@code provided} scope download directory
|
||||||
|
* @since 1.8
|
||||||
|
*/
|
||||||
|
public File libProvidedDirectory() {
|
||||||
|
return libProvidedDirectory_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the {@code provided} scope modules download directory.
|
||||||
|
*
|
||||||
|
* @return the {@code provided} scope modules download directory
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public File libProvidedModulesDirectory() {
|
||||||
|
return libProvidedModulesDirectory_;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the {@code runtime} scope download directory.
|
* Retrieves the {@code runtime} scope download directory.
|
||||||
*
|
*
|
||||||
|
|
@ -298,6 +464,16 @@ public class DownloadOperation extends AbstractOperation<DownloadOperation> {
|
||||||
return libRuntimeDirectory_;
|
return libRuntimeDirectory_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the {@code runtime} scope modules download directory.
|
||||||
|
*
|
||||||
|
* @return the {@code runtime} scope modules download directory
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public File libRuntimeModulesDirectory() {
|
||||||
|
return libRuntimeModulesDirectory_;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the {@code standalone} scope download directory.
|
* Retrieves the {@code standalone} scope download directory.
|
||||||
*
|
*
|
||||||
|
|
@ -308,6 +484,16 @@ public class DownloadOperation extends AbstractOperation<DownloadOperation> {
|
||||||
return libStandaloneDirectory_;
|
return libStandaloneDirectory_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the {@code standalone} scope modules download directory.
|
||||||
|
*
|
||||||
|
* @return the {@code standalone} scope modules download directory
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public File libStandaloneModulesDirectory() {
|
||||||
|
return libStandaloneModulesDirectory_;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the {@code test} scope download directory.
|
* Retrieves the {@code test} scope download directory.
|
||||||
*
|
*
|
||||||
|
|
@ -318,6 +504,16 @@ public class DownloadOperation extends AbstractOperation<DownloadOperation> {
|
||||||
return libTestDirectory_;
|
return libTestDirectory_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the {@code test} scope modules download directory.
|
||||||
|
*
|
||||||
|
* @return the {@code test} scope modules download directory
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public File libTestModulesDirectory() {
|
||||||
|
return libTestModulesDirectory_;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves whether the sources classifier should also be downloaded.
|
* Retrieves whether the sources classifier should also be downloaded.
|
||||||
*
|
*
|
||||||
|
|
@ -352,4 +548,17 @@ public class DownloadOperation extends AbstractOperation<DownloadOperation> {
|
||||||
}
|
}
|
||||||
return retriever_;
|
return retriever_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the hierarchical properties that are used.
|
||||||
|
*
|
||||||
|
* @return the hierarchical properties
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public HierarchicalProperties properties() {
|
||||||
|
if (properties_ == null) {
|
||||||
|
properties_ = new HierarchicalProperties();
|
||||||
|
}
|
||||||
|
return properties_;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,8 @@ package rife.bld.operations;
|
||||||
|
|
||||||
import rife.bld.BldVersion;
|
import rife.bld.BldVersion;
|
||||||
import rife.bld.BuildExecutor;
|
import rife.bld.BuildExecutor;
|
||||||
|
import rife.template.TemplateFactory;
|
||||||
|
import rife.tools.ExceptionUtils;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
|
@ -18,8 +20,11 @@ import static java.util.Comparator.comparingInt;
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
public class HelpOperation {
|
public class HelpOperation {
|
||||||
|
private static final String JSON_ARGUMENT = "--json";
|
||||||
|
|
||||||
private final BuildExecutor executor_;
|
private final BuildExecutor executor_;
|
||||||
private final List<String> arguments_;
|
private final List<String> arguments_;
|
||||||
|
private boolean outputJson_ = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new help operation.
|
* Creates a new help operation.
|
||||||
|
|
@ -41,51 +46,116 @@ public class HelpOperation {
|
||||||
public void execute() {
|
public void execute() {
|
||||||
var topic = "";
|
var topic = "";
|
||||||
if (!arguments_.isEmpty()) {
|
if (!arguments_.isEmpty()) {
|
||||||
topic = arguments_.remove(0);
|
if (arguments_.get(0).equals(JSON_ARGUMENT)) {
|
||||||
|
arguments_.remove(0);
|
||||||
|
outputJson_ = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
topic = arguments_.remove(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!arguments_.isEmpty() && arguments_.get(0).equals(JSON_ARGUMENT)) {
|
||||||
|
arguments_.remove(0);
|
||||||
|
outputJson_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
System.err.println("Welcome to bld " + BldVersion.getVersion() + ".");
|
if (!outputJson_) {
|
||||||
System.err.println();
|
executePrintWelcome();
|
||||||
|
}
|
||||||
|
|
||||||
boolean print_full_help = true;
|
var print_full_help = true;
|
||||||
|
Exception exception = null;
|
||||||
try {
|
try {
|
||||||
var commands = executor_.buildCommands();
|
var commands = executor_.buildCommands();
|
||||||
if (commands.containsKey(topic)) {
|
if (commands.containsKey(topic)) {
|
||||||
var command = commands.get(topic);
|
var command = commands.get(topic);
|
||||||
var help = command.getHelp().getDescription(topic);
|
var help = command.getHelp().getDescription(topic);
|
||||||
if (!help.isEmpty()) {
|
if (!help.isEmpty()) {
|
||||||
System.err.println(help);
|
if (outputJson_) {
|
||||||
|
var t = TemplateFactory.JSON.get("bld.help_description");
|
||||||
|
t.setValueEncoded("command", topic);
|
||||||
|
t.setValueEncoded("description", help);
|
||||||
|
System.out.print(t.getContent());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
System.err.println(help);
|
||||||
|
}
|
||||||
print_full_help = false;
|
print_full_help = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
exception = e;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (print_full_help) {
|
if (print_full_help) {
|
||||||
executePrintOverviewHelp();
|
executePrintOverviewHelp(exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void executePrintOverviewHelp(Exception exception) {
|
||||||
|
if (outputJson_) {
|
||||||
|
var t = TemplateFactory.JSON.get("bld.help_commands");
|
||||||
|
|
||||||
|
if (exception != null) {
|
||||||
|
t.setValueEncoded("error-message", ExceptionUtils.getExceptionStackTrace(exception));
|
||||||
|
}
|
||||||
|
|
||||||
|
var commands = executor_.buildCommands();
|
||||||
|
for (var command : commands.entrySet()) {
|
||||||
|
if (t.isValueSet("commands")) {
|
||||||
|
t.setValue("separator", ", ");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
t.blankValue("separator");
|
||||||
|
}
|
||||||
|
t.setValueEncoded("command", command.getKey());
|
||||||
|
var build_help = command.getValue().getHelp();
|
||||||
|
t.setValueEncoded("summary", build_help.getSummary());
|
||||||
|
t.appendBlock("commands", "command");
|
||||||
|
}
|
||||||
|
System.out.print(t.getContent());
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (exception != null) {
|
||||||
|
exception.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
System.err.println("""
|
||||||
|
The bld CLI provides its features through a series of commands that
|
||||||
|
perform specific tasks. The help command provides more information about
|
||||||
|
the other commands.
|
||||||
|
|
||||||
|
Usage: help [command] [""" + JSON_ARGUMENT + "]");
|
||||||
|
|
||||||
|
executePrintCommands();
|
||||||
|
executePrintHelpArguments();
|
||||||
|
executePrintBldArguments();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Part of the {@link #execute} operation, prints the help overview
|
* Part of the {@link #execute} operation, prints the welcome message.
|
||||||
* with summaries of all build commands.
|
|
||||||
*
|
*
|
||||||
* @since 1.5
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
public void executePrintOverviewHelp() {
|
public void executePrintWelcome() {
|
||||||
var commands = executor_.buildCommands();
|
System.err.println("Welcome to bld " + BldVersion.getVersion() + ".");
|
||||||
|
System.err.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Part of the {@link #execute} operation, prints the summaries of all supported build commands.
|
||||||
|
*
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public void executePrintCommands() {
|
||||||
System.err.println("""
|
System.err.println("""
|
||||||
The bld CLI provides its features through a series of commands that
|
|
||||||
perform specific tasks. The help command provides more information about
|
|
||||||
the other commands.
|
|
||||||
|
|
||||||
Usage : help [command]
|
The following commands are supported:
|
||||||
|
""");
|
||||||
The following commands are supported.
|
|
||||||
""");
|
|
||||||
|
|
||||||
|
var commands = executor_.buildCommands();
|
||||||
var command_length = commands.keySet().stream().max(comparingInt(String::length)).get().length() + 2;
|
var command_length = commands.keySet().stream().max(comparingInt(String::length)).get().length() + 2;
|
||||||
for (var command : commands.entrySet()) {
|
for (var command : commands.entrySet()) {
|
||||||
System.err.print(" ");
|
System.err.print(" ");
|
||||||
|
|
@ -94,12 +164,35 @@ public class HelpOperation {
|
||||||
System.err.print(build_help.getSummary());
|
System.err.print(build_help.getSummary());
|
||||||
System.err.println();
|
System.err.println();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Part of the {@link #execute} operation, prints the supported help arguments.
|
||||||
|
*
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public void executePrintHelpArguments() {
|
||||||
System.err.println("""
|
System.err.println("""
|
||||||
|
|
||||||
-?, -h, --help Shows this help message
|
The following help arguments are supported:
|
||||||
-D<name>=<value> Set a JVM system property
|
|
||||||
-s, --stacktrace Print out the stacktrace for exceptions
|
--json Outputs help in JSON format""");
|
||||||
""");
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Part of the {@link #execute} operation, prints the supported bld arguments.
|
||||||
|
*
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public void executePrintBldArguments() {
|
||||||
|
System.err.println("""
|
||||||
|
|
||||||
|
The following bld arguments are supported:
|
||||||
|
|
||||||
|
--offline Works without Internet (only as first argument)
|
||||||
|
-?, -h, --help Shows the help
|
||||||
|
-D<name>=<value> Sets a JVM system property
|
||||||
|
-s, --stacktrace Prints out the stacktrace for exceptions
|
||||||
|
""");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -5,6 +5,11 @@
|
||||||
package rife.bld.operations;
|
package rife.bld.operations;
|
||||||
|
|
||||||
import rife.bld.BaseProject;
|
import rife.bld.BaseProject;
|
||||||
|
import rife.tools.FileUtils;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests a Java application with JUnit.
|
* Tests a Java application with JUnit.
|
||||||
|
|
@ -24,6 +29,39 @@ public class JUnitOperation extends TestOperation<JUnitOperation, JUnitOptions>
|
||||||
return new JUnitOptions();
|
return new JUnitOptions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<String> executeConstructProcessCommandList() {
|
||||||
|
if (mainClass() == null) {
|
||||||
|
throw new IllegalArgumentException("ERROR: Missing main class for test execution.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var args = new ArrayList<String>();
|
||||||
|
args.add(javaTool());
|
||||||
|
args.addAll(javaOptions());
|
||||||
|
args.add("-cp");
|
||||||
|
var classpath = FileUtils.joinPaths(classpath());
|
||||||
|
args.add(classpath);
|
||||||
|
args.add(mainClass());
|
||||||
|
// the JUnit console launcher syntax changed in v1.10.x,
|
||||||
|
// this logic defaults to the new syntax but if it finds an older
|
||||||
|
// JUnit jar in the classpath, uses the old syntax
|
||||||
|
var junit_version_1_10_and_later = true;
|
||||||
|
var junit_version_pattern = Pattern.compile("junit-platform-console-standalone-(\\d+)\\.(\\d+)\\.");
|
||||||
|
var junit_version_matcher = junit_version_pattern.matcher(classpath);
|
||||||
|
if (junit_version_matcher.find() &&
|
||||||
|
(Integer.parseInt(junit_version_matcher.group(1)) < 1 ||
|
||||||
|
(Integer.parseInt(junit_version_matcher.group(1)) == 1 &&
|
||||||
|
Integer.parseInt(junit_version_matcher.group(2)) < 10))) {
|
||||||
|
junit_version_1_10_and_later = false;
|
||||||
|
}
|
||||||
|
if (junit_version_1_10_and_later) {
|
||||||
|
args.add("execute");
|
||||||
|
}
|
||||||
|
args.addAll(testToolOptions());
|
||||||
|
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JUnitOperation fromProject(BaseProject project) {
|
public JUnitOperation fromProject(BaseProject project) {
|
||||||
super.fromProject(project);
|
super.fromProject(project);
|
||||||
|
|
@ -34,7 +72,7 @@ public class JUnitOperation extends TestOperation<JUnitOperation, JUnitOptions>
|
||||||
}
|
}
|
||||||
|
|
||||||
// add the default JUnit options if none were specified
|
// add the default JUnit options if none were specified
|
||||||
if (testToolOptions().isEmpty() && mainClass().equals(DEFAULT_TEST_TOOL_JUNIT5)) {
|
if (testToolOptions().isEmpty() && DEFAULT_TEST_TOOL_JUNIT5.equals(mainClass())) {
|
||||||
testToolOptions().defaultOptions();
|
testToolOptions().defaultOptions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -45,9 +83,9 @@ public class JUnitOperation extends TestOperation<JUnitOperation, JUnitOptions>
|
||||||
var argument = arguments.get(0);
|
var argument = arguments.get(0);
|
||||||
if (argument.startsWith("-")) {
|
if (argument.startsWith("-")) {
|
||||||
arguments.remove(0);
|
arguments.remove(0);
|
||||||
if (argument.equals("--junit-help")) {
|
if ("--junit-help".equals(argument)) {
|
||||||
testToolOptions().add("--help");
|
testToolOptions().add("--help");
|
||||||
} else if (argument.equals("--junit-clear")) {
|
} else if ("--junit-clear".equals(argument)) {
|
||||||
testToolOptions().clear();
|
testToolOptions().clear();
|
||||||
} else {
|
} else {
|
||||||
testToolOptions().add(argument);
|
testToolOptions().add(argument);
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ package rife.bld.operations;
|
||||||
|
|
||||||
import rife.bld.BaseProject;
|
import rife.bld.BaseProject;
|
||||||
import rife.bld.NamedFile;
|
import rife.bld.NamedFile;
|
||||||
import rife.bld.Project;
|
|
||||||
import rife.tools.FileUtils;
|
import rife.tools.FileUtils;
|
||||||
import rife.tools.StringUtils;
|
import rife.tools.StringUtils;
|
||||||
|
|
||||||
|
|
@ -95,6 +94,7 @@ public class JarOperation extends AbstractOperation<JarOperation> {
|
||||||
// don't use putAll since Attributes does an instanceof check
|
// don't use putAll since Attributes does an instanceof check
|
||||||
// on the map being passed in, causing it to fail if it's not
|
// on the map being passed in, causing it to fail if it's not
|
||||||
// and instance of Attributes
|
// and instance of Attributes
|
||||||
|
//noinspection UseBulkOperation
|
||||||
attributes.put(entry.getKey(), entry.getValue());
|
attributes.put(entry.getKey(), entry.getValue());
|
||||||
// ^^^ READ above, don't use putAll
|
// ^^^ READ above, don't use putAll
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,12 @@
|
||||||
*/
|
*/
|
||||||
package rife.bld.operations;
|
package rife.bld.operations;
|
||||||
|
|
||||||
|
import rife.tools.FileUtils;
|
||||||
import rife.tools.StringUtils;
|
import rife.tools.StringUtils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.nio.file.Path;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -39,8 +40,8 @@ public class JavaOptions extends ArrayList<String> {
|
||||||
* @return this list of options
|
* @return this list of options
|
||||||
* @since 1.5.18
|
* @since 1.5.18
|
||||||
*/
|
*/
|
||||||
public JavaOptions modulePath(File... modules) {
|
public JavaOptions modulePath(File... paths) {
|
||||||
return modulePath(Arrays.asList(modules));
|
return modulePath(List.of(paths));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -49,9 +50,49 @@ public class JavaOptions extends ArrayList<String> {
|
||||||
* @return this list of options
|
* @return this list of options
|
||||||
* @since 1.5.18
|
* @since 1.5.18
|
||||||
*/
|
*/
|
||||||
public JavaOptions modulePath(List<File> modules) {
|
public JavaOptions modulePath(List<File> paths) {
|
||||||
|
return modulePathStrings(paths.stream().map(File::getAbsolutePath).toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A list of directories, each directory is a directory of modules.
|
||||||
|
*
|
||||||
|
* @return this list of options
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public JavaOptions modulePath(Path... paths) {
|
||||||
|
return modulePathPaths(List.of(paths));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A list of directories, each directory is a directory of modules.
|
||||||
|
*
|
||||||
|
* @return this list of options
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public JavaOptions modulePathPaths(List<Path> paths) {
|
||||||
|
return modulePath(paths.stream().map(Path::toFile).toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A list of directories, each directory is a directory of modules.
|
||||||
|
*
|
||||||
|
* @return this list of options
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public JavaOptions modulePath(String... paths) {
|
||||||
|
return modulePathStrings(List.of(paths));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A list of directories, each directory is a directory of modules.
|
||||||
|
*
|
||||||
|
* @return this list of options
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public JavaOptions modulePathStrings(List<String> paths) {
|
||||||
add("--module-path");
|
add("--module-path");
|
||||||
add(StringUtils.join(modules, ":"));
|
add(FileUtils.joinPaths(paths));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -62,8 +103,8 @@ public class JavaOptions extends ArrayList<String> {
|
||||||
* @return this list of options
|
* @return this list of options
|
||||||
* @since 1.5.18
|
* @since 1.5.18
|
||||||
*/
|
*/
|
||||||
public JavaOptions upgradeModulePath(File... modulePath) {
|
public JavaOptions upgradeModulePath(File... paths) {
|
||||||
return upgradeModulePath(Arrays.asList(modulePath));
|
return upgradeModulePath(List.of(paths));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -73,9 +114,53 @@ public class JavaOptions extends ArrayList<String> {
|
||||||
* @return this list of options
|
* @return this list of options
|
||||||
* @since 1.5.18
|
* @since 1.5.18
|
||||||
*/
|
*/
|
||||||
public JavaOptions upgradeModulePath(List<File> modulePath) {
|
public JavaOptions upgradeModulePath(List<File> paths) {
|
||||||
|
return upgradeModulePathStrings(paths.stream().map(File::getAbsolutePath).toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of directories, each directory is a directory of modules
|
||||||
|
* that replace upgradeable modules in the runtime image
|
||||||
|
*
|
||||||
|
* @return this list of options
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public JavaOptions upgradeModulePath(Path... paths) {
|
||||||
|
return upgradeModulePathPaths(List.of(paths));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of directories, each directory is a directory of modules
|
||||||
|
* that replace upgradeable modules in the runtime image
|
||||||
|
*
|
||||||
|
* @return this list of options
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public JavaOptions upgradeModulePathPaths(List<Path> paths) {
|
||||||
|
return upgradeModulePath(paths.stream().map(Path::toFile).toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of directories, each directory is a directory of modules
|
||||||
|
* that replace upgradeable modules in the runtime image
|
||||||
|
*
|
||||||
|
* @return this list of options
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public JavaOptions upgradeModulePath(String... paths) {
|
||||||
|
return upgradeModulePathStrings(List.of(paths));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of directories, each directory is a directory of modules
|
||||||
|
* that replace upgradeable modules in the runtime image
|
||||||
|
*
|
||||||
|
* @return this list of options
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public JavaOptions upgradeModulePathStrings(List<String> paths) {
|
||||||
add("--upgrade-module-path");
|
add("--upgrade-module-path");
|
||||||
add(StringUtils.join(modulePath, ":"));
|
add(FileUtils.joinPaths(paths));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -88,7 +173,7 @@ public class JavaOptions extends ArrayList<String> {
|
||||||
* @since 1.5.18
|
* @since 1.5.18
|
||||||
*/
|
*/
|
||||||
public JavaOptions addModules(String... modules) {
|
public JavaOptions addModules(String... modules) {
|
||||||
return addModules(Arrays.asList(modules));
|
return addModules(List.of(modules));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -112,8 +197,8 @@ public class JavaOptions extends ArrayList<String> {
|
||||||
* @return this list of options
|
* @return this list of options
|
||||||
* @since 1.5.18
|
* @since 1.5.18
|
||||||
*/
|
*/
|
||||||
public JavaOptions enableNativeAccess(List... modules) {
|
public JavaOptions enableNativeAccess(String... modules) {
|
||||||
return enableNativeAccess(Arrays.asList(modules));
|
return enableNativeAccess(List.of(modules));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -215,7 +300,7 @@ public class JavaOptions extends ArrayList<String> {
|
||||||
* @since 1.5.18
|
* @since 1.5.18
|
||||||
*/
|
*/
|
||||||
public JavaOptions agentLib(String libName) {
|
public JavaOptions agentLib(String libName) {
|
||||||
return agentLib(libName, null);
|
return agentLib(libName, (String)null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -225,7 +310,28 @@ public class JavaOptions extends ArrayList<String> {
|
||||||
* @since 1.5.18
|
* @since 1.5.18
|
||||||
*/
|
*/
|
||||||
public JavaOptions agentLib(String libName, String options) {
|
public JavaOptions agentLib(String libName, String options) {
|
||||||
add("-agentlib:" + libName + (options == null ? "" : ":" + options));
|
add("-agentlib:" + libName + (options == null ? "" : "=" + options));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load native agent library.
|
||||||
|
*
|
||||||
|
* @return this list of options
|
||||||
|
* @since 1.7.1
|
||||||
|
*/
|
||||||
|
public JavaOptions agentLib(String libName, String... options) {
|
||||||
|
return agentLib(libName, List.of(options));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load native agent library.
|
||||||
|
*
|
||||||
|
* @return this list of options
|
||||||
|
* @since 1.7.1
|
||||||
|
*/
|
||||||
|
public JavaOptions agentLib(String libName, List<String> options) {
|
||||||
|
add("-agentlib:" + libName + (options == null || options.isEmpty() ? "" : "=" + StringUtils.join(options, ",")));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -236,7 +342,7 @@ public class JavaOptions extends ArrayList<String> {
|
||||||
* @since 1.5.18
|
* @since 1.5.18
|
||||||
*/
|
*/
|
||||||
public JavaOptions agentPath(File pathName) {
|
public JavaOptions agentPath(File pathName) {
|
||||||
return agentPath(pathName, null);
|
return agentPath(pathName.getAbsolutePath(), (String)null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -246,7 +352,108 @@ public class JavaOptions extends ArrayList<String> {
|
||||||
* @since 1.5.18
|
* @since 1.5.18
|
||||||
*/
|
*/
|
||||||
public JavaOptions agentPath(File pathName, String options) {
|
public JavaOptions agentPath(File pathName, String options) {
|
||||||
add("-agentpath:" + pathName + (options == null ? "" : ":" + options));
|
return agentPath(pathName.getAbsolutePath(), options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load native agent library by full pathname.
|
||||||
|
*
|
||||||
|
* @return this list of options
|
||||||
|
* @since 1.7.1
|
||||||
|
*/
|
||||||
|
public JavaOptions agentPath(File pathName, String... options) {
|
||||||
|
return agentPath(pathName.getAbsolutePath(), List.of(options));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load native agent library by full pathname.
|
||||||
|
*
|
||||||
|
* @return this list of options
|
||||||
|
* @since 1.7.1
|
||||||
|
*/
|
||||||
|
public JavaOptions agentPath(File pathName, List<String> options) {
|
||||||
|
return agentPath(pathName.getAbsolutePath(), options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load native agent library by full pathname.
|
||||||
|
*
|
||||||
|
* @return this list of options
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public JavaOptions agentPath(Path pathName) {
|
||||||
|
return agentPath(pathName.toFile(), (String)null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load native agent library by full pathname.
|
||||||
|
*
|
||||||
|
* @return this list of options
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public JavaOptions agentPath(Path pathName, String options) {
|
||||||
|
return agentPath(pathName.toFile(), options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load native agent library by full pathname.
|
||||||
|
*
|
||||||
|
* @return this list of options
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public JavaOptions agentPath(Path pathName, String... options) {
|
||||||
|
return agentPath(pathName.toFile(), List.of(options));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load native agent library by full pathname.
|
||||||
|
*
|
||||||
|
* @return this list of options
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public JavaOptions agentPath(Path pathName, List<String> options) {
|
||||||
|
return agentPath(pathName.toFile(), options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load native agent library by full pathname.
|
||||||
|
*
|
||||||
|
* @return this list of options
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public JavaOptions agentPath(String pathName) {
|
||||||
|
return agentPath(pathName, (String)null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load native agent library by full pathname.
|
||||||
|
*
|
||||||
|
* @return this list of options
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public JavaOptions agentPath(String pathName, String options) {
|
||||||
|
add("-agentpath:" + pathName + (options == null ? "" : "=" + options));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load native agent library by full pathname.
|
||||||
|
*
|
||||||
|
* @return this list of options
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public JavaOptions agentPath(String pathName, String... options) {
|
||||||
|
return agentPath(pathName, List.of(options));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load native agent library by full pathname.
|
||||||
|
*
|
||||||
|
* @return this list of options
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public JavaOptions agentPath(String pathName, List<String> options) {
|
||||||
|
add("-agentpath:" + pathName + (options == null || options.isEmpty() ? "" : "=" + StringUtils.join(options, ",")));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -257,7 +464,7 @@ public class JavaOptions extends ArrayList<String> {
|
||||||
* @since 1.5.18
|
* @since 1.5.18
|
||||||
*/
|
*/
|
||||||
public JavaOptions javaAgent(File jarPath) {
|
public JavaOptions javaAgent(File jarPath) {
|
||||||
return javaAgent(jarPath, null);
|
return javaAgent(jarPath.getAbsolutePath(), (String)null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -267,7 +474,108 @@ public class JavaOptions extends ArrayList<String> {
|
||||||
* @since 1.5.18
|
* @since 1.5.18
|
||||||
*/
|
*/
|
||||||
public JavaOptions javaAgent(File jarPath, String options) {
|
public JavaOptions javaAgent(File jarPath, String options) {
|
||||||
add("-javaagent:" + jarPath + (options == null ? "" : ":" + options));
|
return javaAgent(jarPath.getAbsolutePath(), options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load Java programming language agent.
|
||||||
|
*
|
||||||
|
* @return this list of options
|
||||||
|
* @since 1.7.1
|
||||||
|
*/
|
||||||
|
public JavaOptions javaAgent(File jarPath, String... options) {
|
||||||
|
return javaAgent(jarPath.getAbsolutePath(), List.of(options));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load Java programming language agent.
|
||||||
|
*
|
||||||
|
* @return this list of options
|
||||||
|
* @since 1.7.1
|
||||||
|
*/
|
||||||
|
public JavaOptions javaAgent(File jarPath, List<String> options) {
|
||||||
|
return javaAgent(jarPath.getAbsolutePath(), options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load Java programming language agent.
|
||||||
|
*
|
||||||
|
* @return this list of options
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public JavaOptions javaAgent(Path jarPath) {
|
||||||
|
return javaAgent(jarPath.toFile(), (String)null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load Java programming language agent.
|
||||||
|
*
|
||||||
|
* @return this list of options
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public JavaOptions javaAgent(Path jarPath, String options) {
|
||||||
|
return javaAgent(jarPath.toFile(), options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load Java programming language agent.
|
||||||
|
*
|
||||||
|
* @return this list of options
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public JavaOptions javaAgent(Path jarPath, String... options) {
|
||||||
|
return javaAgent(jarPath.toFile(), List.of(options));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load Java programming language agent.
|
||||||
|
*
|
||||||
|
* @return this list of options
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public JavaOptions javaAgent(Path jarPath, List<String> options) {
|
||||||
|
return javaAgent(jarPath.toFile(), options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load Java programming language agent.
|
||||||
|
*
|
||||||
|
* @return this list of options
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public JavaOptions javaAgent(String jarPath) {
|
||||||
|
return javaAgent(jarPath, (String)null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load Java programming language agent.
|
||||||
|
*
|
||||||
|
* @return this list of options
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public JavaOptions javaAgent(String jarPath, String options) {
|
||||||
|
add("-javaagent:" + jarPath + (options == null ? "" : "=" + options));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load Java programming language agent.
|
||||||
|
*
|
||||||
|
* @return this list of options
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public JavaOptions javaAgent(String jarPath, String... options) {
|
||||||
|
return javaAgent(jarPath, List.of(options));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load Java programming language agent.
|
||||||
|
*
|
||||||
|
* @return this list of options
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public JavaOptions javaAgent(String jarPath, List<String> options) {
|
||||||
|
add("-javaagent:" + jarPath + (options == null || options.isEmpty() ? "" : "=" + StringUtils.join(options, ",")));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -5,7 +5,6 @@
|
||||||
package rife.bld.operations;
|
package rife.bld.operations;
|
||||||
|
|
||||||
import rife.bld.BaseProject;
|
import rife.bld.BaseProject;
|
||||||
import rife.bld.Project;
|
|
||||||
import rife.bld.operations.exceptions.ExitStatusException;
|
import rife.bld.operations.exceptions.ExitStatusException;
|
||||||
import rife.tools.FileUtils;
|
import rife.tools.FileUtils;
|
||||||
import rife.tools.StringUtils;
|
import rife.tools.StringUtils;
|
||||||
|
|
@ -27,6 +26,7 @@ import java.util.regex.Pattern;
|
||||||
public class JavadocOperation extends AbstractOperation<JavadocOperation> {
|
public class JavadocOperation extends AbstractOperation<JavadocOperation> {
|
||||||
private File buildDirectory_;
|
private File buildDirectory_;
|
||||||
private final List<String> classpath_ = new ArrayList<>();
|
private final List<String> classpath_ = new ArrayList<>();
|
||||||
|
private final List<String> modulePath_ = new ArrayList<>();
|
||||||
private final List<File> sourceFiles_ = new ArrayList<>();
|
private final List<File> sourceFiles_ = new ArrayList<>();
|
||||||
private final List<File> sourceDirectories_ = new ArrayList<>();
|
private final List<File> sourceDirectories_ = new ArrayList<>();
|
||||||
private final JavadocOptions javadocOptions_ = new JavadocOptions();
|
private final JavadocOptions javadocOptions_ = new JavadocOptions();
|
||||||
|
|
@ -75,6 +75,7 @@ public class JavadocOperation extends AbstractOperation<JavadocOperation> {
|
||||||
}
|
}
|
||||||
executeBuildSources(
|
executeBuildSources(
|
||||||
classpath(),
|
classpath(),
|
||||||
|
modulePath(),
|
||||||
sources,
|
sources,
|
||||||
buildDirectory());
|
buildDirectory());
|
||||||
}
|
}
|
||||||
|
|
@ -82,12 +83,13 @@ public class JavadocOperation extends AbstractOperation<JavadocOperation> {
|
||||||
/**
|
/**
|
||||||
* Part of the {@link #execute} operation, build sources to a destination.
|
* Part of the {@link #execute} operation, build sources to a destination.
|
||||||
*
|
*
|
||||||
* @param classpath the classpath list used for the compilation
|
* @param classpath the classpath list used for the javadoc generation
|
||||||
|
* @param modulePath the module path list used for the javadoc generation
|
||||||
* @param sources the source files to compile
|
* @param sources the source files to compile
|
||||||
* @param destination the destination directory
|
* @param destination the destination directory
|
||||||
* @since 1.5.10
|
* @since 2.1
|
||||||
*/
|
*/
|
||||||
protected void executeBuildSources(List<String> classpath, List<File> sources, File destination)
|
protected void executeBuildSources(List<String> classpath, List<String> modulePath, List<File> sources, File destination)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
if (sources.isEmpty() || destination == null) {
|
if (sources.isEmpty() || destination == null) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -104,7 +106,13 @@ public class JavadocOperation extends AbstractOperation<JavadocOperation> {
|
||||||
try (var file_manager = documentation.getStandardFileManager(null, null, null)) {
|
try (var file_manager = documentation.getStandardFileManager(null, null, null)) {
|
||||||
var compilation_units = file_manager.getJavaFileObjectsFromFiles(filtered_sources);
|
var compilation_units = file_manager.getJavaFileObjectsFromFiles(filtered_sources);
|
||||||
var diagnostics = new DiagnosticCollector<JavaFileObject>();
|
var diagnostics = new DiagnosticCollector<JavaFileObject>();
|
||||||
var options = new ArrayList<>(List.of("-d", destination.getAbsolutePath(), "-cp", FileUtils.joinPaths(classpath)));
|
var options = new ArrayList<>(List.of("-d", destination.getAbsolutePath()));
|
||||||
|
if (!classpath.isEmpty()) {
|
||||||
|
options.addAll(List.of("-cp", FileUtils.joinPaths(classpath)));
|
||||||
|
}
|
||||||
|
if (!modulePath.isEmpty()) {
|
||||||
|
options.addAll(List.of("-p", FileUtils.joinPaths(modulePath)));
|
||||||
|
}
|
||||||
options.addAll(javadocOptions());
|
options.addAll(javadocOptions());
|
||||||
var documentation_task = documentation.getTask(null, file_manager, diagnostics, null, options, compilation_units);
|
var documentation_task = documentation.getTask(null, file_manager, diagnostics, null, options, compilation_units);
|
||||||
if (!documentation_task.call()) {
|
if (!documentation_task.call()) {
|
||||||
|
|
@ -147,6 +155,7 @@ public class JavadocOperation extends AbstractOperation<JavadocOperation> {
|
||||||
var operation = buildDirectory(project.buildJavadocDirectory())
|
var operation = buildDirectory(project.buildJavadocDirectory())
|
||||||
.classpath(project.compileMainClasspath())
|
.classpath(project.compileMainClasspath())
|
||||||
.classpath(project.buildMainDirectory().getAbsolutePath())
|
.classpath(project.buildMainDirectory().getAbsolutePath())
|
||||||
|
.modulePath(project.compileMainModulePath())
|
||||||
.sourceFiles(project.mainSourceFiles());
|
.sourceFiles(project.mainSourceFiles());
|
||||||
if (project.javaRelease() != null && !javadocOptions().containsRelease()) {
|
if (project.javaRelease() != null && !javadocOptions().containsRelease()) {
|
||||||
javadocOptions().release(project.javaRelease());
|
javadocOptions().release(project.javaRelease());
|
||||||
|
|
@ -192,6 +201,32 @@ public class JavadocOperation extends AbstractOperation<JavadocOperation> {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides entries for the javadoc module path.
|
||||||
|
*
|
||||||
|
* @param modulePath module path entries
|
||||||
|
* @return this operation instance
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public JavadocOperation modulePath(String... modulePath) {
|
||||||
|
modulePath_.addAll(Arrays.asList(modulePath));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides a list of entries for the javadoc moduel path.
|
||||||
|
* <p>
|
||||||
|
* A copy will be created to allow this list to be independently modifiable.
|
||||||
|
*
|
||||||
|
* @param modulePath a list of module path entries
|
||||||
|
* @return this operation instance
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public JavadocOperation modulePath(List<String> modulePath) {
|
||||||
|
modulePath_.addAll(modulePath);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides files for which documentation should be generated.
|
* Provides files for which documentation should be generated.
|
||||||
*
|
*
|
||||||
|
|
@ -362,6 +397,18 @@ public class JavadocOperation extends AbstractOperation<JavadocOperation> {
|
||||||
return classpath_;
|
return classpath_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the list of entries for the javadoc module path.
|
||||||
|
* <p>
|
||||||
|
* This is a modifiable list that can be retrieved and changed.
|
||||||
|
*
|
||||||
|
* @return the javadoc module path list
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public List<String> modulePath() {
|
||||||
|
return modulePath_;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the list of files for which documentation should be generation.
|
* Retrieves the list of files for which documentation should be generation.
|
||||||
* <p>
|
* <p>
|
||||||
|
|
|
||||||
|
|
@ -9,10 +9,10 @@ import rife.tools.FileUtils;
|
||||||
import rife.tools.StringUtils;
|
import rife.tools.StringUtils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.nio.file.Path;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Options for the standard javadoc tool.
|
* Options for the standard javadoc tool.
|
||||||
|
|
@ -100,7 +100,7 @@ public class JavadocOptions extends ArrayList<String> {
|
||||||
*/
|
*/
|
||||||
public JavadocOptions doclet(String className) {
|
public JavadocOptions doclet(String className) {
|
||||||
add("-doclet");
|
add("-doclet");
|
||||||
add("className");
|
add(className);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -112,7 +112,7 @@ public class JavadocOptions extends ArrayList<String> {
|
||||||
*/
|
*/
|
||||||
public JavadocOptions docletPath(String path) {
|
public JavadocOptions docletPath(String path) {
|
||||||
add("-docletpath");
|
add("-docletpath");
|
||||||
add("path");
|
add(path);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -135,7 +135,7 @@ public class JavadocOptions extends ArrayList<String> {
|
||||||
*/
|
*/
|
||||||
public JavadocOptions encoding(String name) {
|
public JavadocOptions encoding(String name) {
|
||||||
add("-encoding");
|
add("-encoding");
|
||||||
add("name");
|
add(name);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -178,8 +178,48 @@ public class JavadocOptions extends ArrayList<String> {
|
||||||
* @since 1.5.18
|
* @since 1.5.18
|
||||||
*/
|
*/
|
||||||
public JavadocOptions extDirs(List<File> dirs) {
|
public JavadocOptions extDirs(List<File> dirs) {
|
||||||
|
return extDirsStrings(dirs.stream().map(File::getAbsolutePath).toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override location of installed extensions
|
||||||
|
*
|
||||||
|
* @return this list of options
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public JavadocOptions extDirs(Path... dirs) {
|
||||||
|
return extDirsPaths(Arrays.asList(dirs));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override location of installed extensions
|
||||||
|
*
|
||||||
|
* @return this list of options
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public JavadocOptions extDirsPaths(List<Path> dirs) {
|
||||||
|
return extDirs(dirs.stream().map(Path::toFile).toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override location of installed extensions
|
||||||
|
*
|
||||||
|
* @return this list of options
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public JavadocOptions extDirs(String... dirs) {
|
||||||
|
return extDirsStrings(Arrays.asList(dirs));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override location of installed extensions
|
||||||
|
*
|
||||||
|
* @return this list of options
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public JavadocOptions extDirsStrings(List<String> dirs) {
|
||||||
add("-extdirs");
|
add("-extdirs");
|
||||||
add(dirs.stream().map(File::getAbsolutePath).collect(Collectors.joining(",")));
|
add(String.join(",", dirs));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -213,7 +253,7 @@ public class JavadocOptions extends ArrayList<String> {
|
||||||
*/
|
*/
|
||||||
public JavadocOptions locale(String name) {
|
public JavadocOptions locale(String name) {
|
||||||
add("-locale");
|
add("-locale");
|
||||||
add("name");
|
add(name);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -256,8 +296,48 @@ public class JavadocOptions extends ArrayList<String> {
|
||||||
* @since 1.6.3
|
* @since 1.6.3
|
||||||
*/
|
*/
|
||||||
public JavadocOptions modulePath(List<File> paths) {
|
public JavadocOptions modulePath(List<File> paths) {
|
||||||
|
return modulePathStrings(paths.stream().map(File::getAbsolutePath).toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify where to find application modules
|
||||||
|
*
|
||||||
|
* @return this list of options
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public JavadocOptions modulePath(Path... paths) {
|
||||||
|
return modulePathPaths(Arrays.asList(paths));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify where to find application modules
|
||||||
|
*
|
||||||
|
* @return this list of options
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public JavadocOptions modulePathPaths(List<Path> paths) {
|
||||||
|
return modulePath(paths.stream().map(Path::toFile).toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify where to find application modules
|
||||||
|
*
|
||||||
|
* @return this list of options
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public JavadocOptions modulePath(String... paths) {
|
||||||
|
return modulePathStrings(Arrays.asList(paths));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify where to find application modules
|
||||||
|
*
|
||||||
|
* @return this list of options
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public JavadocOptions modulePathStrings(List<String> paths) {
|
||||||
add("--module-path");
|
add("--module-path");
|
||||||
add(FileUtils.joinPaths(paths.stream().map(File::getAbsolutePath).toList()));
|
add(FileUtils.joinPaths(paths));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -268,8 +348,28 @@ public class JavadocOptions extends ArrayList<String> {
|
||||||
* @since 1.6.3
|
* @since 1.6.3
|
||||||
*/
|
*/
|
||||||
public JavadocOptions moduleSourcePath(File path) {
|
public JavadocOptions moduleSourcePath(File path) {
|
||||||
|
return moduleSourcePath(path.getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify where to find input source files for multiple modules
|
||||||
|
*
|
||||||
|
* @return this list of options
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public JavadocOptions moduleSourcePath(Path path) {
|
||||||
|
return moduleSourcePath(path.toFile());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify where to find input source files for multiple modules
|
||||||
|
*
|
||||||
|
* @return this list of options
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public JavadocOptions moduleSourcePath(String path) {
|
||||||
add("--module-source-path");
|
add("--module-source-path");
|
||||||
add(path.getAbsolutePath());
|
add(path);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -425,9 +525,29 @@ public class JavadocOptions extends ArrayList<String> {
|
||||||
* @return this list of options
|
* @return this list of options
|
||||||
* @since 1.5.12
|
* @since 1.5.12
|
||||||
*/
|
*/
|
||||||
public JavadocOptions addScript(File file) {
|
public JavadocOptions addScript(File path) {
|
||||||
|
return addScript(path.getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a script file to the generated documentation
|
||||||
|
*
|
||||||
|
* @return this list of options
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public JavadocOptions addScript(Path path) {
|
||||||
|
return addScript(path.toFile());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a script file to the generated documentation
|
||||||
|
*
|
||||||
|
* @return this list of options
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public JavadocOptions addScript(String path) {
|
||||||
add("--add-script");
|
add("--add-script");
|
||||||
add(file.getAbsolutePath());
|
add(path);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -437,9 +557,29 @@ public class JavadocOptions extends ArrayList<String> {
|
||||||
* @return this list of options
|
* @return this list of options
|
||||||
* @since 1.5.12
|
* @since 1.5.12
|
||||||
*/
|
*/
|
||||||
public JavadocOptions addStylesheet(File file) {
|
public JavadocOptions addStylesheet(File path) {
|
||||||
|
return addStylesheet(path.getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a stylesheet file to the generated documentation
|
||||||
|
*
|
||||||
|
* @return this list of options
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public JavadocOptions addStylesheet(Path path) {
|
||||||
|
return addStylesheet(path.toFile());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a stylesheet file to the generated documentation
|
||||||
|
*
|
||||||
|
* @return this list of options
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public JavadocOptions addStylesheet(String path) {
|
||||||
add("--add-stylesheet");
|
add("--add-stylesheet");
|
||||||
add(file.getAbsolutePath());
|
add(path);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -578,9 +718,29 @@ public class JavadocOptions extends ArrayList<String> {
|
||||||
* @return this list of options
|
* @return this list of options
|
||||||
* @since 1.5.12
|
* @since 1.5.12
|
||||||
*/
|
*/
|
||||||
public JavadocOptions stylesheet(File file) {
|
public JavadocOptions stylesheet(File path) {
|
||||||
|
return stylesheet(path.getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* File to change style of the generated documentation
|
||||||
|
*
|
||||||
|
* @return this list of options
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public JavadocOptions stylesheet(Path path) {
|
||||||
|
return stylesheet(path.toFile());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* File to change style of the generated documentation
|
||||||
|
*
|
||||||
|
* @return this list of options
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public JavadocOptions stylesheet(String path) {
|
||||||
add("--main-stylesheet");
|
add("--main-stylesheet");
|
||||||
add(file.getAbsolutePath());
|
add(path);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -735,9 +895,29 @@ public class JavadocOptions extends ArrayList<String> {
|
||||||
* @return this list of options
|
* @return this list of options
|
||||||
* @since 1.5.18
|
* @since 1.5.18
|
||||||
*/
|
*/
|
||||||
public JavadocOptions overview(File htmlFile) {
|
public JavadocOptions overview(File path) {
|
||||||
|
return overview(path.getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read overview documentation from HTML file
|
||||||
|
*
|
||||||
|
* @return this list of options
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public JavadocOptions overview(Path path) {
|
||||||
|
return overview(path.toFile());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read overview documentation from HTML file
|
||||||
|
*
|
||||||
|
* @return this list of options
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public JavadocOptions overview(String path) {
|
||||||
add("-overview");
|
add("-overview");
|
||||||
add(htmlFile.getAbsolutePath());
|
add(path);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -793,8 +973,28 @@ public class JavadocOptions extends ArrayList<String> {
|
||||||
* @since 1.5.12
|
* @since 1.5.12
|
||||||
*/
|
*/
|
||||||
public JavadocOptions snippetPath(File path) {
|
public JavadocOptions snippetPath(File path) {
|
||||||
|
return snippetPath(path.getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The path for external snippets
|
||||||
|
*
|
||||||
|
* @return this list of options
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public JavadocOptions snippetPath(Path path) {
|
||||||
|
return snippetPath(path.toFile());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The path for external snippets
|
||||||
|
*
|
||||||
|
* @return this list of options
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public JavadocOptions snippetPath(String path) {
|
||||||
add("--snippet-path");
|
add("--snippet-path");
|
||||||
add(path.getAbsolutePath());
|
add(path);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -852,8 +1052,28 @@ public class JavadocOptions extends ArrayList<String> {
|
||||||
* @since 1.5.12
|
* @since 1.5.12
|
||||||
*/
|
*/
|
||||||
public JavadocOptions tagletPath(File path) {
|
public JavadocOptions tagletPath(File path) {
|
||||||
|
return tagletPath(path.getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The path to Taglets
|
||||||
|
*
|
||||||
|
* @return this list of options
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public JavadocOptions tagletPath(Path path) {
|
||||||
|
return tagletPath(path.toFile());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The path to Taglets
|
||||||
|
*
|
||||||
|
* @return this list of options
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public JavadocOptions tagletPath(String path) {
|
||||||
add("-tagletpath");
|
add("-tagletpath");
|
||||||
add(path.getAbsolutePath());
|
add(path);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
77
src/main/java/rife/bld/operations/JlinkOperation.java
Normal file
77
src/main/java/rife/bld/operations/JlinkOperation.java
Normal file
|
|
@ -0,0 +1,77 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2024 Erik C. Thauvin (https://erik.thauvin.net/)
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||||
|
*/
|
||||||
|
package rife.bld.operations;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create run-time images using the jlink tool.
|
||||||
|
*
|
||||||
|
* @author <a href="https://erik.thauvin.net/">Erik C. Thauvin</a>
|
||||||
|
* @since 2.1.0
|
||||||
|
*/
|
||||||
|
public class JlinkOperation extends AbstractToolProviderOperation<JlinkOperation> {
|
||||||
|
private final List<String> disabledPlugins_ = new ArrayList<>();
|
||||||
|
private final JlinkOptions jlinkOptions_ = new JlinkOptions();
|
||||||
|
|
||||||
|
public JlinkOperation() {
|
||||||
|
super("jlink");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disable the plugin(s) mentioned.
|
||||||
|
*
|
||||||
|
* @param plugins the plugin name(s)
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JlinkOperation disablePlugin(List<String> plugins) {
|
||||||
|
disabledPlugins_.addAll(plugins);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disable the plugin(s) mentioned.
|
||||||
|
*
|
||||||
|
* @param plugins the plugin name(s)
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JlinkOperation disablePlugin(String... plugins) {
|
||||||
|
return disablePlugin(List.of(plugins));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute() throws Exception {
|
||||||
|
toolArgsFromFiles();
|
||||||
|
disabledPlugins_.forEach(plugin -> toolArgs("--disable-plugin", plugin));
|
||||||
|
toolArgs(jlinkOptions_);
|
||||||
|
super.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides a list of options to provide to the jlink tool.
|
||||||
|
* <p>
|
||||||
|
* A copy will be created to allow this list to be independently modifiable.
|
||||||
|
*
|
||||||
|
* @param options the argument-value pairs
|
||||||
|
* @return this operation instance
|
||||||
|
*/
|
||||||
|
public JlinkOperation jlinkOptions(Map<String, String> options) {
|
||||||
|
jlinkOptions_.putAll(options);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the list of options for the jlink tool.
|
||||||
|
* <p>
|
||||||
|
* This is a modifiable list that can be retrieved and changed.
|
||||||
|
*
|
||||||
|
* @return the map of jlink options
|
||||||
|
*/
|
||||||
|
public JlinkOptions jlinkOptions() {
|
||||||
|
return jlinkOptions_;
|
||||||
|
}
|
||||||
|
}
|
||||||
408
src/main/java/rife/bld/operations/JlinkOptions.java
Normal file
408
src/main/java/rife/bld/operations/JlinkOptions.java
Normal file
|
|
@ -0,0 +1,408 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2024 Erik C. Thauvin (https://erik.thauvin.net/)
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||||
|
*/
|
||||||
|
package rife.bld.operations;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Options for jlink tool.
|
||||||
|
*
|
||||||
|
* @author <a href="https://erik.thauvin.net/">Erik C. Thauvin</a>
|
||||||
|
* @since 2.1.0
|
||||||
|
*/
|
||||||
|
public class JlinkOptions extends LinkedHashMap<String, String> {
|
||||||
|
/**
|
||||||
|
* All Modules Path.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public final static String ALL_MODULE_PATH = "ALL-MODULE-PATH";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Root modules to resolve in addition to the initial modules.
|
||||||
|
* <p>
|
||||||
|
* Module can also be {@link #ALL_MODULE_PATH}
|
||||||
|
*
|
||||||
|
* @param modules one or more modules
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JlinkOptions addModules(List<String> modules) {
|
||||||
|
put("--add-modules", String.join(",", modules));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Root modules to resolve in addition to the initial modules.
|
||||||
|
* <p>
|
||||||
|
* Module can also be {@link #ALL_MODULE_PATH}
|
||||||
|
*
|
||||||
|
* @param modules one or more modules
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JlinkOptions addModules(String... modules) {
|
||||||
|
return addModules(List.of(modules));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Link in service provider modules and their dependencies.
|
||||||
|
*
|
||||||
|
* @param bindServices {@code true} to bind services, {@code false} otherwise
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JlinkOptions bindServices(boolean bindServices) {
|
||||||
|
if (bindServices) {
|
||||||
|
put("--bind-services");
|
||||||
|
} else {
|
||||||
|
remove("--bind-services");
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compression to use in compressing resources.
|
||||||
|
* <p>
|
||||||
|
* <b>Requires Java 21 or higher</b>. Use {@link #compress(CompressionLevel)} for lower versions.
|
||||||
|
* <p>
|
||||||
|
* Where {@link ZipCompression#ZIP_0 ZIP_0} provides no compression and {@link ZipCompression#ZIP_9 ZIP_9} provides
|
||||||
|
* the best compression.
|
||||||
|
* <p>Default is {@link ZipCompression#ZIP_6 ZIP_6}
|
||||||
|
*
|
||||||
|
* @param compression the {@link ZipCompression compression} level
|
||||||
|
* @return this map of options
|
||||||
|
* @see #compress(ZipCompression)
|
||||||
|
*/
|
||||||
|
public JlinkOptions compress(ZipCompression compression) {
|
||||||
|
put("--compress", compression.level);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable compression of resources.
|
||||||
|
* <p>
|
||||||
|
* Use {@link #compress(ZipCompression)} on Java 21 or higher.
|
||||||
|
*
|
||||||
|
* @param compression the {@link CompressionLevel compression} level
|
||||||
|
* @return this map of options
|
||||||
|
* @see #compress(CompressionLevel)
|
||||||
|
*/
|
||||||
|
public JlinkOptions compress(CompressionLevel compression) {
|
||||||
|
put("--compress", compression.level);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Byte order of generated jimage.
|
||||||
|
* <p>
|
||||||
|
* Default: native
|
||||||
|
*
|
||||||
|
* @param endian the byte order
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JlinkOptions endian(Endian endian) {
|
||||||
|
put("--endian", endian.byteOrder);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Suppress a fatal error when signed modular JARs are linked in the image.
|
||||||
|
*
|
||||||
|
* @param ignoreSigningInformation {@code true} to ignore signing information, {@code false} otherwise
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JlinkOptions ignoreSigningInformation(boolean ignoreSigningInformation) {
|
||||||
|
if (ignoreSigningInformation) {
|
||||||
|
put("--ignore-signing-information");
|
||||||
|
} else {
|
||||||
|
remove("--ignore-signing-information");
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a launcher command of the given name for the module.
|
||||||
|
*
|
||||||
|
* @param name the name
|
||||||
|
* @param module the module
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("UnusedReturnValue")
|
||||||
|
public JlinkOptions launcher(String name, String module) {
|
||||||
|
put("--launcher", name + "=" + module);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a launcher command of the given name for the module and the main class.
|
||||||
|
*
|
||||||
|
* @param name the name
|
||||||
|
* @param module the module
|
||||||
|
* @param mainClass the main class
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JlinkOptions launcher(String name, String module, String mainClass) {
|
||||||
|
put("--launcher", name + "=" + module + "/" + mainClass);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Limit the universe of observable modules.
|
||||||
|
*
|
||||||
|
* @param modules one or more modules
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JlinkOptions limitModule(List<String> modules) {
|
||||||
|
put("--limit-modules", String.join(",", modules));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Limit the universe of observable modules.
|
||||||
|
*
|
||||||
|
* @param modules one or more modules
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JlinkOptions limitModule(String... modules) {
|
||||||
|
return limitModule(List.of(modules));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module path.
|
||||||
|
* <p>
|
||||||
|
* If not specified, the JDKs jmods directory will be used, if it exists. If specified, but it does not contain the
|
||||||
|
* {@code java.base} module, the JDKs jmods directory will be added, if it exists.
|
||||||
|
*
|
||||||
|
* @param path the module path
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JlinkOptions modulePath(String path) {
|
||||||
|
put("--module-path", path);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module path.
|
||||||
|
* <p>
|
||||||
|
* If not specified, the JDKs jmods directory will be used, if it exists. If specified, but it does not contain the
|
||||||
|
* {@code java.base} module, the JDKs jmods directory will be added, if it exists.
|
||||||
|
*
|
||||||
|
* @param path the module path
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JlinkOptions modulePath(File path) {
|
||||||
|
return modulePath(path.getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module path.
|
||||||
|
* <p>
|
||||||
|
* If not specified, the JDKs jmods directory will be used, if it exists. If specified, but it does not contain the
|
||||||
|
* {@code java.base} module, the JDKs jmods directory will be added, if it exists.
|
||||||
|
*
|
||||||
|
* @param path the module path
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JlinkOptions modulePath(Path path) {
|
||||||
|
return modulePath(path.toFile().getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exclude include header files.
|
||||||
|
*
|
||||||
|
* @param noHeaderFiles {@code true} to exclude header files, {@code false} otherwise
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JlinkOptions noHeaderFiles(boolean noHeaderFiles) {
|
||||||
|
if (noHeaderFiles) {
|
||||||
|
put("--no-header-files");
|
||||||
|
} else {
|
||||||
|
remove("--no-header-files");
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exclude man pages.
|
||||||
|
*
|
||||||
|
* @param noManPages {@code true} to exclude man pages, {@code false} otherwise
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JlinkOptions noManPages(boolean noManPages) {
|
||||||
|
if (noManPages) {
|
||||||
|
put("--no-man-pages");
|
||||||
|
} else {
|
||||||
|
remove("--no-man-pages");
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Location of output path.
|
||||||
|
*
|
||||||
|
* @param path the output path
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JlinkOptions output(String path) {
|
||||||
|
put("--output", path);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Location of output path.
|
||||||
|
*
|
||||||
|
* @param path the output path
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JlinkOptions output(File path) {
|
||||||
|
return output(path.getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Location of output path.
|
||||||
|
*
|
||||||
|
* @param path the output path
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JlinkOptions output(Path path) {
|
||||||
|
return output(path.toFile().getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Associates {@code null} with the specified key in this map. If the map previously contained a mapping for the
|
||||||
|
* key, the old value is replaced.
|
||||||
|
*
|
||||||
|
* @param key key with which the specified value is to be associated
|
||||||
|
*/
|
||||||
|
public void put(String key) {
|
||||||
|
put(key, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Suggest providers that implement the given service types from the module path.
|
||||||
|
*
|
||||||
|
* @param filename the filename
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JlinkOptions saveOpts(String filename) {
|
||||||
|
put("--save-opts", filename);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Strip debug information.
|
||||||
|
*
|
||||||
|
* @param stripDebug {@code true} to strip debug info, {@code false} otherwise
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JlinkOptions stripDebug(boolean stripDebug) {
|
||||||
|
if (stripDebug) {
|
||||||
|
put("--strip-debug");
|
||||||
|
} else {
|
||||||
|
remove("--strip-debug");
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Strip native commands.
|
||||||
|
*
|
||||||
|
* @param stripNativeCommands {@code true} to strip, {@code false} otherwise
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JlinkOptions stripNativeCommands(boolean stripNativeCommands) {
|
||||||
|
if (stripNativeCommands) {
|
||||||
|
put("--strip-native-commands");
|
||||||
|
} else {
|
||||||
|
remove("--strip-native-commands");
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Suggest providers that implement the given service types from the module path.
|
||||||
|
*
|
||||||
|
* @param names one or more provider names
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JlinkOptions suggestProviders(List<String> names) {
|
||||||
|
put("--suggest-providers", String.join(",", names));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Suggest providers that implement the given service types from the module path.
|
||||||
|
*
|
||||||
|
* @param names one or more provider names
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JlinkOptions suggestProviders(String... names) {
|
||||||
|
return suggestProviders(List.of(names));
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> toList() {
|
||||||
|
var list = new ArrayList<String>();
|
||||||
|
forEach((k, v) -> {
|
||||||
|
list.add(k);
|
||||||
|
if (v != null && !v.isEmpty()) {
|
||||||
|
list.add(v);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable verbose tracing.
|
||||||
|
*
|
||||||
|
* @param verbose {@code true} to enable verbose tracing, {@code false} otherwise.
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JlinkOptions verbose(boolean verbose) {
|
||||||
|
if (verbose) {
|
||||||
|
put("--verbose");
|
||||||
|
} else {
|
||||||
|
remove("--verbose");
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The byte orders.
|
||||||
|
*/
|
||||||
|
public enum Endian {
|
||||||
|
BIG("big"), LITTLE("little");
|
||||||
|
|
||||||
|
public final String byteOrder;
|
||||||
|
|
||||||
|
Endian(String byteOrder) {
|
||||||
|
this.byteOrder = byteOrder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resources compression levels.
|
||||||
|
*/
|
||||||
|
public enum CompressionLevel {
|
||||||
|
/**
|
||||||
|
* Level 0: No compression
|
||||||
|
*/
|
||||||
|
NO_COMPRESSION("0"),
|
||||||
|
/**
|
||||||
|
* Level 1: Constant string sharing
|
||||||
|
*/
|
||||||
|
CONSTANT_STRING_SHARING("1"),
|
||||||
|
/**
|
||||||
|
* Level 2: ZIP
|
||||||
|
*/
|
||||||
|
ZIP("2");
|
||||||
|
|
||||||
|
public final String level;
|
||||||
|
|
||||||
|
CompressionLevel(String level) {
|
||||||
|
this.level = level;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
156
src/main/java/rife/bld/operations/JmodOperation.java
Normal file
156
src/main/java/rife/bld/operations/JmodOperation.java
Normal file
|
|
@ -0,0 +1,156 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2024 Erik C. Thauvin (https://erik.thauvin.net/)
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||||
|
*/
|
||||||
|
package rife.bld.operations;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create JMOD files with the jmod tool.
|
||||||
|
*
|
||||||
|
* @author <a href="https://erik.thauvin.net/">Erik C. Thauvin</a>
|
||||||
|
* @since 2.1.0
|
||||||
|
*/
|
||||||
|
public class JmodOperation extends AbstractToolProviderOperation<JmodOperation> {
|
||||||
|
private final JmodOptions jmodOptions_ = new JmodOptions();
|
||||||
|
private String jmodFile_;
|
||||||
|
private OperationMode operationMode_;
|
||||||
|
|
||||||
|
public JmodOperation() {
|
||||||
|
super("jmod");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute() throws Exception {
|
||||||
|
if (operationMode_ != null) {
|
||||||
|
toolArgs(operationMode_.mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
toolArgsFromFiles();
|
||||||
|
toolArgs(jmodOptions_);
|
||||||
|
|
||||||
|
if (jmodFile_ != null) {
|
||||||
|
toolArgs(jmodFile_);
|
||||||
|
}
|
||||||
|
|
||||||
|
super.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the name of the JMOD file to create or from which to retrieve information.
|
||||||
|
*
|
||||||
|
* @return the JMOD file
|
||||||
|
*/
|
||||||
|
public String jmodFile() {
|
||||||
|
return jmodFile_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies name of the JMOD file to create or from which to retrieve information.
|
||||||
|
* <p>
|
||||||
|
* The JMOD file is <b>required</b>.
|
||||||
|
*
|
||||||
|
* @param file the JMOD file
|
||||||
|
* @return this operation instance
|
||||||
|
*/
|
||||||
|
public JmodOperation jmodFile(String file) {
|
||||||
|
jmodFile_ = file;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies name of the JMOD file to create or from which to retrieve information.
|
||||||
|
* <p>
|
||||||
|
* The JMOD file is <b>required</b>.
|
||||||
|
*
|
||||||
|
* @param file the JMOD file
|
||||||
|
* @return this operation instance
|
||||||
|
*/
|
||||||
|
public JmodOperation jmodFile(File file) {
|
||||||
|
return jmodFile(file.getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies name of the JMOD file to create or from which to retrieve information.
|
||||||
|
* <p>
|
||||||
|
* The JMOD file is <b>required</b>.
|
||||||
|
*
|
||||||
|
* @param file the JMOD file
|
||||||
|
* @return this operation instance
|
||||||
|
*/
|
||||||
|
public JmodOperation jmodFile(Path file) {
|
||||||
|
return jmodFile(file.toFile().getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the list of options for the jmod tool.
|
||||||
|
* <p>
|
||||||
|
* This is a modifiable list that can be retrieved and changed.
|
||||||
|
*
|
||||||
|
* @return the map of jmod options
|
||||||
|
*/
|
||||||
|
public JmodOptions jmodOptions() {
|
||||||
|
return jmodOptions_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides a list of options to provide to the jmod tool.
|
||||||
|
* <p>
|
||||||
|
* A copy will be created to allow this list to be independently modifiable.
|
||||||
|
*
|
||||||
|
* @param options the list of jmod options
|
||||||
|
* @return this operation instance
|
||||||
|
*/
|
||||||
|
public JmodOperation jmodOptions(Map<String, String> options) {
|
||||||
|
jmodOptions_.putAll(options);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the {@link OperationMode operation mode}.
|
||||||
|
* <p>
|
||||||
|
* The operation mode is <b>required</b>.
|
||||||
|
*
|
||||||
|
* @param mode the mode
|
||||||
|
* @return this operation instance
|
||||||
|
*/
|
||||||
|
public JmodOperation operationMode(OperationMode mode) {
|
||||||
|
operationMode_ = mode;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The operation modes.
|
||||||
|
*/
|
||||||
|
public enum OperationMode {
|
||||||
|
/**
|
||||||
|
* Creates a new JMOD archive file.
|
||||||
|
*/
|
||||||
|
CREATE("create"),
|
||||||
|
/**
|
||||||
|
* Prints the module details.
|
||||||
|
*/
|
||||||
|
DESCRIBE("describe"),
|
||||||
|
/**
|
||||||
|
* Extracts all the files from the JMOD archive file.
|
||||||
|
*/
|
||||||
|
EXTRACT("extract"),
|
||||||
|
/**
|
||||||
|
* Determines leaf modules and records the hashes of the dependencies that directly and indirectly require them.
|
||||||
|
*/
|
||||||
|
HASH("hash"),
|
||||||
|
/**
|
||||||
|
* Prints the names of all the entries.
|
||||||
|
*/
|
||||||
|
LIST("list");
|
||||||
|
|
||||||
|
final String mode;
|
||||||
|
|
||||||
|
OperationMode(String mode) {
|
||||||
|
this.mode = mode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
473
src/main/java/rife/bld/operations/JmodOptions.java
Normal file
473
src/main/java/rife/bld/operations/JmodOptions.java
Normal file
|
|
@ -0,0 +1,473 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2024 Erik C. Thauvin (https://erik.thauvin.net/)
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||||
|
*/
|
||||||
|
package rife.bld.operations;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.time.temporal.ChronoUnit;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Options for jmod tool.
|
||||||
|
*
|
||||||
|
* @author <a href="https://erik.thauvin.net/">Erik C. Thauvin</a>
|
||||||
|
* @since 2.1.0
|
||||||
|
*/
|
||||||
|
public class JmodOptions extends LinkedHashMap<String, String> {
|
||||||
|
/**
|
||||||
|
* Application jar files|dir containing classes.
|
||||||
|
*
|
||||||
|
* @param classpath the classpath
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JmodOptions classpath(String classpath) {
|
||||||
|
put("--class-path", classpath);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Location of native commands.
|
||||||
|
*
|
||||||
|
* @param path the location
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JmodOptions cmds(String path) {
|
||||||
|
put("--cmds", path);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Location of native commands.
|
||||||
|
*
|
||||||
|
* @param path the location
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("UnusedReturnValue")
|
||||||
|
public JmodOptions cmds(File path) {
|
||||||
|
return cmds(path.getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Location of native commands.
|
||||||
|
*
|
||||||
|
* @param path the location
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JmodOptions cmds(Path path) {
|
||||||
|
return cmds(path.toFile().getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compression to use when creating the JMOD archive.
|
||||||
|
* <p>
|
||||||
|
* <b>Requires Java 20 or higher</b>.
|
||||||
|
* <p>
|
||||||
|
* Where {@link ZipCompression#ZIP_0 ZIP_0} provides no compression and {@link ZipCompression#ZIP_9 ZIP_9} provides the
|
||||||
|
* best compression.
|
||||||
|
* <p>
|
||||||
|
* Default is {@link ZipCompression#ZIP_6 ZIP_6}
|
||||||
|
*
|
||||||
|
* @param compression the {@link ZipCompression compression} level
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("UnusedReturnValue")
|
||||||
|
public JmodOptions compress(ZipCompression compression) {
|
||||||
|
put("--compress", compression.level);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Location of user-editable config files
|
||||||
|
*
|
||||||
|
* @param path the path to the config files
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JmodOptions config(String path) {
|
||||||
|
put("--config", path);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Location of user-editable config files
|
||||||
|
*
|
||||||
|
* @param path the path to the config files
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JmodOptions config(File path) {
|
||||||
|
return config(path.getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Location of user-editable config files
|
||||||
|
*
|
||||||
|
* @param path the path to the config files
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JmodOptions config(Path path) {
|
||||||
|
return config(path.toFile().getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Date and time for the timestamps of entries.
|
||||||
|
*
|
||||||
|
* @param date the date
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JmodOptions date(ZonedDateTime date) {
|
||||||
|
put("--date", date.truncatedTo(ChronoUnit.SECONDS).format(DateTimeFormatter.ISO_INSTANT));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Target directory for extract
|
||||||
|
*
|
||||||
|
* @param path the directory path
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JmodOptions dir(String path) {
|
||||||
|
put("--dir", path);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Target directory for extract
|
||||||
|
*
|
||||||
|
* @param path the directory path
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JmodOptions dir(File path) {
|
||||||
|
return dir(path.getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Target directory for extract
|
||||||
|
*
|
||||||
|
* @param path the directory path
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JmodOptions dir(Path path) {
|
||||||
|
return dir(path.toFile().getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exclude from the default root set of modules.
|
||||||
|
*
|
||||||
|
* @param doNotResolveByDefault {@code true} to not resolve, {@code false} otherwise
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JmodOptions doNotResolveByDefault(boolean doNotResolveByDefault) {
|
||||||
|
if (doNotResolveByDefault) {
|
||||||
|
put("--do-not-resolve-by-default");
|
||||||
|
} else {
|
||||||
|
remove("--do-not-resolve-by-default");
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dry run of hash mode.
|
||||||
|
*
|
||||||
|
* @param dryRun {@code true} for dry run, {@code false} otherwise
|
||||||
|
* @return this list of operation
|
||||||
|
*/
|
||||||
|
public JmodOptions dryRun(boolean dryRun) {
|
||||||
|
if (dryRun) {
|
||||||
|
put("--dry-run");
|
||||||
|
} else {
|
||||||
|
remove("--dry-run");
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exclude files matching the supplied pattern list.
|
||||||
|
*
|
||||||
|
* @param patterns one or more patterns
|
||||||
|
* @return the map of options
|
||||||
|
*/
|
||||||
|
public JmodOptions exclude(List<FilePattern> patterns) {
|
||||||
|
var args = new ArrayList<String>();
|
||||||
|
for (var p : patterns) {
|
||||||
|
if (p.type == FilePatternType.GLOB) {
|
||||||
|
args.add("glob:" + p.pattern);
|
||||||
|
} else if (p.type == FilePatternType.REGEX) {
|
||||||
|
args.add("regex:" + p.pattern);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
put("--exclude", String.join(",", args));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exclude files matching the supplied pattern list.
|
||||||
|
*
|
||||||
|
* @param patterns one or more patterns
|
||||||
|
* @return the map of options
|
||||||
|
*/
|
||||||
|
public JmodOptions exclude(FilePattern... patterns) {
|
||||||
|
return exclude(List.of(patterns));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute and record hashes to tie a packaged module with modules matching the given regular expression pattern and
|
||||||
|
* depending upon it directly or indirectly. The hashes are recorded in the JMOD file being created, or a JMOD file
|
||||||
|
* or modular JAR on the module path specified the jmod hash command.
|
||||||
|
*
|
||||||
|
* @param regexPattern the regular expression pattern
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JmodOptions hashModules(String regexPattern) {
|
||||||
|
put("--hash-modules", regexPattern);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Location of header files.
|
||||||
|
*
|
||||||
|
* @param path the location
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JmodOptions headerFiles(String path) {
|
||||||
|
put("--header-files", path);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Location of header files.
|
||||||
|
*
|
||||||
|
* @param path the location
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("UnusedReturnValue")
|
||||||
|
public JmodOptions headerFiles(File path) {
|
||||||
|
return headerFiles(path.getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Location of header files.
|
||||||
|
*
|
||||||
|
* @param path the location
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JmodOptions headerFiles(Path path) {
|
||||||
|
return headerFiles(path.toFile().getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Location of legal notices.
|
||||||
|
*
|
||||||
|
* @param path the location
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JmodOptions legalNotices(String path) {
|
||||||
|
put("--legal-notices", path);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Location of legal notices.
|
||||||
|
*
|
||||||
|
* @param path the location
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("UnusedReturnValue")
|
||||||
|
public JmodOptions legalNotices(File path) {
|
||||||
|
return legalNotices(path.getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Location of legal notices.
|
||||||
|
*
|
||||||
|
* @param path the location
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JmodOptions legalNotices(Path path) {
|
||||||
|
return legalNotices(path.toFile().getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Location of native libraries.
|
||||||
|
*
|
||||||
|
* @param path the location
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JmodOptions libs(String path) {
|
||||||
|
put("--libs", path);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Location of native libraries.
|
||||||
|
*
|
||||||
|
* @param path the location
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("UnusedReturnValue")
|
||||||
|
public JmodOptions libs(File path) {
|
||||||
|
return libs(path.getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Location of native libraries.
|
||||||
|
*
|
||||||
|
* @param path the location
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JmodOptions libs(Path path) {
|
||||||
|
return libs(path.toFile().getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main class.
|
||||||
|
*
|
||||||
|
* @param name the class name
|
||||||
|
* @return this list of operation
|
||||||
|
*/
|
||||||
|
public JmodOptions mainClass(String name) {
|
||||||
|
put("--main-class", name);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Location of man pages.
|
||||||
|
*
|
||||||
|
* @param path the location
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JmodOptions manPages(String path) {
|
||||||
|
put("--man-pages", path);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Location of man pages.
|
||||||
|
*
|
||||||
|
* @param path the location
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("UnusedReturnValue")
|
||||||
|
public JmodOptions manPages(File path) {
|
||||||
|
return manPages(path.getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Location of man pages.
|
||||||
|
*
|
||||||
|
* @param path the location
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JmodOptions manPages(Path path) {
|
||||||
|
return manPages(path.toFile().getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module path.
|
||||||
|
*
|
||||||
|
* @param path the module path
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JmodOptions modulePath(String path) {
|
||||||
|
put("--module-path", path);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module path.
|
||||||
|
*
|
||||||
|
* @param path the module path
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JmodOptions modulePath(File path) {
|
||||||
|
return modulePath(path.getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module path.
|
||||||
|
*
|
||||||
|
* @param path the module path
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JmodOptions modulePath(Path path) {
|
||||||
|
return modulePath(path.toFile().getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module version.
|
||||||
|
*
|
||||||
|
* @param version the module version.
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JmodOptions moduleVersion(String version) {
|
||||||
|
put("--module-version", version);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Associates {@code null} with the specified key in this map. If the map previously contained a mapping for the
|
||||||
|
* key, the old value is replaced.
|
||||||
|
*
|
||||||
|
* @param key key with which the specified value is to be associated
|
||||||
|
*/
|
||||||
|
public void put(String key) {
|
||||||
|
put(key, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Target platform.
|
||||||
|
*
|
||||||
|
* @param platform the platform
|
||||||
|
* @return this list of operation
|
||||||
|
*/
|
||||||
|
public JmodOptions targetPlatform(String platform) {
|
||||||
|
put("--target-platform", platform);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hint for a tool to issue a warning if the module is resolved.
|
||||||
|
*
|
||||||
|
* @param reason the reason
|
||||||
|
* @return this map of options
|
||||||
|
*/
|
||||||
|
public JmodOptions warnIfResolved(ResolvedReason reason) {
|
||||||
|
put("--warn-if-resolved", reason.reason);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The resolved reasons.
|
||||||
|
*/
|
||||||
|
public enum ResolvedReason {
|
||||||
|
DEPRECATED("deprecated"),
|
||||||
|
DEPRECATED_FOR_REMOVAL("deprecated-for-removal"),
|
||||||
|
INCUBATING("incubating");
|
||||||
|
|
||||||
|
final String reason;
|
||||||
|
|
||||||
|
ResolvedReason(String reason) {
|
||||||
|
this.reason = reason;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The file pattern types.
|
||||||
|
*/
|
||||||
|
public enum FilePatternType {
|
||||||
|
GLOB, REGEX
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines a file pattern and pattern type.
|
||||||
|
*
|
||||||
|
* @param type the pattern type
|
||||||
|
* @param pattern the pattern
|
||||||
|
*/
|
||||||
|
public record FilePattern(FilePatternType type, String pattern) {
|
||||||
|
}
|
||||||
|
}
|
||||||
124
src/main/java/rife/bld/operations/JpackageOperation.java
Normal file
124
src/main/java/rife/bld/operations/JpackageOperation.java
Normal file
|
|
@ -0,0 +1,124 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2024 Erik C. Thauvin (https://erik.thauvin.net/)
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||||
|
*/
|
||||||
|
package rife.bld.operations;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Package self-contained Java applications with the jpackage tool.
|
||||||
|
*
|
||||||
|
* @author <a href="https://erik.thauvin.net/">Erik C. Thauvin</a>
|
||||||
|
* @since 2.1.0
|
||||||
|
*/
|
||||||
|
public class JpackageOperation extends AbstractToolProviderOperation<JpackageOperation> {
|
||||||
|
private final JpackageOptions jpackageOptions_ = new JpackageOptions();
|
||||||
|
private final List<Launcher> launchers_ = new ArrayList<>();
|
||||||
|
|
||||||
|
public JpackageOperation() {
|
||||||
|
super("jpackage");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of application launchers.
|
||||||
|
* <p>
|
||||||
|
* The main application launcher will be built from the command line options.
|
||||||
|
* <p>
|
||||||
|
* Additional alternative launchers can be built using this option, and this option can be used to build multiple
|
||||||
|
* additional launchers.
|
||||||
|
*
|
||||||
|
* @param launchers one or more {@link Launcher launchers}
|
||||||
|
* @return this operation instance
|
||||||
|
*/
|
||||||
|
public JpackageOperation addLauncher(List<Launcher> launchers) {
|
||||||
|
launchers_.addAll(launchers);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of application launchers.
|
||||||
|
* <p>
|
||||||
|
* The main application launcher will be built from the command line options.
|
||||||
|
* <p>
|
||||||
|
* Additional alternative launchers can be built using this option, and this option can be used to build multiple
|
||||||
|
* additional launchers.
|
||||||
|
*
|
||||||
|
* @param launchers one or more {@link Launcher launchers}
|
||||||
|
* @return this operation instance
|
||||||
|
*/
|
||||||
|
public JpackageOperation addLauncher(Launcher... launchers) {
|
||||||
|
return addLauncher(List.of(launchers));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute() throws Exception {
|
||||||
|
toolArgs(cmdFiles().stream().map(opt -> '@' + opt).toList());
|
||||||
|
for (var l : launchers_) {
|
||||||
|
toolArgs("--add-launcher", l.name + '=' + l.path);
|
||||||
|
}
|
||||||
|
toolArgs(jpackageOptions_);
|
||||||
|
super.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the list of options for the jpackage tool.
|
||||||
|
* <p>
|
||||||
|
* This is a modifiable list that can be retrieved and changed.
|
||||||
|
*
|
||||||
|
* @return the map of jpackage options
|
||||||
|
*/
|
||||||
|
public JpackageOptions jpackageOptions() {
|
||||||
|
return jpackageOptions_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides a list of options to provide to the jpackage tool.
|
||||||
|
* <p>
|
||||||
|
* A copy will be created to allow this list to be independently modifiable.
|
||||||
|
*
|
||||||
|
* @param options the map of jpackage options
|
||||||
|
* @return this operation instance
|
||||||
|
*/
|
||||||
|
public JpackageOperation jpackageOptions(Map<String, String> options) {
|
||||||
|
jpackageOptions_.putAll(options);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the list of application launchers.
|
||||||
|
*
|
||||||
|
* @return the list of launchers
|
||||||
|
*/
|
||||||
|
public List<Launcher> launchers() {
|
||||||
|
return launchers_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Name of launcher, and a path to a Properties file that contains a list of key, value pairs.
|
||||||
|
* <p>
|
||||||
|
* The keys {@code module}, {@code main-jar}, {@code main-class}, {@code description},
|
||||||
|
* {@code arguments}, {@code java-options}, {@code app-version}, {@code icon},
|
||||||
|
* {@code launcher-as-service}, {@code win-console}, {@code win-shortcut}, {@code win-menu},
|
||||||
|
* {@code linux-app-category}, and {@code linux-shortcut} can be used.
|
||||||
|
* <p>
|
||||||
|
* These options are added to, or used to overwrite, the original command line options to build an additional
|
||||||
|
* alternative launcher.
|
||||||
|
*
|
||||||
|
* @param name the name
|
||||||
|
* @param path absolute path or relative to the current directory
|
||||||
|
*/
|
||||||
|
public record Launcher(String name, String path) {
|
||||||
|
public Launcher(String name, File path) {
|
||||||
|
this(name, path.getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Launcher(String name, Path path) {
|
||||||
|
this(name, path.toFile().getAbsolutePath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
1338
src/main/java/rife/bld/operations/JpackageOptions.java
Normal file
1338
src/main/java/rife/bld/operations/JpackageOptions.java
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -9,9 +9,11 @@ import rife.bld.BldVersion;
|
||||||
import rife.bld.dependencies.*;
|
import rife.bld.dependencies.*;
|
||||||
import rife.bld.dependencies.exceptions.DependencyException;
|
import rife.bld.dependencies.exceptions.DependencyException;
|
||||||
import rife.bld.operations.exceptions.OperationOptionException;
|
import rife.bld.operations.exceptions.OperationOptionException;
|
||||||
|
import rife.bld.operations.exceptions.RestApiException;
|
||||||
import rife.bld.operations.exceptions.SignException;
|
import rife.bld.operations.exceptions.SignException;
|
||||||
import rife.bld.operations.exceptions.UploadException;
|
import rife.bld.operations.exceptions.UploadException;
|
||||||
import rife.bld.publish.*;
|
import rife.bld.publish.*;
|
||||||
|
import rife.ioc.HierarchicalProperties;
|
||||||
import rife.tools.FileUtils;
|
import rife.tools.FileUtils;
|
||||||
import rife.tools.exceptions.FileUtilsErrorException;
|
import rife.tools.exceptions.FileUtilsErrorException;
|
||||||
|
|
||||||
|
|
@ -26,7 +28,9 @@ import java.time.ZoneId;
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import static rife.bld.dependencies.Dependency.*;
|
||||||
import static rife.bld.publish.MetadataBuilder.SNAPSHOT_TIMESTAMP_FORMATTER;
|
import static rife.bld.publish.MetadataBuilder.SNAPSHOT_TIMESTAMP_FORMATTER;
|
||||||
import static rife.tools.HttpUtils.*;
|
import static rife.tools.HttpUtils.*;
|
||||||
import static rife.tools.StringUtils.encodeHexLower;
|
import static rife.tools.StringUtils.encodeHexLower;
|
||||||
|
|
@ -38,6 +42,11 @@ import static rife.tools.StringUtils.encodeHexLower;
|
||||||
* @since 1.5.7
|
* @since 1.5.7
|
||||||
*/
|
*/
|
||||||
public class PublishOperation extends AbstractOperation<PublishOperation> {
|
public class PublishOperation extends AbstractOperation<PublishOperation> {
|
||||||
|
private static final String OSSRH_STAGING_MANUAL_SEARCH = "https://" + Repository.OSSRH_STAGING_API_DOMAIN + "/manual/search/repositories";
|
||||||
|
private static final String OSSRH_STAGING_MANUAL_UPLOAD = "https://" + Repository.OSSRH_STAGING_API_DOMAIN + "/manual/upload/repository/";
|
||||||
|
|
||||||
|
private boolean offline_ = false;
|
||||||
|
private HierarchicalProperties properties_ = null;
|
||||||
private ArtifactRetriever retriever_ = null;
|
private ArtifactRetriever retriever_ = null;
|
||||||
private final HttpClient client_ = HttpClient.newHttpClient();
|
private final HttpClient client_ = HttpClient.newHttpClient();
|
||||||
|
|
||||||
|
|
@ -45,6 +54,7 @@ public class PublishOperation extends AbstractOperation<PublishOperation> {
|
||||||
private final List<Repository> repositories_ = new ArrayList<>();
|
private final List<Repository> repositories_ = new ArrayList<>();
|
||||||
private final DependencyScopes dependencies_ = new DependencyScopes();
|
private final DependencyScopes dependencies_ = new DependencyScopes();
|
||||||
private PublishInfo info_ = new PublishInfo();
|
private PublishInfo info_ = new PublishInfo();
|
||||||
|
private PublishProperties publishProperties_ = new PublishProperties();
|
||||||
private final List<PublishArtifact> artifacts_ = new ArrayList<>();
|
private final List<PublishArtifact> artifacts_ = new ArrayList<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -53,6 +63,11 @@ public class PublishOperation extends AbstractOperation<PublishOperation> {
|
||||||
* @since 1.5.7
|
* @since 1.5.7
|
||||||
*/
|
*/
|
||||||
public void execute() {
|
public void execute() {
|
||||||
|
if (offline_) {
|
||||||
|
System.out.println("Offline mode: publish is disabled");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (repositories().isEmpty()) {
|
if (repositories().isEmpty()) {
|
||||||
throw new OperationOptionException("ERROR: the publication repositories should be specified");
|
throw new OperationOptionException("ERROR: the publication repositories should be specified");
|
||||||
}
|
}
|
||||||
|
|
@ -77,6 +92,11 @@ public class PublishOperation extends AbstractOperation<PublishOperation> {
|
||||||
executePublishArtifacts(repository, actual_version);
|
executePublishArtifacts(repository, actual_version);
|
||||||
executePublishPom(repository, actual_version);
|
executePublishPom(repository, actual_version);
|
||||||
executePublishMetadata(repository, moment);
|
executePublishMetadata(repository, moment);
|
||||||
|
|
||||||
|
if (!info().version().isSnapshot() &&
|
||||||
|
repository.location().contains(Repository.OSSRH_STAGING_API_DOMAIN)) {
|
||||||
|
executeCloseOSSRHStagingRepository(repository);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!silent()) {
|
if (!silent()) {
|
||||||
System.out.println("Publishing finished successfully.");
|
System.out.println("Publishing finished successfully.");
|
||||||
|
|
@ -104,13 +124,13 @@ public class PublishOperation extends AbstractOperation<PublishOperation> {
|
||||||
*
|
*
|
||||||
* @param repository the repository to publish to
|
* @param repository the repository to publish to
|
||||||
* @param moment the timestamp at which the operation started executing
|
* @param moment the timestamp at which the operation started executing
|
||||||
* @return the adapted version number with the snapshot timestamp and build number
|
* @return the adapted version with the snapshot timestamp and build number
|
||||||
* @since 1.5.10
|
* @since 1.5.10
|
||||||
*/
|
*/
|
||||||
protected VersionNumber executePublishSnapshotMetadata(Repository repository, ZonedDateTime moment) {
|
protected Version executePublishSnapshotMetadata(Repository repository, ZonedDateTime moment) {
|
||||||
var metadata = new MetadataBuilder();
|
var metadata = new MetadataBuilder();
|
||||||
|
|
||||||
VersionNumber actual_version;
|
Version actual_version;
|
||||||
if (repository.isLocal()) {
|
if (repository.isLocal()) {
|
||||||
actual_version = info().version();
|
actual_version = info().version();
|
||||||
metadata.snapshotLocal();
|
metadata.snapshotLocal();
|
||||||
|
|
@ -120,16 +140,21 @@ public class PublishOperation extends AbstractOperation<PublishOperation> {
|
||||||
// determine which build number to use
|
// determine which build number to use
|
||||||
var snapshot_build_number = 1;
|
var snapshot_build_number = 1;
|
||||||
try {
|
try {
|
||||||
var resolver = new DependencyResolver(artifactRetriever(), List.of(repository), new Dependency(info().groupId(), info().artifactId(), info().version()));
|
var resolution = new VersionResolution(properties());
|
||||||
|
var resolver = new DependencyResolver(resolution, artifactRetriever(), List.of(repository), new Dependency(info().groupId(), info().artifactId(), info().version()));
|
||||||
var snapshot_meta = resolver.getSnapshotMavenMetadata();
|
var snapshot_meta = resolver.getSnapshotMavenMetadata();
|
||||||
snapshot_build_number = snapshot_meta.getSnapshotBuildNumber() + 1;
|
var build_number_meta = snapshot_meta.getSnapshotBuildNumber();
|
||||||
|
if (build_number_meta == null) {
|
||||||
|
throw new DependencyException("Snapshot metadata build number doesn't exist.");
|
||||||
|
}
|
||||||
|
snapshot_build_number = build_number_meta + 1;
|
||||||
} catch (DependencyException e) {
|
} catch (DependencyException e) {
|
||||||
// start the build number from the beginning
|
// start the build number from the beginning
|
||||||
System.out.println("Unable to retrieve previous snapshot metadata, using first build number.");
|
System.out.println("Unable to retrieve previous snapshot metadata, using first build number.");
|
||||||
System.out.println("This is expected for a first publication or for publication to a staging repository.");
|
System.out.println("This is expected for a first publication or for publication to a staging repository.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// adapt the actual version that's use by the artifacts
|
// adapt the actual version used by the artifacts
|
||||||
var snapshot_qualifier = snapshot_timestamp + "-" + snapshot_build_number;
|
var snapshot_qualifier = snapshot_timestamp + "-" + snapshot_build_number;
|
||||||
actual_version = info().version().withQualifier(snapshot_qualifier);
|
actual_version = info().version().withQualifier(snapshot_qualifier);
|
||||||
|
|
||||||
|
|
@ -150,7 +175,7 @@ public class PublishOperation extends AbstractOperation<PublishOperation> {
|
||||||
.info(info())
|
.info(info())
|
||||||
.updated(moment)
|
.updated(moment)
|
||||||
.build(),
|
.build(),
|
||||||
info().version() + "/" + repository.getMetadataName(), true);
|
info().version() + "/" + repository.getMetadataName(), false);
|
||||||
return actual_version;
|
return actual_version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -162,18 +187,18 @@ public class PublishOperation extends AbstractOperation<PublishOperation> {
|
||||||
* @param actualVersion the version that was potentially adapted if this is a snapshot
|
* @param actualVersion the version that was potentially adapted if this is a snapshot
|
||||||
* @since 1.5.10
|
* @since 1.5.10
|
||||||
*/
|
*/
|
||||||
protected void executePublishArtifacts(Repository repository, VersionNumber actualVersion) {
|
protected void executePublishArtifacts(Repository repository, Version actualVersion) {
|
||||||
// upload artifacts
|
// upload artifacts
|
||||||
for (var artifact : artifacts()) {
|
for (var artifact : artifacts()) {
|
||||||
var artifact_name = new StringBuilder(info().artifactId()).append("-").append(actualVersion);
|
var artifact_name = new StringBuilder(info().artifactId()).append('-').append(actualVersion);
|
||||||
if (!artifact.classifier().isEmpty()) {
|
if (!artifact.classifier().isEmpty()) {
|
||||||
artifact_name.append("-").append(artifact.classifier());
|
artifact_name.append('-').append(artifact.classifier());
|
||||||
}
|
}
|
||||||
var type = artifact.type();
|
var type = artifact.type();
|
||||||
if (type == null) {
|
if (TYPE_JAR.equals(type) || TYPE_MODULAR_JAR.equals(type) || TYPE_CLASSPATH_JAR.equals(type)) {
|
||||||
type = "jar";
|
type = TYPE_JAR;
|
||||||
}
|
}
|
||||||
artifact_name.append(".").append(type);
|
artifact_name.append('.').append(type);
|
||||||
|
|
||||||
executePublishFileArtifact(repository, artifact.file(), info().version() + "/" + artifact_name);
|
executePublishFileArtifact(repository, artifact.file(), info().version() + "/" + artifact_name);
|
||||||
}
|
}
|
||||||
|
|
@ -186,11 +211,11 @@ public class PublishOperation extends AbstractOperation<PublishOperation> {
|
||||||
* @param actualVersion the version that was potentially adapted if this is a snapshot
|
* @param actualVersion the version that was potentially adapted if this is a snapshot
|
||||||
* @since 1.5.10
|
* @since 1.5.10
|
||||||
*/
|
*/
|
||||||
protected void executePublishPom(Repository repository, VersionNumber actualVersion) {
|
protected void executePublishPom(Repository repository, Version actualVersion) {
|
||||||
// generate and upload pom
|
// generate and upload pom
|
||||||
executePublishStringArtifact(
|
executePublishStringArtifact(
|
||||||
repository,
|
repository,
|
||||||
new PomBuilder().info(info()).dependencies(dependencies()).build(),
|
new PomBuilder().properties(publishProperties()).info(info()).dependencies(dependencies()).build(),
|
||||||
info().version() + "/" + info().artifactId() + "-" + actualVersion + ".pom", true);
|
info().version() + "/" + info().artifactId() + "-" + actualVersion + ".pom", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -202,8 +227,9 @@ public class PublishOperation extends AbstractOperation<PublishOperation> {
|
||||||
* @since 1.5.8
|
* @since 1.5.8
|
||||||
*/
|
*/
|
||||||
protected void executePublishMetadata(Repository repository, ZonedDateTime moment) {
|
protected void executePublishMetadata(Repository repository, ZonedDateTime moment) {
|
||||||
var current_versions = new ArrayList<VersionNumber>();
|
var current_versions = new ArrayList<Version>();
|
||||||
var resolver = new DependencyResolver(artifactRetriever(), List.of(repository), new Dependency(info().groupId(), info().artifactId(), info().version()));
|
var resolution = new VersionResolution(properties());
|
||||||
|
var resolver = new DependencyResolver(resolution, artifactRetriever(), List.of(repository), new Dependency(info().groupId(), info().artifactId(), info().version()));
|
||||||
try {
|
try {
|
||||||
current_versions.addAll(resolver.getMavenMetadata().getVersions());
|
current_versions.addAll(resolver.getMavenMetadata().getVersions());
|
||||||
} catch (DependencyException e) {
|
} catch (DependencyException e) {
|
||||||
|
|
@ -458,12 +484,8 @@ public class PublishOperation extends AbstractOperation<PublishOperation> {
|
||||||
var builder = HttpRequest.newBuilder()
|
var builder = HttpRequest.newBuilder()
|
||||||
.PUT(body)
|
.PUT(body)
|
||||||
.uri(URI.create(url))
|
.uri(URI.create(url))
|
||||||
.header(HEADER_USER_AGENT, "bld/" + BldVersion.getVersion() +
|
.header(HEADER_USER_AGENT, constructBldUserAgent());
|
||||||
" (" + System.getProperty("os.name") + "; " + System.getProperty("os.version") + "; " + System.getProperty("os.arch") + ") " +
|
applyAuthorization(repository, builder);
|
||||||
"(" + System.getProperty("java.vendor") + " " + System.getProperty("java.vm.name") + "; " + System.getProperty("java.version") + "; " + System.getProperty("java.vm.version") + ")");
|
|
||||||
if (repository.username() != null && repository.password() != null) {
|
|
||||||
builder.header(HEADER_AUTHORIZATION, basicAuthorizationHeader(repository.username(), repository.password()));
|
|
||||||
}
|
|
||||||
var request = builder.build();
|
var request = builder.build();
|
||||||
|
|
||||||
HttpResponse<String> response;
|
HttpResponse<String> response;
|
||||||
|
|
@ -489,6 +511,105 @@ public class PublishOperation extends AbstractOperation<PublishOperation> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String constructBldUserAgent() {
|
||||||
|
return "bld/" + BldVersion.getVersion() +
|
||||||
|
" (" + System.getProperty("os.name") + "; " + System.getProperty("os.version") + "; " + System.getProperty("os.arch") + ") " +
|
||||||
|
"(" + System.getProperty("java.vendor") + " " + System.getProperty("java.vm.name") + "; " + System.getProperty("java.version") + "; " + System.getProperty("java.vm.version") + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void applyAuthorization(Repository repository, HttpRequest.Builder builder) {
|
||||||
|
if (repository.username() != null && repository.password() != null) {
|
||||||
|
builder.header(HEADER_AUTHORIZATION, basicAuthorizationHeader(repository.username(), repository.password()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Part of the {@link #execute} operation, closes the OSSRH staging API repository.
|
||||||
|
*
|
||||||
|
* @param repository the repository to close a staging repository in
|
||||||
|
* @since 2.2.2
|
||||||
|
*/
|
||||||
|
protected void executeCloseOSSRHStagingRepository(Repository repository) {
|
||||||
|
var url_search = OSSRH_STAGING_MANUAL_SEARCH;
|
||||||
|
System.out.print("Finding open staging repositories at: " + url_search + " ... ");
|
||||||
|
System.out.flush();
|
||||||
|
try {
|
||||||
|
var builder_search = HttpRequest.newBuilder()
|
||||||
|
.GET()
|
||||||
|
.uri(URI.create(url_search))
|
||||||
|
.header(HEADER_USER_AGENT, constructBldUserAgent());
|
||||||
|
applyAuthorization(repository, builder_search);
|
||||||
|
var request_list = builder_search.build();
|
||||||
|
|
||||||
|
HttpResponse<String> response_search;
|
||||||
|
try {
|
||||||
|
response_search = client_.send(request_list, HttpResponse.BodyHandlers.ofString());
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.out.print("I/O error");
|
||||||
|
throw new RestApiException(url_search, e);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
System.out.print("interrupted");
|
||||||
|
throw new RestApiException(url_search, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response_search.statusCode() >= 200 &&
|
||||||
|
response_search.statusCode() < 300) {
|
||||||
|
System.out.println("done");
|
||||||
|
|
||||||
|
var pattern_key = Pattern.compile("\\{\\s*\"key\"\\s*:\\s*\"([^\"]+)\"\\s*,\\s*\"state\"\\s*:\\s*\"open\"");
|
||||||
|
var matcher_key = pattern_key.matcher(response_search.body());
|
||||||
|
if (matcher_key.find()) {
|
||||||
|
var key = matcher_key.group(1);
|
||||||
|
System.out.println("Found open staging repository with key: " + key);
|
||||||
|
|
||||||
|
var url_close = OSSRH_STAGING_MANUAL_UPLOAD + key;
|
||||||
|
System.out.print("Closing the staging repository at: " + url_close + " ... ");
|
||||||
|
System.out.flush();
|
||||||
|
var builder_close = HttpRequest.newBuilder()
|
||||||
|
.POST(BodyPublishers.ofString(""))
|
||||||
|
.uri(URI.create(url_close))
|
||||||
|
.header(HEADER_USER_AGENT, constructBldUserAgent());
|
||||||
|
applyAuthorization(repository, builder_close);
|
||||||
|
var request_close = builder_close.build();
|
||||||
|
|
||||||
|
HttpResponse<String> response_close;
|
||||||
|
try {
|
||||||
|
response_close = client_.send(request_close, HttpResponse.BodyHandlers.ofString());
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.out.print("I/O error");
|
||||||
|
throw new RestApiException(url_close, e);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
System.out.print("interrupted");
|
||||||
|
throw new RestApiException(url_close, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response_close.statusCode() >= 200 &&
|
||||||
|
response_close.statusCode() < 300) {
|
||||||
|
System.out.print("done");
|
||||||
|
} else {
|
||||||
|
System.out.println("failed");
|
||||||
|
var pattern_error = Pattern.compile("\\s*\"error\"\\s*:\\s*\"([^\"]*)\"");
|
||||||
|
var matcher_error = pattern_error.matcher(response_close.body());
|
||||||
|
if (matcher_error.find()) {
|
||||||
|
var error = matcher_error.group(1);
|
||||||
|
System.out.print(error.translateEscapes());
|
||||||
|
}
|
||||||
|
throw new RestApiException(url_close, response_close.statusCode());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
System.out.print("No open staging repository found.");
|
||||||
|
throw new RestApiException(url_search);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
System.out.print("failed");
|
||||||
|
throw new RestApiException(url_search, response_search.statusCode());
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
System.out.println();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configures a publish operation from a {@link BaseProject}.
|
* Configures a publish operation from a {@link BaseProject}.
|
||||||
*
|
*
|
||||||
|
|
@ -496,12 +617,19 @@ public class PublishOperation extends AbstractOperation<PublishOperation> {
|
||||||
* @since 1.5.7
|
* @since 1.5.7
|
||||||
*/
|
*/
|
||||||
public PublishOperation fromProject(BaseProject project) {
|
public PublishOperation fromProject(BaseProject project) {
|
||||||
|
if (project.javaRelease() != null) {
|
||||||
|
publishProperties()
|
||||||
|
.mavenCompilerSource(project.javaRelease())
|
||||||
|
.mavenCompilerTarget(project.javaRelease());
|
||||||
|
}
|
||||||
|
offline(project.offline());
|
||||||
|
properties(project.properties());
|
||||||
artifactRetriever(project.artifactRetriever());
|
artifactRetriever(project.artifactRetriever());
|
||||||
dependencies().include(project.dependencies());
|
dependencies().include(project.dependencies());
|
||||||
artifacts(List.of(
|
artifacts(List.of(
|
||||||
new PublishArtifact(new File(project.buildDistDirectory(), project.jarFileName()), "", "jar"),
|
new PublishArtifact(new File(project.buildDistDirectory(), project.jarFileName()), "", TYPE_JAR),
|
||||||
new PublishArtifact(new File(project.buildDistDirectory(), project.sourcesJarFileName()), "sources", "jar"),
|
new PublishArtifact(new File(project.buildDistDirectory(), project.sourcesJarFileName()), CLASSIFIER_SOURCES, TYPE_JAR),
|
||||||
new PublishArtifact(new File(project.buildDistDirectory(), project.javadocJarFileName()), "javadoc", "jar")));
|
new PublishArtifact(new File(project.buildDistDirectory(), project.javadocJarFileName()), CLASSIFIER_JAVADOC, TYPE_JAR)));
|
||||||
if (info().groupId() == null) {
|
if (info().groupId() == null) {
|
||||||
info().groupId(project.pkg());
|
info().groupId(project.pkg());
|
||||||
}
|
}
|
||||||
|
|
@ -517,6 +645,30 @@ public class PublishOperation extends AbstractOperation<PublishOperation> {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether the operation has to run offline.
|
||||||
|
*
|
||||||
|
* @param flag {@code true} if the operation runs offline; or
|
||||||
|
* {@code false} otherwise
|
||||||
|
* @return this operation instance
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public PublishOperation offline(boolean flag) {
|
||||||
|
offline_ = flag;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the operation has to run offline.
|
||||||
|
*
|
||||||
|
* @return {@code true} if the operation runs offline; or
|
||||||
|
* {@code false} otherwise
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public boolean offline() {
|
||||||
|
return offline_;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the moment of publication.
|
* Provides the moment of publication.
|
||||||
* <p>
|
* <p>
|
||||||
|
|
@ -593,6 +745,18 @@ public class PublishOperation extends AbstractOperation<PublishOperation> {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the publication properties.
|
||||||
|
*
|
||||||
|
* @param properties the publication properties
|
||||||
|
* @return this operation instance
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public PublishOperation publishProperties(PublishProperties properties) {
|
||||||
|
publishProperties_ = properties;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the publication info structure.
|
* Provides the publication info structure.
|
||||||
*
|
*
|
||||||
|
|
@ -643,6 +807,18 @@ public class PublishOperation extends AbstractOperation<PublishOperation> {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the hierarchical properties to use.
|
||||||
|
*
|
||||||
|
* @param properties the hierarchical properties
|
||||||
|
* @return this operation instance
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public PublishOperation properties(HierarchicalProperties properties) {
|
||||||
|
properties_ = properties;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the repositories to which will be published.
|
* Retrieves the repositories to which will be published.
|
||||||
* <p>
|
* <p>
|
||||||
|
|
@ -667,6 +843,18 @@ public class PublishOperation extends AbstractOperation<PublishOperation> {
|
||||||
return dependencies_;
|
return dependencies_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the publication properties.
|
||||||
|
* <p>
|
||||||
|
* This is a modifiable structure that can be retrieved and changed.
|
||||||
|
*
|
||||||
|
* @return the publication properties
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public PublishProperties publishProperties() {
|
||||||
|
return publishProperties_;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the publication info structure.
|
* Retrieves the publication info structure.
|
||||||
* <p>
|
* <p>
|
||||||
|
|
@ -703,4 +891,17 @@ public class PublishOperation extends AbstractOperation<PublishOperation> {
|
||||||
}
|
}
|
||||||
return retriever_;
|
return retriever_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the hierarchical properties that are used.
|
||||||
|
*
|
||||||
|
* @return the hierarchical properties
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public HierarchicalProperties properties() {
|
||||||
|
if (properties_ == null) {
|
||||||
|
properties_ = new HierarchicalProperties();
|
||||||
|
}
|
||||||
|
return properties_;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ package rife.bld.operations;
|
||||||
|
|
||||||
import rife.bld.BaseProject;
|
import rife.bld.BaseProject;
|
||||||
import rife.bld.dependencies.*;
|
import rife.bld.dependencies.*;
|
||||||
|
import rife.ioc.HierarchicalProperties;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
@ -24,13 +25,21 @@ import static rife.bld.dependencies.Dependency.CLASSIFIER_SOURCES;
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
public class PurgeOperation extends AbstractOperation<PurgeOperation> {
|
public class PurgeOperation extends AbstractOperation<PurgeOperation> {
|
||||||
|
private boolean offline_ = false;
|
||||||
|
private HierarchicalProperties properties_ = null;
|
||||||
private ArtifactRetriever retriever_ = null;
|
private ArtifactRetriever retriever_ = null;
|
||||||
private final List<Repository> repositories_ = new ArrayList<>();
|
private final List<Repository> repositories_ = new ArrayList<>();
|
||||||
private final DependencyScopes dependencies_ = new DependencyScopes();
|
private final DependencyScopes dependencies_ = new DependencyScopes();
|
||||||
private File libCompileDirectory_;
|
private File libCompileDirectory_;
|
||||||
|
private File libCompileModulesDirectory_;
|
||||||
|
private File libProvidedDirectory_;
|
||||||
|
private File libProvidedModulesDirectory_;
|
||||||
private File libRuntimeDirectory_;
|
private File libRuntimeDirectory_;
|
||||||
|
private File libRuntimeModulesDirectory_;
|
||||||
private File libStandaloneDirectory_;
|
private File libStandaloneDirectory_;
|
||||||
|
private File libStandaloneModulesDirectory_;
|
||||||
private File libTestDirectory_;
|
private File libTestDirectory_;
|
||||||
|
private File libTestModulesDirectory_;
|
||||||
private boolean preserveSources_ = false;
|
private boolean preserveSources_ = false;
|
||||||
private boolean preserveJavadoc_ = false;
|
private boolean preserveJavadoc_ = false;
|
||||||
|
|
||||||
|
|
@ -40,7 +49,13 @@ public class PurgeOperation extends AbstractOperation<PurgeOperation> {
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
public void execute() {
|
public void execute() {
|
||||||
|
if (offline_) {
|
||||||
|
System.out.println("Offline mode: purge is disabled");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
executePurgeCompileDependencies();
|
executePurgeCompileDependencies();
|
||||||
|
executePurgeProvidedDependencies();
|
||||||
executePurgeRuntimeDependencies();
|
executePurgeRuntimeDependencies();
|
||||||
executePurgeStandaloneDependencies();
|
executePurgeStandaloneDependencies();
|
||||||
executePurgeTestDependencies();
|
executePurgeTestDependencies();
|
||||||
|
|
@ -55,7 +70,16 @@ public class PurgeOperation extends AbstractOperation<PurgeOperation> {
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
protected void executePurgeCompileDependencies() {
|
protected void executePurgeCompileDependencies() {
|
||||||
executePurgeDependencies(libCompileDirectory(), dependencies().resolveCompileDependencies(artifactRetriever(), repositories()));
|
executePurgeDependencies(libCompileDirectory(), libCompileModulesDirectory(), dependencies().resolveCompileDependencies(properties(), artifactRetriever(), repositories()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Part of the {@link #execute} operation, purge the {@code provided} scope artifacts.
|
||||||
|
*
|
||||||
|
* @since 1.8
|
||||||
|
*/
|
||||||
|
protected void executePurgeProvidedDependencies() {
|
||||||
|
executePurgeDependencies(libProvidedDirectory(), libProvidedModulesDirectory(), dependencies().resolveProvidedDependencies(properties(), artifactRetriever(), repositories()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -64,7 +88,7 @@ public class PurgeOperation extends AbstractOperation<PurgeOperation> {
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
protected void executePurgeRuntimeDependencies() {
|
protected void executePurgeRuntimeDependencies() {
|
||||||
executePurgeDependencies(libRuntimeDirectory(), dependencies().resolveRuntimeDependencies(artifactRetriever(), repositories()));
|
executePurgeDependencies(libRuntimeDirectory(), libRuntimeModulesDirectory(), dependencies().resolveRuntimeDependencies(properties(), artifactRetriever(), repositories()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -73,7 +97,7 @@ public class PurgeOperation extends AbstractOperation<PurgeOperation> {
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
protected void executePurgeStandaloneDependencies() {
|
protected void executePurgeStandaloneDependencies() {
|
||||||
executePurgeDependencies(libStandaloneDirectory(), dependencies().resolveStandaloneDependencies(artifactRetriever(), repositories()));
|
executePurgeDependencies(libStandaloneDirectory(), libStandaloneModulesDirectory(), dependencies().resolveStandaloneDependencies(properties(), artifactRetriever(), repositories()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -82,46 +106,66 @@ public class PurgeOperation extends AbstractOperation<PurgeOperation> {
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
protected void executePurgeTestDependencies() {
|
protected void executePurgeTestDependencies() {
|
||||||
executePurgeDependencies(libTestDirectory(), dependencies().resolveTestDependencies(artifactRetriever(), repositories()));
|
executePurgeDependencies(libTestDirectory(), libTestModulesDirectory(), dependencies().resolveTestDependencies(properties(), artifactRetriever(), repositories()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Part of the {@link #execute} operation, purge the artifacts for a particular dependency scope.
|
* Part of the {@link #execute} operation, purge the artifacts for a particular dependency scope.
|
||||||
*
|
*
|
||||||
* @param destinationDirectory the directory from which the artifacts should be purged
|
* @param classpathDirectory the directory from which the artifacts should be purged
|
||||||
* @param dependencies the dependencies to purge
|
* @param modulesDirectory the directory from which the modules should be purged
|
||||||
* @since 1.6
|
* @param dependencies the dependencies to purge
|
||||||
|
* @since 2.1
|
||||||
*/
|
*/
|
||||||
protected void executePurgeDependencies(File destinationDirectory, DependencySet dependencies) {
|
protected void executePurgeDependencies(File classpathDirectory, File modulesDirectory, DependencySet dependencies) {
|
||||||
if (destinationDirectory == null) {
|
if (classpathDirectory == null && modulesDirectory == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var filenames = new HashSet<String>();
|
|
||||||
|
var classpath_names = new HashSet<String>();
|
||||||
|
var modules_names = new HashSet<String>();
|
||||||
for (var dependency : dependencies) {
|
for (var dependency : dependencies) {
|
||||||
|
var filenames = classpath_names;
|
||||||
|
if (dependency.isModularJar()) {
|
||||||
|
filenames = modules_names;
|
||||||
|
}
|
||||||
addTransferLocations(filenames, dependency);
|
addTransferLocations(filenames, dependency);
|
||||||
if (preserveSources_) {
|
if (preserveSources_ && !dependency.excludedClassifiers().contains(CLASSIFIER_SOURCES)) {
|
||||||
addTransferLocations(filenames, dependency.withClassifier(CLASSIFIER_SOURCES));
|
addTransferLocations(filenames, dependency.withClassifier(CLASSIFIER_SOURCES));
|
||||||
}
|
}
|
||||||
if (preserveJavadoc_) {
|
if (preserveJavadoc_ && !dependency.excludedClassifiers().contains(CLASSIFIER_JAVADOC)) {
|
||||||
addTransferLocations(filenames, dependency.withClassifier(CLASSIFIER_JAVADOC));
|
addTransferLocations(filenames, dependency.withClassifier(CLASSIFIER_JAVADOC));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
purgeFromDirectory(classpathDirectory, modulesDirectory, classpath_names);
|
||||||
|
purgeFromDirectory(modulesDirectory, classpathDirectory, modules_names);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void purgeFromDirectory(File directory, File preserveDirectory, HashSet<String> preservedFileNames) {
|
||||||
|
if (directory == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
boolean printed_header = false;
|
boolean printed_header = false;
|
||||||
for (var file : destinationDirectory.listFiles()) {
|
var classpath_files = directory.listFiles();
|
||||||
if (!filenames.contains(file.getName())) {
|
if (classpath_files != null) {
|
||||||
if (!printed_header) {
|
for (var file : classpath_files) {
|
||||||
printed_header = true;
|
if (!preservedFileNames.contains(file.getName()) && !file.equals(preserveDirectory)) {
|
||||||
System.out.println("Deleting from " + destinationDirectory.getName() + ":");
|
if (!printed_header) {
|
||||||
|
printed_header = true;
|
||||||
|
System.out.println("Deleting from " + directory.getName() + ":");
|
||||||
|
}
|
||||||
|
System.out.println(" " + file.getName());
|
||||||
|
file.delete();
|
||||||
}
|
}
|
||||||
System.out.println(" " + file.getName());
|
|
||||||
file.delete();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addTransferLocations(HashSet<String> filenames, Dependency dependency) {
|
private void addTransferLocations(HashSet<String> filenames, Dependency dependency) {
|
||||||
for (var location : new DependencyResolver(artifactRetriever(), repositories(), dependency).getTransferLocations()) {
|
var resolution = new VersionResolution(properties());
|
||||||
|
for (var location : new DependencyResolver(resolution, artifactRetriever(), repositories(), dependency).getTransferLocations()) {
|
||||||
filenames.add(location.substring(location.lastIndexOf("/") + 1));
|
filenames.add(location.substring(location.lastIndexOf("/") + 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -133,17 +177,49 @@ public class PurgeOperation extends AbstractOperation<PurgeOperation> {
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
public PurgeOperation fromProject(BaseProject project) {
|
public PurgeOperation fromProject(BaseProject project) {
|
||||||
return artifactRetriever(project.artifactRetriever())
|
return offline(project.offline())
|
||||||
|
.properties(project.properties())
|
||||||
|
.artifactRetriever(project.artifactRetriever())
|
||||||
.repositories(project.repositories())
|
.repositories(project.repositories())
|
||||||
.dependencies(project.dependencies())
|
.dependencies(project.dependencies())
|
||||||
.libCompileDirectory(project.libCompileDirectory())
|
.libCompileDirectory(project.libCompileDirectory())
|
||||||
|
.libCompileModulesDirectory(project.libCompileModulesDirectory())
|
||||||
|
.libProvidedDirectory(project.libProvidedDirectory())
|
||||||
|
.libProvidedModulesDirectory(project.libProvidedModulesDirectory())
|
||||||
.libRuntimeDirectory(project.libRuntimeDirectory())
|
.libRuntimeDirectory(project.libRuntimeDirectory())
|
||||||
|
.libRuntimeModulesDirectory(project.libRuntimeModulesDirectory())
|
||||||
.libStandaloneDirectory(project.libStandaloneDirectory())
|
.libStandaloneDirectory(project.libStandaloneDirectory())
|
||||||
|
.libStandaloneModulesDirectory(project.libStandaloneModulesDirectory())
|
||||||
.libTestDirectory(project.libTestDirectory())
|
.libTestDirectory(project.libTestDirectory())
|
||||||
|
.libTestModulesDirectory(project.libTestModulesDirectory())
|
||||||
.preserveSources(project.downloadSources())
|
.preserveSources(project.downloadSources())
|
||||||
.preserveJavadoc(project.downloadJavadoc());
|
.preserveJavadoc(project.downloadJavadoc());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether the operation has to run offline.
|
||||||
|
*
|
||||||
|
* @param flag {@code true} if the operation runs offline; or
|
||||||
|
* {@code false} otherwise
|
||||||
|
* @return this operation instance
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public PurgeOperation offline(boolean flag) {
|
||||||
|
offline_ = flag;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the operation has to run offline.
|
||||||
|
*
|
||||||
|
* @return {@code true} if the operation runs offline; or
|
||||||
|
* {@code false} otherwise
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public boolean offline() {
|
||||||
|
return offline_;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates whether the sources classifier files should be preserved.
|
* Indicates whether the sources classifier files should be preserved.
|
||||||
*
|
*
|
||||||
|
|
@ -220,6 +296,42 @@ public class PurgeOperation extends AbstractOperation<PurgeOperation> {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the {@code compile} scope modules purge directory.
|
||||||
|
*
|
||||||
|
* @param directory the directory to purge the {@code compile} scope modules from
|
||||||
|
* @return this operation instance
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public PurgeOperation libCompileModulesDirectory(File directory) {
|
||||||
|
libCompileModulesDirectory_ = directory;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the {@code provided} scope purge directory.
|
||||||
|
*
|
||||||
|
* @param directory the directory to purge the {@code provided} scope artifacts from
|
||||||
|
* @return this operation instance
|
||||||
|
* @since 1.8
|
||||||
|
*/
|
||||||
|
public PurgeOperation libProvidedDirectory(File directory) {
|
||||||
|
libProvidedDirectory_ = directory;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the {@code provided} scope modules purge directory.
|
||||||
|
*
|
||||||
|
* @param directory the directory to purge the {@code provided} scope modules from
|
||||||
|
* @return this operation instance
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public PurgeOperation libProvidedModulesDirectory(File directory) {
|
||||||
|
libProvidedModulesDirectory_ = directory;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the {@code runtime} scope purge directory.
|
* Provides the {@code runtime} scope purge directory.
|
||||||
*
|
*
|
||||||
|
|
@ -232,6 +344,18 @@ public class PurgeOperation extends AbstractOperation<PurgeOperation> {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the {@code runtime} scope modules purge directory.
|
||||||
|
*
|
||||||
|
* @param directory the directory to purge the {@code runtime} scope modules from
|
||||||
|
* @return this operation instance
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public PurgeOperation libRuntimeModulesDirectory(File directory) {
|
||||||
|
libRuntimeModulesDirectory_ = directory;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the {@code standalone} scope purge directory.
|
* Provides the {@code standalone} scope purge directory.
|
||||||
*
|
*
|
||||||
|
|
@ -244,6 +368,18 @@ public class PurgeOperation extends AbstractOperation<PurgeOperation> {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the {@code standalone} scope modules purge directory.
|
||||||
|
*
|
||||||
|
* @param directory the directory to purge the {@code standalone} scope modules from
|
||||||
|
* @return this operation instance
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public PurgeOperation libStandaloneModulesDirectory(File directory) {
|
||||||
|
libStandaloneModulesDirectory_ = directory;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the {@code test} scope purge directory.
|
* Provides the {@code test} scope purge directory.
|
||||||
*
|
*
|
||||||
|
|
@ -256,6 +392,18 @@ public class PurgeOperation extends AbstractOperation<PurgeOperation> {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the {@code test} scope modules purge directory.
|
||||||
|
*
|
||||||
|
* @param directory the directory to purge the {@code test} scope modules from
|
||||||
|
* @return this operation instance
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public PurgeOperation libTestModulesDirectory(File directory) {
|
||||||
|
libTestModulesDirectory_ = directory;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the artifact retriever to use.
|
* Provides the artifact retriever to use.
|
||||||
*
|
*
|
||||||
|
|
@ -268,6 +416,18 @@ public class PurgeOperation extends AbstractOperation<PurgeOperation> {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the hierarchical properties to use.
|
||||||
|
*
|
||||||
|
* @param properties the hierarchical properties
|
||||||
|
* @return this operation instance
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public PurgeOperation properties(HierarchicalProperties properties) {
|
||||||
|
properties_ = properties;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the repositories in which the dependencies will be resolved.
|
* Retrieves the repositories in which the dependencies will be resolved.
|
||||||
* <p>
|
* <p>
|
||||||
|
|
@ -302,6 +462,36 @@ public class PurgeOperation extends AbstractOperation<PurgeOperation> {
|
||||||
return libCompileDirectory_;
|
return libCompileDirectory_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the {@code compile} scope modules purge directory.
|
||||||
|
*
|
||||||
|
* @return the {@code compile} scope modules purge directory
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public File libCompileModulesDirectory() {
|
||||||
|
return libCompileModulesDirectory_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the {@code provided} scope purge directory.
|
||||||
|
*
|
||||||
|
* @return the {@code provided} scope purge directory
|
||||||
|
* @since 1.8
|
||||||
|
*/
|
||||||
|
public File libProvidedDirectory() {
|
||||||
|
return libProvidedDirectory_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the {@code provided} scope modules purge directory.
|
||||||
|
*
|
||||||
|
* @return the {@code provided} scope modules purge directory
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public File libProvidedModulesDirectory() {
|
||||||
|
return libProvidedModulesDirectory_;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the {@code runtime} scope purge directory.
|
* Retrieves the {@code runtime} scope purge directory.
|
||||||
*
|
*
|
||||||
|
|
@ -312,6 +502,16 @@ public class PurgeOperation extends AbstractOperation<PurgeOperation> {
|
||||||
return libRuntimeDirectory_;
|
return libRuntimeDirectory_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the {@code runtime} scope modules purge directory.
|
||||||
|
*
|
||||||
|
* @return the {@code runtime} scope modules purge directory
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public File libRuntimeModulesDirectory() {
|
||||||
|
return libRuntimeModulesDirectory_;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the {@code standalone} scope purge directory.
|
* Retrieves the {@code standalone} scope purge directory.
|
||||||
*
|
*
|
||||||
|
|
@ -322,6 +522,16 @@ public class PurgeOperation extends AbstractOperation<PurgeOperation> {
|
||||||
return libStandaloneDirectory_;
|
return libStandaloneDirectory_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the {@code standalone} scope modules purge directory.
|
||||||
|
*
|
||||||
|
* @return the {@code standalone} scope modules purge directory
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public File libStandaloneModulesDirectory() {
|
||||||
|
return libStandaloneModulesDirectory_;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the {@code test} scope purge directory.
|
* Retrieves the {@code test} scope purge directory.
|
||||||
*
|
*
|
||||||
|
|
@ -332,6 +542,16 @@ public class PurgeOperation extends AbstractOperation<PurgeOperation> {
|
||||||
return libTestDirectory_;
|
return libTestDirectory_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the {@code test} scope modules purge directory.
|
||||||
|
*
|
||||||
|
* @return the {@code test} scope modules purge directory
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public File libTestModulesDirectory() {
|
||||||
|
return libTestModulesDirectory_;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves whether the sources classifier files should be preserved.
|
* Retrieves whether the sources classifier files should be preserved.
|
||||||
*
|
*
|
||||||
|
|
@ -366,4 +586,17 @@ public class PurgeOperation extends AbstractOperation<PurgeOperation> {
|
||||||
}
|
}
|
||||||
return retriever_;
|
return retriever_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the hierarchical properties that are used.
|
||||||
|
*
|
||||||
|
* @return the hierarchical properties
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public HierarchicalProperties properties() {
|
||||||
|
if (properties_ == null) {
|
||||||
|
properties_ = new HierarchicalProperties();
|
||||||
|
}
|
||||||
|
return properties_;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import rife.bld.BaseProject;
|
||||||
import rife.tools.FileUtils;
|
import rife.tools.FileUtils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -17,6 +18,7 @@ import java.util.List;
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
public class RunOperation extends AbstractProcessOperation<RunOperation> {
|
public class RunOperation extends AbstractProcessOperation<RunOperation> {
|
||||||
|
public static final String ARGS_OPTION = "--args=";
|
||||||
protected final List<String> runOptions_ = new ArrayList<>();
|
protected final List<String> runOptions_ = new ArrayList<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -29,12 +31,30 @@ public class RunOperation extends AbstractProcessOperation<RunOperation> {
|
||||||
var args = new ArrayList<String>();
|
var args = new ArrayList<String>();
|
||||||
args.add(javaTool());
|
args.add(javaTool());
|
||||||
args.addAll(javaOptions());
|
args.addAll(javaOptions());
|
||||||
|
|
||||||
if (!classpath().isEmpty()) {
|
if (!classpath().isEmpty()) {
|
||||||
args.add("-cp");
|
args.add("-cp");
|
||||||
args.add(FileUtils.joinPaths(classpath()));
|
args.add(FileUtils.joinPaths(classpath()));
|
||||||
}
|
}
|
||||||
args.add(mainClass());
|
|
||||||
|
if (!modulePath().isEmpty()) {
|
||||||
|
args.add("-p");
|
||||||
|
args.add(FileUtils.joinPaths(modulePath()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (module() != null && !module().isEmpty()) {
|
||||||
|
args.add("-m");
|
||||||
|
args.add(module());
|
||||||
|
}
|
||||||
|
else if (mainClass() != null && !mainClass().isEmpty()){
|
||||||
|
args.add(mainClass());
|
||||||
|
}
|
||||||
|
else if (!silent()) {
|
||||||
|
System.err.println("No main class or module specified.");
|
||||||
|
}
|
||||||
|
|
||||||
args.addAll(runOptions());
|
args.addAll(runOptions());
|
||||||
|
|
||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -46,12 +66,28 @@ public class RunOperation extends AbstractProcessOperation<RunOperation> {
|
||||||
*/
|
*/
|
||||||
public RunOperation fromProject(BaseProject project) {
|
public RunOperation fromProject(BaseProject project) {
|
||||||
var operation = workDirectory(project.workDirectory())
|
var operation = workDirectory(project.workDirectory())
|
||||||
.javaTool(project.javaTool())
|
.javaTool(project.javaTool())
|
||||||
.classpath(project.runClasspath())
|
.classpath(project.runClasspath())
|
||||||
.mainClass(project.mainClass());
|
.modulePath(project.runModulePath())
|
||||||
|
.mainClass(project.mainClass())
|
||||||
|
.module(project.module());
|
||||||
if (project.usesRife2Agent()) {
|
if (project.usesRife2Agent()) {
|
||||||
operation.javaOptions().javaAgent(project.getRife2AgentFile());
|
operation.javaOptions().javaAgent(project.getRife2AgentFile());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// parse the run arguments if any
|
||||||
|
var args = project.arguments();
|
||||||
|
if (!args.isEmpty()) {
|
||||||
|
var arg = args.get(0);
|
||||||
|
if (arg.startsWith(ARGS_OPTION)) {
|
||||||
|
args.remove(0);
|
||||||
|
var runArgs = arg.substring(ARGS_OPTION.length());
|
||||||
|
if (!runArgs.isBlank()) {
|
||||||
|
runOptions_.addAll(0, Arrays.asList(runArgs.split(" ")));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return operation;
|
return operation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,12 +5,10 @@
|
||||||
package rife.bld.operations;
|
package rife.bld.operations;
|
||||||
|
|
||||||
import rife.bld.BaseProject;
|
import rife.bld.BaseProject;
|
||||||
import rife.bld.Project;
|
|
||||||
import rife.tools.FileUtils;
|
import rife.tools.FileUtils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests a Java application.
|
* Tests a Java application.
|
||||||
|
|
@ -53,8 +51,14 @@ public class TestOperation<T extends TestOperation<T, O>, O extends List<String>
|
||||||
var args = new ArrayList<String>();
|
var args = new ArrayList<String>();
|
||||||
args.add(javaTool());
|
args.add(javaTool());
|
||||||
args.addAll(javaOptions());
|
args.addAll(javaOptions());
|
||||||
args.add("-cp");
|
if (!classpath().isEmpty()) {
|
||||||
args.add(FileUtils.joinPaths(classpath()));
|
args.add("-cp");
|
||||||
|
args.add(FileUtils.joinPaths(classpath()));
|
||||||
|
}
|
||||||
|
if (!modulePath().isEmpty()) {
|
||||||
|
args.add("-p");
|
||||||
|
args.add(FileUtils.joinPaths(modulePath()));
|
||||||
|
}
|
||||||
args.add(mainClass());
|
args.add(mainClass());
|
||||||
args.addAll(testToolOptions());
|
args.addAll(testToolOptions());
|
||||||
|
|
||||||
|
|
@ -70,7 +74,8 @@ public class TestOperation<T extends TestOperation<T, O>, O extends List<String>
|
||||||
public T fromProject(BaseProject project) {
|
public T fromProject(BaseProject project) {
|
||||||
var operation = workDirectory(project.workDirectory())
|
var operation = workDirectory(project.workDirectory())
|
||||||
.javaTool(project.javaTool())
|
.javaTool(project.javaTool())
|
||||||
.classpath(project.testClasspath());
|
.classpath(project.testClasspath())
|
||||||
|
.modulePath(project.testModulePath());
|
||||||
if (project.usesRife2Agent()) {
|
if (project.usesRife2Agent()) {
|
||||||
operation.javaOptions().javaAgent(project.getRife2AgentFile());
|
operation.javaOptions().javaAgent(project.getRife2AgentFile());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ package rife.bld.operations;
|
||||||
|
|
||||||
import rife.bld.BaseProject;
|
import rife.bld.BaseProject;
|
||||||
import rife.bld.NamedFile;
|
import rife.bld.NamedFile;
|
||||||
import rife.bld.Project;
|
|
||||||
import rife.tools.FileUtils;
|
import rife.tools.FileUtils;
|
||||||
import rife.tools.exceptions.FileUtilsErrorException;
|
import rife.tools.exceptions.FileUtilsErrorException;
|
||||||
|
|
||||||
|
|
@ -98,7 +97,9 @@ public class UberJarOperation extends AbstractOperation<UberJarOperation> {
|
||||||
.sourceDirectories(stagingDirectory)
|
.sourceDirectories(stagingDirectory)
|
||||||
.destinationDirectory(destinationDirectory())
|
.destinationDirectory(destinationDirectory())
|
||||||
.destinationFileName(destinationFileName())
|
.destinationFileName(destinationFileName())
|
||||||
.excluded(List.of(Pattern.compile("(?:(?:^.*[/\\\\])|^)\\.DS_Store$")))
|
.excluded(List.of(
|
||||||
|
Pattern.compile("(?:(?:^.*[/\\\\])|^)\\.DS_Store$"),
|
||||||
|
Pattern.compile("(?:(?:^.*[/\\\\])|^).+\\.(DSA|RSA|SF)$")))
|
||||||
.silent(true)
|
.silent(true)
|
||||||
.execute();
|
.execute();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@
|
||||||
package rife.bld.operations;
|
package rife.bld.operations;
|
||||||
|
|
||||||
import rife.bld.BaseProject;
|
import rife.bld.BaseProject;
|
||||||
import rife.bld.Project;
|
|
||||||
import rife.bld.dependencies.*;
|
import rife.bld.dependencies.*;
|
||||||
|
import rife.ioc.HierarchicalProperties;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
@ -18,6 +18,7 @@ import java.util.List;
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
public class UpdatesOperation extends AbstractOperation<UpdatesOperation> {
|
public class UpdatesOperation extends AbstractOperation<UpdatesOperation> {
|
||||||
|
private HierarchicalProperties properties_ = null;
|
||||||
private ArtifactRetriever retriever_ = null;
|
private ArtifactRetriever retriever_ = null;
|
||||||
private final List<Repository> repositories_ = new ArrayList<>();
|
private final List<Repository> repositories_ = new ArrayList<>();
|
||||||
private final DependencyScopes dependencies_ = new DependencyScopes();
|
private final DependencyScopes dependencies_ = new DependencyScopes();
|
||||||
|
|
@ -29,11 +30,12 @@ public class UpdatesOperation extends AbstractOperation<UpdatesOperation> {
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
public void execute() {
|
public void execute() {
|
||||||
|
var resolution = new VersionResolution(properties());
|
||||||
var result = new DependencyScopes();
|
var result = new DependencyScopes();
|
||||||
for (var entry : dependencies_.entrySet()) {
|
for (var entry : dependencies_.entrySet()) {
|
||||||
var scope = entry.getKey();
|
var scope = entry.getKey();
|
||||||
for (var dependency : entry.getValue()) {
|
for (var dependency : entry.getValue()) {
|
||||||
var latest = new DependencyResolver(artifactRetriever(), repositories(), dependency).latestVersion();
|
var latest = new DependencyResolver(resolution, artifactRetriever(), repositories(), dependency).latestVersion();
|
||||||
if (latest.compareTo(dependency.version()) > 0) {
|
if (latest.compareTo(dependency.version()) > 0) {
|
||||||
var latest_dependency = new Dependency(dependency.groupId(), dependency.artifactId(), latest,
|
var latest_dependency = new Dependency(dependency.groupId(), dependency.artifactId(), latest,
|
||||||
dependency.classifier(), dependency.type());
|
dependency.classifier(), dependency.type());
|
||||||
|
|
@ -66,7 +68,8 @@ public class UpdatesOperation extends AbstractOperation<UpdatesOperation> {
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
public UpdatesOperation fromProject(BaseProject project) {
|
public UpdatesOperation fromProject(BaseProject project) {
|
||||||
return artifactRetriever(project.artifactRetriever())
|
return properties(project.properties())
|
||||||
|
.artifactRetriever(project.artifactRetriever())
|
||||||
.repositories(project.repositories())
|
.repositories(project.repositories())
|
||||||
.dependencies(project.dependencies());
|
.dependencies(project.dependencies());
|
||||||
}
|
}
|
||||||
|
|
@ -121,6 +124,18 @@ public class UpdatesOperation extends AbstractOperation<UpdatesOperation> {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the hierarchical properties to use.
|
||||||
|
*
|
||||||
|
* @param properties the hierarchical properties
|
||||||
|
* @return this operation instance
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public UpdatesOperation properties(HierarchicalProperties properties) {
|
||||||
|
properties_ = properties;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the repositories in which the dependencies will be resolved.
|
* Retrieves the repositories in which the dependencies will be resolved.
|
||||||
* <p>
|
* <p>
|
||||||
|
|
@ -167,4 +182,17 @@ public class UpdatesOperation extends AbstractOperation<UpdatesOperation> {
|
||||||
}
|
}
|
||||||
return retriever_;
|
return retriever_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the hierarchical properties that are used.
|
||||||
|
*
|
||||||
|
* @return the hierarchical properties
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public HierarchicalProperties properties() {
|
||||||
|
if (properties_ == null) {
|
||||||
|
properties_ = new HierarchicalProperties();
|
||||||
|
}
|
||||||
|
return properties_;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
30
src/main/java/rife/bld/operations/ZipCompression.java
Normal file
30
src/main/java/rife/bld/operations/ZipCompression.java
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
/**
|
||||||
|
* Copyright 2024 Erik C. Thauvin (https://erik.thauvin.net/)
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||||
|
*/
|
||||||
|
package rife.bld.operations;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The zip compression levels for jlink and jmod.
|
||||||
|
*
|
||||||
|
* @author <a href="https://erik.thauvin.net/">Erik C. Thauvin</a>
|
||||||
|
* @since 2.1.0
|
||||||
|
*/
|
||||||
|
public enum ZipCompression {
|
||||||
|
ZIP_0("zip-0"),
|
||||||
|
ZIP_1("zip-1"),
|
||||||
|
ZIP_2("zip-2"),
|
||||||
|
ZIP_3("zip-3"),
|
||||||
|
ZIP_4("zip-4"),
|
||||||
|
ZIP_5("zip-5"),
|
||||||
|
ZIP_6("zip-6"),
|
||||||
|
ZIP_7("zip-7"),
|
||||||
|
ZIP_8("zip-8"),
|
||||||
|
ZIP_9("zip-9");
|
||||||
|
|
||||||
|
public final String level;
|
||||||
|
|
||||||
|
ZipCompression(String level) {
|
||||||
|
this.level = level;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||||
|
*/
|
||||||
|
package rife.bld.operations.exceptions;
|
||||||
|
|
||||||
|
import rife.tools.HttpUtils;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When thrown, indicates that something went wrong during the use of a rest API call.
|
||||||
|
*
|
||||||
|
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||||
|
* @since 2.2.2
|
||||||
|
*/
|
||||||
|
public class RestApiException extends RuntimeException {
|
||||||
|
@Serial private static final long serialVersionUID = -6753423938407177328L;
|
||||||
|
|
||||||
|
private final String url_;
|
||||||
|
|
||||||
|
public RestApiException(String url, int status) {
|
||||||
|
super("An error occurred while using rest API at '" + url + "'\nHTTP status code " + status + " : " + HttpUtils.statusReason(status));
|
||||||
|
url_ = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RestApiException(String url, Throwable cause) {
|
||||||
|
super("An error occurred while using rest API at '" + url + "'", cause);
|
||||||
|
url_ = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RestApiException(String url) {
|
||||||
|
super("An error occurred while using rest API at '" + url + "'");
|
||||||
|
url_ = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUrl() {
|
||||||
|
return url_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,8 +4,6 @@
|
||||||
*/
|
*/
|
||||||
package rife.bld.operations.exceptions;
|
package rife.bld.operations.exceptions;
|
||||||
|
|
||||||
import rife.tools.HttpUtils;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.Serial;
|
import java.io.Serial;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
*/
|
*/
|
||||||
package rife.bld.publish;
|
package rife.bld.publish;
|
||||||
|
|
||||||
|
import rife.bld.dependencies.Version;
|
||||||
import rife.bld.dependencies.VersionNumber;
|
import rife.bld.dependencies.VersionNumber;
|
||||||
import rife.template.TemplateFactory;
|
import rife.template.TemplateFactory;
|
||||||
import rife.tools.StringUtils;
|
import rife.tools.StringUtils;
|
||||||
|
|
@ -24,7 +25,7 @@ public class MetadataBuilder {
|
||||||
|
|
||||||
private PublishInfo info_ = null;
|
private PublishInfo info_ = null;
|
||||||
private ZonedDateTime timestamp_ = null;
|
private ZonedDateTime timestamp_ = null;
|
||||||
private final Set<VersionNumber> otherVersions_ = new HashSet<>();
|
private final Set<Version> otherVersions_ = new HashSet<>();
|
||||||
private ZonedDateTime snapshotTimestamp_ = null;
|
private ZonedDateTime snapshotTimestamp_ = null;
|
||||||
private Integer snapshotBuildNumber_ = null;
|
private Integer snapshotBuildNumber_ = null;
|
||||||
private boolean snapshotLocal_ = false;
|
private boolean snapshotLocal_ = false;
|
||||||
|
|
@ -81,7 +82,7 @@ public class MetadataBuilder {
|
||||||
* @return this {@code MetadataBuilder} instance
|
* @return this {@code MetadataBuilder} instance
|
||||||
* @since 1.5.8
|
* @since 1.5.8
|
||||||
*/
|
*/
|
||||||
public MetadataBuilder otherVersions(Collection<VersionNumber> otherVersions) {
|
public MetadataBuilder otherVersions(Collection<Version> otherVersions) {
|
||||||
otherVersions_.addAll(otherVersions);
|
otherVersions_.addAll(otherVersions);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
@ -94,7 +95,7 @@ public class MetadataBuilder {
|
||||||
* @return the other versions
|
* @return the other versions
|
||||||
* @since 1.5.8
|
* @since 1.5.8
|
||||||
*/
|
*/
|
||||||
public Set<VersionNumber> otherVersions() {
|
public Set<Version> otherVersions() {
|
||||||
return otherVersions_;
|
return otherVersions_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,15 @@ package rife.bld.publish;
|
||||||
import rife.bld.dependencies.*;
|
import rife.bld.dependencies.*;
|
||||||
import rife.template.Template;
|
import rife.template.Template;
|
||||||
import rife.template.TemplateFactory;
|
import rife.template.TemplateFactory;
|
||||||
|
import rife.tools.FileUtils;
|
||||||
import rife.tools.StringUtils;
|
import rife.tools.StringUtils;
|
||||||
|
import rife.tools.exceptions.FileUtilsErrorException;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import static rife.bld.dependencies.Dependency.TYPE_JAR;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the functionalities to build a Maven POM xml file.
|
* Provides the functionalities to build a Maven POM xml file.
|
||||||
*
|
*
|
||||||
|
|
@ -19,6 +24,7 @@ import java.util.Objects;
|
||||||
*/
|
*/
|
||||||
public class PomBuilder {
|
public class PomBuilder {
|
||||||
private PublishInfo info_ = null;
|
private PublishInfo info_ = null;
|
||||||
|
private PublishProperties properties_ = new PublishProperties();
|
||||||
private DependencyScopes dependencies_ = new DependencyScopes();
|
private DependencyScopes dependencies_ = new DependencyScopes();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -43,6 +49,28 @@ public class PomBuilder {
|
||||||
return info_;
|
return info_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the properties to build the POM with.
|
||||||
|
*
|
||||||
|
* @param properties the properties to use
|
||||||
|
* @return this {@code PomBuilder} instance
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public PomBuilder properties(PublishProperties properties) {
|
||||||
|
properties_ = properties;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the properties to build the POM with.
|
||||||
|
*
|
||||||
|
* @return the properties to use
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public PublishProperties properties() {
|
||||||
|
return properties_;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the dependencies to build the POM for.
|
* Provides the dependencies to build the POM for.
|
||||||
*
|
*
|
||||||
|
|
@ -112,15 +140,38 @@ public class PomBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (properties() != null && !properties().isEmpty()) {
|
||||||
|
for (var entry : properties().entrySet()) {
|
||||||
|
if (entry.getKey() != null) {
|
||||||
|
t.setValueEncoded("property-key", entry.getKey());
|
||||||
|
t.setValueEncoded("property-value", Objects.requireNonNullElse(entry.getValue(), ""));
|
||||||
|
t.appendBlock("properties", "property");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
t.setBlock("properties-tag");
|
||||||
|
}
|
||||||
|
|
||||||
if (dependencies() != null && !dependencies().isEmpty()) {
|
if (dependencies() != null && !dependencies().isEmpty()) {
|
||||||
addDependencies(t, Scope.compile);
|
addDependencies(t, Scope.compile);
|
||||||
addDependencies(t, Scope.runtime);
|
addDependencies(t, Scope.runtime);
|
||||||
|
addDependencies(t, Scope.provided);
|
||||||
t.setBlock("dependencies-tag");
|
t.setBlock("dependencies-tag");
|
||||||
}
|
}
|
||||||
|
|
||||||
return StringUtils.stripBlankLines(t.getContent());
|
return StringUtils.stripBlankLines(t.getContent());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a POM into the given file.
|
||||||
|
*
|
||||||
|
* @since 1.7.1
|
||||||
|
*/
|
||||||
|
public static void generateInto(PublishInfo info, DependencyScopes dependencies, File file)
|
||||||
|
throws FileUtilsErrorException {
|
||||||
|
var pomBuilder = new PomBuilder().info(info).dependencies(dependencies);
|
||||||
|
FileUtils.writeString(pomBuilder.build(), file);
|
||||||
|
}
|
||||||
|
|
||||||
private void addDependencies(Template t, Scope scope) {
|
private void addDependencies(Template t, Scope scope) {
|
||||||
var scoped_dependencies = dependencies().scope(scope);
|
var scoped_dependencies = dependencies().scope(scope);
|
||||||
if (!scoped_dependencies.isEmpty()) {
|
if (!scoped_dependencies.isEmpty()) {
|
||||||
|
|
@ -137,7 +188,7 @@ public class PomBuilder {
|
||||||
|
|
||||||
t.blankValue("dependency-type");
|
t.blankValue("dependency-type");
|
||||||
t.blankValue("dependency-type-tag");
|
t.blankValue("dependency-type-tag");
|
||||||
if (!dependency.type().equals("jar")) {
|
if (!TYPE_JAR.equals(dependency.type())) {
|
||||||
t.setValueEncoded("dependency-type", dependency.type());
|
t.setValueEncoded("dependency-type", dependency.type());
|
||||||
t.setBlock("dependency-type-tag");
|
t.setBlock("dependency-type-tag");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,8 @@ package rife.bld.publish;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
|
import static rife.bld.dependencies.Dependency.TYPE_JAR;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains the information about an artifact that will be published.
|
* Contains the information about an artifact that will be published.
|
||||||
*
|
*
|
||||||
|
|
@ -19,6 +21,6 @@ public record PublishArtifact(File file, String classifier, String type) {
|
||||||
public PublishArtifact(File file, String classifier, String type) {
|
public PublishArtifact(File file, String classifier, String type) {
|
||||||
this.file = file;
|
this.file = file;
|
||||||
this.classifier = (classifier == null ? "" : classifier);
|
this.classifier = (classifier == null ? "" : classifier);
|
||||||
this.type = (type == null ? "jar" : type);
|
this.type = (type == null ? TYPE_JAR : type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
*/
|
*/
|
||||||
package rife.bld.publish;
|
package rife.bld.publish;
|
||||||
|
|
||||||
|
import rife.bld.dependencies.Version;
|
||||||
import rife.bld.dependencies.VersionNumber;
|
import rife.bld.dependencies.VersionNumber;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
@ -18,7 +19,7 @@ import java.util.List;
|
||||||
public class PublishInfo {
|
public class PublishInfo {
|
||||||
private String groupId_ = null;
|
private String groupId_ = null;
|
||||||
private String artifactId_ = null;
|
private String artifactId_ = null;
|
||||||
private VersionNumber version_ = null;
|
private Version version_ = null;
|
||||||
private String name_ = null;
|
private String name_ = null;
|
||||||
private String description_ = null;
|
private String description_ = null;
|
||||||
private String url_ = null;
|
private String url_ = null;
|
||||||
|
|
@ -81,7 +82,7 @@ public class PublishInfo {
|
||||||
* @return this {@code PublishInfo} instance
|
* @return this {@code PublishInfo} instance
|
||||||
* @since 1.5.7
|
* @since 1.5.7
|
||||||
*/
|
*/
|
||||||
public PublishInfo version(VersionNumber version) {
|
public PublishInfo version(Version version) {
|
||||||
version_ = version;
|
version_ = version;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
@ -92,7 +93,7 @@ public class PublishInfo {
|
||||||
* @return the project's version.
|
* @return the project's version.
|
||||||
* @since 1.5.7
|
* @since 1.5.7
|
||||||
*/
|
*/
|
||||||
public VersionNumber version() {
|
public Version version() {
|
||||||
return version_;
|
return version_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -163,7 +164,7 @@ public class PublishInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the custompath to the {@code gpg} executable used for signing.
|
* Provides the custom path to the {@code gpg} executable used for signing.
|
||||||
* <p>
|
* <p>
|
||||||
* By default, {@code gpg} will be used.
|
* By default, {@code gpg} will be used.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
80
src/main/java/rife/bld/publish/PublishProperties.java
Normal file
80
src/main/java/rife/bld/publish/PublishProperties.java
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2001-2024 Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||||
|
*/
|
||||||
|
package rife.bld.publish;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the properties information for publication.
|
||||||
|
*
|
||||||
|
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public class PublishProperties extends LinkedHashMap<String, String> {
|
||||||
|
private static final String MAVEN_COMPILER_SOURCE = "maven.compiler.source";
|
||||||
|
private static final String MAVEN_COMPILER_TARGET = "maven.compiler.target";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the value of the 'maven.compiler.source' property.
|
||||||
|
*
|
||||||
|
* @param value the value to be set for the 'maven.compiler.source' property
|
||||||
|
* @return this {@code PomProperties} instance
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public PublishProperties mavenCompilerSource(Integer value) {
|
||||||
|
if (value == null) {
|
||||||
|
remove(MAVEN_COMPILER_SOURCE);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
put(MAVEN_COMPILER_SOURCE, String.valueOf(value));
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the value of the 'maven.compiler.source' property.
|
||||||
|
*
|
||||||
|
* @return the value of the 'maven.compiler.source' property
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public Integer mavenCompilerSource() {
|
||||||
|
var value = get(MAVEN_COMPILER_SOURCE);
|
||||||
|
if (value == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return Integer.parseInt(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the value of the 'maven.compiler.target' property.
|
||||||
|
*
|
||||||
|
* @param value the value to be set for the 'maven.compiler.target' property
|
||||||
|
* @return this {@code PomProperties} instance
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public PublishProperties mavenCompilerTarget(Integer value) {
|
||||||
|
if (value == null) {
|
||||||
|
remove(MAVEN_COMPILER_TARGET);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
put(MAVEN_COMPILER_TARGET, String.valueOf(value));
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the value of the 'maven.compiler.target' property.
|
||||||
|
*
|
||||||
|
* @return the value of the 'maven.compiler.target' property
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public Integer mavenCompilerTarget() {
|
||||||
|
var value = get(MAVEN_COMPILER_TARGET);
|
||||||
|
if (value == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return Integer.parseInt(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -18,6 +18,7 @@ import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.jar.*;
|
import java.util.jar.*;
|
||||||
|
import java.util.regex.MatchResult;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import static rife.tools.FileUtils.JAR_FILE_PATTERN;
|
import static rife.tools.FileUtils.JAR_FILE_PATTERN;
|
||||||
|
|
@ -32,32 +33,53 @@ import static rife.tools.FileUtils.JAVA_FILE_PATTERN;
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
public class Wrapper {
|
public class Wrapper {
|
||||||
|
private enum LaunchMode {
|
||||||
|
Cli,
|
||||||
|
Build
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final String BUILD_ARGUMENT = "--build";
|
||||||
|
public static final String OFFLINE_ARGUMENT = "--offline";
|
||||||
|
|
||||||
|
public static final String WRAPPER_PREFIX = "bld-wrapper";
|
||||||
|
public static final String WRAPPER_PROPERTIES = WRAPPER_PREFIX + ".properties";
|
||||||
|
|
||||||
static final String MAVEN_CENTRAL = "https://repo1.maven.org/maven2/";
|
static final String MAVEN_CENTRAL = "https://repo1.maven.org/maven2/";
|
||||||
static final String SONATYPE_SNAPSHOTS = "https://s01.oss.sonatype.org/content/repositories/snapshots/";
|
static final String CENTRAL_SNAPSHOTS = "https://central.sonatype.com/repository/maven-snapshots/";
|
||||||
static final String DOWNLOAD_LOCATION = MAVEN_CENTRAL + "com/uwyn/rife2/bld/${version}/";
|
static final String DOWNLOAD_LOCATION = MAVEN_CENTRAL + "com/uwyn/rife2/bld/${version}/";
|
||||||
static final String DOWNLOAD_LOCATION_SNAPSHOT = SONATYPE_SNAPSHOTS + "com/uwyn/rife2/bld/${version}/";
|
static final String DOWNLOAD_LOCATION_SNAPSHOT = CENTRAL_SNAPSHOTS + "com/uwyn/rife2/bld/${version}/";
|
||||||
|
static final String BLD_CACHE = "bld.cache";
|
||||||
static final String BLD_FILENAME = "bld-${version}.jar";
|
static final String BLD_FILENAME = "bld-${version}.jar";
|
||||||
static final String BLD_SOURCES_FILENAME = "bld-${version}-sources.jar";
|
static final String BLD_SOURCES_FILENAME = "bld-${version}-sources.jar";
|
||||||
static final String BLD_VERSION = "BLD_VERSION";
|
static final String BLD_VERSION = "BLD_VERSION";
|
||||||
static final String BLD_BUILD_HASH = "bld-build.hash";
|
|
||||||
static final String WRAPPER_PREFIX = "bld-wrapper";
|
|
||||||
static final String WRAPPER_PROPERTIES = WRAPPER_PREFIX + ".properties";
|
|
||||||
static final String WRAPPER_JAR = WRAPPER_PREFIX + ".jar";
|
static final String WRAPPER_JAR = WRAPPER_PREFIX + ".jar";
|
||||||
static final String BLD_PROPERTY_VERSION = "bld.version";
|
static final String BLD_PROPERTY_VERSION = "bld.version";
|
||||||
static final String RIFE2_PROPERTY_DOWNLOAD_LOCATION = "rife2.downloadLocation";
|
static final String RIFE2_PROPERTY_DOWNLOAD_LOCATION = "rife2.downloadLocation";
|
||||||
static final String BLD_PROPERTY_DOWNLOAD_LOCATION = "bld.downloadLocation";
|
static final String BLD_PROPERTY_DOWNLOAD_LOCATION = "bld.downloadLocation";
|
||||||
static final String PROPERTY_REPOSITORIES = "bld.repositories";
|
static final String PROPERTY_REPOSITORIES = "bld.repositories";
|
||||||
static final String PROPERTY_EXTENSION_PREFIX = "bld.extension";
|
static final String PROPERTY_EXTENSION_PREFIX = "bld.extension";
|
||||||
static final String PROPERTY_EXTENSIONS = "bld.extensions";
|
|
||||||
static final String PROPERTY_DOWNLOAD_EXTENSION_SOURCES = "bld.downloadExtensionSources";
|
static final String PROPERTY_DOWNLOAD_EXTENSION_SOURCES = "bld.downloadExtensionSources";
|
||||||
static final String PROPERTY_DOWNLOAD_EXTENSION_JAVADOC = "bld.downloadExtensionJavadoc";
|
static final String PROPERTY_DOWNLOAD_EXTENSION_JAVADOC = "bld.downloadExtensionJavadoc";
|
||||||
static final String PROPERTY_SOURCE_DIRECTORIES = "bld.sourceDirectories";
|
static final String PROPERTY_SOURCE_DIRECTORIES = "bld.sourceDirectories";
|
||||||
|
static final String PROPERTY_JAVAC_OPTIONS = "bld.javacOptions";
|
||||||
|
static final String PROPERTY_JAVA_OPTIONS = "bld.javaOptions";
|
||||||
static final File BLD_USER_DIR = new File(System.getProperty("user.home"), ".bld");
|
static final File BLD_USER_DIR = new File(System.getProperty("user.home"), ".bld");
|
||||||
static final File DISTRIBUTIONS_DIR = new File(BLD_USER_DIR, "dist");
|
static final File DISTRIBUTIONS_DIR = new File(BLD_USER_DIR, "dist");
|
||||||
|
static final Pattern META_DATA_LOCAL_COPY = Pattern.compile("<localCopy>\\s*true\\s*</localCopy>", Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
|
||||||
static final Pattern META_DATA_SNAPSHOT_VERSION = Pattern.compile("<snapshotVersion>.*?<value>([^<]+)</value>", Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
|
static final Pattern META_DATA_SNAPSHOT_VERSION = Pattern.compile("<snapshotVersion>.*?<value>([^<]+)</value>", Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
|
||||||
|
static final Pattern OPTIONS_PATTERN = Pattern.compile("\"[^\"]+\"|\\S+");
|
||||||
|
static final Pattern JVM_PROPERTY_PATTERN = Pattern.compile("-D(.+?)=(.*)");
|
||||||
|
|
||||||
|
private static final Pattern JAR_EXCLUDE_SOURCES_PATTERN = Pattern.compile("^.*-sources\\.jar$", Pattern.CASE_INSENSITIVE);
|
||||||
|
private static final Pattern JAR_EXCLUDE_JAVADOC_PATTERN = Pattern.compile("^.*-javadoc\\.jar$", Pattern.CASE_INSENSITIVE);
|
||||||
|
private static final Pattern[] CLASSPATH_INCLUDED_JARS = new Pattern[]{JAR_FILE_PATTERN};
|
||||||
|
private static final Pattern[] CLASSPATH_EXCLUDED_JARS = new Pattern[]{JAR_EXCLUDE_SOURCES_PATTERN, JAR_EXCLUDE_JAVADOC_PATTERN, Pattern.compile(WRAPPER_JAR)};
|
||||||
|
|
||||||
private File currentDir_ = new File(System.getProperty("user.dir"));
|
private File currentDir_ = new File(System.getProperty("user.dir"));
|
||||||
|
private LaunchMode launchMode_ = LaunchMode.Cli;
|
||||||
|
private boolean offline_ = false;
|
||||||
|
|
||||||
|
private final Properties jvmProperties_ = new Properties();
|
||||||
private final Properties wrapperProperties_ = new Properties();
|
private final Properties wrapperProperties_ = new Properties();
|
||||||
private File wrapperPropertiesFile_ = null;
|
private File wrapperPropertiesFile_ = null;
|
||||||
private final Set<String> repositories_ = new LinkedHashSet<>();
|
private final Set<String> repositories_ = new LinkedHashSet<>();
|
||||||
|
|
@ -98,6 +120,10 @@ public class Wrapper {
|
||||||
private static final Pattern BLD_JAR_PATTERN = Pattern.compile("/\\.bld/dist/bld-[^\"/!]+(?<!sources)\\.jar");
|
private static final Pattern BLD_JAR_PATTERN = Pattern.compile("/\\.bld/dist/bld-[^\"/!]+(?<!sources)\\.jar");
|
||||||
private static final Pattern BLD_SOURCES_JAR_PATTERN = Pattern.compile("/\\.bld/dist/bld-[^\"/!]+-sources\\.jar");
|
private static final Pattern BLD_SOURCES_JAR_PATTERN = Pattern.compile("/\\.bld/dist/bld-[^\"/!]+-sources\\.jar");
|
||||||
private static final Pattern BLD_PROPERTY_VERSION_PATTERN = Pattern.compile(".*bld\\.version.*");
|
private static final Pattern BLD_PROPERTY_VERSION_PATTERN = Pattern.compile(".*bld\\.version.*");
|
||||||
|
private static final Pattern JAR_DIRECTORY_LIB_COMPILE_RECURSIVE_PATTERN = Pattern.compile("<jarDirectory\\s+url=\"file://\\$PROJECT_DIR\\$/lib/compile\"\\s+recursive=\"false\"");
|
||||||
|
private static final Pattern JAR_DIRECTORY_LIB_PROVIDED_RECURSIVE_PATTERN = Pattern.compile("<jarDirectory\\s+url=\"file://\\$PROJECT_DIR\\$/lib/provided\"\\s+recursive=\"false\"");
|
||||||
|
private static final Pattern JAR_DIRECTORY_LIB_RUNTIME_RECURSIVE_PATTERN = Pattern.compile("<jarDirectory\\s+url=\"file://\\$PROJECT_DIR\\$/lib/runtime\"\\s+recursive=\"false\"");
|
||||||
|
private static final Pattern JAR_DIRECTORY_LIB_TEST_RECURSIVE_PATTERN = Pattern.compile("<jarDirectory\\s+url=\"file://\\$PROJECT_DIR\\$/lib/test\"\\s+recursive=\"false\"");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Upgraded the IDEA bld files that were generated with a previous version.
|
* Upgraded the IDEA bld files that were generated with a previous version.
|
||||||
|
|
@ -109,15 +135,50 @@ public class Wrapper {
|
||||||
*/
|
*/
|
||||||
public void upgradeIdeaBldLibrary(File destinationDirectory, String version)
|
public void upgradeIdeaBldLibrary(File destinationDirectory, String version)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
var file = new File(destinationDirectory, Path.of("libraries", "bld.xml").toString());
|
var libraries_bld = new File(destinationDirectory, Path.of("libraries", "bld.xml").toString());
|
||||||
if (file.exists()) {
|
if (libraries_bld.exists()) {
|
||||||
try {
|
try {
|
||||||
var content = FileUtils.readString(file);
|
var content = FileUtils.readString(libraries_bld);
|
||||||
content = BLD_JAR_PATTERN.matcher(content).replaceAll("/.bld/dist/bld-" + version + ".jar");
|
content = BLD_JAR_PATTERN.matcher(content).replaceAll("/.bld/dist/bld-" + version + ".jar");
|
||||||
content = BLD_SOURCES_JAR_PATTERN.matcher(content).replaceAll("/.bld/dist/bld-" + version + "-sources.jar");
|
content = BLD_SOURCES_JAR_PATTERN.matcher(content).replaceAll("/.bld/dist/bld-" + version + "-sources.jar");
|
||||||
content = RIFE2_JAR_PATTERN.matcher(content).replaceAll("/.bld/dist/bld-" + version + ".jar");
|
content = RIFE2_JAR_PATTERN.matcher(content).replaceAll("/.bld/dist/bld-" + version + ".jar");
|
||||||
content = RIFE2_SOURCES_JAR_PATTERN.matcher(content).replaceAll("/.bld/dist/bld-" + version + "-sources.jar");
|
content = RIFE2_SOURCES_JAR_PATTERN.matcher(content).replaceAll("/.bld/dist/bld-" + version + "-sources.jar");
|
||||||
FileUtils.writeString(content, file);
|
FileUtils.writeString(content, libraries_bld);
|
||||||
|
} catch (FileUtilsErrorException e) {
|
||||||
|
throw new IOException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var libraries_compile = new File(destinationDirectory, Path.of("libraries", "compile.xml").toString());
|
||||||
|
if (libraries_compile.exists()) {
|
||||||
|
try {
|
||||||
|
var content = FileUtils.readString(libraries_compile);
|
||||||
|
content = JAR_DIRECTORY_LIB_COMPILE_RECURSIVE_PATTERN.matcher(content).replaceAll("<jarDirectory url=\"file://\\$PROJECT_DIR\\$/lib/compile\" recursive=\"true\"");
|
||||||
|
content = JAR_DIRECTORY_LIB_PROVIDED_RECURSIVE_PATTERN.matcher(content).replaceAll("<jarDirectory url=\"file://\\$PROJECT_DIR\\$/lib/provided\" recursive=\"true\"");
|
||||||
|
FileUtils.writeString(content, libraries_compile);
|
||||||
|
} catch (FileUtilsErrorException e) {
|
||||||
|
throw new IOException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var libraries_runtime = new File(destinationDirectory, Path.of("libraries", "runtime.xml").toString());
|
||||||
|
if (libraries_runtime.exists()) {
|
||||||
|
try {
|
||||||
|
var content = FileUtils.readString(libraries_runtime);
|
||||||
|
content = JAR_DIRECTORY_LIB_RUNTIME_RECURSIVE_PATTERN.matcher(content).replaceAll("<jarDirectory url=\"file://\\$PROJECT_DIR\\$/lib/runtime\" recursive=\"true\"");
|
||||||
|
FileUtils.writeString(content, libraries_runtime);
|
||||||
|
} catch (FileUtilsErrorException e) {
|
||||||
|
throw new IOException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var libraries_test = new File(destinationDirectory, Path.of("libraries", "test.xml").toString());
|
||||||
|
if (libraries_test.exists()) {
|
||||||
|
try {
|
||||||
|
var content = FileUtils.readString(libraries_test);
|
||||||
|
content = JAR_DIRECTORY_LIB_PROVIDED_RECURSIVE_PATTERN.matcher(content).replaceAll("<jarDirectory url=\"file://\\$PROJECT_DIR\\$/lib/provided\" recursive=\"true\"");
|
||||||
|
content = JAR_DIRECTORY_LIB_TEST_RECURSIVE_PATTERN.matcher(content).replaceAll("<jarDirectory url=\"file://\\$PROJECT_DIR\\$/lib/test\" recursive=\"true\"");
|
||||||
|
FileUtils.writeString(content, libraries_test);
|
||||||
} catch (FileUtilsErrorException e) {
|
} catch (FileUtilsErrorException e) {
|
||||||
throw new IOException(e);
|
throw new IOException(e);
|
||||||
}
|
}
|
||||||
|
|
@ -138,8 +199,8 @@ public class Wrapper {
|
||||||
if (file.exists()) {
|
if (file.exists()) {
|
||||||
try {
|
try {
|
||||||
var content = FileUtils.readString(file);
|
var content = FileUtils.readString(file);
|
||||||
content = BLD_JAR_PATTERN.matcher(content).replaceAll("bld-" + version + ".jar");
|
content = BLD_JAR_PATTERN.matcher(content).replaceAll("/.bld/dist/bld-" + version + ".jar");
|
||||||
content = RIFE2_JAR_PATTERN.matcher(content).replaceAll("bld-" + version + ".jar");
|
content = RIFE2_JAR_PATTERN.matcher(content).replaceAll("/.bld/dist/bld-" + version + ".jar");
|
||||||
FileUtils.writeString(content, file);
|
FileUtils.writeString(content, file);
|
||||||
} catch (FileUtilsErrorException e) {
|
} catch (FileUtilsErrorException e) {
|
||||||
throw new IOException(e);
|
throw new IOException(e);
|
||||||
|
|
@ -164,9 +225,11 @@ public class Wrapper {
|
||||||
var properties_blueprint = """
|
var properties_blueprint = """
|
||||||
bld.downloadExtensionJavadoc=false
|
bld.downloadExtensionJavadoc=false
|
||||||
bld.downloadExtensionSources=true
|
bld.downloadExtensionSources=true
|
||||||
bld.extensions=
|
|
||||||
bld.repositories=MAVEN_CENTRAL,RIFE2
|
|
||||||
bld.downloadLocation=
|
bld.downloadLocation=
|
||||||
|
bld.extensions=
|
||||||
|
bld.javaOptions=
|
||||||
|
bld.javacOptions=
|
||||||
|
bld.repositories=MAVEN_CENTRAL,RIFE2_RELEASES
|
||||||
bld.sourceDirectories=
|
bld.sourceDirectories=
|
||||||
bld.version=${version}
|
bld.version=${version}
|
||||||
"""
|
"""
|
||||||
|
|
@ -190,6 +253,7 @@ public class Wrapper {
|
||||||
|
|
||||||
try (var jar = new JarOutputStream(new FileOutputStream(new File(destinationDirectory, WRAPPER_JAR)), manifest)) {
|
try (var jar = new JarOutputStream(new FileOutputStream(new File(destinationDirectory, WRAPPER_JAR)), manifest)) {
|
||||||
addClassToJar(jar, Wrapper.class);
|
addClassToJar(jar, Wrapper.class);
|
||||||
|
addClassToJar(jar, Wrapper.LaunchMode.class);
|
||||||
addClassToJar(jar, WrapperClassLoader.class);
|
addClassToJar(jar, WrapperClassLoader.class);
|
||||||
addClassToJar(jar, FileUtils.class);
|
addClassToJar(jar, FileUtils.class);
|
||||||
addClassToJar(jar, FileUtilsErrorException.class);
|
addClassToJar(jar, FileUtilsErrorException.class);
|
||||||
|
|
@ -199,6 +263,107 @@ public class Wrapper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the current directory for the wrapper.
|
||||||
|
*
|
||||||
|
* @param dir the directory to set as the current directory
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public void currentDir(File dir) {
|
||||||
|
currentDir_ = dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the properties set for the wrapper.
|
||||||
|
*
|
||||||
|
* @param version the bld version they should be using
|
||||||
|
* @throws IOException when an error occurred during the creation of the wrapper files
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public void initWrapperProperties(String version)
|
||||||
|
throws IOException {
|
||||||
|
// ensure required properties are available
|
||||||
|
wrapperProperties_.put(PROPERTY_REPOSITORIES, MAVEN_CENTRAL);
|
||||||
|
wrapperProperties_.put(BLD_PROPERTY_VERSION, version);
|
||||||
|
|
||||||
|
// retrieve properties from possible locations
|
||||||
|
var config = libBldDirectory(WRAPPER_PROPERTIES);
|
||||||
|
if (config.exists()) {
|
||||||
|
wrapperPropertiesFile_ = config;
|
||||||
|
wrapperProperties_.load(new FileReader(config));
|
||||||
|
} else {
|
||||||
|
config = libDirectory(WRAPPER_PROPERTIES);
|
||||||
|
if (config.exists()) {
|
||||||
|
wrapperPropertiesFile_ = config;
|
||||||
|
wrapperProperties_.load(new FileReader(config));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// extract repositories
|
||||||
|
if (wrapperProperties_.containsKey(PROPERTY_REPOSITORIES)) {
|
||||||
|
for (var repository : wrapperProperties_.getProperty(PROPERTY_REPOSITORIES).split(",")) {
|
||||||
|
repository = repository.trim();
|
||||||
|
if (!repository.isBlank()) {
|
||||||
|
repositories_.add(repository);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// extract wrapper extension specifications
|
||||||
|
for (var property : wrapperProperties_.entrySet()) {
|
||||||
|
if (property.getKey().toString().startsWith(PROPERTY_EXTENSION_PREFIX)) {
|
||||||
|
for (var extension : property.getValue().toString().split(",")) {
|
||||||
|
extension = extension.trim();
|
||||||
|
if (!extension.isBlank()) {
|
||||||
|
extensions_.add(extension);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// check whether extension sources or javadoc should be downloaded
|
||||||
|
downloadExtensionSources_ = Boolean.parseBoolean(wrapperProperties_.getProperty(PROPERTY_DOWNLOAD_EXTENSION_SOURCES, "false"));
|
||||||
|
downloadExtensionJavadoc_ = Boolean.parseBoolean(wrapperProperties_.getProperty(PROPERTY_DOWNLOAD_EXTENSION_JAVADOC, "false"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the set of extension repositories.
|
||||||
|
*
|
||||||
|
* @return the set of extension repositories
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public Set<String> repositories() {
|
||||||
|
return repositories_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the set of extensions.
|
||||||
|
*
|
||||||
|
* @return the set of extensions
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public Set<String> extensions() {
|
||||||
|
return extensions_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the wrapper properties.
|
||||||
|
*
|
||||||
|
* @return the wrapper properties
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public Properties wrapperProperties() {
|
||||||
|
return wrapperProperties_;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the wrapper properties file.
|
||||||
|
*
|
||||||
|
* @return the wrapper properties file
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public File wrapperPropertiesFile() {
|
||||||
|
return wrapperPropertiesFile_;
|
||||||
|
}
|
||||||
|
|
||||||
private void addClassToJar(JarOutputStream jar, Class klass)
|
private void addClassToJar(JarOutputStream jar, Class klass)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
addFileToJar(jar, klass.getName().replace('.', '/') + ".class");
|
addFileToJar(jar, klass.getName().replace('.', '/') + ".class");
|
||||||
|
|
@ -249,28 +414,49 @@ public class Wrapper {
|
||||||
|
|
||||||
private int installAndLaunch(List<String> arguments) {
|
private int installAndLaunch(List<String> arguments) {
|
||||||
if (!arguments.isEmpty()) {
|
if (!arguments.isEmpty()) {
|
||||||
File current_file = null;
|
File current_file;
|
||||||
try {
|
try {
|
||||||
current_file = new File(arguments.remove(0)).getCanonicalFile();
|
current_file = new File(arguments.remove(0)).getCanonicalFile();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
currentDir_ = new File(current_file.getParent());
|
currentDir_ = new File(current_file.getParent());
|
||||||
}
|
|
||||||
try {
|
if (!arguments.isEmpty() &&
|
||||||
initWrapperProperties(getVersion());
|
BUILD_ARGUMENT.equals(arguments.get(0))) {
|
||||||
File distribution;
|
launchMode_ = LaunchMode.Build;
|
||||||
try {
|
arguments.remove(0);
|
||||||
distribution = installDistribution();
|
|
||||||
} catch (IOException e) {
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// first argument after the --build argument is the main build file
|
||||||
|
// arguments.get(0)
|
||||||
|
|
||||||
|
// check if the next argument enables offline mode
|
||||||
|
if (arguments.size() >= 2 &&
|
||||||
|
OFFLINE_ARGUMENT.equals(arguments.get(1))) {
|
||||||
|
offline_ = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
extractJvmProperties(arguments);
|
||||||
|
initWrapperProperties(getVersion());
|
||||||
|
var distribution = installDistribution();
|
||||||
return launchMain(distribution, arguments);
|
return launchMain(distribution, arguments);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void extractJvmProperties(List<String> arguments) {
|
||||||
|
for (var arg : arguments) {
|
||||||
|
var matcher = JVM_PROPERTY_PATTERN.matcher(arg);
|
||||||
|
if (matcher.matches()) {
|
||||||
|
jvmProperties_.put(matcher.group(1), matcher.group(2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private File buildBldDirectory() {
|
private File buildBldDirectory() {
|
||||||
return Path.of(currentDir_.getAbsolutePath(), "build", "bld").toFile();
|
return Path.of(currentDir_.getAbsolutePath(), "build", "bld").toFile();
|
||||||
}
|
}
|
||||||
|
|
@ -295,50 +481,6 @@ public class Wrapper {
|
||||||
return Path.of(currentDir_.getAbsolutePath(), "lib", "bld", path).toFile();
|
return Path.of(currentDir_.getAbsolutePath(), "lib", "bld", path).toFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initWrapperProperties(String version)
|
|
||||||
throws IOException {
|
|
||||||
// ensure required properties are available
|
|
||||||
wrapperProperties_.put(PROPERTY_REPOSITORIES, MAVEN_CENTRAL);
|
|
||||||
wrapperProperties_.put(BLD_PROPERTY_VERSION, version);
|
|
||||||
|
|
||||||
// retrieve properties from possible locations
|
|
||||||
var config = libBldDirectory(WRAPPER_PROPERTIES);
|
|
||||||
if (config.exists()) {
|
|
||||||
wrapperPropertiesFile_ = config;
|
|
||||||
wrapperProperties_.load(new FileReader(config));
|
|
||||||
} else {
|
|
||||||
config = libDirectory(WRAPPER_PROPERTIES);
|
|
||||||
if (config.exists()) {
|
|
||||||
wrapperPropertiesFile_ = config;
|
|
||||||
wrapperProperties_.load(new FileReader(config));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// extract repositories
|
|
||||||
if (wrapperProperties_.containsKey(PROPERTY_REPOSITORIES)) {
|
|
||||||
for (var repository : wrapperProperties_.getProperty(PROPERTY_REPOSITORIES).split(",")) {
|
|
||||||
repository = repository.trim();
|
|
||||||
if (!repository.isBlank()) {
|
|
||||||
repositories_.add(repository);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// extract wrapper extension specifications
|
|
||||||
for (var property : wrapperProperties_.entrySet()) {
|
|
||||||
if (property.getKey().toString().startsWith(PROPERTY_EXTENSION_PREFIX)) {
|
|
||||||
for (var extension : property.getValue().toString().split(",")) {
|
|
||||||
extension = extension.trim();
|
|
||||||
if (!extension.isBlank()) {
|
|
||||||
extensions_.add(extension);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// check whether extension sources or javadoc should be downloaded
|
|
||||||
downloadExtensionSources_ = Boolean.parseBoolean(wrapperProperties_.getProperty(PROPERTY_DOWNLOAD_EXTENSION_SOURCES, "false"));
|
|
||||||
downloadExtensionJavadoc_ = Boolean.parseBoolean(wrapperProperties_.getProperty(PROPERTY_DOWNLOAD_EXTENSION_JAVADOC, "false"));
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getWrapperVersion()
|
private String getWrapperVersion()
|
||||||
throws IOException {
|
throws IOException {
|
||||||
return wrapperProperties_.getProperty(BLD_PROPERTY_VERSION, getVersion());
|
return wrapperProperties_.getProperty(BLD_PROPERTY_VERSION, getVersion());
|
||||||
|
|
@ -364,7 +506,7 @@ public class Wrapper {
|
||||||
var location = getWrapperDownloadLocation(version);
|
var location = getWrapperDownloadLocation(version);
|
||||||
var result = new StringBuilder(location);
|
var result = new StringBuilder(location);
|
||||||
if (!location.endsWith("/")) {
|
if (!location.endsWith("/")) {
|
||||||
result.append("/");
|
result.append('/');
|
||||||
}
|
}
|
||||||
result.append(fileName);
|
result.append(fileName);
|
||||||
return result.toString();
|
return result.toString();
|
||||||
|
|
@ -401,41 +543,73 @@ public class Wrapper {
|
||||||
|
|
||||||
var download_version = version;
|
var download_version = version;
|
||||||
var is_snapshot = isSnapshot(version);
|
var is_snapshot = isSnapshot(version);
|
||||||
if (is_snapshot) {
|
var is_local = false;
|
||||||
var meta_data = readString(version, new URL(downloadUrl(version, "maven-metadata.xml")));
|
if (offline_) {
|
||||||
var matcher = META_DATA_SNAPSHOT_VERSION.matcher(meta_data);
|
System.out.println("Offline mode: no artifacts will be checked nor downloaded");
|
||||||
if (matcher.find()) {
|
System.out.flush();
|
||||||
download_version = matcher.group(1);
|
}
|
||||||
|
else {
|
||||||
|
if (is_snapshot) {
|
||||||
|
var meta_data = "";
|
||||||
|
try {
|
||||||
|
meta_data = readString(version, new URL(downloadUrl(version, "maven-metadata.xml")));
|
||||||
|
} catch (IOException e) {
|
||||||
|
try {
|
||||||
|
meta_data = readString(version, new URL(downloadUrl(version, "maven-metadata-local.xml")));
|
||||||
|
} catch (IOException e2) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var local_matcher = META_DATA_LOCAL_COPY.matcher(meta_data);
|
||||||
|
is_local = local_matcher.find();
|
||||||
|
if (!is_local) {
|
||||||
|
var version_matcher = META_DATA_SNAPSHOT_VERSION.matcher(meta_data);
|
||||||
|
if (version_matcher.find()) {
|
||||||
|
download_version = version_matcher.group(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var distribution_file = new File(DISTRIBUTIONS_DIR, bldFileName(version));
|
var distribution_file = new File(DISTRIBUTIONS_DIR, bldFileName(version));
|
||||||
var distribution_sources_file = new File(DISTRIBUTIONS_DIR, bldSourcesFileName(version));
|
var distribution_sources_file = new File(DISTRIBUTIONS_DIR, bldSourcesFileName(version));
|
||||||
|
|
||||||
// if this is a snapshot and the distribution file exists,
|
if (!offline_) {
|
||||||
// ensure that it's the latest by comparing hashes
|
// if this is a snapshot and the distribution file exists,
|
||||||
if (is_snapshot && distribution_file.exists()) {
|
// ensure that it's the latest by comparing hashes
|
||||||
var download_md5 = readString(version, new URL(downloadUrl(version, bldFileName(download_version)) + ".md5"));
|
if (is_snapshot && distribution_file.exists()) {
|
||||||
try {
|
boolean delete_distribution_files = is_local;
|
||||||
var digest = MessageDigest.getInstance("MD5");
|
if (!delete_distribution_files) {
|
||||||
digest.update(FileUtils.readBytes(distribution_file));
|
var download_md5 = readString(version, new URL(downloadUrl(version, bldFileName(download_version)) + ".md5"));
|
||||||
if (!download_md5.equals(encodeHexLower(digest.digest()))) {
|
try {
|
||||||
distribution_file.delete();
|
var digest = MessageDigest.getInstance("MD5");
|
||||||
distribution_sources_file.delete();
|
digest.update(FileUtils.readBytes(distribution_file));
|
||||||
|
if (!download_md5.equals(encodeHexLower(digest.digest()))) {
|
||||||
|
delete_distribution_files = true;
|
||||||
|
}
|
||||||
|
} catch (NoSuchAlgorithmException ignore) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (NoSuchAlgorithmException ignore) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// download distribution jars if necessary
|
if (delete_distribution_files) {
|
||||||
if (!distribution_file.exists()) {
|
distribution_file.delete();
|
||||||
downloadDistribution(distribution_file, downloadUrl(version, bldFileName(download_version)));
|
if (distribution_sources_file.exists()) {
|
||||||
}
|
distribution_sources_file.delete();
|
||||||
if (!distribution_sources_file.exists()) {
|
}
|
||||||
try {
|
}
|
||||||
downloadDistribution(distribution_sources_file, downloadUrl(version, bldSourcesFileName(download_version)));
|
|
||||||
} catch (IOException e) {
|
}
|
||||||
// this is not critical, ignore
|
|
||||||
|
// download distribution jars if necessary
|
||||||
|
if (!distribution_file.exists()) {
|
||||||
|
downloadDistribution(distribution_file, downloadUrl(version, bldFileName(download_version)));
|
||||||
|
}
|
||||||
|
if (!distribution_sources_file.exists()) {
|
||||||
|
try {
|
||||||
|
downloadDistribution(distribution_sources_file, downloadUrl(version, bldSourcesFileName(download_version)));
|
||||||
|
} catch (IOException e) {
|
||||||
|
// this is not critical, ignore
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -475,15 +649,17 @@ public class Wrapper {
|
||||||
|
|
||||||
private void resolveExtensions() {
|
private void resolveExtensions() {
|
||||||
if (null == classloader_ ||
|
if (null == classloader_ ||
|
||||||
null == wrapperPropertiesFile_) {
|
null == wrapperPropertiesFile_ ||
|
||||||
|
offline_) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var resolver_class = classloader_.loadClass("rife.bld.wrapper.WrapperExtensionResolver");
|
var resolver_class = classloader_.loadClass("rife.bld.wrapper.WrapperExtensionResolver");
|
||||||
var constructor = resolver_class.getConstructor(File.class, File.class, File.class, Collection.class, Collection.class, boolean.class, boolean.class);
|
var constructor = resolver_class.getConstructor(File.class, File.class, Properties.class, Properties.class, Collection.class, Collection.class, boolean.class, boolean.class);
|
||||||
var update_method = resolver_class.getMethod("updateExtensions");
|
var update_method = resolver_class.getMethod("updateExtensions");
|
||||||
var resolver = constructor.newInstance(currentDir_, new File(wrapperPropertiesFile_.getAbsolutePath() + ".hash"), libBldDirectory(),
|
var resolver = constructor.newInstance(currentDir_, libBldDirectory(),
|
||||||
|
jvmProperties_, wrapperProperties_,
|
||||||
repositories_, extensions_,
|
repositories_, extensions_,
|
||||||
downloadExtensionSources_, downloadExtensionJavadoc_);
|
downloadExtensionSources_, downloadExtensionJavadoc_);
|
||||||
update_method.invoke(resolver);
|
update_method.invoke(resolver);
|
||||||
|
|
@ -496,7 +672,7 @@ public class Wrapper {
|
||||||
|
|
||||||
private int launchMain(File jarFile, List<String> arguments)
|
private int launchMain(File jarFile, List<String> arguments)
|
||||||
throws IOException, InterruptedException, FileUtilsErrorException {
|
throws IOException, InterruptedException, FileUtilsErrorException {
|
||||||
if (arguments.isEmpty() || !arguments.get(0).equals("--build")) {
|
if (launchMode_ == LaunchMode.Cli) {
|
||||||
return launchMainCli(jarFile, arguments);
|
return launchMainCli(jarFile, arguments);
|
||||||
}
|
}
|
||||||
return launchMainBuild(jarFile, arguments);
|
return launchMainBuild(jarFile, arguments);
|
||||||
|
|
@ -505,8 +681,8 @@ public class Wrapper {
|
||||||
private int launchMainCli(File jarFile, List<String> arguments)
|
private int launchMainCli(File jarFile, List<String> arguments)
|
||||||
throws IOException, InterruptedException {
|
throws IOException, InterruptedException {
|
||||||
var args = new ArrayList<String>();
|
var args = new ArrayList<String>();
|
||||||
args.add("java");
|
args.add(findJavaExecutable());
|
||||||
includeJvmParameters(arguments, args);
|
includeJvmProperties(arguments, args);
|
||||||
|
|
||||||
args.add("-cp");
|
args.add("-cp");
|
||||||
args.add(jarFile.getAbsolutePath());
|
args.add(jarFile.getAbsolutePath());
|
||||||
|
|
@ -514,6 +690,7 @@ public class Wrapper {
|
||||||
args.add("-jar");
|
args.add("-jar");
|
||||||
args.add(jarFile.getAbsolutePath());
|
args.add(jarFile.getAbsolutePath());
|
||||||
|
|
||||||
|
args.addAll(bldJavaOptions());
|
||||||
args.addAll(arguments);
|
args.addAll(arguments);
|
||||||
|
|
||||||
var process_builder = new ProcessBuilder(args);
|
var process_builder = new ProcessBuilder(args);
|
||||||
|
|
@ -526,8 +703,6 @@ public class Wrapper {
|
||||||
throws IOException, InterruptedException {
|
throws IOException, InterruptedException {
|
||||||
resolveExtensions();
|
resolveExtensions();
|
||||||
|
|
||||||
arguments.remove(0);
|
|
||||||
|
|
||||||
var build_bld_dir = buildBldDirectory();
|
var build_bld_dir = buildBldDirectory();
|
||||||
if (build_bld_dir.exists()) {
|
if (build_bld_dir.exists()) {
|
||||||
FileUtils.deleteDirectory(buildBldDirectory());
|
FileUtils.deleteDirectory(buildBldDirectory());
|
||||||
|
|
@ -545,6 +720,7 @@ public class Wrapper {
|
||||||
var compilation_units = file_manager.getJavaFileObjectsFromFiles(bldSourceFiles());
|
var compilation_units = file_manager.getJavaFileObjectsFromFiles(bldSourceFiles());
|
||||||
var diagnostics = new DiagnosticCollector<JavaFileObject>();
|
var diagnostics = new DiagnosticCollector<JavaFileObject>();
|
||||||
var options = new ArrayList<>(List.of("-d", buildBldDirectory().getAbsolutePath(), "-cp", classpath));
|
var options = new ArrayList<>(List.of("-d", buildBldDirectory().getAbsolutePath(), "-cp", classpath));
|
||||||
|
options.addAll(bldJavacOptions());
|
||||||
var compilation_task = compiler.getTask(null, file_manager, diagnostics, options, null, compilation_units);
|
var compilation_task = compiler.getTask(null, file_manager, diagnostics, options, null, compilation_units);
|
||||||
if (!compilation_task.call()) {
|
if (!compilation_task.call()) {
|
||||||
if (!diagnostics.getDiagnostics().isEmpty()) {
|
if (!diagnostics.getDiagnostics().isEmpty()) {
|
||||||
|
|
@ -558,11 +734,15 @@ public class Wrapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
var java_args = new ArrayList<String>();
|
var java_args = new ArrayList<String>();
|
||||||
java_args.add("java");
|
java_args.add(findJavaExecutable());
|
||||||
includeJvmParameters(arguments, java_args);
|
includeJvmProperties(arguments, java_args);
|
||||||
|
|
||||||
java_args.add("-cp");
|
java_args.add("-cp");
|
||||||
java_args.add(classpath);
|
java_args.add(classpath);
|
||||||
|
|
||||||
|
java_args.addAll(bldJavaOptions());
|
||||||
java_args.addAll(arguments);
|
java_args.addAll(arguments);
|
||||||
|
|
||||||
var process_builder = new ProcessBuilder(java_args);
|
var process_builder = new ProcessBuilder(java_args);
|
||||||
process_builder.directory(currentDir_);
|
process_builder.directory(currentDir_);
|
||||||
process_builder.inheritIO();
|
process_builder.inheritIO();
|
||||||
|
|
@ -571,11 +751,20 @@ public class Wrapper {
|
||||||
return process.waitFor();
|
return process.waitFor();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void includeJvmParameters(List<String> arguments, List<String> javaArgs) {
|
private static String findJavaExecutable() {
|
||||||
|
var executable = System.getProperty("os.name").toLowerCase().contains("win") ? "java.exe" : "java";
|
||||||
|
var java_home = System.getProperty("java.home");
|
||||||
|
if (null == java_home) {
|
||||||
|
return executable;
|
||||||
|
}
|
||||||
|
return java_home + File.separator + "bin" + File.separator + executable;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void includeJvmProperties(List<String> arguments, List<String> javaArgs) {
|
||||||
var i = arguments.iterator();
|
var i = arguments.iterator();
|
||||||
while (i.hasNext()) {
|
while (i.hasNext()) {
|
||||||
var arg = i.next();
|
var arg = i.next();
|
||||||
if (arg.matches("-D(.+?)=(.*)")) {
|
if (JVM_PROPERTY_PATTERN.matcher(arg).matches()) {
|
||||||
javaArgs.add(arg);
|
javaArgs.add(arg);
|
||||||
i.remove();
|
i.remove();
|
||||||
}
|
}
|
||||||
|
|
@ -585,7 +774,7 @@ public class Wrapper {
|
||||||
private List<File> bldClasspathJars() {
|
private List<File> bldClasspathJars() {
|
||||||
// detect the jar files in the compile lib directory
|
// detect the jar files in the compile lib directory
|
||||||
var dir_abs = libBldDirectory().getAbsoluteFile();
|
var dir_abs = libBldDirectory().getAbsoluteFile();
|
||||||
var jar_files = FileUtils.getFileList(dir_abs, JAR_FILE_PATTERN, Pattern.compile(WRAPPER_JAR));
|
var jar_files = FileUtils.getFileList(dir_abs, CLASSPATH_INCLUDED_JARS, CLASSPATH_EXCLUDED_JARS);
|
||||||
|
|
||||||
// build the compilation classpath
|
// build the compilation classpath
|
||||||
return new ArrayList<>(jar_files.stream().map(file -> new File(dir_abs, file)).toList());
|
return new ArrayList<>(jar_files.stream().map(file -> new File(dir_abs, file)).toList());
|
||||||
|
|
@ -615,6 +804,28 @@ public class Wrapper {
|
||||||
return source_files;
|
return source_files;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<String> bldJavacOptions() {
|
||||||
|
if (!wrapperProperties_.containsKey(PROPERTY_JAVAC_OPTIONS)) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
return OPTIONS_PATTERN.matcher(wrapperProperties_.get(PROPERTY_JAVAC_OPTIONS).toString())
|
||||||
|
.results()
|
||||||
|
.map(MatchResult::group)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> bldJavaOptions() {
|
||||||
|
if (!wrapperProperties_.containsKey(PROPERTY_JAVA_OPTIONS)) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
return OPTIONS_PATTERN.matcher(wrapperProperties_.get(PROPERTY_JAVA_OPTIONS).toString())
|
||||||
|
.results()
|
||||||
|
.map(MatchResult::group)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
private String readString(String version, URL url)
|
private String readString(String version, URL url)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
var connection = url.openConnection();
|
var connection = url.openConnection();
|
||||||
|
|
|
||||||
|
|
@ -4,16 +4,12 @@
|
||||||
*/
|
*/
|
||||||
package rife.bld.wrapper;
|
package rife.bld.wrapper;
|
||||||
|
|
||||||
|
import rife.bld.BldCache;
|
||||||
import rife.bld.BuildExecutor;
|
import rife.bld.BuildExecutor;
|
||||||
import rife.bld.dependencies.*;
|
import rife.bld.dependencies.*;
|
||||||
import rife.tools.FileUtils;
|
import rife.ioc.HierarchicalProperties;
|
||||||
import rife.tools.StringUtils;
|
|
||||||
import rife.tools.exceptions.FileUtilsErrorException;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.security.MessageDigest;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import static rife.bld.dependencies.Dependency.CLASSIFIER_JAVADOC;
|
import static rife.bld.dependencies.Dependency.CLASSIFIER_JAVADOC;
|
||||||
|
|
@ -28,9 +24,8 @@ import static rife.bld.dependencies.Dependency.CLASSIFIER_SOURCES;
|
||||||
* @since 1.5.8
|
* @since 1.5.8
|
||||||
*/
|
*/
|
||||||
public class WrapperExtensionResolver {
|
public class WrapperExtensionResolver {
|
||||||
private final ArtifactRetriever retriever_ = ArtifactRetriever.cachingInstance();
|
private final VersionResolution resolution_;
|
||||||
private final File hashFile_;
|
private final ArtifactRetriever retriever_;
|
||||||
private final String fingerPrintHash_;
|
|
||||||
private final File destinationDirectory_;
|
private final File destinationDirectory_;
|
||||||
private final List<Repository> repositories_ = new ArrayList<>();
|
private final List<Repository> repositories_ = new ArrayList<>();
|
||||||
private final DependencySet dependencies_ = new DependencySet();
|
private final DependencySet dependencies_ = new DependencySet();
|
||||||
|
|
@ -40,39 +35,41 @@ public class WrapperExtensionResolver {
|
||||||
|
|
||||||
private boolean headerPrinted_ = false;
|
private boolean headerPrinted_ = false;
|
||||||
|
|
||||||
public WrapperExtensionResolver(File currentDir, File hashFile, File destinationDirectory,
|
public WrapperExtensionResolver(File currentDir, File destinationDirectory,
|
||||||
|
Properties jvmProperties, Properties wrapperProperties,
|
||||||
Collection<String> repositories, Collection<String> extensions,
|
Collection<String> repositories, Collection<String> extensions,
|
||||||
boolean downloadSources, boolean downloadJavadoc) {
|
boolean downloadSources, boolean downloadJavadoc) {
|
||||||
var properties = BuildExecutor.setupProperties(currentDir);
|
var properties = BuildExecutor.setupProperties(currentDir);
|
||||||
|
properties.getRoot().putAll(jvmProperties);
|
||||||
|
properties = new HierarchicalProperties().parent(properties);
|
||||||
|
properties.putAll(wrapperProperties);
|
||||||
|
|
||||||
|
resolution_ = new VersionResolution(properties);
|
||||||
|
|
||||||
|
retriever_ = ArtifactRetriever.cachingInstance();
|
||||||
Repository.resolveMavenLocal(properties);
|
Repository.resolveMavenLocal(properties);
|
||||||
|
|
||||||
hashFile_ = hashFile;
|
|
||||||
destinationDirectory_ = destinationDirectory;
|
destinationDirectory_ = destinationDirectory;
|
||||||
|
|
||||||
for (var repository : repositories) {
|
for (var repository : repositories) {
|
||||||
repositories_.add(Repository.resolveRepository(properties, repository));
|
repositories_.add(Repository.resolveRepository(properties, repository));
|
||||||
}
|
}
|
||||||
dependencies_.addAll(extensions.stream().map(Dependency::parse).toList());
|
|
||||||
|
dependencies_.addAll(extensions.stream().map(d -> resolution_.overrideDependency(Dependency.parse(d))).toList());
|
||||||
|
|
||||||
downloadSources_ = downloadSources;
|
downloadSources_ = downloadSources;
|
||||||
downloadJavadoc_ = downloadJavadoc;
|
downloadJavadoc_ = downloadJavadoc;
|
||||||
fingerPrintHash_ = createHash(repositories_.stream().map(Objects::toString).toList(), extensions, downloadSources, downloadJavadoc);
|
|
||||||
}
|
|
||||||
|
|
||||||
private String createHash(Collection<String> repositories, Collection<String> extensions, boolean downloadSources, boolean downloadJavadoc) {
|
|
||||||
try {
|
|
||||||
var fingerprint = String.join("\n", repositories) + "\n" + String.join("\n", extensions) + "\n" + downloadSources + "\n" + downloadJavadoc;
|
|
||||||
var digest = MessageDigest.getInstance("SHA-1");
|
|
||||||
digest.update(fingerprint.getBytes(StandardCharsets.UTF_8));
|
|
||||||
return StringUtils.encodeHexLower(digest.digest());
|
|
||||||
} catch (NoSuchAlgorithmException e) {
|
|
||||||
// should not happen
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateExtensions() {
|
public void updateExtensions() {
|
||||||
// verify and update the fingerprint hash file,
|
// verify and update the fingerprint hash file,
|
||||||
// don't update the extensions if the hash is identical
|
// don't update the extensions if the hash is identical
|
||||||
if (validateHash()) {
|
var cache = new BldCache(destinationDirectory_, resolution_);
|
||||||
|
cache.cacheExtensionsHash(
|
||||||
|
repositories_.stream().map(Objects::toString).toList(),
|
||||||
|
dependencies_.stream().map(Objects::toString).toList());
|
||||||
|
cache.cacheExtensionsDownloads(downloadSources_, downloadJavadoc_);
|
||||||
|
if (cache.isExtensionsCacheValid()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -82,74 +79,20 @@ public class WrapperExtensionResolver {
|
||||||
// purge the files that are not part of the latest extensions anymore
|
// purge the files that are not part of the latest extensions anymore
|
||||||
purgeExtensionDependencies(filenames);
|
purgeExtensionDependencies(filenames);
|
||||||
|
|
||||||
writeHash();
|
cache.cacheExtensionsLocalArtifacts(localArtifacts_);
|
||||||
|
cache.writeCache();
|
||||||
|
|
||||||
if (headerPrinted_) {
|
if (headerPrinted_) {
|
||||||
System.out.println();
|
System.out.println();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean validateHash() {
|
|
||||||
try {
|
|
||||||
if (hashFile_.exists()) {
|
|
||||||
var contents = FileUtils.readString(hashFile_);
|
|
||||||
var lines = StringUtils.split(contents, "\n");
|
|
||||||
if (!lines.isEmpty()) {
|
|
||||||
// first line is the fingerprint hash
|
|
||||||
if (lines.remove(0).equals(fingerPrintHash_)) {
|
|
||||||
// other lines are last modified timestamps of local files
|
|
||||||
// that were dependency artifacts
|
|
||||||
while (!lines.isEmpty()) {
|
|
||||||
var line = lines.get(0);
|
|
||||||
var parts = line.split(":", 2);
|
|
||||||
// verify that the local file has the same modified timestamp still
|
|
||||||
if (parts.length == 2) {
|
|
||||||
var file = new File(parts[1]);
|
|
||||||
if (!file.exists() || !file.canRead() || file.lastModified() != Long.parseLong(parts[0])) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
lines.remove(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// there were no invalid lines, so the hash file contents are valid
|
|
||||||
if (lines.isEmpty()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
hashFile_.delete();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
} catch (FileUtilsErrorException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void writeHash() {
|
|
||||||
try {
|
|
||||||
var contents = new StringBuilder();
|
|
||||||
contents.append(fingerPrintHash_);
|
|
||||||
for (var file : localArtifacts_) {
|
|
||||||
if (file.exists() && file.canRead()) {
|
|
||||||
contents.append("\n").append(file.lastModified()).append(":").append(file.getAbsolutePath());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FileUtils.writeString(contents.toString(), hashFile_);
|
|
||||||
} catch (FileUtilsErrorException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Set<String> transferExtensionDependencies() {
|
private Set<String> transferExtensionDependencies() {
|
||||||
var filenames = new HashSet<String>();
|
var filenames = new HashSet<String>();
|
||||||
var dependencies = new DependencySet();
|
var dependencies = new DependencySet();
|
||||||
for (var d : dependencies_) {
|
for (var d : dependencies_) {
|
||||||
if (d != null) {
|
if (d != null) {
|
||||||
dependencies.addAll(new DependencyResolver(retriever_, repositories_, d).getAllDependencies(Scope.compile, Scope.runtime));
|
dependencies.addAll(new DependencyResolver(resolution_, retriever_, repositories_, d).getAllDependencies(Scope.compile, Scope.runtime));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!dependencies.isEmpty()) {
|
if (!dependencies.isEmpty()) {
|
||||||
|
|
@ -166,7 +109,7 @@ public class WrapperExtensionResolver {
|
||||||
additional_classifiers = classifiers.toArray(new String[0]);
|
additional_classifiers = classifiers.toArray(new String[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
var artifacts = dependencies.transferIntoDirectory(retriever_, repositories_, destinationDirectory_, additional_classifiers);
|
var artifacts = dependencies.transferIntoDirectory(resolution_, retriever_, repositories_, destinationDirectory_, destinationDirectory_, additional_classifiers);
|
||||||
for (var artifact : artifacts) {
|
for (var artifact : artifacts) {
|
||||||
var location = artifact.location();
|
var location = artifact.location();
|
||||||
|
|
||||||
|
|
@ -183,7 +126,7 @@ public class WrapperExtensionResolver {
|
||||||
private void purgeExtensionDependencies(Set<String> filenames) {
|
private void purgeExtensionDependencies(Set<String> filenames) {
|
||||||
for (var file : destinationDirectory_.listFiles()) {
|
for (var file : destinationDirectory_.listFiles()) {
|
||||||
if (file.getName().startsWith(Wrapper.WRAPPER_PREFIX) ||
|
if (file.getName().startsWith(Wrapper.WRAPPER_PREFIX) ||
|
||||||
file.getName().equals(Wrapper.BLD_BUILD_HASH)) {
|
file.getName().equals(Wrapper.BLD_CACHE)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!filenames.contains(file.getName())) {
|
if (!filenames.contains(file.getName())) {
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue