如何解决如何生成、编译、jar 和依赖一个 gradle 模块 示例
我有一个使用 OpenAPI 指定 API 的 Java Gradle 项目。我使用了 org.openapi.generator
插件,它可以生成源代码和完整的 Gradle 模块。
我希望有一种方法可以定义生成、编译、jar 步骤,以便我可以让其他模块依赖于生成的模块。
即
# api/build.gradle:
plugins {
id 'java'
id "org.openapi.generator" version "5.0.0"
}
repositories {
mavenCentral()
}
dependencies {
testImplementation group: 'junit',name: 'junit',version: '4.12'
}
compileJava.dependsOn "openApiGenerate"
openApiGenerate {
generatorName = "java"
inputSpec = "$projectDir/src/main/openapi/spec.yaml".toString()
outputDir = "$buildDir/generated"
apiPackage = "com.example.api"
invokerPackage = "com.example.api.invoker"
modelPackage = "com.example.api.model"
configOptions = [
dateLibrary: "java8",library : "native"
]
groupId = "com.example"
id = "api"
}
gradlew api:openApiGenerate
生成(忽略了无关文件):
api/build/generated/
├── build.gradle
├── pom.xml
├── settings.gradle
└── src
├── main/java/...
└── test/java/...
有什么方法可以委托、包含或依赖来自项目中其他模块的这个生成的模块?生成的模块具有可靠的 group:artifact:version
坐标。
即我希望能够在项目的其他地方指定 com.example:api:1.0
。
我已经通读了 https://docs.gradle.org/current/userguide/composite_builds.html,因为它似乎接近我的预期,但我是 Gradle 的新手,它有点深入。
我尝试覆盖 api/build.gradle
中的主要和测试源集,但我不喜欢必须从 api/build/generated/build.gradle
复制和粘贴依赖项。
我发现 https://docs.gradle.org/current/userguide/declaring_dependencies.html#sec:dependency-types 包含一个诱人的示例,但由于它是纯源依赖项而失败了。
dependencies {
implementation files("$buildDir/classes") {
builtBy 'compile'
}
}
我查看了这个示例,但如何依赖尚不存在的项目 (api/build/generated/
)?
dependencies {
implementation project(':shared')
}
解决方法
好问题!我没有完美的答案,但希望以下内容仍然会有所帮助。
建议的方法
我会将依赖于生成的 API 的模块的 builds 与生成 API 的 build 完全分开。这种构建之间的唯一联系应该是依赖声明。这意味着,您必须手动确保先构建 API 生成项目,然后才构建依赖项目。
默认情况下,这意味着还要在构建依赖项目之前发布 API 模块。这种默认设置的替代方案确实是复合构建——例如,允许您在发布之前先在本地测试新生成的 API。但是,在创建/运行复合构建之前,您必须在每次 OpenAPI 文档更改时手动运行 API 生成构建。
示例
假设您有项目 A,具体取决于生成的 API。它的 Gradle 构建将包含如下内容:
dependencies {
implementation 'com.example:api:1.0'
}
在运行 A 的构建之前,您首先必须运行
-
./gradlew openApiGenerate
来自您的api
项目。 -
./gradlew publish
来自api/build/generated/
目录。
然后 A 的构建可以从发布存储库中获取已发布的依赖项。
或者,您可以在本地删除第 2 步并使用额外的 Gradle CLI 选项运行 A 的构建:
./gradlew --include-build $path_to/api/build/generated/ …
减少手工工作的想法
我对此考虑了很多,但没有想出任何完整的解决方案——因此我上面的建议并不完美。让我仍然总结一下我对如何如何工作的想法。
- 您将拥有一个生成 API 的 Gradle 构建版本 - 类似于您的
api
项目。该构建也将提交给您的 VCS。 - 该构建会发布生成的 API,即使它本身不会生成它。相反,它会以某种方式委托给
openApiGenerate
任务生成的 Gradle 构建。委托必须通过GradleBuild
task 进行。
关键在于:所有有关依赖项和已发布工件的信息都必须通过 Gradle CLI 有效地检索。我怀疑目前是否可行。 - 依赖 API 的项目然后可以在复合构建中包含类似
api
的 Gradle 项目,而无需上述方法中的手动麻烦。
用我实际使用的内容扩展@Chriki 的回答:
-
使用空的
api/
文件将api/settings.gradle
定义为自己的项目。这告诉 gradle 它是一个独立的项目。
-
定义 api 模块:
# api/build.gradle plugins { id 'java' id "org.openapi.generator" version "5.0.0" } repositories { mavenCentral() } openApiGenerate { generatorName = "java" inputSpec = "$projectDir/src/main/openapi/specification.yaml" outputDir = "$buildDir/generated" apiPackage = "com.example.api" invokerPackage = "com.example.api.invoker" modelPackage = "com.example.api.model" configOptions = [ dateLibrary: "java8",library : "native" ] groupId = "com.example" id = "api" version = "1.0.0" }
注意
group
和id
(和version
)明确定义了它的 maven 坐标。 -
包含带有替换的构建,以便依赖项可以仅使用其 maven 坐标:
# settings.gradle includeBuild('api/build/generated') { dependencySubstitution { substitute module('com.example:api') with project(':') } }
...以及在其他一些模块中:
# app/build.gradle dependencies { implementation group: 'com.example',name: 'api' }
与
./gradlew --include-build api/build/generated
相比,它的主要优点是 [我的] IDE 也会将其全部“链接”起来。 -
生成 API 库:
./gradlew --project-dir api/ openApiGenerate
-
构建/运行主项目:
./gradlew build ./gradlew run
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。