def _perform_bisect(attrname, nix_file, to_pick, max_rebuilds, failure_line): for rev in to_pick: git.try_cherry_pick_all(rev) drv = nix.instantiate(attrname, nix_file) print(f"Instantiated {drv}.") num_rebuilds = len(nix.build_dry([drv])[0]) if num_rebuilds == 0: return "good" if max_rebuilds is not None: if num_rebuilds > max_rebuilds: print( f"Need to rebuild {num_rebuilds} derivations, which exceeds the maximum." ) return "skip rebuild_count" try: nix.build(nix.dependencies([drv])) except nix.BuildFailure as failure: failed_drvs = failure.drvs_failed print(f"Dependencies {failed_drvs} failed to build.") return f"skip dependency_failure" if failure_line is not None: result = nix.log_contains(drv, failure_line) if result == "yes": print("Failure line detected.") return "bad" elif result == "no_success": print("Build success.") return "good" elif result == "no_fail": print("Failure without failure line.") return "skip unknown_build_failure" else: raise Exception() else: if nix.build_would_succeed([drv]): print("Build success.") return "good" else: print("Build failure.") return "bad"
def _single_run(self, bisect_fun): patchset = read_patchset() with git.git_checkpoint(): one_patch_succeeded = False for (i, rev) in enumerate(patchset): success = git.try_cherry_pick_all(rev) one_patch_succeeded = success or one_patch_succeeded if not one_patch_succeeded: remaining_patchset = patchset[i + 1 :] for skip_range in get_skip_ranges(remaining_patchset): if within_range( "HEAD", get_named_skip_refs(skip_range, remaining_patchset) ): print( f"Commit with remaining patches matches known skip range {skip_range}." ) return f"skip {skip_range}" return bisect_fun()
def pick(rev): success = git.try_cherry_pick_all(rev) if not success: raise EnvSetupFailedException("Cherry-pick failed")