Jazzschmidt Jazzschmidt - 1 year ago 77
Groovy Question

Apply external Plugin to a subset of subprojects

I am using the Gradle SSH Plugin to deploy some, but not all subprojects to two different remote machines. I want to configure these remotes in the main build script to avoid duplication, but cannot apply the plugin as per this:

configure([
project(':Subproject1'), project(':Subproject5'), project(':Subproject7')
])
{
buildscript {
dependencies {
classpath 'org.hidetake:gradle-ssh-plugin:2.4.2'
}
}

apply plugin: "org.hidetake.ssh"

ssh.settings {
user = getProperty('ssh.username')
identity = file(getProperty('ssh.identity'))
knownHosts = allowAnyHosts
}

remotes {
tomcat {
host = getProperty('ssh.hosts.tomcat')
}
jboss {
host = getProperty('ssh.hosts.jboss')
}
}
}


Gradle fails with
> Plugin with id 'org.hidetake.ssh' not found
.

Everything is fine when the contents of the configuration closure are applied per project. How can I elegantly solve this issue?

Answer Source

Guessing here as I haven't reproduced your issue, but the buildscript block is special as it is pre-parsed before normal groovy parsing of the build files and I suspect that having it inside a project block like you have will not work.

Have you tried moving the buildscript block to the root level in the script above?

edit 1: old gradle forums post discussion this can be found here

edit 2: adding a snippet of code in response to a comment.

To remove duplication and only define say the repository references in one place, you could use the following pattern:

buildscript {
  ext.RepositoryConfigurator = {
    maven {
      credentials.username artifactoryReader
      credentials.password artifactoryReaderPwd
      url                  artifactoryReaderUrl
    }
    jcenter()
    mavenCentral()
  }

  ext.DependencyConfigurator = {
    classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:1.2"
  }

  ext.ResolutionConfigurator = {
    resolutionStrategy.cacheChangingModulesFor 60, 'minutes'
  }

  repositories             RepositoryConfigurator
  dependencies             DependencyConfigurator
  configurations.classpath ResolutionConfigurator
}

apply plugin: "some.plugin.requiring.above.classpath"

gradle.rootProject {
  buildscript { 
    repositories             RepositoryConfigurator
    dependencies             DependencyConfigurator
    configurations.classpath ResolutionConfigurator
  }
}

gradle.allprojects {  
  buildscript { 
    repositories             RepositoryConfigurator
    dependencies             DependencyConfigurator
    configurations.classpath ResolutionConfigurator
  }
}

In other words: since the buildscript block is special and pre-parsed, you can not use things defined elsewhere in the buildscript block. Going in the other direction is ok though, i.e. you can define things in the buildscript block which are then visible elsewhere. We can use this to define the repository references once inside the buildscript block and then use that reference in other places in the build file.

The above is from a settings.gradle file so might or might not be a perfect fit, but should demonstrate the idea.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download