72 Commits

Author SHA1 Message Date
36c7af3c52 docs: update changelog, changelog-zh-CN 2025-08-19 13:05:23 +08:00
34b11eb5b7 Bump version to 1.0.7 2025-08-19 12:56:18 +08:00
72037d6f08 Merge remote-tracking branch 'origin/master' 2025-08-19 12:46:33 +08:00
cf4b59db1a Bump version to 1.0.6 2025-08-19 12:42:51 +08:00
74da386f49 refactor(fix): add custom sourceSetName and fix sourceSets conflict in PropertiesDeployHelper 2025-08-19 12:37:26 +08:00
ceccd2e2cf fix: some number type will be consistent to String in GeneratorFactory 2025-08-19 12:36:41 +08:00
Fankesyooni
22b0a1be2c Merge pull request #1 from Doddddd/master
fix: 转义属性值中的 $,避免 Javadoc 格式化异常
2025-06-27 01:28:24 +08:00
Doddddd
a16da731cf fix: 转义属性值中的 $,避免 Javadoc 格式化异常 2025-06-27 00:54:46 +08:00
99a6e02d1d docs: update README 2025-06-24 15:37:07 +08:00
9e7d5ec574 chore: bump dependencies 2025-03-17 01:07:01 +08:00
f00c6e718c chore: bump gradle to 8.13 2025-03-17 01:06:58 +08:00
1e513489c8 chore: update project files 2025-03-17 01:06:52 +08:00
fdab590578 chore: update .editorconfig 2025-03-17 01:06:48 +08:00
dd85954691 chore: update .gitignore 2025-03-17 01:06:39 +08:00
37644fcd8d docs: update license 2025-01-13 10:40:46 +08:00
341a7497ec chore: update project files 2024-11-10 19:39:52 +08:00
138551dd44 chore: bump dependencies 2024-11-10 19:39:31 +08:00
d54aebefca chore: bump gradle to 8.10.2 2024-11-10 19:39:23 +08:00
7b24cd442e chore: update .editorconfig 2024-06-21 10:17:59 +08:00
77c374d6b6 chore: update project files 2024-06-21 10:17:55 +08:00
f2bdbb8124 chore: bump dependencies 2024-06-20 13:05:16 +08:00
21d4857d5c chore: bump gradle to 8.7 2024-06-20 13:05:12 +08:00
f5ab29e6b6 chore: update .editorconfig 2024-06-20 13:05:05 +08:00
255bd4035e chore: bump dependencies 2024-02-20 10:05:19 +08:00
98ca5dbc29 chore: bump gradle to 8.6 2024-02-20 10:05:10 +08:00
91cfa2f30a chore: update .editorconfig 2024-01-13 21:32:50 +08:00
68bfcc9b5a docs: update contacts 2024-01-02 03:32:43 +08:00
3481495626 docs: update copyright date to 2024 for all existing files 2024-01-01 01:46:51 +08:00
7acba690fb style: merge to new ktlint version & rules 2023-12-29 21:26:22 +08:00
c7ec2ab836 chore: add included properties for build 2023-12-29 21:17:47 +08:00
89626aeca7 chore: specify project name in properties 2023-12-28 23:29:38 +08:00
59453292f3 chore: update .gitignore 2023-12-28 22:30:08 +08:00
c12e55dbc1 chore: merge and update to java 21 2023-12-28 21:32:05 +08:00
192d3c9a5e chore: bump gradle to 8.5 2023-12-28 21:32:00 +08:00
e5e5915618 chore: merge to new maven publish way 2023-12-28 21:05:31 +08:00
e28c9feb20 chore: update project files 2023-12-28 20:56:16 +08:00
595e3768f7 chore: bump dependencies 2023-12-28 20:56:11 +08:00
179462c0ae docs: use relative link 2023-12-11 02:29:00 +08:00
90f36ac825 chore: update project files 2023-12-11 02:23:36 +08:00
8a71e739c0 chore: bump dependency versions 2023-12-11 01:05:01 +08:00
4eaaf82430 docs: update README-zh-CN 2023-12-11 01:03:35 +08:00
ef19ea07a5 docs: update promotion 2023-11-18 18:21:56 +08:00
c98dfb6b3d chore: bump "com.highcapable.sweetdependency" version to 1.0.4 2023-11-14 00:39:20 +08:00
a978baa1fe Bump version to 1.0.5 2023-11-08 14:52:10 +08:00
93c8107e76 fix: special or repeat chars cause code generation failed 2023-11-08 14:50:49 +08:00
5d5c3af69a Bump version to 1.0.4 2023-11-04 02:19:28 +08:00
87143b99c4 chore: update project files 2023-11-04 02:19:00 +08:00
ec03595552 chore: bump "com.highcapable.sweetdependency" version to 1.0.3 2023-11-04 02:18:02 +08:00
33abb4bafa refactor: replace not to ! 2023-11-04 02:10:46 +08:00
2337d5710b docs: update guide 2023-11-04 02:10:46 +08:00
1bf1a030dc feat: add multiple projects configure function 2023-11-04 02:10:45 +08:00
6c5835bc72 feat: remove auto conversion if it's an interpolation 2023-11-04 02:10:45 +08:00
d9c8c5dc84 fix: like "a=some", "a_b=some" style's property key name will fail on build 2023-11-04 02:10:44 +08:00
d2aed2120e feat: use @Nonnull better for Kotlin code 2023-11-03 23:10:53 +08:00
67c79a591c chore: update dependencies 2023-11-03 23:03:37 +08:00
fe1c8594c8 docs: update promotion 2023-10-24 22:23:53 +08:00
db2817a85a Bump version to 1.0.3 2023-09-26 08:35:49 +08:00
ebb1b95658 chore: bump "com.highcapable.sweetdependency" version to 1.0.2 2023-09-26 08:28:44 +08:00
68116f9f1f fix: when set global configure children configure "all" replaced problem 2023-09-26 08:01:59 +08:00
bd22e7b134 refactor: remove related lowercase functions 2023-09-26 07:59:06 +08:00
416522a673 feat: add stub function for possible problems with nested lambdas 2023-09-26 07:11:58 +08:00
d59e6feaab docs: update guide 2023-09-26 06:35:26 +08:00
f08d25912d refactor: standardize Gradle project naming 2023-09-26 06:33:58 +08:00
1bcd23113d fix: Gradle lifecycle problem 2023-09-26 04:35:44 +08:00
22b4228a46 feat: replace "/" to "or" 2023-09-26 04:28:48 +08:00
7485b13e7c feat: add checking update function 2023-09-26 03:40:39 +08:00
e24f6d0df1 feat: styled new SLog 2023-09-26 03:17:07 +08:00
10ae6ed17a refactor: unconditionally to output the sources even got an error 2023-09-26 02:01:13 +08:00
d41347066d docs: fix description 2023-09-16 00:28:21 +08:00
b6507c0e99 docs: update comments 2023-09-12 13:53:55 +08:00
c3481acb2d chore: optimize SweetProperty configs 2023-09-08 13:13:24 +08:00
d3ff5689ae docs: update readme zh-cn 2023-09-08 12:22:34 +08:00
50 changed files with 867 additions and 455 deletions

View File

@@ -10,6 +10,24 @@ ktlint_standard_argument-list-wrapping = disabled
ktlint_standard_parameter-list-wrapping = disabled
ktlint_standard_trailing-comma-on-declaration-site = disabled
ktlint_function_signature_body_expression_wrapping = multiline
ktlint_standard_string-template-indent = disabled
ktlint_standard_function-signature = disabled
ktlint_standard_trailing-comma-on-call-site = disabled
ktlint_standard_multiline-expression-wrapping = disabled
ktlint_standard_no-empty-first-line-in-class-body = disabled
ktlint_standard_if-else-wrapping = disabled
ktlint_standard_if-else-bracing = disabled
ktlint_standard_statement-wrapping = disabled
ktlint_standard_blank-line-before-declaration = disabled
ktlint_standard_no-empty-file = disabled
ktlint_standard_property-naming = disabled
ktlint_standard_function-naming = disabled
ktlint_standard_chain-method-continuation = disabled
ktlint_standard_class-signature = disabled
ktlint_standard_condition-wrapping = disabled
ktlint_standard_class-signature = disabled
ktlint_standard_no-trailing-spaces = disabled
ktlint_standard_multiline-loop = disabled
ij_continuation_indent_size = 2
indent_size = 4
indent_style = space

117
.gitignore vendored
View File

@@ -1,13 +1,110 @@
## Fully .gtignore for IntelliJ, Android Studio and Gradle based Java projects
## References:
## - https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
## - https://github.com/android/platform-samples/blob/main/.gitignore
# User-specific stuff
.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
.idea/**/libraries
# Gradle and Maven with auto-import
.idea/.name
.idea/artifacts
.idea/compiler.xml
.idea/jarRepositories.xml
.idea/modules.xml
.idea/*.iml
.idea/modules
.idea/caches
.idea/material_theme**
.idea/other.xml
*.iml
.gradle
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
*.ipr
# Kotlin
.kotlin
# Misc
.idea/misc.xml
# CMake
cmake-build-*/
# Mongo Explorer plugin
.idea/**/mongoSettings.xml
# File-based project format
*.iws
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# SonarLint plugin
.idea/sonarlint/
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
# Editor-based Rest Client
.idea/httpRequests
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser
# Android studio 3.1+ additional
.idea/deployment*.xml
.idea/assetWizardSettings.xml
.idea/androidTestResultsUserPreferences.xml
# Android projects
**/local.properties
/captures
.externalNativeBuild
.cxx
.cxx
# Gradle projects
.gradle
build/
# Mkdocs temporary serving folder
docs-gen
site
*.bak
.idea/appInsightsSettings.xml
# Mac OS
.DS_Store

10
.idea/.gitignore generated vendored
View File

@@ -1,10 +0,0 @@
# Default ignored files
/shelf/
/workspace.xml
/gradle.xml
/misc.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

6
.idea/compiler.xml generated
View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="17" />
</component>
</project>

View File

@@ -1,6 +1,7 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="CheckImageSize" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="ReplaceUntilWithRangeUntil" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false">
<option name="processCode" value="true" />

View File

@@ -1,20 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
<remote-repository>
<option name="id" value="MavenRepo" />
<option name="name" value="MavenRepo" />
<option name="url" value="https://repo.maven.apache.org/maven2/" />
</remote-repository>
</component>
</project>

2
.idea/kotlinc.xml generated
View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="KotlinJpsPluginSettings">
<option name="version" value="1.9.10" />
<option name="version" value="2.1.10" />
</component>
</project>

7
.idea/ktlint-plugin.xml generated Normal file
View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="KtLint plugin">
<ktlintMode>MANUAL</ktlintMode>
<formatOnSave>false</formatOnSave>
</component>
</project>

6
.idea/markdown.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="MarkdownSettings">
<option name="showProblemsInCodeBlocks" value="false" />
</component>
</project>

124
.idea/uiDesigner.xml generated
View File

@@ -1,124 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>

View File

