Code review for multiple repository plugin


(sethgoings) #1

Hey all - I respect the Gradle community a lot when it comes to design/architectural decisions (especially those of the build domain type). I have an interesting problem I’d like to pose to the Gradle community…

Let’s say you have a project that lives in two places: (1) a public git repository, and (2) a private/internal git repository. These two repositories’ master branches are manually sync’d at appropriate times.

How do you build a build system in that project that:

  • doesn’t hold any internal repository information in the actual project you’ve open sourced but yet you still can publish the project’s artifacts to either Maven Central or an internal artifact repository (or both) - not have to deal with multiple build/deployment systems (or at least share a great deal of build/publishing/software deployment logic) - make sure we can take advantage of pulling down dependencies from Maven Central outside of my company’s infrastructure, but use our own proxy when builds are run internally

Here’s my stab at a plugin implementation: https://github.com/ReadyTalk/gradle-readytalk-plugin

I figured for the internal artifact repository case I’d take advantage of init scripts. My init script internally looks something like this:

allprojects {
  ext.artifactory_username = "<artifactory username>"
  ext.artifactory_password = "<artifactory password>"
  ext.oss_sonatype_username = "<oss sonatype username>"
  ext.oss_sonatype_password = "<oss sonatype password>"
  ext.artifactory_root = "<internal artifactory instance>"
  ext.artifactory_main = "<artifactory main resolution url>"
  ext.local_root = "/home/${artifactory_username}/.ivy2/local"
    ext.<company>_repo = {
    url artifactory_main
    credentials {
      username = artifactory_username
      password = artifactory_password
    }
  }
    ext.local_repo = {
    name = '<company>_init_local'
    url local_root
    layout "maven"
  }
    buildscript {
    repositories {
      ivy local_repo
      ivy(<company>_repo).name = '<company>_init_ivy_main'
      maven(<company>_repo).name = '<company>_init_maven_main'
    }
  }
}

With this implementation, I can easily switch on/off internal/external publishing of projects and reliance on internal artifact repositories and also enable projects to be built by the open source community by relying on Maven Central.

  • What do you guys think of this? Did I overlook an easier solution? - I plan on extending this plugin a bit more so that I can promote modules to releases (promote in repository managers and create branches/tags in Git) all from simple commands via the terminal. Is there something that could help me out there (besides using the REST API for Artifactory/Sonatype)? - How can I better architect this plugin? I essentially have plugins which do two things:

  • initialize tasks

  • create/manage both resolve and publish repositories for me.

    Is there an easier, more coherent way to divide up these concerns using the Gradle API?