I want to make a gradle task to zip a subdirectory called pack from my resources folder, I am not very familiar with gradle, so sorry if this seems like something easy, so far I have this:
task genResourcePack(type: Zip) {
from sourceSets.main.resources
include '**/*'
archiveName 'pack.zip'
}
this zips my entire resources folder, which I do not want, I also tried doing this as well:
task genResourcePack(type: Zip) {
from sourceSets.main.resources.include('pack/')
include '**/*'
archiveName 'pack.zip'
}
which is a little better, but then the zip has a folder called pack at the top, and I want to flatten this folder, but not all the way, basically I want the from to target the subdirectory of pack directly.
I actually just found a solution to my problem, but it isn't particularly elegant so I'll keep this open in case someone has a better way. I replaced my from with the following line:
from sourceSets.main.resources.getSrcDirs()[0].toPath().resolve('pack')
Related
I have a multi-module project in Gradle
root
-- ProjectA
-- ProjectB
Both ProjectA and ProjectB use the application plugin to create a zip in "ProjectA/build/distributions" and "ProjectB/build/distributions" respectively.
Now I want to copy the two zip files into "root/build/distributions".
I have tried various approaches, e.g. adding this in the build.gradle of the root project:
subprojects {
task copyFiles(type: Copy) {
includeEmptyDirs = true
from "$buildDir/distributions"
include '*.zip'
into "$parent.buildDir/distributions"
}
copyFiles.dependsOn(build)
}
or just adding a task to the root project:
task copyFiles(type: Copy) {
from "ProjectA/build/distributions"
from "ProjectB/build/distributions"
include "*.zip"
into "$buildDir/distributions"
}
build.dependsOn(copyFiles)
However, in both cases, nothing happens. No file gets copied.
What am I doing wrong?
I can see two things you are doing wrong:
You have relative paths to the subprojects. This is discouraged as it means you will always have to invoke Gradle from the root folder. And if a Gradle daemon was started from somehere else, it will fail. You could fix it by using the rootDir property (e.g. `from "$rootDir/ProjectA/...") but there is a better way...
The other problem is that you have no dependencies from your copyFiles task in your root project to the required distZip tasks in the sub-projects. So if the distributions have not already been built previously, there are no guarantees that it will work (which it apparently doesn't).
To fix it, you can have a look at the question "Referencing the outputs of a task in another project in Gradle", which covers the more general use case of what you ask. There are currently two answers, both of which are good.
So in your case, you can probably do either this:
task copyFiles(type: Copy) {
from tasks.getByPath(":ProjectA:distZip").outputs
from tasks.getByPath(":ProjectB:distZip").outputs
into "$buildDir/distributions"
}
or this:
task copyFiles(type: Copy) {
subprojects {
from(tasks.withType(Zip)) {
include "*.zip"
}
}
into "$buildDir/distributions"
}
Gradle will implicitly make the copy task depend on the other tasks automatically, so you don't need to do that yourself.
Also note that the currently accepted answer to the question I referenced is about configuration variants, and this is probably the most correct way to model the relationships (see here for more documentation on the topic). But I prefer the simplicity of the direct access to the tasks over the verbose and arguably more complex way to model it through configurations. Let's hope it gets simpler in a later release.
When learning from the tutorial, I encountered a sample below:
task dist(type: Zip) {
dependsOn spiJar
from 'src/dist'
into('libs') {
from spiJar.archivePath // what's meaning
from configurations.runtime // what's meaning
}
}
artifacts {
archives dist
}
As a newbie to gradle, how to understand this into(...){ from ...}?
In this particular case:
from spiJar.archivePath
is probably (since I don't know what exactly spiJar is) resolved to the output of spiJar task - namely a jar archive - particular file.
When it comes to the second question configurations is (simplifying) is a map that matches given name - runtime in this case - with a group of dependencies (jar files in this case).
When:
from configurations.runtime
is used is copies all the dependencies from runtime configuration into given destination.
In addition to the previews answer, to, possibly, clarify a little. Due to dsl reference, Zip task provide the into(destPath, configureClosure) method, which:
Creates and configures a child CopySpec with a destination directory inside the archive for the files.
This means, that it could create an additional directory with the some content in it. In your case, script creates a libs directory within archive and specifies the resources, which should be copied into this directory. This resources could be out of the src/dist directory, which will be fully zipped into the archive's root.
Here is a dsl reference for CopySpec task, which is configured by the into method of the Zip task. As you can see, from just:
Specifies source files or directories for a copy.
The maven assembly plugin has an includeBaseDirectory option that (when set to false) avoids having a single top-level directory inside the tar/zip artifact with the same name as the artifact itself.
I'd like to achieve the same result with Gradle, but I don't see how. I'm using a configuration like this:
task distTar(type: Tar) {
compression Compression.GZIP
extension "tar.gz"
}
I don't see any options for the Tar task that do what I want. How can I exclude the base directory in my archive with Gradle?
By reconfiguring the distribution plugin (which gets implicitly applied by the application plugin) you can simply do (in Kotlin DSL):
distributions {
main {
contents {
into("/")
}
}
}
This affects the output in both Tar and Zip formats.
(Disclaimer: This answer is loosely based on this Gradle forum post).
Ok, I figured it out. It was simpler than I thought. To copy the library dependencies into lib at the root of the archive, I use a CopySpec:
task distTar(type: Tar) {
into('lib') {
from libsDir
include '*.jar'
}
}
Similar CopySpecs can be used to copy e.g. bin and conf directories.
I'm fairly new to Gradle, and trying to port an existing Maven pom.xml that makes extensive use of maven-assembly-plugin to create various zip files.
In the example below, I'm getting files from various subdirectories (with particular extensions), and then mapping them in a flat structure to a ZIP file.
task batchZip(type: Zip) {
from fileTree('src/main/sas') {
include('**/*.sas')
include('**/*.ds')
}.files
}
This puts all the files in the root of the zip. What I ideally need though, is for the files to live under a particular path in the root of the zip, e.g. /shared/sas.
Is there a way to do this without first copying all the files to a local directory and then zipping that up?
task batchZip(type: Zip) {
into('shared/sas') {
from { fileTree('src/main/sas').files }
include('**/*.sas')
include('**/*.ds')
}
}
Have a look at the docs. It seems that if You specify appropriate into You'll get the result You're looking for.
I can copy all the jars in dependency section for "compile" configuration like so
task('copyJars') {
ext.collection = files { genLibDir.listFiles() }
delete ext.collection
copy { from configurations.compile into genLibDir }
}
but how do I copy their source jar files somewhere?
thanks,
Dean
As of Gradle 1.0, I don't know of an easy way to deal with third-party sources Jars. You could add them as explicit dependencies (to a separate configuration) or maybe crawl the Gradle cache.
By the way, delete ext.collection is in the wrong spot. It will be executed in the configuration phase, and will delete files no matter which tasks are going to be executed. (Also listFiles() will get invoked for every build.)
Also, a task whose main purpose is copying should alway use the Copy task type rather than the copy method.