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

相关文章

Linux下进程的CPU配置与线程绑定过程

《Linux下进程的CPU配置与线程绑定过程》本文介绍Linux系统中基于进程和线程的CPU配置方法,通过taskset命令和pthread库调整亲和力,将进程/线程绑定到特定CPU核心以优化资源分配... 目录1 基于进程的CPU配置1.1 对CPU亲和力的配置1.2 绑定进程到指定CPU核上运行2 基于

MySQL 多列 IN 查询之语法、性能与实战技巧(最新整理)

《MySQL多列IN查询之语法、性能与实战技巧(最新整理)》本文详解MySQL多列IN查询,对比传统OR写法,强调其简洁高效,适合批量匹配复合键,通过联合索引、分批次优化提升性能,兼容多种数据库... 目录一、基础语法:多列 IN 的两种写法1. 直接值列表2. 子查询二、对比传统 OR 的写法三、性能分析

Spring Boot spring-boot-maven-plugin 参数配置详解(最新推荐)

《SpringBootspring-boot-maven-plugin参数配置详解(最新推荐)》文章介绍了SpringBootMaven插件的5个核心目标(repackage、run、start... 目录一 spring-boot-maven-plugin 插件的5个Goals二 应用场景1 重新打包应用

Java中读取YAML文件配置信息常见问题及解决方法

《Java中读取YAML文件配置信息常见问题及解决方法》:本文主要介绍Java中读取YAML文件配置信息常见问题及解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要... 目录1 使用Spring Boot的@ConfigurationProperties2. 使用@Valu

Python办公自动化实战之打造智能邮件发送工具

《Python办公自动化实战之打造智能邮件发送工具》在数字化办公场景中,邮件自动化是提升工作效率的关键技能,本文将演示如何使用Python的smtplib和email库构建一个支持图文混排,多附件,多... 目录前言一、基础配置:搭建邮件发送框架1.1 邮箱服务准备1.2 核心库导入1.3 基础发送函数二、

Jenkins分布式集群配置方式

《Jenkins分布式集群配置方式》:本文主要介绍Jenkins分布式集群配置方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1.安装jenkins2.配置集群总结Jenkins是一个开源项目,它提供了一个容易使用的持续集成系统,并且提供了大量的plugin满

PowerShell中15个提升运维效率关键命令实战指南

《PowerShell中15个提升运维效率关键命令实战指南》作为网络安全专业人员的必备技能,PowerShell在系统管理、日志分析、威胁检测和自动化响应方面展现出强大能力,下面我们就来看看15个提升... 目录一、PowerShell在网络安全中的战略价值二、网络安全关键场景命令实战1. 系统安全基线核查

SpringBoot线程池配置使用示例详解

《SpringBoot线程池配置使用示例详解》SpringBoot集成@Async注解,支持线程池参数配置(核心数、队列容量、拒绝策略等)及生命周期管理,结合监控与任务装饰器,提升异步处理效率与系统... 目录一、核心特性二、添加依赖三、参数详解四、配置线程池五、应用实践代码说明拒绝策略(Rejected

基于Python实现一个图片拆分工具

《基于Python实现一个图片拆分工具》这篇文章主要为大家详细介绍了如何基于Python实现一个图片拆分工具,可以根据需要的行数和列数进行拆分,感兴趣的小伙伴可以跟随小编一起学习一下... 简单介绍先自己选择输入的图片,默认是输出到项目文件夹中,可以自己选择其他的文件夹,选择需要拆分的行数和列数,可以通过

Python使用pip工具实现包自动更新的多种方法

《Python使用pip工具实现包自动更新的多种方法》本文深入探讨了使用Python的pip工具实现包自动更新的各种方法和技术,我们将从基础概念开始,逐步介绍手动更新方法、自动化脚本编写、结合CI/C... 目录1. 背景介绍1.1 目的和范围1.2 预期读者1.3 文档结构概述1.4 术语表1.4.1 核