AndyJ
AndyJ

Reputation: 1314

How can I create a zip in gradle from a list of files?

This is most certainly a gradle newbie question but it's really beating me up. My source tree looks like this:

|-- master
    buildSrc
    build.gradle
|-- comp1
    !-- filea
    !-- fileb
|-- comp2
    !-- file1
    !-- file2
    !-- etc

I'm running the build.gradle in the master directory which uses a custom task (called in prepBundle (not shown)) to produce a list of files which need to be in a zip file. There is some various external processing that goes into the list so there isn't a way to use any basic includes or closures to come up with the list.

This is what I have:

task showFilelist(dependsOn:prepBundle){ 
  prepBundle.outputs.files.each{ 
    println "including file: ${it}"
  }
}

task createBundle(type:Zip,dependsOn:prepBundle){ 
  inputs.files(prepBundle.outputs.files)
  outputs.file(archiveName)
  baseName = "somebundle"
  from ".."
  include prepBundle.outputs.files
}

If I just run showFilelist, I do get the correctly resolved paths to the files I want to zip:

<snip>
:showFilelist
including file: C:\fullpath\master\build.gradle
including file: C:\fullpath\comp1\filea
including file: C:\fullpath\comp2\file1

But when I run my bundling task, it blows up:

:createBundle

FAILURE: Build aborted because of an internal error.

* What went wrong:
Build aborted because of an unexpected internal error. Please file an issue at: http://forums.gradle.org.

* Try:
Run with --debug option to get additional debug info.

* Exception is:
org.gradle.api.UncheckedIOException: java.io.IOException: The process cannot access the file because another process has locked a portion of the file
        at org.gradle.util.hash.HashUtil.createHash(HashUtil.java:56)
        at org.gradle.util.hash.HashUtil.createHash(HashUtil.java:34)
        at org.gradle.api.internal.changedetection.state.DefaultHasher.hash(DefaultHasher.java:24)
        at org.gradle.api.internal.changedetection.state.CachingHasher.hash(CachingHasher.java:45)
        at org.gradle.api.internal.changedetection.state.DefaultFileSnapshotter$1.run(DefaultFileSnapshotter.j
ava:48)
        at org.gradle.internal.Factories$1.create(Factories.java:22)
        at org.gradle.cache.internal.DefaultCacheAccess.useCache(DefaultCacheAccess.java:143)
        at org.gradle.cache.internal.DefaultCacheAccess.useCache(DefaultCacheAccess.java:131)
        at org.gradle.cache.internal.DefaultPersistentDirectoryStore.useCache(DefaultPersistentDirectoryStore.

In prepBundle I iterate the list of files and there isn't any file being used by another process. I don't believe it's a gradle problem, I think it's something I'm doing wrong with the configuration of the zip task. If I change the createBundle a bit to drop the inputs and outputs, it looks like this:

task createBundle(type:Zip,dependsOn:prepBundle){ 
  baseName = "somebundle"
  include prepBundle.outputs.files
}

But then doesn't do anything:

:createBundle UP-TO-DATE

BUILD SUCCESSFUL

How should I put this zip together when I just have a list of files and the parent root directory for the files are not under my current project?

Thanks for any help!

Upvotes: 10

Views: 25750

Answers (3)

Jorge Machado
Jorge Machado

Reputation: 772

Just for reference I have this and it works fine. (nar = jar) Without archiveName and destinationDir it does not work for me

task zip(type: Zip) {
    archiveName=rootProject.name+"-"+project.version+".zip"
    destinationDir = file('build/')
    project.subprojects.nar.outputs.files.files.each{
        from it.first().getPath()
    }
}

zip.dependsOn(subprojects.nar)

Upvotes: 0

ankit.ag.in
ankit.ag.in

Reputation: 171

You can easily create a zip file with a task, look at the example below:

task createDist(type: Zip){
  archiveName="dist.zip"
  destinationDir = file('build/')
  from (files('./test-module/build/libs'))
}

You can use variety of methods to include files here, e.g.:

 from fileTree('./libs')
 from project('config').jar.outputs.files
 from project('core').jar.outputs.files
 from project('batch-jobs').jar.outputs.files
 from project('gateway1').jar.outputs.files
 from project('gateway2').jar.outputs.files

Upvotes: 11

Peter
Peter

Reputation: 793

I'm not sure what the concrete problem behind is, but I assume that has to to with

inputs.files(prepBundle.outputs.files)

and/or (this is superfluous and can break things)

outputs.file(archiveName)

I guess, that you would like to add all files from prepBundle to your archive. This can be easily achieved when you use the from property of the inherited Copy task of the Zip task.

Using the from property will change your task to

task createBundle(type:Zip,dependsOn:prepBundle){ 
  prepBundle.outputs.files.each {
    from it.getPath() // adds every single file to the archive
  }
  baseName = "somebundle"
  from ".." // I assume that you add another path here not ".." 
}

As you can see I skipped also the include part and the output.file(..) because include property is superfluous when using from with an specific file. output.file(..) is superfluous because it's already defined by the Zip task.

Upvotes: 6

Related Questions