Gradle 实战 - SourceSet 配置 -ApiHug准备-工具篇-011

2024-04-14 00:44

本文主要是介绍Gradle 实战 - SourceSet 配置 -ApiHug准备-工具篇-011,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  🤗 ApiHug × {Postman|Swagger|Api...} = 快↑ 准√ 省↓

  1. GitHub - apihug/apihug.com: All abou the Apihug   
  2. apihug.com: 有爱,有温度,有质量,有信任
  3. ApiHug - API design Copilot - IntelliJ IDEs Plugin | Marketplace

ApiHug 整个工具链基于 Gradle, 使用 ApiHug 准备工作最先需要学习的就是 gradle. 工欲善其事,必先利其器

多 Sourceset 管理 也是 ApiHug 喜欢使用的, 我们称之为 干湿分离, 不同代码放置不同目录

SourceSet 给我们在 gradle 项目中组织我们代码结构的自由; Gradle SourceSet 定义open in new window & org.gradle.api.tasks.SourceSet 支持的APIopen in new window。

SourceSet到底是什么,官网中像下面这样解释的,SourceSet包括源文件及位置、它们的依赖、编译输出的位置这三个概念,SourceSet可以把不同文件目录里的文件按照逻辑关系组织起来。

  1. the source files and where they’re located
  2. the compilation classpath, including any required dependencies (via Gradle configurations)
  3. where the compiled class files are placed

Source sets and Java compilation

#项目结构

一般的项目结构可能看起来:

source-sets ├── src │    ├── main │    │    └── java │    │        ├── SourceSetsMain.java│    │        └── SourceSetsObject.java│    └── test │         └── java │             └── SourceSetsTest.java└── build.gradle 

build.gradle 内容:


apply plugin : "java"
description = "Source Sets example"
test {testLogging {events "passed", "skipped", "failed"}
}
dependencies {   implementation('org.apache.httpcomponents:httpclient:4.5.12')testImplementation('junit:junit:4.12')
}

java plugin 默认 src/main/java & src/test/java 为源码目录, 手动打印下:

task printSourceSetInformation(){doLast{sourceSets.each { srcSet ->println "["+srcSet.name+"]"print "-->Source directories: "+srcSet.allJava.srcDirs+"\n"print "-->Output directories: "+srcSet.output.classesDirs.files+"\n"println ""}}
}

SourceSet 文档open in new window, 有非常多的字段,这里不一一枚举。

你可以看到输出如下:

 ./gradlew printSourceSetInformation> Task :source-sets:printSourceSetInformation
[main]
-->Source directories: [.../source-sets/src/main/java]
-->Output directories: [.../source-sets/build/classes/java/main][test]
-->Source directories: [.../source-sets/src/test/java]
-->Output directories: [.../source-sets/build/classes/java/test]

默认两个 sourcesets 一个是 main 另外一个是 test 。


mainContains the production source code of the project, which is compiled and assembled into a JAR.testContains your test source code, which is compiled and executed using JUnit or TestNG. These are typically unit tests, but you can include any test in this source set as long as they all share the same compilation and runtime classpaths

#其他默认配置

java 插件同样生成一些默认的 gradle 配置, 基本遵循这样的规则 <sourceSetName><configurationName>, 我们熟悉的 main & test

比如我们配置的 build.gradle:

dependencies { implementation('org.apache.httpcomponents:httpclient:4.5.12') testImplementation('junit:junit:4.12') 
}

注意 implementation 而不是 mainimplementation, gradle 为 main 做了例外。

默认 testImplementation 继承 implementation, 继承他所有的 dependencies & outputs

打印验证:


task printSourceSetInformation(){doLast{sourceSets.each { srcSet ->println "["+srcSet.name+"]"print "-->Source directories: "+srcSet.allJava.srcDirs+"\n"print "-->Output directories: "+srcSet.output.classesDirs.files+"\n"print "-->Compile classpath:\n"srcSet.compileClasspath.files.each { print "  "+it.path+"\n"}println ""}}
}

输出如下:


[main]
// same output as before
-->Compile classpath:.../httpclient-4.5.12.jar.../httpcore-4.4.13.jar.../commons-logging-1.2.jar.../commons-codec-1.11.jar[test]
// same output as before
-->Compile classpath:.../source-sets/build/classes/java/main.../source-sets/build/resources/main.../httpclient-4.5.12.jar.../junit-4.12.jar.../httpcore-4.4.13.jar.../commons-logging-1.2.jar.../commons-codec-1.11.jar.../hamcrest-core-1.3.jar

