# Simple zip creation with dependencies

**URL:** <https://discuss.gradle.org/t/simple-zip-creation-with-dependencies/12083>\
**Category:** Help/Discuss\
**Created:** [October 8, 2015, 1:20am UTC](https://discuss.gradle.org/t/simple-zip-creation-with-dependencies/12083 "2015-10-08T01:20:41Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![mbratch](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/mbratch/32/3227_2.png) [@mbratch](https://discuss.gradle.org/u/mbratch)\
**Post date:** [October 8, 2015, 1:20am UTC](https://discuss.gradle.org/t/simple-zip-creation-with-dependencies/12083/1 "2015-10-08T01:20:41Z")

</div>

I would like to define a task (we’ll call “zip”) that creates a zip file containing my assembled jar file, some config files, and some doc files. Further, I want to gather these files into the zip and have the zip have a single folder path to these files.

Here is what my tasks look like:

```
// Gather the dist files to a single folder
task copyDistFiles(type: Copy, dependsOn: assemble) {
    from "${libsDir}" // jar file(s)
    from 'doc' // doc file(s)
    from 'config' // config file(s)
    into "${buildDir}/dist_files"
}

// zip (into my_files.zip) the dist files and include the first level folder name
task zip(type: Zip, dependsOn: copyDistFiles) {
    baseName = 'my_files'
    from buildDir
    include 'dist_files/*'
}

build.dependsOn zip

```

This basically works for me. When I do a `gradle -q build`, the `build` dependency results in the files being copied and the zip being created as I want it. The zip file is located in `build/distributions/my_files.zip` and it contains `dist_files/*` where `*` are the files I want.

I have now two questions:

1. What I really want is for the `dist_files` folder in my build directory to be temporary. After the `zip` file is created in `build/distributions` I don’t need that folder around. I can add some code to delete the folder, but is there a more canonical way to do this?

2. Originally, I had the above tasks defined with `<< {` rather than just `{`. I know that `<< {` is shorthand for `doLast` and occurs at execution time, whereas, as shown above, the task contents run at configuration time. What is confusing to me is that when I use `<< {`, the dependency doesn’t seem to work. If I do `gradle -q build`, `gradle` will say that the zip file is up to date even if it hasn’t been created yet. Why is that so?

---

<div class="post-metadata">

**Author:** ![sterling](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/sterling/32/5395_2.png) [@sterling](https://discuss.gradle.org/u/sterling)\
**Post date:** [October 8, 2015, 1:32am UTC](https://discuss.gradle.org/t/simple-zip-creation-with-dependencies/12083/2 "2015-10-08T01:32:39Z")

</div>

[Zip](https://docs.gradle.org/current/dsl/org.gradle.api.tasks.bundling.Zip.html) has a similar API to [Copy](https://docs.gradle.org/current/dsl/org.gradle.api.tasks.Copy.html), so you can skip copying to an intermediate directory first by configuring the zip task the same way as you would the copy task. You don’t need to specify a destination (an ‘into’) because it defaults to the root of the archive.

If your jar is coming from the `jar` task, you can just say:

```gradle
task zip(type: Zip) {
   from jar
   from 'doc'
   from 'config'
}

```

`zip` will automatically depend on `jar`

Your task is considered up-to-date when you use `doLast` because the task has an empty list of inputs when we’re deciding to execute the task. And for this particular type of task, the inputs are marked as [SkipWhenEmpty](https://docs.gradle.org/current/javadoc/org/gradle/api/tasks/SkipWhenEmpty.html).

---

<div class="post-metadata">

**Author:** ![mbratch](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/mbratch/32/3227_2.png) [@mbratch](https://discuss.gradle.org/u/mbratch)\
**Post date:** [October 8, 2015, 1:38am UTC](https://discuss.gradle.org/t/simple-zip-creation-with-dependencies/12083/3 "2015-10-08T01:38:57Z")

</div>

Thanks for the prompt reply.  
That worked great, and makes perfect sense.

What determines the “list of inputs” for these particular tasks? I thought that since what they depend upon had changed, the `doLast` block would execute.

---

<div class="post-metadata">

**Author:** ![jjustinic](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/jjustinic/32/9005_2.png) [@jjustinic](https://discuss.gradle.org/u/jjustinic)\
**Post date:** [October 8, 2015, 3:05am UTC](https://discuss.gradle.org/t/simple-zip-creation-with-dependencies/12083/4 "2015-10-08T03:05:24Z")

</div>

> [@mbratch](#):
>
> What determines the “list of inputs” for these particular tasks? I thought that since what they depend upon had changed, the doLast block would execute.

The list of inputs are the locations that are specified with each `from`, but the problem was timing.

The `doLast {...}` block adds a TaskAction which runs in the execution phase. Additionally, the Copy and Zip tasks already implement their own TaskAction which does the actual Copy / Zip work in the execution phase.

You have a chicken and egg problem if you configure the things that determine if the task should run in the phase that actually executes the actions. Your TaskAction won’t run to configure the task inputs unless the inputs have changed, but you have no inputs unless the TaskAction runs.

---

<div class="post-metadata">

**Author:** ![mbratch](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/mbratch/32/3227_2.png) [@mbratch](https://discuss.gradle.org/u/mbratch)\
**Post date:** [October 8, 2015, 10:34am UTC](https://discuss.gradle.org/t/simple-zip-creation-with-dependencies/12083/5 "2015-10-08T10:34:14Z")

</div>

Thank you. That makes sense. I’ve been reading the Gradle documentation online, particularly the discussion on the build lifecycle, but how the pre-defined tasks work has still been a little mysterious to me. This helped a lot.
