bmuschko / gradle-cargo-plugin

Gradle plugin that provides deployment capabilities to local and remote containers via Cargo
Apache License 2.0
258 stars 63 forks source link

Support artifact dependency as alternative to local installer installUrl #171

Closed cschabl closed 5 years ago

cschabl commented 6 years ago

For local deployments cargo can be configured to download the Zip archive of the container and install it. Specifiying the location of the Zip archive as Gradle dependency instead of a URL would leverage Gradle's dependency caching for those container Zips available in artifact repositories (like Tomcat in Maven Central).

You can't use Gradle's offline mode with the installUrl.

davidfra commented 6 years ago

I could also need that feature. Currently I am using a customized tomcat zip which I uploaded in our companies maven repository server. It would be easier to reference it with dependency management. I saw that the maven cargo plugin can do that. Its called ArtifactInstaller

bmuschko commented 6 years ago

Happy to receive a contribution from the community! I'd probably expose a custom configuration that can be used to assign the ZIP file. That would automatically leverage Gradle's caching capabilities.

cschabl commented 6 years ago

I found a solution with Gradle's own scripting capabilities (though an enhancement of the cargo plugin would be better):

dependencies {
   ...
    archives "org.apache.tomcat:tomcat:8.0.53@zip"
}

cargo {
    containerId = 'tomcat8x'
    ...
    local {
            installer {
                // installUrl is set in TaskExecutionAdapter below from managed dependency
                downloadDir = file('./build/cargo-download')
                extractDir = file('./build/tomcat')
            }

}

task buildWarAndStartLocal(group: cargoStartLocal.group, dependsOn: cargoStartLocal) {
    project.gradle.addListener(new TaskExecutionAdapter() {
        void beforeExecute(Task task) {
            if (task.name == 'cargoStartLocal') {

                cargo.local.installer {
                    installUrl = "file:///" + configurations.archives.asList().find { it.canonicalPath.contains("tomcat") }
                }
           }
       }
   })

  cargoStartLocal.dependsOn war
}
cschabl commented 6 years ago

As an alternative to the property installUrl I'd like to introduce a property installDependency. Example:

cargo {
    containerId = 'tomcat8x'
    ...
    local {
            installer {
               installDependency "org.apache.tomcat:tomcat:8.0.53@zip"
            }

}

But I couldn't find anything in the Gradle API to resolve a single dependency literal!?

@bmuschko's proposal of a custom configuration seems to be the easiest way to go.

jutoft commented 5 years ago

I have a few proposals on how to fix this. All of them untested.

First

// create configruation for the zip installer dependency
configurations {
    javaeezip
}

// depend on apache tomcat
dependencies {
    javaeezip("org.apache.tomcat:tomcat:8.0.53@zip")
}

// download apache tomcat to cache before being referenced from installUrl
cargoStartLocal.dependsOn configurations.javaeezip

cargo {
    containerId = 'tomcat8x'
    ...
    local {
            installer {
               // this have to be setup after all the configuration setup cause it might be resolved right here.
                installUrl = configurations.javaeezip.singleFile
            }
}

Another solution is to let gradle extract the server instead of making cargo do it. It will extract the server every time.

// create configruation for the zip installer dependency
configurations {
    javaeezip
}

// depend on apache tomcat
dependencies {
    javaeezip("org.apache.tomcat:tomcat:8.0.53@zip")
}

// extract from zip, this could also be a sync task with excludes setup
task extractJavaee(type: Copy, dependsOn: configurations.javaeezip) {
    // {} is there to delay resolving the path until later.
    from({ zipTree(configurations.javaeezip.singleFile) })
    into("$buildDir/javaee/home")

    // you might have to drop the outer-most folder
   // eachFile {
     // path = path.replace('jboss-eap-6.4/', '')
   // }
      //includeEmptyDirs = false
}

// download apache tomcat to cache before being referenced from installUrl
cargoStartLocal.dependsOn extractJavaee

cargo {
    containerId = 'tomcat8x'
    ...
    local {
            homeDir = file("$buildDir/javaee/home")
}
cschabl commented 5 years ago

@jutoft, I tested your first solution and got a ProjectConfigurationException with cause:

groovy.lang.MissingPropertyException: Could not get unknown property 'javaeezip' for configuration container of type org.gradle.api.internal.artifacts.configurations

That's why I used a TaskExecutionAdapter in my work-around above. But the cargo-plugin itself probably could use configurations.javaeezip.singleFile if it finds a javaeezip dependency on execution.

bmuschko commented 5 years ago

@jutoft @cschabl The functionality has been provided by the PR https://github.com/bmuschko/gradle-cargo-plugin/pull/176.