Gradle zip task with lazy include property includes itself

Hi I got this zip task which works great:

def dir = new File("${projectDir.parentFile}/test/")

task testZip(type: Zip) {
    from dir
    destinationDirectory = dir
    include 'toast/**'
    
    archiveFileName = 'test.zip'
}

but then when I make the include property lazy (because I need to in my real case)

def dir = new File("${projectDir.parentFile}/test/")

task testZip(type: Zip) {
    from dir
    destinationDirectory = dir
    include {
        'toast/**'
    }
    
    archiveFileName = 'test.zip'
}

then it creates a zip that includes everything in the folder, (so the generated archive too). In this test case the inner zip is just corrupted (doesn’t run infinitely) but in the real world case it does make an infinite zip. (Not sure why, maybe my best case has too few or small files). Either way the test case shows the problem, the generated zip contains a zip even though it should only contain the toast directory and all of its content.

How do I fix this? I need a lazy include because the directory I want to include is computed by other tasks. I get the exact same problem with Tar except it refuses to create the archive since it includes itself.

Using exclude '*.zip' is a dumb workaround which makes the archive include other folders I don’t want. I only want to include a specific folder, lazyly.

Here’s what the monster looks like in the real world case. I basically need to retrieve the version of the project from Java to then use that version to name the folders I’m packaging. (Making a libGDX game and packaging it with a jre using packr). The problematic tasks are 'makeArchive_' + platform.


String jumpaiVersion;

task fetchVersion(type: JavaExec) {
    outputs.upToDateWhen { jumpaiVersion != null }

    main = 'net.jumpai.Version'
    classpath = sourceSets.main.runtimeClasspath
    standardOutput new ByteArrayOutputStream()
    doLast {
        jumpaiVersion = standardOutput.toString().replaceAll("\\s+", "")
    }
}

def names = [
    'win64' : "Jumpai-%%VERSION%%-Windows-64Bit",
    'win32' : "Jumpai-%%VERSION%%-Windows-32Bit",
    'linux64' : "Jumpai-%%VERSION%%-Linux-64Bit",
    'linux32' : "Jumpai-%%VERSION%%-Linux-32Bit",
    'mac' : "Jumpai-%%VERSION%%-Mac.app"
]

def platforms = names.keySet() as String[]

def jdks = [
    'win64' : 'https://cdn.azul.com/zulu/bin/zulu9.0.7.1-jdk9.0.7-win_x64.zip',
    'win32' : 'https://cdn.azul.com/zulu/bin/zulu9.0.7.1-jdk9.0.7-win_i686.zip',
    'linux64' : 'https://cdn.azul.com/zulu/bin/zulu9.0.7.1-jdk9.0.7-linux_x64.tar.gz',
    'linux32' : 'https://cdn.azul.com/zulu/bin/zulu9.0.7.1-jdk9.0.7-linux_i686.tar.gz',
    'mac' : 'https://cdn.azul.com/zulu/bin/zulu9.0.7.1-jdk9.0.7-macosx_x64.zip'
]

def formats = [
    'win64' : 'ZIP',
    'win32' : 'ZIP',
    'linux64' : 'TAR_GZ',
    'linux32' : 'TAR_GZ',
    'mac' : 'ZIP'
]
File jdksDir = new File(project.buildscript.sourceFile.parentFile.parentFile, 'out/jdks')
File gameJar = new File("${projectDir.parentFile}/desktop/build/libs/Jumpai.jar")
File gameData = new File("${projectDir.parentFile}/desktop/build/libs/Jumpai.data")

File packrDir = new File("${projectDir.parentFile}/out/packr/")

File minimalTmpDir = new File("${projectDir.parentFile}/desktop/build/libs/minimal-tmp")

task minimizeGameJar {
    dependsOn ':desktop:dist'
    doFirst {
        minimalTmpDir.mkdirs()
        copy {
            from zipTree(gameJar)
            into minimalTmpDir
        }

        for(file in minimalTmpDir.listFiles())
            if(file.getName().contains("humble"))
                file.delete()
    }
}

task makeMinimal(type: Zip) {
    dependsOn minimizeGameJar
    dependsOn fetchVersion

    from minimalTmpDir
    include '**'
    archiveFileName = provider {
        "Jumpai-${->jumpaiVersion}-Minimal.jar"
    }
    destinationDir packrDir

    doLast {
        minimalTmpDir.deleteDir()
    }
}

task copyGameJar(type: Copy) {
    outputs.upToDateWhen { gameData.exists() }

    dependsOn ':desktop:dist'
    from gameJar.getAbsolutePath()
    into gameData.getParentFile()
    rename("Jumpai.jar", "Jumpai.data")
}

task setWindowsIcons(type: Exec) {
    dependsOn fetchVersion
    workingDir '.'
    commandLine 'cmd', '/c', 'set_windows_icons.bat', "${->jumpaiVersion}"
}

for(platform in platforms) {
    task("getJdk_" + platform) {
        String url = jdks[platform]
        File jdkDir = new File(jdksDir, platform + "-jdk")
        File jdkFile = new File(jdkDir, url.split("/").last())
        outputs.upToDateWhen { jdkFile.exists() }

        doFirst {

            if(!jdkDir.exists())
                jdkDir.mkdirs()

            if(jdkFile.exists())
            {
                println jdkFile.getName() + " is already present"
                return
            }
            else
            {
                println "Downloading " + jdkFile.getName()
                new URL(url).withInputStream {
                    i -> jdkFile.withOutputStream { it << i }
                }
            }

            for(file in jdkDir.listFiles()) {
                if(file.equals(jdkFile))
                    continue

                if(file.isFile()) {
                    if (!file.delete())
                        println "ERROR: could not delete " + file.getAbsoluteFile()
                } else if(!file.deleteDir())
                    println "ERROR: could not delete content of " + file.getAbsoluteFile()
            }

            if(url.endsWith(".tar.gz"))// don't mix up archive type of what we downloaded vs archive type of what we compress (in formats)
            {
                copy {
                    from tarTree(resources.gzip(jdkFile))
                    into jdkDir
                }
            }
            else if(url.endsWith(".zip"))
            {
                copy {
                    from zipTree(jdkFile)
                    into jdkDir
                }
            }
        }
    }

    File packrInDir = new File(packrDir, platform)
    String platformRawName = names[platform]

    task("packr_" + platform, type: JavaExec) {
        outputs.upToDateWhen { new File(packrDir, platformRawName.replace("%%VERSION%%", jumpaiVersion)).exists() }

        dependsOn fetchVersion
        dependsOn copyGameJar
        dependsOn 'getJdk_' + platform

        main = 'com.badlogicgames.packr.Packr'
        classpath = sourceSets.main.runtimeClasspath
        args 'tools/res/packr_config/' + platform + '.json'

        workingDir = project.buildscript.sourceFile.parentFile.parentFile
        doLast {
            File packrOutDir = new File(packrDir, platformRawName.replace("%%VERSION%%", jumpaiVersion));
            packrOutDir.deleteDir()

            if(packrOutDir.exists())
            {
                println "ERROR Could not delete packr output " + packrOutDir.getAbsolutePath()
                return
            }

            if(!packrInDir.renameTo(packrOutDir))
                println "ERROR Could not rename packr output dir for " + packrInDir.getName()
        }
    }

    if(formats[platform] == 'ZIP')
    {
        task('makeArchive_' + platform, type: Zip) {
            if(platform.contains("win"))
                dependsOn setWindowsIcons
            dependsOn fetchVersion
            dependsOn 'packr_' + platform
            
            from packrDir
            destinationDirectory = packrDir

            include {
                platformRawName.replace("%%VERSION%%", jumpaiVersion) + "/"
            }
            
            archiveFileName = provider {
                platformRawName.replace("%%VERSION%%", jumpaiVersion) + ".zip"
            }
        }
    }
    else if(formats[platform] == 'TAR_GZ')
    {
        task('makeArchive_' + platform, type: Tar) {
            dependsOn 'packr_' + platform
            from packrDir
            destinationDirectory = packrDir
            include {
                platformRawName.replace("%%VERSION%%", jumpaiVersion) + '/**'
            }
            archiveFileName = provider {
                platformRawName.replace("%%VERSION%%", jumpaiVersion) + ".tar.gz"
            }
            extension 'tar'
            compression = Compression.GZIP
        }
    }
    else
        println 'Unsupported format for ' + platform
}

task deploy {
    dependsOn makeMinimal
    for(platform in platforms)
        dependsOn 'makeArchive_' + platform
}