$matches[1], 'version' => $matches[2]); } else { return false; } } $db = new SQLite3('autobuild.db'); $runs = Array(); $handle = opendir('cauldron/x86_64/core/'); while (false !== ($entry = readdir($handle))) { if (preg_match("/^....-..-..$/", $entry, $matches)) { array_push($runs, $matches[0]); } } closedir($handle); $handle = opendir('cauldron/aarch64/core/'); while (false !== ($entry = readdir($handle))) { if (preg_match("/^....-..-..$/", $entry, $matches)) { array_push($runs, $matches[0]); } } closedir($handle); sort($runs); $latestlinks = glob("cauldron/*/core/latest"); $latest = 0; foreach ($latestlinks as $link) { # This is ugly but readlink() returns false even if is_link() returns # true and readlink() as user apache in php cli works. $date = `readlink $link`; if ($date > $latest) { $latest = $date; } } $run = $_GET['run']; if (!$run || $run=="latest") { $run = $latest; } foreach ($runs as $r) { if ($r==$run) { break; } $prev = $r; } $runepoc = strtotime($run); $packages = Array(); if ($handle = opendir('/distrib/bootstrap/distrib/cauldron/SRPMS/core/release/')) { while (false !== ($entry = readdir($handle))) { if ($parsed = parse_package($entry)) { $packages[$parsed['package']] = $entry; } } closedir($handle); } $prev_failure = Array(); if ($prev) { $status_name = array_shift(glob("cauldron/*/core/$prev/status.core.log")); $status_file = fopen($status_name, "r"); if ($status_file !== false) { // The file should always be there but better not get an infinite loop flooding the logs when it disappears while (!feof($status_file)) { $line = fgets($status_file); if (preg_match("/^(.*): (.*)$/", $line, $matches)) { $rpm = parse_package($matches[1]); $status = $matches[2]; if ($status != "ok" && $status != "unknown" && $status != "not_on_this_arch") { $prev_failure[$rpm['package']] = 1; } } } fclose($status_file); } } $success = Array(); $failure = Array(); $fixed = Array(); $removed = Array(); $broken = Array(); $base_dir = array_shift(glob("cauldron/*/core/$run")); $status_name = "$base_dir/status.core.log"; if (!file_exists($status_name)) { echo "Invalid run"; exit; } $start_time = 0; if (file_exists("$base_dir/VERSION")) { #Mageia 5 Devel-i586-Download 20140311 15:50 #Mageia 5 Devel-x86_64-Download 20140311 15:50 $version = file_get_contents("$base_dir/VERSION"); preg_match('/ (\d{8} \d{2}:\d{2})$/', $version, $matches); $start_time = strtotime($matches[1]); } $status_file = fopen($status_name, "r"); while (!feof($status_file)) { $line = fgets($status_file); if (preg_match("/^(.*): (.*)$/", $line, $matches)) { $rpm = $matches[1]; $status = $matches[2]; if ($start_time == 0 && $status != 'recreate_srpm_failure' && $status != 'not_on_this_arch') { $build_stat = stat("$base_dir/$rpm"); if ($build_stat && $build_stat['mtime']) { $start_time = $build_stat['mtime']; } } if ($status == "ok") { array_push($success, $rpm); } elseif ($status != "unknown" && $status != "not_on_this_arch"){ $failure[$rpm] = $status; $parsed = parse_package($rpm); $package = $parsed['package']; if(!array_key_exists($package, $prev_failure)) { $broken[$rpm] = 1; } if(!array_key_exists($package, $packages)) { $removed[$rpm] = 1; } else { # For recreate_srpm_failure, $rpm is the one that was in the repo # For other failures, mga release may be incorrect so use something less reliable if ($status == 'recreate_srpm_failure' && $rpm != $packages[$package]) { $fixed[$rpm] = 1; } else { $file = '/distrib/bootstrap/distrib/cauldron/SRPMS/core/release/' . $packages[$package]; if (file_exists($file)) { $pkg_stat = stat($file); if ($pkg_stat['mtime'] > $start_time) { $fixed[$rpm] = 1; } } } } } } } fclose($status_file); sort($success); ksort($failure); $nb_failed = count($failure); $nb_success = count($success); $nb_fixed = count($fixed); $nb_removed = count($removed); $nb_still_broken = $nb_failed - $nb_fixed - $nb_removed; $nb_tried = $nb_failed + $nb_success; $succes_percent = round($nb_success*1000/$nb_tried)/10; $estimated_percent = round(($nb_success+$nb_fixed)*1000/($nb_tried-$nb_removed))/10; $title = "Autobuild results for $run"; echo "$title\n"; ?> = 4; } function get_package_id($package) { global $db; return $db->querySingle("SELECT Id FROM Packages WHERE Name = '$package'"); } function get_build_history($package_id) { global $db; if ($package_id) { # TODO: optimize by retrieving Runs.Id once at the start $result = $db->query("SELECT ResultValues.Name FROM Runs, Results, ResultValues WHERE Runs.Id = Results.Run AND Results.Result = ResultValues.Id AND Results.Package = '$package_id' ORDER BY Start DESC LIMIT 10"); if ($result) { $build_stats = Array(); while ($entry = $result->fetchArray(SQLITE3_ASSOC)) { array_push($build_stats, $entry['Name']); } return $build_stats; } } return false; } function get_package_attributes($package_id) { global $db, $runepoc; if ($package_id) { # TODO: optimize by retrieving Runs.Id once at the start $attributes = $db->querySingle("SELECT Attr FROM Attributes, Runs WHERE Runs.Id = Attributes.Run AND Runs.Start = $runepoc AND Attributes.Package = '$package_id';"); } return $attributes; } echo "

$title

\n"; echo "
"; if (array_key_exists('include_success', $_GET) && $_GET['include_success'] === 'true') { echo "Only failures"; } else { echo "Include successful packages"; } echo "\n"; echo "

Changes since this run

\n"; echo "\n"; echo "\n"; echo "\n"; echo "\n"; echo "
Fixed$nb_fixed
Removed$nb_removed
Unchanged$nb_still_broken
\n"; echo "
If no new package was broken, success rate next time should be $estimated_percent%.\n"; echo "

Failed builds ($nb_failed/$nb_tried)

\n"; echo "\n"; echo "\n"; foreach ($failure as $rpm => $error) { $parsed = parse_package($rpm); $history_link = 'History'; $status_html = ""; if (array_key_exists($rpm, $fixed)) { $status_html = " Fixed"; } elseif (array_key_exists($rpm, $removed)) { $status_html = " Removed"; } elseif (array_key_exists($rpm, $broken)) { $status_html = " New"; } $error_html = $error; if (file_exists("icons/error-$error.png")) { $error_html = " $error"; } $packageid = get_package_id($parsed['package']); $history = get_build_history($packageid); if (is_flaky($history)) { $history_link = $history_link . " "; } $langs = ""; $errors = ""; $stage = ""; $attributes = get_package_attributes($packageid); if ($attributes) { # Attributes are space separated words of the form "TYPE_SPECIFIER", e.g., "lang_php" # Types are currently build (use of a particular build system), # lang (use of a programming language) or err (a common build error). foreach (explode(" ", $attributes) as $attr) { if (empty($attr)) { continue; } $attrname = explode("_", $attr)[1]; if (substr($attr, 0, 5) === "lang_") { $lang = ucfirst($attrname); $icon_fn = "icons/" . str_replace("_", "-", $attr) . ".png"; if (file_exists($icon_fn)) { $langs = $langs . " "; } else { $langs = $langs . " $lang"; } } elseif (substr($attr, 0, 4) === "err_") { # TODO: create link into wiki with information about these errors $errors = "$errors $attrname"; } elseif (substr($attr, 0, 6) === "stage_") { if ($attrname != 'nobuild') { if ($attrname == 'preprep') { $stage = 'Before %prep'; } else { $stage = "%$attrname"; } } } } } echo ""; if (file_exists("$base_dir/$rpm/")) { echo ""; } else { echo ""; } echo "\n"; } $db->close(); ?>
StatusFailure typeBuild stepLanguagesDetected errors
$rpm$rpm$status_html$error_html$stage$history_link$langs$errors
Successful builds ($nb_success/$nb_tried)\n\n"; } ?>