Gradle构建中替换文件

5

我正在尝试用Gradle构建脚本生成的新文件替换资源文件夹(src/main/resources)中的文件。 我在做这件事时遇到了麻烦; 排除好像被记住了,从而阻止了我的新文件添加。

以下是说明此行为的简短示例。

项目结构:

TestProject
-- src/main/java
---- entry
------ EntryPoint.java
---- run
------ HelloWorldTest.java
-- src/main/resources
---- test.properties // FILE TO REPLACE

src/main/resources中的test.properties文件内容如下:

错误的文件,带有额外的文本以便于根据大小判断它被放入了JAR文件

build.gradle:

apply plugin: 'java'

task makeProp {
    def propDir = new File(buildDir, "props")
    ext.propFile = new File(propDir, "test.properties")
    outputs.file propFile

    doLast {
        propDir.mkdirs()
        propFile.createNewFile()
        propFile.withWriter('utf-8') { writer ->
            writer.writeLine 'Right File'
        }
    }
}

jar {
    dependsOn('makeProp')

    if (project.hasProperty('testExclude')) {
        sourceSets {
            exclude('test.properties')
        }
    }

    from (makeProp.propFile) {
        into '/'
    }
}

./gradlew build 命令生成的 JAR 文件内容(包含两个文件):

Archive:  TestProject.jar
  Length     Date   Time    Name
 --------    ----   ----    ----
        0  08-07-15 14:27   META-INF/
       25  08-07-15 14:27   META-INF/MANIFEST.MF
        0  08-07-15 13:50   run/
      499  08-07-15 13:50   run/HelloWorldTest.class
        0  08-07-15 13:50   entry/
     1413  08-07-15 13:50   entry/EntryPoint.class
       95  08-07-15 14:27   test.properties
       11  08-07-15 14:03   test.properties
 --------                   -------
     2043                   8 files

./gradlew build -PtestExclude 命令生成的 JAR 包内容(未包含任何文件):

Archive:  TestProject.jar
  Length     Date   Time    Name
 --------    ----   ----    ----
        0  08-07-15 14:29   META-INF/
       25  08-07-15 14:29   META-INF/MANIFEST.MF
        0  08-07-15 13:50   run/
      499  08-07-15 13:50   run/HelloWorldTest.class
        0  08-07-15 13:50   entry/
     1413  08-07-15 13:50   entry/EntryPoint.class
 --------                   -------
     1937                   6 files
3个回答

5

我曾经做过非常类似的事情,以下是我的解决方法。主要目标是确保任务在您的jar文件被创建和文件被处理之前运行。请尝试此方法。

    // create a properties file add it to folder preprocessing
    task propertiesFile << {
        // 
        description 'Dynamically creates a properties file.'

        // needed for the first pass
        def folder = project.file('src/main/resources');
        if(!folder.exists()){
            folder.mkdirs()
        }

        //write it to a propertiess file
        def props = project.file('src/main/resources/test.properties')
        props.delete()
        props << 'write this to my file!!!!'

    }

    processResources.dependsOn propertiesFile

我最终做了类似于这样的事情。我接受了这个答案,并跟着我的答案。我希望有一个更直接的解决方案,而不是基本上绕过他们的排除机制,但我相信机制工作的方式一定有一些合理的原因,对于像我这样的构建新手来说无法想到。 - Ironcache

2

最终我选择的解决方案与Pumphouse发布的类似,但不是删除文件,而是将其重命名为临时名称,将该临时名称排除在外,并在构建完成后将其重命名(我需要在构建完成后保留文件内容和位置)。

修改后的build.gradle:

apply plugin: 'java'

def props = project.file('src/main/resources/test.properties')
def temp = project.file('src/main/resources/temp.properties')

task makeProp {
    ... // Unchanged
}

jar {
    dependsOn('makeProp')

    // Move the properties file to a temp location
    props.renameTo(temp) // This returns a boolean; can perform conditional checks.

    // Exclude the temp file
    if (project.hasProperty('testExclude')) {
        sourceSets {
            exclude('temp.properties')
        }
    }

    // Insert the right prop file
    from (makeProp.propFile) {
        into '/'
    }
}
jar << {
    // Restore the temp file
    temp.renameTo(props)
}

1
事实上,Gradle的SourceSet排除模式适用于所有包含的路径,而不仅仅是特定的路径。因此,在您上面的示例中,所有名为test.properties的文件都将被排除,无论它们的位置如何。
您可以做的是将默认的test.properties放在其他地方,并使构建基于情况复制/生成相关版本。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接