mirror of
https://github.com/HighCapable/SweetProperty.git
synced 2025-09-05 10:15:36 +08:00
feat: add checking update function
This commit is contained in:
@@ -18,6 +18,9 @@ plugins:
|
|||||||
version: 0.25.3
|
version: 0.25.3
|
||||||
|
|
||||||
libraries:
|
libraries:
|
||||||
|
com.squareup.okhttp3:
|
||||||
|
okhttp:
|
||||||
|
version: 4.11.0
|
||||||
com.squareup:
|
com.squareup:
|
||||||
kotlinpoet:
|
kotlinpoet:
|
||||||
version: 1.14.2
|
version: 1.14.2
|
||||||
|
@@ -21,6 +21,7 @@ kotlin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
implementation(com.squareup.okhttp3.okhttp)
|
||||||
implementation(com.squareup.kotlinpoet)
|
implementation(com.squareup.kotlinpoet)
|
||||||
implementation(com.squareup.javapoet)
|
implementation(com.squareup.javapoet)
|
||||||
implementation(net.lingala.zip4j.zip4j)
|
implementation(net.lingala.zip4j.zip4j)
|
||||||
|
@@ -25,6 +25,7 @@ import com.highcapable.sweetproperty.SweetProperty
|
|||||||
import com.highcapable.sweetproperty.gradle.factory.getOrCreate
|
import com.highcapable.sweetproperty.gradle.factory.getOrCreate
|
||||||
import com.highcapable.sweetproperty.gradle.proxy.IGradleLifecycle
|
import com.highcapable.sweetproperty.gradle.proxy.IGradleLifecycle
|
||||||
import com.highcapable.sweetproperty.plugin.extension.dsl.configure.SweetPropertyConfigureExtension
|
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.plugin.helper.PropertiesDeployHelper
|
||||||
import com.highcapable.sweetproperty.utils.debug.SError
|
import com.highcapable.sweetproperty.utils.debug.SError
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
@@ -44,6 +45,7 @@ internal class SweetPropertyExtension internal constructor() : IGradleLifecycle
|
|||||||
|
|
||||||
override fun onSettingsEvaluate(settings: Settings) {
|
override fun onSettingsEvaluate(settings: Settings) {
|
||||||
val configs = configure?.build(settings) ?: SError.make("Extension \"${SweetPropertyConfigureExtension.NAME}\" create failed")
|
val configs = configure?.build(settings) ?: SError.make("Extension \"${SweetPropertyConfigureExtension.NAME}\" create failed")
|
||||||
|
PluginUpdateHelper.checkingForUpdate(settings)
|
||||||
PropertiesDeployHelper.initialize(settings, configs)
|
PropertiesDeployHelper.initialize(settings, configs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -0,0 +1,81 @@
|
|||||||
|
/*
|
||||||
|
* SweetProperty - An easy get project properties anywhere Gradle plugin.
|
||||||
|
* Copyright (C) 2019-2023 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 / 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>")).not() || endsWith("</metadata>").not()) 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() ?: ""
|
||||||
|
}
|
@@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* SweetProperty - An easy get project properties anywhere Gradle plugin.
|
||||||
|
* Copyright (C) 2019-2023 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() ?: ""
|
Reference in New Issue
Block a user