How to copy dependencies to directories per configuration?

Hello,
I need to copy dependencies of gradle plugins (quality plugins like pmd, jacoco, etc.) and utils to different directories to use them on an offline station with flat directories declaration. I want them in separate directories to import them on demand and not in a fat directory.

1/ Why the script below doesn’t work? Actually, it creates only “testng” directory (last in alphabetical order) and copy all dependencies in. And I see all the configurations go through the “println” so I know it iterate over the configurations.
I’m sure it’s just a typo in Groovy but I can’t figure it out.

repositories {
    jcenter()
}

configurations {
    // Utils
    sl4j
    // Tests
    junit
    testng
    // Quality from Gradle plugins
    pmd
    findbugs
    jdepend
    //jacoco
    checkstyle
}

dependencies {
    // Utils
    sl4j 'org.slf4j:slf4j-api:1.7.18'
    // Tests
    junit 'junit:junit:4.12'
    testng 'org.testng:testng:6.9.10'
    // Quality from Gradle plugins
    pmd 'net.sourceforge.pmd:pmd-core:5.2.3'
    pmd 'net.sourceforge.pmd:pmd-java:5.2.3'
    findbugs 'com.google.code.findbugs:findbugs:3.0.1'
    jdepend 'org.apache.ant:ant-jdepend:1.9.4'
    //jacoco 'org.jacoco:jacoco:0.7.5.201505241946'
    checkstyle 'com.puppycrawl.tools:checkstyle:5.9'
}

task copyDependencies(type: Copy) {
    configurations.all {
        config ->
            println config.name
            from config
            into config.name
    }
}

2/ Is there a better way to get the dependencies of a plugin than activate it on the offline machine, check what Graddle try to download and add it to the script on the online machine?

3/ The jacoco plugin doesn’t work, I need to download the jacoco-0.7.6.201602180812.zip and expand it in a directory cause the download on jcenter miss doc and examples. Any idea?

Thank you!

Firstly have you looked at Ivypot plugin? It might cover your use case.

Question 1:

task copyDependencies(type: Copy) {
  into 'offlineDir'
  project.configurations.each { cfg ->
        into cfg.name, {
                from cfg
        }
  }
}

Question 3: Have you tried to add @zip in your dependency?

Thank you!

I didn’t know Ivypot, I go to check and test it, seems exactly what I need.

The code you wrote for Q1 do the job but even with https://docs.gradle.org/current/javadoc/org/gradle/api/tasks/AbstractCopyTask.html#into(java.lang.Object) I’m a bit confuse on the structure. Probably the groovy syntax that I’m not used to.

For Q3, it works but anything else than https://docs.gradle.org/current/javadoc/org/gradle/api/artifacts/dsl/DependencyHandler.html to explain why the zip extension, any reference to digg? Maybe there is some extension that I don’t know. I didn’t know the @notation for extension, did I miss a link in documentation?

Anyway, thank you again!

Not too worry, the CopySpec notation catches me out every now an dthen and I use it quite a bit!

Normally one supplies a top-level into for the Copy task. This tell it the root folder to copy to. Then you can use the into( Object, Closure) notation (see Copy task for info) to add child copy specs which will write into subfolders. You should also read up on Copy.with. Usually in Groovy with is just a delegate closure to object it is atatched to, but in Copy it behaves differently. There it allows you to attach a CopySpec as a child of the parent that is the Copy task. It can also be used to copy into subfolders.

That information is remarkably hard to find. You may catch the clues here:

but, the best is to read this one:

All is working now, thanks to your plugin.

Here is the result, if someone have the same issue…

plugins {
    id "org.ysb33r.ivypot" version "0.3.7"
}
repositories {
    jcenter()
}
configurations {
    // All dependencies that goes to the Ivy repository format
    compile

    // Gradle quality plugins that goes to flatDir
    pmd
    findbugs
    jdepend
    jacoco
    checkstyle
}

dependencies {
    // Logs
    compile 'log4j:log4j:1.2.16'
    compile 'org.slf4j:slf4j-api:1.7.18'
    // Tests
    compile 'junit:junit:4.12'
    compile 'junit:junit:4.11'
    compile 'org.hamcrest:hamcrest-core:1.3'
    compile 'org.mockito:mockito-all:1.9.5'
    compile 'org.testng:testng:6.9.10'
    compile 'org.apache.poi:poi:3.14'

    // Quality from Gradle plugins
    pmd 'net.sourceforge.pmd:pmd-java:5.2.3'
    findbugs 'com.google.code.findbugs:findbugs:3.0.1'
    jdepend 'jdepend:jdepend:2.9.1'
    jdepend 'org.apache.ant:ant-jdepend:1.9.6'
    jacoco 'org.jacoco:org.jacoco.report:0.7.6.201602180812'
    jacoco 'org.jacoco:org.jacoco.ant:0.7.6.201602180812'
    jacoco 'org.ow2.asm:asm-tree:5.0.2'
    jacoco 'org.ow2.asm:asm-commons:5.0.2'
    checkstyle 'com.puppycrawl.tools:checkstyle:5.9'
}

task syncFlatRepositories(type: Copy) {
    into '/tmp/flat'
    project.configurations.each { cfg ->
        if (cfg.name != "compile") {
            into cfg.name, {
                from cfg
            }
        }
    }
}

syncRemoteRepositories {
    repoRoot '/tmp/ivy'
    repositories {
        jcenter()
    }
    configurations 'compile'
    includeBuildScriptDependencies = false
}

I have some problems with the plugins if I try to use the Ivy part so I need to keep them in flat directories and use them with, for example

pmd fileTree(dir: "/my/path/pmd", include:["*.jar"])

Probably a better way to do it if I find answer to Q2.

I’ve some issues with the plugin but I switch to github to talk, here is not the right place :slight_smile:

Feel free to raise issues on Github for your use cases. There are definitely some corner cases that the plugin cannot handle at the moment.

If you want to use plugins offline, don’t use the plugins {} syntax. Rather use the old buildscript {} syntax. Here are examples of how to it was accomplished:

BTW If a plugin pulls down additional dependencies during task execution, then we are on a different playing field. Some of them can be handled (i.e. jruby-gradle-base & the latest ascidoctor, but some plugins assume that you will be online). If you have any of those you can raise them on Github and I’ll have a look.