注意 test 的编译路径上, 既包含 main 也包含自己的比如 junit 依赖。


public class SourceSetsTest {@Testpublic void whenRun_ThenSuccess() {SourceSetsObject underTest = new SourceSetsObject("lorem", "ipsum");assertThat(underTest.getUser(), is("lorem"));assertThat(underTest.getPassword(), is("ipsum"));}
}

所以测试用例的项目, 得以运行, 依赖 junit + main


.\gradlew.bat  source-sets:build test  BUILD SUCCESSFUL in 3s
6 actionable tasks: 1 executed, 5 up-to-date

#定制 Source Sets

特别在我们定制一些 integration 测试目录的时候, 有两种方式一种是筛选 IT 结尾的测试类, 另外一种是用独立的 sourceset.

#文件后缀方式

include "**/*IT*", "**/*IntTest*" 表达式来匹配:

task integrationTest(type: Test) {useJUnitPlatform()description = "Execute integration tests."group = "verification"include "**/*IT*", "**/*IntTest*"testLogging {events 'FAILED', 'SKIPPED'}
}

#独立文件目录

目录结构:


└─src├─itest│  └─java│      └─com│          └─dearxue│              └─itest│                      SourceSetsItest.java│├─main│  └─java│      └─com│          └─dearxue│              └─main│                      SourceSetsMain.java│                      SourceSetsObject.java│└─test└─java└─com└─dearxue└─testSourceSetsTest.java

build 配置


sourceSets {itest {java {}}
}

这里我们没有配置任何source 目录, 因为目录 itest 匹配 sourceSets 名称 itest。 当然我们也可以定制一个自己的名字:

sourceSets{itest {java {srcDirs("src/itest")}}
}

目录输出:

Task :source-sets:printSourceSetInformation
[itest]
-->Source directories: [....\source-sets\src\itest\java]
-->Output directories: [....\source-sets\build\classes\java\itest]
-->Compile classpath:
....

#Source Sets 定制依赖

如果你还记得 main & implementation 和 test & testImplementation, 那么你的定制 sourcesets 也可以有自己的依赖关系;

遵从这样规则: <sourceSetName><configurationName>


dependencies {implementation('org.apache.httpcomponents:httpclient:4.5.12')testImplementation('junit:junit:4.12')itestImplementation('com.google.guava:guava:29.0-jre')
}

itestImplementation 只对我们的 itest 生效, 添加如下测试用例:


public class SourceSetsItest {@Testpublic void givenImmutableList_whenRun_ThenSuccess() {SourceSetsObject underTest = new SourceSetsObject("lorem", "ipsum");List<String> someStrings = ImmutableList.of("deraxue", "is", "cool");assertThat(underTest.getUser(), is("lorem"));assertThat(underTest.getPassword(), is("ipsum"));assertThat(someStrings.size(), is(3));}
}

添加独立针对 itest 的任务:


task itest(type: Test) {description = "Run integration tests"group = "verification"testClassesDirs = sourceSets.itest.output.classesDirsclasspath = sourceSets.itest.runtimeClasspath
}

注意这部分声明是在 gradle 的 configuration 阶段执行的, 也就是他们的执行的顺序非常重要, 我们还不能引用到 itest 的sources set; 这样的执行结果会:


$ ./gradlew clean itest// some compilation issuesFAILURE: Build failed with an exception.* What went wrong:
Execution failed for task ':source-sets:compileItestJava'.
> Compilation failed; see the compiler error output for details.

新的 itest 生成独立的配置, 也就是 itestImplementation 没有继承 JUnit 依赖, 也没有继承 main 的 output


sourceSets{itest {compileClasspath += sourceSets.main.outputruntimeClasspath += sourceSets.main.outputjava {}}
}// dependencies declaration
configurations {itestImplementation.extendsFrom(testImplementation)itestRuntimeOnly.extendsFrom(testRuntimeOnly)
}

现在再运行就没有问题了。

项目地址: Gradle Source Sets 例子open in new window

#一些配置参考


