没有复合构建的生活
让我们假设您刚刚开始在一个项目保存在单个存储库中的公司工作。每个项目都有一个单独的构建,它们之间唯一的关系是彼此依赖,因为它符合他们的需求。有些项目的依赖性比其他项目更多,有些项目甚至可能与其他项目没有依赖关系。
项目数量很重要; 当它很低时,你可以说它们都可以放在一个伞形项目下,就像用Maven及其反应堆功能完成的那样。Gradle有类似的功能; 除了,在不触发所有其他项目的情况下,更容易定位特定构建。在某种程度上,你可以说Gradle的反应堆更智能,并选择要执行的目标。
但是当一个项目数量超过十几个时,会发生什么呢,比如几百个呢?即使使用更智能的反应堆,Gradle也必须阅读所有项目的配置,然后解决相应的目标。这肯定会花费你日常工作的宝贵时间,这是一个很大的禁忌。
解决方案是将每个项目分解为单独的构建。反应堆功能已经不复存在; 因此,我们不必为阅读和配置所有项目付出代价,以后再丢弃大部分项目。但是,现在,当依赖项可能引入了错误或二进制不兼容时,我们失去了做出反应的机会,这是在monorepo中组织代码的原因之一。
现在,我们必须遵循旧的和尝试过的工作流程:
对依赖项目进行更改。
构建工件并将工件发布到存储库。大多数人依赖快照工件。
确保依赖项目使用新发布的工件/快照。
编译并运行测试以确定代码是否再次运行。
冲洗并重复直至其工作。
这种方法的问题在于我们浪费时间发布中间工件,并且有时我们会忘记发布快照发布并在调试会话中花费数小时,直到我们意识到二进制文件不正确为止。
复合材料构建到救援
现在让我们看看Composite Builds如何解决我们自己遇到的问题。我们首先看一下以下项目及它们之间的依赖关系。
PROJECT1
Project2 < - 依赖 - Project1
Project3 < - 依赖 - Project2
这个小的依赖图告诉我们,对Project1所做的任何更改都会影响Project2,因此也会影响到Project3。这是因为对Project2的更改也会影响Project3。这个monorepo的目录结构如下所示:
├ ─ ─ PROJECT1
展示│ └ ─ ─ 构建。gradle这个
├ ─ ─ 项目2
展示│ └ ─ ─ 构建。gradle这个
└ ─ ─ 项目3
└ ─ ─ 构建。gradle这个
在这里,我们可以看到三个项目及其各自的构建文件。每个项目都有自己的发布生命周期和版本,我们可以在他们的构建文件中观察到
PROJECT1 /的build.gradle
apply plugin: 'java'
group = 'com.acme'
version = '1.0.0'
项目2 /的build.gradle
apply plugin:'java'
group = 'com.acme'
version = '2.3.0'
依赖 {
编译 'com.acme:project1:1.0.0'
项目3 /的build.gradle
apply plugin:'java'
group = 'com.acme'
version = '1.2.0'
依赖 {
编译 'com.acme:project2:2.3.0'
}
激活Composite Builds功能需要在名为settings.gradle的文件中配置项目之间的链接。项目2和3需要此文件; 因此,我们的存储库看起来像这样:
。
├── 项目1
展示│ └── 构建。gradle这个
├── 项目2
展示│ ├── 构建。gradle这个
展示│ └── 设置。gradle这个
└── 项目3
├── 建造。gradle这个
└── 设置。gradle这个
接下来,我们写下项目之间的链接,如下所示:
项目2 / settings.gradle
includeBuild ” ../project1'
项目3 / settings.gradle
includeBuild ” ../project2'
大。有了这个设置,我们现在可以通过发出以下命令来构建Project3:
$ cd project3
$ pwd
的/ tmp /项目3
$ gradle课程
>任务:proce***esources
>任务:project2:proce***esources
>任务:project1:compileJava
>任务:project1:proce***esources
>任务:project1:类
>任务:project1:jar
>任务:project2:compileJava
>任务:project2:类
>任务:project2:jar
>任务:compileJava
>任务:课程
您可以理解,project1和project2都是构建的。在project1中进行更改并在project3上触发构建,将再次按预期构建所有三个项目。现在,想象一下将这个monorepo增长到几十个或几百个项目,你很快就会意识到没有必要拥有快照版本,如果有的话。Gradle还有其他功能,例如输入/输出的任务缓存,这使得构建更快。同样,最近公布的构建缓存功能通过“交换”由CI场中其他节点计算的输出来加速构建。
©著作权归作者所有:来自51CTO博客作者萤火的萤的原创作品,如需转载,请注明出处,否则将追究法律责任