Avoid double-builds of the same change

When a change build is in progress, avoid rescheduling it
again.

Change-Id: Idfaf760b26a6fa3046ca5bc38688bba8367035f7
diff --git a/jenkins/gerrit-verifier-flow.groovy b/jenkins/gerrit-verifier-flow.groovy
index 2de10ad..ebd1c9a 100644
--- a/jenkins/gerrit-verifier-flow.groovy
+++ b/jenkins/gerrit-verifier-flow.groovy
@@ -33,6 +33,7 @@
   static int myAccountId = 1022687
   static int waitForResultTimeout = 10000
   static int maxBuilds = 3
+  static String verifierJobName = "Gerrit-verifier-change"
 }
 
 def lastBuild = build.getPreviousSuccessfulBuild()
@@ -55,6 +56,18 @@
 def jsonSlurper = new JsonSlurper()
 def changesJson = jsonSlurper.parseText(changes)
 
+def getBuildRunsInProgress() {
+  def verifierChangeJob = Hudson.instance.getJob(Globals.verifierJobName)
+  def verifierRuns = verifierChangeJob.builds
+  def pendingBuilds = verifierRuns.findAll { it.building }
+  return pendingBuilds
+}
+
+def changeOfBuildRun(run) {
+  def params = run.allActions.findAll { it in hudson.model.ParametersAction }
+  return params.collect { it.getParameter("CHANGE_ID").value }
+}
+
 def acceptedChanges = changesJson.findAll {
   change ->
   sha1 = change.current_revision
@@ -77,27 +90,41 @@
       def myVerifications = verified.findAll {
         verification -> verification._account_id == Globals.myAccountId && verification.value != 0
       }
-      if(!myVerifications.empty) {
-        println "I have already verified " + sha1 + " commit: SKIPPING"
-        false
-      } else {
-        true
-      }
+      return myVerifications.empty
     }
   }
 }
 
-println "Gerrit has " + acceptedChanges.size() + " change(s) since " + since
-if(acceptedChanges.size() > Globals.maxBuilds) {
-  println "  but I'm building only ${Globals.maxBuilds} of them at the moment"
+def inProgress = getBuildRunsInProgress()
+if(!inProgress.empty) {
+  println "Changes currently in progress: "
+  inProgress.each {
+    b -> println("Change ${changeOfBuildRun(b)}: $b")
+  }
+}
+
+def inProgressChangesNums = inProgress.collect { changeOfBuildRun(it) }.flatten()
+def todoChangesNums = acceptedChanges.collect { "${it._number}" }
+def filteredChanges = todoChangesNums - inProgressChangesNums
+
+def buildsBandwith = Globals.maxBuilds - inProgressChangesNums.size
+
+println "Gerrit has " + filteredChanges.size() + " change(s) since " + since
+if(buildsBandwith <= 0) {
+  println "  but there is NO bandwidth for further builds yet"
+}
+else {
+  if(filteredChanges.size() > buildsBandwith) {
+    println "  but I'm building only ${buildsBandwith} of them at the moment"
+  }
 }
 println "================================================================================"
 
-def changesTodo = acceptedChanges.reverse().take(Globals.maxBuilds)
-changesTodo.each { change ->
-  println(Globals.gerrit + change._number +
-          " [" + change.current_revision + "] " + change.subject) }
+if(buildsBandwith > 0) {
+  def changesTodo = filteredChanges.reverse().take(buildsBandwith)
 
-def builds = changesTodo.collect { change -> { -> build("Gerrit-verifier-change", CHANGE_ID: change._number) } }
-parallel(builds)
+  println "Building changes: $changesTodo ..."
 
+  def builds = changesTodo.collect { change -> { -> build(Globals.verifierJobName, CHANGE_ID: change) } }
+  parallel(builds)
+}