如何生成、编译、jar 和依赖一个 gradle 模块
How to generate, compile, jar, and depend on a gradle module
我有一个 Java Gradle 项目,它使用指定的 API OpenAPI。我使用了 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 与生成的 build 完全分开API。此类构建之间的唯一联系应该是依赖声明。这意味着,您必须手动确保首先构建 API 生成项目,然后才构建依赖项目。
默认情况下,这意味着在构建依赖项目之前还要发布 API 模块。此默认设置的替代方法确实是复合构建——例如,允许您在发布之前先在本地测试新生成的 API。但是,在 creating/running 复合构建之前,每次打开 API 文档更改时,您都必须手动 运行 生成 API 生成构建。
例子
假设您有项目 A,这取决于生成的 API。它的 Gradle 构建将包含如下内容:
dependencies {
implementation 'com.example:api:1.0'
}
在 运行ning A 的构建之前,您首先必须 运行
./gradlew openApiGenerate
来自您的 api
项目。
./gradlew publish
来自 api/build/generated/
目录。
然后 A 的构建可以从发布存储库中获取已发布的依赖项。
或者,您可以在本地删除第 2 步,然后 运行 A 的构建具有额外的 Gradle CLI 选项:
./gradlew --include-build $path_to/api/build/generated/ …
减少体力劳动的想法
我对此思考了很多,但没有想出任何完整的解决方案——因此我上面的建议并不完美。让我仍然总结一下我对 可以如何 工作的想法。
- 您将有一个 Gradle 生成生成 API – 类似于您的
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
相比,它的主要优势在于 [my] IDE 也会 'link' 这一切。
生成 API 库:
./gradlew --project-dir api/ openApiGenerate
Build/run主项目:
./gradlew build
./gradlew run
我有一个 Java Gradle 项目,它使用指定的 API OpenAPI。我使用了 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 与生成的 build 完全分开API。此类构建之间的唯一联系应该是依赖声明。这意味着,您必须手动确保首先构建 API 生成项目,然后才构建依赖项目。
默认情况下,这意味着在构建依赖项目之前还要发布 API 模块。此默认设置的替代方法确实是复合构建——例如,允许您在发布之前先在本地测试新生成的 API。但是,在 creating/running 复合构建之前,每次打开 API 文档更改时,您都必须手动 运行 生成 API 生成构建。
例子
假设您有项目 A,这取决于生成的 API。它的 Gradle 构建将包含如下内容:
dependencies {
implementation 'com.example:api:1.0'
}
在 运行ning A 的构建之前,您首先必须 运行
./gradlew openApiGenerate
来自您的api
项目。./gradlew publish
来自api/build/generated/
目录。
然后 A 的构建可以从发布存储库中获取已发布的依赖项。
或者,您可以在本地删除第 2 步,然后 运行 A 的构建具有额外的 Gradle CLI 选项:
./gradlew --include-build $path_to/api/build/generated/ …
减少体力劳动的想法
我对此思考了很多,但没有想出任何完整的解决方案——因此我上面的建议并不完美。让我仍然总结一下我对 可以如何 工作的想法。
- 您将有一个 Gradle 生成生成 API – 类似于您的
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
相比,它的主要优势在于 [my] IDE 也会 'link' 这一切。生成 API 库:
./gradlew --project-dir api/ openApiGenerate
Build/run主项目:
./gradlew build ./gradlew run