@@ -1,14 +1,20 @@
# Sweet Property
[![GitHub license](https://img.shields.io/github/license/HighCapable/SweetProperty?color=blue)](https://github.com/HighCapable/SweetProperty/blob/master/LICENSE)
[![GitHub release](https://img.shields.io/github/v/release/HighCapable/SweetProperty?display_name=release&logo=github&color=green)](https://github.com/HighCapable/SweetProperty/releases)
[![Telegram](https://img.shields.io/badge/discussion-Telegram-blue.svg?logo=telegram)](https://t.me/HighCapable_Dev)
[![GitHub license](https://img.shields.io/github/license/HighCapable/SweetProperty?color=blue&style=flat-square)](https://github.com/HighCapable/SweetProperty/blob/master/LICENSE)
[![GitHub release](https://img.shields.io/github/v/release/HighCapable/SweetProperty?display_name=release&logo=github&color=green&style=flat-square)](https://github.com/HighCapable/SweetProperty/releases)
[![Telegram](https://img.shields.io/badge/discussion-Telegram-blue.svg?logo=telegram&style=flat-square)](https://t.me/HighCapable_Dev)
[![QQ](https://img.shields.io/badge/discussion-QQ-blue.svg?logo=tencent-qq&logoColor=red&style=flat-square)](https://qm.qq.com/cgi-bin/qm/qr?k=Pnsc5RY6N2mBKFjOLPiYldbAbprAU3V7&jump_from=webapi&authKey=X5EsOVzLXt1dRunge8ryTxDRrh9/IiW1Pua75eDLh9RE3KXE+bwXIYF5cWri/9lf)
<img src="https://github.com/HighCapable/SweetProperty/blob/master/img-src/icon.png?raw=true" width = "100" height = "100" alt="LOGO"/>
<img src="img-src/icon.png" width = "100" height = "100" alt="LOGO"/>
一个轻松在任意地方获取项目属性的 Gradle 插件。
[English](https://github.com/HighCapable/SweetProperty/blob/master/README.md) | 简体中文
[English](README.md) | 简体中文
| <img src="https://github.com/HighCapable/.github/blob/main/img-src/logo.jpg?raw=true" width = "30" height = "30" alt="LOGO"/> | [HighCapable](https://github.com/HighCapable) |
|-------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------|
这个项目属于上述组织,**点击上方链接关注这个组织**,发现更多好项目。
## 这是什么
@@ -38,11 +44,11 @@
## 开始使用
- [点击这里](https://github.com/HighCapable/SweetProperty/blob/master/docs/guide-zh-CN.md) 查看使用文档
- [点击这里](docs/guide-zh-CN.md) 查看使用文档
## 更新日志
- [点击这里](https://github.com/HighCapable/SweetProperty/blob/master/docs/changelog-zh-CN.md) 查看历史更新日志
- [点击这里](docs/changelog-zh-CN.md) 查看历史更新日志
## 项目推广
@@ -50,6 +56,15 @@
本项目同样使用了 **SweetDependency**
<!--suppress HtmlDeprecatedAttribute -->
<div align="center">
<h2>嘿,还请君留步!👋</h2>
<h3>这里有 Android 开发工具、UI 设计、Gradle 插件、Xposed 模块和实用软件等相关项目。</h3>
<h3>如果下方的项目能为你提供帮助,不妨为我点个 star 吧!</h3>
<h3>所有项目免费、开源,遵循对应开源许可协议。</h3>
<h1><a href="https://github.com/fankes/fankes/blob/main/project-promote/README-zh-CN.md">→ 查看更多关于我的项目,请点击这里 ←</a></h1>
</div>
## Star History
![Star History Chart](https://api.star-history.com/svg?repos=HighCapable/SweetProperty&type=Date)
@@ -61,7 +76,7 @@
```
Apache License Version 2.0
Copyright (C) 2019-2023 HighCapable
Copyright (C) 2019 HighCapable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -76,4 +91,4 @@ See the License for the specific language governing permissions and
limitations under the License.
```
版权所有 © 2019-2023 HighCapable
版权所有 © 2019 HighCapable

View File

@@ -1,14 +1,20 @@
# Sweet Property
[![GitHub license](https://img.shields.io/github/license/HighCapable/SweetProperty?color=blue)](https://github.com/HighCapable/SweetProperty/blob/master/LICENSE)
[![GitHub release](https://img.shields.io/github/v/release/HighCapable/SweetProperty?display_name=release&logo=github&color=green)](https://github.com/HighCapable/SweetProperty/releases)
[![Telegram](https://img.shields.io/badge/discussion-Telegram-blue.svg?logo=telegram)](https://t.me/HighCapable_Dev)
[![GitHub license](https://img.shields.io/github/license/HighCapable/SweetProperty?color=blue&style=flat-square)](https://github.com/HighCapable/SweetProperty/blob/master/LICENSE)
[![GitHub release](https://img.shields.io/github/v/release/HighCapable/SweetProperty?display_name=release&logo=github&color=green&style=flat-square)](https://github.com/HighCapable/SweetProperty/releases)
[![Telegram](https://img.shields.io/badge/discussion-Telegram-blue.svg?logo=telegram&style=flat-square)](https://t.me/HighCapable_Dev)
[![QQ](https://img.shields.io/badge/discussion-QQ-blue.svg?logo=tencent-qq&logoColor=red&style=flat-square)](https://qm.qq.com/cgi-bin/qm/qr?k=Pnsc5RY6N2mBKFjOLPiYldbAbprAU3V7&jump_from=webapi&authKey=X5EsOVzLXt1dRunge8ryTxDRrh9/IiW1Pua75eDLh9RE3KXE+bwXIYF5cWri/9lf)
<img src="https://github.com/HighCapable/SweetProperty/blob/master/img-src/icon.png?raw=true" width = "100" height = "100" alt="LOGO"/>
<img src="img-src/icon.png" width = "100" height = "100" alt="LOGO"/>
An easy get project properties anywhere Gradle plugin.
English | [简体中文](https://github.com/HighCapable/SweetProperty/blob/master/README-zh-CN.md)
English | [简体中文](README-zh-CN.md)
| <img src="https://github.com/HighCapable/.github/blob/main/img-src/logo.jpg?raw=true" width = "30" height = "30" alt="LOGO"/> | [HighCapable](https://github.com/HighCapable) |
|-------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------|
This project belongs to the above-mentioned organization, **click the link above to follow this organization** and discover more good projects.
## What's this
@@ -43,11 +49,11 @@ Some functions may be incompatible, support will be gradually dropped in the fut
## Get Started
- [Click here](https://github.com/HighCapable/SweetProperty/blob/master/docs/guide.md) to view the documentation
- [Click here](docs/guide.md) to view the documentation
## Changelog
- [Click here](https://github.com/HighCapable/SweetProperty/blob/master/docs/changelog.md) to view the historical changelog
- [Click here](docs/changelog.md) to view the historical changelog
## Promotion
@@ -56,6 +62,15 @@ you can check out the [SweetDependency](https://github.com/HighCapable/SweetDepe
This project also uses **SweetDependency**.
<!--suppress HtmlDeprecatedAttribute -->
<div align="center">
<h2>Hey, please stay! 👋</h2>
<h3>Here are related projects such as Android development tools, UI design, Gradle plugins, Xposed Modules and practical software. </h3>
<h3>If the project below can help you, please give me a star! </h3>
<h3>All projects are free, open source, and follow the corresponding open source license agreement. </h3>
<h1><a href="https://github.com/fankes/fankes/blob/main/project-promote/README.md">→ To see more about my projects, please click here ←</a></h1>
</div>
## Star History
![Star History Chart](https://api.star-history.com/svg?repos=HighCapable/SweetProperty&type=Date)
@@ -67,7 +82,7 @@ This project also uses **SweetDependency**.
```
Apache License Version 2.0
Copyright (C) 2019-2023 HighCapable
Copyright (C) 2019 HighCapable
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -82,4 +97,4 @@ See the License for the specific language governing permissions and
limitations under the License.
```
Copyright © 2019-2023 HighCapable
Copyright © 2019 HighCapable

View File

@@ -1,16 +1,4 @@
plugins {
autowire(libs.plugins.kotlin.jvm) apply false
}
allprojects {
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>().configureEach {
kotlinOptions {
jvmTarget = "17"
freeCompilerArgs = listOf(
"-Xno-param-assertions",
"-Xno-call-assertions",
"-Xno-receiver-assertions"
)
}
}
autowire(libs.plugins.maven.publish) apply false
}

View File

@@ -16,4 +16,34 @@
- 作废了 ~~`propertiesFileName`~~ 方法
- 新增 `propertiesFileNames` 方法,现在你可以同时设置一组属性配置文件名称了
- 新增 `includeKeys` 方法,现在你可以设置仅包含的属性键值名称数组了
- 新增 `keyValuesRules` 方法,现在你可以在属性键值装载过程中修改键值内容的实际解析结果
- 新增 `keyValuesRules` 方法,现在你可以在属性键值装载过程中修改键值内容的实际解析结果
## 1.0.3 | 2023.09.26
- 自动生成代码功能将始终输出源码文件,以方便在生成失败的时候进行调试
- 修复 Gradle 生命周期问题
- 修复根项目大小写变化后识别为两个项目的问题
- 修复在全局配置中使用过其它配置方法后,子项目的 `all` 方法失效问题
- 改进并采用 Gradle 项目命名规范
- 新增插件自身检查更新功能
- 一些其它功能性的改进
## 1.0.4 | 2023.11.04
- 修复类似 `a=some``a_b=some` 的属性键值名称会造成重复方法名称的问题
- 修复使用 `${...}` 生成的插值内容依然会携带字符串类型引号问题
- 生成的代码使用 `@Nonnull` 标记以使其能够在 Kotlin DSL 脚本中识别为非空返回值类型
- 新增 `project(...)` 配置方法支持同时配置多个项目
- 一些其它功能性的改进
## 1.0.5 | 2023.11.08
- 修复遇到特殊字符和重复键值名称造成代码生成失败的严重问题
## 1.0.7 | 2025.08.19
- 修复在新版 Android Gradle Plugin 及 Android Studio/IDEA 中部署源码路径时的错误
`removeContentEntry: removed content entry url 'build/generated/sweet-property' still exists after removing`
- 新增 `sourceSetName` 方法,允许自定义要部署的源集名称
- 修复在类型自动转换过程中某些 `commit id` 和 Hash 可能被识别为数值类型的问题
- 合并 [#1](https://github.com/HighCapable/SweetProperty/pull/1) 并重新发布版本 (1.0.7)

View File

@@ -17,4 +17,34 @@
- 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
- Added `keyValuesRules` method, now you can modify the actual parsing result of the value content during the properties key-values loading process
## 1.0.3 | 2023.09.26
- The automatic code generation function will always output source code files to facilitate debugging when the generation fails
- Fix Gradle lifecycle problem
- Fix root project was recognized as two projects after the case was changed
- Fix `all` function of the sub-project fails after using other configuration functions in the global configuration
- Improve and adopt Gradle project naming convention
- Added plugin own update function
- Some other functional improvements
## 1.0.4 | 2023.11.04
- Fix the issue where attribute key value names like `a=some` and `a_b=some` would cause duplicate method names
- Fix the problem that the interpolation content generated using `${...}` still carries string type quotes
- Generated code is marked with `@Nonnull` to make it recognized as a non-null return type in Kotlin DSL scripts
- Added `project(...)` configuration method to support configuring multiple projects at the same time
- Some other functional improvements
## 1.0.5 | 2023.11.08
- Fix a serious issue that caused code generation failure when encountering special characters and duplicate key-value names
## 1.0.7 | 2025.08.19
- Fix errors when deploying source code paths in the new version of Android Gradle Plugin and Android Studio/IDEA
`removeContentEntry: removed content entry url 'build/generated/sweet-property' still exists after removing`
- Added the `sourceSetName` method to allow customization of the source set name to be deployed
- Fix an issue where some `commit id` and Hash might be recognized as numeric types during the automatic type conversion process
- Merge [#1](https://github.com/HighCapable/SweetProperty/pull/1) and re-release the version (1.0.7)

View File

@@ -155,6 +155,10 @@ sweetProperty {
// 默认为 "build/generated/sweet-property"
// 建议将生成的代码放置于 "build" 目录下,因为生成的代码不建议去修改它
generateDirPath = "build/generated/sweet-property"
// 自定义部署的 `sourceSet` 名称
// 如果你的项目源码部署名称不是默认值,可以在这里自定义
// 默认为 "main"
sourceSetName = "main"
// 自定义生成的包名
// Android 项目默认使用 "android" 配置方法块中的 "namespace"
// 普通的 Kotlin on Jvm 项目默认使用项目设置的 "project.group"
@@ -194,13 +198,28 @@ sweetProperty {
// 配置 "buildScript"
}
}
// 子项目配置
// 其它项目与子项目配置
// 在方法参数中填入需要配置的项目完整名称来配置对应的项目
// 如果你的项目为嵌套型子项目,例如 app → sub
// 此时你需要使用 ":" 来分隔多个子项目,例如 "app:sub"
// 你不需要再填写子项目前面的 ":",例如 ":app"
// 如果当前项目是子项目,你必须填写子项目前面的 ":",例如 ":app"
// 如果当前项目为嵌套型子项目,例如 appsub
// 此时你需要使用 ":" 来分隔多个子项目,例如 ":app:sub"
// 注意:在 1.0.2 版本及以前是不需要添加 ":" 来标识子项目的,且添加后会报错
// 这是一个错误做法,目前统一了 Gradle 的项目命名规范,请使用新的规范
// 根项目的名称不能直接用来配置子项目,请使用 "rootProject"
project("app") {
project(":app") {
all {
// 配置 "all"
}
sourcesCode {
// 配置 "sourcesCode"
}
buildScript {
// 配置 "buildScript"
}
}
// 同时进行多个项目与子项目配置
// 在方法参数中填入需要配置的项目完整名称数组来配置每个对应的项目
project(":modules:library1", ":modules:library2") {
all {
// 配置 "all"
}

View File

@@ -168,6 +168,10 @@ sweetProperty {
// It is recommended to place the generated code in the "build" directory,
// because the generated code is not recommended to be modified
generateDirPath = "build/generated/sweet-property"
// Custom deployed `sourceSet` name
// If your project source code deployment name is not the default value, you can customize it here
// Defaults to "main"
sourceSetName = "main"
// Custom generated package name
// Android projects use the "namespace" in the "android" configuration method block by default
// Ordinary Kotlin on Jvm projects use the "project.group" of the project settings by default
@@ -208,13 +212,29 @@ sweetProperty {
// Configure "buildScript"
}
}
// Sub-projects configuration
// Other projects and sub-projects configurations
// Fill in the full name of the project that needs to be configured in the method parameters to configure the corresponding project
// If your project is a nested sub-projects, such as app → sub
// At this point you need to use ":" to separate multiple sub-projects, such as "app:sub"
// You don't need to fill in the ":" in front of the sub-projects, such as ":app"
// If the current project is a sub-project, you must fill in the ":" in front of the sub-project, such as ":app"
// If the current project is a nested sub-project, such as appsub
// At this time you need to use ":" to separate multiple sub-projects, such as ":app:sub"
// Note: In version 1.0.2 and before, there is no need to add ":" to identify sub-projects, and an error will be thrown after adding it
// This is a wrong approach, Gradle's project naming convention is currently unified, please use the new convention
// The name of the root project cannot be used directly to configure sub-projects, please use "rootProject"
project("app") {
project(":app") {
all {
// Configure "all"
}
sourcesCode {
// Configure "sourcesCode"
}
buildScript {
// Configure "buildScript"
}
}
// Configure multiple projects and sub-projects at the same time
// Fill in the method parameters with the array of complete names of the projects that need to be configured
// to configure each corresponding project
project(":modules:library1", ":modules:library2") {
all {
// Configure "all"
}
@@ -225,7 +245,6 @@ sweetProperty {
// Configure "buildScript"
}
}
}
```
If you want to use it in Groovy DSL, please change the `=` of all variables to spaces, delete the `is` in front of `Enable` and lowercase `E`.

View File

@@ -1,19 +1,27 @@
# Project Configuration
project.name=SweetProperty
project.description=An easy get project properties anywhere Gradle plugin
project.url=https://github.com/HighCapable/SweetProperty
project.groupName=com.highcapable.sweetproperty
project.moduleName=sweet-property
project.version=1.0.2
project.licence.name=Apache License 2.0
project.licence.url=https://github.com/HighCapable/SweetProperty/blob/master/LICENSE
project.developer.id=0
project.developer.name=fankes
project.developer.email=qzmmcn@163.com
project.version=1.0.7
# Gradle Plugin Configuration
gradle.plugin.moduleName=${project.groupName}.gradle.plugin
gradle.plugin.implementationClass=${project.groupName}.plugin.SweetPropertyPlugin
# Maven Publish Configuration
maven.publish.scm.connection=scm:git:git://github.com/HighCapable/SweetProperty
maven.publish.scm.developerConnection=scm:git:ssh://github.com/HighCapable/SweetProperty
maven.publish.scm.url=https://github.com/HighCapable/SweetProperty
SONATYPE_HOST=CENTRAL_PORTAL
RELEASE_SIGNING_ENABLED=true
# Maven POM Configuration
POM_NAME=SweetProperty
POM_ARTIFACT_ID=sweet-property
POM_DESCRIPTION=An easy get project properties anywhere Gradle plugin.
POM_URL=https://github.com/HighCapable/SweetProperty
POM_LICENSE_NAME=Apache License 2.0
POM_LICENSE_URL=https://github.com/HighCapable/SweetProperty/blob/master/LICENSE
POM_LICENSE_DIST=repo
POM_SCM_URL=https://github.com/HighCapable/SweetProperty
POM_SCM_CONNECTION=scm:git:git://github.com/HighCapable/SweetProperty
POM_SCM_DEV_CONNECTION=scm:git:ssh://github.com/HighCapable/SweetProperty
POM_DEVELOPER_ID=0
POM_DEVELOPER_NAME=fankes
POM_DEVELOPER_EMAIL=qzmmcn@163.com
POM_DEVELOPER_URL=https://github.com/fankes

View File

@@ -12,15 +12,18 @@ repositories:
plugins:
org.jetbrains.kotlin.jvm:
alias: kotlin-jvm
version: 1.9.10
version: 2.1.10
com.vanniktech.maven.publish:
alias: maven-publish
version: 0.25.3
version: 0.31.0
libraries:
com.squareup.okhttp3:
okhttp:
version: 4.12.0
com.squareup:
kotlinpoet:
version: 1.14.2
version: 2.1.0
javapoet:
version: 1.13.0
net.lingala.zip4j:

View File

@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View File

@@ -1,4 +1,3 @@
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
pluginManagement {
repositories {
gradlePluginPortal()
@@ -8,8 +7,8 @@ pluginManagement {
}
}
plugins {
id("com.highcapable.sweetdependency") version "1.0.1"
id("com.highcapable.sweetproperty") version "1.0.2"
id("com.highcapable.sweetdependency") version "1.0.4"
id("com.highcapable.sweetproperty") version "1.0.7"
}
sweetDependency {
isEnableVerboseMode = false
@@ -18,13 +17,14 @@ sweetProperty {
global {
sourcesCode {
className = rootProject.name
includeKeys(
"^project\\..*\$".toRegex(),
"^gradle\\..*\$".toRegex()
)
isEnableRestrictedAccess = true
}
}
rootProject { sourcesCode { isEnable = false } }
project("sweetproperty-gradle-plugin") {
buildScript { isEnableTypeAutoConversion = false }
}
rootProject { all { isEnable = false } }
}
rootProject.name = "SweetProperty"
include(":sweetproperty-gradle-plugin")

View File

@@ -1,2 +0,0 @@
.gradle
build/

View File

@@ -4,23 +4,29 @@ plugins {
autowire(libs.plugins.maven.publish)
}
allprojects {
group = property.project.groupName
version = property.project.version
}
group = property.project.groupName
version = property.project.version
java {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
withSourcesJar()
}
kotlin {
jvmToolchain(17)
jvmToolchain(21)
sourceSets.all { languageSettings { languageVersion = "2.0" } }
compilerOptions {
freeCompilerArgs = listOf(
"-Xno-param-assertions",
"-Xno-call-assertions",
"-Xno-receiver-assertions"
)
}
}
dependencies {
implementation(com.squareup.okhttp3.okhttp)
implementation(com.squareup.kotlinpoet)
implementation(com.squareup.javapoet)
implementation(net.lingala.zip4j.zip4j)
@@ -33,34 +39,4 @@ gradlePlugin {
implementationClass = property.gradle.plugin.implementationClass
}
}
}
mavenPublishing {
coordinates(property.project.groupName, property.project.moduleName, property.project.version)
pom {
name = property.project.name
description = property.project.description
url = property.project.url
licenses {
license {
name = property.project.licence.name
url = property.project.licence.url
distribution = property.project.licence.url
}
}
developers {
developer {
id = property.project.developer.id
name = property.project.developer.name
email = property.project.developer.email
}
}
scm {
url = property.maven.publish.scm.url
connection = property.maven.publish.scm.connection
developerConnection = property.maven.publish.scm.developerConnection
}
}
publishToMavenCentral(com.vanniktech.maven.publish.SonatypeHost.S01)
signAllPublications()
}

View File

@@ -1,6 +1,6 @@
/*
* SweetProperty - An easy get project properties anywhere Gradle plugin
* Copyright (C) 2019-2023 HighCapable
* SweetProperty - An easy get project properties anywhere Gradle plugin.
* Copyright (C) 2019 HighCapable
* https://github.com/HighCapable/SweetProperty
*
* Apache License Version 2.0
@@ -17,7 +17,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is Created by fankes on 2023/8/25.
* This file is created by fankes on 2023/8/25.
*/
package com.highcapable.sweetproperty

View File

@@ -1,6 +1,6 @@
/*
* SweetProperty - An easy get project properties anywhere Gradle plugin
* Copyright (C) 2019-2023 HighCapable
* SweetProperty - An easy get project properties anywhere Gradle plugin.
* Copyright (C) 2019 HighCapable
* https://github.com/HighCapable/SweetProperty
*
* Apache License Version 2.0
@@ -17,7 +17,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is Created by fankes on 2023/8/28.
* This file is created by fankes on 2023/8/28.
*/
package com.highcapable.sweetproperty.gradle.entity
@@ -43,11 +43,12 @@ internal class ProjectDescriptor private constructor() {
* @return [ProjectDescriptor]
*/
internal fun create(settings: Settings, name: String = "") = ProjectDescriptor().also {
val isRootProject = name.isBlank() || name == settings.rootProject.name
val isRootProject = name.isBlank() || name.lowercase() == settings.rootProject.name.lowercase()
val subProjectNotice = "if this is a sub-project, please set it like \":$name\""
it.type = Type.SETTINGS
it.name = name.noBlank() ?: settings.rootProject.name
it.currentDir = (if (isRootProject) settings.rootProject else settings.findProject(":$name"))?.projectDir
?: SError.make("Project \"$name\" not found")
it.currentDir = (if (isRootProject) settings.rootProject else settings.findProject(name))?.projectDir
?: SError.make("Project \"$name\" not found${if (!name.startsWith(":")) ", $subProjectNotice" else ""}")
it.rootDir = settings.rootDir
it.homeDir = settings.gradle.gradleUserHomeDir
}
@@ -59,7 +60,7 @@ internal class ProjectDescriptor private constructor() {
*/
internal fun create(project: Project) = ProjectDescriptor().also {
it.type = Type.PROJECT
it.name = project.fullName
it.name = project.fullName()
it.currentDir = project.projectDir
it.rootDir = project.rootDir
it.homeDir = project.gradle.gradleUserHomeDir

View File

@@ -1,6 +1,6 @@
/*
* SweetProperty - An easy get project properties anywhere Gradle plugin
* Copyright (C) 2019-2023 HighCapable
* SweetProperty - An easy get project properties anywhere Gradle plugin.
* Copyright (C) 2019 HighCapable
* https://github.com/HighCapable/SweetProperty
*
* Apache License Version 2.0
@@ -17,7 +17,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is Created by fankes on 2023/8/27.
* This file is created by fankes on 2023/8/27.
*/
@file:Suppress("unused", "USELESS_CAST", "KotlinRedundantDiagnosticSuppress")
@@ -37,7 +37,7 @@ import org.gradle.api.plugins.ExtensionAware
*/
internal fun ExtensionAware.getOrCreate(name: String, clazz: Class<*>, vararg args: Any?) = name.toSafeExtName().let { sName ->
runCatching { extensions.create(sName, clazz, *args).asExtension() }.getOrElse {
if ((it is IllegalArgumentException && it.message?.startsWith("Cannot add extension with name") == true).not()) throw it
if (!(it is IllegalArgumentException && it.message?.startsWith("Cannot add extension with name") == true)) throw it
runCatching { extensions.getByName(sName).asExtension() }.getOrNull() ?: SError.make("Create or get extension failed with name \"$sName\"")
}
}
@@ -50,7 +50,7 @@ internal fun ExtensionAware.getOrCreate(name: String, clazz: Class<*>, vararg ar
*/
internal inline fun <reified T> ExtensionAware.getOrCreate(name: String, vararg args: Any?) = name.toSafeExtName().let { sName ->
runCatching { extensions.create(sName, T::class.java, *args) as T }.getOrElse {
if ((it is IllegalArgumentException && it.message?.startsWith("Cannot add extension with name") == true).not()) throw it
if (!(it is IllegalArgumentException && it.message?.startsWith("Cannot add extension with name") == true)) throw it
runCatching { extensions.getByName(sName) as? T? }.getOrNull() ?: SError.make("Create or get extension failed with name \"$sName\"")
}
}

View File

@@ -1,6 +1,6 @@
/*
* SweetProperty - An easy get project properties anywhere Gradle plugin
* Copyright (C) 2019-2023 HighCapable
* SweetProperty - An easy get project properties anywhere Gradle plugin.
* Copyright (C) 2019 HighCapable
* https://github.com/HighCapable/SweetProperty
*
* Apache License Version 2.0
@@ -17,7 +17,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is Created by fankes on 2023/8/27.
* This file is created by fankes on 2023/8/27.
*/
package com.highcapable.sweetproperty.gradle.factory
@@ -29,23 +29,23 @@ import org.gradle.kotlin.dsl.repositories
/**
* 获取指定项目的完整名称
* @param isUseColon 是否在子项目前使用冒号 - 默认是
* @return [String]
*/
internal val Project.fullName
get(): String {
val baseNames = mutableListOf<String>()
internal fun Project.fullName(isUseColon: Boolean = true): String {
val isRoot = this == rootProject
val baseNames = mutableListOf<String>()
/**
* 递归子项目
* @param project 当前项目
*/
fun fetchChild(project: Project) {
project.parent?.also { if (it != it.rootProject) fetchChild(it) }
baseNames.add(project.name)
}
fetchChild(project = this)
return buildString { baseNames.onEach { append(":$it") }.clear() }.drop(1)
}
/**
* 递归子项目
* @param project 当前项目
*/
fun fetchChild(project: Project) {
project.parent?.also { if (it != it.rootProject) fetchChild(it) }
baseNames.add(project.name)
}; fetchChild(project = this)
return buildString { baseNames.onEach { append(":$it") }.clear() }.let { if (isUseColon && !isRoot) it else it.drop(1) }
}
/**
* 向构建脚本添加自定义依赖

View File

@@ -1,6 +1,6 @@
/*
* SweetProperty - An easy get project properties anywhere Gradle plugin
* Copyright (C) 2019-2023 HighCapable
* SweetProperty - An easy get project properties anywhere Gradle plugin.
* Copyright (C) 2019 HighCapable
* https://github.com/HighCapable/SweetProperty
*
* Apache License Version 2.0
@@ -17,7 +17,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is Created by fankes on 2023/8/27.
* This file is created by fankes on 2023/8/27.
*/
package com.highcapable.sweetproperty.gradle.proxy

View File

@@ -1,6 +1,6 @@
/*
* SweetProperty - An easy get project properties anywhere Gradle plugin
* Copyright (C) 2019-2023 HighCapable
* SweetProperty - An easy get project properties anywhere Gradle plugin.
* Copyright (C) 2019 HighCapable
* https://github.com/HighCapable/SweetProperty
*
* Apache License Version 2.0
@@ -17,7 +17,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is Created by fankes on 2023/8/27.
* This file is created by fankes on 2023/8/27.
*/
package com.highcapable.sweetproperty.plugin
@@ -25,6 +25,7 @@ import com.highcapable.sweetproperty.SweetProperty
import com.highcapable.sweetproperty.gradle.factory.getOrCreate
import com.highcapable.sweetproperty.gradle.proxy.IGradleLifecycle
import com.highcapable.sweetproperty.plugin.extension.dsl.configure.SweetPropertyConfigureExtension
import com.highcapable.sweetproperty.plugin.helper.PluginUpdateHelper
import com.highcapable.sweetproperty.plugin.helper.PropertiesDeployHelper
import com.highcapable.sweetproperty.utils.debug.SError
import org.gradle.api.Project
@@ -44,6 +45,7 @@ internal class SweetPropertyExtension internal constructor() : IGradleLifecycle
override fun onSettingsEvaluate(settings: Settings) {
val configs = configure?.build(settings) ?: SError.make("Extension \"${SweetPropertyConfigureExtension.NAME}\" create failed")
PluginUpdateHelper.checkingForUpdate(settings)
PropertiesDeployHelper.initialize(settings, configs)
}

View File

@@ -1,6 +1,6 @@
/*
* SweetProperty - An easy get project properties anywhere Gradle plugin
* Copyright (C) 2019-2023 HighCapable
* SweetProperty - An easy get project properties anywhere Gradle plugin.
* Copyright (C) 2019 HighCapable
* https://github.com/HighCapable/SweetProperty
*
* Apache License Version 2.0
@@ -17,7 +17,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is Created by fankes on 2023/8/25.
* This file is created by fankes on 2023/8/25.
*/
@file:Suppress("unused")
@@ -42,10 +42,10 @@ class SweetPropertyPlugin<T : ExtensionAware> internal constructor() : Plugin<T>
extension.onSettingsLoaded(target)
target.gradle.settingsEvaluated { extension.onSettingsEvaluate(target) }
target.gradle.projectsLoaded {
extension.onProjectLoaded(rootProject)
rootProject.afterEvaluate { extension.onProjectEvaluate(rootProject) }
rootProject.beforeEvaluate { extension.onProjectLoaded(rootProject = this) }
rootProject.afterEvaluate { extension.onProjectEvaluate(rootProject = this) }
}
}
else -> SError.make("${SweetProperty.TAG} can only applied in settings.gradle/settings.gradle.kts, but current is $target")
else -> SError.make("${SweetProperty.TAG} can only applied in settings.gradle or settings.gradle.kts, but current is $target")
}
}

View File

@@ -1,6 +1,6 @@
/*
* SweetProperty - An easy get project properties anywhere Gradle plugin
* Copyright (C) 2019-2023 HighCapable
* SweetProperty - An easy get project properties anywhere Gradle plugin.
* Copyright (C) 2019 HighCapable
* https://github.com/HighCapable/SweetProperty
*
* Apache License Version 2.0
@@ -17,7 +17,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is Created by fankes on 2023/8/28.
* This file is created by fankes on 2023/8/28.
*/
package com.highcapable.sweetproperty.plugin.config.default
@@ -56,6 +56,7 @@ internal object DefaultConfigs {
) = object : ISweetPropertyConfigs.ISourcesCodeGenerateConfigs {
override val name get() = name
override val generateDirPath get() = ISweetPropertyConfigs.DEFAULT_GENERATE_DIR_PATH
override val sourceSetName get() = ISweetPropertyConfigs.DEFAULT_SOURCE_SET_NAME
override val packageName get() = ""
override val className get() = ""
override val isEnableRestrictedAccess get() = false

View File

@@ -1,6 +1,6 @@
/*
* SweetProperty - An easy get project properties anywhere Gradle plugin
* Copyright (C) 2019-2023 HighCapable
* SweetProperty - An easy get project properties anywhere Gradle plugin.
* Copyright (C) 2019 HighCapable
* https://github.com/HighCapable/SweetProperty
*
* Apache License Version 2.0
@@ -17,7 +17,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is Created by fankes on 2023/8/28.
* This file is created by fankes on 2023/8/28.
*/
package com.highcapable.sweetproperty.plugin.config.factory
@@ -33,7 +33,7 @@ import org.gradle.api.Project
* @param project 当前项目
* @return [ISweetPropertyConfigs.ISubConfigs]
*/
internal fun ISweetPropertyConfigs.with(project: Project) = projects[project.fullName] ?: global
internal fun ISweetPropertyConfigs.with(project: Project) = projects[project.fullName()] ?: global
/**
* 创建 [ISweetPropertyConfigs.ISubConfigs] 实例
@@ -47,12 +47,12 @@ internal fun SweetPropertyConfigureExtension.SubConfigureExtension.create(
) = object : ISweetPropertyConfigs.ISubConfigs {
override val sourcesCode
get() = this@create.sourcesCodeConfigure?.create(name, global.sourcesCodeConfigure, this@create.allConfigure, global.allConfigure)
?: global.sourcesCodeConfigure?.create(name, globalBase = global.allConfigure)
?: DefaultConfigs.subConfigs(name, global.allConfigure).sourcesCode
?: global.sourcesCodeConfigure?.create(name, globalBase = this@create.allConfigure ?: global.allConfigure)
?: DefaultConfigs.subConfigs(name, base = this@create.allConfigure ?: global.allConfigure).sourcesCode
override val buildScript
get() = this@create.buildScriptConfigure?.create(name, global.buildScriptConfigure, this@create.allConfigure, global.allConfigure)
?: global.buildScriptConfigure?.create(name, globalBase = global.allConfigure)
?: DefaultConfigs.subConfigs(name, global.allConfigure).buildScript
?: global.buildScriptConfigure?.create(name, globalBase = this@create.allConfigure ?: global.allConfigure)
?: DefaultConfigs.subConfigs(name, base = this@create.allConfigure ?: global.allConfigure).buildScript
}
/**
@@ -74,6 +74,10 @@ private fun SweetPropertyConfigureExtension.SourcesCodeGenerateConfigureExtensio
get() = this@create.generateDirPath.noBlank()
?: global?.generateDirPath?.noBlank()
?: DefaultConfigs.sourcesCodeGenerateConfigs(name, selfBase, globalBase).generateDirPath
override val sourceSetName
get() = this@create.sourceSetName.noBlank()
?: global?.sourceSetName?.noBlank()
?: DefaultConfigs.sourcesCodeGenerateConfigs(name, selfBase, globalBase).sourceSetName
override val packageName
get() = this@create.packageName.noBlank()
?: global?.packageName?.noBlank()

View File

@@ -1,6 +1,6 @@
/*
* SweetProperty - An easy get project properties anywhere Gradle plugin
* Copyright (C) 2019-2023 HighCapable
* SweetProperty - An easy get project properties anywhere Gradle plugin.
* Copyright (C) 2019 HighCapable
* https://github.com/HighCapable/SweetProperty
*
* Apache License Version 2.0
@@ -17,7 +17,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is Created by fankes on 2023/8/25.
* This file is created by fankes on 2023/8/25.
*/
package com.highcapable.sweetproperty.plugin.config.proxy
@@ -40,6 +40,11 @@ internal interface ISweetPropertyConfigs {
*/
internal const val DEFAULT_GENERATE_DIR_PATH = "build/generated/${SweetPropertyProperties.PROJECT_MODULE_NAME}"
/**
* 默认的部署 `sourceSet` 名称
*/
internal const val DEFAULT_SOURCE_SET_NAME = "main"
/**
* 默认的属性配置文件名称
*
@@ -91,6 +96,9 @@ internal interface ISweetPropertyConfigs {
/** 自定义生成的目录路径 */
val generateDirPath: String
/** 自定义部署的 `sourceSet` 名称 */
val sourceSetName: String
/** 自定义生成的包名 */
val packageName: String

View File

@@ -1,6 +1,6 @@
/*
* SweetProperty - An easy get project properties anywhere Gradle plugin
* Copyright (C) 2019-2023 HighCapable
* SweetProperty - An easy get project properties anywhere Gradle plugin.
* Copyright (C) 2019 HighCapable
* https://github.com/HighCapable/SweetProperty
*
* Apache License Version 2.0
@@ -17,7 +17,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is Created by fankes on 2023/8/25.
* This file is created by fankes on 2023/8/25.
*/
@file:Suppress("unused")

View File

@@ -1,6 +1,6 @@
/*
* SweetProperty - An easy get project properties anywhere Gradle plugin
* Copyright (C) 2019-2023 HighCapable
* SweetProperty - An easy get project properties anywhere Gradle plugin.
* Copyright (C) 2019 HighCapable
* https://github.com/HighCapable/SweetProperty
*
* Apache License Version 2.0
@@ -17,7 +17,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is Created by fankes on 2023/8/27.
* This file is created by fankes on 2023/8/27.
*/
package com.highcapable.sweetproperty.plugin.extension.accessors.proxy

View File

@@ -1,6 +1,6 @@
/*
* SweetProperty - An easy get project properties anywhere Gradle plugin
* Copyright (C) 2019-2023 HighCapable
* SweetProperty - An easy get project properties anywhere Gradle plugin.
* Copyright (C) 2019 HighCapable
* https://github.com/HighCapable/SweetProperty
*
* Apache License Version 2.0
@@ -17,9 +17,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is Created by fankes on 2023/8/25.
* This file is created by fankes on 2023/8/25.
*/
@file:Suppress("unused", "MemberVisibilityCanBePrivate", "PropertyName")
@file:Suppress("unused", "MemberVisibilityCanBePrivate", "PropertyName", "DeprecatedCallableAddReplaceWith")
package com.highcapable.sweetproperty.plugin.extension.dsl.configure
@@ -92,14 +92,22 @@ open class SweetPropertyConfigureExtension internal constructor() {
* 配置根项目
* @param action 配置方法体
*/
fun rootProject(action: Action<SubConfigureExtension>) = project(ROOT_PROJECT_TAG, action)
fun rootProject(action: Action<SubConfigureExtension>) = configureProject(ROOT_PROJECT_TAG, action)
/**
* 配置指定项目
* 配置指定项目 (数组)
* @param names 项目完整名称 (数组)
* @param action 配置方法体
*/
fun project(vararg names: String, action: Action<SubConfigureExtension>) = names.forEach { configureProject(it, action) }
/**
* 配置项目
* @param name 项目完整名称
* @param action 配置方法体
*/
fun project(name: String, action: Action<SubConfigureExtension>) = action.execute(SubConfigureExtension().also { projectConfigures[name] = it })
private fun configureProject(name: String, action: Action<SubConfigureExtension>) =
action.execute(SubConfigureExtension().also { projectConfigures[name] = it })
/**
* 子配置方法体实现类
@@ -115,6 +123,16 @@ open class SweetPropertyConfigureExtension internal constructor() {
/** 当前构建脚本生成代码功能配置实例 */
internal var buildScriptConfigure: BuildScriptGenerateConfigureExtension? = null
/**
* 错误的调用会导致关闭整个插件的功能
*
* 请使用 [all]、[sourcesCode]、[buildScript]
* @throws [IllegalStateException]
*/
@Deprecated(message = "Do not use", level = DeprecationLevel.ERROR)
val isEnable: Boolean
get() = SError.make("Please called all { isEnable = ... }, sourcesCode { isEnable = ... }, buildScript { isEnable = ... }")
/**
* 配置通用生成代码功能
* @param action 配置方法体
@@ -155,6 +173,16 @@ open class SweetPropertyConfigureExtension internal constructor() {
var generateDirPath = ""
@JvmName("generateDirPath") set
/**
* 自定义部署的 `sourceSet` 名称
*
* 如果你的项目源码部署名称不是默认值 - 可以在这里自定义
*
* 默认为 [ISweetPropertyConfigs.DEFAULT_SOURCE_SET_NAME]
*/
var sourceSetName = ""
@JvmName("sourceSetName") set
/**
* 自定义生成的包名
*
@@ -456,13 +484,13 @@ open class SweetPropertyConfigureExtension internal constructor() {
/** 检查合法包名 */
fun String.checkingValidPackageName() {
if (isNotBlank() && matches("^[a-zA-Z_][a-zA-Z0-9_]*(\\.[a-zA-Z_][a-zA-Z0-9_]*)*$".toRegex()).not())
if (isNotBlank() && !matches("^[a-zA-Z_][a-zA-Z0-9_]*(\\.[a-zA-Z_][a-zA-Z0-9_]*)*$".toRegex()))
SError.make("Invalid package name \"$this\"")
}
/** 检查合法类名 */
fun String.checkingValidClassName() {
if (isNotBlank() && matches("^[a-zA-Z][a-zA-Z0-9_]*$".toRegex()).not())
if (isNotBlank() && !matches("^[a-zA-Z][a-zA-Z0-9_]*$".toRegex()))
SError.make("Invalid class name \"$this\"")
}
@@ -483,14 +511,14 @@ open class SweetPropertyConfigureExtension internal constructor() {
val currentGlobal = globalConfigure.create()
val currentProjects = mutableMapOf<String, ISweetPropertyConfigs.ISubConfigs>()
val rootName = settings.rootProject.name
if (projectConfigures.containsKey(rootName))
if (projectConfigures.any { (name, _) -> name.lowercase() == rootName.lowercase() })
SError.make("This name \"$rootName\" is a root project, please use rootProject function to configure it, not project(\"$rootName\")")
if (projectConfigures.containsKey(ROOT_PROJECT_TAG)) {
projectConfigures[rootName] = projectConfigures[ROOT_PROJECT_TAG] ?: SError.make("Internal error")
projectConfigures.remove(ROOT_PROJECT_TAG)
}
projectConfigures.forEach { (name, subConfigure) ->
name.checkingStartWithLetter(description = "Project")
name.replaceFirst(":", "").checkingStartWithLetter(description = "Project")
subConfigure.checkingNames()
currentProjects[name] = subConfigure.create(name, globalConfigure)
}; return object : ISweetPropertyConfigs {

View File

@@ -1,6 +1,6 @@
/*
* SweetProperty - An easy get project properties anywhere Gradle plugin
* Copyright (C) 2019-2023 HighCapable
* SweetProperty - An easy get project properties anywhere Gradle plugin.
* Copyright (C) 2019 HighCapable
* https://github.com/HighCapable/SweetProperty
*
* Apache License Version 2.0
@@ -17,7 +17,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is Created by fankes on 2023/8/27.
* This file is created by fankes on 2023/8/27.
*/
package com.highcapable.sweetproperty.plugin.generator
@@ -27,6 +27,7 @@ import com.highcapable.sweetproperty.plugin.config.proxy.ISweetPropertyConfigs
import com.highcapable.sweetproperty.plugin.extension.accessors.proxy.IExtensionAccessors
import com.highcapable.sweetproperty.plugin.generator.factory.PropertyMap
import com.highcapable.sweetproperty.plugin.generator.factory.parseTypedValue
import com.highcapable.sweetproperty.plugin.generator.factory.toOptimize
import com.highcapable.sweetproperty.utils.capitalize
import com.highcapable.sweetproperty.utils.debug.SError
import com.highcapable.sweetproperty.utils.firstNumberToLetter
@@ -40,6 +41,7 @@ import com.squareup.javapoet.MethodSpec
import com.squareup.javapoet.TypeSpec
import java.text.SimpleDateFormat
import java.util.*
import javax.annotation.Nonnull
import javax.lang.model.element.Modifier
import kotlin.properties.Delegates
@@ -84,6 +86,9 @@ internal class PropertiesAccessorsGenerator {
/** 生成的属性键值连续名称重复次数数组 */
private val grandSuccessiveDuplicateIndexs = mutableMapOf<String, Int>()
/** 生成的属性键值不重复调用方法数组 */
private val usedSuccessiveMethods = mutableMapOf<String, MutableList<String>>()
/** 生成的属性键值不重复 TAG 数组 */
private val usedSuccessiveTags = mutableSetOf<String>()
@@ -94,7 +99,7 @@ internal class PropertiesAccessorsGenerator {
*/
private inline fun noRepeated(vararg tags: String, block: () -> Unit) {
val allTag = tags.joinToString("-")
if (usedSuccessiveTags.contains(allTag).not()) block()
if (!usedSuccessiveTags.contains(allTag)) block()
usedSuccessiveTags.add(allTag)
}
@@ -177,9 +182,10 @@ internal class PropertiesAccessorsGenerator {
*/
private fun TypeSpec.Builder.addSuccessiveMethod(accessorsName: String, methodName: String, className: String) =
addMethod(
MethodSpec.methodBuilder("get${methodName.capitalize()}")
MethodSpec.methodBuilder("get${getOrCreateUsedSuccessiveMethodName(methodName, className).capitalize()}")
.addJavadoc("Resolve the \"$accessorsName\" accessors")
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
.addAnnotation(Nonnull::class.java)
.returns(className.capitalized().asClassType())
.addStatement("return ${className.uncapitalized()}")
.build()
@@ -189,17 +195,20 @@ internal class PropertiesAccessorsGenerator {
* 向通用构建器描述类添加最终键值方法
* @param accessorsName 接续名
* @param methodName 方法名
* @param className 类名
* @param value 键值内容
* @return [TypeSpec.Builder]
*/
private fun TypeSpec.Builder.addFinalValueMethod(accessorsName: String, methodName: String, value: Any) =
private fun TypeSpec.Builder.addFinalValueMethod(accessorsName: String, methodName: String, className: String, value: Any) =
addMethod(
MethodSpec.methodBuilder("get${methodName.capitalize()}").apply {
MethodSpec.methodBuilder("get${getOrCreateUsedSuccessiveMethodName(methodName, className).capitalize()}").apply {
val typedValue = value.parseTypedValue(configs.isEnableTypeAutoConversion)
addJavadoc("Resolve the \"$accessorsName\" value ${typedValue.second}")
val safeValueForJavadoc = typedValue.second.replace("$", "$$")
addJavadoc("Resolve the \"$accessorsName\" value $safeValueForJavadoc")
addModifiers(Modifier.PUBLIC, Modifier.FINAL)
.addAnnotation(Nonnull::class.java)
.returns(typedValue.first.java)
.addStatement("return ${typedValue.second}")
.addStatement("return $safeValueForJavadoc")
}.build()
)
@@ -211,6 +220,20 @@ internal class PropertiesAccessorsGenerator {
private fun MethodSpec.Builder.addSuccessiveStatement(className: String) =
addStatement("${className.uncapitalized()} = new ${className.capitalized()}()")
/**
* 获取不重复调用方法名称
* @param methodName 方法名
* @param className 类名
* @return [String]
*/
private fun getOrCreateUsedSuccessiveMethodName(methodName: String, className: String): String {
if (usedSuccessiveMethods[className] == null) usedSuccessiveMethods[className] = mutableListOf()
val methods = usedSuccessiveMethods[className]!!
val finalName = if (methods.contains(methodName)) "$methodName${methods.filter { it == methodName }.size + 1}" else methodName
methods.add(methodName)
return finalName
}
/**
* 获取、创建通用构建器描述类
* @param name 名称
@@ -234,9 +257,10 @@ internal class PropertiesAccessorsGenerator {
*
* 解析完成后需要调用 [releaseParseTypeSpec] 完成解析
* @param successiveName 连续的名称
* @param key 键值名称 (原始名称)
* @param value 键值内容
*/
private fun parseTypeSpec(successiveName: String, value: Any) {
private fun parseTypeSpec(successiveName: String, key: String, value: Any) {
/**
* 获取生成的属性键值连续名称重复次数
* @return [Int]
@@ -258,10 +282,7 @@ internal class PropertiesAccessorsGenerator {
var grandAcccessorsName = ""
var grandSuccessiveName = ""
val successiveNames = mutableListOf<Triple<String, String, String>>()
val splitNames = replace(".", "|").replace("-", "|")
.replace("_", "|").replace(" ", "_")
.split("|").dropWhile { it.isBlank() }
.ifEmpty { listOf(this) }
val splitNames = split("_").dropWhile { it.isBlank() }.ifEmpty { listOf(this) }
splitNames.forEach { eachName ->
val name = eachName.capitalize().toNonJavaName().firstNumberToLetter()
grandAcccessorsName += if (grandAcccessorsName.isNotBlank()) ".$eachName" else eachName
@@ -279,9 +300,10 @@ internal class PropertiesAccessorsGenerator {
val nextAccessorsName = nextItem?.first ?: ""
val nextClassName = nextItem?.second ?: ""
val nextMethodName = nextItem?.third ?: ""
val lastClassName = lastItem?.second ?: ""
val lastMethodName = lastItem?.third ?: ""
val isPreLastIndex = index == successiveNames.lastIndex - 1
if (successiveNames.size == 1) getOrCreateClassSpec(TOP_SUCCESSIVE_NAME).addFinalValueMethod(successiveName, methodName, value)
if (successiveNames.size == 1) getOrCreateClassSpec(TOP_SUCCESSIVE_NAME).addFinalValueMethod(key, methodName, className, value)
if (index == successiveNames.lastIndex) return@forEachIndexed
if (index == 0) noRepeated(TOP_SUCCESSIVE_NAME, methodName, className) {
getOrCreateClassSpec(TOP_SUCCESSIVE_NAME, accessorsName)
@@ -291,12 +313,12 @@ internal class PropertiesAccessorsGenerator {
}
noRepeated(className, nextMethodName, nextClassName) {
getOrCreateClassSpec(className, accessorsName).apply {
if (isPreLastIndex.not()) {
if (!isPreLastIndex) {
addSuccessiveField(nextAccessorsName, nextClassName)
addSuccessiveMethod(nextAccessorsName, nextMethodName, nextClassName)
} else addFinalValueMethod(successiveName, lastMethodName, value)
} else addFinalValueMethod(key, lastMethodName, lastClassName, value)
}
if (isPreLastIndex.not()) preAddConstructorSpecNames.add(className to nextClassName)
if (!isPreLastIndex) preAddConstructorSpecNames.add(className to nextClassName)
}
}
}
@@ -342,6 +364,7 @@ internal class PropertiesAccessorsGenerator {
preAddConstructorSpecNames.clear()
grandSuccessiveNames.clear()
grandSuccessiveDuplicateIndexs.clear()
usedSuccessiveMethods.clear()
usedSuccessiveTags.clear()
if (isClearAll) memoryExtensionClasses.clear()
}
@@ -367,8 +390,8 @@ internal class PropertiesAccessorsGenerator {
val keyValues = allKeyValues[index]
clearGeneratedData()
createTopClassSpec(configs)
keyValues.forEach { (key, value) ->
parseTypeSpec(key, value)
keyValues.toOptimize().forEach { (key, value) ->
parseTypeSpec(key, value.first, value.second)
releaseParseTypeSpec()
}; files.add(buildTypeSpec().createJavaFile(ACCESSORS_PACKAGE_NAME))
}; files
@@ -380,10 +403,15 @@ internal class PropertiesAccessorsGenerator {
*/
internal val compileStubFiles get(): List<JavaFile> {
val stubFiles = mutableListOf<JavaFile>()
val nonnullFile =
TypeSpec.annotationBuilder(Nonnull::class.java.simpleName)
.addModifiers(Modifier.PUBLIC)
.build().createJavaFile(Nonnull::class.java.packageName)
val iExtensionAccessorsFile =
TypeSpec.interfaceBuilder(IExtensionAccessors::class.java.simpleName)
.addModifiers(Modifier.PUBLIC)
.build().createJavaFile(IExtensionAccessors::class.java.packageName)
stubFiles.add(nonnullFile)
stubFiles.add(iExtensionAccessorsFile)
return stubFiles
}

View File

@@ -1,6 +1,6 @@
/*
* SweetProperty - An easy get project properties anywhere Gradle plugin
* Copyright (C) 2019-2023 HighCapable
* SweetProperty - An easy get project properties anywhere Gradle plugin.
* Copyright (C) 2019 HighCapable
* https://github.com/HighCapable/SweetProperty
*
* Apache License Version 2.0
@@ -17,7 +17,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is Created by fankes on 2023/8/27.
* This file is created by fankes on 2023/8/27.
*/
package com.highcapable.sweetproperty.plugin.generator
@@ -25,9 +25,10 @@ import com.highcapable.sweetproperty.SweetProperty
import com.highcapable.sweetproperty.plugin.config.proxy.ISweetPropertyConfigs
import com.highcapable.sweetproperty.plugin.generator.factory.PropertyMap
import com.highcapable.sweetproperty.plugin.generator.factory.parseTypedValue
import com.highcapable.sweetproperty.plugin.generator.factory.toOptimize
import com.highcapable.sweetproperty.plugin.generator.factory.toUnderscores
import com.highcapable.sweetproperty.utils.debug.SError
import com.highcapable.sweetproperty.utils.firstNumberToLetter
import com.highcapable.sweetproperty.utils.underscore
import com.squareup.kotlinpoet.FileSpec
import com.squareup.kotlinpoet.KModifier
import com.squareup.kotlinpoet.PropertySpec
@@ -67,13 +68,13 @@ internal class PropertiesSourcesGenerator {
""".trimIndent()
)
if (configs.isEnableRestrictedAccess) addModifiers(KModifier.INTERNAL)
keyValues.forEach { (key, value) ->
val typedValue = value.parseTypedValue(configs.isEnableTypeAutoConversion)
addProperty(PropertySpec.builder(key.firstNumberToLetter().underscore(), typedValue.first).apply {
addKdoc("Resolve the \"$key\" value ${typedValue.second}")
keyValues.toOptimize().toUnderscores().forEach { (key, value) ->
val typedValue = value.second.parseTypedValue(configs.isEnableTypeAutoConversion)
addProperty(PropertySpec.builder(key.firstNumberToLetter(), typedValue.first).apply {
addKdoc("Resolve the \"${value.first.toKotlinPoetNoEscape()}\" value ${typedValue.second.toKotlinPoetNoEscape()}")
if (configs.isEnableRestrictedAccess) addModifiers(KModifier.INTERNAL)
addModifiers(KModifier.CONST)
initializer(typedValue.second.toKotlinPoetSpace())
initializer(typedValue.second.toKotlinPoetNoEscape().toKotlinPoetSpace())
}.build())
}
}.build())
@@ -85,4 +86,10 @@ internal class PropertiesSourcesGenerator {
* @return [String]
*/
private fun String.toKotlinPoetSpace() = replace(" ", "·")
/**
* 转换到 KotlinPoet 非转义字符内容
* @return [String]
*/
private fun String.toKotlinPoetNoEscape() = replace("%", "%%")
}

View File

@@ -1,6 +1,6 @@
/*
* SweetProperty - An easy get project properties anywhere Gradle plugin
* Copyright (C) 2019-2023 HighCapable
* SweetProperty - An easy get project properties anywhere Gradle plugin.
* Copyright (C) 2019 HighCapable
* https://github.com/HighCapable/SweetProperty
*
* Apache License Version 2.0
@@ -17,18 +17,28 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is Created by fankes on 2023/8/27.
* This file is created by fankes on 2023/8/27.
*/
package com.highcapable.sweetproperty.plugin.generator.factory
import com.highcapable.sweetproperty.utils.underscore
import kotlin.reflect.KClass
/** 属性键值数组类型定义 */
internal typealias PropertyMap = MutableMap<String, Any>
/** 属性键值优化数组类型定义 */
internal typealias PropertyOptimizeMap = MutableMap<String, Pair<String, Any>>
/** 属性键值规则类型定义 */
internal typealias PropertyValueRule = (value: String) -> String
/**
* 移除键值内容自动转换类型的引号
* @return [String]
*/
internal fun String.removeAutoConversion() = removeSurrounding("\"").removeSurrounding("'")
/**
* 解析到键值内容类型
* @param isAutoConversion 是否自动转换类型
@@ -46,16 +56,50 @@ internal fun Any.parseTypedValue(isAutoConversion: Boolean): Pair<KClass<*>, Str
it.drop(1).dropLast(1)
} else it.replace("\"", "\\\"")
}
if (isAutoConversion.not()) return Pair(String::class, "\"$valueString\"")
if (!isAutoConversion) return Pair(String::class, "\"$valueString\"")
val trimmed = valueString.trim()
val typeSpec = when {
isStringType -> String::class
valueString.trim().toIntOrNull() != null -> Int::class
valueString.trim().toLongOrNull() != null -> Long::class
valueString.trim().toDoubleOrNull() != null -> Double::class
valueString.trim().toFloatOrNull() != null -> Float::class
valueString.trim() == "true" || valueString.trim() == "false" -> Boolean::class
isStringType || trimmed.any { !it.isDigit() && it != '.' && it != '-' } -> String::class
trimmed.toIntOrNull() != null -> Int::class
trimmed.toLongOrNull() != null -> Long::class
trimmed.toDoubleOrNull() != null -> Double::class
trimmed.toFloatOrNull() != null -> Float::class
trimmed == "true" || trimmed == "false" -> Boolean::class
else -> String::class
}; return Pair(typeSpec, if (typeSpec == String::class) "\"$valueString\"" else valueString.let {
if (typeSpec == Long::class && it.endsWith("L").not()) "${it}L" else it
})
}
val finalValue = when (typeSpec) {
String::class -> "\"$valueString\""
Long::class -> if (trimmed.endsWith("L")) trimmed else "${trimmed}L"
else -> trimmed
}; return typeSpec to finalValue
}
/**
* [PropertyMap] 转换到 [PropertyOptimizeMap]
*
* 替换可能的键值名称特殊字符内容并保留原始键值名称
* @return [PropertyOptimizeMap]
*/
internal fun PropertyMap.toOptimize(): PropertyOptimizeMap {
val newMap: PropertyOptimizeMap = mutableMapOf()
var uniqueNumber = 1
forEach { (key, value) ->
var newKey = key.replace("\\W".toRegex(), "_")
while (newMap.containsKey(newKey)) newKey = "$newKey${++uniqueNumber}"
newMap[newKey] = key to value
}; return newMap
}
/**
* [PropertyOptimizeMap] 转换为大写下划线命名
* @return [PropertyOptimizeMap]
*/
internal fun PropertyOptimizeMap.toUnderscores(): PropertyOptimizeMap {
val newMap: PropertyOptimizeMap = mutableMapOf()
var uniqueNumber = 1
forEach { (key, value) ->
var newKey = key.underscore()
while (newMap.containsKey(newKey)) newKey = "$newKey${++uniqueNumber}"
newMap[newKey] = value.first to value.second
}; return newMap
}

View File

@@ -0,0 +1,81 @@
/*
* SweetProperty - An easy get project properties anywhere Gradle plugin.
* Copyright (C) 2019 HighCapable
* https://github.com/HighCapable/SweetProperty
*
* Apache License Version 2.0
*
* 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.
*
* This file is created by fankes on 2023/9/26.
*/
package com.highcapable.sweetproperty.plugin.helper
import com.highcapable.sweetproperty.SweetProperty
import com.highcapable.sweetproperty.generated.SweetPropertyProperties
import com.highcapable.sweetproperty.utils.debug.SLog
import com.highcapable.sweetproperty.utils.executeUrlBody
import org.gradle.api.initialization.Settings
import org.xml.sax.InputSource
import java.io.StringReader
import javax.xml.parsers.DocumentBuilderFactory
/**
* 插件自身检查更新工具类
*/
internal object PluginUpdateHelper {
/** OSS Release URL 地址 */
private const val SONATYPE_OSS_RELEASES_URL = "https://s01.oss.sonatype.org/content/repositories/releases"
/** 依赖配置文件名 */
private const val METADATA_FILE_NAME = "maven-metadata.xml"
/** 插件自身依赖 URL 名称 */
private val groupUrlNotation =
"${SweetPropertyProperties.PROJECT_GROUP_NAME.replace(".","/")}/${SweetPropertyProperties.GRADLE_PLUGIN_MODULE_NAME}"
/** 检查更新 URL 地址 */
private val releaseUrl = "$SONATYPE_OSS_RELEASES_URL/$groupUrlNotation/$METADATA_FILE_NAME"
/**
* 检查更新
* @param settings 当前设置
*/
internal fun checkingForUpdate(settings: Settings) {
if (settings.gradle.startParameter.isOffline) return
val latestVersion = releaseUrl.executeUrlBody(isShowFailure = false).trim().findLatest()
if (latestVersion.isNotBlank() && latestVersion != SweetProperty.VERSION) SLog.note(
"""
Plugin update is available, the current version is ${SweetProperty.VERSION}, please update to $latestVersion
You can modify your plugin version in your project's settings.gradle or settings.gradle.kts
plugins {
id("${SweetPropertyProperties.PROJECT_GROUP_NAME}") version "$latestVersion"
...
}
For more information, you can visit ${SweetProperty.PROJECT_URL}
""".trimIndent(), SLog.UP
)
}
/**
* 解析 [METADATA_FILE_NAME] 内容并获取 "latest"
* @return [String]
*/
private fun String.findLatest() = runCatching {
if (!(contains("<metadata ") || contains("<metadata>")) || !endsWith("</metadata>")) return@runCatching ""
DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(InputSource(StringReader(this))).let { document ->
document.getElementsByTagName("latest")?.let { if (it.length > 0) it.item(0)?.textContent ?: "" else "" }
}
}.getOrNull() ?: ""
}

View File

@@ -1,6 +1,6 @@
/*
* SweetProperty - An easy get project properties anywhere Gradle plugin
* Copyright (C) 2019-2023 HighCapable
* SweetProperty - An easy get project properties anywhere Gradle plugin.
* Copyright (C) 2019 HighCapable
* https://github.com/HighCapable/SweetProperty
*
* Apache License Version 2.0
@@ -17,7 +17,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is Created by fankes on 2023/8/30.
* This file is created by fankes on 2023/8/30.
*/
package com.highcapable.sweetproperty.plugin.helper
@@ -36,10 +36,12 @@ import com.highcapable.sweetproperty.plugin.config.type.GenerateLocationType
import com.highcapable.sweetproperty.plugin.generator.PropertiesAccessorsGenerator
import com.highcapable.sweetproperty.plugin.generator.PropertiesSourcesGenerator
import com.highcapable.sweetproperty.plugin.generator.factory.PropertyMap
import com.highcapable.sweetproperty.plugin.generator.factory.removeAutoConversion
import com.highcapable.sweetproperty.utils.camelcase
import com.highcapable.sweetproperty.utils.code.entity.MavenPomData
import com.highcapable.sweetproperty.utils.code.factory.compile
import com.highcapable.sweetproperty.utils.debug.SError
import com.highcapable.sweetproperty.utils.debug.SLog
import com.highcapable.sweetproperty.utils.flatted
import com.highcapable.sweetproperty.utils.hasInterpolation
import com.highcapable.sweetproperty.utils.isEmpty
@@ -48,7 +50,6 @@ import com.highcapable.sweetproperty.utils.noEmpty
import com.highcapable.sweetproperty.utils.replaceInterpolation
import com.highcapable.sweetproperty.utils.toStringMap
import com.highcapable.sweetproperty.utils.uppercamelcase
import org.gradle.api.DomainObjectCollection
import org.gradle.api.Project
import org.gradle.api.initialization.Settings
import java.io.File
@@ -102,7 +103,7 @@ internal object PropertiesDeployHelper {
internal fun initialize(settings: Settings, configs: ISweetPropertyConfigs) {
this.configs = configs
checkingConfigsModified(settings)
if (configs.isEnable.not()) return
if (!configs.isEnable) return
generatedAccessors(settings)
}
@@ -111,7 +112,7 @@ internal object PropertiesDeployHelper {
* @param rootProject 当前根项目
*/
internal fun resolve(rootProject: Project) {
if (configs.isEnable.not()) return
if (!configs.isEnable) return
resolveAccessors(rootProject)
}
@@ -120,7 +121,7 @@ internal object PropertiesDeployHelper {
* @param rootProject 当前根项目
*/
internal fun deploy(rootProject: Project) {
if (configs.isEnable.not()) return
if (!configs.isEnable) return
deployAccessors(rootProject)
deploySourcesCode(rootProject)
}
@@ -152,13 +153,13 @@ internal object PropertiesDeployHelper {
allConfigs.add(configs.global.buildScript)
}
configs.projects.forEach { (name, subConfigs) ->
if (subConfigs.buildScript.isEnable.not()) return@forEach
if (!subConfigs.buildScript.isEnable) return@forEach
allProperties.add(generatedProperties(subConfigs.buildScript, ProjectDescriptor.create(settings, name)))
allConfigs.add(subConfigs.buildScript)
}
if (isConfigsModified.not() &&
if (!isConfigsModified &&
allProperties == cachedSettingsProperties &&
accessorsDir.resolve(accessorsPomData.relativePomPath).isEmpty().not()
!accessorsDir.resolve(accessorsPomData.relativePomPath).isEmpty()
) return
cachedSettingsProperties = allProperties
accessorsGenerator.build(allConfigs, allProperties).compile(accessorsPomData, accessorsDir.absolutePath, accessorsGenerator.compileStubFiles)
@@ -169,7 +170,7 @@ internal object PropertiesDeployHelper {
* @param rootProject 当前根项目
*/
private fun resolveAccessors(rootProject: Project) {
if (accessorsDir.resolve(accessorsPomData.relativePomPath).isEmpty().not())
if (!accessorsDir.resolve(accessorsPomData.relativePomPath).isEmpty())
rootProject.addDependencyToBuildScript(accessorsDir.absolutePath, accessorsPomData)
}
@@ -181,7 +182,7 @@ internal object PropertiesDeployHelper {
/** 部署扩展方法 */
fun Project.deploy() {
val configs = configs.with(this).buildScript
if (configs.isEnable.not()) return
if (!configs.isEnable) return
val className = accessorsGenerator.propertiesClass(configs.name)
val accessorsClass = loadBuildScriptClass(className) ?: SError.make(
"""
@@ -205,13 +206,15 @@ internal object PropertiesDeployHelper {
fun Project.generate() {
val configs = configs.with(this).sourcesCode
val outputDir = file(configs.generateDirPath)
if (configs.isEnable.not()) return
if (!configs.isEnable) return
val properties = generatedProperties(configs, ProjectDescriptor.create(project = this))
if (isConfigsModified.not() && properties == cachedProjectProperties[fullName] && outputDir.isEmpty().not()) {
if (!isConfigsModified && properties == cachedProjectProperties[fullName()] && !outputDir.isEmpty()) {
if (configs.isEnable) configureSourceSets(project = this)
return
}; outputDir.apply { if (exists()) deleteRecursively() }
cachedProjectProperties[fullName] = properties
// 每次都会重新创建目录
outputDir.mkdirs()
cachedProjectProperties[fullName()] = properties
val packageName = generatedPackageName(configs, project = this)
val className = generatedClassName(configs, project = this)
sourcesGenerator.build(configs, properties, packageName, className).writeTo(outputDir)
@@ -226,16 +229,26 @@ internal object PropertiesDeployHelper {
* @param project 当前项目
*/
private fun configureSourceSets(project: Project) {
fun Project.deploySourceSets(name: String) = runCatching {
val configs = configs.with(project).sourcesCode
fun Project.deploySourceSet(name: String, sourceSetName: String = configs.sourceSetName) = runCatching {
val extension = get(name)
val collection = extension.javaClass.getMethod("getSourceSets").invoke(extension) as DomainObjectCollection<*>
collection.configureEach {
val kotlin = javaClass.getMethod("getKotlin").invoke(this)
kotlin.javaClass.getMethod("srcDir", Any::class.java).invoke(kotlin, configs.with(project).sourcesCode.generateDirPath)
}
val collection = extension.javaClass.getMethod("getSourceSets").invoke(extension) as? Iterable<*>?
val mainSet = collection?.firstOrNull {
it?.javaClass?.getMethod("getName")?.invoke(it) == sourceSetName
} ?: return@runCatching SLog.warn("Could not found source set \"$sourceSetName\" for $name extension")
val kotlin = mainSet.javaClass.getMethod("getKotlin").invoke(mainSet)
val generateDir = configs.generateDirPath
val generateFile = File(generateDir)
// 确保目录存在
if (!generateFile.exists()) generateFile.mkdirs()
val srcDirs = kotlin.javaClass.getMethod("getSrcDirs").invoke(kotlin) as Set<*>
val alreadyAdded = srcDirs.any { it is File && it.canonicalPath == generateFile.canonicalPath }
if (!alreadyAdded) kotlin.javaClass.getMethod("srcDir", Any::class.java).invoke(kotlin, generateFile)
}.onFailure {
SLog.error(msg = "Failed to deploy source set \"$sourceSetName\" for $name extension\n${it.stackTraceToString()}")
}
if (project.hasExtension("kotlin")) project.deploySourceSets(name = "kotlin")
if (project.hasExtension("android")) project.deploySourceSets(name = "android")
if (project.hasExtension("kotlin")) project.deploySourceSet(name = "kotlin")
if (project.hasExtension("android")) project.deploySourceSet(name = "android")
}
/**
@@ -293,7 +306,8 @@ internal object PropertiesDeployHelper {
fun String.resolveValue(): String = replaceInterpolation { matchKey ->
if (resolveKeys.size > 5) SError.make("Key \"$key\" has been called recursively multiple times of those $resolveKeys")
resolveKeys.add(matchKey)
val resolveValue = if (configs.isEnableValueInterpolation) resolveKeyValues[matchKey] ?: "" else matchKey
var resolveValue = if (configs.isEnableValueInterpolation) resolveKeyValues[matchKey] ?: "" else matchKey
resolveValue = resolveValue.removeAutoConversion()
if (resolveValue.hasInterpolation()) resolveValue.resolveValue()
else resolveValue
}
@@ -323,7 +337,7 @@ internal object PropertiesDeployHelper {
val packageName = configs.packageName.noBlank()
?: project.namespace()
?: project.group.toString().noBlank()
?: "$DEFAULT_PACKAGE_NAME.${project.fullName.replace(":", "").flatted()}"
?: "$DEFAULT_PACKAGE_NAME.${project.fullName(isUseColon = false).replace(":", "").flatted()}"
return "$packageName.generated"
}
@@ -335,7 +349,7 @@ internal object PropertiesDeployHelper {
*/
private fun generatedClassName(configs: ISweetPropertyConfigs.ISourcesCodeGenerateConfigs, project: Project): String {
val className = configs.className.noBlank()
?: project.fullName.replace(":", "_").uppercamelcase().noBlank()
?: project.fullName(isUseColon = false).replace(":", "_").uppercamelcase().noBlank()
?: "Undefined"
return "${className.uppercamelcase()}Properties"
}

View File

@@ -1,6 +1,6 @@
/*
* SweetProperty - An easy get project properties anywhere Gradle plugin
* Copyright (C) 2019-2023 HighCapable
* SweetProperty - An easy get project properties anywhere Gradle plugin.
* Copyright (C) 2019 HighCapable
* https://github.com/HighCapable/SweetProperty
*
* Apache License Version 2.0
@@ -17,7 +17,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is Created by fankes on 2023/8/27.
* This file is created by fankes on 2023/8/27.
*/
@file:Suppress("unused")
@@ -52,7 +52,7 @@ internal fun String.parseUnixFileSeparator() = replace("\\", "/")
* - 如果文件不存在 - 返回 true
* @return [Boolean]
*/
internal fun File.isEmpty() = exists().not() || isDirectory.not() || listFiles().isNullOrEmpty()
internal fun File.isEmpty() = !exists() || !isDirectory || listFiles().isNullOrEmpty()
/** 删除目录下的空子目录 */
internal fun File.deleteEmptyRecursively() {

View File

@@ -0,0 +1,58 @@
/*
* SweetProperty - An easy get project properties anywhere Gradle plugin.
* Copyright (C) 2019 HighCapable
* https://github.com/HighCapable/SweetProperty
*
* Apache License Version 2.0
*
* 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.
*
* This file is created by fankes on 2023/9/26.
*/
package com.highcapable.sweetproperty.utils
import com.highcapable.sweetproperty.utils.debug.SError
import com.highcapable.sweetproperty.utils.debug.SLog
import okhttp3.Credentials
import okhttp3.OkHttpClient
import okhttp3.Request
import java.util.concurrent.TimeUnit
/**
* 获取当前 URL 地址的请求体字符串内容 (GET) (同步)
* @param username 用户名
* @param password 密码
* @param isShowFailure 是否显示错误 - 默认是
* @return [String]
*/
internal fun String.executeUrlBody(username: String = "", password: String = "", isShowFailure: Boolean = true) = runCatching {
OkHttpClient()
.newBuilder()
.connectTimeout(10000, TimeUnit.MILLISECONDS)
.authenticator { _, response ->
if (response.code == 400 || response.code == 401)
response.request.newBuilder()
.header("Authorization", Credentials.basic(username, password))
.build()
else null
}.build().newCall(
Request.Builder().url(when {
startsWith("https://") -> "https://" + replace("https://", "").replace("//", "/")
startsWith("http://") -> "http://" + replace("http://", "").replace("//", "/")
else -> SError.make("Invalid URL: $this")
}).get().build()
).execute().let {
if (it.code == 200 || it.code == 404) it.body?.string() ?: ""
else SError.make("Request failed with code ${it.code}")
}
}.onFailure { if (isShowFailure) SLog.error("Failed to connect to $this\n$it") }.getOrNull() ?: ""

View File

@@ -1,6 +1,6 @@
/*
* SweetProperty - An easy get project properties anywhere Gradle plugin
* Copyright (C) 2019-2023 HighCapable
* SweetProperty - An easy get project properties anywhere Gradle plugin.
* Copyright (C) 2019 HighCapable
* https://github.com/HighCapable/SweetProperty
*
* Apache License Version 2.0
@@ -17,7 +17,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is Created by fankes on 2023/8/26.
* This file is created by fankes on 2023/8/26.
*/
package com.highcapable.sweetproperty.utils

View File

@@ -1,6 +1,6 @@
/*
* SweetProperty - An easy get project properties anywhere Gradle plugin
* Copyright (C) 2019-2023 HighCapable
* SweetProperty - An easy get project properties anywhere Gradle plugin.
* Copyright (C) 2019 HighCapable
* https://github.com/HighCapable/SweetProperty
*
* Apache License Version 2.0
@@ -17,7 +17,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is Created by fankes on 2023/8/27.
* This file is created by fankes on 2023/8/27.
*/
package com.highcapable.sweetproperty.utils.code
@@ -59,7 +59,7 @@ internal object CodeCompiler {
if (files.isEmpty()) {
if (outputDir.exists()) outputDir.deleteRecursively()
return
} else outputDir.also { if (it.exists().not()) it.mkdirs() }
} else outputDir.also { if (!it.exists()) it.mkdirs() }
val outputBuildDir = "$outputDirPath/build".toFile().also { if (it.exists()) it.deleteRecursively(); it.mkdirs() }
val outputClassesDir = "${outputBuildDir.absolutePath}/classes".toFile().apply { mkdirs() }
val outputSourcesDir = "${outputBuildDir.absolutePath}/sources".toFile().apply { mkdirs() }
@@ -75,14 +75,15 @@ internal object CodeCompiler {
diagnosticsMessage += " ${diagnostic.getMessage(null)}\n"
}
runCatching { fileManager.close() }
compileOnlyFiles.forEach { "${outputClassesDir.absolutePath}/${it.name}".replace(".java", ".class").toFile().delete() }
files.forEach {
it.toFiles(outputSourcesDir).also { (sourceDir, sourceFile) ->
sourceDir.mkdirs()
sourceFile.writeText(it.getCharContent(true).toString())
}
}
if (result) {
compileOnlyFiles.forEach { "${outputClassesDir.absolutePath}/${it.name}".replace(".java", ".class").toFile().delete() }
files.forEach {
it.toFiles(outputSourcesDir).also { (sourceDir, sourceFile) ->
sourceDir.mkdirs()
sourceFile.writeText(it.getCharContent(true).toString())
}
}; outputClassesDir.deleteEmptyRecursively()
outputClassesDir.deleteEmptyRecursively()
writeMetaInf(outputClassesDir)
writeMetaInf(outputSourcesDir)
createJarAndPom(pomData, outputDir, outputBuildDir, outputClassesDir, outputSourcesDir)
@@ -98,7 +99,7 @@ internal object CodeCompiler {
* @param sourcesDir 编译源码目录
*/
private fun createJarAndPom(pomData: MavenPomData, outputDir: File, buildDir: File, classesDir: File, sourcesDir: File) {
val pomDir = outputDir.resolve(pomData.relativePomPath).also { if (it.exists().not()) it.mkdirs() }
val pomDir = outputDir.resolve(pomData.relativePomPath).also { if (!it.exists()) it.mkdirs() }
packageToJar(classesDir, pomDir, pomData, isSourcesJar = false)
packageToJar(sourcesDir, pomDir, pomData, isSourcesJar = true)
writePom(pomDir, pomData)
@@ -158,7 +159,7 @@ internal object CodeCompiler {
* @throws IllegalStateException 如果编译输出目录不存在
*/
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()) SError.make("Jar file output path not found: ${buildDir.absolutePath}")
val jarFile = outputDir.resolve("${pomData.artifactId}-${pomData.version}${if (isSourcesJar) "-sources" else ""}.jar")
if (jarFile.exists()) jarFile.delete()
ZipFile(jarFile).addFolder(buildDir, ZipParameters().apply { isIncludeRootFolder = false })

View File

@@ -1,6 +1,6 @@
/*
* SweetProperty - An easy get project properties anywhere Gradle plugin
* Copyright (C) 2019-2023 HighCapable
* SweetProperty - An easy get project properties anywhere Gradle plugin.
* Copyright (C) 2019 HighCapable
* https://github.com/HighCapable/SweetProperty
*
* Apache License Version 2.0
@@ -17,7 +17,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is Created by fankes on 2023/8/27.
* This file is created by fankes on 2023/8/27.
*/
package com.highcapable.sweetproperty.utils.code.entity

View File

@@ -1,6 +1,6 @@
/*
* SweetProperty - An easy get project properties anywhere Gradle plugin
* Copyright (C) 2019-2023 HighCapable
* SweetProperty - An easy get project properties anywhere Gradle plugin.
* Copyright (C) 2019 HighCapable
* https://github.com/HighCapable/SweetProperty
*
* Apache License Version 2.0
@@ -17,7 +17,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is Created by fankes on 2023/8/27.
* This file is created by fankes on 2023/8/27.
*/
@file:Suppress("unused")

View File

@@ -1,6 +1,6 @@
/*
* SweetProperty - An easy get project properties anywhere Gradle plugin
* Copyright (C) 2019-2023 HighCapable
* SweetProperty - An easy get project properties anywhere Gradle plugin.
* Copyright (C) 2019 HighCapable
* https://github.com/HighCapable/SweetProperty
*
* Apache License Version 2.0
@@ -17,7 +17,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is Created by fankes on 2023/8/27.
* This file is created by fankes on 2023/8/27.
*/
package com.highcapable.sweetproperty.utils.debug

View File

@@ -1,6 +1,6 @@
/*
* SweetProperty - An easy get project properties anywhere Gradle plugin
* Copyright (C) 2019-2023 HighCapable
* SweetProperty - An easy get project properties anywhere Gradle plugin.
* Copyright (C) 2019 HighCapable
* https://github.com/HighCapable/SweetProperty
*
* Apache License Version 2.0
@@ -17,22 +17,87 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is Created by fankes on 2023/8/27.
* This file is created by fankes on 2023/8/27.
*/
@file:Suppress("unused")
@file:Suppress("unused", "MemberVisibilityCanBePrivate")
package com.highcapable.sweetproperty.utils.debug
import com.highcapable.sweetproperty.SweetProperty
import org.apache.log4j.Logger
/**
* 全局 Log 管理类
*/
internal object SLog {
internal const val DONE = ""
internal const val IGNORE = ""
internal const val ERROR = ""
internal const val WARN = "⚠️"
internal const val LINK = "➡️"
internal const val WIRE = "⚙️"
internal const val UP = "⬆️"
internal const val ROTATE = "\uD83D\uDD04"
internal const val ANLZE = "\uD83D\uDD0D"
internal const val STRNG = "\uD83D\uDCAA"
/** 当前日志输出对象 */
private val logger = Logger.getLogger(SLog::class.java)
/**
* 打印 Info (提醒) 级别 Log (绿色)
* @param msg 消息内容
* @param symbol 前缀符号 - 仅限非 [noTag] - 默认无
* @param noTag 无标签 - 默认否
*/
internal fun note(msg: Any, symbol: String = "", noTag: Boolean = false) =
log(if (noTag) msg else msg.createSymbolMsg(symbol), color = "38;5;10")
/**
* 打印 Info 级别 Log (无颜色)
* @param msg 消息内容
* @param symbol 前缀符号 - 仅限非 [noTag] - 默认无
* @param noTag 无标签 - 默认否
*/
internal fun info(msg: Any, symbol: String = "", noTag: Boolean = false) =
log(if (noTag) msg else msg.createSymbolMsg(symbol))
/**
* 打印 Warn 级别 Log (黄色)
* @param msg 消息内容
* @param symbol 前缀符号 - 仅限非 [noTag] - 默认 [WARN]
* @param noTag 无标签 - 默认否
*/
internal fun warn(msg: Any, symbol: String = WARN, noTag: Boolean = false) =
log(if (noTag) msg else msg.createSymbolMsg(symbol), color = "33")
/**
* 打印 Error 级别 Log (红色)
* @param msg 消息内容
* @param symbol 前缀符号 - 仅限非 [noTag] - 默认 [ERROR]
* @param noTag 无标签 - 默认否
*/
internal fun error(msg: Any, symbol: String = ERROR, noTag: Boolean = false) =
log(if (noTag) msg else msg.createSymbolMsg(symbol), isError = true)
/**
* 创建符号消息内容
* @param symbol 前缀符号
* @return [String]
*/
private fun Any.createSymbolMsg(symbol: String) =
if (symbol.isNotBlank()) "[${SweetProperty.TAG}] $symbol $this" else "[${SweetProperty.TAG}] $this"
/**
* 打印 Log
* @param msg 消息内容
* @param color 颜色代码 - 默认无颜色
* @param isError 是否强制为错误日志 - 默认否
*/
internal fun log(msg: String) = println("[${SweetProperty.TAG}] $msg")
private fun log(msg: Any, color: String = "0", isError: Boolean = false) = when {
isError -> logger.error(msg)
color != "0" -> println("\u001B[${color}m$msg\u001B[0m")
else -> println(msg)
}
}

View File

@@ -1,6 +1,6 @@
/*
* SweetProperty - An easy get project properties anywhere Gradle plugin
* Copyright (C) 2019-2023 HighCapable
* SweetProperty - An easy get project properties anywhere Gradle plugin.
* Copyright (C) 2019 HighCapable
* https://github.com/HighCapable/SweetProperty
*
* Apache License Version 2.0
@@ -17,7 +17,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is Created by fankes on 2023/8/27.
* This file is created by fankes on 2023/8/27.
*/
@file:Suppress("unused")