簡體   English   中英

如何構建和 maven 發布 flutter aar?

[英]How to build and maven-publish a flutter aar?

我正在從事一個 flutter 項目,我正在從中構建 aar。 按照 flutter 提供的說明,我可以將此 aar 集成到我的本地 android 項目中。但我的問題是此 aar 是在本地集成的。 我想 maven-publish 這個 aar 以便團隊成員可以輕松訪問它。

借助年級中的publishing任務,可以從本機庫中發布。 但是對於 flutter 庫,我不確定我們應該做什么。 所以,我需要這方面的幫助。

我試圖弄清楚同樣的事情..我沒有,真的,但這是我走了多遠:

第一次嘗試

這有點混亂,可能會被覆蓋,但我能夠通過將 maven-publish 內容添加到生成的項目 gradle .android/Flutter/build.gradle來發布到本地 Nexus 存儲庫,這似乎負責構建庫。

apply plugin: 'maven-publish'

...

afterEvaluate {
    publishing {
        repositories {
            maven {
                url = "http://10.2.0.210:8081/repository/maven-releases/"
                credentials{
                    username "a"
                    password "b"
                }
            }
        }

        publications {
            // Creates a Maven publication called "release".
            release(MavenPublication) {
                // Applies the component for the release build variant.
                from project.components.release

                // You can then customize attributes of the publication as shown below.
                groupId = 'com.example.myflutmod'
                artifactId = 'something_module'
                version = '0.1.0'
            }
            // Creates a Maven publication called “debug”.
            debug(MavenPublication) {
                // Applies the component for the debug build variant.
                from project.components.debug

                groupId = 'com.example.myflutmod'
                artifactId = 'something_module'
                version = '0.1.0'
            }
        }
    }
}

然后我做了

flutter build aar
./gradlew -b .android/Flutter/build.gradle publish

最后在主 android 應用程序項目中添加相同的 maven 存儲庫配置和一個依賴項,如implementation "com.example.myflutmod:something_module:0.1.0"

它沒有在上傳中包含“插件依賴 aars”(就像我的例子中的 url_launcher),所以應用程序沒有構建。 這可能很容易添加,盡管我沒有考慮過。

另外的選擇

所以相反,我更深入地發現,在修改 flutter 工具時,很容易通過將文件系統存儲庫替換為您的自定義存儲庫來上傳它構建的所有 .aars。 所以在你的 flutter aar_init_script.gradle安裝下的 aar_init_script.gradle 中:

diff --git a/packages/flutter_tools/gradle/aar_init_script.gradle b/packages/flutter_tools/gradle/aar_init_script.gradle
index cc2bbe6f98..242ac61fb0 100644
--- a/packages/flutter_tools/gradle/aar_init_script.gradle
+++ b/packages/flutter_tools/gradle/aar_init_script.gradle
@@ -37,7 +37,10 @@ void configureProject(Project project, String outputDir) {
     project.uploadArchives {
         repositories {
             mavenDeployer {
-                repository(url: "file://${outputDir}/outputs/repo")
+                //repository(url: "file://${outputDir}/outputs/repo")
+                repository(url: "http://10.2.0.210:8081/repository/maven-releases/") {
+                    authentication(userName: "a", password: "b")
+                }
             }
         }
     }

看起來對他們來說添加一些屬性或切換到構建命令以使其使用外部配置的存儲庫相當簡單。 也許將來會有PR。

但現在我更傾向於制作一個腳本,在構建后“手動”上傳file://${outputDir}/outputs/repo中的任何內容。

將 shell 腳本和 gradle 文件添加到您的 flutter 項目中,並在您需要在 maven 中更新 aar 時運行它

上傳.sh

#!/usr/bin/env sh

flutter pub get

#cd ..
#./gradlew build

cd .android
./gradlew build

./gradlew \
  -I=../script/flutter_aar_upload.gradle \
  -Pmaven-url=maven-url \
  -Pmaven-user=username \
  -Pmaven-pwd=password \
  -Pis-plugin=false \
  -PbuildNumber=${pom-1.0.0} \
  -Pt

flutter_aar_upload_maven.gradle

// 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.

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.")
  }

  project.apply plugin: "maven"

  // 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 = version
  if (mavenUrl.startsWith("file:")) {
    //本地路徑時,原邏輯
    project.version = project.version.replace("-SNAPSHOT", "")
  }


  project.android.libraryVariants.all { variant ->
    addAarTask(project, variant)
  }

  project.uploadArchives {
    repositories {
      mavenDeployer {
        repository(url: mavenUrl) {
          if (mavenUser != null) {
            authentication(userName: mavenUser, password: mavenPwd)
          }
        }
        //默認本地路徑:
        //repository(url: "file://${outputDir}/outputs/repo")
      }
    }
  }
  if (!project.property("is-plugin").toBoolean()) {
    return
  }

  if (project.hasProperty('localEngineOut')) {
    // TODO(egarciad): Support local engine.
    // This most likely requires refactoring `flutter.gradle`, so the logic can be reused.
    throw new GradleException(
        "Local engine isn't supported when building the plugins as AAR. " +
            "See: https://github.com/flutter/flutter/issues/40866")
  }

  // 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 "https://storage.googleapis.com/download.flutter.io"
    }
  }
  String engineVersion = flutterEngineVersion()
  project.dependencies {
    // Add the embedding dependency.
    //使用api方式打入aar
    compileOnly("io.flutter:flutter_embedding_release:1.0.0-$engineVersion") {
      //    api("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 = true
    }
  }
}

