#!/usr/bin/php
DRUPAL_ROOT,
'SITE_NAME' => SITE_NAME,
);
$fatal_err = FALSE;
foreach ($vars as $name => $val) {
if (empty($val)) {
print "ERROR: \"$name\" constant not defined, aborting\n";
$fatal_err = TRUE;
}
}
if ($fatal_err) {
exit(1);
}
$script_name = $argv[0];
// Setup variables for Drupal bootstrap
$_SERVER['HTTP_HOST'] = SITE_NAME;
$_SERVER['REQUEST_URI'] = '/' . $script_name;
$_SERVER['SCRIPT_NAME'] = '/' . $script_name;
$_SERVER['PHP_SELF'] = '/' . $script_name;
$_SERVER['SCRIPT_FILENAME'] = $_SERVER['PWD'] .'/'. $script_name;
$_SERVER['PATH_TRANSLATED'] = $_SERVER['SCRIPT_FILENAME'];
if (!chdir(DRUPAL_ROOT)) {
print "ERROR: Can't chdir(DRUPAL_ROOT), aborting.\n";
exit(1);
}
// Make sure our umask is sane for generating directories and files.
umask(022);
require_once 'includes/bootstrap.inc';
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
define('BASE_DIRECTORY', DRUPAL_ROOT .'/'. file_create_path(variable_get('project_release_history_directory', 'release-history')));
if (!is_dir(BASE_DIRECTORY)) {
wd_err(t("ERROR: History directory (%directory) does not exist, aborting.\n", array('%directory' => BASE_DIRECTORY)));
exit(1);
}
/// @todo Add command-line args to only generate a given project/version.
project_release_history_generate_all();
// ------------------------------------------------------------
// Functions: main work
// ------------------------------------------------------------
/**
* Figure out what project and API terms to generate the history for.
*/
function project_release_history_generate_all() {
$api_terms = project_release_compatibility_list();
wd_msg(t('Generating XML release history files for all projects.'));
$query = db_query("SELECT DISTINCT(prn.pid), tn.tid FROM {project_release_nodes} prn INNER JOIN {term_node} tn ON prn.nid = tn.nid WHERE tn.tid IN (%s)", implode(',', array_keys($api_terms)));
$i = 0;
while ($project = db_fetch_object($query)) {
project_release_history_generate_project_xml($project->pid, $project->tid);
$i++;
}
wd_msg(t('Completed XML release history files for @num_projects.', array('@num_projects' => format_plural($i, '1 project/version pair', '@count project/version pairs'))));
}
/**
* Generate the XML history file for a given project name and API
* compatibility term.
*
* @todo If a history file already exists for this combination, this
* function will generate a new history and atomically replace the old
* one (currently, just logs to watchdog for debugging).
*
* @todo If there's no subdirectory in the directory tree for this
* project yet, this function creates one.
*
* @param $project_nid
* Project ID (node id of the project node) to generate history for.
* @param $api_tid
* Taxonomy id (tid) of the API compatibility term to use.
*/
function project_release_history_generate_project_xml($project_nid, $api_tid) {
$api_vid = _project_release_get_api_vid();
$api_terms = project_release_compatibility_list();
if (!isset($api_terms[$api_tid])) {
wd_err(t('API compatibility term %tid not found.', array('%tid' => $api_tid)));
return FALSE;
}
$api_version = $api_terms[$api_tid];
// Get project-wide data:
$sql = "SELECT n.title, n.nid, p.uri, prdv.major FROM {node} n INNER JOIN {project_projects} p ON n.nid = p.nid LEFT JOIN {project_release_default_versions} prdv ON prdv.nid = n.nid AND prdv.tid = %d WHERE p.nid = %d";
$query = db_query($sql, $api_tid, $project_nid);
if (!db_num_rows($query)) {
wd_err(t('Project ID %pid not found', array('%pid' => $project_nid)));
return FALSE;
}
$project = db_fetch_object($query);
if (!isset($project->major)) {
wd_err(t('No release found for project %project_name compatible with %api_version.', array('%project_name' => $project->uri, '%api_version' => $api_version)));
return FALSE;
}
$xml = "
' . check_plain($xml));
return FALSE;
}
// We have to close this handle before we can rename().
fclose($hist_fd);
// Now we can atomically rename the .new into place in the "live" spot.
if (!rename($tmp_filename, $filename)) {
wd_err(t("ERROR: rename(@old, $new) failed, can't write history for %project.", array('@old' => $tmp_filename, '@new' => $filename, '%project' => $project->title)));
return FALSE;
}
return TRUE;
}
// ------------------------------------------------------------
// Functions: utility methods
// ------------------------------------------------------------
/**
* Wrapper function for watchdog() to log notice messages.
*/
function wd_msg($msg, $link = NULL) {
watchdog('release_history', $msg, WATCHDOG_NOTICE, $link);
}
/**
* Wrapper function for watchdog() to log error messages.
*/
function wd_err($msg, $link = NULL) {
watchdog('release_hist_error', $msg, WATCHDOG_ERROR, $link);
}