Fedora OCaml: Improve parallelism by not waiting for rebuilds unless they are require...
[goaljobs-goals.git] / fedora_ocaml_rebuild.ml
index b4445dd..2eccde1 100644 (file)
@@ -1,5 +1,6 @@
 (* Perform a complete Fedora OCaml rebuild, in build order. *)
 
+open Unix
 open Printf
 
 open Goaljobs
@@ -35,10 +36,50 @@ let pkg_deps = dependencies branch source_packages
 
 (* Goal: rebuild all packages. *)
 let rec goal all () =
-  List.iter (fun pkg -> require (rebuilt pkg)) source_packages
+  List.iter (fun pkg -> require (rebuild_started pkg)) source_packages
 
 (* Goal: That 'package' has been rebuilt and exists in Koji. *)
 and rebuilt pkg =
+  let specfile = fedora_specfile pkg branch in
+
+  (* Note: verrel may change as we go along, so don't assign it to
+   * variable.
+   *)
+
+  (* Note the target must be both of these because the old verrel
+   * could exist as a koji build without it having been part of the
+   * rebuild.
+   *)
+  target (file_contains_string specfile rebuild_name &&
+          koji_build_state (fedora_verrel pkg branch) == `Complete);
+
+  (* Start the rebuild. *)
+  require (rebuild_started pkg);
+
+  (* Wait for the build state to reach a conclusion. *)
+  let rec loop () =
+    match koji_build_state (fedora_verrel pkg branch) with
+    | `Building ->
+      sleep 30;
+      loop ()
+    | `Complete ->
+      ()
+    | `Deleted ->
+      failwith (sprintf "rebuild of package %s: deleted" pkg)
+    | `Failed ->
+      failwith (sprintf "rebuild of package %s: failed" pkg)
+    | `Canceled ->
+      failwith (sprintf "rebuild of package %s: canceled" pkg)
+  in
+  loop ();
+
+  (* Wait for the build to appear in Koji repo. *)
+  koji_wait_repo koji_target (fedora_verrel pkg branch)
+
+(* Goal: The rebuild of the package has started, but we haven't waited
+ * for it to finish.
+ *)
+and rebuild_started pkg =
   let deps = List.assoc pkg pkg_deps in
   let specfile = fedora_specfile pkg branch in
 
@@ -47,19 +88,20 @@ and rebuilt pkg =
    * rebuild.
    *)
   target (file_contains_string specfile rebuild_name &&
-            koji_build_exists (fedora_verrel pkg branch));
+            (match koji_build_state (fedora_verrel pkg branch) with
+            | `Building | `Complete -> true
+            | `Deleted | `Failed | `Canceled -> false));
 
-  (* All dependent packages must have been done first. *)
+  (* All dependent packages must have been fully rebuilt and in the
+   * repo first.
+   *)
   List.iter (fun dep -> require (rebuilt dep)) deps;
 
   (* A local test build must succeed. *)
   require (local_build_succeeded pkg);
 
-  (* Rebuild the package in Koji. *)
-  koji_build pkg branch;
-
-  (* Wait for the build to appear in Koji repo.  Note verrel may change. *)
-  koji_wait_repo koji_target (fedora_verrel pkg branch)
+  (* Rebuild the package in Koji, but don't wait. *)
+  koji_build ~wait:false pkg branch
 
 and local_build_succeeded pkg =
   (* The specfile must have been updated. *)