void configurePlugin(Project project, String outputDir, 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
  }
  //flutter plugin 版本號
  File pubspecFile = project.file("../pubspec.yaml")
  String versionLine = pubspecFile.readLines().find { line->
    line.startsWith("version:")
  }
  def pluginVersion = versionLine.split(":")[1].trim()
  println("configurePlugin: " + project.toString() + " v" + pluginVersion)
  configureProject(project, outputDir, mavenUser, mavenPwd, pluginVersion)
}

void addAarTask(Project project, 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 `uploadArchives` runs.
    if (!project.gradle.startParameter.taskNames.contains(taskName)) {
      return
    }
    project.uploadArchives.repositories.mavenDeployer {
      pom {
        artifactId = "${project.name}_${variant.name.toLowerCase()}"
      }
    }
    overrideDefaultPublishConfig(project, variant)
    // Generate the Maven artifacts.
    finalizedBy "uploadArchives"
  }
}

// This method mimics the logic in AGP when `android.defaultPublishConfig` is set in `build.gradle`:
// https://android.googlesource.com/platform/tools/base/+/studio-master-dev/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/variant/VariantHelper.java
//
// Unfortunately, `android.defaultPublishConfig` cannot be overriden at this point since
// AGP already run this code.
void overrideDefaultPublishConfig(Project project, variant) {
  String variantName = variant.name.capitalize()
  Task bundle = project.tasks.findByName("bundle${variantName}Aar")
  // gradle:3.2.0
  if (bundle == null) {
    bundle = project.tasks.findByName("bundle${variantName}") // gradle:3.1.0
  }
  if (bundle == null) {
    throw new GradleException("Can't generate AAR for variant ${variantName}.")
  }
  // Clear the current archive artifacts since the artifacts are based on `android.defaultPublishConfig`.
  project.configurations["archives"].artifacts.clear()
  // Add the artifact that will be published.
  project.artifacts.add("archives", bundle)

  def scopeMappings = project.uploadArchives.repositories.mavenDeployer.pom.scopeMappings
  // Clear the scope mappings added by AGP since they are based on the current `android.defaultPublishConfig`.
  scopeMappings.mappings.clear()
  // Add the new mappings.
  for (Configuration configuration : flattenConfiguration(variant.runtimeConfiguration)) {
    scopeMappings.addMapping(/* priority = */ 300, configuration, "compile")
  }
}

Set<Configuration> flattenConfiguration(Configuration configuration) {
  Set<Configuration> configs = [configuration]
  for (Configuration extend : configuration.extendsFrom) {
    configs.addAll(flattenConfiguration(extend))
  }
  return configs
}

projectsEvaluated {
  assert rootProject.hasProperty("is-plugin")
  if (rootProject.property("is-plugin").toBoolean()) {
    assert rootProject.hasProperty("maven-url")
    // In plugin projects, the root project is the plugin.
    configureProject(rootProject, rootProject.property("maven-url"),
        rootProject.property("maven-user"), rootProject.property("maven-pwd"),
        project.property("buildNumber")
    )
    return
  }
  // The module project is the `:flutter` subproject.
  Project moduleProject = rootProject.subprojects.find { it.name == "flutter" }

  assert moduleProject != null
  assert moduleProject.hasProperty("maven-url")
  configureProject(moduleProject, moduleProject.property("maven-url"),
      moduleProject.property("maven-user"), moduleProject.property("maven-pwd"),
      moduleProject.property("buildNumber")
  )

  // 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.
  String mavenUrl = moduleProject.property("maven-url")
  String version = moduleProject.property("buildNumber")

  println("Version: $version")
  println("MavenUrl: " + mavenUrl)

  //輸出 配置
  String buildMode = moduleProject.gradle.startParameter
      .taskNames.find { it.startsWith("assembleAar") }.substring(11)
  println("BuildMode: $buildMode")

  println("================================================================================")
  //配置插件
  modulePlugins.each { pluginProject ->
    configurePlugin(pluginProject, mavenUrl,
        moduleProject.property("maven-user"), moduleProject.property("maven-pwd"))
    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"))
    }
  }
  //結束
  println("================================================================================")

  String mUrl = mavenUrl
  if (mavenUrl.startsWith("file://")) {
    mUrl = mavenUrl.substring(7)
  }

  String groupId = moduleProject.group

  println("""
1. 添加maven地址
repositories {
  maven {
      url '${mUrl}'
  }
  maven {
      url 'https://storage.googleapis.com/download.flutter.io'
  }
}
2. 添加依賴
dependencies {
  implementation '${groupId}:flutter_${buildMode.toLowerCase()}:${version}'
}
""")
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM