Legato
Legato

Reputation: 1081

Gradle distribution - create an empty directory

Is there a way to add empty directories (e.g, "logs") when creating a distribution with the gradle distribution plugin?

I saw this JIRA, describing the exact same thing. It is still open https://issues.gradle.org/browse/GRADLE-1671

I wonder if there are any workarounds I can use. I don't quite understand the workarounds described in the jira.

Thank you.

Upvotes: 7

Views: 14985

Answers (3)

kevinmm
kevinmm

Reputation: 3376

This seems odd answering this so late. But, there are 2 issues here.

  1. We should really avoid creating empty directories. But, if we must...we must.
  2. The previous examples attempt to create empty directories outside of the current project, which seems to go against the goal of most builds. We can avoid this and work more naturally within gradle by adding a custom task.
    plugins {
        id 'java'
        id 'distribution'
    }
    
    group 'org.example'
    version '1.0-SNAPSHOT'
    
    task createEmptyLogDir() {
        ext {
            buildDir = layout.buildDirectory.dir('empty_dirs')
        }
        doFirst {
            File.createTempDir().with {
                def dir = new File(buildDir.get().asFile, 'logs')
                dir.mkdirs()
            }
        }
        outputs.dir(buildDir)
    }
    
    tasks.assembleDist.configure {
        dependsOn('createEmptyLogDir')
    }
    
    distributions {
        main {
            distributionBaseName = 'app'
            contents {
                into('lib') {
                    from tasks.jar 
                }
                from tasks.createEmptyLogDir {
                    includeEmptyDirs = true
                }
            }
        }
    }

This has the advantage of building within the build directory, using task inputs/outputs for up-to-date checks, and cleaning up.

An important note is that we cannot just create the distribution with empty directories, alone. This will be seen as no source and up-to-date. So, I added the jar in this example. Tested with gradle 7.1.

Upvotes: 2

Christian
Christian

Reputation: 309

Based on Logato's own answer I've come up with the following code, which is more elegant and also closes the file pointer correctly (using the with context):

distributions {
    main {
        baseName = 'app'
        contents {
            into('') {
                File.createTempDir().with {
                    def tmpLog = new File(absolutePath, 'logs')
                    println tmpLog.absolutePath
                    tmpLog.mkdirs()
                    from (absolutePath) {
                        includeEmptyDirs = true
                    }
                }
                // ...
            }
            // ...
        }
    }
}

Upvotes: 2

Legato
Legato

Reputation: 1081

So I managed to work around this by following the suggestion in the mentioned JIRA to create a dummy empty directory and then copy it to the distribution location.

It's ugly but works. I'm sure it can be written more efficiently though. This is the Copy block from inside distributions/main/contents:

into('') {
    //create an empty 'logs' directory in distribution root
    def logDirBase = new File('/tmp/app-dummy-dir')
    logDirBase.mkdirs()
    def logDir = new File(logDirBase.absolutePath + '/logs')
    logDir.mkdirs()

    from {logDirBase}
}

Upvotes: 9

Related Questions