mirror of
https://github.com/ethauvin/bld.git
synced 2025-04-24 07:47:11 -07:00
First commit of standalone repo
This commit is contained in:
commit
696b23b57a
241 changed files with 28028 additions and 0 deletions
57
.gitignore
vendored
Normal file
57
.gitignore
vendored
Normal file
|
@ -0,0 +1,57 @@
|
|||
*.log
|
||||
embedded_dbs
|
||||
.gradle
|
||||
.DS_Store
|
||||
build
|
||||
lib/bld/**
|
||||
lib/compile/**
|
||||
lib/runtime/**
|
||||
lib/standalone/**
|
||||
lib/test/**
|
||||
!bld-wrapper.jar
|
||||
!bld-wrapper.properties
|
||||
|
||||
# IDEA ignores
|
||||
|
||||
# User-specific
|
||||
.idea/**/workspace.xml
|
||||
.idea/**/tasks.xml
|
||||
.idea/**/usage.statistics.xml
|
||||
.idea/**/dictionaries
|
||||
.idea/**/shelf
|
||||
|
||||
# AWS User-specific
|
||||
.idea/**/aws.xml
|
||||
|
||||
# Generated files
|
||||
.idea/**/contentModel.xml
|
||||
|
||||
# Sensitive or high-churn files
|
||||
.idea/**/dataSources/
|
||||
.idea/**/dataSources.ids
|
||||
.idea/**/dataSources.local.xml
|
||||
.idea/**/sqlDataSources.xml
|
||||
.idea/**/dynamic.xml
|
||||
.idea/**/uiDesigner.xml
|
||||
.idea/**/dbnavigator.xml
|
||||
|
||||
# Gradle
|
||||
.idea/**/gradle.xml
|
||||
|
||||
# Mongo Explorer plugin
|
||||
.idea/**/mongoSettings.xml
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Cursive Clojure plugin
|
||||
.idea/replstate.xml
|
||||
|
||||
# SonarLint plugin
|
||||
.idea/sonarlint/
|
||||
|
||||
# Editor-based Rest Client
|
||||
.idea/httpRequests
|
8
.idea/.gitignore
generated
vendored
Normal file
8
.idea/.gitignore
generated
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
14
.idea/bld.iml
generated
Normal file
14
.idea/bld.iml
generated
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<output url="file://$MODULE_DIR$/build/bld" />
|
||||
<output-test url="file://$MODULE_DIR$/build/bld" />
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$/src/bld">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/bld/java" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="bld" level="project" />
|
||||
</component>
|
||||
</module>
|
7
.idea/codeStyles/Project.xml
generated
Normal file
7
.idea/codeStyles/Project.xml
generated
Normal file
|
@ -0,0 +1,7 @@
|
|||
<component name="ProjectCodeStyleConfiguration">
|
||||
<code_scheme name="Project" version="173">
|
||||
<ScalaCodeStyleSettings>
|
||||
<option name="MULTILINE_STRING_CLOSING_QUOTES_ON_NEW_LINE" value="true" />
|
||||
</ScalaCodeStyleSettings>
|
||||
</code_scheme>
|
||||
</component>
|
5
.idea/codeStyles/codeStyleConfig.xml
generated
Normal file
5
.idea/codeStyles/codeStyleConfig.xml
generated
Normal file
|
@ -0,0 +1,5 @@
|
|||
<component name="ProjectCodeStyleConfiguration">
|
||||
<state>
|
||||
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
|
||||
</state>
|
||||
</component>
|
32
.idea/framework.iml
generated
Normal file
32
.idea/framework.iml
generated
Normal file
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<output url="file://$MODULE_DIR$/build/main" />
|
||||
<output-test url="file://$MODULE_DIR$/build/test" />
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="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/test/java" isTestSource="true" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/core/src/main/resources/templates" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/src/main/resources/templates" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module-library" scope="RUNTIME">
|
||||
<library>
|
||||
<CLASSES>
|
||||
<root url="file://$MODULE_DIR$/src/main/resources/templates" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</orderEntry>
|
||||
<orderEntry type="library" name="compile" level="project" />
|
||||
<orderEntry type="library" scope="RUNTIME" name="runtime" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="test" level="project" />
|
||||
<orderEntry type="module" module-name="bld" />
|
||||
</component>
|
||||
</module>
|
17
.idea/libraries/bld.xml
generated
Normal file
17
.idea/libraries/bld.xml
generated
Normal file
|
@ -0,0 +1,17 @@
|
|||
<component name="libraryTable">
|
||||
<library name="bld">
|
||||
<CLASSES>
|
||||
<root url="file://$PROJECT_DIR$/lib/bld" />
|
||||
<root url="jar://$USER_HOME$/.rife2/dist/rife2-1.6.3.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$USER_HOME$/.rife2/dist/rife2-1.6.3-sources.jar!/" />
|
||||
</SOURCES>
|
||||
<excluded>
|
||||
<root url="jar://$PROJECT_DIR$/lib/bld/bld-wrapper.jar!/" />
|
||||
</excluded>
|
||||
<jarDirectory url="file://$PROJECT_DIR$/lib/bld" recursive="false" />
|
||||
<jarDirectory url="file://$PROJECT_DIR$/lib/bld" recursive="false" type="SOURCES" />
|
||||
</library>
|
||||
</component>
|
13
.idea/libraries/compile.xml
generated
Normal file
13
.idea/libraries/compile.xml
generated
Normal file
|
@ -0,0 +1,13 @@
|
|||
<component name="libraryTable">
|
||||
<library name="compile">
|
||||
<CLASSES>
|
||||
<root url="file://$PROJECT_DIR$/lib/compile" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="file://$PROJECT_DIR$/lib/compile" />
|
||||
</SOURCES>
|
||||
<jarDirectory url="file://$PROJECT_DIR$/lib/compile" recursive="false" />
|
||||
<jarDirectory url="file://$PROJECT_DIR$/lib/compile" recursive="false" type="SOURCES" />
|
||||
</library>
|
||||
</component>
|
14
.idea/libraries/runtime.xml
generated
Normal file
14
.idea/libraries/runtime.xml
generated
Normal file
|
@ -0,0 +1,14 @@
|
|||
<component name="libraryTable">
|
||||
<library name="runtime">
|
||||
<CLASSES>
|
||||
<root url="file://$PROJECT_DIR$/lib/runtime" />
|
||||
<root url="file://$PROJECT_DIR$/src/main/resources" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="file://$PROJECT_DIR$/lib/runtime" />
|
||||
</SOURCES>
|
||||
<jarDirectory url="file://$PROJECT_DIR$/lib/runtime" recursive="false" />
|
||||
<jarDirectory url="file://$PROJECT_DIR$/lib/runtime" recursive="false" type="SOURCES" />
|
||||
</library>
|
||||
</component>
|
15
.idea/libraries/test.xml
generated
Normal file
15
.idea/libraries/test.xml
generated
Normal file
|
@ -0,0 +1,15 @@
|
|||
<component name="libraryTable">
|
||||
<library name="test">
|
||||
<CLASSES>
|
||||
<root url="file://$PROJECT_DIR$/lib/test" />
|
||||
<root url="file://$PROJECT_DIR$/src/test/resources" />
|
||||
<root url="file://$PROJECT_DIR$/core/src/test/resources" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="file://$PROJECT_DIR$/lib/test" />
|
||||
</SOURCES>
|
||||
<jarDirectory url="file://$PROJECT_DIR$/lib/test" recursive="false" />
|
||||
<jarDirectory url="file://$PROJECT_DIR$/lib/test" recursive="false" type="SOURCES" />
|
||||
</library>
|
||||
</component>
|
9
.idea/misc.xml
generated
Normal file
9
.idea/misc.xml
generated
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="PDMPlugin">
|
||||
<option name="skipTestSources" value="false" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" project-jdk-name="19" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/build" />
|
||||
</component>
|
||||
</project>
|
9
.idea/modules.xml
generated
Normal file
9
.idea/modules.xml
generated
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/bld.iml" filepath="$PROJECT_DIR$/.idea/bld.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/framework.iml" filepath="$PROJECT_DIR$/.idea/framework.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
13
.idea/runConfigurations/Run Tests.xml
generated
Normal file
13
.idea/runConfigurations/Run Tests.xml
generated
Normal file
|
@ -0,0 +1,13 @@
|
|||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Run Tests" type="JUnit" factoryName="JUnit">
|
||||
<module name="framework" />
|
||||
<option name="PACKAGE_NAME" value="rife" />
|
||||
<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>
|
7
.idea/vcs.xml
generated
Normal file
7
.idea/vcs.xml
generated
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/core" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
202
LICENSE.txt
Normal file
202
LICENSE.txt
Normal file
|
@ -0,0 +1,202 @@
|
|||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
2
bld
Executable file
2
bld
Executable file
|
@ -0,0 +1,2 @@
|
|||
#!/usr/bin/env sh
|
||||
java -jar "$(dirname "$0")/lib/bld/bld-wrapper.jar" "$0" --build rife.BldBuild "$@"
|
4
bld.bat
Normal file
4
bld.bat
Normal file
|
@ -0,0 +1,4 @@
|
|||
@echo off
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
java -jar "%DIRNAME%/lib/bld/bld-wrapper.jar" "%0" --build rife.BldBuild %*
|
BIN
images/bld_logo.png
Normal file
BIN
images/bld_logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.9 KiB |
13
images/bld_logo.svg
Normal file
13
images/bld_logo.svg
Normal file
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 179 108" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<g transform="matrix(1,0,0,1,-210.511,-96.3382)">
|
||||
<g transform="matrix(1,0,0,1,-23.3386,-649.816)">
|
||||
<g transform="matrix(0.221288,0,0,0.24,73.9536,390.254)">
|
||||
<path d="M722.568,1482.92L722.568,1921.1L808.968,1921.1L808.968,1888.7C822.168,1907.9 846.168,1930.1 893.568,1930.1C933.168,1930.1 961.968,1917.5 985.368,1893.5C1012.97,1865.9 1027.37,1827.5 1027.37,1786.1C1027.37,1741.7 1011.17,1705.1 985.368,1680.5C961.968,1658.3 928.968,1644.5 892.368,1644.5C862.968,1644.5 830.568,1654.1 808.968,1683.5L808.968,1482.92L722.568,1482.92ZM871.368,1718.9C888.768,1718.9 903.768,1723.7 917.568,1736.9C930.168,1748.9 938.568,1766.3 938.568,1787.9C938.568,1807.7 930.168,1825.1 917.568,1837.1C904.368,1849.7 887.568,1855.7 872.568,1855.7C856.368,1855.7 837.168,1849.1 823.368,1835.9C813.168,1826.3 803.568,1810.1 803.568,1787.9C803.568,1765.1 812.568,1749.5 822.768,1738.7C836.568,1724.3 852.768,1718.9 871.368,1718.9Z" style="fill:rgb(35,146,255);fill-rule:nonzero;"/>
|
||||
<rect x="1083.77" y="1482.92" width="86.4" height="438.182" style="fill:rgb(250,144,82);fill-rule:nonzero;"/>
|
||||
<path d="M1531.37,1482.92L1444.97,1482.92L1444.97,1683.5C1423.37,1654.1 1390.97,1644.5 1361.57,1644.5C1324.97,1644.5 1291.97,1658.3 1268.57,1680.5C1242.77,1705.1 1226.57,1741.7 1226.57,1786.1C1226.57,1827.5 1240.97,1865.9 1268.57,1893.5C1291.97,1917.5 1320.77,1930.1 1360.37,1930.1C1407.77,1930.1 1431.77,1907.9 1444.97,1888.7L1444.97,1921.1L1531.37,1921.1L1531.37,1482.92ZM1382.57,1718.9C1401.17,1718.9 1417.37,1724.3 1431.17,1738.7C1441.37,1749.5 1450.37,1765.1 1450.37,1787.9C1450.37,1810.1 1440.77,1826.3 1430.57,1835.9C1416.77,1849.1 1397.57,1855.7 1381.37,1855.7C1366.37,1855.7 1349.57,1849.7 1336.37,1837.1C1323.77,1825.1 1315.37,1807.7 1315.37,1787.9C1315.37,1766.3 1323.77,1748.9 1336.37,1736.9C1350.17,1723.7 1365.17,1718.9 1382.57,1718.9Z" style="fill:rgb(35,146,255);fill-rule:nonzero;"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.4 KiB |
BIN
lib/bld/bld-wrapper.jar
Normal file
BIN
lib/bld/bld-wrapper.jar
Normal file
Binary file not shown.
8
lib/bld/bld-wrapper.properties
Normal file
8
lib/bld/bld-wrapper.properties
Normal file
|
@ -0,0 +1,8 @@
|
|||
bld.downloadExtensionJavadoc=false
|
||||
bld.downloadExtensionSources=true
|
||||
bld.extension-antlr=com.uwyn.rife2:bld-antlr4:1.1.0
|
||||
bld.extension-archive=com.uwyn.rife2:bld-archive:0.3.0
|
||||
bld.extension-tests=com.uwyn.rife2:bld-tests-badge:1.3.0
|
||||
bld.repositories=MAVEN_CENTRAL,RIFE2_RELEASES
|
||||
rife2.downloadLocation=
|
||||
rife2.version=1.6.3
|
254
src/bld/java/rife/BldBuild.java
Normal file
254
src/bld/java/rife/BldBuild.java
Normal file
|
@ -0,0 +1,254 @@
|
|||
/*
|
||||
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||
*/
|
||||
package rife;
|
||||
|
||||
import rife.bld.BuildCommand;
|
||||
import rife.bld.Project;
|
||||
import rife.bld.dependencies.VersionNumber;
|
||||
import rife.bld.extension.Antlr4Operation;
|
||||
import rife.bld.extension.TestsBadgeOperation;
|
||||
import rife.bld.extension.ZipOperation;
|
||||
import rife.bld.operations.*;
|
||||
import rife.bld.publish.*;
|
||||
import rife.bld.wrapper.Wrapper;
|
||||
import rife.tools.DirBuilder;
|
||||
import rife.tools.FileUtils;
|
||||
import rife.tools.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
import java.util.List;
|
||||
import java.util.jar.Attributes;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static rife.bld.dependencies.Repository.*;
|
||||
import static rife.bld.dependencies.Scope.*;
|
||||
import static rife.bld.operations.JavadocOptions.DocLinkOption.NO_MISSING;
|
||||
import static rife.bld.operations.TemplateType.*;
|
||||
import static rife.tools.FileUtils.path;
|
||||
|
||||
public class BldBuild extends Project {
|
||||
public BldBuild()
|
||||
throws Exception {
|
||||
pkg = "rife";
|
||||
name = "bld";
|
||||
mainClass = "rife.bld.Cli";
|
||||
version = version(FileUtils.readString(new File(srcMainResourcesDirectory(), "BLD_VERSION")));
|
||||
|
||||
javaRelease = 17;
|
||||
downloadSources = true;
|
||||
autoDownloadPurge = true;
|
||||
|
||||
repositories = List.of(MAVEN_CENTRAL, RIFE2_RELEASES);
|
||||
scope(test)
|
||||
.include(dependency("org.slf4j", "slf4j-simple", version(2,0,7)))
|
||||
.include(dependency("net.imagej", "ij", version("1.54d")))
|
||||
.include(dependency("org.junit.jupiter", "junit-jupiter", version(5,9,3)))
|
||||
.include(dependency("org.junit.platform", "junit-platform-console-standalone", version(1,9,3)))
|
||||
.include(dependency("com.h2database", "h2", version(2,1,214)))
|
||||
.include(dependency("net.sourceforge.htmlunit", "htmlunit", version(2,70,0)))
|
||||
.include(dependency("org.postgresql", "postgresql", version(42,6,0)))
|
||||
.include(dependency("com.mysql", "mysql-connector-j", version(8,0,33)))
|
||||
.include(dependency("org.mariadb.jdbc", "mariadb-java-client", version(3,1,4)))
|
||||
.include(dependency("org.hsqldb", "hsqldb", version(2,7,1)))
|
||||
.include(dependency("org.apache.derby", "derby", version("10.16.1.1")))
|
||||
.include(dependency("org.apache.derby", "derbytools", version("10.16.1.1")))
|
||||
.include(dependency("com.oracle.database.jdbc", "ojdbc11", version("23.2.0.0")))
|
||||
.include(dependency("org.json", "json", version(20230227)));
|
||||
|
||||
cleanOperation()
|
||||
.directories(
|
||||
new File(workDirectory(), "embedded_dbs"),
|
||||
new File(workDirectory(), "logs"));
|
||||
|
||||
var core_directory = new File(workDirectory(), "core");
|
||||
var core_src_directory = new File(core_directory, "src");
|
||||
var core_src_main_directory = new File(core_src_directory, "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
|
||||
.sourceDirectories(List.of(new File(core_src_main_directory, "antlr")))
|
||||
.outputDirectory(new File(buildDirectory(), "generated/rife/template/antlr"))
|
||||
.visitor()
|
||||
.longMessages();
|
||||
|
||||
precompileOperation()
|
||||
.sourceDirectories(core_src_main_resources_templates_directory)
|
||||
.templateTypes(HTML, XML, SQL, TXT, JSON);
|
||||
|
||||
compileOperation()
|
||||
.mainSourceDirectories(antlr4Operation.outputDirectory(), core_src_main_java_directory)
|
||||
.testSourceDirectories(core_src_test_java_directory)
|
||||
.compileOptions()
|
||||
.debuggingInfo(JavacOptions.DebuggingInfo.ALL);
|
||||
|
||||
jarOperation()
|
||||
.sourceDirectories(core_src_main_resources_directory)
|
||||
.excluded(Pattern.compile("^\\Q" + core_src_main_resources_templates_directory.getAbsolutePath() + "\\E.*"))
|
||||
.manifestAttribute(Attributes.Name.MAIN_CLASS, mainClass());
|
||||
|
||||
zipBldOperation
|
||||
.destinationDirectory(buildDistDirectory())
|
||||
.destinationFileName("rife2-" + version() + "-bld.zip");
|
||||
|
||||
testsBadgeOperation
|
||||
.classpath(core_src_main_resources_directory.getAbsolutePath())
|
||||
.classpath(core_src_test_resources_directory.getAbsolutePath());
|
||||
propagateJavaProperties(testsBadgeOperation.javaOptions(),
|
||||
"test.postgres",
|
||||
"test.mysql",
|
||||
"test.mariadb",
|
||||
"test.oracle",
|
||||
"test.oracle-free",
|
||||
"test.derby",
|
||||
"test.hsqldb",
|
||||
"test.h2");
|
||||
|
||||
javadocOperation()
|
||||
.excluded(
|
||||
"rife/antlr/",
|
||||
"rife/asm/",
|
||||
"rife/.*/databasedrivers/",
|
||||
"rife/.*/imagestoredrivers/",
|
||||
"rife/.*/rawstoredrivers/",
|
||||
"rife/.*/textstoredrivers/",
|
||||
"rife/database/capabilities/"
|
||||
)
|
||||
.javadocOptions()
|
||||
.docTitle("<a href=\"https://rife2.com/bld\">bld</a> " + version())
|
||||
.docLint(NO_MISSING)
|
||||
.keywords()
|
||||
.splitIndex()
|
||||
.tag("apiNote", "a", "API Note:")
|
||||
.link("https://jakarta.ee/specifications/servlet/5.0/apidocs/")
|
||||
.link("https://jsoup.org/apidocs/")
|
||||
.overview(new File(srcMainJavaDirectory(), "overview.html"));
|
||||
|
||||
publishOperation()
|
||||
.repository(version.isSnapshot() ? repository("rife2-snapshots") : repository("rife2-releases"))
|
||||
.repository(version.isSnapshot() ? repository("sonatype-snapshots") : repository("sonatype-releases"))
|
||||
.info(new PublishInfo()
|
||||
.groupId("com.uwyn.rife2")
|
||||
.artifactId("bld")
|
||||
.name("bld")
|
||||
.description("Pure java build tool for developers who don't like dealing with build tools.")
|
||||
.url("https://github.com/rife2/bld")
|
||||
.developer(new PublishDeveloper()
|
||||
.id("gbevin")
|
||||
.name("Geert Bevin")
|
||||
.email("gbevin@uwyn.com")
|
||||
.url("https://github.com/gbevin"))
|
||||
.license(new PublishLicense()
|
||||
.name("The Apache License, Version 2.0")
|
||||
.url("https://www.apache.org/licenses/LICENSE-2.0.txt"))
|
||||
.scm(new PublishScm()
|
||||
.connection("scm:git:https://github.com/rife2/bld.git")
|
||||
.developerConnection("scm:git:git@github.com:rife2/bld.git")
|
||||
.url("https://github.com/rife2/bld"))
|
||||
.signKey(property("sign.key"))
|
||||
.signPassphrase(property("sign.passphrase")))
|
||||
.artifacts(
|
||||
new PublishArtifact(zipBldOperation.destinationFile(), "bld", "zip"));
|
||||
}
|
||||
|
||||
void propagateJavaProperties(JavaOptions options, String... names) {
|
||||
for (var name : names) {
|
||||
if (properties().contains(name)) {
|
||||
options.property(name, properties().getValueString(name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final Antlr4Operation antlr4Operation = new Antlr4Operation() {
|
||||
@Override
|
||||
public void execute()
|
||||
throws Exception {
|
||||
super.execute();
|
||||
// replace the package name so that it becomes part of RIFE2
|
||||
FileUtils.transformFiles(outputDirectory(), FileUtils.JAVA_FILE_PATTERN, null, s ->
|
||||
StringUtils.replace(s, "org.antlr.v4.runtime", "rife.antlr.v4.runtime"));
|
||||
}
|
||||
};
|
||||
@BuildCommand(summary = "Generates the grammar Java sources")
|
||||
public void generateGrammar()
|
||||
throws Exception {
|
||||
antlr4Operation.executeOnce();
|
||||
}
|
||||
|
||||
public void compile()
|
||||
throws Exception {
|
||||
generateGrammar();
|
||||
super.compile();
|
||||
}
|
||||
|
||||
final ZipOperation zipBldOperation = new ZipOperation();
|
||||
@BuildCommand(value = "zip-bld", summary = "Creates the bld zip archive")
|
||||
public void zipBld()
|
||||
throws Exception {
|
||||
jar();
|
||||
var tmp = Files.createTempDirectory("bld").toFile();
|
||||
try {
|
||||
new Wrapper().createWrapperFiles(path(tmp, "lib").toFile(), VersionNumber.UNKNOWN.toString());
|
||||
new DirBuilder(tmp, t -> {
|
||||
t.dir("bld", b -> {
|
||||
b.dir("bin", i -> {
|
||||
i.file("bld", f -> {
|
||||
f.copy(path(srcMainDirectory(), "bld", "bld"));
|
||||
f.perms(0755);
|
||||
});
|
||||
i.file("bld.bat", f -> {
|
||||
f.copy(path(srcMainDirectory(), "bld", "bld.bat"));
|
||||
f.perms(0755);
|
||||
});
|
||||
});
|
||||
b.dir("lib", l -> {
|
||||
l.file("bld-wrapper.jar", f -> f.move(path(tmp, "lib", "bld-wrapper.jar")));
|
||||
});
|
||||
});
|
||||
t.dir("lib", l -> l.delete());
|
||||
});
|
||||
|
||||
zipBldOperation
|
||||
.sourceDirectories(tmp)
|
||||
.execute();
|
||||
} finally {
|
||||
FileUtils.deleteDirectory(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
private final TestsBadgeOperation testsBadgeOperation = new TestsBadgeOperation();
|
||||
public void test()
|
||||
throws Exception {
|
||||
testsBadgeOperation.executeOnce(() -> testsBadgeOperation
|
||||
.url(property("testsBadgeUrl"))
|
||||
.apiKey(property("testsBadgeApiKey"))
|
||||
.fromProject(this));
|
||||
}
|
||||
|
||||
@BuildCommand(summary = "Creates all the distribution artifacts")
|
||||
public void all()
|
||||
throws Exception {
|
||||
jar();
|
||||
jarSources();
|
||||
jarJavadoc();
|
||||
zipBld();
|
||||
}
|
||||
|
||||
public void publish()
|
||||
throws Exception {
|
||||
all();
|
||||
super.publish();
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
throws Exception {
|
||||
new BldBuild().start(args);
|
||||
}
|
||||
}
|
2
src/main/bld/bld
Executable file
2
src/main/bld/bld
Executable file
|
@ -0,0 +1,2 @@
|
|||
#!/usr/bin/env sh
|
||||
java -jar "$(dirname "$0")/../lib/bld-wrapper.jar" "$0" "$@"
|
4
src/main/bld/bld.bat
Normal file
4
src/main/bld/bld.bat
Normal file
|
@ -0,0 +1,4 @@
|
|||
@echo off
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
java -jar "%DIRNAME%/../lib/bld-wrapper.jar" "%0" %*
|
1608
src/main/java/rife/bld/BaseProject.java
Normal file
1608
src/main/java/rife/bld/BaseProject.java
Normal file
File diff suppressed because it is too large
Load diff
43
src/main/java/rife/bld/BldVersion.java
Normal file
43
src/main/java/rife/bld/BldVersion.java
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* 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.resources.ResourceFinderClasspath;
|
||||
import rife.resources.exceptions.ResourceFinderErrorException;
|
||||
|
||||
/**
|
||||
* Singleton class that provides access to the current RIFE2 version as a string.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.0
|
||||
*/
|
||||
public class BldVersion {
|
||||
private String version_;
|
||||
|
||||
BldVersion() {
|
||||
ResourceFinderClasspath resource_finder = ResourceFinderClasspath.instance();
|
||||
try {
|
||||
version_ = resource_finder.getContent("BLD_VERSION");
|
||||
} catch (ResourceFinderErrorException e) {
|
||||
version_ = null;
|
||||
}
|
||||
|
||||
if (version_ != null) {
|
||||
version_ = version_.trim();
|
||||
}
|
||||
if (null == version_) {
|
||||
version_ = "unknown version";
|
||||
}
|
||||
}
|
||||
|
||||
private String getVersionString() {
|
||||
return version_;
|
||||
}
|
||||
|
||||
public static String getVersion() {
|
||||
return BldVersionSingleton.INSTANCE.getVersionString();
|
||||
}
|
||||
}
|
||||
|
14
src/main/java/rife/bld/BldVersionSingleton.java
Normal file
14
src/main/java/rife/bld/BldVersionSingleton.java
Normal file
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||
*/
|
||||
package rife.bld;
|
||||
|
||||
/**
|
||||
* Helper class to avoid Double Check Locking
|
||||
* and still have a thread-safe singleton pattern
|
||||
*/
|
||||
class BldVersionSingleton {
|
||||
static final BldVersion INSTANCE = new BldVersion();
|
||||
}
|
||||
|
52
src/main/java/rife/bld/BuildCommand.java
Normal file
52
src/main/java/rife/bld/BuildCommand.java
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* 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 java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* Declares a {@link BuildExecutor} method to be used as a build command.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.METHOD})
|
||||
@Documented
|
||||
public @interface BuildCommand {
|
||||
/**
|
||||
* When provided, specifies a name for the build command that can be
|
||||
* different from the method name.
|
||||
*
|
||||
* @return a string representing the build command name
|
||||
* @since 1.5
|
||||
*/
|
||||
String value() default "";
|
||||
|
||||
/**
|
||||
* When provided, specifies a short description about the command.
|
||||
*
|
||||
* @return the short summary, defaults to {@code ""}
|
||||
* @since 1.5.12
|
||||
*/
|
||||
String summary() default "";
|
||||
|
||||
/**
|
||||
* When provided, specifies the full help description of a command.
|
||||
*
|
||||
* @return the full help description, defaults to {@code ""}
|
||||
* @since 1.5.12
|
||||
*/
|
||||
String description() default "";
|
||||
|
||||
/**
|
||||
* When provided, specifies a class that provides help about the
|
||||
* build command.
|
||||
*
|
||||
* @return a class providing help information
|
||||
* @since 1.5
|
||||
*/
|
||||
Class<? extends CommandHelp> help() default CommandHelp.class;
|
||||
}
|
467
src/main/java/rife/bld/BuildExecutor.java
Normal file
467
src/main/java/rife/bld/BuildExecutor.java
Normal file
|
@ -0,0 +1,467 @@
|
|||
/*
|
||||
* 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.DependencyResolver;
|
||||
import rife.bld.dependencies.Repository;
|
||||
import rife.bld.help.HelpHelp;
|
||||
import rife.bld.operations.HelpOperation;
|
||||
import rife.bld.operations.exceptions.ExitStatusException;
|
||||
import rife.ioc.HierarchicalProperties;
|
||||
import rife.tools.ExceptionUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Base class that executes build commands from a list of arguments.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @see BuildCommand
|
||||
* @see CommandDefinition
|
||||
* @since 1.5
|
||||
*/
|
||||
public class BuildExecutor {
|
||||
public static final File RIFE2_USER_DIR = new File(System.getProperty("user.home"), ".rife2");
|
||||
public static final String BLD_PROPERTIES = "bld.properties";
|
||||
public static final String LOCAL_PROPERTIES = "local.properties";
|
||||
|
||||
private static final String ARG_HELP1 = "--help";
|
||||
private static final String ARG_HELP2 = "-h";
|
||||
private static final String ARG_HELP3 = "-?";
|
||||
private static final String ARG_STACKTRACE1 = "--stacktrace";
|
||||
private static final String ARG_STACKTRACE2 = "-s";
|
||||
|
||||
private final HierarchicalProperties properties_;
|
||||
private List<String> arguments_ = Collections.emptyList();
|
||||
private Map<String, CommandDefinition> buildCommands_ = null;
|
||||
private final AtomicReference<String> currentCommandName_ = new AtomicReference<>();
|
||||
private final AtomicReference<CommandDefinition> currentCommandDefinition_ = new AtomicReference<>();
|
||||
private int exitStatus_ = 0;
|
||||
|
||||
/**
|
||||
* Show the full Java stacktrace when exceptions occur, as opposed
|
||||
* to the chain of messages.
|
||||
* <p>
|
||||
* Defaults to {@code false}, can be set to {@code true} by setting
|
||||
* through code or by adding {@code --stacktrace} as a CLI argument.
|
||||
*
|
||||
* @since 1.5.19
|
||||
*/
|
||||
protected boolean showStacktrace = false;
|
||||
|
||||
/**
|
||||
* Creates a new build executor instance.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public BuildExecutor() {
|
||||
properties_ = setupProperties(workDirectory());
|
||||
Repository.resolveMavenLocal(properties());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a properties hierarchy for bld execution.
|
||||
*
|
||||
* @param workDirectory the directory where the project build files are location
|
||||
* @return the properties hierarchy
|
||||
* @since 1.5.12
|
||||
*/
|
||||
public static HierarchicalProperties setupProperties(File workDirectory) {
|
||||
var system_properties = HierarchicalProperties.createSystemInstance();
|
||||
|
||||
var java_properties = system_properties;
|
||||
system_properties = java_properties.getParent();
|
||||
|
||||
HierarchicalProperties bld_properties = null;
|
||||
HierarchicalProperties local_properties = null;
|
||||
|
||||
var bld_properties_file = new File(RIFE2_USER_DIR, BLD_PROPERTIES);
|
||||
if (bld_properties_file.exists() && bld_properties_file.isFile() && bld_properties_file.canRead()) {
|
||||
try {
|
||||
var bld = new Properties();
|
||||
bld.load(new FileReader(bld_properties_file));
|
||||
bld_properties = new HierarchicalProperties();
|
||||
bld_properties.putAll(bld);
|
||||
|
||||
bld_properties.parent(system_properties);
|
||||
} catch (IOException e) {
|
||||
Logger.getLogger("rife.bld").warning("Unable to parse " + bld_properties_file + " as a properties file:\n" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
var local_properties_file = new File(workDirectory, LOCAL_PROPERTIES);
|
||||
if (local_properties_file.exists() && local_properties_file.isFile() && local_properties_file.canRead()) {
|
||||
try {
|
||||
var local = new Properties();
|
||||
local.load(new FileReader(local_properties_file));
|
||||
local_properties = new HierarchicalProperties();
|
||||
local_properties.putAll(local);
|
||||
|
||||
local_properties.parent(Objects.requireNonNullElse(bld_properties, system_properties));
|
||||
} catch (IOException e) {
|
||||
Logger.getLogger("rife.bld").warning("Unable to parse " + local_properties_file + " as a properties file:\n" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
java_properties.parent(
|
||||
Objects.requireNonNullElse(local_properties,
|
||||
Objects.requireNonNullElse(bld_properties, system_properties)));
|
||||
|
||||
final HierarchicalProperties properties = new HierarchicalProperties();
|
||||
properties.parent(java_properties);
|
||||
return properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the properties uses by this conversation.
|
||||
*
|
||||
* @return the instance of {@code HierarchicalProperties} that is used
|
||||
* by this build executor
|
||||
* @since 1.5
|
||||
*/
|
||||
public HierarchicalProperties properties() {
|
||||
return properties_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a property from the {@link #properties()}.
|
||||
*
|
||||
* @param name the name of the property
|
||||
* @return the requested property; or {@code null} if it doesn't exist
|
||||
* @since 1.5.15
|
||||
*/
|
||||
public String property(String name) {
|
||||
return properties().getValueString(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a property from the {@link #properties()} with a default value.
|
||||
*
|
||||
* @param name the name of the property
|
||||
* @param defaultValue the value that should be used as a fallback
|
||||
* @return the requested property; or the default value if it doesn't exist
|
||||
* @since 1.5.15
|
||||
*/
|
||||
public String property(String name, String defaultValue) {
|
||||
return properties().getValueString(name, defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for the existence of a property in {@link #properties()}.
|
||||
*
|
||||
* @param name the name of the property
|
||||
* @return {@code true} if the property exists; or {@code false} otherwise
|
||||
* @since 1.5.15
|
||||
*/
|
||||
public boolean hasProperty(String name) {
|
||||
return properties().contains(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the work directory of the project.
|
||||
* Defaults to this process's user working directory, which when running
|
||||
* through the bld wrapper corresponds to the top-level project directory.
|
||||
*
|
||||
* @since 1.5.12
|
||||
*/
|
||||
public File workDirectory() {
|
||||
return new File(System.getProperty("user.dir"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the exist status to use at the end of the execution.
|
||||
*
|
||||
* @param status sets the exit status
|
||||
* @since 1.5.1
|
||||
*/
|
||||
public void exitStatus(int status) {
|
||||
exitStatus_ = status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the exit status.
|
||||
*
|
||||
* @return the exit status
|
||||
* @since 1.5.1
|
||||
*/
|
||||
public int exitStatus() {
|
||||
return exitStatus_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the build commands from the provided arguments.
|
||||
* <p>
|
||||
* While the build is executing, the arguments can be retrieved
|
||||
* using {@link #arguments()}.
|
||||
*
|
||||
* @param arguments the arguments to execute the build with
|
||||
* @return the exist status
|
||||
* @since 1.5.1
|
||||
*/
|
||||
public int execute(String[] arguments) {
|
||||
arguments_ = new ArrayList<>(Arrays.asList(arguments));
|
||||
|
||||
var show_help = false;
|
||||
show_help |= arguments_.removeAll(List.of(ARG_HELP1, ARG_HELP2, ARG_HELP3));
|
||||
showStacktrace |= arguments_.removeAll(List.of(ARG_STACKTRACE1, ARG_STACKTRACE2));
|
||||
show_help |= arguments_.isEmpty();
|
||||
|
||||
if (show_help) {
|
||||
new HelpOperation(this, Collections.emptyList()).execute();
|
||||
return exitStatus_;
|
||||
}
|
||||
|
||||
while (!arguments_.isEmpty()) {
|
||||
var command = arguments_.remove(0);
|
||||
|
||||
try {
|
||||
if (!executeCommand(command)) {
|
||||
break;
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
exitStatus(1);
|
||||
|
||||
System.err.println();
|
||||
|
||||
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_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the execution of the build. This method will call
|
||||
* System.exit() when done with the appropriate exit status.
|
||||
*
|
||||
* @param arguments the arguments to execute the build with
|
||||
* @see #execute
|
||||
* @since 1.5.1
|
||||
*/
|
||||
public void start(String[] arguments) {
|
||||
System.exit(execute(arguments));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the list of arguments that are being processed.
|
||||
*
|
||||
* @return the list of arguments
|
||||
* @since 1.5
|
||||
*/
|
||||
public List<String> arguments() {
|
||||
return arguments_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the commands that can be executed by this {@code BuildExecutor}.
|
||||
*
|
||||
* @return a map containing the name of the build command and the method that
|
||||
* corresponds to execution
|
||||
* @see BuildCommand
|
||||
* @since 1.5
|
||||
*/
|
||||
public Map<String, CommandDefinition> buildCommands() {
|
||||
if (buildCommands_ == null) {
|
||||
var build_commands = new TreeMap<String, CommandDefinition>();
|
||||
|
||||
Class<?> klass = getClass();
|
||||
|
||||
try {
|
||||
while (klass != null) {
|
||||
for (var method : klass.getDeclaredMethods()) {
|
||||
if (method.getParameters().length == 0 && method.isAnnotationPresent(BuildCommand.class)) {
|
||||
method.setAccessible(true);
|
||||
|
||||
var name = method.getName();
|
||||
var annotation = method.getAnnotation(BuildCommand.class);
|
||||
|
||||
var annotation_name = annotation.value();
|
||||
if (annotation_name != null && !annotation_name.isEmpty()) {
|
||||
name = annotation_name;
|
||||
}
|
||||
|
||||
if (!build_commands.containsKey(name)) {
|
||||
var build_help = annotation.help();
|
||||
CommandHelp command_help = null;
|
||||
if (build_help != null && build_help != CommandHelp.class) {
|
||||
command_help = build_help.getDeclaredConstructor().newInstance();
|
||||
}
|
||||
|
||||
var summary = annotation.summary();
|
||||
var description = annotation.description();
|
||||
if ((summary != null && !summary.isBlank()) ||
|
||||
(description != null && !description.isBlank())) {
|
||||
if (summary == null) summary = "";
|
||||
if (description == null) description = "";
|
||||
if (command_help != null) {
|
||||
if (summary.isBlank()) summary = command_help.getSummary();
|
||||
if (description.isBlank()) description = command_help.getDescription(name);
|
||||
}
|
||||
command_help = new AnnotatedCommandHelp(summary, description);
|
||||
}
|
||||
|
||||
build_commands.put(name, new CommandAnnotated(this, method, command_help));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
klass = klass.getSuperclass();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
buildCommands_ = build_commands;
|
||||
}
|
||||
|
||||
return buildCommands_;
|
||||
}
|
||||
|
||||
private static class AnnotatedCommandHelp implements CommandHelp {
|
||||
private final String summary_;
|
||||
private final String description_;
|
||||
|
||||
AnnotatedCommandHelp(String summary, String description) {
|
||||
summary_ = summary;
|
||||
description_ = description;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSummary() {
|
||||
return summary_;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription(String topic) {
|
||||
return description_;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the execution of a single command.
|
||||
*
|
||||
* @param command the name of the command to execute
|
||||
* @return {@code true} when the command was found and executed; or
|
||||
* {@code false} if the command couldn't be found
|
||||
* @throws Throwable when an exception occurred during the command execution
|
||||
* @see BuildCommand
|
||||
* @since 1.5
|
||||
*/
|
||||
public boolean executeCommand(String command)
|
||||
throws Throwable {
|
||||
var matched_command = command;
|
||||
var definition = buildCommands().get(command);
|
||||
|
||||
// try to find a match for the provided command amongst
|
||||
// the ones that are known
|
||||
if (definition == null) {
|
||||
// try to find starting matching options
|
||||
var matches = new ArrayList<>(buildCommands().keySet().stream()
|
||||
.filter(c -> c.toLowerCase().startsWith(command.toLowerCase()))
|
||||
.toList());
|
||||
|
||||
if (matches.isEmpty()) {
|
||||
// try to find fuzzy matching options
|
||||
var fuzzy_regexp = new StringBuilder("^.*");
|
||||
for (var ch : command.toCharArray()) {
|
||||
fuzzy_regexp.append("\\Q");
|
||||
fuzzy_regexp.append(ch);
|
||||
fuzzy_regexp.append("\\E.*");
|
||||
}
|
||||
fuzzy_regexp.append("$");
|
||||
var fuzzy_pattern = Pattern.compile(fuzzy_regexp.toString());
|
||||
matches.addAll(buildCommands().keySet().stream()
|
||||
.filter(c -> fuzzy_pattern.matcher(c.toLowerCase()).matches())
|
||||
.toList());
|
||||
}
|
||||
|
||||
// only proceed if exactly one match was found
|
||||
if (matches.size() == 1) {
|
||||
matched_command = matches.get(0);
|
||||
System.out.println("Executing matched command: " + matched_command);
|
||||
definition = buildCommands().get(matched_command);
|
||||
}
|
||||
}
|
||||
|
||||
// execute the command if we found one
|
||||
if (definition != null) {
|
||||
try {
|
||||
currentCommandName_.set(matched_command);
|
||||
currentCommandDefinition_.set(definition);
|
||||
definition.execute();
|
||||
} catch (ExitStatusException e) {
|
||||
exitStatus(e.getExitStatus());
|
||||
return e.getExitStatus() == ExitStatusException.EXIT_SUCCESS;
|
||||
} finally {
|
||||
currentCommandDefinition_.set(null);
|
||||
currentCommandName_.set(null);
|
||||
}
|
||||
} else {
|
||||
new HelpOperation(this, arguments()).executePrintOverviewHelp();
|
||||
System.err.println();
|
||||
System.err.println("ERROR: unknown command '" + command + "'");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the name of the currently executing command.
|
||||
*
|
||||
* @return the name of the current command; or
|
||||
* {@code null} if no command is currently executing
|
||||
* @since 1.5.12
|
||||
*/
|
||||
public String getCurrentCommandName() {
|
||||
return currentCommandName_.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the definition of the currently executing command.
|
||||
*
|
||||
* @return the definition of the current command; or
|
||||
* {@code null} if no command is currently executing
|
||||
* @since 1.5.12
|
||||
*/
|
||||
public CommandDefinition getCurrentCommandDefinition() {
|
||||
return currentCommandDefinition_.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* The standard {@code help} command.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
@BuildCommand(help = HelpHelp.class)
|
||||
public void help() {
|
||||
new HelpOperation(this, arguments()).execute();
|
||||
}
|
||||
}
|
100
src/main/java/rife/bld/Cli.java
Normal file
100
src/main/java/rife/bld/Cli.java
Normal file
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* 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.help.*;
|
||||
import rife.bld.operations.*;
|
||||
|
||||
/**
|
||||
* Implements the RIFE2 CLI build executor that is available when running
|
||||
* the RIFE2 jar as an executable jar.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5
|
||||
*/
|
||||
public class Cli extends BuildExecutor {
|
||||
private final CreateBaseOperation createBaseOperation_ = new CreateBaseOperation();
|
||||
private final CreateBlankOperation createBlankOperation_ = new CreateBlankOperation();
|
||||
private final CreateLibOperation createLibOperation_ = new CreateLibOperation();
|
||||
private final CreateRife2Operation createRife2Operation_ = new CreateRife2Operation();
|
||||
private final UpgradeOperation upgradeOperation_ = new UpgradeOperation();
|
||||
private final VersionOperation versionOperation_ = new VersionOperation();
|
||||
|
||||
/**
|
||||
* The standard {@code create} command.
|
||||
*
|
||||
* @throws Exception when an error occurred during the creation process
|
||||
* @since 1.5
|
||||
*/
|
||||
@BuildCommand(help = CreateRife2Help.class)
|
||||
public void create()
|
||||
throws Exception {
|
||||
createRife2Operation_.executeOnce(() -> createRife2Operation_.fromArguments(arguments()));
|
||||
}
|
||||
|
||||
/**
|
||||
* The standard {@code create-blank} command.
|
||||
*
|
||||
* @throws Exception when an error occurred during the creation process
|
||||
* @since 1.5
|
||||
*/
|
||||
@BuildCommand(value = "create-blank", help = CreateBlankHelp.class)
|
||||
public void createBlank()
|
||||
throws Exception {
|
||||
createBlankOperation_.executeOnce(() -> createBlankOperation_.fromArguments(arguments()));
|
||||
}
|
||||
|
||||
/**
|
||||
* The standard {@code create-base} command.
|
||||
*
|
||||
* @throws Exception when an error occurred during the creation process
|
||||
* @since 1.5.20
|
||||
*/
|
||||
@BuildCommand(value = "create-base", help = CreateBaseHelp.class)
|
||||
public void createBase()
|
||||
throws Exception {
|
||||
createBaseOperation_.executeOnce(() -> createBaseOperation_.fromArguments(arguments()));
|
||||
}
|
||||
|
||||
/**
|
||||
* The standard {@code create-lib} command.
|
||||
*
|
||||
* @throws Exception when an error occurred during the creation process
|
||||
* @since 1.6
|
||||
*/
|
||||
@BuildCommand(value = "create-lib", help = CreateLibHelp.class)
|
||||
public void createLib()
|
||||
throws Exception {
|
||||
createLibOperation_.executeOnce(() -> createLibOperation_.fromArguments(arguments()));
|
||||
}
|
||||
|
||||
/**
|
||||
* The standard {@code upgrade} command.
|
||||
*
|
||||
* @throws Exception when an error occurred during the upgrade process
|
||||
* @since 1.5
|
||||
*/
|
||||
@BuildCommand(help = UpgradeHelp.class)
|
||||
public void upgrade()
|
||||
throws Exception {
|
||||
upgradeOperation_.executeOnce();
|
||||
}
|
||||
|
||||
/**
|
||||
* The standard {@code version} command.
|
||||
*
|
||||
* @since 1.5.2
|
||||
*/
|
||||
@BuildCommand(help = VersionHelp.class)
|
||||
public void version()
|
||||
throws Exception {
|
||||
versionOperation_.executeOnce();
|
||||
}
|
||||
|
||||
public static void main(String[] arguments)
|
||||
throws Exception {
|
||||
new Cli().start(arguments);
|
||||
}
|
||||
}
|
36
src/main/java/rife/bld/CommandAnnotated.java
Normal file
36
src/main/java/rife/bld/CommandAnnotated.java
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* 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 java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
class CommandAnnotated implements CommandDefinition {
|
||||
private final BuildExecutor executor_;
|
||||
private final Method method_;
|
||||
private final CommandHelp help_;
|
||||
|
||||
CommandAnnotated(BuildExecutor executor, Method method, CommandHelp help) {
|
||||
executor_ = executor;
|
||||
method_ = method;
|
||||
if (help == null) {
|
||||
help = new CommandHelp() {};
|
||||
}
|
||||
help_ = help;
|
||||
}
|
||||
|
||||
public void execute()
|
||||
throws Throwable {
|
||||
try {
|
||||
method_.invoke(executor_);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw e.getCause();
|
||||
}
|
||||
}
|
||||
|
||||
public CommandHelp getHelp() {
|
||||
return help_;
|
||||
}
|
||||
}
|
33
src/main/java/rife/bld/CommandDefinition.java
Normal file
33
src/main/java/rife/bld/CommandDefinition.java
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||
*/
|
||||
package rife.bld;
|
||||
|
||||
/**
|
||||
* Defines the logic for a build command.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5
|
||||
*/
|
||||
public interface CommandDefinition {
|
||||
/**
|
||||
* Called when a build command is executed.
|
||||
*
|
||||
* @throws Throwable when an error occurred during the execution of the build command
|
||||
* @since 1.5
|
||||
*/
|
||||
void execute() throws Throwable;
|
||||
|
||||
/**
|
||||
* Retrieves the help information of a build command.
|
||||
* <p>
|
||||
* Defaults to blank help sections.
|
||||
*
|
||||
* @return this build command's help information
|
||||
* @since 1.5
|
||||
*/
|
||||
default CommandHelp getHelp() {
|
||||
return new CommandHelp() {};
|
||||
}
|
||||
}
|
33
src/main/java/rife/bld/CommandHelp.java
Normal file
33
src/main/java/rife/bld/CommandHelp.java
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||
*/
|
||||
package rife.bld;
|
||||
|
||||
/**
|
||||
* Interface that provides help texts to display about {@link BuildExecutor} commands.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5
|
||||
*/
|
||||
public interface CommandHelp {
|
||||
/**
|
||||
* Returns a short description about the command.
|
||||
*
|
||||
* @return the short summary, defaults to {@code ""}
|
||||
* @since 1.5
|
||||
*/
|
||||
default String getSummary() {
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the full help description of a command.
|
||||
*
|
||||
* @return the full help description, defaults to {@code ""}
|
||||
* @since 1.5
|
||||
*/
|
||||
default String getDescription(String topic) {
|
||||
return "";
|
||||
}
|
||||
}
|
19
src/main/java/rife/bld/NamedFile.java
Normal file
19
src/main/java/rife/bld/NamedFile.java
Normal file
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* 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 java.io.File;
|
||||
|
||||
/**
|
||||
* Combines the information of a filesystem file with the name it's intended
|
||||
* to have.
|
||||
*
|
||||
* @param name the intended name of the file
|
||||
* @param file the location on the filesystem
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5
|
||||
*/
|
||||
public record NamedFile(String name, File file) {
|
||||
}
|
195
src/main/java/rife/bld/Project.java
Normal file
195
src/main/java/rife/bld/Project.java
Normal file
|
@ -0,0 +1,195 @@
|
|||
/*
|
||||
* 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.help.*;
|
||||
import rife.bld.operations.*;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.jar.Attributes;
|
||||
|
||||
/**
|
||||
* Provides the configuration and commands of a Java project for the
|
||||
* build system with all standard commands ready to go.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5
|
||||
*/
|
||||
public class Project extends BaseProject {
|
||||
/*
|
||||
* Standard build commands
|
||||
*/
|
||||
|
||||
private final JavadocOperation javadocOperation_ = new JavadocOperation();
|
||||
private final PrecompileOperation precompileOperation_ = new PrecompileOperation();
|
||||
private final JarOperation jarOperation_ = new JarOperation();
|
||||
private final JarOperation jarSourcesOperation_ = new JarOperation();
|
||||
private final JarOperation jarJavadocOperation_ = new JarOperation();
|
||||
private final JUnitOperation junitTestOperation_ = new JUnitOperation();
|
||||
private final UberJarOperation uberJarOperation_ = new UberJarOperation();
|
||||
|
||||
@Override
|
||||
public JUnitOperation testOperation() {
|
||||
return junitTestOperation_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the project's default javadoc operation.
|
||||
*
|
||||
* @return the default javadoc operation instance
|
||||
* @since 1.5.18
|
||||
*/
|
||||
public JavadocOperation javadocOperation() {
|
||||
return javadocOperation_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the project's default precompile operation.
|
||||
*
|
||||
* @return the default precompile operation instance
|
||||
* @since 1.5.18
|
||||
*/
|
||||
public PrecompileOperation precompileOperation() {
|
||||
return precompileOperation_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the project's default jar operation.
|
||||
*
|
||||
* @return the default jar operation instance
|
||||
* @since 1.5.18
|
||||
*/
|
||||
public JarOperation jarOperation() {
|
||||
return jarOperation_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the project's default jar operation for sources.
|
||||
*
|
||||
* @return the default jar operation instance for sources
|
||||
* @since 1.5.18
|
||||
*/
|
||||
public JarOperation jarSourcesOperation() {
|
||||
return jarSourcesOperation_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the project's default jar operation for javadoc.
|
||||
*
|
||||
* @return the default jar operation instance for javadoc
|
||||
* @since 1.5.18
|
||||
*/
|
||||
public JarOperation jarJavadocOperation() {
|
||||
return jarJavadocOperation_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the project's default uberjar operation.
|
||||
*
|
||||
* @return the default uberjar operation instance
|
||||
* @since 1.5.18
|
||||
*/
|
||||
public UberJarOperation uberJarOperation() {
|
||||
return uberJarOperation_;
|
||||
}
|
||||
|
||||
@BuildCommand(help = JUnitHelp.class)
|
||||
@Override
|
||||
public void test()
|
||||
throws Exception {
|
||||
super.test();
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard build command, generates javadoc.
|
||||
*
|
||||
* @since 1.5.10
|
||||
*/
|
||||
@BuildCommand(help = JavadocHelp.class)
|
||||
public void javadoc()
|
||||
throws Exception {
|
||||
javadocOperation().executeOnce(() -> javadocOperation().fromProject(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard build command, pre-compiles RIFE2 templates to class files.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
@BuildCommand(help = PrecompileHelp.class)
|
||||
public void precompile()
|
||||
throws Exception {
|
||||
precompileOperation().executeOnce(() -> precompileOperation().fromProject(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard build command, creates a jar archive for the project.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
@BuildCommand(help = JarHelp.class)
|
||||
public void jar()
|
||||
throws Exception {
|
||||
compile();
|
||||
precompile();
|
||||
jarOperation().executeOnce(() -> jarOperation().fromProject(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard build command, creates a sources jar archive for the project.
|
||||
*
|
||||
* @since 1.5.10
|
||||
*/
|
||||
@BuildCommand(value = "jar-sources", help = JarSourcesHelp.class)
|
||||
public void jarSources()
|
||||
throws Exception {
|
||||
jarSourcesOperation().executeOnce(() -> jarSourcesOperation()
|
||||
.manifestAttributes(Map.of(Attributes.Name.MANIFEST_VERSION, "1.0"))
|
||||
.sourceDirectories(List.of(srcMainJavaDirectory()))
|
||||
.destinationDirectory(buildDistDirectory())
|
||||
.destinationFileName(sourcesJarFileName()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard build command, creates a javadoc jar archive for the project.
|
||||
*
|
||||
* @since 1.5.10
|
||||
*/
|
||||
@BuildCommand(value = "jar-javadoc", help = JarJavadocHelp.class)
|
||||
public void jarJavadoc()
|
||||
throws Exception {
|
||||
compile();
|
||||
javadoc();
|
||||
jarJavadocOperation().executeOnce(() -> jarJavadocOperation().manifestAttributes(Map.of(Attributes.Name.MANIFEST_VERSION, "1.0"))
|
||||
.sourceDirectories(List.of(buildJavadocDirectory()))
|
||||
.destinationDirectory(buildDistDirectory())
|
||||
.destinationFileName(javadocJarFileName()));
|
||||
}
|
||||
/**
|
||||
* Standard build command, creates an UberJar archive for the project.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
@BuildCommand(help = UberJarHelp.class)
|
||||
public void uberjar()
|
||||
throws Exception {
|
||||
jar();
|
||||
uberJarOperation().executeOnce(() -> uberJarOperation().fromProject(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard publish command, uploads artifacts to the publication repository.
|
||||
*
|
||||
* @since 1.5.7
|
||||
*/
|
||||
@BuildCommand(help = PublishHelp.class)
|
||||
public void publish()
|
||||
throws Exception {
|
||||
jar();
|
||||
jarSources();
|
||||
jarJavadoc();
|
||||
publishOperation().executeOnce(() -> publishOperation().fromProject(this));
|
||||
}
|
||||
}
|
134
src/main/java/rife/bld/WebProject.java
Normal file
134
src/main/java/rife/bld/WebProject.java
Normal file
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
* 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.help.*;
|
||||
import rife.bld.operations.*;
|
||||
import rife.bld.publish.PublishArtifact;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Provides the configuration and commands of a Java web project for the
|
||||
* build system.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5
|
||||
*/
|
||||
public class WebProject extends Project {
|
||||
/**
|
||||
* The main war archive creation.
|
||||
*
|
||||
* @see #warFileName()
|
||||
* @since 1.5.0
|
||||
*/
|
||||
protected String warFileName = null;
|
||||
/**
|
||||
* The main webapp directory.
|
||||
*
|
||||
* @see #srcMainWebappDirectory()
|
||||
* @since 1.5
|
||||
*/
|
||||
protected File srcMainWebappDirectory = null;
|
||||
|
||||
/*
|
||||
* Standard build commands
|
||||
*/
|
||||
|
||||
private final WarOperation warOperation_ = new WarOperation();
|
||||
|
||||
/**
|
||||
* Retrieves the project's default war operation.
|
||||
*
|
||||
* @return the default war operation instance
|
||||
* @since 1.5.18
|
||||
*/
|
||||
protected WarOperation warOperation() {
|
||||
return warOperation_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard build command, creates an UberJar archive for the web project.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
@Override
|
||||
public void uberjar()
|
||||
throws Exception {
|
||||
jar();
|
||||
uberJarOperation().executeOnce(() -> {
|
||||
uberJarOperation().fromProject(this);
|
||||
uberJarOperation().sourceDirectories(List.of(new NamedFile("webapp", srcMainWebappDirectory())));
|
||||
uberJarOperation().jarSourceFiles().addAll(standaloneClasspathJars());
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard build command, creates a war archive for the web project.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
@BuildCommand(help = WarHelp.class)
|
||||
public void war()
|
||||
throws Exception {
|
||||
jar();
|
||||
warOperation().executeOnce(() -> warOperation().fromProject(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard publish-web command, uploads artifacts to the publication repository.
|
||||
*
|
||||
* @since 1.5.7
|
||||
*/
|
||||
@BuildCommand(help = PublishWebHelp.class)
|
||||
public void publish()
|
||||
throws Exception {
|
||||
jar();
|
||||
jarSources();
|
||||
jarJavadoc();
|
||||
uberjar();
|
||||
war();
|
||||
publishOperation().executeOnce(() -> {
|
||||
publishOperation().fromProject(this);
|
||||
publishOperation().artifacts().add(new PublishArtifact(new File(buildDistDirectory(), uberJarFileName()), "uber", "jar"));
|
||||
publishOperation().artifacts().add(new PublishArtifact(new File(buildDistDirectory(), warFileName()), "", "war"));
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* Project directories
|
||||
*/
|
||||
|
||||
@Override
|
||||
public File libStandaloneDirectory() {
|
||||
return Objects.requireNonNullElseGet(libStandaloneDirectory, () -> new File(libDirectory(), "standalone"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the project main webapp directory.
|
||||
* Defaults to {@code "webapp"} relative to {@link #srcMainDirectory()}.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public File srcMainWebappDirectory() {
|
||||
return Objects.requireNonNullElseGet(srcMainWebappDirectory, () -> new File(srcMainDirectory(), "webapp"));
|
||||
}
|
||||
|
||||
/*
|
||||
* Project options
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns filename to use for the main war archive creation.
|
||||
* By default, appends the version and the {@code war} extension to the {@link #archiveBaseName()}.
|
||||
*
|
||||
* @since 1.5.0
|
||||
*/
|
||||
public String warFileName() {
|
||||
return Objects.requireNonNullElseGet(warFileName, () -> archiveBaseName() + "-" + version() + ".war");
|
||||
}
|
||||
}
|
40
src/main/java/rife/bld/blueprints/BaseProjectBlueprint.java
Normal file
40
src/main/java/rife/bld/blueprints/BaseProjectBlueprint.java
Normal file
|
@ -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.blueprints;
|
||||
|
||||
import rife.bld.Project;
|
||||
import rife.bld.dependencies.VersionNumber;
|
||||
import rife.tools.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
import static rife.bld.dependencies.Repository.MAVEN_CENTRAL;
|
||||
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.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5.20
|
||||
*/
|
||||
public class BaseProjectBlueprint extends Project {
|
||||
public BaseProjectBlueprint(File work, String packageName, String projectName) {
|
||||
this(work, packageName, projectName, new VersionNumber(0,0,1));
|
||||
}
|
||||
|
||||
public BaseProjectBlueprint(File work, String packageName, String projectName, VersionNumber versionNumber) {
|
||||
workDirectory = work;
|
||||
|
||||
pkg = packageName;
|
||||
name = projectName;
|
||||
mainClass = packageName + "." + StringUtils.capitalize(projectName) + "Main";
|
||||
version = versionNumber;
|
||||
|
||||
downloadSources = true;
|
||||
repositories = List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS);
|
||||
}
|
||||
}
|
43
src/main/java/rife/bld/blueprints/BlankProjectBlueprint.java
Normal file
43
src/main/java/rife/bld/blueprints/BlankProjectBlueprint.java
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||
*/
|
||||
package rife.bld.blueprints;
|
||||
|
||||
import rife.bld.Project;
|
||||
import rife.bld.dependencies.VersionNumber;
|
||||
import rife.tools.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
import static rife.bld.dependencies.Repository.MAVEN_CENTRAL;
|
||||
import static rife.bld.dependencies.Repository.SONATYPE_SNAPSHOTS;
|
||||
import static rife.bld.dependencies.Scope.test;
|
||||
|
||||
/**
|
||||
* Provides the dependency information required to create a new blank project.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5
|
||||
*/
|
||||
public class BlankProjectBlueprint extends Project {
|
||||
public BlankProjectBlueprint(File work, String packageName, String projectName) {
|
||||
this(work, packageName, projectName, new VersionNumber(0,0,1));
|
||||
}
|
||||
|
||||
public BlankProjectBlueprint(File work, String packageName, String projectName, VersionNumber versionNumber) {
|
||||
workDirectory = work;
|
||||
|
||||
pkg = packageName;
|
||||
name = projectName;
|
||||
mainClass = packageName + "." + StringUtils.capitalize(projectName) + "Main";
|
||||
version = versionNumber;
|
||||
|
||||
downloadSources = true;
|
||||
repositories = List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS);
|
||||
scope(test)
|
||||
.include(dependency("org.junit.jupiter", "junit-jupiter", version(5,9,3)))
|
||||
.include(dependency("org.junit.platform", "junit-platform-console-standalone", version(1,9,3)));
|
||||
}
|
||||
}
|
39
src/main/java/rife/bld/blueprints/LibProjectBlueprint.java
Normal file
39
src/main/java/rife/bld/blueprints/LibProjectBlueprint.java
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||
*/
|
||||
package rife.bld.blueprints;
|
||||
|
||||
import rife.bld.Project;
|
||||
import rife.bld.dependencies.VersionNumber;
|
||||
import rife.tools.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
import static rife.bld.dependencies.Repository.MAVEN_CENTRAL;
|
||||
import static rife.bld.dependencies.Repository.SONATYPE_SNAPSHOTS;
|
||||
|
||||
/**
|
||||
* Provides the dependency information required to create a new lib project.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.6
|
||||
*/
|
||||
public class LibProjectBlueprint extends Project {
|
||||
public LibProjectBlueprint(File work, String packageName, String projectName) {
|
||||
this(work, packageName, projectName, new VersionNumber(0,0,1));
|
||||
}
|
||||
|
||||
public LibProjectBlueprint(File work, String packageName, String projectName, VersionNumber versionNumber) {
|
||||
workDirectory = work;
|
||||
|
||||
pkg = packageName;
|
||||
name = projectName;
|
||||
mainClass = packageName + "." + StringUtils.capitalize(projectName) + "Lib";
|
||||
version = versionNumber;
|
||||
|
||||
downloadSources = true;
|
||||
repositories = List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS);
|
||||
}
|
||||
}
|
53
src/main/java/rife/bld/blueprints/Rife2ProjectBlueprint.java
Normal file
53
src/main/java/rife/bld/blueprints/Rife2ProjectBlueprint.java
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||
*/
|
||||
package rife.bld.blueprints;
|
||||
|
||||
import rife.bld.WebProject;
|
||||
import rife.bld.dependencies.VersionNumber;
|
||||
import rife.bld.operations.TemplateType;
|
||||
import rife.tools.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
import static rife.bld.dependencies.Repository.MAVEN_CENTRAL;
|
||||
import static rife.bld.dependencies.Repository.SONATYPE_SNAPSHOTS;
|
||||
import static rife.bld.dependencies.Scope.*;
|
||||
|
||||
/**
|
||||
* Provides the dependency information required to create a new RIFE2 project.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5
|
||||
*/
|
||||
public class Rife2ProjectBlueprint extends WebProject {
|
||||
public Rife2ProjectBlueprint(File work, String packageName, String projectName) {
|
||||
this(work, packageName, projectName, new VersionNumber(0,0,1));
|
||||
}
|
||||
|
||||
public Rife2ProjectBlueprint(File work, String packageName, String projectName, VersionNumber versionNumber) {
|
||||
workDirectory = work;
|
||||
|
||||
pkg = packageName;
|
||||
name = projectName;
|
||||
mainClass = packageName + "." + StringUtils.capitalize(projectName) + "Site";
|
||||
version = versionNumber;
|
||||
|
||||
downloadSources = true;
|
||||
repositories = List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS);
|
||||
scope(compile)
|
||||
.include(dependency("com.uwyn.rife2", "rife2", version(1,6,3)));
|
||||
scope(test)
|
||||
.include(dependency("org.jsoup", "jsoup", version(1,16,1)))
|
||||
.include(dependency("org.junit.jupiter", "junit-jupiter", version(5,9,3)))
|
||||
.include(dependency("org.junit.platform", "junit-platform-console-standalone", version(1,9,3)));
|
||||
scope(standalone)
|
||||
.include(dependency("org.eclipse.jetty", "jetty-server", version(11,0,15)))
|
||||
.include(dependency("org.eclipse.jetty", "jetty-servlet", version(11,0,15)))
|
||||
.include(dependency("org.slf4j", "slf4j-simple", version(2,0,7)));
|
||||
|
||||
precompileOperation().templateTypes(TemplateType.HTML);
|
||||
}
|
||||
}
|
10
src/main/java/rife/bld/blueprints/package-info.java
Normal file
10
src/main/java/rife/bld/blueprints/package-info.java
Normal file
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||
*/
|
||||
|
||||
/**
|
||||
* Provides blueprints for project creation.
|
||||
* @since 1.5
|
||||
*/
|
||||
package rife.bld.blueprints;
|
202
src/main/java/rife/bld/dependencies/ArtifactRetriever.java
Normal file
202
src/main/java/rife/bld/dependencies/ArtifactRetriever.java
Normal file
|
@ -0,0 +1,202 @@
|
|||
/*
|
||||
* 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 rife.tools.FileUtils;
|
||||
import rife.tools.exceptions.FileUtilsErrorException;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.nio.channels.Channels;
|
||||
import java.security.MessageDigest;
|
||||
import java.util.*;
|
||||
|
||||
import static rife.tools.HttpUtils.HEADER_AUTHORIZATION;
|
||||
import static rife.tools.HttpUtils.basicAuthorizationHeader;
|
||||
import static rife.tools.StringUtils.encodeHexLower;
|
||||
|
||||
/**
|
||||
* Retrieves artifact data.
|
||||
* <p>
|
||||
* To instantiate, use either {@link #instance()} for direct retrieval of
|
||||
* each request, or {@link #cachingInstance()} where previous retrievals
|
||||
* of remote string content will be cached for faster future retrieval.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5.18
|
||||
*/
|
||||
public abstract class ArtifactRetriever {
|
||||
private final static ArtifactRetriever UNCACHED = new ArtifactRetriever() {
|
||||
String getCached(RepositoryArtifact artifact) {
|
||||
return null;
|
||||
}
|
||||
|
||||
void cache(RepositoryArtifact artifact, String content) {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets an artifact retriever that does direct retrieval of each request.
|
||||
*
|
||||
* @return the direct retrieval instance
|
||||
* @since 1.5.18
|
||||
*/
|
||||
public static ArtifactRetriever instance() {
|
||||
return UNCACHED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a caching artifact retriever where previous retrievals
|
||||
* of remote string content will be cached for faster future retrieval.
|
||||
*
|
||||
* @return a caching instance
|
||||
* @since 1.5.18
|
||||
*/
|
||||
public static ArtifactRetriever cachingInstance() {
|
||||
return new ArtifactRetriever() {
|
||||
private final Map<RepositoryArtifact, String> artifactCache = new HashMap<>();
|
||||
|
||||
String getCached(RepositoryArtifact artifact) {
|
||||
return artifactCache.get(artifact);
|
||||
}
|
||||
|
||||
void cache(RepositoryArtifact artifact, String content) {
|
||||
artifactCache.put(artifact, content);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
private ArtifactRetriever() {
|
||||
}
|
||||
|
||||
abstract String getCached(RepositoryArtifact artifact);
|
||||
|
||||
abstract void cache(RepositoryArtifact artifact, String content);
|
||||
|
||||
/**
|
||||
* Reads the contents of an artifact as a string.
|
||||
*
|
||||
* @param artifact the artifact who's content to retrieve
|
||||
* @return the string content of the artifact
|
||||
* @throws FileUtilsErrorException when an error occurred when reading the contents
|
||||
* @since 1.5.18
|
||||
*/
|
||||
public String readString(RepositoryArtifact artifact)
|
||||
throws FileUtilsErrorException {
|
||||
if (artifact.repository().isLocal()) {
|
||||
return FileUtils.readString(new File(artifact.location()));
|
||||
} else {
|
||||
var cached = getCached(artifact);
|
||||
if (cached != null) {
|
||||
return cached;
|
||||
}
|
||||
|
||||
try {
|
||||
var connection = new URL(artifact.location()).openConnection();
|
||||
connection.setUseCaches(false);
|
||||
if (artifact.repository().username() != null && artifact.repository().password() != null) {
|
||||
connection.setRequestProperty(
|
||||
HEADER_AUTHORIZATION,
|
||||
basicAuthorizationHeader(artifact.repository().username(), artifact.repository().password()));
|
||||
}
|
||||
try (var input_stream = connection.getInputStream()) {
|
||||
var result = FileUtils.readString(input_stream);
|
||||
cache(artifact, result);
|
||||
return result;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new FileUtilsErrorException("Error while reading URL '" + artifact.location() + ".", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Transfers artifact into the provided directory.
|
||||
* <p>
|
||||
* The destination directory must exist and be writable.
|
||||
*
|
||||
* @param artifact the artifact to transfer
|
||||
* @param directory the directory to transfer the artifact into
|
||||
* @return {@code true} when the artifact is present in the directory (it could already have been
|
||||
* there and be validated as correct); or {@code false} when the artifact couldn't be transferred
|
||||
* @throws IOException when an error occurred during the transfer
|
||||
* @throws FileUtilsErrorException when an error occurred during the transfer
|
||||
* @since 1.5.18
|
||||
*/
|
||||
public boolean transferIntoDirectory(RepositoryArtifact artifact, File directory)
|
||||
throws IOException, FileUtilsErrorException {
|
||||
if (directory == null) throw new IllegalArgumentException("directory can't be null");
|
||||
if (!directory.exists()) throw new IllegalArgumentException("directory '" + directory + "' doesn't exit");
|
||||
if (!directory.canWrite()) throw new IllegalArgumentException("directory '" + directory + "' can't be written to");
|
||||
if (!directory.isDirectory()) throw new IllegalArgumentException("directory '" + directory + "' is not a directory");
|
||||
|
||||
var download_filename = artifact.location().substring(artifact.location().lastIndexOf("/") + 1);
|
||||
var download_file = new File(directory, download_filename);
|
||||
System.out.print("Downloading: " + artifact.location() + " ... ");
|
||||
System.out.flush();
|
||||
try {
|
||||
if (artifact.repository().isLocal()) {
|
||||
var source = new File(artifact.location());
|
||||
if (source.exists()) {
|
||||
FileUtils.copy(source, download_file);
|
||||
System.out.print("done");
|
||||
return true;
|
||||
} else {
|
||||
System.out.print("not found");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
if (download_file.exists() && download_file.canRead()) {
|
||||
if (checkHash(artifact, download_file, ".sha256", "SHA-256") ||
|
||||
checkHash(artifact, download_file, ".md5", "MD5")) {
|
||||
System.out.print("exists");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
var connection = new URL(artifact.location()).openConnection();
|
||||
connection.setUseCaches(false);
|
||||
if (artifact.repository().username() != null && artifact.repository().password() != null) {
|
||||
connection.setRequestProperty(
|
||||
HEADER_AUTHORIZATION,
|
||||
basicAuthorizationHeader(artifact.repository().username(), artifact.repository().password()));
|
||||
}
|
||||
try (var input_stream = connection.getInputStream()) {
|
||||
var readableByteChannel = Channels.newChannel(input_stream);
|
||||
try (var fileOutputStream = new FileOutputStream(download_file)) {
|
||||
var fileChannel = fileOutputStream.getChannel();
|
||||
fileChannel.transferFrom(readableByteChannel, 0, Long.MAX_VALUE);
|
||||
|
||||
System.out.print("done");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (FileNotFoundException e) {
|
||||
System.out.print("not found");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkHash(RepositoryArtifact artifact, File downloadFile, String extension, String algorithm) {
|
||||
try {
|
||||
var hash_sum = readString(artifact.appendPath(extension));
|
||||
var digest = MessageDigest.getInstance(algorithm);
|
||||
digest.update(FileUtils.readBytes(downloadFile));
|
||||
return hash_sum.equals(encodeHexLower(digest.digest()));
|
||||
} catch (Exception e) {
|
||||
// no-op, the hash file couldn't be found or calculated, so it couldn't be checked
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
169
src/main/java/rife/bld/dependencies/Dependency.java
Normal file
169
src/main/java/rife/bld/dependencies/Dependency.java
Normal file
|
@ -0,0 +1,169 @@
|
|||
/*
|
||||
* 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.util.Objects;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Contains the information required to describe an url 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)
|
||||
* @since 1.5
|
||||
*/
|
||||
public record Dependency(String groupId, String artifactId, VersionNumber version, String classifier, String type, ExclusionSet exclusions, Dependency parent) {
|
||||
public static final String CLASSIFIER_SOURCES = "sources";
|
||||
public static final String CLASSIFIER_JAVADOC = "javadoc";
|
||||
|
||||
public Dependency(String groupId, String artifactId) {
|
||||
this(groupId, artifactId, null, null, null);
|
||||
}
|
||||
|
||||
public Dependency(String groupId, String artifactId, VersionNumber version) {
|
||||
this(groupId, artifactId, version, null, null);
|
||||
}
|
||||
|
||||
public Dependency(String groupId, String artifactId, VersionNumber version, String classifier) {
|
||||
this(groupId, artifactId, version, classifier, null);
|
||||
}
|
||||
|
||||
public Dependency(String groupId, String artifactId, VersionNumber version, String classifier, String type) {
|
||||
this(groupId, artifactId, version, classifier, type, null);
|
||||
}
|
||||
|
||||
public Dependency(String groupId, String artifactId, VersionNumber version, String classifier, String type, ExclusionSet exclusions) {
|
||||
this(groupId, artifactId, version, classifier, type, null, null);
|
||||
}
|
||||
|
||||
public Dependency(String groupId, String artifactId, VersionNumber version, String classifier, String type, ExclusionSet exclusions, Dependency parent) {
|
||||
this.groupId = groupId;
|
||||
this.artifactId = artifactId;
|
||||
this.version = (version == null ? VersionNumber.UNKNOWN : version);
|
||||
this.classifier = (classifier == null ? "" : classifier);
|
||||
this.type = (type == null ? "jar" : type);
|
||||
this.exclusions = (exclusions == null ? new ExclusionSet() : exclusions);
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
private static final Pattern DEPENDENCY_PATTERN = Pattern.compile("^(?<groupId>[^:@]+):(?<artifactId>[^:@]+)(?::(?<version>[^:@]+)(?::(?<classifier>[^:@]+))?)?(?:@(?<type>[^:@]+))?$");
|
||||
|
||||
/**
|
||||
* Parses a dependency from a string representation.
|
||||
* The format is {@code groupId:artifactId:version:classifier@type}.
|
||||
* The {@code version}, {@code classifier} and {@code type} are optional.
|
||||
* <p>
|
||||
* If the string can't be successfully parsed, {@code null} will be returned.
|
||||
*
|
||||
* @param dependency the dependency string to parse
|
||||
* @return a parsed instance of {@code Dependency}; or
|
||||
* {@code null} when the string couldn't be parsed
|
||||
* @since 1.5.2
|
||||
*/
|
||||
public static Dependency parse(String dependency) {
|
||||
if (dependency == null || dependency.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var matcher = DEPENDENCY_PATTERN.matcher(dependency);
|
||||
if (!matcher.matches()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var groupId = matcher.group("groupId");
|
||||
var artifactId = matcher.group("artifactId");
|
||||
var version = VersionNumber.parse(matcher.group("version"));
|
||||
var classifier = matcher.group("classifier");
|
||||
var type = matcher.group("type");
|
||||
|
||||
return new Dependency(groupId, artifactId, version, classifier, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the base dependency of this dependency, replacing the version number
|
||||
* with an unknown version number.
|
||||
*
|
||||
* @return this dependency's base dependency
|
||||
* @since 1.5
|
||||
*/
|
||||
public Dependency baseDependency() {
|
||||
return new Dependency(groupId, artifactId, VersionNumber.UNKNOWN, classifier, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an exclusion to this dependency.
|
||||
*
|
||||
* @param groupId the exclusion group identifier, use {@code "*"} to exclude all groupIds
|
||||
* @param artifactId the exclusion url identifier, use {@code "*"} to exclude all artifactIds
|
||||
* @return this dependency instance
|
||||
* @since 1.5
|
||||
*/
|
||||
public Dependency exclude(String groupId, String artifactId) {
|
||||
exclusions.add(new DependencyExclusion(groupId, artifactId));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new dependency with the same data, except for the provided classifier.
|
||||
*
|
||||
* @param classifier the classifier to use for the new dependency
|
||||
* @return the new dependency with the changed classifier
|
||||
* @since 1.5.6
|
||||
*/
|
||||
public Dependency withClassifier(String classifier) {
|
||||
return new Dependency(groupId, artifactId, version, classifier, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a filename that corresponds to the dependency information.
|
||||
*
|
||||
* @return a filename for the dependency
|
||||
* @since 1.5.4
|
||||
*/
|
||||
public String toFileName() {
|
||||
var result = new StringBuilder(artifactId());
|
||||
result.append("-").append(version());
|
||||
if (!classifier().isEmpty()) {
|
||||
result.append("-").append(classifier());
|
||||
}
|
||||
result.append(".").append(type());
|
||||
return result.toString();
|
||||
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
var result = new StringBuilder(groupId).append(":").append(artifactId);
|
||||
if (!version.equals(VersionNumber.UNKNOWN)) {
|
||||
result.append(":").append(version);
|
||||
}
|
||||
if (!classifier.isEmpty()) {
|
||||
result.append(":").append(classifier);
|
||||
}
|
||||
if (!type.isEmpty() && !type.equals("jar")) {
|
||||
result.append("@").append(type);
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
var that = (Dependency) o;
|
||||
return groupId.equals(that.groupId) &&
|
||||
artifactId.equals(that.artifactId) &&
|
||||
classifier.equals(that.classifier) &&
|
||||
type.equals(that.type);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return Objects.hash(groupId, artifactId, classifier, type);
|
||||
}
|
||||
}
|
34
src/main/java/rife/bld/dependencies/DependencyExclusion.java
Normal file
34
src/main/java/rife/bld/dependencies/DependencyExclusion.java
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* 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.util.Objects;
|
||||
|
||||
/**
|
||||
* Contains the information to describe a dependency exclusion.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5
|
||||
*/
|
||||
public record DependencyExclusion(String groupId, String artifactId) {
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
DependencyExclusion that = (DependencyExclusion) o;
|
||||
return Objects.equals(groupId, that.groupId) && Objects.equals(artifactId, that.artifactId);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return Objects.hash(groupId, artifactId);
|
||||
}
|
||||
|
||||
boolean matches(PomDependency dependency) {
|
||||
return (groupId().equals("*") && artifactId().equals("*")) ||
|
||||
(groupId().equals("*") && artifactId().equals(dependency.artifactId())) ||
|
||||
(groupId().equals(dependency.groupId()) && artifactId().equals("*")) ||
|
||||
(groupId().equals(dependency.groupId()) && artifactId().equals(dependency.artifactId()));
|
||||
|
||||
}
|
||||
}
|
427
src/main/java/rife/bld/dependencies/DependencyResolver.java
Normal file
427
src/main/java/rife/bld/dependencies/DependencyResolver.java
Normal file
|
@ -0,0 +1,427 @@
|
|||
/*
|
||||
* 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 rife.bld.dependencies.exceptions.*;
|
||||
import rife.tools.exceptions.FileUtilsErrorException;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Resolves a dependency within a list of Maven-compatible repositories.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5
|
||||
*/
|
||||
public class DependencyResolver {
|
||||
private final ArtifactRetriever retriever_;
|
||||
private final List<Repository> repositories_;
|
||||
private final Dependency dependency_;
|
||||
|
||||
private MavenMetadata metadata_ = null;
|
||||
private MavenMetadata snapshotMetadata_ = null;
|
||||
|
||||
/**
|
||||
* Creates a new resolver for a particular dependency.
|
||||
* <p>
|
||||
* The repositories will be checked in the order they're listed.
|
||||
*
|
||||
* @param retriever the retriever to use to get artifacts
|
||||
* @param repositories the repositories to use for the resolution
|
||||
* @param dependency the dependency to resolve
|
||||
* @since 1.5.18
|
||||
*/
|
||||
public DependencyResolver(ArtifactRetriever retriever, List<Repository> repositories, Dependency dependency) {
|
||||
retriever_ = retriever;
|
||||
if (repositories == null) {
|
||||
repositories = Collections.emptyList();
|
||||
}
|
||||
repositories_ = repositories;
|
||||
dependency_ = dependency;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the dependency exists in any of the provided repositories.
|
||||
*
|
||||
* @return {@code true} if the dependency exists; {@code false} otherwise
|
||||
* @since 1.5
|
||||
*/
|
||||
public boolean exists() {
|
||||
try {
|
||||
if (getMavenMetadata() == null) {
|
||||
return false;
|
||||
}
|
||||
if (!dependency_.version().equals(VersionNumber.UNKNOWN)) {
|
||||
return getMavenMetadata().getVersions().contains(dependency_.version());
|
||||
}
|
||||
return true;
|
||||
} catch (ArtifactNotFoundException | ArtifactRetrievalErrorException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Resolves the dependency version in the provided repositories.
|
||||
* <p>
|
||||
* When the dependency was defined without a specific version number,
|
||||
* the latest version number will be returned if the dependency exists.
|
||||
* If the dependency couldn't be found and no specific version number
|
||||
* was provided, {@linkplain VersionNumber#UNKNOWN} will be returned.
|
||||
*
|
||||
* @return the resolved version
|
||||
* @since 1.5
|
||||
*/
|
||||
public VersionNumber resolveVersion() {
|
||||
var version = dependency_.version();
|
||||
if (version.equals(VersionNumber.UNKNOWN)) {
|
||||
return latestVersion();
|
||||
}
|
||||
return version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the direct dependencies of the resolved dependency for the
|
||||
* provided scopes.
|
||||
*
|
||||
* @param scopes the scopes to return the direct dependencies for
|
||||
* @return the requested direct dependencies; or an empty {@linkplain DependencySet}
|
||||
* if no direct dependencies could be found or the dependency doesn't exist in
|
||||
* the provided repositories
|
||||
* @since 1.5
|
||||
*/
|
||||
public DependencySet getDirectDependencies(Scope... scopes) {
|
||||
var pom_dependencies = getMavenPom(dependency_).getDependencies(scopes);
|
||||
var result = new DependencySet();
|
||||
for (var dependency : pom_dependencies) {
|
||||
result.add(dependency.convertToDependency());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all the transitive dependencies of the resolved dependency for the
|
||||
* provided scopes. This includes the dependency of this resolver also.
|
||||
* <p>
|
||||
* This can be a slow and expensive operation since querying continues through
|
||||
* the complete POM hierarchy until all transitive dependencies have been found.
|
||||
*
|
||||
* @param scopes the scopes to return the transitive dependencies for
|
||||
* @return the requested transitive dependencies; or an empty {@linkplain DependencySet}
|
||||
* if no transitive dependencies could be found or the dependency doesn't exist in
|
||||
* the provided repositories
|
||||
* @since 1.5
|
||||
*/
|
||||
public DependencySet getAllDependencies(Scope... scopes) {
|
||||
var result = new DependencySet();
|
||||
result.add(dependency_);
|
||||
|
||||
var dependency_queue = new ArrayList<PomDependency>();
|
||||
|
||||
var parent = dependency_;
|
||||
var next_dependencies = getMavenPom(parent).getDependencies(scopes);
|
||||
|
||||
while (parent != null && next_dependencies != null) {
|
||||
// remove any next dependencies that are already queued
|
||||
dependency_queue.forEach(next_dependencies::remove);
|
||||
// remove any next dependencies that match the current exclusion context
|
||||
final var exclusion_context = parent;
|
||||
next_dependencies.removeIf(it -> matchesExclusions(exclusion_context, it));
|
||||
// add all next dependencies to the queue
|
||||
dependency_queue.addAll(next_dependencies);
|
||||
|
||||
// unless we find a next set of dependencies to add, stop resolving
|
||||
parent = null;
|
||||
next_dependencies = null;
|
||||
|
||||
// iterate through the dependency queue until we find one that isn't
|
||||
// part of the results yet
|
||||
while (!dependency_queue.isEmpty()) {
|
||||
var candidate = dependency_queue.remove(0);
|
||||
var dependency = candidate.convertToDependency();
|
||||
if (!result.contains(dependency)) {
|
||||
result.add(dependency);
|
||||
|
||||
// we found a dependency that was added to the result, get its
|
||||
// dependencies so that they can be added to the queue after
|
||||
// filtering
|
||||
parent = dependency;
|
||||
next_dependencies = new DependencyResolver(retriever_, repositories_, dependency).getMavenPom(parent).getDependencies(scopes);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean matchesExclusions(Dependency context, PomDependency checked) {
|
||||
while (context != null) {
|
||||
if (context.exclusions() != null) {
|
||||
for (var exclusion : context.exclusions()) {
|
||||
if (exclusion.matches(checked)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
context = context.parent();
|
||||
}
|
||||
|
||||
if (dependency_.exclusions() != null) {
|
||||
for (var exclusion : dependency_.exclusions()) {
|
||||
if (exclusion.matches(checked)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all the versions of the resolved dependency.
|
||||
*
|
||||
* @return this dependency's version list; or an empty list if the dependency
|
||||
* couldn't be found in the provided repositories
|
||||
* @since 1.5
|
||||
*/
|
||||
public List<VersionNumber> listVersions() {
|
||||
return getMavenMetadata().getVersions();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the latest version of the resolved dependency.
|
||||
*
|
||||
* @return this dependency's latest version; or {@link VersionNumber#UNKNOWN}
|
||||
* if the dependency couldn't be found in the provided repositories
|
||||
* @since 1.5
|
||||
*/
|
||||
public VersionNumber latestVersion() {
|
||||
return getMavenMetadata().getLatest();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the release version of the resolved dependency.
|
||||
*
|
||||
* @return this dependency's release version; or {@link VersionNumber#UNKNOWN}
|
||||
* if the dependency couldn't be found in the provided repositories
|
||||
* @since 1.5
|
||||
*/
|
||||
public VersionNumber releaseVersion() {
|
||||
return getMavenMetadata().getRelease();
|
||||
}
|
||||
|
||||
/**
|
||||
* Transfers the artifacts for the resolved dependency into the provided directory.
|
||||
* <p>
|
||||
* The destination directory must exist and be writable.
|
||||
*
|
||||
* @param directory the directory to transfer the dependency artifact into
|
||||
* @return the artifact that was successfully transferred; or {@code null} if no artifact was transferred
|
||||
* @throws DependencyTransferException when an error occurred during the transfer
|
||||
* @since 1.5.10
|
||||
*/
|
||||
public RepositoryArtifact transferIntoDirectory(File directory)
|
||||
throws DependencyTransferException {
|
||||
for (var artifact : getTransferArtifacts()) {
|
||||
try {
|
||||
if (retriever_.transferIntoDirectory(artifact, directory)) {
|
||||
return artifact;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new DependencyTransferException(dependency_, artifact.location(), directory, e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the repositories that are used by this dependency resolver.
|
||||
*
|
||||
* @return the dependency resolver's repositories
|
||||
* @since 1.5
|
||||
*/
|
||||
public List<Repository> repositories() {
|
||||
return repositories_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the dependency that is resolved.
|
||||
*
|
||||
* @return the resolved dependency
|
||||
* @since 1.5
|
||||
*/
|
||||
public Dependency dependency() {
|
||||
return dependency_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all the potential locations for the dependency
|
||||
* within the provided repositories.
|
||||
*
|
||||
* @return a list of potential transfer locations
|
||||
* @since 1.5.10
|
||||
*/
|
||||
public List<String> getTransferLocations() {
|
||||
return getTransferArtifacts().stream().map(RepositoryArtifact::location).toList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the main Maven metadata for this dependency
|
||||
*
|
||||
* @return this dependency's metadata
|
||||
* @since 1.5.8
|
||||
*/
|
||||
public MavenMetadata getMavenMetadata() {
|
||||
if (metadata_ == null) {
|
||||
var locations = getMetadataLocations();
|
||||
metadata_ = parseMavenMetadata(locations);
|
||||
}
|
||||
|
||||
return metadata_;
|
||||
}
|
||||
|
||||
/**
|
||||
* THe Maven metadata with snapshot information when this is a snapshot version.
|
||||
*
|
||||
* @return Maven metadata if this is a snapshot dependency version; or
|
||||
* {@code null} if this version is not a snapshot
|
||||
* @since 1.5.8
|
||||
*/
|
||||
public MavenMetadata getSnapshotMavenMetadata() {
|
||||
if (snapshotMetadata_ == null) {
|
||||
final var version = resolveVersion();
|
||||
if (version.isSnapshot()) {
|
||||
var locations = getSnapshotMetadataLocations();
|
||||
snapshotMetadata_ = parseMavenMetadata(locations);
|
||||
}
|
||||
}
|
||||
|
||||
return snapshotMetadata_;
|
||||
}
|
||||
|
||||
private List<RepositoryArtifact> getTransferArtifacts() {
|
||||
final var version = resolveVersion();
|
||||
final VersionNumber pom_version;
|
||||
if (version.isSnapshot()) {
|
||||
var metadata = getSnapshotMavenMetadata();
|
||||
pom_version = metadata.getSnapshot();
|
||||
} else {
|
||||
pom_version = version;
|
||||
}
|
||||
|
||||
return getArtifactLocations().stream().map(a -> {
|
||||
var result = new StringBuilder();
|
||||
result.append(version).append("/").append(dependency_.artifactId()).append("-").append(pom_version);
|
||||
if (!dependency_.classifier().isEmpty()) {
|
||||
result.append("-").append(dependency_.classifier());
|
||||
}
|
||||
var type = dependency_.type();
|
||||
if (type == null) {
|
||||
type = "jar";
|
||||
}
|
||||
result.append(".").append(type);
|
||||
|
||||
return a.appendPath(result.toString());
|
||||
}).toList();
|
||||
}
|
||||
|
||||
private List<RepositoryArtifact> getArtifactLocations() {
|
||||
return repositories_.stream().map(repository -> new RepositoryArtifact(repository, repository.getArtifactLocation(dependency_))).toList();
|
||||
}
|
||||
|
||||
private List<RepositoryArtifact> getMetadataLocations() {
|
||||
return getArtifactLocations().stream().map(a -> a.appendPath(a.repository().getMetadataName())).toList();
|
||||
}
|
||||
|
||||
private List<RepositoryArtifact> getSnapshotMetadataLocations() {
|
||||
var version = resolveVersion();
|
||||
return getArtifactLocations().stream().map(a -> a.appendPath(version + "/" + a.repository().getMetadataName())).toList();
|
||||
}
|
||||
|
||||
private MavenMetadata parseMavenMetadata(List<RepositoryArtifact> artifacts) {
|
||||
RepositoryArtifact retrieved_artifact = null;
|
||||
String metadata = null;
|
||||
for (var artifact : artifacts) {
|
||||
try {
|
||||
var content = retriever_.readString(artifact);
|
||||
if (content == null) {
|
||||
throw new ArtifactNotFoundException(dependency_, artifact.location());
|
||||
}
|
||||
|
||||
retrieved_artifact = artifact;
|
||||
metadata = content;
|
||||
|
||||
break;
|
||||
} catch (FileUtilsErrorException e) {
|
||||
if (e.getCause() instanceof FileNotFoundException) {
|
||||
continue;
|
||||
}
|
||||
throw new ArtifactRetrievalErrorException(dependency_, artifact.location(), e);
|
||||
}
|
||||
}
|
||||
|
||||
if (metadata == null) {
|
||||
throw new ArtifactNotFoundException(dependency_, artifacts.stream().map(RepositoryArtifact::location).collect(Collectors.joining(", ")));
|
||||
}
|
||||
|
||||
var xml = new Xml2MavenMetadata();
|
||||
if (!xml.processXml(metadata)) {
|
||||
throw new DependencyXmlParsingErrorException(dependency_, retrieved_artifact.location(), xml.getErrors());
|
||||
}
|
||||
|
||||
return xml;
|
||||
}
|
||||
|
||||
private List<RepositoryArtifact> getPomLocations() {
|
||||
final var version = resolveVersion();
|
||||
final VersionNumber pom_version;
|
||||
if (version.isSnapshot()) {
|
||||
var metadata = getSnapshotMavenMetadata();
|
||||
pom_version = metadata.getSnapshot();
|
||||
} else {
|
||||
pom_version = version;
|
||||
}
|
||||
|
||||
return getArtifactLocations().stream().map(a -> a.appendPath(version + "/" + dependency_.artifactId() + "-" + pom_version + ".pom")).toList();
|
||||
}
|
||||
|
||||
Xml2MavenPom getMavenPom(Dependency parent) {
|
||||
RepositoryArtifact retrieved_artifact = null;
|
||||
String pom = null;
|
||||
var artifacts = getPomLocations();
|
||||
|
||||
for (var artifact : artifacts) {
|
||||
try {
|
||||
var content = retriever_.readString(artifact);
|
||||
if (content == null) {
|
||||
throw new ArtifactNotFoundException(dependency_, artifact.location());
|
||||
}
|
||||
|
||||
retrieved_artifact = artifact;
|
||||
pom = content;
|
||||
|
||||
break;
|
||||
} catch (FileUtilsErrorException e) {
|
||||
if (e.getCause() instanceof FileNotFoundException) {
|
||||
continue;
|
||||
}
|
||||
throw new ArtifactRetrievalErrorException(dependency_, artifact.location(), e);
|
||||
}
|
||||
}
|
||||
|
||||
if (pom == null) {
|
||||
throw new ArtifactNotFoundException(dependency_, artifacts.stream().map(RepositoryArtifact::location).collect(Collectors.joining(", ")));
|
||||
}
|
||||
|
||||
var xml = new Xml2MavenPom(parent, retriever_, repositories_);
|
||||
if (!xml.processXml(pom)) {
|
||||
throw new DependencyXmlParsingErrorException(dependency_, retrieved_artifact.location(), xml.getErrors());
|
||||
}
|
||||
|
||||
return xml;
|
||||
}
|
||||
}
|
141
src/main/java/rife/bld/dependencies/DependencyScopes.java
Normal file
141
src/main/java/rife/bld/dependencies/DependencyScopes.java
Normal file
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* 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.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Convenience class to map a {@link Scope} to its dependencies.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5
|
||||
*/
|
||||
public class DependencyScopes extends LinkedHashMap<Scope, DependencySet> {
|
||||
/**
|
||||
* Creates an empty dependency scope map.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public DependencyScopes() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a dependency scope map from another one.
|
||||
*
|
||||
* @param other the other map to create this one from
|
||||
* @since 1.5
|
||||
*/
|
||||
public DependencyScopes(DependencyScopes other) {
|
||||
for (var entry : other.entrySet()) {
|
||||
put(entry.getKey(), new DependencySet(entry.getValue()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Includes all the dependencies from another dependency scope map.
|
||||
*
|
||||
* @param other the other map to include dependencies from
|
||||
* @since 1.5
|
||||
*/
|
||||
public void include(DependencyScopes other) {
|
||||
for (var entry : other.entrySet()) {
|
||||
var dependencies = get(entry.getKey());
|
||||
if (dependencies == null) {
|
||||
dependencies = new DependencySet();
|
||||
put(entry.getKey(), dependencies);
|
||||
}
|
||||
dependencies.addAll(entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the {@link DependencySet} for a particular scope.
|
||||
*
|
||||
* @param scope the scope to retrieve the dependencies for
|
||||
* @return the scope's {@code DependencySet};
|
||||
* or an empty {@code DependencySet} if none have been defined for the provided scope.
|
||||
* @since 1.5
|
||||
*/
|
||||
public DependencySet scope(Scope scope) {
|
||||
return computeIfAbsent(scope, k -> new DependencySet());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the transitive set of dependencies that would be used for the compile scope in a project.
|
||||
*
|
||||
* @param retriever the retriever to use to get artifacts
|
||||
* @param repositories the repositories to use for the resolution
|
||||
* @return the compile scope dependency set
|
||||
* @since 1.6
|
||||
*/
|
||||
public DependencySet resolveCompileDependencies(ArtifactRetriever retriever, List<Repository> repositories) {
|
||||
return resolveScopedDependencies(retriever, repositories,
|
||||
new Scope[]{Scope.provided, Scope.compile},
|
||||
new Scope[]{Scope.compile},
|
||||
null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the transitive set of dependencies that would be used for the runtime scope in a project.
|
||||
*
|
||||
* @param retriever the retriever to use to get artifacts
|
||||
* @param repositories the repositories to use for the resolution
|
||||
* @return the runtime scope dependency set
|
||||
* @since 1.6
|
||||
*/
|
||||
public DependencySet resolveRuntimeDependencies(ArtifactRetriever retriever, List<Repository> repositories) {
|
||||
return resolveScopedDependencies(retriever, repositories,
|
||||
new Scope[]{Scope.provided, Scope.compile, Scope.runtime},
|
||||
new Scope[]{Scope.compile, Scope.runtime},
|
||||
resolveCompileDependencies(retriever, repositories));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the transitive set of dependencies that would be used for the standalone scope in a project.
|
||||
*
|
||||
* @param retriever the retriever to use to get artifacts
|
||||
* @param repositories the repositories to use for the resolution
|
||||
* @return the standalone scope dependency set
|
||||
* @since 1.6
|
||||
*/
|
||||
public DependencySet resolveStandaloneDependencies(ArtifactRetriever retriever, List<Repository> repositories) {
|
||||
return resolveScopedDependencies(retriever, repositories,
|
||||
new Scope[]{Scope.standalone},
|
||||
new Scope[]{Scope.compile, Scope.runtime},
|
||||
null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the transitive set of dependencies that would be used for the test scope in a project.
|
||||
*
|
||||
* @param retriever the retriever to use to get artifacts
|
||||
* @param repositories the repositories to use for the resolution
|
||||
* @return the test scope dependency set
|
||||
* @since 1.6
|
||||
*/
|
||||
public DependencySet resolveTestDependencies(ArtifactRetriever retriever, List<Repository> repositories) {
|
||||
return resolveScopedDependencies(retriever, repositories,
|
||||
new Scope[]{Scope.test},
|
||||
new Scope[]{Scope.compile, Scope.runtime},
|
||||
null);
|
||||
}
|
||||
|
||||
private DependencySet resolveScopedDependencies(ArtifactRetriever retriever, List<Repository> repositories, Scope[] resolvedScopes, Scope[] transitiveScopes, DependencySet excluded) {
|
||||
var dependencies = new DependencySet();
|
||||
for (var scope : resolvedScopes) {
|
||||
var scoped_dependencies = get(scope);
|
||||
if (scoped_dependencies != null) {
|
||||
for (var dependency : scoped_dependencies) {
|
||||
dependencies.addAll(new DependencyResolver(retriever, repositories, dependency).getAllDependencies(transitiveScopes));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (excluded != null) {
|
||||
dependencies.removeAll(excluded);
|
||||
}
|
||||
return dependencies;
|
||||
}
|
||||
}
|
266
src/main/java/rife/bld/dependencies/DependencySet.java
Normal file
266
src/main/java/rife/bld/dependencies/DependencySet.java
Normal file
|
@ -0,0 +1,266 @@
|
|||
/*
|
||||
* 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 rife.bld.dependencies.exceptions.DependencyTransferException;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Convenience class to handle a set of {@link Dependency} objects.
|
||||
* <p>
|
||||
* Only a single version of each dependency can exist in this set.
|
||||
* When adding a new dependency, it will only be added if it didn't exist
|
||||
* in the set yet, or if the new dependency has a higher version than
|
||||
* the existing one.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5
|
||||
*/
|
||||
public class DependencySet extends AbstractSet<Dependency> implements Set<Dependency> {
|
||||
private final Map<Dependency, Dependency> dependencies_ = new LinkedHashMap<>();
|
||||
private final Set<LocalDependency> localDependencies_ = new LinkedHashSet<>();
|
||||
|
||||
/**
|
||||
* Creates an empty dependency set.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public DependencySet() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a dependency set from another one.
|
||||
*
|
||||
* @param other the other set to create this one from
|
||||
* @since 1.5
|
||||
*/
|
||||
public DependencySet(DependencySet other) {
|
||||
addAll(other);
|
||||
}
|
||||
|
||||
/**
|
||||
* Includes a dependency into the dependency set.
|
||||
*
|
||||
* @param dependency the dependency to include
|
||||
* @return this dependency set instance
|
||||
* @since 1.5
|
||||
*/
|
||||
public DependencySet include(Dependency dependency) {
|
||||
add(dependency);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Includes a local dependency into the dependency set.
|
||||
* <p>
|
||||
* Local dependencies aren't resolved and point to a location on
|
||||
* the file system.
|
||||
*
|
||||
* @param dependency the dependency to include
|
||||
* @return this dependency set instance
|
||||
* @since 1.5.2
|
||||
*/
|
||||
public DependencySet include(LocalDependency dependency) {
|
||||
localDependencies_.add(dependency);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the local dependencies.
|
||||
*
|
||||
* @return the set of local dependencies
|
||||
* @since 1.5.2
|
||||
*/
|
||||
public Set<LocalDependency> localDependencies() {
|
||||
return localDependencies_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transfers the artifacts for the dependencies into the provided directory.
|
||||
* <p>
|
||||
* The destination directory must exist and be writable.
|
||||
*
|
||||
* @param retriever the retriever to use to get artifacts
|
||||
* @param repositories the repositories to use for the transfer
|
||||
* @param directory the directory to transfer the artifacts into
|
||||
* @return the list of artifacts that were transferred successfully
|
||||
* @throws DependencyTransferException when an error occurred during the transfer
|
||||
* @since 1.5.10
|
||||
*/
|
||||
public List<RepositoryArtifact> transferIntoDirectory(ArtifactRetriever retriever, List<Repository> repositories, File directory) {
|
||||
return transferIntoDirectory(retriever, repositories, directory, (String[]) null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transfers the artifacts for the dependencies into the provided directory,
|
||||
* including other classifiers.
|
||||
* <p>
|
||||
* The destination directory must exist and be writable.
|
||||
*
|
||||
* @param retriever the retriever to use to get artifacts
|
||||
* @param repositories the repositories to use for the download
|
||||
* @param directory the directory to download the artifacts into
|
||||
* @param classifiers the additional classifiers to transfer
|
||||
* @return the list of artifacts that were transferred successfully
|
||||
* @throws DependencyTransferException when an error occurred during the transfer
|
||||
* @since 1.5.10
|
||||
*/
|
||||
public List<RepositoryArtifact> transferIntoDirectory(ArtifactRetriever retriever, List<Repository> repositories, File directory, String... classifiers) {
|
||||
var result = new ArrayList<RepositoryArtifact>();
|
||||
for (var dependency : this) {
|
||||
var artifact = new DependencyResolver(retriever, repositories, dependency).transferIntoDirectory(directory);
|
||||
if (artifact != null) {
|
||||
result.add(artifact);
|
||||
}
|
||||
|
||||
if (classifiers != null) {
|
||||
for (var classifier : classifiers) {
|
||||
if (classifier != null) {
|
||||
var classifier_artifact = new DependencyResolver(retriever, repositories, dependency.withClassifier(classifier)).transferIntoDirectory(directory);
|
||||
if (classifier_artifact != null) {
|
||||
result.add(classifier_artifact);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the dependency that was stored in the set.
|
||||
* <p>
|
||||
* The version can be different from the dependency passed in and this
|
||||
* method can be used to look up the actual version of the dependency in the set.
|
||||
*
|
||||
* @param dependency the dependency to look for
|
||||
* @return the dependency in the set; or
|
||||
* {@code null} if no such dependency exists
|
||||
* @since 1.5
|
||||
*/
|
||||
public Dependency get(Dependency dependency) {
|
||||
return dependencies_.get(dependency);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the string description of the transitive hierarchical tree of
|
||||
* dependencies for a particular scope.
|
||||
*
|
||||
* @param retriever the retriever to use to get artifacts
|
||||
* @param repositories the repositories to look for dependencies in
|
||||
* @param scopes the scopes to return the transitive dependencies for
|
||||
* @return the generated tree description string; or an empty string if
|
||||
* there were no dependencies to describe
|
||||
* @since 1.5.21
|
||||
*/
|
||||
public String generateTransitiveDependencyTree(ArtifactRetriever retriever, List<Repository> repositories, Scope... scopes) {
|
||||
var compile_dependencies = new DependencySet();
|
||||
for (var dependency : this) {
|
||||
compile_dependencies.addAll(new DependencyResolver(retriever, repositories, dependency).getAllDependencies(scopes));
|
||||
}
|
||||
return compile_dependencies.generateDependencyTree();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the string description of the hierarchical tree of
|
||||
* dependencies in this {@code DependencySet}. This relies on the {@code Dependency}
|
||||
* {@code parent} field to be set correctly to indicate their relationships.
|
||||
*
|
||||
* @return the generated tree description string; or an empty string if
|
||||
* there were no dependencies to describe
|
||||
* @since 1.5.21
|
||||
*/
|
||||
public String generateDependencyTree() {
|
||||
var result = new StringBuilder();
|
||||
|
||||
var dependency_list = new ArrayList<>(this);
|
||||
var dependency_stack = new Stack<DependencyTreeEntry>();
|
||||
|
||||
var roots = dependency_list.stream().filter(dependency -> dependency.parent() == null).toList();
|
||||
dependency_list.removeIf(dependency -> dependency.parent() == null);
|
||||
|
||||
var roots_it = roots.iterator();
|
||||
while (roots_it.hasNext()) {
|
||||
var root = roots_it.next();
|
||||
|
||||
dependency_list.add(0, root);
|
||||
stack:
|
||||
do {
|
||||
var list_it = dependency_list.iterator();
|
||||
while (list_it.hasNext()) {
|
||||
var list_dep = list_it.next();
|
||||
if (list_dep.parent() == null) {
|
||||
list_it.remove();
|
||||
var entry = new DependencyTreeEntry(null, list_dep, !roots_it.hasNext());
|
||||
result.append(entry).append(System.lineSeparator());
|
||||
dependency_stack.add(entry);
|
||||
} else {
|
||||
var stack_entry = dependency_stack.peek();
|
||||
if (list_dep.parent().equals(stack_entry.dependency())) {
|
||||
list_it.remove();
|
||||
|
||||
boolean last = dependency_list.stream().noneMatch(d -> d.parent().equals(stack_entry.dependency()));
|
||||
var entry = new DependencyTreeEntry(stack_entry, list_dep, last);
|
||||
result.append(entry).append(System.lineSeparator());
|
||||
dependency_stack.add(entry);
|
||||
continue stack;
|
||||
}
|
||||
}
|
||||
}
|
||||
dependency_stack.pop();
|
||||
} while (!dependency_stack.isEmpty());
|
||||
}
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
private record DependencyTreeEntry(DependencyTreeEntry parent, Dependency dependency, boolean last) {
|
||||
public String toString() {
|
||||
var result = new StringBuilder();
|
||||
|
||||
if (last) {
|
||||
result.insert(0, "└─ ");
|
||||
} else {
|
||||
result.insert(0, "├─ ");
|
||||
}
|
||||
|
||||
var p = parent();
|
||||
while (p != null) {
|
||||
if (p.last()) {
|
||||
result.insert(0, " ");
|
||||
} else {
|
||||
result.insert(0, "│ ");
|
||||
}
|
||||
p = p.parent();
|
||||
}
|
||||
|
||||
return result.toString() + dependency;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean add(Dependency dependency) {
|
||||
var existing = dependencies_.get(dependency);
|
||||
if (existing == null) {
|
||||
dependencies_.put(dependency, dependency);
|
||||
return true;
|
||||
}
|
||||
if (dependency.version().compareTo(existing.version()) > 0) {
|
||||
dependencies_.remove(dependency);
|
||||
dependencies_.put(dependency, dependency);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public Iterator<Dependency> iterator() {
|
||||
return dependencies_.keySet().iterator();
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return dependencies_.size();
|
||||
}
|
||||
}
|
16
src/main/java/rife/bld/dependencies/ExclusionSet.java
Normal file
16
src/main/java/rife/bld/dependencies/ExclusionSet.java
Normal file
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* 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.util.LinkedHashSet;
|
||||
|
||||
/**
|
||||
* Convenience class to handle a set of {@link DependencyExclusion} objects.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5
|
||||
*/
|
||||
public class ExclusionSet extends LinkedHashSet<DependencyExclusion> {
|
||||
}
|
17
src/main/java/rife/bld/dependencies/LocalDependency.java
Normal file
17
src/main/java/rife/bld/dependencies/LocalDependency.java
Normal file
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Contains the information required to describe a local dependency for the build system.
|
||||
* <p>
|
||||
* If the local dependency points to a directory, it will be scanned for jar files.
|
||||
*
|
||||
* @param path the file system path of the local dependency
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5.2
|
||||
*/
|
||||
public record LocalDependency(String path) {
|
||||
}
|
63
src/main/java/rife/bld/dependencies/MavenMetadata.java
Normal file
63
src/main/java/rife/bld/dependencies/MavenMetadata.java
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* 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.util.List;
|
||||
|
||||
/**
|
||||
* Provides Maven metadata information
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5.8
|
||||
*/
|
||||
public interface MavenMetadata {
|
||||
/**
|
||||
* Returns latest version number in the metadata.
|
||||
*
|
||||
* @return the latest version number
|
||||
* @since 1.5.8
|
||||
*/
|
||||
VersionNumber getLatest();
|
||||
|
||||
/**
|
||||
* Returns release version number in the metadata.
|
||||
*
|
||||
* @return the release version number
|
||||
* @since 1.5.8
|
||||
*/
|
||||
VersionNumber getRelease();
|
||||
|
||||
/**
|
||||
* Returns snapshot version number in the metadata.
|
||||
*
|
||||
* @return the snapshot version number
|
||||
* @since 1.5.8
|
||||
*/
|
||||
VersionNumber getSnapshot();
|
||||
|
||||
/**
|
||||
* Returns snapshot timestamp in the metadata.
|
||||
*
|
||||
* @return the snapshot timestamp
|
||||
* @since 1.5.8
|
||||
*/
|
||||
String getSnapshotTimestamp();
|
||||
|
||||
/**
|
||||
* Returns snapshot build number in the metadata.
|
||||
*
|
||||
* @return the snapshot build number
|
||||
* @since 1.5.8
|
||||
*/
|
||||
Integer getSnapshotBuildNumber();
|
||||
|
||||
/**
|
||||
* Returns all the release or snapshot versions in the metadata.
|
||||
*
|
||||
* @return the version number list
|
||||
* @since 1.5.8
|
||||
*/
|
||||
List<VersionNumber> getVersions();
|
||||
}
|
47
src/main/java/rife/bld/dependencies/PomDependency.java
Normal file
47
src/main/java/rife/bld/dependencies/PomDependency.java
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* 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.util.*;
|
||||
|
||||
/**
|
||||
* Contains the information required to describe a dependency with all
|
||||
* the details stored in a Maven POM descriptor.
|
||||
* <p>
|
||||
* This is used by the {@linkplain DependencyResolver} while traversing
|
||||
* the dependency graph, eventually resulting into fully resolved
|
||||
* {@linkplain Dependency} instances.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5
|
||||
*/
|
||||
public record PomDependency(String groupId, String artifactId, String version, String classifier, String type,
|
||||
String scope, String optional, ExclusionSet exclusions, Dependency parent) {
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
PomDependency that = (PomDependency) o;
|
||||
return Objects.equals(groupId, that.groupId) && Objects.equals(artifactId, that.artifactId) && Objects.equals(classifier, that.classifier) && Objects.equals(type, that.type);
|
||||
}
|
||||
|
||||
boolean isPomImport() {
|
||||
return "pom".equals(type()) && "import".equals(scope());
|
||||
}
|
||||
|
||||
Dependency convertToDependency() {
|
||||
return new Dependency(
|
||||
groupId(),
|
||||
artifactId(),
|
||||
VersionNumber.parse(version()),
|
||||
classifier(),
|
||||
type(),
|
||||
exclusions(),
|
||||
parent());
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return Objects.hash(groupId, artifactId, classifier, type);
|
||||
}
|
||||
}
|
197
src/main/java/rife/bld/dependencies/Repository.java
Normal file
197
src/main/java/rife/bld/dependencies/Repository.java
Normal file
|
@ -0,0 +1,197 @@
|
|||
/*
|
||||
* 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 rife.ioc.HierarchicalProperties;
|
||||
import rife.tools.StringEncryptor;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
/**
|
||||
* Contains the information required to locate a Maven-compatible repository.
|
||||
*
|
||||
* @param location the base location of the repository
|
||||
* @param username the username to access the repository
|
||||
* @param password the password to access the repository
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5
|
||||
*/
|
||||
public record Repository(String location, String username, String password) {
|
||||
public static Repository MAVEN_LOCAL = null;
|
||||
public static final Repository MAVEN_CENTRAL = new Repository("https://repo1.maven.org/maven2/");
|
||||
public static final Repository SONATYPE_RELEASES = new Repository("https://s01.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_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 Repository RIFE2_RELEASES = new Repository("https://repo.rife2.com/releases/");
|
||||
public static final Repository RIFE2_SNAPSHOTS = new Repository("https://repo.rife2.com/snapshots/");
|
||||
|
||||
private static final String MAVEN_LOCAL_REPO_PROPERTY = "maven.repo.local";
|
||||
|
||||
public static final String PROPERTY_BLD_REPO_PREFIX = "bld.repo.";
|
||||
public static final String PROPERTY_BLD_REPO_USERNAME_SUFFIX = ".username";
|
||||
public static final String PROPERTY_BLD_REPO_PASSWORD_SUFFIX = ".password";
|
||||
|
||||
/**
|
||||
* This method will be called as soon as hierarchical properties
|
||||
* are initialized in the build executor. It is not intended to be called
|
||||
* manually.
|
||||
*
|
||||
* @param properties the hierarchical properties to use for resolving
|
||||
* the maven local repository
|
||||
* @since 1.5.12
|
||||
*/
|
||||
public static void resolveMavenLocal(HierarchicalProperties properties) {
|
||||
var user_home = properties.getValueString("user.home");
|
||||
if (user_home == null) {
|
||||
user_home = System.getProperty("user.home");
|
||||
}
|
||||
var maven_local = properties.getValueString(
|
||||
MAVEN_LOCAL_REPO_PROPERTY,
|
||||
Path.of(user_home, ".m2", "repository").toString());
|
||||
MAVEN_LOCAL = new Repository(maven_local);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the repository in the provided hierarchical properties.
|
||||
* <p>
|
||||
* For instance, using the name {@code myrepo} will look for the following properties:<br>
|
||||
* {@code bld.repo.myrepo}<br>
|
||||
* {@code bld.repo.myrepo.username} (optional)<br>
|
||||
* {@code bld.repo.myrepo.password} (optional)
|
||||
* <p>
|
||||
* If the {@code bld.repo.myrepo} property isn't found, the {@code locationOrName}
|
||||
* parameter will be used as a location instead.
|
||||
*
|
||||
* @param properties the hierarchical properties to look into
|
||||
* @param locationOrName the text to resolve a repository name or to be used as a location
|
||||
* @return the repository instance
|
||||
* @since 1.5.12
|
||||
*/
|
||||
public static Repository resolveRepository(HierarchicalProperties properties, String locationOrName) {
|
||||
if (properties != null && properties.contains(PROPERTY_BLD_REPO_PREFIX + locationOrName)) {
|
||||
var location = properties.getValueString(PROPERTY_BLD_REPO_PREFIX + locationOrName);
|
||||
var username = properties.getValueString(PROPERTY_BLD_REPO_PREFIX + locationOrName + PROPERTY_BLD_REPO_USERNAME_SUFFIX);
|
||||
var password = properties.getValueString(PROPERTY_BLD_REPO_PREFIX + locationOrName + PROPERTY_BLD_REPO_PASSWORD_SUFFIX);
|
||||
return new Repository(location, username, password);
|
||||
}
|
||||
|
||||
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 "RIFE2_RELEASES" -> Repository.RIFE2_RELEASES;
|
||||
case "RIFE2_SNAPSHOTS" -> Repository.RIFE2_SNAPSHOTS;
|
||||
default -> new Repository(locationOrName);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new repository with only a location.
|
||||
*
|
||||
* @param location the location to create the repository for
|
||||
* @since 1.5
|
||||
*/
|
||||
public Repository(String location) {
|
||||
this(location, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether this repository is local.
|
||||
*
|
||||
* @return {@code true} when this repository is local; or
|
||||
* {@code false} otherwise
|
||||
* @since 1.5.10
|
||||
*/
|
||||
public boolean isLocal() {
|
||||
return location().startsWith("/") || location().startsWith("file:");
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new repository instance of the same location, but with
|
||||
* different credentials.
|
||||
*
|
||||
* @param username the username to access the repository
|
||||
* @param password the password to access the repository
|
||||
* @return the new repository
|
||||
* @since 1.5.10
|
||||
*/
|
||||
public Repository withCredentials(String username, String password) {
|
||||
return new Repository(location(), username, password);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs the location for a dependency if it would be located in this repository.
|
||||
*
|
||||
* @param dependency the dependency to create the location for
|
||||
* @return the constructed location
|
||||
* @since 1.5.10
|
||||
*/
|
||||
public String getArtifactLocation(Dependency dependency) {
|
||||
return getArtifactLocation(dependency.groupId(), dependency.artifactId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs the location for a dependency if it would be located in this repository.
|
||||
*
|
||||
* @param groupId the groupId dependency to create the location for
|
||||
* @param artifactId the artifactId dependency to create the location for
|
||||
* @return the constructed location
|
||||
* @since 1.5.10
|
||||
*/
|
||||
public String getArtifactLocation(String groupId, String artifactId) {
|
||||
var group_path = groupId.replace(".", "/");
|
||||
var result = new StringBuilder();
|
||||
if (isLocal()) {
|
||||
if (location().startsWith("file://")) {
|
||||
result.append(location().substring("file://".length()));
|
||||
} else {
|
||||
result.append(location());
|
||||
}
|
||||
} else {
|
||||
result.append(location());
|
||||
}
|
||||
if (!location().endsWith("/")) {
|
||||
result.append("/");
|
||||
}
|
||||
return result.append(group_path).append("/").append(artifactId).append("/").toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the appropriate metadata name.
|
||||
*
|
||||
* @return the metadata name for this repository.
|
||||
* @since 1.5.10
|
||||
*/
|
||||
public String getMetadataName() {
|
||||
if (isLocal()) {
|
||||
return "maven-metadata-local.xml";
|
||||
} else {
|
||||
return "maven-metadata.xml";
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
var result = new StringBuilder(location);
|
||||
if (username() != null) {
|
||||
result.append(":");
|
||||
try {
|
||||
result.append(StringEncryptor.MD5HLO.performEncryption(username(), null));
|
||||
if (password() != null) {
|
||||
result.append(":");
|
||||
result.append(StringEncryptor.MD5HLO.performEncryption(password(), null));
|
||||
}
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
// should never happen
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
}
|
23
src/main/java/rife/bld/dependencies/RepositoryArtifact.java
Normal file
23
src/main/java/rife/bld/dependencies/RepositoryArtifact.java
Normal file
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Represents an artifact location in a repository.
|
||||
*
|
||||
* @param repository the repository of the artifact
|
||||
* @param location the location of the artifact in the repository
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.6
|
||||
*/
|
||||
public record RepositoryArtifact(Repository repository, String location) {
|
||||
public RepositoryArtifact appendPath(String path) {
|
||||
return new RepositoryArtifact(repository, location + path);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return repository + ":" + location;
|
||||
}
|
||||
}
|
44
src/main/java/rife/bld/dependencies/Scope.java
Normal file
44
src/main/java/rife/bld/dependencies/Scope.java
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Provides all the dependency scopes that are supported by
|
||||
* the RIFE2 build system.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5
|
||||
*/
|
||||
public enum Scope {
|
||||
/**
|
||||
* Used for compiling the main source code.
|
||||
* @since 1.5
|
||||
*/
|
||||
compile,
|
||||
|
||||
/**
|
||||
* Used when running the main source code.
|
||||
* @since 1.5
|
||||
*/
|
||||
runtime,
|
||||
|
||||
/**
|
||||
* Used when compiling and running the test source code.
|
||||
* @since 1.5
|
||||
*/
|
||||
test,
|
||||
|
||||
/**
|
||||
* Used when running the main source code without container.
|
||||
* @since 1.5
|
||||
*/
|
||||
standalone,
|
||||
|
||||
/**
|
||||
* Provided by a container when running the main source code.
|
||||
* @since 1.5
|
||||
*/
|
||||
provided
|
||||
}
|
249
src/main/java/rife/bld/dependencies/VersionNumber.java
Normal file
249
src/main/java/rife/bld/dependencies/VersionNumber.java
Normal file
|
@ -0,0 +1,249 @@
|
|||
/*
|
||||
* 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.util.Objects;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Contains the information required to describe a dependency version number.
|
||||
* <p>
|
||||
* This operates according to the versioning scheme specified by Maven.
|
||||
* <p>
|
||||
* When the version number is undefined, {@link VersionNumber#UNKNOWN} should be used.
|
||||
*
|
||||
* @param major the major version component
|
||||
* @param minor the minor version component
|
||||
* @param revision the revision of the version
|
||||
* @param qualifier a string qualifier for the version
|
||||
* @param separator the separator used to separate the qualifier from the version number
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5
|
||||
*/
|
||||
public record VersionNumber(Integer major, Integer minor, Integer revision, String qualifier, String separator) implements Comparable<VersionNumber> {
|
||||
public static final String SNAPSHOT_QUALIFIER = "SNAPSHOT";
|
||||
|
||||
/**
|
||||
* Singleton to use when the version is not specified.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
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>.*[^.\\-]))??$");
|
||||
|
||||
/**
|
||||
* Parses a version number from a string representation.
|
||||
* <p>
|
||||
* If the string can't be successfully parsed, {@link VersionNumber#UNKNOWN} will be returned.
|
||||
*
|
||||
* @param version the version string to parse
|
||||
* @return a parsed instance of {@code VersionNumber}; or
|
||||
* {@link VersionNumber#UNKNOWN} when the string couldn't be parsed
|
||||
* @since 1.5
|
||||
*/
|
||||
public static VersionNumber parse(String version) {
|
||||
if (version == null || version.isEmpty()) {
|
||||
return UNKNOWN;
|
||||
}
|
||||
|
||||
var matcher = VERSION_PATTERN.matcher(version);
|
||||
if (!matcher.matches()) {
|
||||
return UNKNOWN;
|
||||
}
|
||||
|
||||
var major = matcher.group("major");
|
||||
var minor = matcher.group("minor");
|
||||
var revision = matcher.group("revision");
|
||||
|
||||
var major_integer = (major != null ? Integer.parseInt(major) : null);
|
||||
var minor_integer = (minor != null ? Integer.parseInt(minor) : null);
|
||||
var revision_integer = (revision != null ? Integer.parseInt(revision) : null);
|
||||
|
||||
var qualifier = matcher.group("qualifier");
|
||||
var separator = matcher.group("separator");
|
||||
|
||||
return new VersionNumber(major_integer, minor_integer, revision_integer, qualifier, separator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a version number with only a major component.
|
||||
*
|
||||
* @param major the major version component
|
||||
* @since 1.5
|
||||
*/
|
||||
public VersionNumber(Integer major) {
|
||||
this(major, null, null, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a version number with a major and minor component.
|
||||
*
|
||||
* @param major the major version component
|
||||
* @param minor the minor version component
|
||||
* @since 1.5
|
||||
*/
|
||||
public VersionNumber(Integer major, Integer minor) {
|
||||
this(major, minor, null, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a version number with major, minor and revision components.
|
||||
*
|
||||
* @param major the major version component
|
||||
* @param minor the minor version component
|
||||
* @param revision the version revision component
|
||||
* @since 1.5
|
||||
*/
|
||||
public VersionNumber(Integer major, Integer minor, Integer revision) {
|
||||
this(major, minor, revision, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a complete version number with qualifier, the separator will default to "{@code -}".
|
||||
*
|
||||
* @param major the major version component
|
||||
* @param minor the minor version component
|
||||
* @param revision the version revision component
|
||||
* @param qualifier the version qualifier
|
||||
* @since 1.5
|
||||
*/
|
||||
public VersionNumber(Integer major, Integer minor, Integer revision, String qualifier) {
|
||||
this(major, minor, revision, qualifier, "-");
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a complete version number with qualifier.
|
||||
*
|
||||
* @param major the major version component
|
||||
* @param minor the minor version component
|
||||
* @param revision the version revision component
|
||||
* @param qualifier the version qualifier
|
||||
* @param separator the separator for the version qualifier
|
||||
* @since 1.5
|
||||
*/
|
||||
public VersionNumber(Integer major, Integer minor, Integer revision, String qualifier, String separator) {
|
||||
this.major = major;
|
||||
this.minor = minor;
|
||||
this.revision = revision;
|
||||
this.qualifier = (qualifier == null ? "" : qualifier);
|
||||
this.separator = separator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the base version number without the qualifier.
|
||||
*
|
||||
* @return the base version number instance
|
||||
* @since 1.5
|
||||
*/
|
||||
public VersionNumber getBaseVersion() {
|
||||
return new VersionNumber(major, minor, revision, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the version number with a different 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a primitive integer for the major version component.
|
||||
*
|
||||
* @return the major version component as an {@code int}
|
||||
* @since 1.5
|
||||
*/
|
||||
public int majorInt() {
|
||||
return major == null ? 0 : major;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a primitive integer for the minor version component.
|
||||
*
|
||||
* @return the minor version component as an {@code int}
|
||||
* @since 1.5
|
||||
*/
|
||||
public int minorInt() {
|
||||
return minor == null ? 0 : minor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a primitive integer for the version revision component.
|
||||
*
|
||||
* @return the version revision component as an {@code int}
|
||||
* @since 1.5
|
||||
*/
|
||||
public int revisionInt() {
|
||||
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() {
|
||||
return qualifier().toUpperCase().contains(SNAPSHOT_QUALIFIER);
|
||||
}
|
||||
|
||||
public int compareTo(VersionNumber other) {
|
||||
if (majorInt() != other.majorInt()) {
|
||||
return majorInt() - other.majorInt();
|
||||
}
|
||||
if (minorInt() != other.minorInt()) {
|
||||
return minorInt() - other.minorInt();
|
||||
}
|
||||
if (revisionInt() != other.revisionInt()) {
|
||||
return revisionInt() - other.revisionInt();
|
||||
}
|
||||
|
||||
if (qualifier.equals(other.qualifier)) {
|
||||
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() {
|
||||
var version = new StringBuilder();
|
||||
version.append(majorInt());
|
||||
if (minor != null || revision != null) {
|
||||
version.append(".");
|
||||
version.append(minorInt());
|
||||
}
|
||||
if (revision != null) {
|
||||
version.append(".");
|
||||
version.append(revisionInt());
|
||||
}
|
||||
if (qualifier != null && !qualifier.isEmpty()) {
|
||||
version.append(separator);
|
||||
version.append(qualifier);
|
||||
}
|
||||
return version.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
return other instanceof VersionNumber && compareTo((VersionNumber) other) == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = majorInt();
|
||||
result = 31 * result + minorInt();
|
||||
result = 31 * result + revisionInt();
|
||||
result = 31 * result + Objects.hashCode(qualifier.toLowerCase());
|
||||
return result;
|
||||
}
|
||||
}
|
120
src/main/java/rife/bld/dependencies/Xml2MavenMetadata.java
Normal file
120
src/main/java/rife/bld/dependencies/Xml2MavenMetadata.java
Normal file
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
* 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 org.xml.sax.Attributes;
|
||||
import org.xml.sax.SAXException;
|
||||
import rife.xml.Xml2Data;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Parses an XML document to generate {@link MavenMetadata}, this is an internal class.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5.8
|
||||
*/
|
||||
public class Xml2MavenMetadata extends Xml2Data implements MavenMetadata {
|
||||
private VersionNumber latest_ = VersionNumber.UNKNOWN;
|
||||
private VersionNumber release_ = VersionNumber.UNKNOWN;
|
||||
private final List<VersionNumber> versions_;
|
||||
private VersionNumber snapshot_ = VersionNumber.UNKNOWN;
|
||||
|
||||
private StringBuilder characterData_ = null;
|
||||
|
||||
private String snapshotTimestamp_ = null;
|
||||
private Integer snapshotBuildNumber_ = null;
|
||||
|
||||
public Xml2MavenMetadata() {
|
||||
versions_ = new ArrayList<>();
|
||||
}
|
||||
|
||||
public VersionNumber getLatest() {
|
||||
return latest_;
|
||||
}
|
||||
|
||||
public VersionNumber getRelease() {
|
||||
return release_;
|
||||
}
|
||||
|
||||
public VersionNumber getSnapshot() {
|
||||
return snapshot_;
|
||||
}
|
||||
|
||||
public String getSnapshotTimestamp() {
|
||||
return snapshotTimestamp_;
|
||||
}
|
||||
|
||||
public Integer getSnapshotBuildNumber() {
|
||||
return snapshotBuildNumber_;
|
||||
}
|
||||
|
||||
public List<VersionNumber> getVersions() {
|
||||
return versions_;
|
||||
}
|
||||
|
||||
public void startElement(String uri, String localName, String qName, Attributes attributes) {
|
||||
characterData_ = new StringBuilder();
|
||||
}
|
||||
|
||||
public void endElement(String uri, String localName, String qName) {
|
||||
switch (qName) {
|
||||
case "latest" -> latest_ = VersionNumber.parse(characterData_.toString());
|
||||
case "release" -> release_ = VersionNumber.parse(characterData_.toString());
|
||||
case "version" -> versions_.add(VersionNumber.parse(characterData_.toString()));
|
||||
case "timestamp" -> snapshotTimestamp_ = characterData_.toString();
|
||||
case "buildNumber" -> snapshotBuildNumber_ = Integer.parseInt(characterData_.toString());
|
||||
case "snapshot" -> {
|
||||
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;
|
||||
}
|
||||
|
||||
private static final Pattern MILESTONE = Pattern.compile("^m\\d*$");
|
||||
private static final Pattern BETA = Pattern.compile("^b\\d*$");
|
||||
private static final Pattern ALPHA = Pattern.compile("^a\\d*$");
|
||||
|
||||
public void endDocument()
|
||||
throws SAXException {
|
||||
// determine latest stable version by removing pre-release qualifiers
|
||||
var filtered_versions = new TreeSet<VersionNumber>();
|
||||
filtered_versions.addAll(versions_.stream()
|
||||
.filter(v -> {
|
||||
if (v.qualifier() == null) return true;
|
||||
var q = v.qualifier().toLowerCase();
|
||||
return !q.startsWith("rc") &&
|
||||
!q.startsWith("cr") &&
|
||||
!q.contains("milestone") &&
|
||||
!MILESTONE.matcher(q).matches() &&
|
||||
!q.contains("beta") &&
|
||||
!BETA.matcher(q).matches() &&
|
||||
!q.contains("alpha") &&
|
||||
!ALPHA.matcher(q).matches();
|
||||
}).toList());
|
||||
|
||||
// only replace the stable version from the metadata when
|
||||
// something remained from the filtering, then use the
|
||||
// last version in the sorted set
|
||||
if (!filtered_versions.isEmpty()) {
|
||||
latest_ = filtered_versions.last();
|
||||
}
|
||||
}
|
||||
|
||||
public void characters(char[] ch, int start, int length) {
|
||||
if (characterData_ != null) {
|
||||
characterData_.append(String.copyValueOf(ch, start, length));
|
||||
}
|
||||
}
|
||||
}
|
375
src/main/java/rife/bld/dependencies/Xml2MavenPom.java
Normal file
375
src/main/java/rife/bld/dependencies/Xml2MavenPom.java
Normal file
|
@ -0,0 +1,375 @@
|
|||
/*
|
||||
* 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 org.xml.sax.Attributes;
|
||||
import rife.xml.Xml2Data;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Parses an XML document to retrieve POM information, this is an internal class.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5.18
|
||||
*/
|
||||
class Xml2MavenPom extends Xml2Data {
|
||||
private final Dependency parent_;
|
||||
private final ArtifactRetriever retriever_;
|
||||
private final List<Repository> repositories_;
|
||||
private Map<Scope, Set<PomDependency>> resolvedDependencies_ = null;
|
||||
|
||||
private final Map<PomDependency, PomDependency> dependencyManagement_ = new LinkedHashMap<>();
|
||||
private final Set<PomDependency> dependencies_ = new LinkedHashSet<>();
|
||||
private final Map<String, String> properties_ = new HashMap<>();
|
||||
private final Stack<String> elementStack_ = new Stack<>();
|
||||
private ExclusionSet exclusions_ = null;
|
||||
|
||||
private boolean collectProperties_ = false;
|
||||
private boolean collectDependencyManagement_ = false;
|
||||
private boolean collectDependencies_ = false;
|
||||
private boolean collectExclusions_ = false;
|
||||
|
||||
private StringBuilder characterData_ = null;
|
||||
|
||||
private String lastGroupId_ = null;
|
||||
private String lastArtifactId_ = null;
|
||||
private String lastVersion_ = null;
|
||||
private String lastType_ = null;
|
||||
private String lastClassifier_ = null;
|
||||
private String lastScope_ = null;
|
||||
private String lastOptional_ = null;
|
||||
private String lastExclusionGroupId_ = null;
|
||||
private String lastExclusionArtifactId_ = null;
|
||||
|
||||
Xml2MavenPom(Dependency parent, ArtifactRetriever retriever, List<Repository> repositories) {
|
||||
parent_ = parent;
|
||||
retriever_ = retriever;
|
||||
repositories_ = repositories;
|
||||
}
|
||||
|
||||
Set<PomDependency> getDependencies(Scope... scopes) {
|
||||
if (scopes == null || scopes.length == 0) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
var scopes_list = Arrays.asList(scopes);
|
||||
|
||||
if (resolvedDependencies_ == null) {
|
||||
var resolved_dependencies = new HashMap<Scope, Set<PomDependency>>();
|
||||
|
||||
if (!dependencies_.isEmpty()) {
|
||||
for (var dependency : dependencies_) {
|
||||
var managed_dependency = dependencyManagement_.get(dependency);
|
||||
var version = dependency.version();
|
||||
var dep_scope = dependency.scope();
|
||||
var optional = dependency.optional();
|
||||
var exclusions = dependency.exclusions();
|
||||
if (managed_dependency != null) {
|
||||
if (version == null) {
|
||||
version = managed_dependency.version();
|
||||
}
|
||||
if (dep_scope == null) {
|
||||
dep_scope = managed_dependency.scope();
|
||||
}
|
||||
if (optional == null) {
|
||||
optional = managed_dependency.optional();
|
||||
}
|
||||
if (exclusions == null) {
|
||||
exclusions = managed_dependency.exclusions();
|
||||
}
|
||||
}
|
||||
if (dep_scope == null) {
|
||||
dep_scope = "compile";
|
||||
}
|
||||
optional = resolveProperties(optional);
|
||||
if ("true".equals(optional)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var resolved_dependency = new PomDependency(
|
||||
resolveProperties(dependency.groupId()),
|
||||
resolveProperties(dependency.artifactId()),
|
||||
resolveProperties(version),
|
||||
resolveProperties(dependency.classifier()),
|
||||
resolveProperties(dependency.type()),
|
||||
dep_scope,
|
||||
"false",
|
||||
exclusions,
|
||||
dependency.parent());
|
||||
if (resolved_dependency.type() == null || resolved_dependency.type().equals("jar")) {
|
||||
var scope = Scope.valueOf(resolved_dependency.scope());
|
||||
if (scopes_list.contains(scope)) {
|
||||
var resolved_dependency_set = resolved_dependencies.computeIfAbsent(scope, k -> new LinkedHashSet<>());
|
||||
resolved_dependency_set.add(resolved_dependency);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resolvedDependencies_ = resolved_dependencies;
|
||||
}
|
||||
|
||||
var result = new LinkedHashSet<PomDependency>();
|
||||
for (var scope : scopes) {
|
||||
var deps = resolvedDependencies_.get(scope);
|
||||
if (deps != null) {
|
||||
result.addAll(deps);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
PomDependency resolveDependency(PomDependency dependency) {
|
||||
return new PomDependency(
|
||||
resolveProperties(dependency.groupId()),
|
||||
resolveProperties(dependency.artifactId()),
|
||||
resolveProperties(dependency.version()),
|
||||
resolveProperties(dependency.classifier()),
|
||||
resolveProperties(dependency.type()),
|
||||
dependency.scope(),
|
||||
resolveProperties(dependency.optional()),
|
||||
dependency.exclusions(),
|
||||
dependency.parent());
|
||||
}
|
||||
|
||||
public void startElement(String uri, String localName, String qName, Attributes attributes) {
|
||||
characterData_ = new StringBuilder();
|
||||
|
||||
switch (qName) {
|
||||
case "parent" -> resetState();
|
||||
case "properties" -> {
|
||||
if (isChildOfProject()) {
|
||||
collectProperties_ = true;
|
||||
}
|
||||
}
|
||||
case "dependencyManagement" -> {
|
||||
if (isChildOfProject()) {
|
||||
collectDependencyManagement_ = true;
|
||||
}
|
||||
}
|
||||
case "dependencies" -> {
|
||||
if (isChildOfProject()) {
|
||||
resetState();
|
||||
collectDependencies_ = true;
|
||||
}
|
||||
}
|
||||
case "exclusions" -> {
|
||||
if (collectDependencyManagement_ || collectDependencies_) {
|
||||
collectExclusions_ = true;
|
||||
exclusions_ = new ExclusionSet();
|
||||
}
|
||||
}
|
||||
case "dependency" -> {
|
||||
if (collectDependencies_) resetState();
|
||||
}
|
||||
}
|
||||
|
||||
elementStack_.push(qName);
|
||||
}
|
||||
|
||||
public void endElement(String uri, String localName, String qName) {
|
||||
elementStack_.pop();
|
||||
|
||||
switch (qName) {
|
||||
case "parent" -> {
|
||||
if (isChildOfProject()) {
|
||||
var parent_dependency = new Dependency(resolveProperties(lastGroupId_), resolveProperties(lastArtifactId_), VersionNumber.parse(resolveProperties(lastVersion_)));
|
||||
var parent = new DependencyResolver(retriever_, repositories_, parent_dependency).getMavenPom(parent_);
|
||||
|
||||
parent.properties_.keySet().removeAll(properties_.keySet());
|
||||
properties_.putAll(parent.properties_);
|
||||
|
||||
parent.dependencyManagement_.keySet().removeAll(dependencyManagement_.keySet());
|
||||
dependencyManagement_.putAll(parent.dependencyManagement_);
|
||||
|
||||
parent.dependencies_.removeAll(dependencies_);
|
||||
dependencies_.addAll(parent.dependencies_);
|
||||
|
||||
resetState();
|
||||
}
|
||||
}
|
||||
case "properties" -> collectProperties_ = false;
|
||||
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(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));
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
case "groupId" -> {
|
||||
if (isChildOfProject()) {
|
||||
addProjectProperty(qName);
|
||||
} else if (isChildOfParent() || isChildOfDependency()) {
|
||||
lastGroupId_ = getCharacterData();
|
||||
} else if (collectExclusions_ && isChildOfExclusion()) {
|
||||
lastExclusionGroupId_ = getCharacterData();
|
||||
}
|
||||
}
|
||||
case "artifactId" -> {
|
||||
if (isChildOfProject()) {
|
||||
addProjectProperty(qName);
|
||||
} else if (isChildOfParent() || isChildOfDependency()) {
|
||||
lastArtifactId_ = getCharacterData();
|
||||
} else if (collectExclusions_ && isChildOfExclusion()) {
|
||||
lastExclusionArtifactId_ = getCharacterData();
|
||||
}
|
||||
}
|
||||
case "version" -> {
|
||||
if (isChildOfProject()) {
|
||||
addProjectProperty(qName);
|
||||
} else if (isChildOfParent() || isChildOfDependency()) {
|
||||
lastVersion_ = getCharacterData();
|
||||
}
|
||||
}
|
||||
case "type" -> {
|
||||
if (isChildOfDependency()) {
|
||||
lastType_ = getCharacterData();
|
||||
}
|
||||
}
|
||||
case "classifier" -> {
|
||||
if (isChildOfDependency()) {
|
||||
lastClassifier_ = getCharacterData();
|
||||
}
|
||||
}
|
||||
case "scope" -> {
|
||||
if (isChildOfDependency()) {
|
||||
lastScope_ = getCharacterData();
|
||||
}
|
||||
}
|
||||
case "optional" -> {
|
||||
if (isChildOfDependency()) {
|
||||
lastOptional_ = getCharacterData();
|
||||
}
|
||||
}
|
||||
case "packaging", "name", "description", "url", "inceptionYear" -> {
|
||||
if (isChildOfProject()) {
|
||||
addProjectProperty(qName);
|
||||
}
|
||||
}
|
||||
default -> {
|
||||
if (collectProperties_) {
|
||||
properties_.put(qName, getCharacterData());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
characterData_ = null;
|
||||
}
|
||||
|
||||
private boolean isChildOfProject() {
|
||||
return elementStack_.peek().equals("project");
|
||||
}
|
||||
|
||||
private boolean isChildOfParent() {
|
||||
return elementStack_.peek().equals("parent");
|
||||
}
|
||||
|
||||
private boolean isChildOfDependency() {
|
||||
return elementStack_.peek().equals("dependency");
|
||||
}
|
||||
|
||||
private boolean isChildOfExclusion() {
|
||||
return elementStack_.peek().equals("exclusion");
|
||||
}
|
||||
|
||||
private void addProjectProperty(String name) {
|
||||
properties_.put("project." + name, getCharacterData());
|
||||
}
|
||||
|
||||
private String getCharacterData() {
|
||||
if (characterData_ == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var result = characterData_.toString().trim();
|
||||
if (result.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static final Pattern MAVEN_PROPERTY = Pattern.compile("\\$\\{([^<>{}]+)}");
|
||||
|
||||
private String resolveProperties(String data) {
|
||||
if (data == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
boolean replaced;
|
||||
do {
|
||||
replaced = false;
|
||||
|
||||
var processed_data = new StringBuilder();
|
||||
var matcher = MAVEN_PROPERTY.matcher(data);
|
||||
var last_end = 0;
|
||||
while (matcher.find()) {
|
||||
if (matcher.groupCount() == 1) {
|
||||
var property = matcher.group(1);
|
||||
if (properties_.containsKey(property)) {
|
||||
processed_data.append(data, last_end, matcher.start());
|
||||
processed_data.append(properties_.get(property));
|
||||
last_end = matcher.end();
|
||||
|
||||
replaced = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (last_end < data.length()) {
|
||||
processed_data.append(data.substring(last_end));
|
||||
}
|
||||
|
||||
data = processed_data.toString();
|
||||
} while (replaced);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
private void resetState() {
|
||||
lastGroupId_ = null;
|
||||
lastArtifactId_ = null;
|
||||
lastVersion_ = null;
|
||||
lastType_ = null;
|
||||
lastClassifier_ = null;
|
||||
lastScope_ = null;
|
||||
lastOptional_ = null;
|
||||
lastExclusionArtifactId_ = null;
|
||||
lastExclusionGroupId_ = null;
|
||||
exclusions_ = null;
|
||||
}
|
||||
|
||||
public void characters(char[] ch, int start, int length) {
|
||||
if (characterData_ != null) {
|
||||
characterData_.append(String.copyValueOf(ch, start, length));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* 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.exceptions;
|
||||
|
||||
import rife.bld.dependencies.Dependency;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
public class ArtifactNotFoundException extends DependencyException {
|
||||
@Serial private static final long serialVersionUID = 3137804373567469249L;
|
||||
|
||||
private final Dependency dependency_;
|
||||
private final String location_;
|
||||
|
||||
public ArtifactNotFoundException(Dependency dependency, String location) {
|
||||
super("Couldn't find artifact for dependency '" + dependency + "' at " + location);
|
||||
|
||||
dependency_ = dependency;
|
||||
location_ = location;
|
||||
}
|
||||
|
||||
public Dependency getDependency() {
|
||||
return dependency_;
|
||||
}
|
||||
|
||||
public String getLocation() {
|
||||
return location_;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* 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.exceptions;
|
||||
|
||||
import rife.bld.dependencies.Dependency;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
public class ArtifactRetrievalErrorException extends DependencyException {
|
||||
@Serial private static final long serialVersionUID = 5570184718213503548L;
|
||||
|
||||
private final Dependency dependency_;
|
||||
private final String location_;
|
||||
|
||||
public ArtifactRetrievalErrorException(Dependency dependency, String location, Throwable e) {
|
||||
super("Unexpected error while retrieving artifact for dependency '" + dependency + "' from '" + location + "'", e);
|
||||
|
||||
dependency_ = dependency;
|
||||
location_ = location;
|
||||
}
|
||||
|
||||
public Dependency getDependency() {
|
||||
return dependency_;
|
||||
}
|
||||
|
||||
public String getLocation() {
|
||||
return location_;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* 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.exceptions;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
public class DependencyException extends RuntimeException {
|
||||
@Serial private static final long serialVersionUID = 7683888067001718316L;
|
||||
|
||||
public DependencyException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public DependencyException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public DependencyException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* 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.exceptions;
|
||||
|
||||
import rife.bld.dependencies.Dependency;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.Serial;
|
||||
|
||||
public class DependencyTransferException extends DependencyException {
|
||||
@Serial private static final long serialVersionUID = 2128741620203670830L;
|
||||
|
||||
private final Dependency dependency_;
|
||||
private final String location_;
|
||||
private final File destination_;
|
||||
|
||||
public DependencyTransferException(Dependency dependency, String location, File destination, Throwable e) {
|
||||
super("Unable to transfer dependency '" + dependency + "' from '" + location + "' into '" + destination + "'", e);
|
||||
|
||||
dependency_ = dependency;
|
||||
location_ = location;
|
||||
destination_ = destination;
|
||||
}
|
||||
|
||||
public Dependency getDependency() {
|
||||
return dependency_;
|
||||
}
|
||||
|
||||
public String getLocation() {
|
||||
return location_;
|
||||
}
|
||||
|
||||
public File getDestination() {
|
||||
return destination_;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* 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.exceptions;
|
||||
|
||||
import rife.bld.dependencies.Dependency;
|
||||
import rife.tools.StringUtils;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.util.Set;
|
||||
|
||||
public class DependencyXmlParsingErrorException extends DependencyException {
|
||||
@Serial private static final long serialVersionUID = -1050469071912675264L;
|
||||
|
||||
private final Dependency dependency_;
|
||||
private final String location_;
|
||||
private final Set<String> errors_;
|
||||
|
||||
public DependencyXmlParsingErrorException(Dependency dependency, String location, Set<String> errors) {
|
||||
super("Unable to parse artifact document for dependency '" + dependency + "' from '" + location + "' :\n" + StringUtils.join(errors, "\n"));
|
||||
|
||||
dependency_ = dependency;
|
||||
location_ = location;
|
||||
errors_ = errors;
|
||||
}
|
||||
|
||||
public Dependency getDependency() {
|
||||
return dependency_;
|
||||
}
|
||||
|
||||
public String getLocation() {
|
||||
return location_;
|
||||
}
|
||||
|
||||
public Set<String> getErrors() {
|
||||
return errors_;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||
*/
|
||||
|
||||
/**
|
||||
* Provides exception classes build system dependency handling.
|
||||
* @since 1.5
|
||||
*/
|
||||
package rife.bld.dependencies.exceptions;
|
10
src/main/java/rife/bld/dependencies/package-info.java
Normal file
10
src/main/java/rife/bld/dependencies/package-info.java
Normal file
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||
*/
|
||||
|
||||
/**
|
||||
* Provides functionalities to resolve and retrieve dependency artifacts.
|
||||
* @since 1.5
|
||||
*/
|
||||
package rife.bld.dependencies;
|
27
src/main/java/rife/bld/help/CleanHelp.java
Normal file
27
src/main/java/rife/bld/help/CleanHelp.java
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||
*/
|
||||
package rife.bld.help;
|
||||
|
||||
import rife.bld.CommandHelp;
|
||||
import rife.tools.StringUtils;
|
||||
|
||||
/**
|
||||
* Provides help for the clean command.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5
|
||||
*/
|
||||
public class CleanHelp implements CommandHelp {
|
||||
public String getSummary() {
|
||||
return "Cleans the build files";
|
||||
}
|
||||
|
||||
public String getDescription(String topic) {
|
||||
return StringUtils.replace("""
|
||||
Cleans the build files.
|
||||
|
||||
Usage : ${topic}""", "${topic}", topic);
|
||||
}
|
||||
}
|
27
src/main/java/rife/bld/help/CompileHelp.java
Normal file
27
src/main/java/rife/bld/help/CompileHelp.java
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||
*/
|
||||
package rife.bld.help;
|
||||
|
||||
import rife.bld.CommandHelp;
|
||||
import rife.tools.StringUtils;
|
||||
|
||||
/**
|
||||
* Provides help for the compile command.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5
|
||||
*/
|
||||
public class CompileHelp implements CommandHelp {
|
||||
public String getSummary() {
|
||||
return "Compiles the project";
|
||||
}
|
||||
|
||||
public String getDescription(String topic) {
|
||||
return StringUtils.replace("""
|
||||
Compiles the project.
|
||||
|
||||
Usage : ${topic}""", "${topic}", topic);
|
||||
}
|
||||
}
|
29
src/main/java/rife/bld/help/CreateBaseHelp.java
Normal file
29
src/main/java/rife/bld/help/CreateBaseHelp.java
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||
*/
|
||||
package rife.bld.help;
|
||||
|
||||
import rife.bld.CommandHelp;
|
||||
import rife.tools.StringUtils;
|
||||
|
||||
/**
|
||||
* Provides help for the create-blank command.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5.20
|
||||
*/
|
||||
public class CreateBaseHelp implements CommandHelp {
|
||||
public String getSummary() {
|
||||
return "Creates a new baseline Java project with minimal commands";
|
||||
}
|
||||
|
||||
public String getDescription(String topic) {
|
||||
return StringUtils.replace("""
|
||||
Creates a new baseline Java project with minimal commands.
|
||||
|
||||
Usage : ${topic} <package> <name>
|
||||
package The package of the project to create
|
||||
name The name of the project to create""", "${topic}", topic);
|
||||
}
|
||||
}
|
29
src/main/java/rife/bld/help/CreateBlankHelp.java
Normal file
29
src/main/java/rife/bld/help/CreateBlankHelp.java
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||
*/
|
||||
package rife.bld.help;
|
||||
|
||||
import rife.bld.CommandHelp;
|
||||
import rife.tools.StringUtils;
|
||||
|
||||
/**
|
||||
* Provides help for the create-blank command.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5
|
||||
*/
|
||||
public class CreateBlankHelp implements CommandHelp {
|
||||
public String getSummary() {
|
||||
return "Creates a new blank Java project with standard commands";
|
||||
}
|
||||
|
||||
public String getDescription(String topic) {
|
||||
return StringUtils.replace("""
|
||||
Creates a new blank Java project with standard commands.
|
||||
|
||||
Usage : ${topic} <package> <name>
|
||||
package The package of the project to create
|
||||
name The name of the project to create""", "${topic}", topic);
|
||||
}
|
||||
}
|
29
src/main/java/rife/bld/help/CreateLibHelp.java
Normal file
29
src/main/java/rife/bld/help/CreateLibHelp.java
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||
*/
|
||||
package rife.bld.help;
|
||||
|
||||
import rife.bld.CommandHelp;
|
||||
import rife.tools.StringUtils;
|
||||
|
||||
/**
|
||||
* Provides help for the create-lib command.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.6
|
||||
*/
|
||||
public class CreateLibHelp implements CommandHelp {
|
||||
public String getSummary() {
|
||||
return "Creates a new Java library with minimal commands";
|
||||
}
|
||||
|
||||
public String getDescription(String topic) {
|
||||
return StringUtils.replace("""
|
||||
Creates a new library Java project with minimal commands.
|
||||
|
||||
Usage : ${topic} <package> <name>
|
||||
package The package of the project to create
|
||||
name The name of the project to create""", "${topic}", topic);
|
||||
}
|
||||
}
|
29
src/main/java/rife/bld/help/CreateRife2Help.java
Normal file
29
src/main/java/rife/bld/help/CreateRife2Help.java
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||
*/
|
||||
package rife.bld.help;
|
||||
|
||||
import rife.bld.CommandHelp;
|
||||
import rife.tools.StringUtils;
|
||||
|
||||
/**
|
||||
* Provides help for the create command.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5
|
||||
*/
|
||||
public class CreateRife2Help implements CommandHelp {
|
||||
public String getSummary() {
|
||||
return "Creates a new RIFE2 project";
|
||||
}
|
||||
|
||||
public String getDescription(String topic) {
|
||||
return StringUtils.replace("""
|
||||
Creates a new RIFE2 project.
|
||||
|
||||
Usage : ${topic} <package> <name>
|
||||
package The package of the project to create
|
||||
name The name of the project to create""", "${topic}", topic);
|
||||
}
|
||||
}
|
27
src/main/java/rife/bld/help/DependencyTreeHelp.java
Normal file
27
src/main/java/rife/bld/help/DependencyTreeHelp.java
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||
*/
|
||||
package rife.bld.help;
|
||||
|
||||
import rife.bld.CommandHelp;
|
||||
import rife.tools.StringUtils;
|
||||
|
||||
/**
|
||||
* Provides help for the dependency tree command.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5.21
|
||||
*/
|
||||
public class DependencyTreeHelp implements CommandHelp {
|
||||
public String getSummary() {
|
||||
return "Outputs the dependency tree of the project";
|
||||
}
|
||||
|
||||
public String getDescription(String topic) {
|
||||
return StringUtils.replace("""
|
||||
Outputs the dependency tree of the project
|
||||
|
||||
Usage : ${topic}""", "${topic}", topic);
|
||||
}
|
||||
}
|
27
src/main/java/rife/bld/help/DownloadHelp.java
Normal file
27
src/main/java/rife/bld/help/DownloadHelp.java
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||
*/
|
||||
package rife.bld.help;
|
||||
|
||||
import rife.bld.CommandHelp;
|
||||
import rife.tools.StringUtils;
|
||||
|
||||
/**
|
||||
* Provides help for the download command.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5
|
||||
*/
|
||||
public class DownloadHelp implements CommandHelp {
|
||||
public String getSummary() {
|
||||
return "Downloads all dependencies of the project";
|
||||
}
|
||||
|
||||
public String getDescription(String topic) {
|
||||
return StringUtils.replace("""
|
||||
Downloads all dependencies of the project
|
||||
|
||||
Usage : ${topic}""", "${topic}", topic);
|
||||
}
|
||||
}
|
19
src/main/java/rife/bld/help/HelpHelp.java
Normal file
19
src/main/java/rife/bld/help/HelpHelp.java
Normal file
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||
*/
|
||||
package rife.bld.help;
|
||||
|
||||
import rife.bld.CommandHelp;
|
||||
|
||||
/**
|
||||
* Provides help for the help command.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5
|
||||
*/
|
||||
public class HelpHelp implements CommandHelp {
|
||||
public String getSummary() {
|
||||
return "Provides help about any of the other commands";
|
||||
}
|
||||
}
|
35
src/main/java/rife/bld/help/JUnitHelp.java
Normal file
35
src/main/java/rife/bld/help/JUnitHelp.java
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||
*/
|
||||
package rife.bld.help;
|
||||
|
||||
import rife.bld.CommandHelp;
|
||||
import rife.tools.StringUtils;
|
||||
|
||||
/**
|
||||
* Provides help for the JUnit test command.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5.20
|
||||
*/
|
||||
public class JUnitHelp implements CommandHelp {
|
||||
public String getSummary() {
|
||||
return "Tests the project with JUnit (takes options)";
|
||||
}
|
||||
|
||||
public String getDescription(String topic) {
|
||||
return StringUtils.replace("""
|
||||
Tests the project with JUnit.
|
||||
|
||||
Additional JUnit console launcher options can be
|
||||
provided after the command.
|
||||
|
||||
These commandline options are provided by this command:
|
||||
--junit-help see the full list of JUnit launcher options
|
||||
--junit-clear clear the JUnit launcher options the build uses
|
||||
(needs to be provided before other options)
|
||||
|
||||
Usage : ${topic} [OPTIONS]""", "${topic}", topic);
|
||||
}
|
||||
}
|
29
src/main/java/rife/bld/help/JarHelp.java
Normal file
29
src/main/java/rife/bld/help/JarHelp.java
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||
*/
|
||||
package rife.bld.help;
|
||||
|
||||
import rife.bld.CommandHelp;
|
||||
import rife.tools.StringUtils;
|
||||
|
||||
/**
|
||||
* Provides help for the jar command.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5
|
||||
*/
|
||||
public class JarHelp implements CommandHelp {
|
||||
public String getSummary() {
|
||||
return "Creates a jar archive for the project";
|
||||
}
|
||||
|
||||
public String getDescription(String topic) {
|
||||
return StringUtils.replace("""
|
||||
Creates a jar archive for the project.
|
||||
The standard jar command will automatically also execute
|
||||
the compile and precompile commands beforehand.
|
||||
|
||||
Usage : ${topic}""", "${topic}", topic);
|
||||
}
|
||||
}
|
29
src/main/java/rife/bld/help/JarJavadocHelp.java
Normal file
29
src/main/java/rife/bld/help/JarJavadocHelp.java
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||
*/
|
||||
package rife.bld.help;
|
||||
|
||||
import rife.bld.CommandHelp;
|
||||
import rife.tools.StringUtils;
|
||||
|
||||
/**
|
||||
* Provides help for the jar-javadoc command.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5.10
|
||||
*/
|
||||
public class JarJavadocHelp implements CommandHelp {
|
||||
public String getSummary() {
|
||||
return "Creates a javadoc jar archive for the project";
|
||||
}
|
||||
|
||||
public String getDescription(String topic) {
|
||||
return StringUtils.replace("""
|
||||
Creates a javadoc jar archive for the project.
|
||||
The standard jar-javadoc command will automatically also execute
|
||||
the compile and javadoc commands beforehand.
|
||||
|
||||
Usage : ${topic}""", "${topic}", topic);
|
||||
}
|
||||
}
|
27
src/main/java/rife/bld/help/JarSourcesHelp.java
Normal file
27
src/main/java/rife/bld/help/JarSourcesHelp.java
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||
*/
|
||||
package rife.bld.help;
|
||||
|
||||
import rife.bld.CommandHelp;
|
||||
import rife.tools.StringUtils;
|
||||
|
||||
/**
|
||||
* Provides help for the jar-sources command.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5.10
|
||||
*/
|
||||
public class JarSourcesHelp implements CommandHelp {
|
||||
public String getSummary() {
|
||||
return "Creates a sources jar archive for the project";
|
||||
}
|
||||
|
||||
public String getDescription(String topic) {
|
||||
return StringUtils.replace("""
|
||||
Creates a sources jar archive for the project.
|
||||
|
||||
Usage : ${topic}""", "${topic}", topic);
|
||||
}
|
||||
}
|
27
src/main/java/rife/bld/help/JavadocHelp.java
Normal file
27
src/main/java/rife/bld/help/JavadocHelp.java
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||
*/
|
||||
package rife.bld.help;
|
||||
|
||||
import rife.bld.CommandHelp;
|
||||
import rife.tools.StringUtils;
|
||||
|
||||
/**
|
||||
* Provides help for the javadoc command.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5.10
|
||||
*/
|
||||
public class JavadocHelp implements CommandHelp {
|
||||
public String getSummary() {
|
||||
return "Generates javadoc for the project";
|
||||
}
|
||||
|
||||
public String getDescription(String topic) {
|
||||
return StringUtils.replace("""
|
||||
Generates javadoc for the project.
|
||||
|
||||
Usage : ${topic}""", "${topic}", topic);
|
||||
}
|
||||
}
|
27
src/main/java/rife/bld/help/PrecompileHelp.java
Normal file
27
src/main/java/rife/bld/help/PrecompileHelp.java
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||
*/
|
||||
package rife.bld.help;
|
||||
|
||||
import rife.bld.CommandHelp;
|
||||
import rife.tools.StringUtils;
|
||||
|
||||
/**
|
||||
* Provides help for the precompile command.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5
|
||||
*/
|
||||
public class PrecompileHelp implements CommandHelp {
|
||||
public String getSummary() {
|
||||
return "Pre-compiles RIFE2 templates to class files";
|
||||
}
|
||||
|
||||
public String getDescription(String topic) {
|
||||
return StringUtils.replace("""
|
||||
Pre-compiles RIFE2 templates to class files
|
||||
|
||||
Usage : ${topic}""", "${topic}", topic);
|
||||
}
|
||||
}
|
30
src/main/java/rife/bld/help/PublishHelp.java
Normal file
30
src/main/java/rife/bld/help/PublishHelp.java
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||
*/
|
||||
package rife.bld.help;
|
||||
|
||||
import rife.bld.CommandHelp;
|
||||
import rife.tools.StringUtils;
|
||||
|
||||
/**
|
||||
* Provides help for the publish command.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5.7
|
||||
*/
|
||||
public class PublishHelp implements CommandHelp {
|
||||
public String getSummary() {
|
||||
return "Publishes the artifacts of your project";
|
||||
}
|
||||
|
||||
public String getDescription(String topic) {
|
||||
return StringUtils.replace("""
|
||||
Publishes the artifacts of the project to the publication
|
||||
repository.
|
||||
The standard publish command will automatically also execute
|
||||
the jar, jar-sources and jar-javadoc commands beforehand.
|
||||
|
||||
Usage : ${topic}""", "${topic}", topic);
|
||||
}
|
||||
}
|
31
src/main/java/rife/bld/help/PublishWebHelp.java
Normal file
31
src/main/java/rife/bld/help/PublishWebHelp.java
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||
*/
|
||||
package rife.bld.help;
|
||||
|
||||
import rife.bld.CommandHelp;
|
||||
import rife.tools.StringUtils;
|
||||
|
||||
/**
|
||||
* Provides help for the publish web command.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5.7
|
||||
*/
|
||||
public class PublishWebHelp implements CommandHelp {
|
||||
public String getSummary() {
|
||||
return "Publishes the artifacts of your web project";
|
||||
}
|
||||
|
||||
public String getDescription(String topic) {
|
||||
return StringUtils.replace("""
|
||||
Publishes the artifacts of the web project to the publication
|
||||
repository.
|
||||
The standard web publish command will automatically also execute
|
||||
the jar, jar-sources, jar-javadoc, uberjar and war commands
|
||||
beforehand.
|
||||
|
||||
Usage : ${topic}""", "${topic}", topic);
|
||||
}
|
||||
}
|
27
src/main/java/rife/bld/help/PurgeHelp.java
Normal file
27
src/main/java/rife/bld/help/PurgeHelp.java
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||
*/
|
||||
package rife.bld.help;
|
||||
|
||||
import rife.bld.CommandHelp;
|
||||
import rife.tools.StringUtils;
|
||||
|
||||
/**
|
||||
* Provides help for the purge command.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5
|
||||
*/
|
||||
public class PurgeHelp implements CommandHelp {
|
||||
public String getSummary() {
|
||||
return "Purges all unused artifacts from the project";
|
||||
}
|
||||
|
||||
public String getDescription(String topic) {
|
||||
return StringUtils.replace("""
|
||||
Purges all the unused dependency artifacts from the project
|
||||
|
||||
Usage : ${topic}""", "${topic}", topic);
|
||||
}
|
||||
}
|
27
src/main/java/rife/bld/help/RunHelp.java
Normal file
27
src/main/java/rife/bld/help/RunHelp.java
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||
*/
|
||||
package rife.bld.help;
|
||||
|
||||
import rife.bld.CommandHelp;
|
||||
import rife.tools.StringUtils;
|
||||
|
||||
/**
|
||||
* Provides help for the run command.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5
|
||||
*/
|
||||
public class RunHelp implements CommandHelp {
|
||||
public String getSummary() {
|
||||
return "Runs the project";
|
||||
}
|
||||
|
||||
public String getDescription(String topic) {
|
||||
return StringUtils.replace("""
|
||||
Runs the project.
|
||||
|
||||
Usage : ${topic}""", "${topic}", topic);
|
||||
}
|
||||
}
|
27
src/main/java/rife/bld/help/TestHelp.java
Normal file
27
src/main/java/rife/bld/help/TestHelp.java
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||
*/
|
||||
package rife.bld.help;
|
||||
|
||||
import rife.bld.CommandHelp;
|
||||
import rife.tools.StringUtils;
|
||||
|
||||
/**
|
||||
* Provides help for the test command.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5
|
||||
*/
|
||||
public class TestHelp implements CommandHelp {
|
||||
public String getSummary() {
|
||||
return "Tests the project";
|
||||
}
|
||||
|
||||
public String getDescription(String topic) {
|
||||
return StringUtils.replace("""
|
||||
Tests the project.
|
||||
|
||||
Usage : ${topic}""", "${topic}", topic);
|
||||
}
|
||||
}
|
29
src/main/java/rife/bld/help/UberJarHelp.java
Normal file
29
src/main/java/rife/bld/help/UberJarHelp.java
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||
*/
|
||||
package rife.bld.help;
|
||||
|
||||
import rife.bld.CommandHelp;
|
||||
import rife.tools.StringUtils;
|
||||
|
||||
/**
|
||||
* Provides help for the uberjar command.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5
|
||||
*/
|
||||
public class UberJarHelp implements CommandHelp {
|
||||
public String getSummary() {
|
||||
return "Creates an UberJar archive for the project";
|
||||
}
|
||||
|
||||
public String getDescription(String topic) {
|
||||
return StringUtils.replace("""
|
||||
Creates an UberJar archive for the project.
|
||||
The standard uberjar command will automatically also execute
|
||||
the jar command beforehand.
|
||||
|
||||
Usage : ${topic}""", "${topic}", topic);
|
||||
}
|
||||
}
|
27
src/main/java/rife/bld/help/UpdatesHelp.java
Normal file
27
src/main/java/rife/bld/help/UpdatesHelp.java
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||
*/
|
||||
package rife.bld.help;
|
||||
|
||||
import rife.bld.CommandHelp;
|
||||
import rife.tools.StringUtils;
|
||||
|
||||
/**
|
||||
* Provides help for the updates command.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5
|
||||
*/
|
||||
public class UpdatesHelp implements CommandHelp {
|
||||
public String getSummary() {
|
||||
return "Checks for updates of the project dependencies";
|
||||
}
|
||||
|
||||
public String getDescription(String topic) {
|
||||
return StringUtils.replace("""
|
||||
Checks which updates are available for the project dependencies.
|
||||
|
||||
Usage : ${topic}""", "${topic}", topic);
|
||||
}
|
||||
}
|
29
src/main/java/rife/bld/help/UpgradeHelp.java
Normal file
29
src/main/java/rife/bld/help/UpgradeHelp.java
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||
*/
|
||||
package rife.bld.help;
|
||||
|
||||
import rife.bld.CommandHelp;
|
||||
import rife.tools.StringUtils;
|
||||
|
||||
/**
|
||||
* Provides help for the upgrade command.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5
|
||||
*/
|
||||
public class UpgradeHelp implements CommandHelp {
|
||||
public String getSummary() {
|
||||
return "Upgrades the bld wrapper to the latest version";
|
||||
}
|
||||
|
||||
public String getDescription(String topic) {
|
||||
return StringUtils.replace("""
|
||||
Upgrades the bld wrapper to the latest version.
|
||||
This command should be executed in the root directory of
|
||||
your project.
|
||||
|
||||
Usage : ${topic}""", "${topic}", topic);
|
||||
}
|
||||
}
|
27
src/main/java/rife/bld/help/VersionHelp.java
Normal file
27
src/main/java/rife/bld/help/VersionHelp.java
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||
*/
|
||||
package rife.bld.help;
|
||||
|
||||
import rife.bld.CommandHelp;
|
||||
import rife.tools.StringUtils;
|
||||
|
||||
/**
|
||||
* Provides help for the version command.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5.2
|
||||
*/
|
||||
public class VersionHelp implements CommandHelp {
|
||||
public String getSummary() {
|
||||
return "Outputs the version of the build system";
|
||||
}
|
||||
|
||||
public String getDescription(String topic) {
|
||||
return StringUtils.replace("""
|
||||
Outputs the version of the build system.
|
||||
|
||||
Usage : ${topic}""", "${topic}", topic);
|
||||
}
|
||||
}
|
29
src/main/java/rife/bld/help/WarHelp.java
Normal file
29
src/main/java/rife/bld/help/WarHelp.java
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||
*/
|
||||
package rife.bld.help;
|
||||
|
||||
import rife.bld.CommandHelp;
|
||||
import rife.tools.StringUtils;
|
||||
|
||||
/**
|
||||
* Provides help for the war command.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5
|
||||
*/
|
||||
public class WarHelp implements CommandHelp {
|
||||
public String getSummary() {
|
||||
return "Creates a war archive for the project";
|
||||
}
|
||||
|
||||
public String getDescription(String topic) {
|
||||
return StringUtils.replace("""
|
||||
Creates a war archive for the project.
|
||||
The standard war command will automatically also execute
|
||||
the jar command beforehand.
|
||||
|
||||
Usage : ${topic}""", "${topic}", topic);
|
||||
}
|
||||
}
|
10
src/main/java/rife/bld/help/package-info.java
Normal file
10
src/main/java/rife/bld/help/package-info.java
Normal file
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
* Copyright 2001-2023 Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||
*/
|
||||
|
||||
/**
|
||||
* Provides help texts for build commands.
|
||||
* @since 1.5
|
||||
*/
|
||||
package rife.bld.help;
|
526
src/main/java/rife/bld/operations/AbstractCreateOperation.java
Normal file
526
src/main/java/rife/bld/operations/AbstractCreateOperation.java
Normal file
|
@ -0,0 +1,526 @@
|
|||
/*
|
||||
* 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.BldVersion;
|
||||
import rife.bld.Project;
|
||||
import rife.bld.operations.exceptions.OperationOptionException;
|
||||
import rife.bld.wrapper.Wrapper;
|
||||
import rife.template.TemplateFactory;
|
||||
import rife.tools.FileUtils;
|
||||
import rife.tools.StringUtils;
|
||||
import rife.tools.exceptions.FileUtilsErrorException;
|
||||
import rife.validation.ValidityChecks;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Provides the baseline foundation for creating a project structure.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5
|
||||
*/
|
||||
public abstract class AbstractCreateOperation<T extends AbstractCreateOperation<T, P>, P extends Project> extends AbstractOperation<AbstractCreateOperation<T, P>> {
|
||||
final String templateBase_;
|
||||
|
||||
File workDirectory_ = new File(System.getProperty("user.dir"));
|
||||
String packageName_;
|
||||
String projectName_;
|
||||
boolean downloadDependencies_;
|
||||
|
||||
P project_;
|
||||
|
||||
String projectClassName_;
|
||||
String projectBuildName_;
|
||||
String projectMainName_;
|
||||
String projectMainUberName_;
|
||||
String projectTestName_;
|
||||
|
||||
File bldPackageDirectory_;
|
||||
File mainPackageDirectory_;
|
||||
File testPackageDirectory_;
|
||||
File ideaDirectory_;
|
||||
File ideaLibrariesDirectory_;
|
||||
File ideaRunConfigurationsDirectory_;
|
||||
File vscodeDirectory_;
|
||||
|
||||
protected AbstractCreateOperation(String templateBase) {
|
||||
templateBase_ = templateBase;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the creation operation.
|
||||
*
|
||||
* @throws FileUtilsErrorException when an error occurred during the creation operation
|
||||
* @throws IOException when an error occurred during the creation operation
|
||||
* @since 1.5
|
||||
*/
|
||||
public void execute()
|
||||
throws FileUtilsErrorException, IOException {
|
||||
if (packageName() == null || projectName() == null) {
|
||||
System.err.println("ERROR: Missing package or project name.");
|
||||
return;
|
||||
}
|
||||
|
||||
executeConfigure();
|
||||
executeCreateProjectStructure();
|
||||
executePopulateProjectStructure();
|
||||
executePopulateIdeaProject();
|
||||
executePopulateVscodeProject();
|
||||
if (downloadDependencies()) {
|
||||
executeDownloadDependencies();
|
||||
}
|
||||
if (!silent()) {
|
||||
System.out.println("The project was successfully created at '" + project_.workDirectory() + "'.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a blueprint of the project.
|
||||
*
|
||||
* @return a blueprint for project creation
|
||||
* @since 1.5
|
||||
*/
|
||||
protected abstract P createProjectBlueprint();
|
||||
|
||||
/**
|
||||
* Part of the {@link #execute} operation, configures the project.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
protected void executeConfigure() {
|
||||
project_ = createProjectBlueprint();
|
||||
|
||||
// standard names
|
||||
projectClassName_ = StringUtils.capitalize(project_.name());
|
||||
projectBuildName_ = projectBuildClassName(projectClassName_);
|
||||
projectMainName_ = projectMainClassName(projectClassName_);
|
||||
projectMainUberName_ = projectMainUberClassName(projectClassName_);
|
||||
projectTestName_ = projectTestClassName(projectClassName_);
|
||||
|
||||
// create the main project structure
|
||||
ideaDirectory_ = new File(project_.workDirectory(), ".idea");
|
||||
ideaLibrariesDirectory_ = new File(ideaDirectory_, "libraries");
|
||||
ideaRunConfigurationsDirectory_ = new File(ideaDirectory_, "runConfigurations");
|
||||
vscodeDirectory_ = new File(project_.workDirectory(), ".vscode");
|
||||
|
||||
var package_dir = project_.pkg().replace('.', File.separatorChar);
|
||||
bldPackageDirectory_ = new File(project_.srcBldJavaDirectory(), package_dir);
|
||||
mainPackageDirectory_ = new File(project_.srcMainJavaDirectory(), package_dir);
|
||||
testPackageDirectory_ = new File(project_.srcTestJavaDirectory(), package_dir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the build class name from the project class name
|
||||
* @param projectClassName the project class name
|
||||
* @return the generated build class name
|
||||
* @since 1.6
|
||||
*/
|
||||
protected String projectBuildClassName(String projectClassName) {
|
||||
return projectClassName + "Build";
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the main class name from the project class name
|
||||
* @param projectClassName the project class name
|
||||
* @return the generated main class name
|
||||
* @since 1.6
|
||||
*/
|
||||
protected String projectMainClassName(String projectClassName) {
|
||||
return projectClassName + "Main";
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the main uber class name from the project class name
|
||||
* @param projectClassName the project class name
|
||||
* @return the generated main uber class name
|
||||
* @since 1.6
|
||||
*/
|
||||
protected String projectMainUberClassName(String projectClassName) {
|
||||
return projectClassName + "Main";
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the test class name from the project class name
|
||||
* @param projectClassName the project class name
|
||||
* @return the generated test class name
|
||||
* @since 1.6
|
||||
*/
|
||||
protected String projectTestClassName(String projectClassName) {
|
||||
return projectClassName + "Test";
|
||||
}
|
||||
|
||||
/**
|
||||
* Part of the {@link #execute} operation, creates the project structure.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
protected void executeCreateProjectStructure() {
|
||||
project_.createProjectStructure();
|
||||
|
||||
bldPackageDirectory_.mkdirs();
|
||||
mainPackageDirectory_.mkdirs();
|
||||
testPackageDirectory_.mkdirs();
|
||||
|
||||
ideaDirectory_.mkdirs();
|
||||
ideaLibrariesDirectory_.mkdirs();
|
||||
ideaRunConfigurationsDirectory_.mkdirs();
|
||||
vscodeDirectory_.mkdirs();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Part of the {@link #execute} operation, populates the project structure.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
protected void executePopulateProjectStructure()
|
||||
throws FileUtilsErrorException, IOException {
|
||||
// project gitignore
|
||||
FileUtils.writeString(
|
||||
TemplateFactory.TXT.get(templateBase_ + "project_gitignore").getContent(),
|
||||
new File(project_.workDirectory(), ".gitignore"));
|
||||
|
||||
// project main
|
||||
var site_template = TemplateFactory.TXT.get(templateBase_ + "project_main");
|
||||
site_template.setValue("package", project_.pkg());
|
||||
site_template.setValue("projectMain", projectMainName_);
|
||||
var project_main_file = new File(mainPackageDirectory_, projectMainName_ + ".java");
|
||||
FileUtils.writeString(site_template.getContent(), project_main_file);
|
||||
|
||||
// project test
|
||||
var test_template = TemplateFactory.TXT.get(templateBase_ + "project_test");
|
||||
test_template.setValue("package", project_.pkg());
|
||||
test_template.setValue("projectTest", projectTestName_);
|
||||
test_template.setValue("projectMain", projectMainName_);
|
||||
if (test_template.hasValueId("project")) {
|
||||
test_template.setValue("project", projectClassName_);
|
||||
}
|
||||
var project_test_file = new File(testPackageDirectory_, projectTestName_ + ".java");
|
||||
FileUtils.writeString(test_template.getContent(), project_test_file);
|
||||
|
||||
// project build
|
||||
var build_template = TemplateFactory.TXT.get(templateBase_ + "project_build");
|
||||
build_template.setValue("projectBuild", projectBuildName_);
|
||||
build_template.setValue("package", project_.pkg());
|
||||
build_template.setValue("project", projectClassName_);
|
||||
if (build_template.hasValueId("projectMain")) {
|
||||
build_template.setValue("projectMain", projectMainName_);
|
||||
}
|
||||
if (build_template.hasValueId("projectTest")) {
|
||||
build_template.setValue("projectTest", projectTestName_);
|
||||
}
|
||||
if (build_template.hasValueId("projectMainUber")) {
|
||||
build_template.setValue("projectMainUber", projectMainUberName_);
|
||||
}
|
||||
for (var entry : project_.dependencies().entrySet()) {
|
||||
build_template.blankValue("dependencies");
|
||||
|
||||
for (var dependency : entry.getValue()) {
|
||||
build_template.setValue("groupId", dependency.groupId());
|
||||
build_template.setValue("artifactId", dependency.artifactId());
|
||||
var version = dependency.version();
|
||||
var version_string = version.major() + "," + version.minor() + "," + version.revision();
|
||||
if (!version.qualifier().isEmpty()) {
|
||||
version_string += ",\"" + version.qualifier() + "\"";
|
||||
}
|
||||
build_template.setValue("version", version_string);
|
||||
build_template.appendBlock("dependencies", "dependency");
|
||||
}
|
||||
build_template.setValue("name", entry.getKey().name());
|
||||
build_template.appendBlock("scopes", "scope");
|
||||
}
|
||||
var project_build_file = new File(bldPackageDirectory_, projectBuildName_ + ".java");
|
||||
FileUtils.writeString(build_template.getContent(), project_build_file);
|
||||
|
||||
// build shell scripts
|
||||
var build_sh_template = TemplateFactory.TXT.get("bld.bld");
|
||||
build_sh_template.setValue("projectBuild", projectBuildName_);
|
||||
build_sh_template.setValue("package", project_.pkg());
|
||||
var build_sh_file = new File(project_.workDirectory(), "bld");
|
||||
FileUtils.writeString(build_sh_template.getContent(), build_sh_file);
|
||||
build_sh_file.setExecutable(true);
|
||||
|
||||
var build_bat_template = TemplateFactory.TXT.get("bld.bld_bat");
|
||||
build_bat_template.setValue("projectBuild", projectBuildName_);
|
||||
build_bat_template.setValue("package", project_.pkg());
|
||||
var build_bat_file = new File(project_.workDirectory(), "bld.bat");
|
||||
FileUtils.writeString(build_bat_template.getContent(), build_bat_file);
|
||||
|
||||
// create the wrapper files
|
||||
new Wrapper().createWrapperFiles(project_.libBldDirectory(), BldVersion.getVersion());
|
||||
}
|
||||
|
||||
/**
|
||||
* Part of the {@link #execute} operation, populates the IDEA project structure.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
protected void executePopulateIdeaProject()
|
||||
throws FileUtilsErrorException {
|
||||
// IDEA project files
|
||||
FileUtils.writeString(
|
||||
TemplateFactory.XML.get(templateBase_ + "idea.app_iml").getContent(),
|
||||
new File(ideaDirectory_, "app.iml"));
|
||||
FileUtils.writeString(
|
||||
TemplateFactory.XML.get(templateBase_ + "idea.bld_iml").getContent(),
|
||||
new File(ideaDirectory_, "bld.iml"));
|
||||
FileUtils.writeString(
|
||||
TemplateFactory.XML.get(templateBase_ + "idea.misc").getContent(),
|
||||
new File(ideaDirectory_, "misc.xml"));
|
||||
FileUtils.writeString(
|
||||
TemplateFactory.XML.get(templateBase_ + "idea.modules").getContent(),
|
||||
new File(ideaDirectory_, "modules.xml"));
|
||||
|
||||
var bld_xml_template = TemplateFactory.XML.get(templateBase_ + "idea.libraries.bld");
|
||||
bld_xml_template.setValue("version", BldVersion.getVersion());
|
||||
var bld_xml_file = new File(ideaLibrariesDirectory_, "bld.xml");
|
||||
FileUtils.writeString(bld_xml_template.getContent(), bld_xml_file);
|
||||
|
||||
FileUtils.writeString(
|
||||
TemplateFactory.XML.get(templateBase_ + "idea.libraries.compile").getContent(),
|
||||
new File(ideaLibrariesDirectory_, "compile.xml"));
|
||||
FileUtils.writeString(
|
||||
TemplateFactory.XML.get(templateBase_ + "idea.libraries.runtime").getContent(),
|
||||
new File(ideaLibrariesDirectory_, "runtime.xml"));
|
||||
FileUtils.writeString(
|
||||
TemplateFactory.XML.get(templateBase_ + "idea.libraries.test").getContent(),
|
||||
new File(ideaLibrariesDirectory_, "test.xml"));
|
||||
|
||||
// IDEA run site
|
||||
if (createIdeaRunMain()) {
|
||||
var run_site_template = TemplateFactory.XML.get(templateBase_ + "idea.runConfigurations.Run_Main");
|
||||
run_site_template.setValue("package", project_.pkg());
|
||||
run_site_template.setValue("projectMain", projectMainName_);
|
||||
var run_site_file = new File(ideaRunConfigurationsDirectory_, "Run Main.xml");
|
||||
FileUtils.writeString(run_site_template.getContent(), run_site_file);
|
||||
}
|
||||
|
||||
// IDEA run tests
|
||||
var run_tests_template = TemplateFactory.XML.get(templateBase_ + "idea.runConfigurations.Run_Tests");
|
||||
run_tests_template.setValue("package", project_.pkg());
|
||||
if (run_tests_template.hasValueId("projectTest")) {
|
||||
run_tests_template.setValue("projectTest", projectTestName_);
|
||||
}
|
||||
var run_tests_file = new File(ideaRunConfigurationsDirectory_, "Run Tests.xml");
|
||||
FileUtils.writeString(run_tests_template.getContent(), run_tests_file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether the IDEA main run target should be generated
|
||||
* @return {@code true} of it should be generated; or {@code false} otherwise
|
||||
* @since 1.6
|
||||
*/
|
||||
protected boolean createIdeaRunMain() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Part of the {@link #execute} operation, populates the vscode project structure.
|
||||
*
|
||||
* @since 1.5.6
|
||||
*/
|
||||
protected void executePopulateVscodeProject()
|
||||
throws FileUtilsErrorException {
|
||||
var launch_template = TemplateFactory.JSON.get(templateBase_ + "vscode.launch");
|
||||
launch_template.setValue("package", project_.pkg());
|
||||
if (launch_template.hasValueId("projectMain")) {
|
||||
launch_template.setValue("projectMain", projectMainName_);
|
||||
}
|
||||
if (launch_template.hasValueId("projectTest")) {
|
||||
launch_template.setValue("projectTest", projectTestName_);
|
||||
}
|
||||
var launch_file = new File(vscodeDirectory_, "launch.json");
|
||||
FileUtils.writeString(launch_template.getContent(), launch_file);
|
||||
|
||||
var settings_template = TemplateFactory.JSON.get(templateBase_ + "vscode.settings");
|
||||
if (settings_template.hasValueId("version")) {
|
||||
settings_template.setValue("version", BldVersion.getVersion());
|
||||
}
|
||||
var settings_file = new File(vscodeDirectory_, "settings.json");
|
||||
FileUtils.writeString(settings_template.getContent(), settings_file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Part of the {@link #execute} operation, downloads the dependencies, when enabled.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
protected void executeDownloadDependencies() {
|
||||
new DownloadOperation().fromProject(project_).execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures a creation operation from command-line arguments.
|
||||
*
|
||||
* @param arguments the arguments that will be considered
|
||||
* @return this operation instance
|
||||
* @since 1.5
|
||||
*/
|
||||
public T fromArguments(List<String> arguments) {
|
||||
String package_name = null;
|
||||
String project_name = null;
|
||||
if (arguments.size() > 0) {
|
||||
package_name = arguments.remove(0);
|
||||
}
|
||||
if (arguments.size() > 0) {
|
||||
project_name = arguments.remove(0);
|
||||
}
|
||||
if ((package_name == null || project_name == null) && System.console() == null) {
|
||||
throw new OperationOptionException("ERROR: Expecting the package and project names as the arguments.");
|
||||
}
|
||||
|
||||
if (package_name == null || package_name.isEmpty()) {
|
||||
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 workDirectory(new File(System.getProperty("user.dir")))
|
||||
.packageName(package_name)
|
||||
.projectName(project_name)
|
||||
.downloadDependencies(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the work directory in which the project will be created.
|
||||
* <p>
|
||||
* If no work directory is provided, the JVM working directory will be used.
|
||||
*
|
||||
* @param directory the directory to use as a work directory
|
||||
* @return this operation instance
|
||||
* @since 1.5
|
||||
*/
|
||||
public T workDirectory(File directory) {
|
||||
if (!directory.exists()) {
|
||||
throw new OperationOptionException("ERROR: The work directory '" + directory + "' doesn't exist.");
|
||||
}
|
||||
if (!directory.isDirectory()) {
|
||||
throw new OperationOptionException("ERROR: '" + directory + "' is not a directory.");
|
||||
}
|
||||
if (!directory.canWrite()) {
|
||||
throw new OperationOptionException("ERROR: The work directory '" + directory + "' is not writable.");
|
||||
}
|
||||
|
||||
workDirectory_ = directory;
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the package of the project that will be created.
|
||||
*
|
||||
* @param name the package name
|
||||
* @return this operation instance
|
||||
* @since 1.5
|
||||
*/
|
||||
public T packageName(String name) {
|
||||
packageName_ = StringUtils.trim(name);
|
||||
if (packageName_.isEmpty()) {
|
||||
throw new OperationOptionException("ERROR: The package name should not be blank.");
|
||||
}
|
||||
|
||||
if (!ValidityChecks.checkJavaPackage(packageName_)) {
|
||||
throw new OperationOptionException("ERROR: The package name is invalid.");
|
||||
}
|
||||
|
||||
packageName_ = name;
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the name of the project that will be created.
|
||||
*
|
||||
* @param name the project name
|
||||
* @return this operation instance
|
||||
* @since 1.5
|
||||
*/
|
||||
public T projectName(String name) {
|
||||
projectName_ = StringUtils.trim(name);
|
||||
if (projectName_.isEmpty()) {
|
||||
throw new OperationOptionException("ERROR: The project name should not be blank.");
|
||||
}
|
||||
|
||||
if (!ValidityChecks.checkJavaIdentifier(projectName_)) {
|
||||
throw new OperationOptionException("ERROR: The project name is invalid.");
|
||||
}
|
||||
projectName_ = name;
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether the dependencies for the project should be downloaded
|
||||
* upon creation, by default this is {@code false}.
|
||||
*
|
||||
* @param flag {@code true} if the dependencies should be downloaded; or
|
||||
* {@code false} otherwise
|
||||
* @return this operation instance
|
||||
* @since 1.5
|
||||
*/
|
||||
public T downloadDependencies(boolean flag) {
|
||||
downloadDependencies_ = flag;
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the work directory that is used for the project creation.
|
||||
*
|
||||
* @return the work directory
|
||||
* @since 1.5
|
||||
*/
|
||||
public File workDirectory() {
|
||||
return workDirectory_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the package that is used for the project creation.
|
||||
*
|
||||
* @return the package name
|
||||
* @since 1.5
|
||||
*/
|
||||
public String packageName() {
|
||||
return packageName_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the name that is used for the project creation.
|
||||
*
|
||||
* @return the project name
|
||||
* @since 1.5
|
||||
*/
|
||||
public String projectName() {
|
||||
return projectName_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves whether dependencies will be downloaded at project creation.
|
||||
*
|
||||
* @return {@code true} if dependencies will be downloaded; or
|
||||
* {@code false} otherwise
|
||||
* @since 1.5
|
||||
*/
|
||||
public boolean downloadDependencies() {
|
||||
return downloadDependencies_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the project instance that was used as a blueprint for the
|
||||
* project creation.
|
||||
*
|
||||
* @return the project creation blueprint instance
|
||||
* @since 1.5
|
||||
*/
|
||||
public P project() {
|
||||
return project_;
|
||||
}
|
||||
}
|
86
src/main/java/rife/bld/operations/AbstractOperation.java
Normal file
86
src/main/java/rife/bld/operations/AbstractOperation.java
Normal file
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Provides common features across all operations
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5.2
|
||||
*/
|
||||
public abstract class AbstractOperation<T extends AbstractOperation<T>> {
|
||||
private boolean silent_ = false;
|
||||
private boolean executed_ = false;
|
||||
|
||||
/**
|
||||
* Changes whether the operation should be silent or not.
|
||||
* <p>
|
||||
* Defaults to not silent.
|
||||
*
|
||||
* @param silent {@code true} if the operation should be silent;
|
||||
* {@code false} otherwise
|
||||
* @return this operation instance
|
||||
* @since 1.5.2
|
||||
*/
|
||||
public T silent(boolean silent) {
|
||||
silent_ = silent;
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether the operation should be silent or not.
|
||||
*
|
||||
* @return {@code true} if the operation should be silent;
|
||||
* {@code false} otherwise
|
||||
* @since 1.5.2
|
||||
*/
|
||||
public boolean silent() {
|
||||
return silent_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that this operation instance is executed once and only once.
|
||||
*
|
||||
* @throws Exception when an exception was thrown by the {@link #execute()} call
|
||||
* @see #executeOnce(Runnable)
|
||||
* @since 1.5.17
|
||||
*/
|
||||
public void executeOnce()
|
||||
throws Exception {
|
||||
executeOnce(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that this operation instance is executed once and only once.
|
||||
* <p>
|
||||
* A setup lambda can be provided that is called when the only execution takes place.
|
||||
*
|
||||
* @param setup the setup lambda that will be called with the only execution
|
||||
* @throws Exception when an exception was thrown by the {@link #execute()} call
|
||||
* @see #executeOnce()
|
||||
* @since 1.5.17
|
||||
*/
|
||||
public void executeOnce(Runnable setup)
|
||||
throws Exception {
|
||||
if (executed_) {
|
||||
return;
|
||||
}
|
||||
executed_ = true;
|
||||
|
||||
if (setup != null) {
|
||||
setup.run();
|
||||
}
|
||||
execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the operation execution that can be wrapped by the {@code #executeOnce} call.
|
||||
*
|
||||
* @throws Exception when an exception occurs during the execution
|
||||
* @since 1.5.10
|
||||
*/
|
||||
public abstract void execute()
|
||||
throws Exception;
|
||||
}
|
337
src/main/java/rife/bld/operations/AbstractProcessOperation.java
Normal file
337
src/main/java/rife/bld/operations/AbstractProcessOperation.java
Normal file
|
@ -0,0 +1,337 @@
|
|||
/*
|
||||
* 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.BaseProject;
|
||||
import rife.bld.operations.exceptions.ExitStatusException;
|
||||
import rife.bld.operations.exceptions.OperationOptionException;
|
||||
import rife.tools.exceptions.FileUtilsErrorException;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Abstract operation that starts a Java application as a separate process.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5.18
|
||||
*/
|
||||
public abstract class AbstractProcessOperation<T extends AbstractProcessOperation<T>> extends AbstractOperation<T> {
|
||||
public static final String DEFAULT_JAVA_TOOL = "java";
|
||||
|
||||
protected File workDirectory_ = new File(System.getProperty("user.dir"));
|
||||
protected String javaTool_ = DEFAULT_JAVA_TOOL;
|
||||
protected final JavaOptions javaOptions_ = new JavaOptions();
|
||||
protected final List<String> classpath_ = new ArrayList<>();
|
||||
protected String mainClass_;
|
||||
protected Function<String, Boolean> outputProcessor_;
|
||||
protected Function<String, Boolean> errorProcessor_;
|
||||
protected Process process_;
|
||||
protected boolean successful_;
|
||||
protected Thread outputProcessorThread_;
|
||||
protected Thread errorProcessorThread_;
|
||||
|
||||
/**
|
||||
* Performs the operation.
|
||||
*
|
||||
* @throws InterruptedException when the operation was interrupted
|
||||
* @throws IOException when an exception occurred during the execution of the process
|
||||
* @throws FileUtilsErrorException when an exception occurred during the retrieval of the operation output
|
||||
* @throws ExitStatusException when the exit status was changed during the operation
|
||||
* @since 1.5
|
||||
*/
|
||||
public void execute()
|
||||
throws IOException, FileUtilsErrorException, InterruptedException, ExitStatusException {
|
||||
successful_ = true;
|
||||
outputProcessorThread_ = null;
|
||||
errorProcessorThread_ = null;
|
||||
|
||||
process_ = executeStartProcess();
|
||||
|
||||
int status = process_.waitFor();
|
||||
|
||||
if (outputProcessorThread_ != null) {
|
||||
outputProcessorThread_.join();
|
||||
}
|
||||
if (errorProcessorThread_ != null) {
|
||||
errorProcessorThread_.join();
|
||||
}
|
||||
if (!successful_) {
|
||||
status = ExitStatusException.EXIT_FAILURE;
|
||||
}
|
||||
|
||||
ExitStatusException.throwOnFailure(status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Part of the {@link #execute} operation, constructs the command list
|
||||
* to use for building the process.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
abstract protected List<String> executeConstructProcessCommandList();
|
||||
|
||||
/**
|
||||
* Part of the {@link #execute} operation, starts the process.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
protected Process executeStartProcess()
|
||||
throws IOException {
|
||||
var builder = new ProcessBuilder(executeConstructProcessCommandList());
|
||||
builder.directory(workDirectory());
|
||||
|
||||
final var output_processor = outputProcessor();
|
||||
if (output_processor == null) {
|
||||
builder.redirectOutput(ProcessBuilder.Redirect.INHERIT);
|
||||
} else {
|
||||
builder.redirectOutput(ProcessBuilder.Redirect.PIPE);
|
||||
}
|
||||
|
||||
final var error_processor = errorProcessor();
|
||||
if (error_processor == null) {
|
||||
builder.redirectError(ProcessBuilder.Redirect.INHERIT);
|
||||
} else {
|
||||
builder.redirectError(ProcessBuilder.Redirect.PIPE);
|
||||
}
|
||||
|
||||
final var process = builder.start();
|
||||
|
||||
if (output_processor != null) {
|
||||
outputProcessorThread_ = startProcessStreamProcessor(process.getInputStream(), output_processor);
|
||||
}
|
||||
if (error_processor != null) {
|
||||
errorProcessorThread_ = startProcessStreamProcessor(process.getErrorStream(), error_processor);
|
||||
}
|
||||
|
||||
return process;
|
||||
}
|
||||
|
||||
private Thread startProcessStreamProcessor(InputStream stream, Function<String, Boolean> processor) {
|
||||
var processor_thread = new Thread(() -> {
|
||||
try {
|
||||
String line;
|
||||
var in = new BufferedReader(new InputStreamReader(stream));
|
||||
while ((line = in.readLine()) != null) {
|
||||
successful_ &= processor.apply(line);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
});
|
||||
processor_thread.start();
|
||||
return processor_thread;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the operation from a {@link BaseProject}.
|
||||
*
|
||||
* @param project the project to configure the operation from
|
||||
* @since 1.5
|
||||
*/
|
||||
abstract public T fromProject(BaseProject project);
|
||||
|
||||
/**
|
||||
* Provides the work directory in which the operation will be performed.
|
||||
* <p>
|
||||
* If no work directory is provided, the JVM working directory will be used.
|
||||
*
|
||||
* @param directory the directory to use as a work directory
|
||||
* @return this operation instance
|
||||
* @since 1.5
|
||||
*/
|
||||
public T workDirectory(File directory) {
|
||||
if (!directory.exists()) {
|
||||
throw new OperationOptionException("ERROR: The work directory '" + directory + "' doesn't exist.");
|
||||
}
|
||||
if (!directory.isDirectory()) {
|
||||
throw new OperationOptionException("ERROR: '" + directory + "' is not a directory.");
|
||||
}
|
||||
if (!directory.canWrite()) {
|
||||
throw new OperationOptionException("ERROR: The work directory '" + directory + "' is not writable.");
|
||||
}
|
||||
|
||||
workDirectory_ = directory;
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the name of the tool to use for {@code java} execution.
|
||||
* <p>
|
||||
* If no java tool is provided {@code java} will be used.
|
||||
*
|
||||
* @param tool the name of the java tool
|
||||
* @return this operation instance
|
||||
* @since 1.5
|
||||
*/
|
||||
public T javaTool(String tool) {
|
||||
javaTool_ = tool;
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the options to provide to the java tool.
|
||||
*
|
||||
* @param options the java tool's options
|
||||
* @return this operation instance
|
||||
* @since 1.5
|
||||
*/
|
||||
public T javaOptions(List<String> options) {
|
||||
javaOptions_.addAll(options);
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides classpath entries to use for the operation.
|
||||
*
|
||||
* @param classpath classpath entries for the operation
|
||||
* @return this operation instance
|
||||
* @since 1.5.18
|
||||
*/
|
||||
public T classpath(String... classpath) {
|
||||
classpath_.addAll(List.of(classpath));
|
||||
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 1.5
|
||||
*/
|
||||
public T classpath(List<String> classpath) {
|
||||
classpath_.addAll(classpath);
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the main class to launch with the java tool.
|
||||
*
|
||||
* @param name the main class to launch
|
||||
* @return this operation instance
|
||||
* @since 1.5
|
||||
*/
|
||||
public T mainClass(String name) {
|
||||
mainClass_ = name;
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the processor that will be used to handle the process output.
|
||||
* <p>
|
||||
* It will be called for each line in the output.
|
||||
*
|
||||
* @param processor the output processor
|
||||
* @return this operation instance
|
||||
* @since 1.5.1
|
||||
*/
|
||||
public T outputProcessor(Function<String, Boolean> processor) {
|
||||
outputProcessor_ = processor;
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the processor that will be used to handle the process errors.
|
||||
* <p>
|
||||
* It will be called for each line in the error output.
|
||||
*
|
||||
* @param processor the error processor
|
||||
* @return this operation instance
|
||||
* @since 1.5.1
|
||||
*/
|
||||
public T errorProcessor(Function<String, Boolean> processor) {
|
||||
errorProcessor_ = processor;
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the work directory in which the operation will be performed.
|
||||
*
|
||||
* @return the directory to use as a work directory
|
||||
* @since 1.5
|
||||
*/
|
||||
public File workDirectory() {
|
||||
return workDirectory_;
|
||||
}
|
||||
|
||||
/**
|
||||
* retrieves the name of the tool to use for {@code java} execution.
|
||||
*
|
||||
* @return the name of the java tool
|
||||
* @since 1.5
|
||||
*/
|
||||
public String javaTool() {
|
||||
return javaTool_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the options to provide to the java tool.
|
||||
* <p>
|
||||
* This is a modifiable list that can be retrieved and changed.
|
||||
*
|
||||
* @return the java tool's options
|
||||
* @since 1.5
|
||||
*/
|
||||
public JavaOptions javaOptions() {
|
||||
return javaOptions_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the classpath to use for the operation.
|
||||
* <p>
|
||||
* This is a modifiable list that can be retrieved and changed.
|
||||
*
|
||||
* @return the operation's classpath
|
||||
* @since 1.5
|
||||
*/
|
||||
public List<String> classpath() {
|
||||
return classpath_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the main class to launch with the java tool.
|
||||
*
|
||||
* @return the main class to launch
|
||||
* @since 1.5
|
||||
*/
|
||||
public String mainClass() {
|
||||
return mainClass_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the processor that is used to handle the process output.
|
||||
*
|
||||
* @return the output processor
|
||||
* @since 1.5.1
|
||||
*/
|
||||
public Function<String, Boolean> outputProcessor() {
|
||||
return outputProcessor_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the processor that is used to handle the process errors.
|
||||
*
|
||||
* @return the error processor
|
||||
* @since 1.5.1
|
||||
*/
|
||||
public Function<String, Boolean> errorProcessor() {
|
||||
return errorProcessor_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the process that was used for the execution.
|
||||
*
|
||||
* @return the process that was executed
|
||||
* @since 1.5
|
||||
*/
|
||||
public Process process() {
|
||||
return process_;
|
||||
}
|
||||
}
|
101
src/main/java/rife/bld/operations/CleanOperation.java
Normal file
101
src/main/java/rife/bld/operations/CleanOperation.java
Normal file
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* 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.BaseProject;
|
||||
import rife.bld.Project;
|
||||
import rife.tools.FileUtils;
|
||||
import rife.tools.exceptions.FileUtilsErrorException;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Cleans by deleting a list of directories and all their contents.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5
|
||||
*/
|
||||
public class CleanOperation extends AbstractOperation<CleanOperation> {
|
||||
private final List<File> directories_ = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Performs the clean operation.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public void execute() {
|
||||
for (var directory : directories()) {
|
||||
executeCleanDirectory(directory);
|
||||
}
|
||||
if (!silent()) {
|
||||
System.out.println("Cleaning finished successfully.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Part of the {@link #execute} operation, cleans an individual directory.
|
||||
*
|
||||
* @param directory the directory to clean.
|
||||
* @since 1.5
|
||||
*/
|
||||
protected void executeCleanDirectory(File directory) {
|
||||
try {
|
||||
FileUtils.deleteDirectory(directory);
|
||||
} catch (FileUtilsErrorException e) {
|
||||
// no-op
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures a clean operation from a {@link BaseProject}.
|
||||
*
|
||||
* @param project the project to configure the clean operation from
|
||||
* @since 1.5
|
||||
*/
|
||||
public CleanOperation fromProject(BaseProject project) {
|
||||
return directories(project.buildDirectory()
|
||||
.listFiles(f -> !f.equals(project.buildBldDirectory())));
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides directories to clean.
|
||||
*
|
||||
* @param directories directories to clean
|
||||
* @return this operation instance
|
||||
* @since 1.5.18
|
||||
*/
|
||||
public CleanOperation directories(File... directories) {
|
||||
directories_.addAll(List.of(directories));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a list of directories to clean.
|
||||
* <p>
|
||||
* A copy will be created to allow this list to be independently modifiable.
|
||||
*
|
||||
* @param directories a list of directories to clean
|
||||
* @return this operation instance
|
||||
* @since 1.5
|
||||
*/
|
||||
public CleanOperation directories(List<File> directories) {
|
||||
directories_.addAll(directories);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the list of directories to clean.
|
||||
* <p>
|
||||
* This is a modifiable list that can be retrieved and changed.
|
||||
*
|
||||
* @return the list of directories to clean.
|
||||
* @since 1.5
|
||||
*/
|
||||
public List<File> directories() {
|
||||
return directories_;
|
||||
}
|
||||
}
|
480
src/main/java/rife/bld/operations/CompileOperation.java
Normal file
480
src/main/java/rife/bld/operations/CompileOperation.java
Normal file
|
@ -0,0 +1,480 @@
|
|||
/*
|
||||
* 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.BaseProject;
|
||||
import rife.bld.Project;
|
||||
import rife.bld.operations.exceptions.ExitStatusException;
|
||||
import rife.tools.FileUtils;
|
||||
|
||||
import javax.tools.*;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Compiles main and test sources in the relevant build directories.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5
|
||||
*/
|
||||
public class CompileOperation extends AbstractOperation<CompileOperation> {
|
||||
private File buildMainDirectory_;
|
||||
private File buildTestDirectory_;
|
||||
private final List<String> compileMainClasspath_ = new ArrayList<>();
|
||||
private final List<String> compileTestClasspath_ = new ArrayList<>();
|
||||
private final List<File> mainSourceFiles_ = new ArrayList<>();
|
||||
private final List<File> testSourceFiles_ = new ArrayList<>();
|
||||
private final List<File> mainSourceDirectories_ = new ArrayList<>();
|
||||
private final List<File> testSourceDirectories_ = new ArrayList<>();
|
||||
private final JavacOptions compileOptions_ = new JavacOptions();
|
||||
private final List<Diagnostic<? extends JavaFileObject>> diagnostics_ = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Performs the compile operation.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public void execute()
|
||||
throws IOException, ExitStatusException {
|
||||
executeCreateBuildDirectories();
|
||||
executeBuildMainSources();
|
||||
executeBuildTestSources();
|
||||
if (!diagnostics().isEmpty()) {
|
||||
throw new ExitStatusException(ExitStatusException.EXIT_FAILURE);
|
||||
}
|
||||
if (!silent()) {
|
||||
System.out.println("Compilation finished successfully.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Part of the {@link #execute} operation, creates the build directories.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
protected void executeCreateBuildDirectories() {
|
||||
if (buildMainDirectory() != null) {
|
||||
buildMainDirectory().mkdirs();
|
||||
}
|
||||
if (buildTestDirectory() != null) {
|
||||
buildTestDirectory().mkdirs();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Part of the {@link #execute} operation, builds the main sources.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
protected void executeBuildMainSources()
|
||||
throws IOException {
|
||||
var sources = new ArrayList<>(mainSourceFiles());
|
||||
for (var directory : mainSourceDirectories()) {
|
||||
sources.addAll(FileUtils.getJavaFileList(directory));
|
||||
}
|
||||
executeBuildSources(
|
||||
compileMainClasspath(),
|
||||
sources,
|
||||
buildMainDirectory());
|
||||
}
|
||||
|
||||
/**
|
||||
* Part of the {@link #execute} operation, builds the test sources.
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
protected void executeBuildTestSources()
|
||||
throws IOException {
|
||||
var sources = new ArrayList<>(testSourceFiles());
|
||||
for (var directory : testSourceDirectories()) {
|
||||
sources.addAll(FileUtils.getJavaFileList(directory));
|
||||
}
|
||||
executeBuildSources(
|
||||
compileTestClasspath(),
|
||||
sources,
|
||||
buildTestDirectory());
|
||||
}
|
||||
|
||||
/**
|
||||
* Part of the {@link #execute} operation, build sources to a destination.
|
||||
*
|
||||
* @param classpath the classpath list used for the compilation
|
||||
* @param sources the source files to compile
|
||||
* @param destination the destination directory
|
||||
* @since 1.5
|
||||
*/
|
||||
protected void executeBuildSources(List<String> classpath, List<File> sources, File destination)
|
||||
throws IOException {
|
||||
if (sources.isEmpty() || destination == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
var compiler = ToolProvider.getSystemJavaCompiler();
|
||||
try (var file_manager = compiler.getStandardFileManager(null, null, null)) {
|
||||
var compilation_units = file_manager.getJavaFileObjectsFromFiles(sources);
|
||||
var diagnostics = new DiagnosticCollector<JavaFileObject>();
|
||||
var options = new ArrayList<>(List.of("-d", destination.getAbsolutePath(), "-cp", FileUtils.joinPaths(classpath)));
|
||||
options.addAll(compileOptions());
|
||||
var compilation_task = compiler.getTask(null, file_manager, diagnostics, options, null, compilation_units);
|
||||
if (!compilation_task.call()) {
|
||||
diagnostics_.addAll(diagnostics.getDiagnostics());
|
||||
executeProcessDiagnostics(diagnostics);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Part of the {@link #execute} operation, processes the compilation diagnostics.
|
||||
*
|
||||
* @param diagnostics the diagnostics to process
|
||||
* @since 1.5
|
||||
*/
|
||||
protected void executeProcessDiagnostics(DiagnosticCollector<JavaFileObject> diagnostics) {
|
||||
for (var diagnostic : diagnostics.getDiagnostics()) {
|
||||
System.err.print(executeFormatDiagnostic(diagnostic));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Part of the {@link #execute} operation, format a single diagnostic.
|
||||
*
|
||||
* @param diagnostic the diagnostic to format
|
||||
* @return a string representation of the diagnostic
|
||||
* @since 1.5
|
||||
*/
|
||||
protected String executeFormatDiagnostic(Diagnostic<? extends JavaFileObject> diagnostic) {
|
||||
return diagnostic.toString() + System.lineSeparator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures a compile operation from a {@link BaseProject}.
|
||||
*
|
||||
* @param project the project to configure the compile operation from
|
||||
* @since 1.5
|
||||
*/
|
||||
public CompileOperation fromProject(BaseProject project) {
|
||||
var operation = buildMainDirectory(project.buildMainDirectory())
|
||||
.buildTestDirectory(project.buildTestDirectory())
|
||||
.compileMainClasspath(project.compileMainClasspath())
|
||||
.compileTestClasspath(project.compileTestClasspath())
|
||||
.mainSourceFiles(project.mainSourceFiles())
|
||||
.testSourceFiles(project.testSourceFiles());
|
||||
if (project.javaRelease() != null && !compileOptions().containsRelease()) {
|
||||
compileOptions().release(project.javaRelease());
|
||||
}
|
||||
return operation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the main build destination directory.
|
||||
*
|
||||
* @param directory the directory to use for the main build destination
|
||||
* @return this operation instance
|
||||
* @since 1.5
|
||||
*/
|
||||
public CompileOperation buildMainDirectory(File directory) {
|
||||
buildMainDirectory_ = directory;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the test build destination directory.
|
||||
*
|
||||
* @param directory the directory to use for the test build destination
|
||||
* @return this operation instance
|
||||
* @since 1.5
|
||||
*/
|
||||
public CompileOperation buildTestDirectory(File directory) {
|
||||
buildTestDirectory_ = directory;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides entries for the main compilation classpath.
|
||||
*
|
||||
* @param classpath classpath entries
|
||||
* @return this operation instance
|
||||
* @since 1.5.18
|
||||
*/
|
||||
public CompileOperation compileMainClasspath(String... classpath) {
|
||||
compileMainClasspath_.addAll(Arrays.asList(classpath));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a list of entries for the main compilation classpath.
|
||||
* <p>
|
||||
* A copy will be created to allow this list to be independently modifiable.
|
||||
*
|
||||
* @param classpath a list of classpath entries
|
||||
* @return this operation instance
|
||||
* @since 1.5
|
||||
*/
|
||||
public CompileOperation compileMainClasspath(List<String> classpath) {
|
||||
compileMainClasspath_.addAll(classpath);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides entries for the test compilation classpath.
|
||||
*
|
||||
* @param classpath classpath entries
|
||||
* @return this operation instance
|
||||
* @since 1.5.18
|
||||
*/
|
||||
public CompileOperation compileTestClasspath(String... classpath) {
|
||||
compileTestClasspath_.addAll(Arrays.asList(classpath));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a list of entries for the test compilation classpath.
|
||||
* <p>
|
||||
* A copy will be created to allow this list to be independently modifiable.
|
||||
*
|
||||
* @param classpath a list of classpath entries
|
||||
* @return this operation instance
|
||||
* @since 1.5
|
||||
*/
|
||||
public CompileOperation compileTestClasspath(List<String> classpath) {
|
||||
compileTestClasspath_.addAll(classpath);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides main files that should be compiled.
|
||||
*
|
||||
* @param files main files
|
||||
* @return this operation instance
|
||||
* @since 1.5.18
|
||||
*/
|
||||
public CompileOperation mainSourceFiles(File... files) {
|
||||
mainSourceFiles_.addAll(Arrays.asList(files));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a list of main files that should be compiled.
|
||||
* <p>
|
||||
* A copy will be created to allow this list to be independently modifiable.
|
||||
*
|
||||
* @param files a list of main files
|
||||
* @return this operation instance
|
||||
* @since 1.5
|
||||
*/
|
||||
public CompileOperation mainSourceFiles(List<File> files) {
|
||||
mainSourceFiles_.addAll(files);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides test files that should be compiled.
|
||||
*
|
||||
* @param files test files
|
||||
* @return this operation instance
|
||||
* @since 1.5.18
|
||||
*/
|
||||
public CompileOperation testSourceFiles(File... files) {
|
||||
testSourceFiles_.addAll(Arrays.asList(files));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a list of test files that should be compiled.
|
||||
* <p>
|
||||
* A copy will be created to allow this list to be independently modifiable.
|
||||
*
|
||||
* @param files a list of test files
|
||||
* @return this operation instance
|
||||
* @since 1.5
|
||||
*/
|
||||
public CompileOperation testSourceFiles(List<File> files) {
|
||||
testSourceFiles_.addAll(files);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides main source directories that should be compiled.
|
||||
*
|
||||
* @param directories main source directories
|
||||
* @return this operation instance
|
||||
* @since 1.5.10
|
||||
*/
|
||||
public CompileOperation mainSourceDirectories(File... directories) {
|
||||
mainSourceDirectories_.addAll(List.of(directories));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a list of main source directories that should be compiled.
|
||||
* <p>
|
||||
* A copy will be created to allow this list to be independently modifiable.
|
||||
*
|
||||
* @param directories a list of main source directories
|
||||
* @return this operation instance
|
||||
* @since 1.5.10
|
||||
*/
|
||||
public CompileOperation mainSourceDirectories(List<File> directories) {
|
||||
mainSourceDirectories_.addAll(directories);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides test source directories that should be compiled.
|
||||
*
|
||||
* @param directories test source directories
|
||||
* @return this operation instance
|
||||
* @since 1.5.10
|
||||
*/
|
||||
public CompileOperation testSourceDirectories(File... directories) {
|
||||
testSourceDirectories_.addAll(List.of(directories));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a list of test source directories that should be compiled.
|
||||
* <p>
|
||||
* A copy will be created to allow this list to be independently modifiable.
|
||||
*
|
||||
* @param directories a list of test source directories
|
||||
* @return this operation instance
|
||||
* @since 1.5.10
|
||||
*/
|
||||
public CompileOperation testSourceDirectories(List<File> directories) {
|
||||
testSourceDirectories_.addAll(directories);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a list of compilation options to provide to the compiler.
|
||||
* <p>
|
||||
* A copy will be created to allow this list to be independently modifiable.
|
||||
*
|
||||
* @param options the list of compilation options
|
||||
* @return this operation instance
|
||||
* @since 1.5
|
||||
*/
|
||||
public CompileOperation compileOptions(List<String> options) {
|
||||
compileOptions_.addAll(options);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the main build destination directory.
|
||||
*
|
||||
* @return the main build destination
|
||||
* @since 1.5
|
||||
*/
|
||||
public File buildMainDirectory() {
|
||||
return buildMainDirectory_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the test build destination directory.
|
||||
*
|
||||
* @return the test build destination
|
||||
* @since 1.5
|
||||
*/
|
||||
public File buildTestDirectory() {
|
||||
return buildTestDirectory_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the list of entries for the main compilation classpath.
|
||||
* <p>
|
||||
* This is a modifiable list that can be retrieved and changed.
|
||||
*
|
||||
* @return the main compilation classpath list
|
||||
* @since 1.5
|
||||
*/
|
||||
public List<String> compileMainClasspath() {
|
||||
return compileMainClasspath_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the list of entries for the test compilation classpath.
|
||||
* <p>
|
||||
* This is a modifiable list that can be retrieved and changed.
|
||||
*
|
||||
* @return the test compilation classpath list
|
||||
* @since 1.5
|
||||
*/
|
||||
public List<String> compileTestClasspath() {
|
||||
return compileTestClasspath_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the list of main files that should be compiled.
|
||||
* <p>
|
||||
* This is a modifiable list that can be retrieved and changed.
|
||||
*
|
||||
* @return the list of main files to compile
|
||||
* @since 1.5
|
||||
*/
|
||||
public List<File> mainSourceFiles() {
|
||||
return mainSourceFiles_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the list of test files that should be compiled.
|
||||
* <p>
|
||||
* This is a modifiable list that can be retrieved and changed.
|
||||
*
|
||||
* @return the list of test files to compile
|
||||
* @since 1.5
|
||||
*/
|
||||
public List<File> testSourceFiles() {
|
||||
return testSourceFiles_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the list of main source directories that should be compiled.
|
||||
* <p>
|
||||
* This is a modifiable list that can be retrieved and changed.
|
||||
*
|
||||
* @return the list of main source directories to compile
|
||||
* @since 1.5.10
|
||||
*/
|
||||
public List<File> mainSourceDirectories() {
|
||||
return mainSourceDirectories_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the list of test source directories that should be compiled.
|
||||
* <p>
|
||||
* This is a modifiable list that can be retrieved and changed.
|
||||
*
|
||||
* @return the list of test source directories to compile
|
||||
* @since 1.5.10
|
||||
*/
|
||||
public List<File> testSourceDirectories() {
|
||||
return testSourceDirectories_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the list of compilation options for the compiler.
|
||||
* <p>
|
||||
* This is a modifiable list that can be retrieved and changed.
|
||||
*
|
||||
* @return the list of compiler options
|
||||
* @since 1.5
|
||||
*/
|
||||
public JavacOptions compileOptions() {
|
||||
return compileOptions_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the list of diagnostics resulting from the compilation.
|
||||
*
|
||||
* @return the list of compilation diagnostics
|
||||
* @since 1.5
|
||||
*/
|
||||
public List<Diagnostic<? extends JavaFileObject>> diagnostics() {
|
||||
return diagnostics_;
|
||||
}
|
||||
}
|
26
src/main/java/rife/bld/operations/CreateBaseOperation.java
Normal file
26
src/main/java/rife/bld/operations/CreateBaseOperation.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.BaseProjectBlueprint;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Creates a new base project structure.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5.20
|
||||
*/
|
||||
public class CreateBaseOperation extends AbstractCreateOperation<CreateBaseOperation, Project> {
|
||||
public CreateBaseOperation() {
|
||||
super("bld.base.");
|
||||
}
|
||||
|
||||
protected Project createProjectBlueprint() {
|
||||
return new BaseProjectBlueprint(new File(workDirectory(), projectName()), packageName(), projectName());
|
||||
}
|
||||
}
|
26
src/main/java/rife/bld/operations/CreateBlankOperation.java
Normal file
26
src/main/java/rife/bld/operations/CreateBlankOperation.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.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());
|
||||
}
|
||||
}
|
35
src/main/java/rife/bld/operations/CreateLibOperation.java
Normal file
35
src/main/java/rife/bld/operations/CreateLibOperation.java
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* 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.BaseProjectBlueprint;
|
||||
import rife.bld.blueprints.LibProjectBlueprint;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Creates a new lib project structure.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.6
|
||||
*/
|
||||
public class CreateLibOperation extends AbstractCreateOperation<CreateLibOperation, Project> {
|
||||
public CreateLibOperation() {
|
||||
super("bld.lib.");
|
||||
}
|
||||
|
||||
protected Project createProjectBlueprint() {
|
||||
return new LibProjectBlueprint(new File(workDirectory(), projectName()), packageName(), projectName());
|
||||
}
|
||||
|
||||
protected String projectMainClassName(String projectClassName) {
|
||||
return projectClassName + "Lib";
|
||||
}
|
||||
|
||||
protected boolean createIdeaRunMain() {
|
||||
return false;
|
||||
}
|
||||
}
|
92
src/main/java/rife/bld/operations/CreateRife2Operation.java
Normal file
92
src/main/java/rife/bld/operations/CreateRife2Operation.java
Normal file
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* 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.blueprints.Rife2ProjectBlueprint;
|
||||
import rife.bld.dependencies.*;
|
||||
import rife.template.TemplateFactory;
|
||||
import rife.tools.FileUtils;
|
||||
import rife.tools.exceptions.FileUtilsErrorException;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Creates a new RIFE2 project structure.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5
|
||||
*/
|
||||
public class CreateRife2Operation extends AbstractCreateOperation<CreateRife2Operation, Rife2ProjectBlueprint> {
|
||||
File srcMainWebappCssDirectory_;
|
||||
File srcMainWebappWebInfDirectory_;
|
||||
|
||||
public CreateRife2Operation() {
|
||||
super("bld.rife2_hello.");
|
||||
}
|
||||
|
||||
protected Rife2ProjectBlueprint createProjectBlueprint() {
|
||||
return new Rife2ProjectBlueprint(new File(workDirectory(), projectName()), packageName(), projectName());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void executeConfigure() {
|
||||
super.executeConfigure();
|
||||
|
||||
projectMainName_ = projectClassName_ + "Site";
|
||||
projectMainUberName_ = projectMainName_ + "Uber";
|
||||
srcMainWebappCssDirectory_ = new File(project_.srcMainWebappDirectory(), "css");
|
||||
srcMainWebappWebInfDirectory_ = new File(project_.srcMainWebappDirectory(), "WEB-INF");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void executeCreateProjectStructure() {
|
||||
super.executeCreateProjectStructure();
|
||||
|
||||
srcMainWebappCssDirectory_.mkdirs();
|
||||
srcMainWebappWebInfDirectory_.mkdirs();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void executePopulateProjectStructure()
|
||||
throws FileUtilsErrorException, IOException {
|
||||
super.executePopulateProjectStructure();
|
||||
|
||||
// project site uber
|
||||
var main_uber_template = TemplateFactory.TXT.get(templateBase_ + "project_main_uber");
|
||||
main_uber_template.setValue("package", project_.pkg());
|
||||
main_uber_template.setValue("projectMain", projectMainName_);
|
||||
main_uber_template.setValue("projectMainUber", projectMainUberName_);
|
||||
var project_main_uber_file = new File(mainPackageDirectory_, projectMainUberName_ + ".java");
|
||||
FileUtils.writeString(main_uber_template.getContent(), project_main_uber_file);
|
||||
|
||||
// project template
|
||||
var template_template = TemplateFactory.HTML.get(templateBase_ + "project_template");
|
||||
template_template.setValue("project", projectClassName_);
|
||||
var project_template_file = new File(project_.srcMainResourcesTemplatesDirectory(), "hello.html");
|
||||
FileUtils.writeString(template_template.getContent(), project_template_file);
|
||||
|
||||
// project css
|
||||
FileUtils.writeString(
|
||||
TemplateFactory.TXT.get(templateBase_ + "project_style").getContent(),
|
||||
new File(srcMainWebappCssDirectory_, "style.css"));
|
||||
|
||||
// project web.xml
|
||||
var web_xml_template = TemplateFactory.XML.get(templateBase_ + "project_web");
|
||||
web_xml_template.setValue("package", project_.pkg());
|
||||
web_xml_template.setValue("projectMain", projectMainName_);
|
||||
var project_web_xml_file = new File(srcMainWebappWebInfDirectory_, "web.xml");
|
||||
FileUtils.writeString(web_xml_template.getContent(), project_web_xml_file);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void executePopulateIdeaProject()
|
||||
throws FileUtilsErrorException {
|
||||
super.executePopulateIdeaProject();
|
||||
FileUtils.writeString(
|
||||
TemplateFactory.XML.get(templateBase_ + "idea.libraries.standalone").getContent(),
|
||||
new File(ideaLibrariesDirectory_, "standalone.xml"));
|
||||
}
|
||||
}
|
181
src/main/java/rife/bld/operations/DependencyTreeOperation.java
Normal file
181
src/main/java/rife/bld/operations/DependencyTreeOperation.java
Normal file
|
@ -0,0 +1,181 @@
|
|||
/*
|
||||
* 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.BaseProject;
|
||||
import rife.bld.dependencies.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static rife.bld.dependencies.Scope.compile;
|
||||
import static rife.bld.dependencies.Scope.runtime;
|
||||
|
||||
/**
|
||||
* Transitively generates a hierarchical tree of dependencies.
|
||||
*
|
||||
* @author Geert Bevin (gbevin[remove] at uwyn dot com)
|
||||
* @since 1.5.21
|
||||
*/
|
||||
public class DependencyTreeOperation extends AbstractOperation<DependencyTreeOperation> {
|
||||
private ArtifactRetriever retriever_ = null;
|
||||
private final List<Repository> repositories_ = new ArrayList<>();
|
||||
private final DependencyScopes dependencies_ = new DependencyScopes();
|
||||
private final StringBuilder dependencyTree_ = new StringBuilder();
|
||||
|
||||
/**
|
||||
* Performs the dependency tree operation.
|
||||
*
|
||||
* @since 1.5.21
|
||||
*/
|
||||
public void execute() {
|
||||
var compile_tree = executeGenerateCompileDependencies();
|
||||
var runtime_tree = executeGenerateRuntimeDependencies();
|
||||
dependencyTree_.setLength(0);
|
||||
dependencyTree_.append(compile_tree);
|
||||
dependencyTree_.append(System.lineSeparator());
|
||||
dependencyTree_.append(runtime_tree);
|
||||
dependencyTree_.append(System.lineSeparator());
|
||||
|
||||
System.out.println(compile_tree);
|
||||
System.out.println(runtime_tree);
|
||||
}
|
||||
|
||||
/**
|
||||
* Part of the {@link #execute} operation, generates the tree for the compile scope.
|
||||
*
|
||||
* @since 1.5.21
|
||||
*/
|
||||
protected String executeGenerateCompileDependencies() {
|
||||
var compile_tree = dependencies().scope(compile).generateTransitiveDependencyTree(artifactRetriever(), repositories(), compile);
|
||||
if (compile_tree.isEmpty()) {
|
||||
compile_tree = "no dependencies" + System.lineSeparator();
|
||||
}
|
||||
return "compile:" + System.lineSeparator() + compile_tree;
|
||||
}
|
||||
|
||||
/**
|
||||
* Part of the {@link #execute} operation, generates the tree for the runtime scope.
|
||||
*
|
||||
* @since 1.5.21
|
||||
*/
|
||||
protected String executeGenerateRuntimeDependencies() {
|
||||
var runtime_tree = dependencies().scope(runtime).generateTransitiveDependencyTree(artifactRetriever(), repositories(), compile, runtime);
|
||||
if (runtime_tree.isEmpty()) {
|
||||
runtime_tree = "no dependencies" + System.lineSeparator();
|
||||
}
|
||||
return "runtime:" + System.lineSeparator() + runtime_tree;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Configures a dependency tree operation from a {@link BaseProject}.
|
||||
*
|
||||
* @param project the project to configure the operation from
|
||||
* @since 1.5.21
|
||||
*/
|
||||
public DependencyTreeOperation fromProject(BaseProject project) {
|
||||
return artifactRetriever(project.artifactRetriever())
|
||||
.repositories(project.repositories())
|
||||
.dependencies(project.dependencies());
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides repositories to resolve the dependencies against.
|
||||
*
|
||||
* @param repositories repositories against which dependencies will be resolved
|
||||
* @return this operation instance
|
||||
* @since 1.5.21
|
||||
*/
|
||||
public DependencyTreeOperation repositories(Repository... repositories) {
|
||||
repositories_.addAll(List.of(repositories));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a list of repositories to resolve the dependencies against.
|
||||
* <p>
|
||||
* A copy will be created to allow this list to be independently modifiable.
|
||||
*
|
||||
* @param repositories a list of repositories against which dependencies will be resolved
|
||||
* @return this operation instance
|
||||
* @since 1.5.21
|
||||
*/
|
||||
public DependencyTreeOperation repositories(List<Repository> repositories) {
|
||||
repositories_.addAll(repositories);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides scoped dependencies to generate a tree for.
|
||||
*
|
||||
* @param dependencies the dependencies that will be resolved for tree generation
|
||||
* @return this operation instance
|
||||
* @since 1.5.21
|
||||
*/
|
||||
public DependencyTreeOperation dependencies(DependencyScopes dependencies) {
|
||||
dependencies_.include(dependencies);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the artifact retriever to use.
|
||||
*
|
||||
* @param retriever the artifact retriever
|
||||
* @return this operation instance
|
||||
* @since 1.5.21
|
||||
*/
|
||||
public DependencyTreeOperation artifactRetriever(ArtifactRetriever retriever) {
|
||||
retriever_ = retriever;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the repositories in which the dependencies will be resolved.
|
||||
* <p>
|
||||
* This is a modifiable list that can be retrieved and changed.
|
||||
*
|
||||
* @return the repositories used for dependency resolution
|
||||
* @since 1.5.21
|
||||
*/
|
||||
public List<Repository> repositories() {
|
||||
return repositories_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the scoped dependencies that will be used for tree generation.
|
||||
* <p>
|
||||
* This is a modifiable structure that can be retrieved and changed.
|
||||
*
|
||||
* @return the scoped dependencies
|
||||
* @since 1.5.21
|
||||
*/
|
||||
public DependencyScopes dependencies() {
|
||||
return dependencies_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the artifact retriever that is used.
|
||||
*
|
||||
* @return the artifact retriever
|
||||
* @since 1.5.21
|
||||
*/
|
||||
public ArtifactRetriever artifactRetriever() {
|
||||
if (retriever_ == null) {
|
||||
return ArtifactRetriever.instance();
|
||||
}
|
||||
return retriever_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last generated dependency tree.
|
||||
*
|
||||
* @return the last generated dependency tree
|
||||
* @since 1.5.21
|
||||
*/
|
||||
public String dependencyTree() {
|
||||
return dependencyTree_.toString();
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue