【问题标题】:How to override a gradle build with dev/prod configuration如何使用 dev/prod 配置覆盖 gradle 构建
【发布时间】:2016-07-16 16:41:43
【问题描述】:

我正在评估 gradle 以替换 ant 构建脚本,但我无法找到一个解决方案来创建正确管理 dev/prod 的标准构建脚本环境。

ant 脚本(它是用于 java 项目,而不是 android)的结构是这样的:

  1. 带有标准任务(编译、build-jar、build-war)的通用脚本
  2. 一个特定的项目脚本,包括第一个脚本,并通过一些属性定义了战争任务应该选择正确文件的位置

我们的项目结构/任务允许在最终战争中覆盖整个目录。让我们考虑这个例子: dev 配置是标准配置,位于 dir webcontent 有多个 prod conf(每个特定安装一个,我们没有超过 10 个不同的 prod 配置)都在 prod 目录下(即 *prod/conf1*m prod/conf2 等)

ant build 有 dev_build 任务作为 prod_conf1_build 之一, prod_conf2_build 一个等 XXX_build 任务做同样的事情:

  1. 指定包含环境目录/文件的父目录(它是项目属性)
  2. 使用调用任务中指定的属性调用构建战争的同一个蚂蚁塔

我正在尝试在 gradle 中做同样的事情,但似乎即使从另一个调用 taks 也会产生一些问题(即任务始终是最新的)

这是一个尝试做同样事情的脚本(它是一个工作草案,我正在学习 gradle),但是当我调用 war_prod 时它不起作用,因为它报告了最新的,所以它什么也不做

apply plugin: 'java'
apply plugin: 'war'
apply plugin: 'eclipse'

project.ext.envdir = "" 

eclipse {
  jdt {
    sourceCompatibility = 1.8
    targetCompatibility = 1.8
    javaRuntimeName = "jdk-1.8.x" 
  }
}


// In this section you declare where to find the dependencies of your project
repositories {
    maven {
        url 'http://artifactory.zzzz.priv/artifactory/libs-release'
        url 'http://artifactory.zzzz.priv/artifactory/libs-snapshot'
        credentials {
            username 'xxxx'
            password 'yyyy'
        }
    }
}

// In this section you declare the dependencies for your production and test code
dependencies {
    // The production code uses the SLF4J logging API at compile time
    compile 'org.slf4j:slf4j-api:1.7.18'

    // Declare the dependency for your favourite test framework you want to use in your tests.
    // TestNG is also supported by the Gradle Test task. Just change the
    // testCompile dependency to testCompile 'org.testng:testng:6.8.1' and add
    // 'test.useTestNG()' to your build script.
    testCompile 'junit:junit:4.12'
}

task war_prod {
    project.ext.envdir='prod/conf1'
    project.ext.envdir=project.ext.envdir.replaceAll('\\\\',File.pathSeparator)
    project.ext.envdir=project.ext.envdir.replaceAll('/',File.pathSeparator)
    tasks.war.execute()
}


war {
 eachFile {
  println 'endir' + project.ext.envdir
  println 'evaluating' + it
  FileTree tree = fileTree(dir: project.ext.envdir)
  tree.visit  { FileVisitDetails  file->
  if (!file.file.isDirectory()) {
  println '\tFileVisitDetails relpath ' + file.relativePath
  println '\tsourcepath ' + it.file.getAbsolutePath()
  println '\tcontains ' + it.file.getAbsolutePath().contains(project.ext.envdir)
  if (it.relativePath == file.relativePath && !it.file.getAbsolutePath().contains(project.ext.envdir)) {
     it.exclude()
     println '\texcluding ' + it
  } else {
   if (it!=null) {
     //println '\tincluding ' + it
     }
  }
  }
  }

 }

 from 'prod/conf1'
}

谁能指出我创建正确 gradle 脚本的正确方向? 是否有特定的 gradle 方式来构建带有 prod/dev 配置的 war 文件(其中配置由一些 dir 和文件表示)?

【问题讨论】:

    标签: java gradle


    【解决方案1】:

    在这种情况下task rules 可能非常有用。基本思想是以结构化的方式保持配置,并使用一般任务来构建一个定义了配置的war文件。请看下面的 build.gradle

    apply plugin: 'war'
    
    repositories {
       mavenCentral()
    }
    
    tasks.addRule("Pattern: buildWar<ENV>") { String taskName ->
        if (taskName.startsWith('buildWar')) {
            def env = (taskName - 'buildWar').toLowerCase()
            if (env in ['dev', 'prod',]) {
              task(taskName, type: War) {
                  println "Configuring env: $env"
                  from("src/main/conf/$env") {
                      into("conf")
                  }
              }
            } else {
              println "Invalid env: $env, skipping."
            }
        }
    }
    

    这里定义的buildWarENV 规则非常具有自我描述性。它接受两个环境 devprod 并通过从适当的文件夹中获取配置来准备战争文件。你可以找到一个演示here。如有问题,尽管问。

    附: Gradle 的工作模型与 ant 有点不同,从基础开始。重要的是,永远不要在其他任务中运行任务。

    【讨论】:

    • 谢谢你,从你的样品开始我已经能够继续我的测试了
    猜你喜欢
    • 2021-08-20
    • 2020-08-26
    • 2017-04-21
    • 2018-06-18
    • 1970-01-01
    • 1970-01-01
    • 2012-06-02
    • 2015-06-05
    • 2015-04-10
    相关资源
    最近更新 更多