🤗 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> {@Overridepublic 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 testBUILD 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> {@Overridepublic 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 pluginsid 'java-gradle-plugin'
}gradlePlugin {// Define the pluginplugins {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.classesDirsclasspath = sourceSets.functionalTest.runtimeClasspathuseJUnitPlatform()
}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 {@Testvoid pluginRegistersATask() {// Create a test project and apply the pluginProject project = ProjectBuilder.builder().build();project.getPlugins().apply("com.dearxue.greeting");// Verify the resultassertNotNull(project.getTasks().findByName("greeting"));}
}
#功能测试
@Testvoid canRunTask() throws IOException {writeString(getSettingsFile(), "");writeString(getBuildFile(), "plugins {" + " id('com.dearxue.greeting')" + "}");// Run the buildGradleRunner runner = GradleRunner.create();runner.forwardOutput();runner.withPluginClasspath();runner.withArguments("greeting");runner.withProjectDir(projectDir);BuildResult result = runner.build();// Verify the resultassertTrue(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 教程