Created
December 20, 2022 11:28
-
-
Save xymelon/5f199d4b2166885ecc349e1fe1ab7c99 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This script is used to initialize the build in a module or plugin project. | |
// During this phase, the script applies the Maven plugin and configures the | |
// destination of the local repository. | |
// The local repository will contain the AAR and POM files. | |
// 基于flutter sdk 3.3.10 aar_init_script.gradle修改(位于packages/flutter_tools/gradle/目录下) | |
// 1、支持上传本地或远程maven仓库(包括自身和依赖的插件库) | |
// 2、支持flutter插件依赖库版本号(以插件依赖库中pubspec.yaml#version为准),并校验maven库中是否存在,避免重复上传maven仓库报错 | |
import java.nio.file.Paths | |
// 改动:新增maven相关参数、版本号 | |
void configureProject(Project project, String mavenUrl, String mavenUser, String mavenPwd, String version) { | |
if (!project.hasProperty("android")) { | |
throw new GradleException("Android property not found.") | |
} | |
if (!project.android.hasProperty("libraryVariants")) { | |
throw new GradleException("Can't generate AAR on a non Android library project."); | |
} | |
// 改动:参数非空校验 | |
if (mavenUrl == null || mavenUrl.isEmpty()) { | |
throw new GradleException("mavenUrl参数为空") | |
} | |
// Snapshot versions include the timestamp in the artifact name. | |
// Therefore, remove the snapshot part, so new runs of `flutter build aar` overrides existing artifacts. | |
// This version isn't relevant in Flutter since the pub version is used | |
// to resolve dependencies. | |
// project.version = project.version.replace("-SNAPSHOT", "") | |
// if (project.hasProperty("buildNumber")) { | |
// project.version = project.property("buildNumber") | |
// } | |
// 改动:版本号参数传递 | |
project.version = version | |
if (isLocalMavenRepo(mavenUrl)) { | |
// 本地路径时,保持原有逻辑 | |
project.version = project.version.replace("-SNAPSHOT", "") | |
} | |
project.android.libraryVariants.all { variant -> | |
addAarTask(project, mavenUrl, variant) | |
} | |
project.publishing { | |
repositories { | |
maven { | |
// 改动:支持上传maven仓库(本地仓库不用认证) | |
url = mavenUrl | |
if (!isLocalMavenRepo(mavenUrl)) { | |
credentials { | |
username = mavenUser | |
password = mavenPwd | |
} | |
} | |
} | |
} | |
} | |
// Some extra work to have alternative publications with the same format as the old maven plugin. | |
// Instead of using classifiers for the variants, the old maven plugin appended `_{variant}` to the artifactId | |
// First, create a default MavenPublication for each variant (except "all" since that is used to publish artifacts in the new way) | |
project.components.forEach { component -> | |
if (component.name != "all") { | |
project.publishing.publications.create(component.name, MavenPublication) { | |
from component | |
} | |
} | |
} | |
// then, rename the artifactId to include the variant and make sure to remove any classifier | |
// data tha gradle has set, as well as adding a <relocation> tag pointing to the new coordinates | |
project.publishing.publications.forEach { pub -> | |
def relocationArtifactId = pub.artifactId | |
pub.artifactId = "${relocationArtifactId}_${pub.name}" | |
pub.alias = true | |
pub.pom.distributionManagement { | |
relocation { | |
// New artifact coordinates | |
groupId = "${pub.groupId}" | |
artifactId = "${relocationArtifactId}" | |
version = "${pub.version}" | |
message = "Use classifiers rather than _variant for new publish plugin" | |
} | |
} | |
} | |
// also publish the artifacts in the new way, using one set of coordinates with classifiers | |
project.publishing.publications.create("all", MavenPublication) { | |
from project.components.all | |
alias false | |
} | |
if (!project.property("is-plugin").toBoolean()) { | |
return | |
} | |
String storageUrl = System.getenv('FLUTTER_STORAGE_BASE_URL') ?: "https://storage.googleapis.com" | |
// This is a Flutter plugin project. Plugin projects don't apply the Flutter Gradle plugin, | |
// as a result, add the dependency on the embedding. | |
project.repositories { | |
maven { | |
url "$storageUrl/download.flutter.io" | |
} | |
} | |
String engineVersion = Paths.get(getFlutterRoot(project), "bin", "internal", "engine.version") | |
.toFile().text.trim() | |
project.dependencies { | |
// Add the embedding dependency. | |
compileOnly("io.flutter:flutter_embedding_release:1.0.0-$engineVersion") { | |
// We only need to expose io.flutter.plugin.* | |
// No need for the embedding transitive dependencies. | |
transitive = false | |
} | |
} | |
} | |
// 改动:新增maven相关参数 | |
void configurePlugin(Project project, String mavenUrl, String mavenUser, String mavenPwd) { | |
if (!project.hasProperty("android")) { | |
// A plugin doesn't support the Android platform when this property isn't defined in the plugin. | |
return | |
} | |
configureProject(project, mavenUrl, mavenUser, mavenPwd, getFlutterPluginVersion(project)) | |
} | |
// 改动:flutter插件依赖库版本号(以插件依赖库中pubspec.yaml#version为准) | |
String getFlutterPluginVersion(Project project) { | |
File pubspecFile = project.file("../pubspec.yaml") | |
String versionLine = pubspecFile.readLines().find { line -> | |
line.startsWith("version:") | |
} | |
return versionLine.split(":")[1].trim() | |
} | |
String getFlutterRoot(Project project) { | |
if (!project.hasProperty("flutter-root")) { | |
throw new GradleException("The `-Pflutter-root` flag must be specified.") | |
} | |
return project.property("flutter-root") | |
} | |
void addAarTask(Project project, String mavenUrl, variant) { | |
String variantName = variant.name.capitalize() | |
String taskName = "assembleAar$variantName" | |
project.tasks.create(name: taskName) { | |
// This check is required to be able to configure the archives before `publish` runs. | |
if (!project.gradle.startParameter.taskNames.contains(taskName)) { | |
return | |
} | |
// :flutter模块每次都执行"publish",保持和之前逻辑一致 | |
def isFlutterProject = project.name == "flutter" | |
// :flutter模块依赖的插件校验下是否已上传maven仓库,不存在则执行"publish",避免每次提醒上传错误 | |
if (isFlutterProject || !pluginInMavenRepo(project, mavenUrl, variant)) { | |
// Generate the Maven artifacts. | |
finalizedBy "publish" | |
} | |
} | |
} | |
// 是否本地仓库 | |
static boolean isLocalMavenRepo(String mavenUrl) { | |
return mavenUrl.startsWith("file") | |
} | |
// 校验maven库中是否存在指定插件aar | |
boolean pluginInMavenRepo(Project project, String mavenUrl, variant) { | |
// 获取flutter插件版本号 | |
def pluginVersion = "" | |
try { | |
pluginVersion = getFlutterPluginVersion(project) | |
} catch (Exception ignored) { | |
return false | |
} | |
def url = buildFileUri(project, mavenUrl, pluginVersion, variant.name.toLowerCase(), "aar") | |
if (isLocalMavenRepo(mavenUrl)) { | |
//本地仓库(判断文件是否存在) | |
return new File(url).exists() | |
} else { | |
//远程仓库(curl判断) | |
return curlResponseCode(url) == 200 | |
} | |
} | |
// 构造指定后缀文件仓库地址,如http://nexus.corp.youdao.com/nexus/content/repositories/luna-android-release/com/example/my_flutter/flutter_release/1.0.2/flutter_release-1.0.2.pom | |
String buildFileUri(Project project, String mavenUrl, String version, String buildType, String suffix) { | |
// groupId使用默认,https://docs.gradle.org/current/userguide/publishing_maven.html#sec:identity_values_in_the_generated_pom | |
def groupId = project.group.toString().replace(".", "/") | |
// artifactId | |
def artifactId = "${project.name}_${buildType}" | |
def fileName = "$artifactId-${version}.${suffix}" | |
// 拼接仓库地址 | |
if (!mavenUrl.endsWith("/")) { | |
mavenUrl += "/" | |
} | |
return "$mavenUrl$groupId/$artifactId/$version/$fileName" | |
} | |
// curl获取状态码 | |
int curlResponseCode(String url) { | |
def stdout = new ByteArrayOutputStream() | |
exec { | |
// -I,只取headers | |
// -w %{http_code},状态码 | |
commandLine 'curl', '-I', '-w %{http_code}', url | |
standardOutput = stdout | |
} | |
def response = stdout.toString().trim() | |
// 状态码最后3位 | |
def length = response.length() | |
if (length >= 3) { | |
return response.substring(length - 3, length).toInteger() | |
} | |
return -1 | |
} | |
// maven-publish has to be applied _before_ the project gets evaluated, but some of the code in | |
// `configureProject` requires the project to be evaluated. Apply the maven plugin to all projects, but | |
// only configure it if it matches the conditions in `projectsEvaluated` | |
allprojects { | |
apply plugin: "maven-publish" | |
} | |
projectsEvaluated { | |
// The module project is the `:flutter` subproject. | |
Project moduleProject = rootProject.subprojects.find { it.name == "flutter" } | |
assert moduleProject != null | |
assert moduleProject.hasProperty("maven-url") | |
// maven仓库 | |
String mavenUrl = moduleProject.property("maven-url") | |
String mavenUser = moduleProject.property("maven-user") | |
String mavenPwd = moduleProject.property("maven-pwd") | |
String version = moduleProject.property("buildNumber") | |
configureProject(moduleProject, mavenUrl, mavenUser, mavenPwd, version) | |
// Gets the plugin subprojects. | |
Set<Project> modulePlugins = rootProject.subprojects.findAll { | |
it.name != "flutter" && it.name != "app" | |
} | |
// When a module is built as a Maven artifacts, plugins must also be built this way | |
// because the module POM's file will include a dependency on the plugin Maven artifact. | |
// This is due to the Android Gradle Plugin expecting all library subprojects to be published | |
// as Maven artifacts. | |
modulePlugins.each { pluginProject -> | |
configurePlugin(pluginProject, mavenUrl, mavenUser, mavenPwd) | |
moduleProject.android.libraryVariants.all { variant -> | |
// Configure the `assembleAar<variantName>` task for each plugin's projects and make | |
// the module's equivalent task depend on the plugin's task. | |
String variantName = variant.name.capitalize() | |
moduleProject.tasks.findByPath("assembleAar$variantName") | |
.dependsOn(pluginProject.tasks.findByPath("assembleAar$variantName")) | |
} | |
} | |
// 上传成功输出日志 | |
gradle.buildFinished { buildResult -> | |
if (buildResult.failure == null) { | |
String groupId = moduleProject.group | |
String storageUrl = System.getenv('FLUTTER_STORAGE_BASE_URL') ?: "https://storage.googleapis.com" | |
String repoUrl = mavenUrl | |
if (mavenUrl.startsWith("file://")) { | |
repoUrl = mavenUrl.substring(7) | |
} | |
//pom文件地址 | |
String pomUrl = buildFileUri(moduleProject, mavenUrl, version, "release", "pom") | |
println(""" | |
上传maven仓库成功,通过下述方式引入flutter模块: | |
1. 打开<host>/app/build.gradle | |
2. 配置仓库地址: | |
repositories { | |
maven { | |
url '$repoUrl' | |
} | |
maven { | |
url '$storageUrl/download.flutter.io' | |
} | |
} | |
3. 添加flutter模块依赖: | |
dependencies { | |
implementation '${groupId}:flutter_release:${version}' | |
} | |
4. 查看*.pom文件(用于特殊情况时确认依赖是否正确): | |
${pomUrl} | |
""") | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment