mirror of
https://github.com/HighCapable/SweetProperty.git
synced 2025-09-06 18:55:40 +08:00
Compare commits
11 Commits
Author | SHA1 | Date | |
---|---|---|---|
5d5c3af69a
|
|||
87143b99c4
|
|||
ec03595552
|
|||
33abb4bafa
|
|||
2337d5710b
|
|||
1bf1a030dc
|
|||
6c5835bc72
|
|||
d9c8c5dc84
|
|||
d2aed2120e
|
|||
67c79a591c
|
|||
fe1c8594c8
|
2
.idea/kotlinc.xml
generated
2
.idea/kotlinc.xml
generated
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="KotlinJpsPluginSettings">
|
<component name="KotlinJpsPluginSettings">
|
||||||
<option name="version" value="1.9.10" />
|
<option name="version" value="1.9.20" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
@@ -10,6 +10,11 @@
|
|||||||
|
|
||||||
[English](https://github.com/HighCapable/SweetProperty/blob/master/README.md) | 简体中文
|
[English](https://github.com/HighCapable/SweetProperty/blob/master/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) |
|
||||||
|
|-------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------|
|
||||||
|
|
||||||
|
这个项目属于上述组织,**点击上方链接关注这个组织**,发现更多好项目。
|
||||||
|
|
||||||
## 这是什么
|
## 这是什么
|
||||||
|
|
||||||
这是一个用来轻松获取 Gradle 项目属性配置文件 `gradle.properties` 中键值的 Gradle 插件。
|
这是一个用来轻松获取 Gradle 项目属性配置文件 `gradle.properties` 中键值的 Gradle 插件。
|
||||||
|
@@ -10,6 +10,11 @@ An easy get project properties anywhere Gradle plugin.
|
|||||||
|
|
||||||
English | [简体中文](https://github.com/HighCapable/SweetProperty/blob/master/README-zh-CN.md)
|
English | [简体中文](https://github.com/HighCapable/SweetProperty/blob/master/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
|
## What's this
|
||||||
|
|
||||||
This is a Gradle plugin to easily get the key-values in the Gradle project properties configuration file `gradle.properties`.
|
This is a Gradle plugin to easily get the key-values in the Gradle project properties configuration file `gradle.properties`.
|
||||||
|
@@ -27,3 +27,11 @@
|
|||||||
- 改进并采用 Gradle 项目命名规范
|
- 改进并采用 Gradle 项目命名规范
|
||||||
- 新增插件自身检查更新功能
|
- 新增插件自身检查更新功能
|
||||||
- 一些其它功能性的改进
|
- 一些其它功能性的改进
|
||||||
|
|
||||||
|
## 1.0.4 | 2023.11.04
|
||||||
|
|
||||||
|
- 修复类似 `a=some` 和 `a_b=some` 的属性键值名称会造成重复方法名称的问题
|
||||||
|
- 修复使用 `${...}` 生成的插值内容依然会携带字符串类型引号问题
|
||||||
|
- 生成的代码使用 `@Nonnull` 标记以使其能够在 Kotlin DSL 脚本中识别为非空返回值类型
|
||||||
|
- 新增 `project(...)` 配置方法支持同时配置多个项目
|
||||||
|
- 一些其它功能性的改进
|
@@ -28,3 +28,11 @@
|
|||||||
- Improve and adopt Gradle project naming convention
|
- Improve and adopt Gradle project naming convention
|
||||||
- Added plugin own update function
|
- Added plugin own update function
|
||||||
- Some other functional improvements
|
- 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
|
@@ -213,6 +213,19 @@ sweetProperty {
|
|||||||
// 配置 "buildScript"
|
// 配置 "buildScript"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 同时进行多个项目与子项目配置
|
||||||
|
// 在方法参数中填入需要配置的项目完整名称数组来配置每个对应的项目
|
||||||
|
project(":modules:library1", ":modules:library2") {
|
||||||
|
all {
|
||||||
|
// 配置 "all"
|
||||||
|
}
|
||||||
|
sourcesCode {
|
||||||
|
// 配置 "sourcesCode"
|
||||||
|
}
|
||||||
|
buildScript {
|
||||||
|
// 配置 "buildScript"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@@ -227,6 +227,19 @@ sweetProperty {
|
|||||||
// Configure "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"
|
||||||
|
}
|
||||||
|
sourcesCode {
|
||||||
|
// Configure "sourcesCode"
|
||||||
|
}
|
||||||
|
buildScript {
|
||||||
|
// Configure "buildScript"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@@ -4,7 +4,7 @@ project.description=An easy get project properties anywhere Gradle plugin.
|
|||||||
project.url=https://github.com/HighCapable/SweetProperty
|
project.url=https://github.com/HighCapable/SweetProperty
|
||||||
project.groupName=com.highcapable.sweetproperty
|
project.groupName=com.highcapable.sweetproperty
|
||||||
project.moduleName=sweet-property
|
project.moduleName=sweet-property
|
||||||
project.version=1.0.3
|
project.version=1.0.4
|
||||||
project.licence.name=Apache License 2.0
|
project.licence.name=Apache License 2.0
|
||||||
project.licence.url=https://github.com/HighCapable/SweetProperty/blob/master/LICENSE
|
project.licence.url=https://github.com/HighCapable/SweetProperty/blob/master/LICENSE
|
||||||
project.developer.id="0"
|
project.developer.id="0"
|
||||||
|
@@ -12,7 +12,7 @@ repositories:
|
|||||||
plugins:
|
plugins:
|
||||||
org.jetbrains.kotlin.jvm:
|
org.jetbrains.kotlin.jvm:
|
||||||
alias: kotlin-jvm
|
alias: kotlin-jvm
|
||||||
version: 1.9.10
|
version: 1.9.20
|
||||||
com.vanniktech.maven.publish:
|
com.vanniktech.maven.publish:
|
||||||
alias: maven-publish
|
alias: maven-publish
|
||||||
version: 0.25.3
|
version: 0.25.3
|
||||||
@@ -20,7 +20,7 @@ plugins:
|
|||||||
libraries:
|
libraries:
|
||||||
com.squareup.okhttp3:
|
com.squareup.okhttp3:
|
||||||
okhttp:
|
okhttp:
|
||||||
version: 4.11.0
|
version: 4.12.0
|
||||||
com.squareup:
|
com.squareup:
|
||||||
kotlinpoet:
|
kotlinpoet:
|
||||||
version: 1.14.2
|
version: 1.14.2
|
||||||
|
@@ -7,8 +7,8 @@ pluginManagement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
plugins {
|
plugins {
|
||||||
id("com.highcapable.sweetdependency") version "1.0.2"
|
id("com.highcapable.sweetdependency") version "1.0.3"
|
||||||
id("com.highcapable.sweetproperty") version "1.0.3"
|
id("com.highcapable.sweetproperty") version "1.0.4"
|
||||||
}
|
}
|
||||||
sweetDependency {
|
sweetDependency {
|
||||||
isEnableVerboseMode = false
|
isEnableVerboseMode = false
|
||||||
|
@@ -48,7 +48,7 @@ internal class ProjectDescriptor private constructor() {
|
|||||||
it.type = Type.SETTINGS
|
it.type = Type.SETTINGS
|
||||||
it.name = name.noBlank() ?: settings.rootProject.name
|
it.name = name.noBlank() ?: settings.rootProject.name
|
||||||
it.currentDir = (if (isRootProject) settings.rootProject else settings.findProject(name))?.projectDir
|
it.currentDir = (if (isRootProject) settings.rootProject else settings.findProject(name))?.projectDir
|
||||||
?: SError.make("Project \"$name\" not found${if (name.startsWith(":").not()) ", $subProjectNotice" else ""}")
|
?: SError.make("Project \"$name\" not found${if (!name.startsWith(":")) ", $subProjectNotice" else ""}")
|
||||||
it.rootDir = settings.rootDir
|
it.rootDir = settings.rootDir
|
||||||
it.homeDir = settings.gradle.gradleUserHomeDir
|
it.homeDir = settings.gradle.gradleUserHomeDir
|
||||||
}
|
}
|
||||||
|
@@ -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 ->
|
internal fun ExtensionAware.getOrCreate(name: String, clazz: Class<*>, vararg args: Any?) = name.toSafeExtName().let { sName ->
|
||||||
runCatching { extensions.create(sName, clazz, *args).asExtension() }.getOrElse {
|
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\"")
|
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 ->
|
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 {
|
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\"")
|
runCatching { extensions.getByName(sName) as? T? }.getOrNull() ?: SError.make("Create or get extension failed with name \"$sName\"")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -44,7 +44,7 @@ internal fun Project.fullName(isUseColon: Boolean = true): String {
|
|||||||
project.parent?.also { if (it != it.rootProject) fetchChild(it) }
|
project.parent?.also { if (it != it.rootProject) fetchChild(it) }
|
||||||
baseNames.add(project.name)
|
baseNames.add(project.name)
|
||||||
}; fetchChild(project = this)
|
}; fetchChild(project = this)
|
||||||
return buildString { baseNames.onEach { append(":$it") }.clear() }.let { if (isUseColon && isRoot.not()) it else it.drop(1) }
|
return buildString { baseNames.onEach { append(":$it") }.clear() }.let { if (isUseColon && !isRoot) it else it.drop(1) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -95,11 +95,11 @@ open class SweetPropertyConfigureExtension internal constructor() {
|
|||||||
fun rootProject(action: Action<SubConfigureExtension>) = configureProject(ROOT_PROJECT_TAG, action)
|
fun rootProject(action: Action<SubConfigureExtension>) = configureProject(ROOT_PROJECT_TAG, action)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 配置指定项目
|
* 配置指定项目 (数组)
|
||||||
* @param name 项目完整名称
|
* @param names 项目完整名称 (数组)
|
||||||
* @param action 配置方法体
|
* @param action 配置方法体
|
||||||
*/
|
*/
|
||||||
fun project(name: String, action: Action<SubConfigureExtension>) = configureProject(name, action)
|
fun project(vararg names: String, action: Action<SubConfigureExtension>) = names.forEach { configureProject(it, action) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 配置项目
|
* 配置项目
|
||||||
@@ -474,13 +474,13 @@ open class SweetPropertyConfigureExtension internal constructor() {
|
|||||||
|
|
||||||
/** 检查合法包名 */
|
/** 检查合法包名 */
|
||||||
fun String.checkingValidPackageName() {
|
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\"")
|
SError.make("Invalid package name \"$this\"")
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 检查合法类名 */
|
/** 检查合法类名 */
|
||||||
fun String.checkingValidClassName() {
|
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\"")
|
SError.make("Invalid class name \"$this\"")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -40,6 +40,7 @@ import com.squareup.javapoet.MethodSpec
|
|||||||
import com.squareup.javapoet.TypeSpec
|
import com.squareup.javapoet.TypeSpec
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
import javax.annotation.Nonnull
|
||||||
import javax.lang.model.element.Modifier
|
import javax.lang.model.element.Modifier
|
||||||
import kotlin.properties.Delegates
|
import kotlin.properties.Delegates
|
||||||
|
|
||||||
@@ -84,6 +85,9 @@ internal class PropertiesAccessorsGenerator {
|
|||||||
/** 生成的属性键值连续名称重复次数数组 */
|
/** 生成的属性键值连续名称重复次数数组 */
|
||||||
private val grandSuccessiveDuplicateIndexs = mutableMapOf<String, Int>()
|
private val grandSuccessiveDuplicateIndexs = mutableMapOf<String, Int>()
|
||||||
|
|
||||||
|
/** 生成的属性键值不重复调用方法数组 */
|
||||||
|
private val usedSuccessiveMethods = mutableMapOf<String, MutableList<String>>()
|
||||||
|
|
||||||
/** 生成的属性键值不重复 TAG 数组 */
|
/** 生成的属性键值不重复 TAG 数组 */
|
||||||
private val usedSuccessiveTags = mutableSetOf<String>()
|
private val usedSuccessiveTags = mutableSetOf<String>()
|
||||||
|
|
||||||
@@ -94,7 +98,7 @@ internal class PropertiesAccessorsGenerator {
|
|||||||
*/
|
*/
|
||||||
private inline fun noRepeated(vararg tags: String, block: () -> Unit) {
|
private inline fun noRepeated(vararg tags: String, block: () -> Unit) {
|
||||||
val allTag = tags.joinToString("-")
|
val allTag = tags.joinToString("-")
|
||||||
if (usedSuccessiveTags.contains(allTag).not()) block()
|
if (!usedSuccessiveTags.contains(allTag)) block()
|
||||||
usedSuccessiveTags.add(allTag)
|
usedSuccessiveTags.add(allTag)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,9 +181,10 @@ internal class PropertiesAccessorsGenerator {
|
|||||||
*/
|
*/
|
||||||
private fun TypeSpec.Builder.addSuccessiveMethod(accessorsName: String, methodName: String, className: String) =
|
private fun TypeSpec.Builder.addSuccessiveMethod(accessorsName: String, methodName: String, className: String) =
|
||||||
addMethod(
|
addMethod(
|
||||||
MethodSpec.methodBuilder("get${methodName.capitalize()}")
|
MethodSpec.methodBuilder("get${getOrCreateUsedSuccessiveMethodName(methodName, className).capitalize()}")
|
||||||
.addJavadoc("Resolve the \"$accessorsName\" accessors")
|
.addJavadoc("Resolve the \"$accessorsName\" accessors")
|
||||||
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
|
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
|
||||||
|
.addAnnotation(Nonnull::class.java)
|
||||||
.returns(className.capitalized().asClassType())
|
.returns(className.capitalized().asClassType())
|
||||||
.addStatement("return ${className.uncapitalized()}")
|
.addStatement("return ${className.uncapitalized()}")
|
||||||
.build()
|
.build()
|
||||||
@@ -189,15 +194,17 @@ internal class PropertiesAccessorsGenerator {
|
|||||||
* 向通用构建器描述类添加最终键值方法
|
* 向通用构建器描述类添加最终键值方法
|
||||||
* @param accessorsName 接续名
|
* @param accessorsName 接续名
|
||||||
* @param methodName 方法名
|
* @param methodName 方法名
|
||||||
|
* @param className 类名
|
||||||
* @param value 键值内容
|
* @param value 键值内容
|
||||||
* @return [TypeSpec.Builder]
|
* @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(
|
addMethod(
|
||||||
MethodSpec.methodBuilder("get${methodName.capitalize()}").apply {
|
MethodSpec.methodBuilder("get${getOrCreateUsedSuccessiveMethodName(methodName, className).capitalize()}").apply {
|
||||||
val typedValue = value.parseTypedValue(configs.isEnableTypeAutoConversion)
|
val typedValue = value.parseTypedValue(configs.isEnableTypeAutoConversion)
|
||||||
addJavadoc("Resolve the \"$accessorsName\" value ${typedValue.second}")
|
addJavadoc("Resolve the \"$accessorsName\" value ${typedValue.second}")
|
||||||
addModifiers(Modifier.PUBLIC, Modifier.FINAL)
|
addModifiers(Modifier.PUBLIC, Modifier.FINAL)
|
||||||
|
.addAnnotation(Nonnull::class.java)
|
||||||
.returns(typedValue.first.java)
|
.returns(typedValue.first.java)
|
||||||
.addStatement("return ${typedValue.second}")
|
.addStatement("return ${typedValue.second}")
|
||||||
}.build()
|
}.build()
|
||||||
@@ -211,6 +218,20 @@ internal class PropertiesAccessorsGenerator {
|
|||||||
private fun MethodSpec.Builder.addSuccessiveStatement(className: String) =
|
private fun MethodSpec.Builder.addSuccessiveStatement(className: String) =
|
||||||
addStatement("${className.uncapitalized()} = new ${className.capitalized()}()")
|
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 名称
|
* @param name 名称
|
||||||
@@ -279,9 +300,10 @@ internal class PropertiesAccessorsGenerator {
|
|||||||
val nextAccessorsName = nextItem?.first ?: ""
|
val nextAccessorsName = nextItem?.first ?: ""
|
||||||
val nextClassName = nextItem?.second ?: ""
|
val nextClassName = nextItem?.second ?: ""
|
||||||
val nextMethodName = nextItem?.third ?: ""
|
val nextMethodName = nextItem?.third ?: ""
|
||||||
|
val lastClassName = lastItem?.second ?: ""
|
||||||
val lastMethodName = lastItem?.third ?: ""
|
val lastMethodName = lastItem?.third ?: ""
|
||||||
val isPreLastIndex = index == successiveNames.lastIndex - 1
|
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(successiveName, methodName, className, value)
|
||||||
if (index == successiveNames.lastIndex) return@forEachIndexed
|
if (index == successiveNames.lastIndex) return@forEachIndexed
|
||||||
if (index == 0) noRepeated(TOP_SUCCESSIVE_NAME, methodName, className) {
|
if (index == 0) noRepeated(TOP_SUCCESSIVE_NAME, methodName, className) {
|
||||||
getOrCreateClassSpec(TOP_SUCCESSIVE_NAME, accessorsName)
|
getOrCreateClassSpec(TOP_SUCCESSIVE_NAME, accessorsName)
|
||||||
@@ -291,12 +313,12 @@ internal class PropertiesAccessorsGenerator {
|
|||||||
}
|
}
|
||||||
noRepeated(className, nextMethodName, nextClassName) {
|
noRepeated(className, nextMethodName, nextClassName) {
|
||||||
getOrCreateClassSpec(className, accessorsName).apply {
|
getOrCreateClassSpec(className, accessorsName).apply {
|
||||||
if (isPreLastIndex.not()) {
|
if (!isPreLastIndex) {
|
||||||
addSuccessiveField(nextAccessorsName, nextClassName)
|
addSuccessiveField(nextAccessorsName, nextClassName)
|
||||||
addSuccessiveMethod(nextAccessorsName, nextMethodName, nextClassName)
|
addSuccessiveMethod(nextAccessorsName, nextMethodName, nextClassName)
|
||||||
} else addFinalValueMethod(successiveName, lastMethodName, value)
|
} else addFinalValueMethod(successiveName, 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()
|
preAddConstructorSpecNames.clear()
|
||||||
grandSuccessiveNames.clear()
|
grandSuccessiveNames.clear()
|
||||||
grandSuccessiveDuplicateIndexs.clear()
|
grandSuccessiveDuplicateIndexs.clear()
|
||||||
|
usedSuccessiveMethods.clear()
|
||||||
usedSuccessiveTags.clear()
|
usedSuccessiveTags.clear()
|
||||||
if (isClearAll) memoryExtensionClasses.clear()
|
if (isClearAll) memoryExtensionClasses.clear()
|
||||||
}
|
}
|
||||||
@@ -380,10 +403,15 @@ internal class PropertiesAccessorsGenerator {
|
|||||||
*/
|
*/
|
||||||
internal val compileStubFiles get(): List<JavaFile> {
|
internal val compileStubFiles get(): List<JavaFile> {
|
||||||
val stubFiles = mutableListOf<JavaFile>()
|
val stubFiles = mutableListOf<JavaFile>()
|
||||||
|
val nonnullFile =
|
||||||
|
TypeSpec.annotationBuilder(Nonnull::class.java.simpleName)
|
||||||
|
.addModifiers(Modifier.PUBLIC)
|
||||||
|
.build().createJavaFile(Nonnull::class.java.packageName)
|
||||||
val iExtensionAccessorsFile =
|
val iExtensionAccessorsFile =
|
||||||
TypeSpec.interfaceBuilder(IExtensionAccessors::class.java.simpleName)
|
TypeSpec.interfaceBuilder(IExtensionAccessors::class.java.simpleName)
|
||||||
.addModifiers(Modifier.PUBLIC)
|
.addModifiers(Modifier.PUBLIC)
|
||||||
.build().createJavaFile(IExtensionAccessors::class.java.packageName)
|
.build().createJavaFile(IExtensionAccessors::class.java.packageName)
|
||||||
|
stubFiles.add(nonnullFile)
|
||||||
stubFiles.add(iExtensionAccessorsFile)
|
stubFiles.add(iExtensionAccessorsFile)
|
||||||
return stubFiles
|
return stubFiles
|
||||||
}
|
}
|
||||||
|
@@ -29,6 +29,12 @@ internal typealias PropertyMap = MutableMap<String, Any>
|
|||||||
/** 属性键值规则类型定义 */
|
/** 属性键值规则类型定义 */
|
||||||
internal typealias PropertyValueRule = (value: String) -> String
|
internal typealias PropertyValueRule = (value: String) -> String
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 移除键值内容自动转换类型的引号
|
||||||
|
* @return [String]
|
||||||
|
*/
|
||||||
|
internal fun String.removeAutoConversion() = removeSurrounding("\"").removeSurrounding("'")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解析到键值内容类型
|
* 解析到键值内容类型
|
||||||
* @param isAutoConversion 是否自动转换类型
|
* @param isAutoConversion 是否自动转换类型
|
||||||
@@ -46,7 +52,7 @@ internal fun Any.parseTypedValue(isAutoConversion: Boolean): Pair<KClass<*>, Str
|
|||||||
it.drop(1).dropLast(1)
|
it.drop(1).dropLast(1)
|
||||||
} else it.replace("\"", "\\\"")
|
} else it.replace("\"", "\\\"")
|
||||||
}
|
}
|
||||||
if (isAutoConversion.not()) return Pair(String::class, "\"$valueString\"")
|
if (!isAutoConversion) return Pair(String::class, "\"$valueString\"")
|
||||||
val typeSpec = when {
|
val typeSpec = when {
|
||||||
isStringType -> String::class
|
isStringType -> String::class
|
||||||
valueString.trim().toIntOrNull() != null -> Int::class
|
valueString.trim().toIntOrNull() != null -> Int::class
|
||||||
@@ -56,6 +62,6 @@ internal fun Any.parseTypedValue(isAutoConversion: Boolean): Pair<KClass<*>, Str
|
|||||||
valueString.trim() == "true" || valueString.trim() == "false" -> Boolean::class
|
valueString.trim() == "true" || valueString.trim() == "false" -> Boolean::class
|
||||||
else -> String::class
|
else -> String::class
|
||||||
}; return Pair(typeSpec, if (typeSpec == String::class) "\"$valueString\"" else valueString.let {
|
}; return Pair(typeSpec, if (typeSpec == String::class) "\"$valueString\"" else valueString.let {
|
||||||
if (typeSpec == Long::class && it.endsWith("L").not()) "${it}L" else it
|
if (typeSpec == Long::class && !it.endsWith("L")) "${it}L" else it
|
||||||
})
|
})
|
||||||
}
|
}
|
@@ -73,7 +73,7 @@ internal object PluginUpdateHelper {
|
|||||||
* @return [String]
|
* @return [String]
|
||||||
*/
|
*/
|
||||||
private fun String.findLatest() = runCatching {
|
private fun String.findLatest() = runCatching {
|
||||||
if ((contains("<metadata ") || contains("<metadata>")).not() || endsWith("</metadata>").not()) return@runCatching ""
|
if (!(contains("<metadata ") || contains("<metadata>")) || !endsWith("</metadata>")) return@runCatching ""
|
||||||
DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(InputSource(StringReader(this))).let { document ->
|
DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(InputSource(StringReader(this))).let { document ->
|
||||||
document.getElementsByTagName("latest")?.let { if (it.length > 0) it.item(0)?.textContent ?: "" else "" }
|
document.getElementsByTagName("latest")?.let { if (it.length > 0) it.item(0)?.textContent ?: "" else "" }
|
||||||
}
|
}
|
||||||
|
@@ -36,6 +36,7 @@ import com.highcapable.sweetproperty.plugin.config.type.GenerateLocationType
|
|||||||
import com.highcapable.sweetproperty.plugin.generator.PropertiesAccessorsGenerator
|
import com.highcapable.sweetproperty.plugin.generator.PropertiesAccessorsGenerator
|
||||||
import com.highcapable.sweetproperty.plugin.generator.PropertiesSourcesGenerator
|
import com.highcapable.sweetproperty.plugin.generator.PropertiesSourcesGenerator
|
||||||
import com.highcapable.sweetproperty.plugin.generator.factory.PropertyMap
|
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.camelcase
|
||||||
import com.highcapable.sweetproperty.utils.code.entity.MavenPomData
|
import com.highcapable.sweetproperty.utils.code.entity.MavenPomData
|
||||||
import com.highcapable.sweetproperty.utils.code.factory.compile
|
import com.highcapable.sweetproperty.utils.code.factory.compile
|
||||||
@@ -102,7 +103,7 @@ internal object PropertiesDeployHelper {
|
|||||||
internal fun initialize(settings: Settings, configs: ISweetPropertyConfigs) {
|
internal fun initialize(settings: Settings, configs: ISweetPropertyConfigs) {
|
||||||
this.configs = configs
|
this.configs = configs
|
||||||
checkingConfigsModified(settings)
|
checkingConfigsModified(settings)
|
||||||
if (configs.isEnable.not()) return
|
if (!configs.isEnable) return
|
||||||
generatedAccessors(settings)
|
generatedAccessors(settings)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,7 +112,7 @@ internal object PropertiesDeployHelper {
|
|||||||
* @param rootProject 当前根项目
|
* @param rootProject 当前根项目
|
||||||
*/
|
*/
|
||||||
internal fun resolve(rootProject: Project) {
|
internal fun resolve(rootProject: Project) {
|
||||||
if (configs.isEnable.not()) return
|
if (!configs.isEnable) return
|
||||||
resolveAccessors(rootProject)
|
resolveAccessors(rootProject)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,7 +121,7 @@ internal object PropertiesDeployHelper {
|
|||||||
* @param rootProject 当前根项目
|
* @param rootProject 当前根项目
|
||||||
*/
|
*/
|
||||||
internal fun deploy(rootProject: Project) {
|
internal fun deploy(rootProject: Project) {
|
||||||
if (configs.isEnable.not()) return
|
if (!configs.isEnable) return
|
||||||
deployAccessors(rootProject)
|
deployAccessors(rootProject)
|
||||||
deploySourcesCode(rootProject)
|
deploySourcesCode(rootProject)
|
||||||
}
|
}
|
||||||
@@ -152,13 +153,13 @@ internal object PropertiesDeployHelper {
|
|||||||
allConfigs.add(configs.global.buildScript)
|
allConfigs.add(configs.global.buildScript)
|
||||||
}
|
}
|
||||||
configs.projects.forEach { (name, subConfigs) ->
|
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)))
|
allProperties.add(generatedProperties(subConfigs.buildScript, ProjectDescriptor.create(settings, name)))
|
||||||
allConfigs.add(subConfigs.buildScript)
|
allConfigs.add(subConfigs.buildScript)
|
||||||
}
|
}
|
||||||
if (isConfigsModified.not() &&
|
if (!isConfigsModified &&
|
||||||
allProperties == cachedSettingsProperties &&
|
allProperties == cachedSettingsProperties &&
|
||||||
accessorsDir.resolve(accessorsPomData.relativePomPath).isEmpty().not()
|
!accessorsDir.resolve(accessorsPomData.relativePomPath).isEmpty()
|
||||||
) return
|
) return
|
||||||
cachedSettingsProperties = allProperties
|
cachedSettingsProperties = allProperties
|
||||||
accessorsGenerator.build(allConfigs, allProperties).compile(accessorsPomData, accessorsDir.absolutePath, accessorsGenerator.compileStubFiles)
|
accessorsGenerator.build(allConfigs, allProperties).compile(accessorsPomData, accessorsDir.absolutePath, accessorsGenerator.compileStubFiles)
|
||||||
@@ -169,7 +170,7 @@ internal object PropertiesDeployHelper {
|
|||||||
* @param rootProject 当前根项目
|
* @param rootProject 当前根项目
|
||||||
*/
|
*/
|
||||||
private fun resolveAccessors(rootProject: Project) {
|
private fun resolveAccessors(rootProject: Project) {
|
||||||
if (accessorsDir.resolve(accessorsPomData.relativePomPath).isEmpty().not())
|
if (!accessorsDir.resolve(accessorsPomData.relativePomPath).isEmpty())
|
||||||
rootProject.addDependencyToBuildScript(accessorsDir.absolutePath, accessorsPomData)
|
rootProject.addDependencyToBuildScript(accessorsDir.absolutePath, accessorsPomData)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,7 +182,7 @@ internal object PropertiesDeployHelper {
|
|||||||
/** 部署扩展方法 */
|
/** 部署扩展方法 */
|
||||||
fun Project.deploy() {
|
fun Project.deploy() {
|
||||||
val configs = configs.with(this).buildScript
|
val configs = configs.with(this).buildScript
|
||||||
if (configs.isEnable.not()) return
|
if (!configs.isEnable) return
|
||||||
val className = accessorsGenerator.propertiesClass(configs.name)
|
val className = accessorsGenerator.propertiesClass(configs.name)
|
||||||
val accessorsClass = loadBuildScriptClass(className) ?: SError.make(
|
val accessorsClass = loadBuildScriptClass(className) ?: SError.make(
|
||||||
"""
|
"""
|
||||||
@@ -205,9 +206,9 @@ internal object PropertiesDeployHelper {
|
|||||||
fun Project.generate() {
|
fun Project.generate() {
|
||||||
val configs = configs.with(this).sourcesCode
|
val configs = configs.with(this).sourcesCode
|
||||||
val outputDir = file(configs.generateDirPath)
|
val outputDir = file(configs.generateDirPath)
|
||||||
if (configs.isEnable.not()) return
|
if (!configs.isEnable) return
|
||||||
val properties = generatedProperties(configs, ProjectDescriptor.create(project = this))
|
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)
|
if (configs.isEnable) configureSourceSets(project = this)
|
||||||
return
|
return
|
||||||
}; outputDir.apply { if (exists()) deleteRecursively() }
|
}; outputDir.apply { if (exists()) deleteRecursively() }
|
||||||
@@ -293,7 +294,8 @@ internal object PropertiesDeployHelper {
|
|||||||
fun String.resolveValue(): String = replaceInterpolation { matchKey ->
|
fun String.resolveValue(): String = replaceInterpolation { matchKey ->
|
||||||
if (resolveKeys.size > 5) SError.make("Key \"$key\" has been called recursively multiple times of those $resolveKeys")
|
if (resolveKeys.size > 5) SError.make("Key \"$key\" has been called recursively multiple times of those $resolveKeys")
|
||||||
resolveKeys.add(matchKey)
|
resolveKeys.add(matchKey)
|
||||||
val resolveValue = if (configs.isEnableValueInterpolation) resolveKeyValues[matchKey] ?: "" else matchKey
|
var resolveValue = if (configs.isEnableValueInterpolation) resolveKeyValues[matchKey] ?: "" else matchKey
|
||||||
|
resolveValue = resolveValue.removeAutoConversion()
|
||||||
if (resolveValue.hasInterpolation()) resolveValue.resolveValue()
|
if (resolveValue.hasInterpolation()) resolveValue.resolveValue()
|
||||||
else resolveValue
|
else resolveValue
|
||||||
}
|
}
|
||||||
|
@@ -52,7 +52,7 @@ internal fun String.parseUnixFileSeparator() = replace("\\", "/")
|
|||||||
* - 如果文件不存在 - 返回 true
|
* - 如果文件不存在 - 返回 true
|
||||||
* @return [Boolean]
|
* @return [Boolean]
|
||||||
*/
|
*/
|
||||||
internal fun File.isEmpty() = exists().not() || isDirectory.not() || listFiles().isNullOrEmpty()
|
internal fun File.isEmpty() = !exists() || !isDirectory || listFiles().isNullOrEmpty()
|
||||||
|
|
||||||
/** 删除目录下的空子目录 */
|
/** 删除目录下的空子目录 */
|
||||||
internal fun File.deleteEmptyRecursively() {
|
internal fun File.deleteEmptyRecursively() {
|
||||||
|
@@ -59,7 +59,7 @@ internal object CodeCompiler {
|
|||||||
if (files.isEmpty()) {
|
if (files.isEmpty()) {
|
||||||
if (outputDir.exists()) outputDir.deleteRecursively()
|
if (outputDir.exists()) outputDir.deleteRecursively()
|
||||||
return
|
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 outputBuildDir = "$outputDirPath/build".toFile().also { if (it.exists()) it.deleteRecursively(); it.mkdirs() }
|
||||||
val outputClassesDir = "${outputBuildDir.absolutePath}/classes".toFile().apply { mkdirs() }
|
val outputClassesDir = "${outputBuildDir.absolutePath}/classes".toFile().apply { mkdirs() }
|
||||||
val outputSourcesDir = "${outputBuildDir.absolutePath}/sources".toFile().apply { mkdirs() }
|
val outputSourcesDir = "${outputBuildDir.absolutePath}/sources".toFile().apply { mkdirs() }
|
||||||
@@ -99,7 +99,7 @@ internal object CodeCompiler {
|
|||||||
* @param sourcesDir 编译源码目录
|
* @param sourcesDir 编译源码目录
|
||||||
*/
|
*/
|
||||||
private fun createJarAndPom(pomData: MavenPomData, outputDir: File, buildDir: File, classesDir: File, sourcesDir: File) {
|
private fun createJarAndPom(pomData: MavenPomData, outputDir: File, buildDir: File, classesDir: File, sourcesDir: File) {
|
||||||
val 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(classesDir, pomDir, pomData, isSourcesJar = false)
|
||||||
packageToJar(sourcesDir, pomDir, pomData, isSourcesJar = true)
|
packageToJar(sourcesDir, pomDir, pomData, isSourcesJar = true)
|
||||||
writePom(pomDir, pomData)
|
writePom(pomDir, pomData)
|
||||||
@@ -159,7 +159,7 @@ internal object CodeCompiler {
|
|||||||
* @throws IllegalStateException 如果编译输出目录不存在
|
* @throws IllegalStateException 如果编译输出目录不存在
|
||||||
*/
|
*/
|
||||||
private fun packageToJar(buildDir: File, outputDir: File, pomData: MavenPomData, isSourcesJar: Boolean) {
|
private fun packageToJar(buildDir: File, outputDir: File, pomData: MavenPomData, isSourcesJar: Boolean) {
|
||||||
if (buildDir.exists().not()) SError.make("Jar file output path not found: ${buildDir.absolutePath}")
|
if (!buildDir.exists()) SError.make("Jar file output path not found: ${buildDir.absolutePath}")
|
||||||
val jarFile = outputDir.resolve("${pomData.artifactId}-${pomData.version}${if (isSourcesJar) "-sources" else ""}.jar")
|
val jarFile = outputDir.resolve("${pomData.artifactId}-${pomData.version}${if (isSourcesJar) "-sources" else ""}.jar")
|
||||||
if (jarFile.exists()) jarFile.delete()
|
if (jarFile.exists()) jarFile.delete()
|
||||||
ZipFile(jarFile).addFolder(buildDir, ZipParameters().apply { isIncludeRootFolder = false })
|
ZipFile(jarFile).addFolder(buildDir, ZipParameters().apply { isIncludeRootFolder = false })
|
||||||
|
Reference in New Issue
Block a user