Spice - Kotlin依赖图谱分析库 - 1

110 阅读4分钟

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

Spice - 软件项目元数据系统

“He who controls the spice, controls the universe”  - Frank Herbert

概览

Spice寻求以某种方式提供持续性构建元数据, 这种方式某种程序上是工具中立的(gradle, maven, bazel), 但可以为各种用例提供高性能, 精简的构建图谱表示,包括(但不限于):

  • 构建系统迁移,
  • 多构建系统场景,
  • 大型代码库的一致性,
  • 声明式构建元数据,
  • 脱离特定构建系统的快速图形感知工具

Spice - 设计和上下文

用于跨构建系统定义的一致性构建元数据

注意: 这是Square的内部设计文件, 所以它可能读起来有些奇怪. 删除了许多引用内部项目的内容, 或仅与内部广场项目相关的特定赞成/反对分析. 它是一个工作文档, 不一定要更新, 但提供它是为了给项目添加一些上下文.

概览

构建系统高可配置, 具有不同的自由度, 可能是图灵完成, 并对其条件做出不同的假设. 这使得在构建系统之间进行转换变得困难和脆弱.

构建系统之间的迁移经常受到大规模的搅动, 需要大量标准化的各种假设, 等等. 此外, 有能力通过构建语言完成繁重的逻辑工作来维护对大型代码库的控制, 意味着构建系统的最坏情况行为通常是开发人员在短期内摆脱困境的最简单途径(比如向gradle的buildSrc添加越来越多的逻辑). 此外, 一些构建系统有非常鲁棒的图谱管理和查询工具, 但其它的却没有. 在所有的这些情况下, 除了选中的构建工具之外, 拥有构建元数据的稳定实现, 将能够允许更容易的迁移, 对大型代码库的构建图谱的控制, 甚至开启在一个选中构建系统中不能轻易(或者高效)访问的特性.

一些声明式的元数据系统已经存在了, 例如Cocoapods或者Maven, 但是这些系统都拥有自己的挑战.

Spice想要成为一个稳定的声明式元数据, 封装所有必要的东西, 来从一个稳定源中生成一个gradle或者bazel (或者任何其它的)构建, 也想成为构建元数据的真源. 从这个元数据中, 可以为开发者生成构建(例如 gradle或者bazel), 也可以为CI(bazel), 为其它感知图谱的工具(linting, 结构化验证, 未受影响的试验避免, 等等), 生成构建.

上下文

现代软件经常是大型的, 复杂的, 模块化的. 模块化和模块之间的关系通常封装在所选构建系统的配置语言之中. 通常, 配置语言中混合了构建步骤指令, 打包/发布指令, 使用的构建扩展细节和大量的元数据. 它导致了构建系统成为宇宙的核心, 在某种方式上, 这进一步导致了所有的用例依赖于构建系统.

在一些场景下, 配置处理的很好, 但在其它的场景下, 它却导致了膨胀和构建降级. 构建工具的DSL越强大, 放入的使用越多, 构建周期就会扩展, 导致缓慢的工具执行, 即使只是为其它工具消费简单的元数据, 或者导致强制这些工具深入构建系统层次. 这些复杂性可以被约束, 但大多数构建系统并没有方法这么做, 或者使用懒执行或者缓存分层的解决方案.

作者们认为软件的核心 - 正在构建什么以及它与正在构建的其他事物的关系 - 最好能够用声明式元数据表达出来, 声明式元数据要严格正确, 准确, 并且清除与构建语言的纠缠. 有了这样的声明式元数据系统, 任何构建工具, 或者任何其它能够从高速访问构建图谱中受益的工具, 能够被优化, 清除污垢, 并且受限于分类(非特殊)用途. 反过来, 这能够被控制达到更清晰的构建图谱(在任务构建工具里面), 命题化CI系统, 更快的分析, 并且能够允许为很多任务消除不必要的计算和I/O. 对于有日益增长的大型开发的组织, 这对于管理软件和工具技术债务以及稳定的基础设施至关重要.

要求

  1. 对开发人员工作流具有最小的侵入性
  2. 构建系统生成应该小于15s
  3. 元数据将强制很少的意见, 但有的话将明确执行它们
  4. 必须表达足够的信息, 以便在Gradle和Bazel中生成构建图谱
  5. 简单明了地理解构建文件(notwithstanding sheer length)
    1. 应用最小惊喜原则.
    2. 尽可能简单, 直到不能更简单.