用Gradle过滤Java类

Mir*_*rco 5 java regex filtering gradle

我在src / main / java / com / company / project / Config.java中有以下课程:

public class Config {

  public static final boolean DEBUG = true;

  ...
}
Run Code Online (Sandbox Code Playgroud)

因此,在其他某个类中,我可以知道Java编译器在评估结果为false时会剥离if()语句,从而可以执行以下操作:

import static com.company.project.Config.DEBUG

if (DEBUG) {
  client.sendMessage("something");

  log.debug("something");
}
Run Code Online (Sandbox Code Playgroud)

在Gradle中,什么是在编译时过滤和更改Config.java中的DEBUG值而不修改原始文件的最佳方法?

到目前为止,我在想:

  1. 创建一个任务updateDebug(type:Copy)来过滤DEBUG并将Config.java复制到一个临时位置
  2. 从sourceSets排除原始Config.java文件,并包含临时文件
  3. 使compileJava.dependsOn updateDebug

以上可能吗?有没有更好的办法?

Mir*_*rco 3

要回答我自己的问题,给定类 src/main/java/com/company/project/Config.java:

public class Config {

  public static final boolean DEBUG = true;

  ...
}
Run Code Online (Sandbox Code Playgroud)

这是我想出的 Gradle 代码:

//
// Command line: gradle war -Production
//
boolean production = hasProperty("roduction");

//
// Import java regex
//
import java.util.regex.*

//
// Change Config.java DEBUG value based on the build type
//
String filterDebugHelper(String line) {
  Pattern pattern = Pattern.compile("(boolean\\s+DEBUG\\s*=\\s*)(true|false)(\\s*;)");
  Matcher matcher = pattern.matcher(line);
  if (matcher.find()) {
    line = matcher.replaceFirst("\$1"+(production? "false": "true")+"\$3");
  }

  return (line);
}

//
// Filter Config.java and inizialize 'DEBUG' according to the current build type
//
task filterDebug(type: Copy) {
  from ("${projectDir}/src/main/java/com/company/project") {
    include "Config.java"

    filter { String line -> filterDebugHelper(line) }
  }
  into "${buildDir}/tmp/filterJava"
}

//
// Remove from compilation the original Config.java and add the filtered one
//
sourceSets {
  main {
    java {
      srcDirs ("${projectDir}/src/main/java", "${buildDir}/tmp/filterJava")
      exclude ("com/company/project/Config.java")
    }

    resources {
    }
  }
}

//
// Execute 'filterDebug' task before compiling 
//
compileJava {
  dependsOn filterDebug
}
Run Code Online (Sandbox Code Playgroud)

诚然,这有点hacky,但它确实有效,它为我提供了最有效的解决方案,同时仍然从单个入口点(build.gradle)控制开发/生产构建。