//protobuf generated 目录配置
sourceSets {main {java {srcDirs 'build/generated/source/proto/main/grpc'srcDirs 'build/generated/source/proto/main/java'}}
}//分门别类设置不同测试目录
sourceSets {componentTest {compileClasspath += sourceSets.main.output + sourceSets.test.outputruntimeClasspath += sourceSets.main.output + sourceSets.test.output}apiTest {compileClasspath += sourceSets.main.output + sourceSets.test.outputruntimeClasspath += sourceSets.main.output + sourceSets.test.output}
}//各个测试任务的目录依赖
task componentTest(type: Test) {description = 'Run component tests.'group = 'verification'testClassesDirs = sourceSets.componentTest.output.classesDirsclasspath = sourceSets.componentTest.runtimeClasspathshouldRunAfter test
}task apiTest(type: Test) {description = 'Run API tests.'group = 'verification'testClassesDirs = sourceSets.apiTest.output.classesDirsclasspath = sourceSets.apiTest.runtimeClasspathshouldRunAfter componentTest
}check.dependsOn componentTest
check.dependsOn apiTest

api-hug-contact

这篇关于Gradle 实战 - SourceSet 配置 -ApiHug准备-工具篇-011的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/901671

相关文章

VScode连接远程Linux服务器环境配置图文教程

《VScode连接远程Linux服务器环境配置图文教程》:本文主要介绍如何安装和配置VSCode,包括安装步骤、环境配置(如汉化包、远程SSH连接)、语言包安装(如C/C++插件)等,文中给出了详... 目录一、安装vscode二、环境配置1.中文汉化包2.安装remote-ssh,用于远程连接2.1安装2

C语言小项目实战之通讯录功能

《C语言小项目实战之通讯录功能》:本文主要介绍如何设计和实现一个简单的通讯录管理系统,包括联系人信息的存储、增加、删除、查找、修改和排序等功能,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录功能介绍:添加联系人模块显示联系人模块删除联系人模块查找联系人模块修改联系人模块排序联系人模块源代码如下

基于Go语言实现一个压测工具

《基于Go语言实现一个压测工具》这篇文章主要为大家详细介绍了基于Go语言实现一个简单的压测工具,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录整体架构通用数据处理模块Http请求响应数据处理Curl参数解析处理客户端模块Http客户端处理Grpc客户端处理Websocket客户端

Redis多种内存淘汰策略及配置技巧分享

《Redis多种内存淘汰策略及配置技巧分享》本文介绍了Redis内存满时的淘汰机制,包括内存淘汰机制的概念,Redis提供的8种淘汰策略(如noeviction、volatile-lru等)及其适用场... 目录前言一、什么是 Redis 的内存淘汰机制?二、Redis 内存淘汰策略1. pythonnoe

java图像识别工具类(ImageRecognitionUtils)使用实例详解

《java图像识别工具类(ImageRecognitionUtils)使用实例详解》:本文主要介绍如何在Java中使用OpenCV进行图像识别,包括图像加载、预处理、分类、人脸检测和特征提取等步骤... 目录前言1. 图像识别的背景与作用2. 设计目标3. 项目依赖4. 设计与实现 ImageRecogni

windos server2022的配置故障转移服务的图文教程

《windosserver2022的配置故障转移服务的图文教程》本文主要介绍了windosserver2022的配置故障转移服务的图文教程,以确保服务和应用程序的连续性和可用性,文中通过图文介绍的非... 目录准备环境:步骤故障转移群集是 Windows Server 2022 中提供的一种功能,用于在多个

windos server2022里的DFS配置的实现

《windosserver2022里的DFS配置的实现》DFS是WindowsServer操作系统提供的一种功能,用于在多台服务器上集中管理共享文件夹和文件的分布式存储解决方案,本文就来介绍一下wi... 目录什么是DFS?优势:应用场景:DFS配置步骤什么是DFS?DFS指的是分布式文件系统(Distr

Golang操作DuckDB实战案例分享

《Golang操作DuckDB实战案例分享》DuckDB是一个嵌入式SQL数据库引擎,它与众所周知的SQLite非常相似,但它是为olap风格的工作负载设计的,DuckDB支持各种数据类型和SQL特性... 目录DuckDB的主要优点环境准备初始化表和数据查询单行或多行错误处理和事务完整代码最后总结Duck

基于Python开发电脑定时关机工具

《基于Python开发电脑定时关机工具》这篇文章主要为大家详细介绍了如何基于Python开发一个电脑定时关机工具,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 简介2. 运行效果3. 相关源码1. 简介这个程序就像一个“忠实的管家”,帮你按时关掉电脑,而且全程不需要你多做

关于Maven中pom.xml文件配置详解

《关于Maven中pom.xml文件配置详解》pom.xml是Maven项目的核心配置文件,它描述了项目的结构、依赖关系、构建配置等信息,通过合理配置pom.xml,可以提高项目的可维护性和构建效率... 目录1. POM文件的基本结构1.1 项目基本信息2. 项目属性2.1 引用属性3. 项目依赖4. 构