Initial commit

This commit is contained in:
2023-09-03 01:11:31 +08:00
commit f03805ff2c
53 changed files with 4392 additions and 0 deletions

5
docs/changelog-zh-CN.md Normal file
View File

@@ -0,0 +1,5 @@
# 更新日志
## 1.0.0 | 2023.09.03
- 首个版本提交至 Maven

5
docs/changelog.md Normal file
View File

@@ -0,0 +1,5 @@
# Changelog
## 1.0.0 | 2023.09.03
- The first version is submitted to Maven

282
docs/guide-zh-CN.md Normal file
View File

@@ -0,0 +1,282 @@
# Sweet Property 使用文档
在开始使用之前,建议你仔细阅读此文档,以便你能更好地了解它的作用方式与功能。
如果你的项目依然在使用 Groovy DSL 进行管理,推荐迁移到 Kotlin DSL。
在 Groovy DSL 中使用此插件发生的任何问题,我们都将不再负责排查和修复,并且在后期版本可能会完全不再支持 Groovy DSL。
注意:此文档中将不再详细介绍在 Groovy DSL 中的使用方法。
## 前提条件
请注意 `SweetProperty` 推荐使用 `pluginManagement` 新方式进行装载,它是自 Gradle `7.x.x` 版本开始添加的功能。
如果你的项目依然在使用 `buildscript` 的方式进行管理,推荐迁移到新方式,这里将不再提供旧版本的使用方式说明。
## 快速开始
首先,打开你根项目的 `settings.gradle.kts`
在你根项目的 `settings.gradle.kts` 中加入如下代码。
如果已经存在 `pluginManagement` 则不需要重复添加。
> 示例如下
```kotlin
pluginManagement {
repositories {
gradlePluginPortal()
google()
mavenCentral()
}
}
plugins {
id("com.highcapable.sweetproperty") version "<version>"
}
```
请将上述代码中的 `<version>` 替换为
[Release](https://github.com/HighCapable/SweetProperty/releases) 中的最新版本, 请注意<u>**不要**</u>在后方加入 `apply false`
上述配置完成后,运行一次 Gradle Sync。
此时 `SweetProperty` 将会自动搜索根项目和每个子项目中的 `gradle.properties` 文件,并读取其中的属性键值,为每个项目生成对应的代码。
## 功能配置
你可以对 `SweetProperty` 进行配置来实现自定义和个性化功能。
`SweetProperty` 为你提供了相对丰富的可自定义功能,下面是这些功能的说明与配置方法。
请在你的 `settings.gradle.kts` 中添加 `sweetProperty` 方法块以开始配置 `SweetProperty`
> 示例如下
```kotlin
sweetProperty {
// 启用 SweetProperty设置为 false 将禁用所有功能
isEnable = true
// 全局配置
// 你可以在全局配置中修改所有项目中的配置
// 每个项目中未进行声明的配置将使用全局配置
// 每个配置方法块中的功能完全一致
// 你可以参考下方根项目、子项目的配置方法
global {
// 通用代码生成功能
// 在这里你可以同时配置构建脚本和项目生成代码的相关功能
all {
// 启用功能
// 你可以分别对 "sourcesCode"、"buildScript" 进行设置
isEnable = true
// 设置属性配置文件名称
// 一般情况下不需要修改此设置,错误的文件名将导致获取到空键值内容
// 如果你有一个自定义名称的属性键值文件,你可以修改这里的设置
// 注意:建议为每个项目单独配置,而不是在全局中修改,以防发生问题
propertiesFileName = "gradle.properties"
// 是否启用排除非字符串类型键值内容
// 默认启用,启用后将从属性键值中排除不是字符串类型的键值及内容
// 这可以排除例如一些系统环境变量的配置或内存中的数据
isEnableExcludeNonStringValue = true
// 是否启用类型自动转换功能
// 默认启用,启用后将自动识别属性键值中的类型并转换为对应的类型
// 例如 "name=hello" 和 "number=1" 它们将会被自动转换为 String 和 Int
isEnableTypeAutoConversion = true
// 是否启用键值内容插值功能
// 默认启用,启用后将自动识别属性键值内容中的 ${...} 内容并进行替换
// 注意:插值的内容仅会从当前 (当前配置文件) 属性键值列表进行查找
isEnableValueInterpolation = true
// 设置固定存在的属性键值数组
// 在这里可以设置一些一定存在的键值,这些键值无论能否从属性键值中得到都会进行生成
// 这些键值在属性键值存在时使用属性键值的内容,不存在时使用这里设置的内容
// 注意:属性键值名称不能存在特殊符号以及空格,否则可能会生成失败
// 例如:你需要获取存于自己本机的密钥或证书,但是其他人的设备上没有这些键值
// 此时这个功能就会变得非常有用,你可以设置在没有这些键值时的默认值
// 当然,你也可以使用这个功能强行向生成的代码中添加额外的属性键值
permanentKeyValues(
"permanent.some.key1" to "some_value_1",
"permanent.some.key2" to "some_value_2"
)
// 设置需要排除的属性键值名称数组
// 在这里可以设置一些你希望从已知的属性键值中排除的键值名称
// 这些键值在属性键值存在它们时被排除,不会出现在生成的代码中
// 注意:如果你排除了 "permanentKeyValues" 中设置的键值,
// 那么它们只会变为你设置的初始键值内容并继续保持存在
// 你可以传入 Regex 或使用 String.toRegex 以使用正则功能
excludeKeys(
"exclude.some.key1",
"exclude.some.key2"
)
// 设置从何处生成属性键值
// 默认为 "CURRENT_PROJECT" 和 "ROOT_PROJECT"
// 你可以使用以下类型来进行设置
// "CURRENT_PROJECT" ← 当前项目
// "ROOT_PROJECT" ← 根项目
// "GLOBAL" ← 全局 (用户目录)
// "SYSTEM" ← 系统
// "SYSTEM_ENV" ← 系统环境变量
// SweetProperty 将从你设置的生成位置依次生成属性键值,生成位置的顺序跟随你设置的顺序决定
// 风险提示:"GLOBAL"、"SYSTEM"、"SYSTEM_ENV" 可能存在密钥和证书,请小心管理生成的代码
generateFrom(CURRENT_PROJECT, ROOT_PROJECT)
}
// 项目生成代码功能
// 此功能类似于 Android 项目自动生成的 BuildConfig
// 在项目中生成的代码可直接被当前项目使用
// 这里的配置包括 "all" 中的配置,你可以对其进行复写
sourcesCode {
// 自定义生成的目录路径
// 你可以填写相对于当前项目的路径
// 默认为 "build/generated/sweet-property"
// 建议将生成的代码放置于 "build" 目录下,因为生成的代码不建议去修改它
generateDirPath = "build/generated/sweet-property"
// 自定义生成的包名
// Android 项目默认使用 "android" 配置方法块中的 "namespace"
// 普通的 Kotlin on Jvm 项目默认使用项目设置的 "project.group"
// 你可以不进行设置,包名在一般情况下会自动进行匹配
packageName = "com.example.mydemo"
// 自定义生成的类名
// 默认使用当前项目的名称 + "Properties"
// 你可以不进行设置,类名在一般情况下会自动进行匹配
className = "MyDemo"
// 是否启用受限访问功能
// 默认不启用,启用后将为生成的类和方法添加 "internal" 修饰符
// 如果你的项目为工具库或依赖,通常情况下建议启用
// 启用后可以防止其他开发者在引用你的库时调用到你的项目属性键值发生问题
isEnableRestrictedAccess = false
}
// 构建脚本生成代码功能
// 在构建脚本中生成的代码可直接被当前 "build.gradle.kts" 使用
// 这里的配置包括 "all" 中的配置,你可以对其进行复写
// 注意Gradle 中也有一个 "buildscript" 方法块,只不过是小写的 "s",请不要混淆
buildScript {
// 自定义构建脚本扩展方法名称
// 默认为 "property"
// 你将在 "build.gradle.kts" 中使用类似 "property.some.key" 的方式进行调用
extensionName = "property"
}
}
// 根项目 (Root Project) 配置
// 这是一个特殊的配置方法块,只能用于根项目
rootProject {
all {
// 配置 "all"
}
sourcesCode {
// 配置 "sourcesCode"
}
buildScript {
// 配置 "buildScript"
}
}
// 子项目配置
// 在方法参数中填入需要配置的项目完整名称来配置对应的项目
// 如果你的项目为嵌套型子项目,例如 app → sub
// 此时你需要使用 ":" 来分隔多个子项目,例如 "app:sub"
// 你不需要再填写子项目前面的 ":",例如 ":app"
// 根项目的名称不能直接用来配置子项目,请使用 "rootProject"
project("app") {
all {
// 配置 "all"
}
sourcesCode {
// 配置 "sourcesCode"
}
buildScript {
// 配置 "buildScript"
}
}
}
```
如需在 Groovy DSL 中使用,请将所有变量的 `=` 改为空格,并删除 `Enable` 前方的 `is` 并将 `E` 小写即可。
如果你遇到了 `Gradle DSL method not found` 错误,解决方案为迁移到 Kotlin DSL。
如果你不想全部使用 Kotlin DSL你也可以仅将 `settings.gradle` 迁移到 `settings.gradle.kts`
## 使用示例
下面是一个项目的 `gradle.properties` 配置文件。
```properties
project.groupName=com.highcapable.sweetpropertydemo
project.description=Hello SweetProperty Demo!
project.version=1.0.0
```
在构建脚本 `build.gradle.kts` 中,我们就可以如下所示这样直接去使用这些键值。
这里以 Maven 发布的配置部分举例。
```kotlin
publications {
create<MavenPublication>("maven") {
groupId = property.project.groupName
version = property.project.version
pom.description.set(property.project.description)
from(components["java"])
}
}
```
同样地,你也可以在当前项目中调用生成的键值。
```kotlin
SweetPropertyDemoProperties.PROJECT_GROUP_NAME
SweetPropertyDemoProperties.PROJECT_DESCRIPTION
SweetPropertyDemoProperties.PROJECT_VERSION
```
下面再以 Android 项目举例。
在 Android 项目中通常需要配置很多重复、固定的属性,例如 `targetSdk`
```properties
project.compileSdk=33
project.targetSdk=33
project.minSdk=22
```
当你设置了 `isEnableTypeAutoConversion = true` 时,`SweetProperty` 在生成实体类过程在默认配置下将尝试将其转换为对应的类型。
例如下方所使用的键值,其类型可被识别为整型,可被项目配置直接使用。
```kotlin
android {
compileSdk = property.project.compileSdk
defaultConfig {
minSdk = property.project.minSdk
targetSdk = property.project.targetSdk
}
}
```
你可以无需再使用 `buildConfigField``BuildConfig` 添加代码,有了 `SweetProperty` 生成的属性键值代码,你可以更加灵活地管理你的项目。
你还可以在属性键值中使用 `${...}` 互相引用其中的内容,但不允许递归引用。
当你设置了 `isEnableValueInterpolation = true` 时,`SweetProperty` 将自动合并这些引用的内容到对应位置。
```properties
project.name=MyDemo
project.developer.name=myname
project.url=https://github.com/${project.developer.name}/${project.name}
```
注意:这个特性是 `SweetProperty` 提供的,原生的 `gradle.properties` 并不支持此功能。
**可能遇到的问题**
如果你的项目仅存在一个根项目,且没有导入任何子项目,此时如果扩展方法不能正常生成,
你可以将你的根项目迁移至子项目并在 `settings.gradle.kts` 中导入这个子项目,这样即可解决此问题。
我们一般推荐将项目的功能进行分类,根项目仅用来管理插件和一些配置。
**局限性说明**
`SweetProperty` 无法生成 `settings.gradle.kts` 中的扩展方法,因为这属于 `SweetProperty` 的上游。
## 问题反馈
如果你在使用 `SweetProperty` 的过程中遇到了任何问题,你都可以随时在 GitHub 开启一个 `issues` 向我们反馈。

297
docs/guide.md Normal file
View File

@@ -0,0 +1,297 @@
# Sweet Property Documentation
Before you start using it, it is recommended that you read this document carefully so that you can better understand how it works and its functions.
If your project is still managed using Groovy DSL, it is recommended to migrate to Kotlin DSL.
We will no longer be responsible for troubleshooting and fixing any issues that occur with this plugin in Groovy DSL,
and Groovy DSL support may be dropped entirely in later releases.
Note: Usage in the Groovy DSL will not be detailed in this document.
## Prerequisites
Please note that `SweetProperty` is recommended to be loaded using the new `pluginManagement` method, which is a feature added since Gradle `7.x.x`
version.
If your project is still managed using the `buildscript` method, it is recommended to migrate to the new method, and the instructions for using the
old version will no longer be provided here.
## Quick Start
First, open `settings.gradle.kts` in your root project.
Add the following code to `settings.gradle.kts` in your root project.
If `pluginManagement` already exists, there is no need to add it again.
> The following example
```kotlin
pluginManagement {
repositories {
gradlePluginPortal()
google()
mavenCentral()
}
}
plugins {
id("com.highcapable.sweetproperty") version "<version>"
}
```
Please replace `<version>` in the above code with the latest version in
[Release](https://github.com/HighCapable/SweetProperty/releases), please note <u>**DO NOT**</u> add `apply false` after.
After the above configuration is completed, run Gradle Sync once.
## Function Configuration
You can configure `SweetProperty` to achieve custom and personalized functions.
`SweetProperty` provides you with a relatively rich set of customizable functions.
The following are the descriptions and configuration methods of these functions.
Please add `sweetProperty` method block to your `settings.gradle.kts` to start configuring `SweetProperty`.
> The following example
```kotlin
sweetProperty {
// Enable SweetProperty, set to false will disable all functions
isEnable = true
// Global configuration
// You can modify the configuration in all projects in the global configuration
// Configurations that are not declared in each project will use the global configuration
// The functions in each configuration method block are exactly the same
// You can refer to the configuration method of the root project and sub-projects below
global {
// General code generation function
// Here you can configure the related functions of the build script and the project generated code at the same time
all {
// Enable functionality
// You can set "sourcesCode" and "buildScript" respectively
isEnable = true
// Set properties name
// In general, you don't need to modify this setting, the wrong file name will lead to getting empty key-values content
// If you have a properties file with a custom name, you can modify the settings here
// Note: It is recommended to configure each project individually, rather than modifying globally, in case of problems
propertiesFileName = "gradle.properties"
// Whether to enable the exclusion of non-string type key-values content
// Enabled by default, when enabled, key-values and content that are not string types will be excluded from the properties key-values
// This can exclude e.g. configuration of some system environment variables or data in memory
isEnableExcludeNonStringValue = true
// Whether to enable the type automatic conversion function
// Enabled by default, when enabled,
// the type in the properties key-values will be automatically recognized and converted to the corresponding type
// For example "name=hello" and "number=1" they will be automatically converted to String and Int
isEnableTypeAutoConversion = true
// Whether to enable key-values content interpolation
// Enabled by default, after enabling, the ${...} content in the properties key-values content
// will be automatically recognized and replaced
// Note: The interpolated content will only be searching from the current (current configuration file) properties key-values list
isEnableValueInterpolation = true
// Set a fixed attribute key-value array
// Here you can set some key values that must exist,
// and these key values will be generated regardless of whether they can be obtained from the properties key-values
// These key-values use the content of the properties key-values when the properties key-values exists,
// and use the content set here when it does not exist
// Note: There cannot be special symbols and spaces in the attribute key value name, otherwise the generation may fail
// For example: you need to obtain the key or certificate stored on your own devices,
// but these keys are not available on other people's devices
// At this point this function will become very useful, you can set the default value when there are no these key-values
// Of course, you can also use this function to forcefully add additional properties key-values to the generated code
permanentKeyValues(
"permanent.some.key1" to "some_value_1",
"permanent.some.key2" to "some_value_2"
)
// Set an array of properties key-values names that need to be excluded
// Here you can set some key names that you want to exclude from the known properties keys
// These keys are excluded when they exist in the properties keys and will not appear in the generated code
// Note: If you exclude the key-values set in "permanentKeyValues",
// then they will only become the initial key-values content you set and continue to exist
// You can pass in a Regex or use String.toRegex to use the regex function
excludeKeys(
"exclude.some.key1",
"exclude.some.key2"
)
// Set where to generate properties key-values
// Defaults to "CURRENT_PROJECT" and "ROOT_PROJECT"
// You can use the following types to set
// "CURRENT_PROJECT" ← Current project
// "ROOT_PROJECT" ← Root project
// "GLOBAL" ← Global (user directory)
// "SYSTEM" ← System
// "SYSTEM_ENV" ← System environment variable
// SweetProperty will generate properties key-values sequentially from the generation positions you set,
// and the order of generation positions is determined by the order you set
// Pay Attention: "GLOBAL", "SYSTEM", "SYSTEM_ENV" may have keys and certificates, please manage the generated code carefully
generateFrom(CURRENT_PROJECT, ROOT_PROJECT)
}
// Project generation code function
// This function is similar to the BuildConfig automatically generated by Android projects
// The code generated in the project can be directly used by the current project
// The configuration here includes the configuration in "all", you can override it
sourcesCode {
// Custom generated directory path
// You can fill in the path relative to the current project
// Defaults to "build/generated/sweet-property"
// 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 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
// You dont need to set it, the package name will automatically match under normal circumstances
packageName = "com.example.mydemo"
// Custom generated class name
// By default, the name of the current project + "Properties" is used
// You don't need to set it, the class name will be automatically matched under normal circumstances
className = "MyDemo"
// Whether to enable restricted access
// Not enabled by default
// When enabled, the "internal" modifier will be added to the generated classes and methods
// If your project is a tool library or dependency, it is usually recommended to enable it
// Once enabled, it can prevent other developers from calling your project properties key-values when referencing your library
isEnableRestrictedAccess = false
}
// Build script generate code function
// The code generated in the build script can be directly used by the current "build.gradle.kts"
// The configuration here includes the configuration in "all", you can override it
// Note: There is also a "buildscript" method block in Gradle, but it is just a lowercase "s", please don't confuse it
buildScript {
// Custom build script extension method name
// Defaults to "property"
// You will call it in "build.gradle.kts" using something like "property.some.key"
extensionName = "property"
}
}
// Root project configuration
// This is a special configuration method block that can only be used in root projects
rootProject {
all {
// Configure "all"
}
sourcesCode {
// Configure "sourcesCode"
}
buildScript {
// Configure "buildScript"
}
}
// Sub-projects configuration
// 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"
// The name of the root project cannot be used directly to configure sub-projects, please use "rootProject"
project("app") {
all {
// Configure "all"
}
sourcesCode {
// Configure "sourcesCode"
}
buildScript {
// 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`.
If you encounter `Gradle DSL method not found` error, the solution is to migrate to Kotlin DSL.
If you don't want to use the Kotlin DSL entirely, you can also migrate just `settings.gradle` to `settings.gradle.kts`.
## Usage Example
Below is a project's `gradle.properties` configuration file.
```properties
project.groupName=com.highcapable.sweetpropertydemo
project.description=Hello SweetProperty Demo!
project.version=1.0.0
```
In the build script `build.gradle.kts`, we can use these keys directly as shown below.
Here is an example of the configuration part published by Maven.
```kotlin
publications {
create<MavenPublication>("maven") {
groupId = property.project.groupName
version = property.project.version
pom.description.set(property.project.description)
from(components["java"])
}
}
```
Similarly, you can also call the generated key-value in the current project.
```kotlin
SweetPropertyDemoProperties.PROJECT_GROUP_NAME
SweetPropertyDemoProperties.PROJECT_DESCRIPTION
SweetPropertyDemoProperties.PROJECT_VERSION
```
Let's take the Android project as an example.
In Android projects, it is usually necessary to configure many repeated and fixed properties, such as `targetSdk`.
```properties
project.compileSdk=33
project.targetSdk=33
project.minSdk=22
```
When you set the `isEnableTypeAutoConversion = true`, `SweetProperty` will try to convert it to the corresponding type under the
default configuration during the process of generating the entity class.
For example, the type of the key-value used below can be recognized as an integer and can be directly used by the project configuration.
```kotlin
android {
compileSdk = property.project.compileSdk
defaultConfig {
minSdk = property.project.minSdk
targetSdk = property.project.targetSdk
}
}
```
You no longer need to use `buildConfigField` to add code to `BuildConfig`,
with the properties key-values code generated by `SweetProperty`, you can manage your project more flexibly.
You can also use `${...}` in properties values to refer to each other, but recursive references are not allowed.
When you set the `isEnableValueInterpolation = true`,
`SweetProperty` will automatically merge the contents of these references into the corresponding locations.
```properties
project.name=MyDemo
project.developer.name=myname
project.url=https://github.com/${project.developer.name}/${project.name}
```
Note: This feature is provided by `SweetProperty`, and the native `gradle.properties` does not support this feature.
**Possible Problems**
If your project only has one root project and does not import any sub-projects,
if extension methods are not generated properly,
you can solve this problem by migrating your root project to a sub-projects and importing this sub-projects in `settings.gradle.kts`.
We generally recommend classifying the functions of the project, and the root project is only used to manage plugins and some configurations.
**Limitations Note**
`SweetProperty` cannot generated extension methods in `settings.gradle.kts`, because this belongs to the upstream of `SweetProperty`.
## Feedback
If you encounter any problems while using `SweetProperty`, you can always open an `issues` on GitHub to give us feedback.