How to override a gradle build with dev/prod configuration

我怕爱的太早我们不能终老 提交于 2021-02-18 17:00:21

问题


I'm evaluating gradle for replacing an ant build script and I can't manage to find a solution for creating a standard build script that correctly manages dev/prod environment.

Than ant script (it's for a java project, not android) is structured in this way:

  1. a common script with the standard tasks (compile, build-jar, build-war)
  2. a specific project script that includes the first one and through some properties it defines where the war task should pick the correct files

Our project structure/taks allows to override entire directories in the final war. Let consider this example: the dev configuration is the standard one and lays int the dir webcontent there are multiple prod conf (one of each specific installation, we do not have more that 10 different prod configs) all under the prod dir (i.e. *prod/conf1*m prod/conf2, etc)

The ant build has the dev_build task as the prod_conf1_build one, the prod_conf2_build one ,etc the XXX_build task do the same things:

  1. specify the parent (it's a project property) dir that contains the env dir/files
  2. call the same ant taks that build the war using the property specified in the calling task

I'm trying to do the same in gradle but it seems that even calling a taks from another one it creates some problem (i.e. the task is always up to date)

Here is the script (it's a working draft, I'm learning gradle) that tries to do the same but it's not working when I call war_prod the taks does nothing since it reports up-to-date

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'
}

Can anyone point me in the right direction for creating a correct gradle script? Is there a specific gradle way to build war files with prod/dev configurations (where the configuration is represented by some dir and files)?


回答1:


In such scenarios task rules might be very useful. Basic idea is to keep configurations in a structured way and use a general task to build a war file with a configuration defined. Please have a look at build.gradle below:

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."
        }
    }
}

The buildWarENV rule defined here is pretty self descriptive. It accepts two environments dev and prod and prepares war file by taking configuration from appropriate folder. You can find a demo here. In case of questions, just ask.

P.S. Gradle has a bit different working model than ant, start with the basics. And what's important, never run a task from within other task.



来源:https://stackoverflow.com/questions/36278999/how-to-override-a-gradle-build-with-dev-prod-configuration

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!