(* Perform a complete Fedora OCaml rebuild, in build order. *) open Unix open Printf open Goaljobs open Config open Git open Fedora let branch = "master" let koji_target = "rawhide" (* The name of the rebuild, and also the magic substring that must * appear in the %changelog when the package has been rebuilt. *) let rebuild_name = "OCaml 4.01.0" (* Packages that have problems or we just don't want to build. *) let blocked = [ "ocaml-libvirt"; (* RHBZ#1009701 *) "ocaml-lwt"; "ocaml-react"; (* loganjerry is handling *) "ocaml-xmlrpc-light"; (* temporary, can remove after 2013-09-19 *) ] (* List of OCaml-related source package names. *) let source_packages = let dirs = shlines "cd %s && ls -1d ocaml*" fedora_dir in dirs @ [ "alt-ergo"; "apron"; "brltty"; "coccinelle"; "coq"; "cduce"; "frama-c"; "gappalib-coq"; "graphviz"; "hivex"; "js-of-ocaml"; "llvm"; "plplot"; "whenjobs"; "why3"; "xen" ] let source_packages = List.filter (fun pkg -> not (List.mem pkg blocked)) source_packages (* Dependencies of each package. (pkg, [deps ...]) *) let pkg_deps = dependencies branch source_packages (* Goal: rebuild all packages. *) let rec goal all () = 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 | `No_such_build -> failwith (sprintf "rebuild of package %s: no build found" pkg) | `Building -> sleep 60; 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 (* 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 && (match koji_build_state (fedora_verrel pkg branch) with | `Building | `Complete -> true | `Deleted | `Failed | `Canceled | `No_such_build -> false)); (* 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. Don't wait ... *) koji_build ~wait:false pkg branch; (* ... but the build doesn't appear in Koji (eg. in 'koji * buildinfo') until the SRPM has been built. This can take quite * some time. Loop here until the build appears. *) let rec loop () = match koji_build_state (fedora_verrel pkg branch) with | `No_such_build -> sleep 60; loop (); | `Building | `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 () and local_build_succeeded pkg = (* The specfile must have been updated. *) require (specfile_updated pkg); let key = sprintf "fedora_ocaml_local_build_%s_%s" pkg (fedora_verrel pkg branch) in target (memory_exists key); (* Do a local test build to ensure the Koji build will work. *) sh " cd %s sudo yum-builddep -y %s fedpkg local " (fedora_repo pkg branch) (fedora_specfile pkg branch); memory_set key "1" and specfile_updated pkg = let repodir = fedora_repo pkg branch in let specfile = fedora_specfile pkg branch in sh " cd %s rm -rf x86_64 noarch *.src.rpm .build* clog git fetch " repodir; if not (git_has_local_changes repodir) then sh " cd %s git pull --rebase " repodir; sh "sudo yum-builddep -y %s" specfile; (* For rationale behind always bumping the spec file, see comment * in 'fedora.ml'. *) (* XXX Automate common specfile fixes. *) let title = rebuild_name ^ " rebuild." in sh "rpmdev-bumpspec -c %s %s" (quote title) specfile; sh " cd %s echo 'Please make further changes as required to the spec file %s.spec' echo '(Press return key)' read emacs -nw %s echo 'OK to commit this change? (press ^C if not)' read fedpkg commit -c echo 'OK to push this change? (press ^C if not)' read fedpkg push " repodir pkg specfile