🤗 ApiHug × {Postman|Swagger|Api...} = 快↑ 准√ 省↓
- GitHub - apihug/apihug.com: All abou the Apihug
- apihug.com: 有爱,有温度,有质量,有信任
- ApiHug - API design Copilot - IntelliJ IDEs Plugin | Marketplace
ApiHug 整个工具链基于 Gradle, 使用 ApiHug 准备工作最先需要学习的就是 gradle. 工欲善其事,必先利其器
如何去扩展 gradle 自带的功能, gradle 是高度定制化, 我们日常很多功能也是社区插件提供的。 Developing Custom Gradle Pluginsopen in new window
#插件位置
#Build Script
位于 buildSrc
下的插件功能, 只能对本项目可见, 不能跨项目分享。
Gradle 会自动检查 来自buildSrc/src/main/java
的扩展, 如果有扩展, gradle 自动包含里面的插件。
#独立插件
完全独立的项目, 就像独立的第三方 Lib 一样, 可以在不同项目中共享重用。
#Build Script - 实现
两个比较完备的例子: Spring framework 内置插件open in new window & Spring boot 内置插件open in new window
定义插件:
- 继承
org.gradle.api.Plugin
- 扩展
org.gradle.api.Project
import org.gradle.api.Plugin;
import org.gradle.api.Project;
public class GreetingPlugin implements Plugin<Project> {
@Override
public void apply(Project project) {
project.task("hello")
.doLast(task -> System.out.println("Hello Gradle!"));
}
}
buildSrc/build.gradle
内容:
plugins {
id 'java-gradle-plugin'
}
gradlePlugin {
plugins {
compileConventionsPlugin {
id = "com.dearxue.GreetingPlugin"
implementationClass = "com.dearxue.GreetingPlugin"
}
}
}
在 app 项目中引入:
plugins {
// Apply the application plugin to add support for building a CLI application in Java.
id 'application'
id 'com.dearxue.GreetingPlugin'
}
运行命令:
>gradlew.bat clean build -x test
BUILD SUCCESSFUL in 3s
12 actionable tasks: 10 executed, 2 up-to-date
.......gradle-advanced>gradlew.bat app:hello
> Task :app:hello
Hello Gradle!
#插件配置
扩展配置 GreetingPluginExtension
public class GreetingPluginExtension {
private String greeter = "Baeldung";
private String message = "Message from the plugin!"
// standard getters and setters
}
改进后的类 GreetingPlugin
public class GreetingPlugin implements Plugin<Project> {
@Override
public void apply(Project project) {
GreetingPluginExtension extension = project.getExtensions()
.create("greeting", GreetingPluginExtension.class);
project.task("hello")
.doLast(task -> {
System.out.println(
"Hello, " + extension.getGreeter());
System.out.println(
"I have a message for You: " + extension.getMessage());
});
}
}
修改后的 app/build.gradle
:
greeting {
greeter = "Stranger"
message = "Message from the build script"
}
运行效果:
>gradlew.bat app:hello
> Task :app:hello
Hello, Stranger
I have a message for You: Message from the build script
#独立插件 - 实现
最好的参照:
- Spring depedency 插件open in new window
- Spring boot 插件open in new window
例子参考例子项目中的 plugin 子项目, 包含相关的单元测试:
plugins {
// Apply the Java Gradle plugin development plugin to add support for developing Gradle plugins
id 'java-gradle-plugin'
}
gradlePlugin {
// Define the plugin
plugins {
greeting {
id = 'com.dearxue.greeting'
implementationClass = 'com.dearxue.PppPlugin'
}
}
}
configurations.functionalTestImplementation.extendsFrom(configurations.testImplementation)
// Add a task to run the functional tests
tasks.register('functionalTest', Test) {
testClassesDirs = sourceSets.functionalTest.output.classesDirs
classpath = sourceSets.functionalTest.runtimeClasspath
useJUnitPlatform()
}
gradlePlugin.testSourceSets(sourceSets.functionalTest)
tasks.named('check') {
// Run the functional tests as part of `check`
dependsOn(tasks.functionalTest)
}
tasks.named('test') {
// Use JUnit Jupiter for unit tests.
useJUnitPlatform()
}
#单元测试
class PppPluginTest {
@Test
void pluginRegistersATask() {
// Create a test project and apply the plugin
Project project = ProjectBuilder.builder().build();
project.getPlugins().apply("com.dearxue.greeting");
// Verify the result
assertNotNull(project.getTasks().findByName("greeting"));
}
}
#功能测试
@Test
void canRunTask() throws IOException {
writeString(getSettingsFile(), "");
writeString(getBuildFile(), "plugins {" + " id('com.dearxue.greeting')" + "}");
// Run the build
GradleRunner runner = GradleRunner.create();
runner.forwardOutput();
runner.withPluginClasspath();
runner.withArguments("greeting");
runner.withProjectDir(projectDir);
BuildResult result = runner.build();
// Verify the result
assertTrue(result.getOutput().contains("Hello from plugin 'com.dearxue.greeting'"));
}
#发布
ID 命名规范:
- They can contain only alphanumeric characters, “.” and “-“
- The id has to have at least one “.” separating the domain name from the plugin name
- Namespaces org.gradle and com.gradleware are restricted
- An id cannot start or end with “.”
- No two or more consecutive “.” characters are allowed
参考下 spring depedency management:
gradlePlugin {
plugins {
dependencyManagement {
displayName = 'Dependency management plugin'
description = 'A Gradle plugin that provides Maven-like dependency management functionality'
id = 'io.spring.dependency-management'
implementationClass = 'io.spring.gradle.dependencymanagement.DependencyManagementPlugin'
}
}
}
#总结
项目地址 gradle-advanced plugin 教程