<?php // Merge requests require_once($INC . "/util.inc.php"); require_once($INC . "/sql.inc.php"); $rg_mr_env_q = getenv("ROCKETGIT_MR_QUEUE"); if (empty($rg_mr_env_q)) $rg_mr_queue = $rg_state_dir . "/q_merge_requests"; else $rg_mr_queue = $rg_mr_env_q; $rg_mr_error = ""; function rg_mr_set_error($str) { global $rg_mr_error; $rg_mr_error = $str; rg_log($str); } function rg_mr_error() { global $rg_mr_error; return $rg_mr_error; } /* * Add a merge request to the queue * We should put it in a queue, with fsync; also, in cron, we must process it */ function rg_mr_queue_add($repo_id, $namespace, $old_rev, $new_rev, $refname, $ip) { global $rg_mr_queue; rg_log("rg_mr_create: repo_id=$repo_id namespace=$namespace" . " old_rev=$old_rev new_rev=$new_rev, refname=$refname" . " ip=$ip rg_mr_queue=$rg_mr_queue"); $c = "repo_id=$repo_id namespace=$namespace old_rev=$old_rev" . " new_rev=$new_rev refname=$refname ip=$ip"; $f = "mr-" . $repo_id . "-" . time() . "-" . rg_id(6); if (!file_exists($rg_mr_queue)) { if (@mkdir($rg_mr_queue, 0700) === FALSE) { rg_mr_set_error("cannot create merge requests queue ($php_errormsg)"); return FALSE; } } if (@file_put_contents($rg_mr_queue . "/" . $f, $c) === FALSE) { rg_mr_set_error("cannot store merge request ($php_errormsg)"); return FALSE; } // TODO: fsync return TRUE; } /* * Add a merge request file to database */ function rg_mr_create($db, $repo_id, $namespace, $old_rev, $new_rev, $refname, $ip) { rg_log("rg_mr_create: repo_id=$repo_id namespace=$namespace" . " old_rev=$old_rev new_rev=$new_rev, refname=$refname" . " ip=$ip"); $now = time(); $params = array("repo_id" => $repo_id, "now" => $now, "namespace" => $namespace, "refname" => $refname, "old_rev" => $old_rev, "new_rev" => $new_rev, "ip" => $ip); $sql = "INSERT INTO merge_requests (repo_id, itime, namespace" . ", refname, old_rev, new_rev, done, ip)" . " VALUES (@@repo_id@@, @@now@@, @@namespace@@, @@refname@@" . ", @@old_rev@@, @@new_rev@@, 0, @@ip@@)"; $res = rg_sql_query_params($db, $sql, $params); if ($res === FALSE) { rg_mr_set_error("cannot insert merge request" . " (" . rg_sql_error() . ")"); return FALSE; } rg_sql_free_result($res); return TRUE; } /* * Loads info from a merge request file */ function rg_mr_queue_load_file($file) { $ret = array(); $ret['ok'] = 0; $c = @file_get_contents($file); if ($c === FALSE) { rg_mr_set_error("cannot load a merge request from $file ($php_errormsg)"); return $ret; } $tokens = explode(" ", trim($c)); foreach ($tokens as $token) { $p = explode("=", $token); $ret[$p[0]] = $p[1]; } $ret['ok'] = 1; return $ret; } /* * Process merge requests queue */ function rg_mr_queue_process($db) { global $rg_mr_queue; rg_prof_start("mr_queue_process"); $ret = TRUE; $dir = @opendir($rg_mr_queue); if ($dir === FALSE) { rg_mr_set_error("cannot open dir $rg_mr_queue ($php_errormsg)!"); return FALSE; } while (($file = readdir($dir))) { if (strncmp($file, "mr-", 3) != 0) continue; $path = $rg_mr_queue . "/" . $file; rg_log("\tLoading merge request from $path..."); $d = rg_mr_queue_load_file($path); if ($d['ok'] != 1) { $ret = FALSE; break; } $r = rg_mr_create($db, $d['repo_id'], $d['namespace'], $d['old_rev'], $d['new_rev'], $d['refname'], $d['ip']); if ($r != TRUE) { rename($path, $rg_mr_queue . "/BAD-" . $file); } else { if (@unlink($path) !== TRUE) rg_log("Warn: Cannot unlink file $path!"); // TODO: Verify it exists in database } } closedir($dir); rg_prof_end("mr_queue_process"); return $ret; } /* * Helper to condiment mr data */ function rg_mr_condiment(&$row) { $row['date_utc'] = gmdate("Y-m-d H:i", $row['itime']); $row['old_rev_short'] = substr($row['old_rev'], 0, 7); $row['new_rev_short'] = substr($row['new_rev'], 0, 7); } /* * Loads merge requests */ function rg_mr_load($db, $repo_id, $limit) { rg_log("rg_mr_load: repo_id=$repo_id limit=$limit"); $params = array("repo_id" => $repo_id); $sql = "SELECT * FROM merge_requests" . " WHERE repo_id = @@repo_id@@" . " AND done = 0" . " ORDER BY itime" . " LIMIT " . $limit; $res = rg_sql_query_params($db, $sql, $params); if ($res === FALSE) { rg_mr_set_error("Cannot load merge requests (" . rg_sql_error() . ")"); return FALSE; } $ret = array(); while (($row = rg_sql_fetch_array($res))) { rg_mr_condiment($row); $ret[] = $row; } rg_sql_free_result($res); return $ret; } /* * Loads a merge request */ function rg_mr_load_one($db, $repo_id, $namespace) { rg_log("rg_mr_load_one: repo_id=$repo_id namespace=$namespace"); $params = array("repo_id" => $repo_id, "namespace" => $namespace); $sql = "SELECT * FROM merge_requests" . " WHERE repo_id = @@repo_id@@" . " AND namespace = @@namespace@@"; $res = rg_sql_query_params($db, $sql, $params); if ($res === FALSE) { rg_mr_set_error("cannot load a merge request" . " (" . rg_sql_error() . ")"); return FALSE; } $row = rg_sql_fetch_array($res); rg_mr_condiment($row); rg_sql_free_result($res); return $row; } ?>