将生成的第三方许可证复制到资产

Copy generated third party licenses to assets

我想在 Gradle 中自动包含最新生成的第三方许可证。

配置:

代码:

task beforeAssemble(dependsOn: assemble) << {
    downloadLicenses.execute()
    CopyToAssetsTask.execute()
}

task CopyToAssetsTask(type: Copy) {
   description = 'Copies generated Third Party Licenses into assets'
   from('$buildDir/reports/license') {
      include('dependency-license.html')
   }
   into '$buildDir/intermediates/assets/debug/legal'
}

apply plugin: 'license'

downloadLicenses {
    includeProjectDependencies = true
    reportByDependency = true
    reportByLicenseType = true
    dependencyConfiguration = "compile"
}

在命令行中: gradlew clean assembleDebug

生成的 APK 没有像我希望的那样包含生成的文件。我对 Gradle 很陌生,所以也许有一个简单的解释?

尝试将 CopyToAssetsTask 更改为:

task CopyToAssetsTask << {
    copy {
        description = 'Copies generated Third Party Licenses into assets'
        from('$buildDir/reports/license') {
            include('dependency-license.html')
        }
        into '$buildDir/intermediates/assets/debug/legal'
    }
}

因为现在,您的复制是在配置阶段完成的。

首先是一些观察。解决方案在最后:

  • 您仍在按程序思考:告诉 Gradle 什么时候做什么(即您在任务 beforeAssemble 中做什么)。使用任务图:指定任务的依赖关系(某些可能性见下文)。当你需要一个任务的输出时,只要让 Gradle 执行那个任务,Gradle 就会计算出那个任务所依赖的传递任务。它将执行所有这些任务:只执行一次,而且顺序正确。
  • 这个声明:task beforeAssemble(dependsOn: assemble),没有意义。您希望任务在 assemble 之前 运行,但是通过依赖 assemble,您实现了相反的结果:assemble 将在 beforeAssemble 之前 运行。

如何指定依赖项?有多个选项:

  • 使用直接依赖:dependsOn.
  • 引用任务 inputs 中的其他任务。
  • 设置任务的选项,这将自动创建一个依赖项。例如:如果 Copy 任务的 from 属性设置为另一个任务的输出,Copy 任务将自动添加另一个任务作为输入。

这是解决方案。你想要两个实现两件事:

  • 在构建期间(在某个特定点)生成许可证信息。
  • 在存档中包含许可证信息。

将此添加到您的构建脚本中:

android {
    // ...

    // Add the output folder of the license plug-in as
    // a source folder for resources.
    sourceSets {
        main {
            resources {
                srcDir 'build/reports/license'
            }
        }
    }
}

downloadLicenses {
    includeProjectDependencies = true
    reportByDependency = true
    reportByLicenseType = true
    dependencyConfiguration = "compile"
}

// Add a dependency after the project has been evaluated, because
// the Android plug-in does not add tasks "generate*Resources" to
// the project immediately.
project.afterEvaluate {
    // Download the licenses when (actually: just before) the
    // resources are generated (for both the "debug" and the
    // "release" build types).

    // If you add/change build types, you have to add to/change
    // these task names.
    generateDebugResources.dependsOn tasks['downloadLicenses']
    generateReleaseResources.dependsOn tasks['downloadLicenses']
}

这个解决方案对我有用,是 Johan Stuyts 发布的答案的略微修改版本。

但有一个限制:生成的报告最终将位于根资产文件夹中,而不是预期的子文件夹中 "legal"。

   buildscript {
       // ...
       dependencies {
          // ...
          classpath 'nl.javadude.gradle.plugins:license-gradle-plugin:0.11.0'
      }
   }

   android {
   // ...

   // Add the output folder of the license plug-in as
   // a source folder for assets.
      sourceSets {
          main {
              // ...
              assets.srcDirs = ['src/main/assets', 'build/reports/license']
          }
      }
   }

   downloadLicenses {
      includeProjectDependencies = true

      reportByDependency = true
      reportByLicenseType = false

      report.html.enabled = true
      report.xml.enabled = false

      dependencyConfiguration = "compile"
   }

   // Add a dependency after the project has been evaluated, because
   // the Android plug-in does not add tasks "merge*Assets" to
   // the project immediately.
   project.afterEvaluate {
      // Download the licenses when (actually: just before) the
      // assets are merged (for both the "debug" and the
      // "release" build types).

      // If you add/change build types, you have to add to/change
      // these task names.
      mergeDebugAssets.dependsOn project.tasks.getByName('downloadLicenses')
      mergeReleaseAssets.dependsOn project.tasks.getByName('downloadLicenses')
   }

在我的项目(gradle 3.4.1)中,它在 Android "Module:app" gradle 文件中是这样工作的:

plugins {
   id "com.github.hierynomus.license" version "0.14.0"
}

license {
   include "**/*.java"
   strictCheck = false
   ignoreFailures = true
   skipExistingHeaders = true
}

downloadLicenses {
   includeProjectDependencies = true
   reportByDependency = true
   reportByLicenseType = false
   dependencyConfiguration = "compile"
   licenses = [
        (group('com.android.support')) : license('Apache License, Version 2.0', 'http://www.apache.org/licenses/LICENSE-2.0'),
        (group('com.android.support.constraint')) : license('Apache License, Version 2.0', 'http://www.apache.org/licenses/LICENSE-2.0'),
        (group('com.google.firebase')) : license('Apache License, Version 2.0', 'http://www.apache.org/licenses/LICENSE-2.0'),
        (group('com.google.android')) : license('Apache License, Version 2.0', 'http://www.apache.org/licenses/LICENSE-2.0'),
        (group('com.google.android.gms')) : license('Apache License, Version 2.0', 'http://www.apache.org/licenses/LICENSE-2.0')
]
}

apply plugin: 'com.android.application'

android {
   compileSdkVersion 25
   buildToolsVersion "25.0.2"

   defaultConfig {
    ...
   }

   sourceSets {
        main {
            assets.srcDirs = ['src/main/assets', 'build/licenses/']
        }
   }

   buildTypes {
    ...
   }
}

dependencies {
   compile 'com.android.support:appcompat-v7:25.3.1'
   compile 'com.android.support:multidex:1.0.1'
   compile 'com.android.support:support-v4:25.3.1'
   compile 'com.android.support:design:25.3.1'
   ...
}

task copyLicenseReport(type: Copy) {
   from('build/reports/license') {
    include '**/*.html'
    include '**/*.xml'
   }
   into 'build/licenses/thirdPartyLicenses'
}

project.afterEvaluate {
   copyLicenseReport.dependsOn project.tasks.getByName('downloadLicenses')
   preBuild.dependsOn copyLicenseReport
}

apply plugin: 'com.google.gms.google-services'