mirror of
https://github.com/HighCapable/SweetProperty.git
synced 2025-09-06 10:45:51 +08:00
Compare commits
17 Commits
Author | SHA1 | Date | |
---|---|---|---|
fb7682d963
|
|||
9a91fdb0bf
|
|||
4ab7eef69c
|
|||
180f475562
|
|||
9e2c26ae73
|
|||
f66cdc1f31
|
|||
2e73f36bf0
|
|||
8594bca9a6
|
|||
8cc09e7fcd
|
|||
6297cb9919
|
|||
c982fec8c5
|
|||
eff8560bd2
|
|||
eead3c8839
|
|||
e113c45a5d
|
|||
6a0c581ccb
|
|||
62207002c4
|
|||
8747853310
|
202
LICENSE
Normal file
202
LICENSE
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 HighCapable [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
|
||||||
|
|
||||||
|
https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
@@ -1,8 +1,8 @@
|
|||||||
# Sweet Property
|
# Sweet Property
|
||||||
|
|
||||||
[](https://github.com/HighCapable/SweetProperty/blob/master/LICENSE)
|
[](https://github.com/HighCapable/SweetProperty/blob/master/LICENSE)
|
||||||

|
[](https://github.com/HighCapable/SweetProperty/releases)
|
||||||
[](https://t.me/HighCapable_Dev)
|
[](https://t.me/HighCapable_Dev)
|
||||||
|
|
||||||
<img src="https://github.com/HighCapable/SweetProperty/blob/master/img-src/icon.png?raw=true" width = "100" height = "100" alt="LOGO"/>
|
<img src="https://github.com/HighCapable/SweetProperty/blob/master/img-src/icon.png?raw=true" width = "100" height = "100" alt="LOGO"/>
|
||||||
|
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
# Sweet Property
|
# Sweet Property
|
||||||
|
|
||||||
[](https://github.com/HighCapable/SweetProperty/blob/master/LICENSE)
|
[](https://github.com/HighCapable/SweetProperty/blob/master/LICENSE)
|
||||||

|
[](https://github.com/HighCapable/SweetProperty/releases)
|
||||||
[](https://t.me/HighCapable_Dev)
|
[](https://t.me/HighCapable_Dev)
|
||||||
|
|
||||||
<img src="https://github.com/HighCapable/SweetProperty/blob/master/img-src/icon.png?raw=true" width = "100" height = "100" alt="LOGO"/>
|
<img src="https://github.com/HighCapable/SweetProperty/blob/master/img-src/icon.png?raw=true" width = "100" height = "100" alt="LOGO"/>
|
||||||
|
|
||||||
|
@@ -2,4 +2,18 @@
|
|||||||
|
|
||||||
## 1.0.0 | 2023.09.03
|
## 1.0.0 | 2023.09.03
|
||||||
|
|
||||||
- 首个版本提交至 Maven
|
- 首个版本提交至 Maven
|
||||||
|
|
||||||
|
## 1.0.1 | 2023.09.04
|
||||||
|
|
||||||
|
- 新增启用 `isEnableTypeAutoConversion` 后可以使用 '' 或 "" 强制设置一个键值内容为字符串类型
|
||||||
|
- 修改生成的代码中属性键值的内容使用优化后的类型呈现
|
||||||
|
|
||||||
|
## 1.0.2 | 2023.09.07
|
||||||
|
|
||||||
|
- 使用 `net.lingala.zip4j` 取代 JDK 默认创建压缩文档功能修复在 Windows 平台中 Gradle 8.0.2+ 版本创建的 JAR 损坏导致找不到生成的 Class 问题
|
||||||
|
- 重构自动生成代码部分的装载功能,增加可能找不到 Class 的错误提示
|
||||||
|
- 作废了 ~~`propertiesFileName`~~ 方法
|
||||||
|
- 新增 `propertiesFileNames` 方法,现在你可以同时设置一组属性配置文件名称了
|
||||||
|
- 新增 `includeKeys` 方法,现在你可以设置仅包含的属性键值名称数组了
|
||||||
|
- 新增 `keyValuesRules` 方法,现在你可以在属性键值装载过程中修改键值内容的实际解析结果
|
@@ -2,4 +2,19 @@
|
|||||||
|
|
||||||
## 1.0.0 | 2023.09.03
|
## 1.0.0 | 2023.09.03
|
||||||
|
|
||||||
- The first version is submitted to Maven
|
- The first version is submitted to Maven
|
||||||
|
|
||||||
|
## 1.0.1 | 2023.09.04
|
||||||
|
|
||||||
|
- After enabling `isEnableTypeAutoConversion`, you can use '' or "" to force the content of a value to be a string type
|
||||||
|
- Modify the content of the properties key-values in the generated code to use the optimized type to render
|
||||||
|
|
||||||
|
## 1.0.2 | 2023.09.07
|
||||||
|
|
||||||
|
- Use `net.lingala.zip4j` to replace JDK's default function of creating compressed files and fix the problem that the JAR created by Gradle 8.0.2+
|
||||||
|
version on Windows platform is broken and the generated classes cannot be found
|
||||||
|
- Refactor the loading function of the automatically generated code part, and add an error message that classes may not be found
|
||||||
|
- Deprecated ~~`propertiesFileName`~~ method
|
||||||
|
- Added `propertiesFileNames` method, now you can set a group of properties file names at the same time
|
||||||
|
- Added `includeKeys` method, now you can set an array of properties key names to include only
|
||||||
|
- Added `keyValuesRules` method, now you can modify the actual parsing result of the value content during the properties key-values loading process
|
@@ -70,23 +70,33 @@ sweetProperty {
|
|||||||
// 启用功能
|
// 启用功能
|
||||||
// 你可以分别对 "sourcesCode"、"buildScript" 进行设置
|
// 你可以分别对 "sourcesCode"、"buildScript" 进行设置
|
||||||
isEnable = true
|
isEnable = true
|
||||||
// 设置属性配置文件名称
|
|
||||||
// 一般情况下不需要修改此设置,错误的文件名将导致获取到空键值内容
|
|
||||||
// 如果你有一个自定义名称的属性键值文件,你可以修改这里的设置
|
|
||||||
// 注意:建议为每个项目单独配置,而不是在全局中修改,以防发生问题
|
|
||||||
propertiesFileName = "gradle.properties"
|
|
||||||
// 是否启用排除非字符串类型键值内容
|
// 是否启用排除非字符串类型键值内容
|
||||||
// 默认启用,启用后将从属性键值中排除不是字符串类型的键值及内容
|
// 默认启用,启用后将从属性键值中排除不是字符串类型的键值及内容
|
||||||
// 这可以排除例如一些系统环境变量的配置或内存中的数据
|
// 这可以排除例如一些系统环境变量的配置或内存中的数据
|
||||||
isEnableExcludeNonStringValue = true
|
isEnableExcludeNonStringValue = true
|
||||||
// 是否启用类型自动转换功能
|
// 是否启用类型自动转换功能
|
||||||
// 默认启用,启用后将自动识别属性键值中的类型并转换为对应的类型
|
// 默认启用,启用后将自动识别属性键值中的类型并转换为对应的类型
|
||||||
// 例如 "name=hello" 和 "number=1" 它们将会被自动转换为 String 和 Int
|
// 在启用后如果你想要强制设置一个键值内容为字符串类型,你可以使用单引号或双引号包裹整个字符串
|
||||||
|
// 注意:在关闭此功能后如上所述的功能也将同时失效
|
||||||
|
// 例如 name=hello 和 number=1 它们将会被自动转换为 String 和 Int
|
||||||
|
// 例如 stringNumber="1" 或 stringNumber='1' 它们将会被强制转换为 String
|
||||||
isEnableTypeAutoConversion = true
|
isEnableTypeAutoConversion = true
|
||||||
// 是否启用键值内容插值功能
|
// 是否启用键值内容插值功能
|
||||||
// 默认启用,启用后将自动识别属性键值内容中的 ${...} 内容并进行替换
|
// 默认启用,启用后将自动识别属性键值内容中的 ${...} 内容并进行替换
|
||||||
// 注意:插值的内容仅会从当前 (当前配置文件) 属性键值列表进行查找
|
// 注意:插值的内容仅会从当前 (当前配置文件) 属性键值列表进行查找
|
||||||
isEnableValueInterpolation = true
|
isEnableValueInterpolation = true
|
||||||
|
// 设置属性配置文件名称数组
|
||||||
|
// 属性配置文件将根据你设置的文件名称自动从当前根项目、子项目以及用户目录的根目录进行获取
|
||||||
|
// 你可以添加多组属性配置文件名称,将按照顺序依次进行读取
|
||||||
|
// 一般情况下不需要修改此设置,错误的文件名将导致获取到空键值内容
|
||||||
|
// 你可以配置 "isAddDefault" 参数来决定是否添加默认的 "gradle.properties" 文件名称
|
||||||
|
// 如果你有一个或多个自定义名称的属性键值文件,你可以修改这里的设置
|
||||||
|
// 注意:建议为每个项目单独配置,而不是在全局中修改,以防发生问题
|
||||||
|
propertiesFileNames(
|
||||||
|
"some_other_1.properties",
|
||||||
|
"some_other_2.properties",
|
||||||
|
isAddDefault = true
|
||||||
|
)
|
||||||
// 设置固定存在的属性键值数组
|
// 设置固定存在的属性键值数组
|
||||||
// 在这里可以设置一些一定存在的键值,这些键值无论能否从属性键值中得到都会进行生成
|
// 在这里可以设置一些一定存在的键值,这些键值无论能否从属性键值中得到都会进行生成
|
||||||
// 这些键值在属性键值存在时使用属性键值的内容,不存在时使用这里设置的内容
|
// 这些键值在属性键值存在时使用属性键值的内容,不存在时使用这里设置的内容
|
||||||
@@ -108,6 +118,21 @@ sweetProperty {
|
|||||||
"exclude.some.key1",
|
"exclude.some.key1",
|
||||||
"exclude.some.key2"
|
"exclude.some.key2"
|
||||||
)
|
)
|
||||||
|
// 设置需要包含的属性键值名称数组
|
||||||
|
// 在这里可以设置一些你希望从已知的属性键值中包含的键值名称
|
||||||
|
// 这些键值在属性键值存在它们时被包含,未被包含的键值不会出现在生成的代码中
|
||||||
|
// 你可以传入 Regex 或使用 String.toRegex 以使用正则功能
|
||||||
|
includeKeys(
|
||||||
|
"include.some.key1",
|
||||||
|
"include.some.key2"
|
||||||
|
)
|
||||||
|
// 设置属性键值规则数组
|
||||||
|
// 你可以设置一组键值规则,使用 "createValueRule" 创建新的规则,用于解析得到的键值内容
|
||||||
|
// 这些键值规则在属性键值存在它们时被应用
|
||||||
|
keyValuesRules(
|
||||||
|
"some.key1" to createValueRule { if (it.contains("_")) it.replace("_", "-") else it },
|
||||||
|
"some.key2" to createValueRule { "$it-value" }
|
||||||
|
)
|
||||||
// 设置从何处生成属性键值
|
// 设置从何处生成属性键值
|
||||||
// 默认为 "CURRENT_PROJECT" 和 "ROOT_PROJECT"
|
// 默认为 "CURRENT_PROJECT" 和 "ROOT_PROJECT"
|
||||||
// 你可以使用以下类型来进行设置
|
// 你可以使用以下类型来进行设置
|
||||||
|
@@ -73,11 +73,6 @@ sweetProperty {
|
|||||||
// Enable functionality
|
// Enable functionality
|
||||||
// You can set "sourcesCode" and "buildScript" respectively
|
// You can set "sourcesCode" and "buildScript" respectively
|
||||||
isEnable = true
|
isEnable = true
|
||||||
// Set properties name
|
|
||||||
// In general, you don't need to modify this setting, the wrong file name will lead to getting empty key-values content
|
|
||||||
// If you have a properties file with a custom name, you can modify the settings here
|
|
||||||
// Note: It is recommended to configure each project individually, rather than modifying globally, in case of problems
|
|
||||||
propertiesFileName = "gradle.properties"
|
|
||||||
// Whether to enable the exclusion of non-string type key-values content
|
// Whether to enable the exclusion of non-string type key-values content
|
||||||
// Enabled by default, when enabled, key-values and content that are not string types will be excluded from the properties key-values
|
// Enabled by default, when enabled, key-values and content that are not string types will be excluded from the properties key-values
|
||||||
// This can exclude e.g. configuration of some system environment variables or data in memory
|
// This can exclude e.g. configuration of some system environment variables or data in memory
|
||||||
@@ -85,14 +80,31 @@ sweetProperty {
|
|||||||
// Whether to enable the type automatic conversion function
|
// Whether to enable the type automatic conversion function
|
||||||
// Enabled by default, when enabled,
|
// Enabled by default, when enabled,
|
||||||
// the type in the properties key-values will be automatically recognized and converted to the corresponding type
|
// the type in the properties key-values will be automatically recognized and converted to the corresponding type
|
||||||
// For example "name=hello" and "number=1" they will be automatically converted to String and Int
|
// After enabling, if you want to force the content of a value to be a string type,
|
||||||
|
// you can use single quotes or double quotes to wrap the entire string
|
||||||
|
// Note: After turning off this function, the functions mentioned above will also become invalid at the same time
|
||||||
|
// For example name=hello and number=1 they will be automatically converted to String and Int
|
||||||
|
// For example stringNumber="1" or stringNumber='1' they will be coerced to String
|
||||||
isEnableTypeAutoConversion = true
|
isEnableTypeAutoConversion = true
|
||||||
// Whether to enable key-values content interpolation
|
// Whether to enable key-values content interpolation
|
||||||
// Enabled by default, after enabling, the ${...} content in the properties key-values content
|
// Enabled by default, after enabling, the ${...} content in the properties key-values content
|
||||||
// will be automatically recognized and replaced
|
// will be automatically recognized and replaced
|
||||||
// Note: The interpolated content will only be searching from the current (current configuration file) properties key-values list
|
// Note: The interpolated content will only be searching from the current (current configuration file) properties key-values list
|
||||||
isEnableValueInterpolation = true
|
isEnableValueInterpolation = true
|
||||||
// Set a fixed attribute key-value array
|
// Set properties names array
|
||||||
|
// The properties file will be automatically obtained from the root directory of
|
||||||
|
// the current root project, subproject and user directory according to the file name you set
|
||||||
|
// You can add multiple sets of properties file names, which will be read in order
|
||||||
|
// In general, you don't need to modify this setting, the wrong file name will lead to getting empty key-values content
|
||||||
|
// You can configure the "isAddDefault" parameter to decide whether to add the default "gradle.properties" file name
|
||||||
|
// If you have one or more properties files with custom names, you can modify the settings here
|
||||||
|
// Note: It is recommended to configure each project individually, rather than modifying globally, in case of problems
|
||||||
|
propertiesFileNames(
|
||||||
|
"some_other_1.properties",
|
||||||
|
"some_other_2.properties",
|
||||||
|
isAddDefault = true
|
||||||
|
)
|
||||||
|
// Set fixed properties key-values array
|
||||||
// Here you can set some key values that must exist,
|
// Here you can set some key values that must exist,
|
||||||
// and these key values will be generated regardless of whether they can be obtained from the properties key-values
|
// and these key values will be generated regardless of whether they can be obtained from the properties key-values
|
||||||
// These key-values use the content of the properties key-values when the properties key-values exists,
|
// These key-values use the content of the properties key-values when the properties key-values exists,
|
||||||
@@ -106,7 +118,7 @@ sweetProperty {
|
|||||||
"permanent.some.key1" to "some_value_1",
|
"permanent.some.key1" to "some_value_1",
|
||||||
"permanent.some.key2" to "some_value_2"
|
"permanent.some.key2" to "some_value_2"
|
||||||
)
|
)
|
||||||
// Set an array of properties key-values names that need to be excluded
|
// Set properties key-values array names that need to be excluded
|
||||||
// Here you can set some key names that you want to exclude from the known properties keys
|
// Here you can set some key names that you want to exclude from the known properties keys
|
||||||
// These keys are excluded when they exist in the properties keys and will not appear in the generated code
|
// These keys are excluded when they exist in the properties keys and will not appear in the generated code
|
||||||
// Note: If you exclude the key-values set in "permanentKeyValues",
|
// Note: If you exclude the key-values set in "permanentKeyValues",
|
||||||
@@ -116,6 +128,22 @@ sweetProperty {
|
|||||||
"exclude.some.key1",
|
"exclude.some.key1",
|
||||||
"exclude.some.key2"
|
"exclude.some.key2"
|
||||||
)
|
)
|
||||||
|
// Set properties key-values array names that need to be included
|
||||||
|
// Here you can set some key-values names that you want to include from known properties keys
|
||||||
|
// These keys are included when the properties key-values exists
|
||||||
|
// Key-values that are not included will not appear in the generated code
|
||||||
|
// You can pass in a Regex or use String.toRegex to use the regex function
|
||||||
|
includeKeys(
|
||||||
|
"include.some.key1",
|
||||||
|
"include.some.key2"
|
||||||
|
)
|
||||||
|
// Set properties key-values rules array
|
||||||
|
// You can set a set of key-values rules and use "createValueRule" to create new rules for parsing the obtained value content
|
||||||
|
// These key-values rules are applied when the properties key-values exists
|
||||||
|
keyValuesRules(
|
||||||
|
"some.key1" to createValueRule { if (it.contains("_")) it.replace("_", "-") else it },
|
||||||
|
"some.key2" to createValueRule { "$it-value" }
|
||||||
|
)
|
||||||
// Set where to generate properties key-values
|
// Set where to generate properties key-values
|
||||||
// Defaults to "CURRENT_PROJECT" and "ROOT_PROJECT"
|
// Defaults to "CURRENT_PROJECT" and "ROOT_PROJECT"
|
||||||
// You can use the following types to set
|
// You can use the following types to set
|
||||||
|
@@ -4,7 +4,7 @@ project.description=An easy get project properties anywhere Gradle plugin
|
|||||||
project.url=https://github.com/HighCapable/SweetProperty
|
project.url=https://github.com/HighCapable/SweetProperty
|
||||||
project.groupName=com.highcapable.sweetproperty
|
project.groupName=com.highcapable.sweetproperty
|
||||||
project.moduleName=sweet-property
|
project.moduleName=sweet-property
|
||||||
project.version=1.0.0
|
project.version=1.0.2
|
||||||
project.licence.name=Apache License 2.0
|
project.licence.name=Apache License 2.0
|
||||||
project.licence.url=https://github.com/HighCapable/SweetProperty/blob/master/LICENSE
|
project.licence.url=https://github.com/HighCapable/SweetProperty/blob/master/LICENSE
|
||||||
project.developer.id=0
|
project.developer.id=0
|
||||||
|
@@ -22,4 +22,7 @@ libraries:
|
|||||||
kotlinpoet:
|
kotlinpoet:
|
||||||
version: 1.14.2
|
version: 1.14.2
|
||||||
javapoet:
|
javapoet:
|
||||||
version: 1.13.0
|
version: 1.13.0
|
||||||
|
net.lingala.zip4j:
|
||||||
|
zip4j:
|
||||||
|
version: 2.11.5
|
@@ -8,8 +8,8 @@ pluginManagement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
plugins {
|
plugins {
|
||||||
id("com.highcapable.sweetdependency") version "1.0.0"
|
id("com.highcapable.sweetdependency") version "1.0.1"
|
||||||
id("com.highcapable.sweetproperty") version "1.0.0"
|
id("com.highcapable.sweetproperty") version "1.0.2"
|
||||||
}
|
}
|
||||||
sweetDependency {
|
sweetDependency {
|
||||||
isEnableVerboseMode = false
|
isEnableVerboseMode = false
|
||||||
|
@@ -23,6 +23,7 @@ kotlin {
|
|||||||
dependencies {
|
dependencies {
|
||||||
implementation(com.squareup.kotlinpoet)
|
implementation(com.squareup.kotlinpoet)
|
||||||
implementation(com.squareup.javapoet)
|
implementation(com.squareup.javapoet)
|
||||||
|
implementation(net.lingala.zip4j.zip4j)
|
||||||
}
|
}
|
||||||
|
|
||||||
gradlePlugin {
|
gradlePlugin {
|
||||||
|
@@ -67,4 +67,4 @@ internal fun Project.addDependencyToBuildScript(repositoryPath: String, pomData:
|
|||||||
* @param name [Class] 完整名称
|
* @param name [Class] 完整名称
|
||||||
* @return [Class]
|
* @return [Class]
|
||||||
*/
|
*/
|
||||||
internal fun Project.loadBuildScriptClass(name: String) = buildscript.classLoader.loadClass(name)
|
internal fun Project.loadBuildScriptClass(name: String) = runCatching { buildscript.classLoader.loadClass(name) }.getOrNull()
|
@@ -23,7 +23,7 @@ package com.highcapable.sweetproperty.plugin.config.default
|
|||||||
|
|
||||||
import com.highcapable.sweetproperty.plugin.config.proxy.ISweetPropertyConfigs
|
import com.highcapable.sweetproperty.plugin.config.proxy.ISweetPropertyConfigs
|
||||||
import com.highcapable.sweetproperty.plugin.extension.dsl.configure.SweetPropertyConfigureExtension
|
import com.highcapable.sweetproperty.plugin.extension.dsl.configure.SweetPropertyConfigureExtension
|
||||||
import com.highcapable.sweetproperty.utils.noBlank
|
import com.highcapable.sweetproperty.plugin.generator.factory.PropertyValueRule
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 默认配置类实现类
|
* 默认配置类实现类
|
||||||
@@ -63,10 +63,10 @@ internal object DefaultConfigs {
|
|||||||
get() = selfBase?.isEnable
|
get() = selfBase?.isEnable
|
||||||
?: globalBase?.isEnable
|
?: globalBase?.isEnable
|
||||||
?: baseGenerateConfigs(name).isEnable
|
?: baseGenerateConfigs(name).isEnable
|
||||||
override val propertiesFileName
|
override val propertiesFileNames
|
||||||
get() = selfBase?.propertiesFileName?.noBlank()
|
get() = selfBase?.propertiesFileNames
|
||||||
?: globalBase?.propertiesFileName?.noBlank()
|
?: globalBase?.propertiesFileNames
|
||||||
?: baseGenerateConfigs(name).propertiesFileName
|
?: baseGenerateConfigs(name).propertiesFileNames
|
||||||
override val permanentKeyValues
|
override val permanentKeyValues
|
||||||
get() = selfBase?.permanentKeyValues
|
get() = selfBase?.permanentKeyValues
|
||||||
?: globalBase?.permanentKeyValues
|
?: globalBase?.permanentKeyValues
|
||||||
@@ -75,6 +75,14 @@ internal object DefaultConfigs {
|
|||||||
get() = selfBase?.excludeKeys
|
get() = selfBase?.excludeKeys
|
||||||
?: globalBase?.excludeKeys
|
?: globalBase?.excludeKeys
|
||||||
?: baseGenerateConfigs(name).excludeKeys
|
?: baseGenerateConfigs(name).excludeKeys
|
||||||
|
override val includeKeys
|
||||||
|
get() = selfBase?.includeKeys
|
||||||
|
?: globalBase?.includeKeys
|
||||||
|
?: baseGenerateConfigs(name).includeKeys
|
||||||
|
override val keyValuesRules
|
||||||
|
get() = selfBase?.keyValuesRules
|
||||||
|
?: globalBase?.keyValuesRules
|
||||||
|
?: baseGenerateConfigs(name).keyValuesRules
|
||||||
override val isEnableExcludeNonStringValue
|
override val isEnableExcludeNonStringValue
|
||||||
get() = selfBase?.isEnableExcludeNonStringValue
|
get() = selfBase?.isEnableExcludeNonStringValue
|
||||||
?: globalBase?.isEnableExcludeNonStringValue
|
?: globalBase?.isEnableExcludeNonStringValue
|
||||||
@@ -111,10 +119,10 @@ internal object DefaultConfigs {
|
|||||||
get() = selfBase?.isEnable
|
get() = selfBase?.isEnable
|
||||||
?: globalBase?.isEnable
|
?: globalBase?.isEnable
|
||||||
?: baseGenerateConfigs(name).isEnable
|
?: baseGenerateConfigs(name).isEnable
|
||||||
override val propertiesFileName
|
override val propertiesFileNames
|
||||||
get() = selfBase?.propertiesFileName?.noBlank()
|
get() = selfBase?.propertiesFileNames
|
||||||
?: globalBase?.propertiesFileName?.noBlank()
|
?: globalBase?.propertiesFileNames
|
||||||
?: baseGenerateConfigs(name).propertiesFileName
|
?: baseGenerateConfigs(name).propertiesFileNames
|
||||||
override val permanentKeyValues
|
override val permanentKeyValues
|
||||||
get() = selfBase?.permanentKeyValues
|
get() = selfBase?.permanentKeyValues
|
||||||
?: globalBase?.permanentKeyValues
|
?: globalBase?.permanentKeyValues
|
||||||
@@ -123,6 +131,14 @@ internal object DefaultConfigs {
|
|||||||
get() = selfBase?.excludeKeys
|
get() = selfBase?.excludeKeys
|
||||||
?: globalBase?.excludeKeys
|
?: globalBase?.excludeKeys
|
||||||
?: baseGenerateConfigs(name).excludeKeys
|
?: baseGenerateConfigs(name).excludeKeys
|
||||||
|
override val includeKeys
|
||||||
|
get() = selfBase?.includeKeys
|
||||||
|
?: globalBase?.includeKeys
|
||||||
|
?: baseGenerateConfigs(name).includeKeys
|
||||||
|
override val keyValuesRules
|
||||||
|
get() = selfBase?.keyValuesRules
|
||||||
|
?: globalBase?.keyValuesRules
|
||||||
|
?: baseGenerateConfigs(name).keyValuesRules
|
||||||
override val isEnableExcludeNonStringValue
|
override val isEnableExcludeNonStringValue
|
||||||
get() = selfBase?.isEnableExcludeNonStringValue
|
get() = selfBase?.isEnableExcludeNonStringValue
|
||||||
?: globalBase?.isEnableExcludeNonStringValue
|
?: globalBase?.isEnableExcludeNonStringValue
|
||||||
@@ -149,9 +165,11 @@ internal object DefaultConfigs {
|
|||||||
private fun baseGenerateConfigs(name: String) = object : ISweetPropertyConfigs.IBaseGenerateConfigs {
|
private fun baseGenerateConfigs(name: String) = object : ISweetPropertyConfigs.IBaseGenerateConfigs {
|
||||||
override val name get() = name
|
override val name get() = name
|
||||||
override val isEnable get() = true
|
override val isEnable get() = true
|
||||||
override val propertiesFileName get() = ISweetPropertyConfigs.DEFAULT_PROPERTIES_FILE_NAME
|
override val propertiesFileNames get() = mutableListOf(ISweetPropertyConfigs.DEFAULT_PROPERTIES_FILE_NAME)
|
||||||
override val permanentKeyValues get() = mutableMapOf<String, Any>()
|
override val permanentKeyValues get() = mutableMapOf<String, Any>()
|
||||||
override val excludeKeys get() = mutableListOf<Any>()
|
override val excludeKeys get() = mutableListOf<Any>()
|
||||||
|
override val includeKeys get() = mutableListOf<Any>()
|
||||||
|
override val keyValuesRules get() = mutableMapOf<String, PropertyValueRule>()
|
||||||
override val isEnableExcludeNonStringValue get() = true
|
override val isEnableExcludeNonStringValue get() = true
|
||||||
override val isEnableTypeAutoConversion get() = true
|
override val isEnableTypeAutoConversion get() = true
|
||||||
override val isEnableValueInterpolation get() = true
|
override val isEnableValueInterpolation get() = true
|
||||||
|
@@ -92,10 +92,10 @@ private fun SweetPropertyConfigureExtension.SourcesCodeGenerateConfigureExtensio
|
|||||||
?: global?.isEnable
|
?: global?.isEnable
|
||||||
?: globalBase?.isEnable
|
?: globalBase?.isEnable
|
||||||
?: DefaultConfigs.sourcesCodeGenerateConfigs(name, selfBase, globalBase).isEnable
|
?: DefaultConfigs.sourcesCodeGenerateConfigs(name, selfBase, globalBase).isEnable
|
||||||
override val propertiesFileName
|
override val propertiesFileNames
|
||||||
get() = this@create.propertiesFileName.noBlank()
|
get() = this@create.propertiesFileNames
|
||||||
?: global?.propertiesFileName?.noBlank()
|
?: global?.propertiesFileNames
|
||||||
?: DefaultConfigs.sourcesCodeGenerateConfigs(name, selfBase, globalBase).propertiesFileName
|
?: DefaultConfigs.sourcesCodeGenerateConfigs(name, selfBase, globalBase).propertiesFileNames
|
||||||
override val permanentKeyValues
|
override val permanentKeyValues
|
||||||
get() = this@create.permanentKeyValues
|
get() = this@create.permanentKeyValues
|
||||||
?: global?.permanentKeyValues
|
?: global?.permanentKeyValues
|
||||||
@@ -104,6 +104,14 @@ private fun SweetPropertyConfigureExtension.SourcesCodeGenerateConfigureExtensio
|
|||||||
get() = this@create.excludeKeys
|
get() = this@create.excludeKeys
|
||||||
?: global?.excludeKeys
|
?: global?.excludeKeys
|
||||||
?: DefaultConfigs.sourcesCodeGenerateConfigs(name, selfBase, globalBase).excludeKeys
|
?: DefaultConfigs.sourcesCodeGenerateConfigs(name, selfBase, globalBase).excludeKeys
|
||||||
|
override val includeKeys
|
||||||
|
get() = this@create.includeKeys
|
||||||
|
?: global?.includeKeys
|
||||||
|
?: DefaultConfigs.sourcesCodeGenerateConfigs(name, selfBase, globalBase).includeKeys
|
||||||
|
override val keyValuesRules
|
||||||
|
get() = this@create.keyValuesRules
|
||||||
|
?: global?.keyValuesRules
|
||||||
|
?: DefaultConfigs.sourcesCodeGenerateConfigs(name, selfBase, globalBase).keyValuesRules
|
||||||
override val isEnableExcludeNonStringValue
|
override val isEnableExcludeNonStringValue
|
||||||
get() = this@create.isEnableExcludeNonStringValue
|
get() = this@create.isEnableExcludeNonStringValue
|
||||||
?: selfBase?.isEnableExcludeNonStringValue
|
?: selfBase?.isEnableExcludeNonStringValue
|
||||||
@@ -155,10 +163,10 @@ private fun SweetPropertyConfigureExtension.BuildScriptGenerateConfigureExtensio
|
|||||||
?: global?.isEnable
|
?: global?.isEnable
|
||||||
?: globalBase?.isEnable
|
?: globalBase?.isEnable
|
||||||
?: DefaultConfigs.buildScriptGenerateConfigs(name, selfBase, globalBase).isEnable
|
?: DefaultConfigs.buildScriptGenerateConfigs(name, selfBase, globalBase).isEnable
|
||||||
override val propertiesFileName
|
override val propertiesFileNames
|
||||||
get() = this@create.propertiesFileName.noBlank()
|
get() = this@create.propertiesFileNames
|
||||||
?: global?.propertiesFileName?.noBlank()
|
?: global?.propertiesFileNames
|
||||||
?: DefaultConfigs.buildScriptGenerateConfigs(name, selfBase, globalBase).propertiesFileName
|
?: DefaultConfigs.buildScriptGenerateConfigs(name, selfBase, globalBase).propertiesFileNames
|
||||||
override val permanentKeyValues
|
override val permanentKeyValues
|
||||||
get() = this@create.permanentKeyValues
|
get() = this@create.permanentKeyValues
|
||||||
?: global?.permanentKeyValues
|
?: global?.permanentKeyValues
|
||||||
@@ -167,6 +175,14 @@ private fun SweetPropertyConfigureExtension.BuildScriptGenerateConfigureExtensio
|
|||||||
get() = this@create.excludeKeys
|
get() = this@create.excludeKeys
|
||||||
?: global?.excludeKeys
|
?: global?.excludeKeys
|
||||||
?: DefaultConfigs.buildScriptGenerateConfigs(name, selfBase, globalBase).excludeKeys
|
?: DefaultConfigs.buildScriptGenerateConfigs(name, selfBase, globalBase).excludeKeys
|
||||||
|
override val includeKeys
|
||||||
|
get() = this@create.includeKeys
|
||||||
|
?: global?.includeKeys
|
||||||
|
?: DefaultConfigs.buildScriptGenerateConfigs(name, selfBase, globalBase).includeKeys
|
||||||
|
override val keyValuesRules
|
||||||
|
get() = this@create.keyValuesRules
|
||||||
|
?: global?.keyValuesRules
|
||||||
|
?: DefaultConfigs.buildScriptGenerateConfigs(name, selfBase, globalBase).keyValuesRules
|
||||||
override val isEnableExcludeNonStringValue
|
override val isEnableExcludeNonStringValue
|
||||||
get() = this@create.isEnableExcludeNonStringValue
|
get() = this@create.isEnableExcludeNonStringValue
|
||||||
?: selfBase?.isEnableExcludeNonStringValue
|
?: selfBase?.isEnableExcludeNonStringValue
|
||||||
|
@@ -24,6 +24,7 @@ package com.highcapable.sweetproperty.plugin.config.proxy
|
|||||||
import com.highcapable.sweetproperty.SweetProperty
|
import com.highcapable.sweetproperty.SweetProperty
|
||||||
import com.highcapable.sweetproperty.generated.SweetPropertyProperties
|
import com.highcapable.sweetproperty.generated.SweetPropertyProperties
|
||||||
import com.highcapable.sweetproperty.plugin.config.type.GenerateLocationType
|
import com.highcapable.sweetproperty.plugin.config.type.GenerateLocationType
|
||||||
|
import com.highcapable.sweetproperty.plugin.generator.factory.PropertyValueRule
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [SweetProperty] 配置类接口类
|
* [SweetProperty] 配置类接口类
|
||||||
@@ -120,8 +121,8 @@ internal interface ISweetPropertyConfigs {
|
|||||||
/** 是否为当前功能生成代码 */
|
/** 是否为当前功能生成代码 */
|
||||||
val isEnable: Boolean
|
val isEnable: Boolean
|
||||||
|
|
||||||
/** 属性配置文件名称 */
|
/** 属性配置文件名称数组 */
|
||||||
val propertiesFileName: String
|
val propertiesFileNames: MutableList<String>
|
||||||
|
|
||||||
/** 固定存在的属性键值数组 */
|
/** 固定存在的属性键值数组 */
|
||||||
val permanentKeyValues: MutableMap<String, Any>
|
val permanentKeyValues: MutableMap<String, Any>
|
||||||
@@ -129,6 +130,12 @@ internal interface ISweetPropertyConfigs {
|
|||||||
/** 被排除的属性键值名称数组 */
|
/** 被排除的属性键值名称数组 */
|
||||||
val excludeKeys: MutableList<Any>
|
val excludeKeys: MutableList<Any>
|
||||||
|
|
||||||
|
/** 被包含的属性键值名称数组 */
|
||||||
|
val includeKeys: MutableList<Any>
|
||||||
|
|
||||||
|
/** 属性键值规则数组 */
|
||||||
|
val keyValuesRules: MutableMap<String, PropertyValueRule>
|
||||||
|
|
||||||
/** 是否启用排除非字符串类型键值内容 */
|
/** 是否启用排除非字符串类型键值内容 */
|
||||||
val isEnableExcludeNonStringValue: Boolean
|
val isEnableExcludeNonStringValue: Boolean
|
||||||
|
|
||||||
|
@@ -28,6 +28,7 @@ import com.highcapable.sweetproperty.gradle.factory.isUnSafeExtName
|
|||||||
import com.highcapable.sweetproperty.plugin.config.factory.create
|
import com.highcapable.sweetproperty.plugin.config.factory.create
|
||||||
import com.highcapable.sweetproperty.plugin.config.proxy.ISweetPropertyConfigs
|
import com.highcapable.sweetproperty.plugin.config.proxy.ISweetPropertyConfigs
|
||||||
import com.highcapable.sweetproperty.plugin.config.type.GenerateLocationType
|
import com.highcapable.sweetproperty.plugin.config.type.GenerateLocationType
|
||||||
|
import com.highcapable.sweetproperty.plugin.generator.factory.PropertyValueRule
|
||||||
import com.highcapable.sweetproperty.utils.debug.SError
|
import com.highcapable.sweetproperty.utils.debug.SError
|
||||||
import com.highcapable.sweetproperty.utils.noEmpty
|
import com.highcapable.sweetproperty.utils.noEmpty
|
||||||
import org.gradle.api.Action
|
import org.gradle.api.Action
|
||||||
@@ -200,12 +201,21 @@ open class SweetPropertyConfigureExtension internal constructor() {
|
|||||||
*/
|
*/
|
||||||
open inner class BaseGenerateConfigureExtension internal constructor() {
|
open inner class BaseGenerateConfigureExtension internal constructor() {
|
||||||
|
|
||||||
|
/** 当前属性配置文件路径数组 */
|
||||||
|
internal var propertiesFileNames: MutableList<String>? = null
|
||||||
|
|
||||||
/** 当前固定存在的属性键值数组 */
|
/** 当前固定存在的属性键值数组 */
|
||||||
internal var permanentKeyValues: MutableMap<String, Any>? = null
|
internal var permanentKeyValues: MutableMap<String, Any>? = null
|
||||||
|
|
||||||
/** 当前被排除的属性键值名称数组 */
|
/** 当前被排除的属性键值名称数组 */
|
||||||
internal var excludeKeys: MutableList<Any>? = null
|
internal var excludeKeys: MutableList<Any>? = null
|
||||||
|
|
||||||
|
/** 当前被包含的属性键值名称数组 */
|
||||||
|
internal var includeKeys: MutableList<Any>? = null
|
||||||
|
|
||||||
|
/** 当前属性键值规则数组 */
|
||||||
|
internal var keyValuesRules: MutableMap<String, PropertyValueRule>? = null
|
||||||
|
|
||||||
/** 当前生成位置类型数组 */
|
/** 当前生成位置类型数组 */
|
||||||
internal var generateLocationTypes: Array<GenerateLocationType>? = null
|
internal var generateLocationTypes: Array<GenerateLocationType>? = null
|
||||||
|
|
||||||
@@ -226,10 +236,11 @@ open class SweetPropertyConfigureExtension internal constructor() {
|
|||||||
/**
|
/**
|
||||||
* 设置属性配置文件名称
|
* 设置属性配置文件名称
|
||||||
*
|
*
|
||||||
* 默认为 [ISweetPropertyConfigs.DEFAULT_PROPERTIES_FILE_NAME]
|
* - 此方法已弃用 - 在之后的版本中将直接被删除
|
||||||
*
|
*
|
||||||
* - 注意:一般情况下不需要修改此设置 - 错误的文件名将导致获取到空键值内容
|
* - 请现在迁移到 [propertiesFileNames]
|
||||||
*/
|
*/
|
||||||
|
@Deprecated(message = "Migrate to propertiesFileNames(...)")
|
||||||
var propertiesFileName = ""
|
var propertiesFileName = ""
|
||||||
@JvmName("propertiesFileName") set
|
@JvmName("propertiesFileName") set
|
||||||
|
|
||||||
@@ -244,8 +255,11 @@ open class SweetPropertyConfigureExtension internal constructor() {
|
|||||||
/**
|
/**
|
||||||
* 是否启用类型自动转换功能
|
* 是否启用类型自动转换功能
|
||||||
*
|
*
|
||||||
*
|
|
||||||
* 默认启用 - 启用后将自动识别属性键值中的类型并转换为对应的类型
|
* 默认启用 - 启用后将自动识别属性键值中的类型并转换为对应的类型
|
||||||
|
*
|
||||||
|
* 在启用后如果你想要强制设置一个键值内容为字符串类型 - 你可以使用单引号或双引号包裹整个字符串
|
||||||
|
*
|
||||||
|
* 注意:在关闭此功能后如上所述的功能也将同时失效
|
||||||
*/
|
*/
|
||||||
var isEnableTypeAutoConversion: Boolean? = null
|
var isEnableTypeAutoConversion: Boolean? = null
|
||||||
@JvmName("enableTypeAutoConversion") set
|
@JvmName("enableTypeAutoConversion") set
|
||||||
@@ -260,6 +274,27 @@ open class SweetPropertyConfigureExtension internal constructor() {
|
|||||||
var isEnableValueInterpolation: Boolean? = null
|
var isEnableValueInterpolation: Boolean? = null
|
||||||
@JvmName("enableValueInterpolation") set
|
@JvmName("enableValueInterpolation") set
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置属性配置文件名称数组
|
||||||
|
*
|
||||||
|
* 属性配置文件将根据你设置的文件名称自动从当前根项目、子项目以及用户目录的根目录进行获取
|
||||||
|
*
|
||||||
|
* 默认为 [ISweetPropertyConfigs.DEFAULT_PROPERTIES_FILE_NAME]
|
||||||
|
*
|
||||||
|
* 你可以添加多组属性配置文件名称 - 将按照顺序依次进行读取
|
||||||
|
*
|
||||||
|
* - 注意:一般情况下不需要修改此设置 - 错误的文件名称将导致获取到空键值内容
|
||||||
|
* @param names 要添加的属性配置文件名称数组
|
||||||
|
* @param isAddDefault 是否添加默认的属性配置文件名称 - 默认是
|
||||||
|
*/
|
||||||
|
@JvmOverloads
|
||||||
|
fun propertiesFileNames(vararg names: String, isAddDefault: Boolean = true) {
|
||||||
|
if (names.isEmpty()) SError.make("Properties file names must not be empty")
|
||||||
|
if (names.any { it.isBlank() }) SError.make("Properties file names must not have blank contents")
|
||||||
|
propertiesFileNames = names.distinct().toMutableList()
|
||||||
|
if (isAddDefault) propertiesFileNames?.add(0, ISweetPropertyConfigs.DEFAULT_PROPERTIES_FILE_NAME)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置固定存在的属性键值数组
|
* 设置固定存在的属性键值数组
|
||||||
*
|
*
|
||||||
@@ -310,6 +345,65 @@ open class SweetPropertyConfigureExtension internal constructor() {
|
|||||||
excludeKeys = keys.distinct().toMutableList()
|
excludeKeys = keys.distinct().toMutableList()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置需要包含的属性键值名称数组
|
||||||
|
*
|
||||||
|
* 在这里可以设置一些你希望从已知的属性键值中包含的键值名称
|
||||||
|
*
|
||||||
|
* 这些键值在属性键值存在它们时被包含 - 未被包含的键值不会出现在生成的代码中
|
||||||
|
* @param keys 键值名称数组 - 你可以传入 [Regex] 或使用 [String.toRegex] 以使用正则功能
|
||||||
|
*/
|
||||||
|
fun includeKeys(vararg keys: Any) {
|
||||||
|
if (keys.isEmpty()) SError.make("Include keys must not be empty")
|
||||||
|
if (keys.any { it.toString().isBlank() }) SError.make("Include keys must not have blank contents")
|
||||||
|
includeKeys = keys.distinct().toMutableList()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置属性键值规则数组
|
||||||
|
*
|
||||||
|
* 你可以设置一组键值规则 - 使用 [createValueRule] 创建新的规则 - 用于解析得到的键值内容
|
||||||
|
*
|
||||||
|
* 示例如下 ↓
|
||||||
|
*
|
||||||
|
* ```kotlin
|
||||||
|
* keyValuesRules(
|
||||||
|
* "some.key1" to createValueRule { if (it.contains("_")) it.replace("_", "-") else it },
|
||||||
|
* "some.key2" to createValueRule { "$it-value" }
|
||||||
|
* )
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* 这些键值规则在属性键值存在它们时被应用
|
||||||
|
* @param pairs 属性键值规则数组
|
||||||
|
*/
|
||||||
|
@JvmName("-kotlin-dsl-only-keyValuesRules-")
|
||||||
|
fun keyValuesRules(vararg pairs: Pair<String, PropertyValueRule>) {
|
||||||
|
if (pairs.isEmpty()) SError.make("Key-values rules must not be empty")
|
||||||
|
if (pairs.any { it.first.isBlank() }) SError.make("Key-values rules must not have blank contents")
|
||||||
|
keyValuesRules = mutableMapOf(*pairs)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置属性键值规则数组 (Groovy 兼容方法)
|
||||||
|
*
|
||||||
|
* 你可以设置一组键值规则 - 使用 [createValueRule] 创建新的规则 - 用于解析得到的键值内容
|
||||||
|
*
|
||||||
|
* 这些键值规则在属性键值存在它们时被应用
|
||||||
|
* @param rules 属性键值规则数组
|
||||||
|
*/
|
||||||
|
fun keyValuesRules(rules: Map<String, PropertyValueRule>) {
|
||||||
|
if (rules.isEmpty()) SError.make("Key-values rules must not be empty")
|
||||||
|
if (rules.any { it.key.isBlank() }) SError.make("Key-values rules must not have blank contents")
|
||||||
|
keyValuesRules = rules.toMutableMap()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建新的属性键值规则
|
||||||
|
* @param rule 回调当前规则
|
||||||
|
* @return [PropertyValueRule]
|
||||||
|
*/
|
||||||
|
fun createValueRule(rule: PropertyValueRule) = rule
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置从何处生成属性键值
|
* 设置从何处生成属性键值
|
||||||
*
|
*
|
||||||
|
@@ -194,13 +194,13 @@ internal class PropertiesAccessorsGenerator {
|
|||||||
*/
|
*/
|
||||||
private fun TypeSpec.Builder.addFinalValueMethod(accessorsName: String, methodName: String, value: Any) =
|
private fun TypeSpec.Builder.addFinalValueMethod(accessorsName: String, methodName: String, value: Any) =
|
||||||
addMethod(
|
addMethod(
|
||||||
MethodSpec.methodBuilder("get${methodName.capitalize()}")
|
MethodSpec.methodBuilder("get${methodName.capitalize()}").apply {
|
||||||
.addJavadoc("Resolve the \"$accessorsName\" value \"$value\"")
|
val typedValue = value.parseTypedValue(configs.isEnableTypeAutoConversion)
|
||||||
.addModifiers(Modifier.PUBLIC, Modifier.FINAL).apply {
|
addJavadoc("Resolve the \"$accessorsName\" value ${typedValue.second}")
|
||||||
val typedValue = value.parseTypedValue(configs.isEnableTypeAutoConversion)
|
addModifiers(Modifier.PUBLIC, Modifier.FINAL)
|
||||||
returns(typedValue.first.java)
|
.returns(typedValue.first.java)
|
||||||
addStatement("return ${typedValue.second}")
|
.addStatement("return ${typedValue.second}")
|
||||||
}.build()
|
}.build()
|
||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -70,7 +70,7 @@ internal class PropertiesSourcesGenerator {
|
|||||||
keyValues.forEach { (key, value) ->
|
keyValues.forEach { (key, value) ->
|
||||||
val typedValue = value.parseTypedValue(configs.isEnableTypeAutoConversion)
|
val typedValue = value.parseTypedValue(configs.isEnableTypeAutoConversion)
|
||||||
addProperty(PropertySpec.builder(key.firstNumberToLetter().underscore(), typedValue.first).apply {
|
addProperty(PropertySpec.builder(key.firstNumberToLetter().underscore(), typedValue.first).apply {
|
||||||
addKdoc("Resolve the \"$key\" value \"$value\"")
|
addKdoc("Resolve the \"$key\" value ${typedValue.second}")
|
||||||
if (configs.isEnableRestrictedAccess) addModifiers(KModifier.INTERNAL)
|
if (configs.isEnableRestrictedAccess) addModifiers(KModifier.INTERNAL)
|
||||||
addModifiers(KModifier.CONST)
|
addModifiers(KModifier.CONST)
|
||||||
initializer(typedValue.second.toKotlinPoetSpace())
|
initializer(typedValue.second.toKotlinPoetSpace())
|
||||||
|
@@ -26,19 +26,29 @@ import kotlin.reflect.KClass
|
|||||||
/** 属性键值数组类型定义 */
|
/** 属性键值数组类型定义 */
|
||||||
internal typealias PropertyMap = MutableMap<String, Any>
|
internal typealias PropertyMap = MutableMap<String, Any>
|
||||||
|
|
||||||
|
/** 属性键值规则类型定义 */
|
||||||
|
internal typealias PropertyValueRule = (value: String) -> String
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解析到键值内容类型
|
* 解析到键值内容类型
|
||||||
* @param isAutoConversion 是否自动转换类型
|
* @param isAutoConversion 是否自动转换类型
|
||||||
* @return [Pair]<[KClass], [String]>
|
* @return [Pair]<[KClass], [String]>
|
||||||
*/
|
*/
|
||||||
internal fun Any.parseTypedValue(isAutoConversion: Boolean): Pair<KClass<*>, String> {
|
internal fun Any.parseTypedValue(isAutoConversion: Boolean): Pair<KClass<*>, String> {
|
||||||
|
var isStringType = false
|
||||||
val valueString = toString()
|
val valueString = toString()
|
||||||
.replace("\n", "\\n")
|
.replace("\n", "\\n")
|
||||||
.replace("\r", "\\r")
|
.replace("\r", "\\r")
|
||||||
.replace("\\", "\\\\")
|
.replace("\\", "\\\\")
|
||||||
.replace("\"", "\\\"")
|
.let {
|
||||||
|
if (isAutoConversion && (it.startsWith("\"") && it.endsWith("\"") || it.startsWith("'") && it.endsWith("'"))) {
|
||||||
|
isStringType = true
|
||||||
|
it.drop(1).dropLast(1)
|
||||||
|
} else it.replace("\"", "\\\"")
|
||||||
|
}
|
||||||
if (isAutoConversion.not()) return Pair(String::class, "\"$valueString\"")
|
if (isAutoConversion.not()) return Pair(String::class, "\"$valueString\"")
|
||||||
val typeSpec = when {
|
val typeSpec = when {
|
||||||
|
isStringType -> String::class
|
||||||
valueString.trim().toIntOrNull() != null -> Int::class
|
valueString.trim().toIntOrNull() != null -> Int::class
|
||||||
valueString.trim().toLongOrNull() != null -> Long::class
|
valueString.trim().toLongOrNull() != null -> Long::class
|
||||||
valueString.trim().toDoubleOrNull() != null -> Double::class
|
valueString.trim().toDoubleOrNull() != null -> Double::class
|
||||||
|
@@ -45,8 +45,8 @@ import com.highcapable.sweetproperty.utils.hasInterpolation
|
|||||||
import com.highcapable.sweetproperty.utils.isEmpty
|
import com.highcapable.sweetproperty.utils.isEmpty
|
||||||
import com.highcapable.sweetproperty.utils.noBlank
|
import com.highcapable.sweetproperty.utils.noBlank
|
||||||
import com.highcapable.sweetproperty.utils.noEmpty
|
import com.highcapable.sweetproperty.utils.noEmpty
|
||||||
import com.highcapable.sweetproperty.utils.parseFileSeparator
|
|
||||||
import com.highcapable.sweetproperty.utils.replaceInterpolation
|
import com.highcapable.sweetproperty.utils.replaceInterpolation
|
||||||
|
import com.highcapable.sweetproperty.utils.toStringMap
|
||||||
import com.highcapable.sweetproperty.utils.uppercamelcase
|
import com.highcapable.sweetproperty.utils.uppercamelcase
|
||||||
import org.gradle.api.DomainObjectCollection
|
import org.gradle.api.DomainObjectCollection
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
@@ -156,7 +156,10 @@ internal object PropertiesDeployHelper {
|
|||||||
allProperties.add(generatedProperties(subConfigs.buildScript, ProjectDescriptor.create(settings, name)))
|
allProperties.add(generatedProperties(subConfigs.buildScript, ProjectDescriptor.create(settings, name)))
|
||||||
allConfigs.add(subConfigs.buildScript)
|
allConfigs.add(subConfigs.buildScript)
|
||||||
}
|
}
|
||||||
if (isConfigsModified.not() && allProperties == cachedSettingsProperties && accessorsDir.isEmpty().not()) return
|
if (isConfigsModified.not() &&
|
||||||
|
allProperties == cachedSettingsProperties &&
|
||||||
|
accessorsDir.resolve(accessorsPomData.relativePomPath).isEmpty().not()
|
||||||
|
) return
|
||||||
cachedSettingsProperties = allProperties
|
cachedSettingsProperties = allProperties
|
||||||
accessorsGenerator.build(allConfigs, allProperties).compile(accessorsPomData, accessorsDir.absolutePath, accessorsGenerator.compileStubFiles)
|
accessorsGenerator.build(allConfigs, allProperties).compile(accessorsPomData, accessorsDir.absolutePath, accessorsGenerator.compileStubFiles)
|
||||||
}
|
}
|
||||||
@@ -166,7 +169,8 @@ internal object PropertiesDeployHelper {
|
|||||||
* @param rootProject 当前根项目
|
* @param rootProject 当前根项目
|
||||||
*/
|
*/
|
||||||
private fun resolveAccessors(rootProject: Project) {
|
private fun resolveAccessors(rootProject: Project) {
|
||||||
if (accessorsDir.isEmpty().not()) rootProject.addDependencyToBuildScript(accessorsDir.absolutePath, accessorsPomData)
|
if (accessorsDir.resolve(accessorsPomData.relativePomPath).isEmpty().not())
|
||||||
|
rootProject.addDependencyToBuildScript(accessorsDir.absolutePath, accessorsPomData)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -178,7 +182,15 @@ internal object PropertiesDeployHelper {
|
|||||||
fun Project.deploy() {
|
fun Project.deploy() {
|
||||||
val configs = configs.with(this).buildScript
|
val configs = configs.with(this).buildScript
|
||||||
if (configs.isEnable.not()) return
|
if (configs.isEnable.not()) return
|
||||||
getOrCreate(configs.extensionName.camelcase(), loadBuildScriptClass(accessorsGenerator.propertiesClass(configs.name)))
|
val className = accessorsGenerator.propertiesClass(configs.name)
|
||||||
|
val accessorsClass = loadBuildScriptClass(className) ?: SError.make(
|
||||||
|
"""
|
||||||
|
Generated class "$className" not found, stop loading $this
|
||||||
|
Please check whether the initialization process is interrupted and re-run Gradle Sync
|
||||||
|
If this doesn't work, please manually delete the entire "${accessorsDir.absolutePath}" directory
|
||||||
|
""".trimIndent()
|
||||||
|
)
|
||||||
|
getOrCreate(configs.extensionName.camelcase(), accessorsClass)
|
||||||
}
|
}
|
||||||
rootProject.deploy()
|
rootProject.deploy()
|
||||||
rootProject.subprojects.forEach { it.deploy() }
|
rootProject.subprojects.forEach { it.deploy() }
|
||||||
@@ -244,43 +256,52 @@ internal object PropertiesDeployHelper {
|
|||||||
val propteries = mutableMapOf<String, Any>()
|
val propteries = mutableMapOf<String, Any>()
|
||||||
configs.permanentKeyValues.forEach { (key, value) -> propteries[key] = value }
|
configs.permanentKeyValues.forEach { (key, value) -> propteries[key] = value }
|
||||||
configs.generateLocationTypes.forEach {
|
configs.generateLocationTypes.forEach {
|
||||||
val nativeKeyValues = when (it) {
|
mutableMapOf<Any?, Any?>().apply {
|
||||||
GenerateLocationType.CURRENT_PROJECT -> createProperties(configs, descriptor.currentDir)
|
when (it) {
|
||||||
GenerateLocationType.ROOT_PROJECT -> createProperties(configs, descriptor.rootDir)
|
GenerateLocationType.CURRENT_PROJECT -> createProperties(configs, descriptor.currentDir).forEach { putAll(it) }
|
||||||
GenerateLocationType.GLOBAL -> createProperties(configs, descriptor.homeDir)
|
GenerateLocationType.ROOT_PROJECT -> createProperties(configs, descriptor.rootDir).forEach { putAll(it) }
|
||||||
GenerateLocationType.SYSTEM -> System.getProperties()
|
GenerateLocationType.GLOBAL -> createProperties(configs, descriptor.homeDir).forEach { putAll(it) }
|
||||||
GenerateLocationType.SYSTEM_ENV -> System.getenv()
|
GenerateLocationType.SYSTEM -> putAll(System.getProperties())
|
||||||
} ?: emptyMap()
|
GenerateLocationType.SYSTEM_ENV -> putAll(System.getenv())
|
||||||
val resolveKeyValues = mutableMapOf<String, Any>()
|
}
|
||||||
nativeKeyValues.forEach native@{ (key, value) ->
|
}.filter { (key, value) ->
|
||||||
val hasExcludeKeys = configs.excludeKeys.noEmpty()?.any { content ->
|
if (configs.isEnableExcludeNonStringValue)
|
||||||
when (content) {
|
|
||||||
is Regex -> content.toString().isNotBlank() && content.matches(key.toString())
|
|
||||||
else -> content.toString() == key
|
|
||||||
}
|
|
||||||
} ?: false
|
|
||||||
if (hasExcludeKeys) return@native
|
|
||||||
val isAvailableKeyValue = if (configs.isEnableExcludeNonStringValue)
|
|
||||||
key is CharSequence && key.isNotBlank() && value is CharSequence
|
key is CharSequence && key.isNotBlank() && value is CharSequence
|
||||||
else key.toString().isNotBlank() && value != null
|
else key.toString().isNotBlank() && value != null
|
||||||
if (isAvailableKeyValue) resolveKeyValues[key.toString()] = value
|
}.toStringMap().filter { (key, _) ->
|
||||||
}
|
configs.includeKeys.noEmpty()?.any { content ->
|
||||||
resolveKeyValues.forEach { (key, value) ->
|
when (content) {
|
||||||
val resolveKeys = mutableListOf<String>()
|
is Regex -> content.matches(key)
|
||||||
|
else -> content.toString() == key
|
||||||
|
}
|
||||||
|
} ?: true
|
||||||
|
}.filter { (key, _) ->
|
||||||
|
configs.excludeKeys.noEmpty()?.none { content ->
|
||||||
|
when (content) {
|
||||||
|
is Regex -> content.matches(key)
|
||||||
|
else -> content.toString() == key
|
||||||
|
}
|
||||||
|
} ?: true
|
||||||
|
}.toMutableMap().also { resolveKeyValues ->
|
||||||
|
resolveKeyValues.onEach { (key, value) ->
|
||||||
|
val resolveKeys = mutableListOf<String>()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理键值内容
|
* 处理键值内容
|
||||||
* @return [String]
|
* @return [String]
|
||||||
*/
|
*/
|
||||||
fun String.resolveValue(): String = replaceInterpolation { matchKey ->
|
fun String.resolveValue(): String = replaceInterpolation { matchKey ->
|
||||||
if (resolveKeys.size > 5) SError.make("Key \"$key\" has been called recursively multiple times of those $resolveKeys")
|
if (resolveKeys.size > 5) SError.make("Key \"$key\" has been called recursively multiple times of those $resolveKeys")
|
||||||
resolveKeys.add(matchKey)
|
resolveKeys.add(matchKey)
|
||||||
val resolveValue = if (configs.isEnableValueInterpolation) resolveKeyValues[matchKey]?.toString() ?: "" else matchKey
|
val resolveValue = if (configs.isEnableValueInterpolation) resolveKeyValues[matchKey] ?: "" else matchKey
|
||||||
if (resolveValue.hasInterpolation()) resolveValue.resolveValue()
|
if (resolveValue.hasInterpolation()) resolveValue.resolveValue()
|
||||||
else resolveValue
|
else resolveValue
|
||||||
}
|
}
|
||||||
if (value.toString().hasInterpolation()) resolveKeyValues[key] = value.toString().resolveValue()
|
if (value.hasInterpolation()) resolveKeyValues[key] = value.resolveValue()
|
||||||
}; propteries.putAll(resolveKeyValues)
|
}.takeIf { configs.keyValuesRules.isNotEmpty() }?.forEach { (key, value) ->
|
||||||
|
configs.keyValuesRules[key]?.also { resolveKeyValues[key] = it(value) }
|
||||||
|
}; propteries.putAll(resolveKeyValues)
|
||||||
|
}
|
||||||
}; return propteries
|
}; return propteries
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -320,12 +341,17 @@ internal object PropertiesDeployHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建新的 [Properties]
|
* 创建新的 [Properties] 数组
|
||||||
* @param configs 当前配置
|
* @param configs 当前配置
|
||||||
* @param dir 当前目录
|
* @param dir 当前目录
|
||||||
* @return [Properties] or null
|
* @return [MutableList]<[Properties]>
|
||||||
*/
|
*/
|
||||||
private fun createProperties(configs: ISweetPropertyConfigs.IBaseGenerateConfigs, dir: File?) = runCatching {
|
private fun createProperties(configs: ISweetPropertyConfigs.IBaseGenerateConfigs, dir: File?) = runCatching {
|
||||||
Properties().apply { load(FileReader(dir?.resolve(configs.propertiesFileName)?.absolutePath?.parseFileSeparator() ?: "")) }
|
mutableListOf<Properties>().apply {
|
||||||
}.getOrNull()
|
configs.propertiesFileNames.forEach {
|
||||||
|
val propertiesFile = dir?.resolve(it)
|
||||||
|
if (propertiesFile?.exists() == true) add(Properties().apply { load(FileReader(propertiesFile.absolutePath)) })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.getOrNull() ?: mutableListOf()
|
||||||
}
|
}
|
@@ -21,6 +21,12 @@
|
|||||||
*/
|
*/
|
||||||
package com.highcapable.sweetproperty.utils
|
package com.highcapable.sweetproperty.utils
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换当前 [Map] 键值到字符串类型
|
||||||
|
* @return [Map]<[String], [String]>
|
||||||
|
*/
|
||||||
|
internal inline fun <reified K, V> Map<K, V>.toStringMap() = mapKeys { e -> e.key.toString() }.mapValues { e -> e.value.toString() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 当数组不为空时返回非空
|
* 当数组不为空时返回非空
|
||||||
* @return [T] or null
|
* @return [T] or null
|
||||||
|
@@ -24,11 +24,10 @@ package com.highcapable.sweetproperty.utils.code
|
|||||||
import com.highcapable.sweetproperty.utils.code.entity.MavenPomData
|
import com.highcapable.sweetproperty.utils.code.entity.MavenPomData
|
||||||
import com.highcapable.sweetproperty.utils.debug.SError
|
import com.highcapable.sweetproperty.utils.debug.SError
|
||||||
import com.highcapable.sweetproperty.utils.deleteEmptyRecursively
|
import com.highcapable.sweetproperty.utils.deleteEmptyRecursively
|
||||||
import com.highcapable.sweetproperty.utils.parseFileSeparator
|
|
||||||
import com.highcapable.sweetproperty.utils.toFile
|
import com.highcapable.sweetproperty.utils.toFile
|
||||||
|
import net.lingala.zip4j.ZipFile
|
||||||
|
import net.lingala.zip4j.model.ZipParameters
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.jar.JarEntry
|
|
||||||
import java.util.jar.JarOutputStream
|
|
||||||
import javax.tools.DiagnosticCollector
|
import javax.tools.DiagnosticCollector
|
||||||
import javax.tools.JavaFileObject
|
import javax.tools.JavaFileObject
|
||||||
import javax.tools.StandardLocation
|
import javax.tools.StandardLocation
|
||||||
@@ -84,8 +83,8 @@ internal object CodeCompiler {
|
|||||||
sourceFile.writeText(it.getCharContent(true).toString())
|
sourceFile.writeText(it.getCharContent(true).toString())
|
||||||
}
|
}
|
||||||
}; outputClassesDir.deleteEmptyRecursively()
|
}; outputClassesDir.deleteEmptyRecursively()
|
||||||
writeMetaInf(outputClassesDir.absolutePath)
|
writeMetaInf(outputClassesDir)
|
||||||
writeMetaInf(outputSourcesDir.absolutePath)
|
writeMetaInf(outputSourcesDir)
|
||||||
createJarAndPom(pomData, outputDir, outputBuildDir, outputClassesDir, outputSourcesDir)
|
createJarAndPom(pomData, outputDir, outputBuildDir, outputClassesDir, outputSourcesDir)
|
||||||
} else SError.make("Failed to compile java files into path: $outputDirPath\n$diagnosticsMessage")
|
} else SError.make("Failed to compile java files into path: $outputDirPath\n$diagnosticsMessage")
|
||||||
}
|
}
|
||||||
@@ -99,30 +98,29 @@ internal object CodeCompiler {
|
|||||||
* @param sourcesDir 编译源码目录
|
* @param sourcesDir 编译源码目录
|
||||||
*/
|
*/
|
||||||
private fun createJarAndPom(pomData: MavenPomData, outputDir: File, buildDir: File, classesDir: File, sourcesDir: File) {
|
private fun createJarAndPom(pomData: MavenPomData, outputDir: File, buildDir: File, classesDir: File, sourcesDir: File) {
|
||||||
val pomPath = "${pomData.groupId.toPomPathName()}/${pomData.artifactId}/${pomData.version}"
|
val pomDir = outputDir.resolve(pomData.relativePomPath).also { if (it.exists().not()) it.mkdirs() }
|
||||||
val pomDir = "${outputDir.absolutePath}/$pomPath".toFile().also { if (it.exists().not()) it.mkdirs() }
|
|
||||||
packageToJar(classesDir, pomDir, pomData, isSourcesJar = false)
|
packageToJar(classesDir, pomDir, pomData, isSourcesJar = false)
|
||||||
packageToJar(sourcesDir, pomDir, pomData, isSourcesJar = true)
|
packageToJar(sourcesDir, pomDir, pomData, isSourcesJar = true)
|
||||||
writePom(pomDir.absolutePath, pomData)
|
writePom(pomDir, pomData)
|
||||||
buildDir.deleteRecursively()
|
buildDir.deleteRecursively()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 写入 META-INF/MANIFEST.MF
|
* 写入 META-INF/MANIFEST.MF
|
||||||
* @param dirPath 当前目录路径
|
* @param dir 当前目录
|
||||||
*/
|
*/
|
||||||
private fun writeMetaInf(dirPath: String) {
|
private fun writeMetaInf(dir: File) {
|
||||||
val metaInfFile = "$dirPath/META-INF".toFile().apply { mkdirs() }
|
val metaInfDir = dir.resolve("META-INF").apply { mkdirs() }
|
||||||
"${metaInfFile.absolutePath}/MANIFEST.MF".toFile().writeText("Manifest-Version: 1.0")
|
metaInfDir.resolve("MANIFEST.MF").writeText("Manifest-Version: 1.0")
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 写入 POM
|
* 写入 POM
|
||||||
* @param dirPath 当前目录路径
|
* @param dir 当前目录
|
||||||
* @param pomData Maven POM 实体
|
* @param pomData Maven POM 实体
|
||||||
*/
|
*/
|
||||||
private fun writePom(dirPath: String, pomData: MavenPomData) =
|
private fun writePom(dir: File, pomData: MavenPomData) =
|
||||||
"$dirPath/${pomData.artifactId}-${pomData.version}.pom".toFile().writeText(
|
dir.resolve("${pomData.artifactId}-${pomData.version}.pom").writeText(
|
||||||
"""
|
"""
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project
|
<project
|
||||||
@@ -137,12 +135,6 @@ internal object CodeCompiler {
|
|||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
)
|
)
|
||||||
|
|
||||||
/**
|
|
||||||
* 转换到 [MavenPomData] 目录名称
|
|
||||||
* @return [String]
|
|
||||||
*/
|
|
||||||
private fun String.toPomPathName() = trim().replace(".", "/").replace("_", "/").replace(":", "/").replace("-", "/")
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 转换到文件
|
* 转换到文件
|
||||||
* @param outputDir 输出目录
|
* @param outputDir 输出目录
|
||||||
@@ -167,26 +159,8 @@ internal object CodeCompiler {
|
|||||||
*/
|
*/
|
||||||
private fun packageToJar(buildDir: File, outputDir: File, pomData: MavenPomData, isSourcesJar: Boolean) {
|
private fun packageToJar(buildDir: File, outputDir: File, pomData: MavenPomData, isSourcesJar: Boolean) {
|
||||||
if (buildDir.exists().not()) SError.make("Jar file output path not found: ${buildDir.absolutePath}")
|
if (buildDir.exists().not()) SError.make("Jar file output path not found: ${buildDir.absolutePath}")
|
||||||
/**
|
val jarFile = outputDir.resolve("${pomData.artifactId}-${pomData.version}${if (isSourcesJar) "-sources" else ""}.jar")
|
||||||
* 添加文件到 JAR
|
|
||||||
* @param jos 当前输出流
|
|
||||||
* @param parentPath 父级路径
|
|
||||||
*/
|
|
||||||
fun File.addToJar(jos: JarOutputStream, parentPath: String = "") {
|
|
||||||
val currentPath = "$parentPath$name".replace("${buildDir.name}|", "").replace("|", "/").parseFileSeparator()
|
|
||||||
if (isFile) {
|
|
||||||
if (name.startsWith(".")) return
|
|
||||||
jos.putNextEntry(JarEntry(currentPath))
|
|
||||||
inputStream().use { fis ->
|
|
||||||
val buffer = ByteArray(4096)
|
|
||||||
var bytesRead: Int
|
|
||||||
while (fis.read(buffer).also { bytesRead = it } != -1) jos.write(buffer, 0, bytesRead)
|
|
||||||
}
|
|
||||||
jos.closeEntry()
|
|
||||||
} else listFiles()?.forEach { it.addToJar(jos, parentPath = "$currentPath|") }
|
|
||||||
}
|
|
||||||
val jarFile = "${outputDir.absolutePath}/${pomData.artifactId}-${pomData.version}${if (isSourcesJar) "-sources" else ""}.jar".toFile()
|
|
||||||
if (jarFile.exists()) jarFile.delete()
|
if (jarFile.exists()) jarFile.delete()
|
||||||
jarFile.outputStream().use { fos -> JarOutputStream(fos).use { jos -> buildDir.addToJar(jos) } }
|
ZipFile(jarFile).addFolder(buildDir, ZipParameters().apply { isIncludeRootFolder = false })
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -27,4 +27,17 @@ package com.highcapable.sweetproperty.utils.code.entity
|
|||||||
* @param artifactId Artifact Id
|
* @param artifactId Artifact Id
|
||||||
* @param version 版本
|
* @param version 版本
|
||||||
*/
|
*/
|
||||||
internal data class MavenPomData(internal val groupId: String, internal val artifactId: String, internal val version: String)
|
internal data class MavenPomData(internal val groupId: String, internal val artifactId: String, internal val version: String) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取 [MavenPomData] 相对路径
|
||||||
|
* @return [String]
|
||||||
|
*/
|
||||||
|
internal val relativePomPath get() = "${groupId.toPomPathName()}/$artifactId/$version"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换到 [MavenPomData] 目录名称
|
||||||
|
* @return [String]
|
||||||
|
*/
|
||||||
|
private fun String.toPomPathName() = trim().replace(".", "/").replace("_", "/").replace(":", "/").replace("-", "/")
|
||||||
|
}
|
Reference in New Issue
Block a user