Licensee - 用于验证依赖关系图许可证符合期望的Gradle插件

398 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

Licensee 📜👀

是一个Gradle插件, 用于验证依赖图谱的许可证, 使其匹配自个的期待. 如果许可证不匹配的话, 你的构建将失败!

Introduction

假如你的闭源产品依赖于Apache 2许可的部件.

implementation 'com.example:example:1.0'

开发者发布了新的版本, 而你忠实地进行升级.

-implementation 'com.example:example:1.0'
+implementation 'com.example:example:1.1'

新版本有基于GPL许可的可传递依赖, 而它并不兼容于你的闭源产品. 你注意到了吗?

你可能在dependency tree diff已经看过新的依赖, 但你检查过它的许可证了吗?

-+--- com.example:example:1.0
++--- com.example:example:1.1
+     --- com.other:other:2.5

应用了Licensee, 你将不必检查了.

首先, 配置它允许Apache 2许可的依赖.

licensee {
  allow('Apache-2.0')
}

现在尝试升级更新将使构建失败.

> Task :app:licensee FAILED
com.other:other:2.5
 - SPDX identifier 'GPL-3.0-or-later' is NOT allowed

危机避免了!

用法

在你想要检查依赖图谱的模块中, 添加依赖并应用插件.

buildscript {
  repository {
    mavenCental()
  }
  dependencies {
    classpath 'app.cash.licensee:licensee-gradle-plugin:1.5.0'
  }
}

apply plugin: 'app.cash.licensee'

开发版本的快照在Sonatype的快照仓库可以查看.

插件的任务将遍历完整的可传递依赖图谱, 所以它只需要用于"叶子"模块(这些模块没有下游依赖), 例如应用和服务模块. 然而, 如果你在构建包工程的话, 请把它应用到每一个包模块.

Licensee要求支持的语言/平台插件也应用到相同的模块:

  • java-library
  • java
  • com.android.application
  • com.android.library
  • org.jetbrains.kotlin.jvm
  • org.jetbrains.kotlin.js
  • org.jetbrains.kotlin.multiplatform

通过licensee DSL配置允许的许可证列表:

licensee {
  allow('Apache-2.0')
}

想要更多的配置选项, 请查看下面的[配置区域].

licensee任务将添加进你的构建, 并且自动地作为check任务的依赖. Android和Kotlin多平台模块会有该任务的特定版本变体(比如licenseeDebuglicenseeJs), licensee任务只不过是将它们聚合在一起.

除了会在检测到不允许的许可证时将构建失败之外, 插件也允许生成一些报告文件.

  1. artifacts.json

    JSON文件, 包含依赖图谱中每一个部件的许可证信息.

  2. validation.txt

    文本文件报告, 包含了每一个部件以及它的许可证是否允许.

这些文件生成在<buildDir>/reports/licensee目录下, 或者对于Android 模块而言, 在<buildDir>/reports/licensee/<variant name>/目录下.

Configuration

下面的函数在licenseeDSL和app.cash.licensee.LicenseeExtension类型上面可用.

allow

允许部件拥有匹配SPDX标识的许可证.

licensee {
  allow('Apache-2.0')
  allow('MIT')
}

可支持标识的完整列表可在spdx.org/licenses/查看.

allowUrl

允许部件拥有匹配URL的未知(非SPDX)许可证.

licensee {
  allowUrl('https://example.com/license.html')
}

allowDependency

通过特定的groupId, artifactId和version来允许某个依赖的许可证. 这对于不包含许可照数据或者拥有非法/不正确的许可证数据的构件非常有用.

licensee {
  allowDependency('com.example', 'example', '1.0')
}

解释字符串能够应用来以文档的方式解释, 为什么尽管缺失或者非法许可证数据, 依赖依然被允许.

licensee {
  allowDependency('com.jetbrains', 'annotations', '16.0.1') {
    because 'Apache-2.0, but typo in license URL fixed in newer versions'
  }
}

解释字符串将包含在验证报告中.

ignoreDependencies

在依赖图谱解析期间, 忽略某个或者某组依赖. 此方法针对的部件将不会被分析许可证信息, 也不会出现在任何报告文件中.

这个函数能够用来忽略内部闭源库和购买了许可证的商业库.

也有一些覆盖方法, 接收了groupId或者groupId:artifactId对.

licensee {
  ignoreDependencies('com.mycompany.internal')
  ignoreDependencies('com.mycompany.utils', 'utils')
}

可以提供解释字符串以文档的形式解释为什么依赖被忽略.

licensee {
  ignoreDependencies('com.example.sdk', 'sdk') {
    because "commercial SDK"
  }
}

忽略可以被标记为可传递, 这将忽略完整的依赖树分支. 这将在不考虑部件坐标或者许可证信息的前提下忽略目标部件的依赖. 因为它是非常危险的, 所以解释字符串是需要的.

licensee {
  ignoreDependencies('com.other.sdk', 'sdk') {
    transitive = true
    because "commercial SDK"
  }
}

开发

更新内嵌许可证信息

运行updateLicenses任务以在src/main/resources/目录下更新内嵌SPDX许可证文件.