问题
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:
- a common script with the standard tasks (compile, build-jar, build-war)
- 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:
- specify the parent (it's a project property) dir that contains the env dir/files
- 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