You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
911 lines
39 KiB
911 lines
39 KiB
import org.gradle.api.artifacts.DependencyResolveDetails
|
|
|
|
import java.util.zip.GZIPOutputStream
|
|
|
|
apply from: "build-version.gradle"
|
|
|
|
// 判断项目是否是普通前端项目
|
|
def isFrontendProject(currentDir){
|
|
return file(currentDir.getAbsolutePath() + '/package.json').exists()
|
|
&& !file(currentDir.getAbsolutePath() + '/webpack.env.lib.cjs').exists();
|
|
}
|
|
|
|
/***********************************************************************
|
|
* gradle 插件
|
|
**********************************************************************/
|
|
buildscript {
|
|
repositories {
|
|
maven {
|
|
allowInsecureProtocol = true
|
|
url "${repository_url}"
|
|
}
|
|
}
|
|
dependencies {
|
|
classpath "com.gradleup.shadow:shadow-gradle-plugin:${shadow_gradle_plugin_version}"
|
|
classpath "org.springframework.boot:org.springframework.boot.gradle.plugin:${spring_boot_version}"
|
|
classpath "io.sc:io.sc.platform.gradle:${platform_plugin_version}"
|
|
classpath "org.asciidoctor:asciidoctor-gradle-jvm:${asciidoctor_version}"
|
|
classpath "com.google.cloud.tools:jib-gradle-plugin:${jib_version}"
|
|
}
|
|
}
|
|
|
|
/***********************************************************************
|
|
* 所有项目(根项目及其子项目)都应用的插件
|
|
**********************************************************************/
|
|
allprojects {
|
|
apply plugin: 'idea'
|
|
apply plugin: 'io.sc.platform.gradle'
|
|
}
|
|
|
|
/***********************************************************************
|
|
* 所有子项目应用的插件
|
|
**********************************************************************/
|
|
subprojects {
|
|
apply plugin: 'java'
|
|
apply plugin: 'java-library'
|
|
apply plugin: 'eclipse'
|
|
apply plugin: 'maven-publish'
|
|
apply plugin: 'org.springframework.boot'
|
|
apply plugin: 'io.spring.dependency-management'
|
|
apply plugin: 'org.asciidoctor.jvm.convert'
|
|
|
|
configurations.all {
|
|
//设置 gradle 拉取依赖包的缓存策略为不进行缓存,可保证每次拉取最新的依赖包
|
|
//resolutionStrategy.cacheDynamicVersionsFor 0, 'seconds' //动态版本: 1.1.+
|
|
//resolutionStrategy.cacheChangingModulesFor 0, 'seconds' //静态版本: 1.1.2
|
|
|
|
//排除不需要的外部依赖
|
|
// exclude group: "org.apache.logging.log4j", module: "log4j-api"
|
|
// exclude group: "org.apache.logging.log4j", module: "log4j-to-slf4j"
|
|
// exclude group: "org.slf4j", module: "slf4j-jdk14"
|
|
exclude group: "org.slf4j", module: "slf4j-nop"
|
|
exclude group: "com.mysql", module: "mysql-connector-j"
|
|
|
|
if(PlatformDependencyVersions!=null && PlatformDependencyVersions.size()>0) {
|
|
resolutionStrategy.eachDependency { DependencyResolveDetails detail ->
|
|
def requested = detail.requested;
|
|
def groupAndName = requested.group + ":" + requested.name;
|
|
String version = PlatformDependencyVersions[groupAndName];
|
|
if (version != null) {
|
|
detail.useVersion(version);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
dependencyManagement {
|
|
resolutionStrategy {
|
|
//设置 gradle 拉取依赖包的缓存策略为不进行缓存,可保证每次拉取最新的依赖包
|
|
//cacheDynamicVersionsFor 0, 'seconds' //动态版本: 1.1.+
|
|
//cacheChangingModulesFor 0, 'seconds' //静态版本: 1.1.2
|
|
}
|
|
imports {
|
|
//mavenBom "org.springframework.cloud:spring-cloud-dependencies:${spring_cloud_version}"
|
|
mavenBom "com.alibaba.cloud:spring-cloud-alibaba-dependencies:${spring_cloud_alibaba_version}"
|
|
mavenBom "org.springframework.statemachine:spring-statemachine-bom:${spring_statemachine_version}"
|
|
}
|
|
}
|
|
|
|
/*-----------------------------------------------------------------
|
|
* 配置构建时所需依赖的仓库 url
|
|
* 将仓库 url 都定位到 ${repository_url} 指定的本地私有仓库地址
|
|
*----------------------------------------------------------------*/
|
|
repositories {
|
|
all { ArtifactRepository repo ->
|
|
if(repo instanceof MavenArtifactRepository){
|
|
def url = repo.url.toString()
|
|
if (
|
|
url.startsWith('https://repo1.maven.org/maven2')
|
|
|| url.startsWith('https://jcenter.bintray.com/')
|
|
|| url.startsWith('https://maven.aliyun.com')
|
|
) {
|
|
remove repo
|
|
}
|
|
}
|
|
}
|
|
maven {
|
|
allowInsecureProtocol = true
|
|
url "${repository_url}"
|
|
}
|
|
}
|
|
|
|
/*-----------------------------------------------------------------
|
|
* java 编译时选项
|
|
*----------------------------------------------------------------*/
|
|
sourceCompatibility ="${java_version}"
|
|
targetCompatibility ="${java_version}"
|
|
compileJava.options.encoding ="${java_encoding}"
|
|
compileTestJava.options.encoding ="${java_encoding}"
|
|
|
|
tasks.withType(JavaCompile) {
|
|
options.compilerArgs += ["-Xlint:deprecation","-Xlint:unchecked"]
|
|
}
|
|
|
|
/*-----------------------------------------------------------------
|
|
* 配置项目基本信息
|
|
*----------------------------------------------------------------*/
|
|
group ="${platform_group}"
|
|
version ="${platform_version}"
|
|
|
|
if(file('package.json').exists()){
|
|
mkdir 'java-src/main/java';
|
|
mkdir 'java-src/main/resources';
|
|
mkdir 'dist';
|
|
sourceSets.main.java.srcDir 'java-src/main/java'
|
|
sourceSets.main.resources.srcDir 'java-src/main/resources'
|
|
sourceSets.main.resources.srcDir 'dist'
|
|
}
|
|
|
|
/*-----------------------------------------------------------------
|
|
* 源代码打包配置
|
|
*----------------------------------------------------------------*/
|
|
task sourcesJar (type : Jar) {
|
|
from sourceSets.main.allJava
|
|
archiveClassifier = 'sources'
|
|
}
|
|
|
|
/*-----------------------------------------------------------------
|
|
* Java 文档打包配置
|
|
*----------------------------------------------------------------*/
|
|
javadoc {
|
|
options.encoding = 'UTF-8'
|
|
// 为了能够尽量规范 java doc 文档编写, 指定如果 java doc 中有错误,会报错,并且无法发布到仓库中
|
|
failOnError=false
|
|
}
|
|
|
|
task javadocJar (type: Jar) {
|
|
from javadoc
|
|
archiveClassifier = 'javadoc'
|
|
}
|
|
|
|
clean {
|
|
delete 'bin' //删除 eclipse 编译的 bin 目录
|
|
delete 'build' //删除 gradle 构建目录
|
|
delete 'dist' //删除前端打包后的目录
|
|
delete 'node_modules' //删除前端 node_modules 目录
|
|
delete 'pnpm-lock.yaml' //删除前端 pnpm 文件
|
|
delete 'package-lock.json' //删除前端 npm 文件
|
|
}
|
|
|
|
/*-----------------------------------------------------------------
|
|
* 配置 eclipse 插件
|
|
*----------------------------------------------------------------*/
|
|
eclipse{
|
|
jdt{
|
|
sourceCompatibility ="${java_version}"
|
|
targetCompatibility ="${java_version}"
|
|
}
|
|
}
|
|
|
|
/*-----------------------------------------------------------------
|
|
* springboot 插件配置
|
|
*----------------------------------------------------------------*/
|
|
jar {
|
|
//可以生成普通的 jar
|
|
enabled = true
|
|
archiveClassifier.set("")
|
|
manifest {
|
|
attributes 'Manifest-Version' : '1.0',
|
|
'Implementation-Title' : name,
|
|
'Implementation-Vendor' : group,
|
|
'Implementation-Version': archiveVersion
|
|
}
|
|
}
|
|
|
|
/*-----------------------------------------------------------------
|
|
* asciidoctor 插件配置,用于生成 asciidoc 文档,用于打包到 jar 中
|
|
*----------------------------------------------------------------*/
|
|
asciidoctor {
|
|
baseDirFollowsSourceDir()
|
|
outputs.upToDateWhen { true }
|
|
|
|
logDocuments = true
|
|
sourceDir = file('asciidoc')
|
|
sources {
|
|
include '*.adoc'
|
|
}
|
|
outputDir = file("dist/help/" + project.name)
|
|
resources {
|
|
from(sourceDir) {
|
|
include 'resources/**'
|
|
}
|
|
}
|
|
}
|
|
|
|
asciidoctorj {
|
|
modules {
|
|
diagram.use()
|
|
}
|
|
}
|
|
|
|
/*-----------------------------------------------------------------
|
|
* 自定义任务,用于生成 asciidoc 文档到 web 服务器,以便实时查看效果
|
|
*----------------------------------------------------------------*/
|
|
task doc(type: org.asciidoctor.gradle.jvm.AsciidoctorTask){
|
|
baseDirFollowsSourceDir()
|
|
outputs.upToDateWhen { true }
|
|
|
|
logDocuments = true
|
|
sourceDir = file('asciidoc')
|
|
sources {
|
|
include '*.adoc'
|
|
}
|
|
outputDir = file("$asciidoc_deploy_dir" + project.name)
|
|
|
|
// 拷贝 asciidoc 自定义资源
|
|
// 设置方式: 通过命令行 -D 传入目标环境参数
|
|
// gradle doc -DdocResource=true # 需要拷贝自定义资源
|
|
// gradle doc -DdocResource=false # 不需要拷贝自定义资源
|
|
def docResource =System.getProperty("docResource")?:"true";
|
|
if(docResource=="true"){
|
|
resources {
|
|
from(sourceDir) {
|
|
include 'resources/**'
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*-----------------------------------------------------------------
|
|
* 资源处理前执行 asciidoctor
|
|
*----------------------------------------------------------------*/
|
|
processResources {
|
|
dependsOn asciidoctor
|
|
doLast{
|
|
//打包时移除 jrebel 相关的文件
|
|
delete "$buildDir/resources/main/rebel.xml"
|
|
}
|
|
}
|
|
|
|
/*-----------------------------------------------------------------
|
|
* 用于自动生成 jrebel.xml 文件的自定义任务(eclipse)
|
|
*----------------------------------------------------------------*/
|
|
task jrebelEclipse() {}
|
|
tasks.jrebelEclipse.doLast {
|
|
File resourcesFile =file('src/main/resources')
|
|
if(resourcesFile!=null && resourcesFile.exists()){
|
|
File rebelFile = file('src/main/resources/rebel.xml')
|
|
rebelFile.withWriter('UTF-8') { writer ->
|
|
writer.write('<?xml version="1.0" encoding="UTF-8"?>\n');
|
|
writer.write('<application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.zeroturnaround.com" xsi:schemaLocation="http://www.zeroturnaround.com http://update.zeroturnaround.com/jrebel/rebel-2_1.xsd">\n');
|
|
writer.write('\t<classpath>\n');
|
|
if(file(project.name + '/src/main').exists()){
|
|
writer.write('\t\t<dir name="' + project.projectDir + '/bin/main"/>\n');
|
|
}
|
|
if(file(project.name + '/src/generated').exists()){
|
|
writer.write('\t\t<dir name="' + project.projectDir + '/bin/generated"/>\n');
|
|
}
|
|
writer.write('\t</classpath>\n');
|
|
writer.write('</application>');
|
|
}
|
|
}
|
|
}
|
|
|
|
/*-----------------------------------------------------------------
|
|
* 用于自动生成 jrebel.xml 文件的自定义任务(idea)
|
|
*----------------------------------------------------------------*/
|
|
task jrebelIdea() {}
|
|
tasks.jrebelIdea.doLast {
|
|
if(isFrontendProject(file('.'))) {
|
|
File resourcesFile = file('java-src/main/resources')
|
|
if (resourcesFile != null && resourcesFile.exists()) {
|
|
File rebelFile = file('java-src/main/resources/rebel.xml')
|
|
rebelFile.withWriter('UTF-8') { writer ->
|
|
writer.write('<?xml version="1.0" encoding="UTF-8"?>\n');
|
|
writer.write('<application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.zeroturnaround.com" xsi:schemaLocation="http://www.zeroturnaround.com http://update.zeroturnaround.com/jrebel/rebel-2_1.xsd">\n');
|
|
writer.write('\t<classpath>\n');
|
|
if (file(project.name + '/java-src/main').exists()) {
|
|
writer.write('\t\t<dir name="' + project.rootProject.projectDir + '/out/production/' + project.name + '"/>\n');
|
|
}
|
|
writer.write('\t</classpath>\n');
|
|
writer.write('</application>');
|
|
}
|
|
}
|
|
}else {
|
|
File resourcesFile = file('src/main/resources')
|
|
if (resourcesFile != null && resourcesFile.exists()) {
|
|
File rebelFile = file('src/main/resources/rebel.xml')
|
|
rebelFile.withWriter('UTF-8') { writer ->
|
|
writer.write('<?xml version="1.0" encoding="UTF-8"?>\n');
|
|
writer.write('<application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.zeroturnaround.com" xsi:schemaLocation="http://www.zeroturnaround.com http://update.zeroturnaround.com/jrebel/rebel-2_1.xsd">\n');
|
|
writer.write('\t<classpath>\n');
|
|
if (file(project.name + '/src/main').exists()) {
|
|
writer.write('\t\t<dir name="' + project.rootProject.projectDir + '/out/production/' + project.name + '"/>\n');
|
|
}
|
|
writer.write('\t</classpath>\n');
|
|
writer.write('</application>');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*-----------------------------------------------------------------
|
|
* maven publish 插件配置
|
|
*----------------------------------------------------------------*/
|
|
publishing {
|
|
repositories {
|
|
maven {
|
|
allowInsecureProtocol = true //允许采用 http 协议发布
|
|
url = version.contains('SNAPSHOT') ? "${repository_snapshot_url}" : "${repository_release_url}"
|
|
credentials {
|
|
username = (version.contains('SNAPSHOT') ? "${repository_snapshot_username}" : "${repository_release_username}")
|
|
password = (version.contains('SNAPSHOT') ? "${repository_snapshot_password}" : "${repository_release_password}")
|
|
}
|
|
}
|
|
}
|
|
publications{
|
|
publication(MavenPublication){
|
|
from components.java
|
|
//artifact sourcesJar
|
|
//artifact javadocJar
|
|
versionMapping {
|
|
usage('java-api') {
|
|
fromResolutionOf('runtimeClasspath')
|
|
}
|
|
usage('java-runtime') {
|
|
fromResolutionResult()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*-----------------------------------------------------------------
|
|
* 更新前端模块的 package.json 文件,同步其中的 name 和 version
|
|
*----------------------------------------------------------------*/
|
|
task frontendUpdatePackageJson(){}
|
|
tasks.frontendUpdatePackageJson.doFirst {
|
|
if(isFrontendProject(file('.'))) {
|
|
println '开始执行 frontendUpdatePackageJson ......'
|
|
}
|
|
}
|
|
tasks.frontendUpdatePackageJson.doLast {
|
|
if(isFrontendProject(file('.'))){
|
|
String content =file('package.json').text;
|
|
def packageJson = new groovy.json.JsonSlurper().parseText(content);
|
|
if(packageJson!=null){
|
|
println packageJson.dependencies;
|
|
packageJson.name =project.name;
|
|
packageJson.version =project.version;
|
|
packageJson.dependencies['platform-core']=platform_core_frontend_version;
|
|
def json = groovy.json.JsonOutput.toJson(packageJson);
|
|
file('package.json').withWriter('UTF-8') { writer ->
|
|
writer.write(groovy.json.JsonOutput.prettyPrint(json));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*-----------------------------------------------------------------
|
|
* pnpm install
|
|
*----------------------------------------------------------------*/
|
|
task frontendNpmInstall(type:Exec){
|
|
if(isFrontendProject(file('.'))){
|
|
workingDir '.'
|
|
if(org.gradle.internal.os.OperatingSystem.current().isWindows()){
|
|
commandLine 'cmd', '/c', 'pnpm', 'install'
|
|
}else{
|
|
commandLine 'pnpm', 'install'
|
|
}
|
|
}else{
|
|
if(org.gradle.internal.os.OperatingSystem.current().isWindows()){
|
|
commandLine 'cmd', '/c', 'cd', '.'
|
|
}else{
|
|
commandLine 'cd', '.'
|
|
}
|
|
}
|
|
}
|
|
tasks.frontendNpmInstall.doFirst {
|
|
if(isFrontendProject(file('.'))) {
|
|
println '开始执行 pnpm install ......';
|
|
}
|
|
}
|
|
|
|
/*-----------------------------------------------------------------
|
|
* pnpm sync
|
|
*----------------------------------------------------------------*/
|
|
task frontendNpmSync(type:Exec){
|
|
if(isFrontendProject(file('.')) && !project.name.contains("io.sc.platform.security.frontend")){
|
|
workingDir '.'
|
|
if(org.gradle.internal.os.OperatingSystem.current().isWindows()){
|
|
commandLine 'cmd', '/c', 'pnpm', 'sync'
|
|
}else{
|
|
commandLine 'pnpm', 'sync'
|
|
}
|
|
}else{
|
|
if(org.gradle.internal.os.OperatingSystem.current().isWindows()){
|
|
commandLine 'cmd', '/c', 'cd', '.'
|
|
}else{
|
|
commandLine 'cd', '.'
|
|
}
|
|
}
|
|
}
|
|
tasks.frontendNpmSync.doFirst {
|
|
if(isFrontendProject(file('.'))) {
|
|
println '开始执行 pnpm sync ......';
|
|
}
|
|
}
|
|
|
|
/*-----------------------------------------------------------------
|
|
* pnpm re install
|
|
*----------------------------------------------------------------*/
|
|
task frontendNpmReInstall(type:Exec){
|
|
if(isFrontendProject(file('.'))){
|
|
workingDir '.'
|
|
if(org.gradle.internal.os.OperatingSystem.current().isWindows()){
|
|
commandLine 'cmd', '/c', 'pnpm', 'install'
|
|
}else{
|
|
commandLine 'pnpm', 'install'
|
|
}
|
|
}else{
|
|
if(org.gradle.internal.os.OperatingSystem.current().isWindows()){
|
|
commandLine 'cmd', '/c', 'cd', '.'
|
|
}else{
|
|
commandLine 'cd', '.'
|
|
}
|
|
}
|
|
}
|
|
tasks.frontendNpmReInstall.doFirst {
|
|
if(isFrontendProject(file('.'))) {
|
|
println '开始执行 pnpm re install ......';
|
|
}
|
|
}
|
|
|
|
/*-----------------------------------------------------------------
|
|
* pnpm run build
|
|
*----------------------------------------------------------------*/
|
|
task frontendNpmBuild(type:Exec) {
|
|
if(isFrontendProject(file('.'))){
|
|
workingDir '.'
|
|
if(org.gradle.internal.os.OperatingSystem.current().isWindows()){
|
|
commandLine 'cmd', '/c', 'pnpm', 'run', 'build'
|
|
}else{
|
|
commandLine 'pnpm', 'run', 'build'
|
|
}
|
|
}else{
|
|
if(org.gradle.internal.os.OperatingSystem.current().isWindows()){
|
|
commandLine 'cmd', '/c', 'cd', '.'
|
|
}else{
|
|
commandLine 'cd', '.'
|
|
}
|
|
}
|
|
}
|
|
tasks.frontendNpmBuild.doFirst {
|
|
if (isFrontendProject(file('.'))) {
|
|
println '开始执行 pnpm run build ......'
|
|
}
|
|
}
|
|
|
|
/*-----------------------------------------------------------------
|
|
* pnpm run prod
|
|
*----------------------------------------------------------------*/
|
|
task frontendNpmProd(type:Exec) {
|
|
if(isFrontendProject(file('.'))){
|
|
workingDir '.'
|
|
if(org.gradle.internal.os.OperatingSystem.current().isWindows()){
|
|
commandLine 'cmd', '/c', 'pnpm', 'run', 'prod'
|
|
}else{
|
|
commandLine 'pnpm', 'run', 'prod'
|
|
}
|
|
}else{
|
|
if(org.gradle.internal.os.OperatingSystem.current().isWindows()){
|
|
commandLine 'cmd', '/c', 'cd', '.'
|
|
}else{
|
|
commandLine 'cd', '.'
|
|
}
|
|
}
|
|
}
|
|
tasks.frontendNpmProd.doFirst {
|
|
if(isFrontendProject(file('.'))){
|
|
println '开始执行 pnpm run prod ......'
|
|
}
|
|
}
|
|
|
|
/*-----------------------------------------------------------------
|
|
* 将入口前端 dist/public/模块名 目录下 index.html 文件复制到 classpath:/templates/模块名.html
|
|
* 提供给 thymeleaf 作为视图模板使用
|
|
*----------------------------------------------------------------*/
|
|
task frontendGenerateThymeleafTemplate {}
|
|
tasks.frontendGenerateThymeleafTemplate.doFirst {
|
|
if(isFrontendProject(file('.'))) {
|
|
println '开始执行 frontendGenerateThymeleafTemplate ......'
|
|
delete "java-src/main/resources/templates"
|
|
mkdir "java-src/main/resources/templates"
|
|
}
|
|
}
|
|
tasks.frontendGenerateThymeleafTemplate.doLast {
|
|
if(isFrontendProject(file('.'))) {
|
|
if(!file("dist/public/${project.name}/index.html").exists()){
|
|
return;
|
|
}
|
|
def content = file("dist/public/${project.name}/index.html").text;
|
|
content = content.replace('<script defer src="javascript/main', """<script defer src="${project.name}/javascript/main""");
|
|
def output = file("java-src/main/resources/templates/${project.name}.html");
|
|
output.withWriter('utf-8') { writer ->
|
|
writer.write content;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*-----------------------------------------------------------------
|
|
* 根据前端定义的多语言 json 文件生成后端 properties 文件
|
|
*----------------------------------------------------------------*/
|
|
task frontendGenerateI18n {}
|
|
tasks.frontendGenerateI18n.doFirst {
|
|
if(isFrontendProject(file('.'))){
|
|
println '开始执行 frontendGenerateI18n ......'
|
|
delete 'java-src/main/resources/' + project.name.replace('.', '/') + '/i18n';
|
|
delete 'java-src/main/resources/META-INF/platform/plugins/messages.json';
|
|
|
|
mkdir 'java-src/main/resources/' + project.name.replace('.', '/') + '/i18n';
|
|
mkdir 'java-src/main/resources/META-INF/platform/plugins';
|
|
}
|
|
}
|
|
tasks.frontendGenerateI18n.doLast {
|
|
if(isFrontendProject(file('.'))){
|
|
def messagesDir ='java-src/main/resources/' + project.name.replace('.', '/') + '/i18n';
|
|
def pluginDir ='java-src/main/resources/META-INF/platform/plugins';
|
|
def jsonDir ='src/i18n';
|
|
|
|
// 获取所有的多语言消息文件
|
|
def tree = fileTree(jsonDir) { include '**/*.json' }
|
|
def i18nMessageFileList =new ArrayList<String>();
|
|
tree.each { File jsonFile -> i18nMessageFileList.add(jsonFile.getName()) }
|
|
|
|
if(i18nMessageFileList.size()>0){
|
|
// 生成 java-src/main/resources/META-INF/platform/plugins/messages.json 文件
|
|
def content ='';
|
|
content +='{\n';
|
|
content +=' includes:[\n';
|
|
content +=' "' + project.name.replace('.','/') + '/i18n/messages"' + '\n';
|
|
content +=' ]\n';
|
|
content +='}\n';
|
|
def output =file(pluginDir + '/messages.json');
|
|
output.withWriter('utf-8') { writer ->
|
|
writer.write content;
|
|
}
|
|
// 生成 java-src/main/resources/{project.name}/messages_{locale}.properties
|
|
for(String fileName : i18nMessageFileList){
|
|
def json = new groovy.json.JsonSlurper().parseText(file(jsonDir + '/' + fileName).text);
|
|
def sb =new StringBuilder();
|
|
json.keySet().each { String key ->
|
|
sb.append(key).append("=").append(groovy.json.StringEscapeUtils.escapeJava(json.get(key))).append("\n");
|
|
};
|
|
def outputFilePath =messagesDir + '/' + fileName.replace('.json','.properties');
|
|
file(outputFilePath).withWriter('utf-8') { writer ->
|
|
writer.write sb.toString();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*-----------------------------------------------------------------
|
|
* 根据前端定义的菜单 json 文件生成后端插件 json 文件
|
|
*----------------------------------------------------------------*/
|
|
task frontendGenerateMenus {}
|
|
tasks.frontendGenerateMenus.doFirst {
|
|
if(isFrontendProject(file('.'))){
|
|
println '开始执行 frontendGenerateMenus ......'
|
|
delete 'java-src/main/resources/META-INF/platform/plugins/menus.json';
|
|
}
|
|
}
|
|
tasks.frontendGenerateMenus.doLast {
|
|
if(isFrontendProject(file('.'))) {
|
|
if(!file('src/menus/menus.json').exists()) {
|
|
return;
|
|
}
|
|
java.nio.file.Files.copy(file('src/menus/menus.json').toPath(), file('java-src/main/resources/META-INF/platform/plugins/menus.json').toPath());
|
|
}
|
|
}
|
|
|
|
/*-----------------------------------------------------------------
|
|
* 根据前端定义的路由 json 文件生成后端插件 json 文件
|
|
*----------------------------------------------------------------*/
|
|
task frontendGenerateRoutes {}
|
|
tasks.frontendGenerateRoutes.doFirst {
|
|
if(isFrontendProject(file('.'))){
|
|
println '开始执行 frontendGenerateRoutes ......'
|
|
delete 'java-src/main/resources/META-INF/platform/plugins/frontend-routes.json';
|
|
}
|
|
}
|
|
tasks.frontendGenerateRoutes.doLast {
|
|
if(isFrontendProject(file('.'))) {
|
|
if(!file("src/routes/routes.json").exists()) {
|
|
return;
|
|
}
|
|
def routes = new groovy.json.JsonSlurper().parseText(file("src/routes/routes.json").text);
|
|
for (def route : routes) {
|
|
route.module = project.name;
|
|
}
|
|
def json = groovy.json.JsonOutput.toJson(routes);
|
|
def outputFile = file("java-src/main/resources/META-INF/platform/plugins/frontend-routes.json");
|
|
outputFile.withWriter('UTF-8') { writer ->
|
|
writer.write(groovy.json.JsonOutput.prettyPrint(json));
|
|
}
|
|
}
|
|
}
|
|
|
|
/*-----------------------------------------------------------------
|
|
* 为后端生成前端资源清单,以便可通过一键导出成独立的前端系统
|
|
*----------------------------------------------------------------*/
|
|
task frontendModule {}
|
|
tasks.frontendModule.doFirst {
|
|
if(isFrontendProject(file('.'))) {
|
|
println '开始执行 frontendModule ......'
|
|
delete 'java-src/main/resources/META-INF/platform/plugins/frontend-module.json'
|
|
}
|
|
}
|
|
tasks.frontendModule.doLast {
|
|
if(isFrontendProject(file('.'))) {
|
|
//components---------------------------------------
|
|
List<String> components =new ArrayList<String>();
|
|
if(file("java-src/main/resources/META-INF/platform/plugins/frontend-routes.json").exists()) {
|
|
def routes = new groovy.json.JsonSlurper().parseText(file("java-src/main/resources/META-INF/platform/plugins/frontend-routes.json").text);
|
|
for (def route : routes) {
|
|
components.add(route.component);
|
|
}
|
|
}
|
|
|
|
//resources----------------------------------------
|
|
List<String> resources = new ArrayList<String>();
|
|
def dirPath = file('dist').absolutePath;
|
|
if(project.name.contains('io.sc.platform.mvc.frontend')){
|
|
def tree = fileTree('dist') {
|
|
include '**/*.*'
|
|
exclude "public/${project.name}/configure.js"
|
|
exclude "public/${project.name}/favicon.svg"
|
|
exclude "public/${project.name}/index.html"
|
|
exclude "public/${project.name}/login-bg.jpg"
|
|
exclude "public/${project.name}/logo.svg"
|
|
}
|
|
tree.each { File file ->
|
|
resources.add(file.absolutePath.substring(dirPath.length()));
|
|
}
|
|
}else{
|
|
def tree = fileTree('dist') {
|
|
include '**/*.*'
|
|
// exclude '**/webjars/**/*.*'
|
|
// exclude "public/${project.name}/configure.js"
|
|
// exclude "public/${project.name}/favicon.svg"
|
|
// exclude "public/${project.name}/index.html"
|
|
// exclude "public/${project.name}/login-bg.jpg"
|
|
// exclude "public/${project.name}/logo.svg"
|
|
}
|
|
tree.each { File file ->
|
|
resources.add(file.absolutePath.substring(dirPath.length()));
|
|
}
|
|
}
|
|
|
|
|
|
//all-in-one------------------------------------
|
|
Map<String,Object> allInOne =new LinkedHashMap<>();
|
|
allInOne.put("name",project.name);
|
|
allInOne.put("components",components);
|
|
allInOne.put("resources",resources);
|
|
|
|
def json = groovy.json.JsonOutput.toJson(allInOne);
|
|
def outputFile =file('java-src/main/resources/META-INF/platform/plugins/frontend-module.json');
|
|
outputFile.withWriter('UTF-8') { writer ->
|
|
writer.write(groovy.json.JsonOutput.prettyPrint(json));
|
|
}
|
|
}
|
|
}
|
|
|
|
/*-----------------------------------------------------------------
|
|
* 打包 jar 之前处理前端资源
|
|
*----------------------------------------------------------------*/
|
|
task frontend() {}
|
|
tasks.frontend.doFirst {
|
|
if(isFrontendProject(file('.'))){
|
|
println '开始执行 frontend ......'
|
|
}
|
|
}
|
|
|
|
// 定义前端构建任务的依赖及执行顺序
|
|
frontendNpmInstall.dependsOn(frontendUpdatePackageJson)
|
|
frontendNpmSync.dependsOn(frontendNpmInstall)
|
|
frontendNpmReInstall.dependsOn(frontendNpmSync)
|
|
frontendNpmBuild.dependsOn(frontendNpmReInstall)
|
|
frontendNpmProd.dependsOn(frontendNpmReInstall)
|
|
|
|
// 资源处理前进行前端模块的构建
|
|
// 设置方式: 通过命令行 -D 传入目标环境参数
|
|
// gradle bootwar -Dfrontend=dev # 采用 pnpm build 构建前端
|
|
// gradle bootwar -Dfrontend=prod # 采用 pnpm prod 构建前端
|
|
// gradle bootwar -Dfrontend=none # 不构建前端, 仅生成后端需要的文件
|
|
def isFrontend =System.getProperty("frontend")?:"prod";
|
|
if(isFrontend=="dev"){
|
|
frontendGenerateThymeleafTemplate.dependsOn(frontendNpmBuild);
|
|
}else if(isFrontend=="prod"){
|
|
frontendGenerateThymeleafTemplate.dependsOn(frontendNpmProd);
|
|
}
|
|
frontendGenerateI18n.dependsOn(frontendGenerateThymeleafTemplate);
|
|
frontendGenerateMenus.dependsOn(frontendGenerateI18n);
|
|
frontendGenerateRoutes.dependsOn(frontendGenerateMenus);
|
|
frontendModule.dependsOn(frontendGenerateRoutes);
|
|
frontend.dependsOn(frontendModule);
|
|
|
|
processResources.dependsOn(frontend)
|
|
|
|
processResources {
|
|
if(isFrontendProject(file('.'))) {
|
|
if(project.name!='io.sc.platform.mvc.frontend'){
|
|
exclude("**/${project.name}/*.*");
|
|
exclude("**/${project.name}/javascript/codemirror.*");
|
|
exclude("**/${project.name}/javascript/echarts.*");
|
|
exclude("**/${project.name}/javascript/maxgraph.*");
|
|
exclude("**/${project.name}/javascript/platform-core.*");
|
|
exclude("**/${project.name}/javascript/quasar.*");
|
|
exclude("**/${project.name}/javascript/vue.*");
|
|
exclude("**/${project.name}/fonts/*.*");
|
|
exclude("**/${project.name}/webjars/**/*.*");
|
|
}
|
|
}
|
|
}
|
|
|
|
// 对每个前端项目在 idea 中排除 node_modules 目录, 避免大量耗时的 idea 索引
|
|
idea {
|
|
module {
|
|
excludeDirs += file('node_modules')
|
|
excludeDirs += file('dist')
|
|
}
|
|
}
|
|
}
|
|
|
|
/***********************************************************************
|
|
* 根(Root)项目配置, 该部分仅用于根项目
|
|
**********************************************************************/
|
|
/*-----------------------------------------------------------------
|
|
* idea 配置
|
|
*----------------------------------------------------------------*/
|
|
tasks.ideaProject.enabled=true //在根工程中执行 ideaProject 任务,用于生成 ipr 文件
|
|
tasks.ideaModule.enabled=false //在根工程中不执行 ideaModule 任务
|
|
tasks.ideaWorkspace.enabled=true //在根工程中执行 ideaWorkspace 任务,用于修改 iws 文件
|
|
|
|
tasks.ideaProject.doFirst {
|
|
delete project.name + '.ipr'
|
|
}
|
|
|
|
/*-----------------------------------------------------------------
|
|
* 定制生成的 idea xml 文件内容
|
|
*----------------------------------------------------------------*/
|
|
idea {
|
|
workspace {
|
|
iws {
|
|
// 自动化配置生成的 iws 文件内容,减少手工操作
|
|
// 1. 设置 Automatically show first error in editor 属性为 false,避免在编辑代码时,总是打开其他有错误的文件,导致混乱
|
|
withXml {
|
|
// 1. 设置 Automatically show first error in editor 属性为 false,避免在编辑代码时,总是打开其他有错误的文件,导致混乱
|
|
def node = it.asNode();
|
|
def compilerWorkspaceConfigurationNode =node.find{it.@name=='CompilerWorkspaceConfiguration'}
|
|
if(compilerWorkspaceConfigurationNode==null){
|
|
compilerWorkspaceConfigurationNode =node.appendNode("component",[name:"CompilerWorkspaceConfiguration"]);
|
|
}
|
|
def autoShowErrorsInEditorNode =compilerWorkspaceConfigurationNode.find{it.@name=='AUTO_SHOW_ERRORS_IN_EDITOR'}
|
|
if(autoShowErrorsInEditorNode==null){
|
|
autoShowErrorsInEditorNode =compilerWorkspaceConfigurationNode.appendNode("option",[name:"AUTO_SHOW_ERRORS_IN_EDITOR"]);
|
|
}
|
|
autoShowErrorsInEditorNode.@value ="false";
|
|
}
|
|
}
|
|
}
|
|
project {
|
|
vcs = 'Git'
|
|
ipr {
|
|
// 自动化配置生成的 ipr 文件内容,减少手工操作
|
|
// 1. 移除根项目模块
|
|
// <component name="ProjectModuleManager">
|
|
// <modules>
|
|
// <module fileurl="file://$PROJECT_DIR$/projectName.iml" filepath="$PROJECT_DIR$/projectName.iml"/> #移除
|
|
// ......
|
|
// </modules>
|
|
// </component>
|
|
// 2. 设置打开 .properties 文件时的转码功能(可显示中文)
|
|
// 将
|
|
// <component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false"/>
|
|
// 替换为:
|
|
// <component name="Encoding" native2AsciiForPropertiesFiles="true" />
|
|
// 3. 使 idea 编译器支持注解(enable annotation processing)
|
|
// 将
|
|
// <annotationProcessing enabled="false" useClasspath="true"/>
|
|
// 替换为:
|
|
// <annotationProcessing>
|
|
// <profile default="true" name="" enabled="true" />
|
|
// </annotationProcessing>
|
|
withXml {
|
|
// 1. 移除根项目模块
|
|
def node = it.asNode()
|
|
def projectModuleManagerNode = node.find { it.@name == 'ProjectModuleManager' }
|
|
def rootImlNode = projectModuleManagerNode.modules.module.find { it.@fileurl == 'file://$PROJECT_DIR$/' + project.name + '.iml' }
|
|
def rootImlParentNode = rootImlNode.parent()
|
|
rootImlParentNode.remove(rootImlNode)
|
|
|
|
// 2. 替换 Encoding
|
|
def encodingNode = node.find { it.@name == 'Encoding' }
|
|
encodingNode.@native2AsciiForPropertiesFiles = "true"
|
|
|
|
// 3. 使 idea 编译器支持注解(enable annotation processing)
|
|
def compilerConfigurationNode = node.find { it.@name == 'CompilerConfiguration' }
|
|
def annotationProcessingNode = compilerConfigurationNode.annotationProcessing[0]
|
|
def annotationProcessingParentNode = annotationProcessingNode.parent()
|
|
annotationProcessingParentNode.remove(annotationProcessingNode)
|
|
annotationProcessingNode = annotationProcessingParentNode.appendNode("annotationProcessing")
|
|
annotationProcessingNode.appendNode("profile", [default: true, enabled: true])
|
|
|
|
// 4. 激活 SaveActions 插件, 修改文件后自动编译并发布, 在 .ipr 文件中生成以下 xml 片段
|
|
// <component name="SaveActionSettings">
|
|
// <option name="actions">
|
|
// <set>
|
|
// <option value="activate" />
|
|
// <option value="reload" />
|
|
// </set>
|
|
// </option>
|
|
// <option name="configurationPath" value="" />
|
|
// </component>
|
|
|
|
// <component name="SaveActionSettings">
|
|
def saveActionSettingsNode = node.find { it.@name == 'SaveActionSettings' }
|
|
if (saveActionSettingsNode == null) {
|
|
saveActionSettingsNode = node.appendNode("component", [name: "SaveActionSettings"])
|
|
}
|
|
|
|
// <option name="actions">
|
|
def actionsNode = saveActionSettingsNode.find { it.@name == 'actions' }
|
|
if (actionsNode == null) {
|
|
actionsNode = saveActionSettingsNode.appendNode("option", [name: "actions"])
|
|
}
|
|
|
|
// <set>
|
|
def setNode = actionsNode.set[0]
|
|
|
|
if (setNode == null) {
|
|
setNode = actionsNode.appendNode("set")
|
|
}
|
|
|
|
// <option value="activate" />
|
|
// <option value="reload" />
|
|
def options = setNode.option
|
|
if (options != null && options.size() > 0) {
|
|
// 先移除
|
|
for (int i = 0; i < options.size(); i++) {
|
|
setNode.remove(options.get(i));
|
|
}
|
|
}
|
|
// 再添加
|
|
setNode.appendNode("option", [value: "activate"])
|
|
setNode.appendNode("option", [value: "reload"])
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*-----------------------------------------------------------------
|
|
* 覆盖根项目的 clean 任务
|
|
* 删除 idea 编译的 out 目录,实际上 out 目录并不在每个子模块中,而在根工程目录中
|
|
* 但是 gradle 对根项目并没有提供 clean 任务, 在此单独为根项目提供 clean 任务
|
|
*----------------------------------------------------------------*/
|
|
task clean {
|
|
doFirst{
|
|
delete 'out'
|
|
}
|
|
}
|
|
|
|
/*-----------------------------------------------------------------
|
|
* 覆盖根工程的 cleanIdea 任务,由于默认 cleanIdea 任务只执行:
|
|
* cleanIdeaProject, cleanIdeaModule 两个任务,
|
|
* gradle 也单独提供了一个 cleanIdeaWorkspace 任务,用于删除 .iws 文件。
|
|
* 为了方便, 我们将 cleanIdea 任务的默认行为改为同时执行 3 两个任务
|
|
* cleanIdeaProject, cleanIdeaModule, cleanIdeaWorkspace
|
|
*----------------------------------------------------------------*/
|
|
cleanIdea {
|
|
dependsOn cleanIdeaWorkspace
|
|
}
|
|
|
|
task github {
|
|
println ''
|
|
}
|
|
|
|
tasks.named('wrapper') {
|
|
distributionUrl = "http://nexus.sc.io:8000/repository/maven-releases/gradle/gradle/${gradleVersion}/gradle-${gradleVersion}-bin.zip"
|
|
}
|
|
|