function xcvs_init($argc, $argv) { $this_file = array_shift($argv); // argv[0] if ($argc < 7) { xcvs_help($this_file, STDERR); exit(3); } $config_file = array_shift($argv); // argv[1] // Load the configuration file and bootstrap Drupal. if (!file_exists($config_file)) { fwrite(STDERR, "Error: failed to load configuration file.\n"); exit(4); } include_once $config_file; // Check temporary file storage. $tempdir = xcvs_get_temp_directory($xcvs['temp']); $username = array_shift($argv); // argv[2] $tag_name = array_shift($argv); // argv[3] $type = array_shift($argv); // argv[4] $cvs_op = array_shift($argv); // argv[5] $dir = array_shift($argv); // argv[6] // Do a full Drupal bootstrap. xcvs_bootstrap($xcvs); // The commitinfo script wrote the lastlog file for us. // Its only contents is the name of the last directory that commitinfo // was invoked with, and that order is the same one as for loginfo. $lastlog = $tempdir . '/xcvs-lastlog.' . posix_getpgrp(); $summary = $tempdir . '/xcvs-summary.' . posix_getpgrp(); $taginfo = $tempdir . '/xcvs-taginfo.' . posix_getpgrp(); // Write the tagged/branched items to a temporary log file, one by one. while (!empty($argv)) { $filename = array_shift($argv); $source_branch = array_shift($argv); $source_branch = empty($source_branch) ? 'HEAD' : $source_branch; $old = array_shift($argv); $new = array_shift($argv); xcvs_log_add($summary, "/{$dir}/{$filename},{$source_branch},{$old},{$new}\n", 'a'); } // Once all logs in a multi-directory tagging/branching operation have been // gathered, the currently processed directory matches the last processed // directory that taginfo was invoked with, which means we've got all the // needed data in the summary file (and the taginfo file that xcvs-taginfo // has written before). if (xcvs_is_last_directory($lastlog, $dir)) { // The taginfo script was nice enough to determine the label type for all // files where the branch or tag was deleted. if ($cvs_op == 'del') { $fd = fopen($taginfo, 'r'); if ($fd === FALSE) { fwrite(STDERR, "Error: failed to open taginfo log at {$summary}.\n"); xcvs_exit(5, $lastlog, $summary, $taginfo); } $label_types = array(); while (!feof($fd)) { $tag_entry = trim(fgets($fd)); list($path, $ltype) = explode(',', $tag_entry); $label_types[$path] = $ltype == 'N' ? VERSIONCONTROL_OPERATION_TAG : VERSIONCONTROL_OPERATION_BRANCH; } fclose($fd); } // Convert the previously written temporary log file // to Version Control API's item format. $fd = fopen($summary, 'r'); if ($fd === FALSE) { fwrite(STDERR, "Error: failed to open summary log at {$summary}.\n"); xcvs_exit(6, $lastlog, $summary, $taginfo); } $items = array(); while (!feof($fd)) { $file_entry = trim(fgets($fd)); if (!$file_entry) { continue; } list($path, $source_branch, $old, $new) = explode(',', $file_entry); if ($type == 'N') { // is a tag $label_type = VERSIONCONTROL_OPERATION_TAG; } else { if ($type == 'T') { // is a branch $label_type = VERSIONCONTROL_OPERATION_BRANCH; } } if (in_array($cvs_op, array('add', 'mov'))) { $items[VERSIONCONTROL_ACTION_ADDED][$label_type][$path] = array('type' => VERSIONCONTROL_ITEM_FILE, 'path' => $path, 'revision' => $new); // $source_branch is not currently being used by Version Control API. } if (in_array($cvs_op, array('del', 'mov'))) { $item = array('type' => VERSIONCONTROL_ITEM_FILE, 'path' => $path, 'revision' => $old); if ($type == '?') { if (!isset($label_types[$path])) { fwrite(STDERR, "Could not determine the label type for {$path}. Not recording into database.\n"); continue; } $label_type = $label_types[$path]; } $items[VERSIONCONTROL_ACTION_DELETED][$label_type][$path] = $item; } } fclose($fd); if (empty($items)) { // If nothing is being tagged, we don't need to log anything. xcvs_exit(0, $lastlog, $summary, $taginfo); } // All data gathered, now let's insert it into the database. foreach ($items as $action => $items_by_action) { foreach ($items_by_action as $label_type => $operation_items) { $operation = array('type' => $label_type, 'date' => time(), 'username' => $username, 'repo_id' => $xcvs['repo_id']); $label = array('type' => $label_type, 'name' => $tag_name, 'action' => $action); $operation['labels'] = array($label); // A word of warning to the user, because it's easy to miss this fact. if ($label['type'] == VERSIONCONTROL_OPERATION_BRANCH && $label['action'] == VERSIONCONTROL_ACTION_ADDED) { fwrite(STDERR, t("\n** NOTE: Don't forget that creating a branch does NOT\n** automatically update your workspace to use that branch.\n** If you want to commit to this new branch, you must run:\n** cvs update -r !branch\n\n", array('!branch' => $label['name']))); } versioncontrol_insert_operation($operation, $operation_items); } } // Clean up. xcvs_exit(0, $lastlog, $summary, $taginfo); } exit(0); }
function xcvs_init($argc, $argv) { $this_file = array_shift($argv); // argv[0] if ($argc < 7) { xcvs_help($this_file, STDERR); exit(3); } $config_file = array_shift($argv); // argv[1] $username = array_shift($argv); // argv[2] $tag_name = array_shift($argv); // argv[3] $type = array_shift($argv); // argv[4] $cvs_op = array_shift($argv); // argv[5] $dir = array_shift($argv); // argv[6] // Load the configuration file and bootstrap Drupal. if (!file_exists($config_file)) { fwrite(STDERR, "Error: failed to load configuration file.\n"); exit(4); } include_once $config_file; // Check temporary file storage. $tempdir = xcvs_get_temp_directory($xcvs['temp']); // Admins and other privileged users don't need to go through any checks. if (!in_array($username, $xcvs['allowed_users'])) { // Do a full Drupal bootstrap. xcvs_bootstrap($xcvs); // Gather info for each tagged/branched file. $items = array(); while (!empty($argv)) { $filename = array_shift($argv); $source_branch = array_shift($argv); $old = array_shift($argv); $new = array_shift($argv); $path = '/' . $dir . '/' . $filename; if ($type == 'N') { // is a tag $label_type = VERSIONCONTROL_OPERATION_TAG; } else { if ($type == 'T') { // is a branch $label_type = VERSIONCONTROL_OPERATION_BRANCH; } } if (in_array($cvs_op, array('add', 'mov'))) { $items[VERSIONCONTROL_ACTION_ADDED][$label_type][$path] = array('type' => VERSIONCONTROL_ITEM_FILE, 'path' => $path, 'revision' => $new); // $source_branch is not currently being used by Version Control API. } if (in_array($cvs_op, array('del', 'mov'))) { $item = array('type' => VERSIONCONTROL_ITEM_FILE, 'path' => $path, 'revision' => $old); if ($type == '?') { $label_type = xcvs_branch_or_tag($tag_name, $item); } $items[VERSIONCONTROL_ACTION_DELETED][$label_type][$path] = $item; } } if (empty($items)) { fwrite(STDERR, "Operation doesn't affect any item, aborting.\n"); exit(7); } foreach ($items as $action => $items_by_action) { foreach ($items_by_action as $label_type => $operation_items) { $operation = array('type' => $label_type, 'username' => $username, 'repo_id' => $xcvs['repo_id']); $label = array('type' => $label_type, 'name' => $tag_name, 'action' => $action); $operation['labels'] = array($label); $access = versioncontrol_has_write_access($operation, $operation_items); // Fail and print out error messages if branch/tag access has been denied. if (!$access) { fwrite(STDERR, implode("\n\n", versioncontrol_get_access_errors()) . "\n\n"); exit(7); } } } } // If we get as far as this, the tagging/branching operation may happen. // Remember this directory so that posttag can combine tags/branches // from different directories in one tag/branch entry. $lastlog = $tempdir . '/xcvs-lastlog.' . posix_getpgrp(); xcvs_log_add($lastlog, $dir); // Also remember the label type per item - posttag won't be able to determine // this by itself because the action has already been executed. Only needed // for branch/tag deletions - 'add' and 'mov' don't need this kind of crap. if ($cvs_op == 'del') { $taginfo = $tempdir . '/xcvs-taginfo.' . posix_getpgrp(); foreach ($items as $action => $items_by_action) { foreach ($items_by_action as $label_type => $operation_items) { foreach ($operation_items as $path => $item) { $ltype = $label_type == VERSIONCONTROL_OPERATION_TAG ? 'N' : 'T'; xcvs_log_add($taginfo, "{$path}," . $ltype . "\n", 'a'); } } } } exit(0); }
/** * Main function and starting point of this script: * Bootstrap Drupal, gather commit data and pass it on to Version Control API. */ function xcvs_init($argc, $argv) { $date = time(); // remember the time of the current commit for later $this_file = array_shift($argv); // argv[0] if ($argc < 7) { xcvs_help($this_file, STDERR); exit(3); } $config_file = array_shift($argv); // argv[1] $username = array_shift($argv); // argv[2] $commitdir = '/' . array_shift($argv); // argv[3] // Load the configuration file and bootstrap Drupal. if (!file_exists($config_file)) { fwrite(STDERR, "Error: failed to load configuration file.\n"); exit(4); } include_once $config_file; // Check temporary file storage. $tempdir = xcvs_get_temp_directory($xcvs['temp']); // The commitinfo script wrote the lastlog file for us. // Its only contents is the name of the last directory that commitinfo // was invoked with, and that order is the same one as for loginfo. $lastlog = $tempdir . '/xcvs-lastlog.' . posix_getpgrp(); $summary = $tempdir . '/xcvs-summary.' . posix_getpgrp(); // Write the changed items to a temporary log file, one by one. if (!empty($argv)) { if ($argv[0] == '- New directory') { xcvs_log_add($summary, "{$commitdir},dir\n", 'a'); } else { while (!empty($argv)) { $filename = array_shift($argv); $old = array_shift($argv); $new = array_shift($argv); xcvs_log_add($summary, "{$commitdir}/{$filename},{$old},{$new}\n", 'a'); } } } // Once all logs in a multi-directory commit have been gathered, // the currently processed directory matches the last processed directory // that commitinfo was invoked with, which means we've got all the // needed data in the summary file. if (xcvs_is_last_directory($lastlog, $commitdir)) { // Convert the previously written temporary log file // to Version Control API's commit action format. $fd = fopen($summary, "r"); if ($fd === FALSE) { fwrite(STDERR, "Error: failed to open summary log at {$summary}.\n"); xcvs_exit(5, $lastlog, $summary); } $operation_items = array(); // Do a full Drupal bootstrap. We need it from now on at the latest, // starting with the action constants in xcvs_get_operation_item(). xcvs_bootstrap($xcvs); while (!feof($fd)) { $file_entry = trim(fgets($fd)); list($path, $item) = xcvs_get_operation_item($file_entry); if ($path) { $operation_items[$path] = $item; } } fclose($fd); // Integrate with the Drupal Version Control API. if (!empty($operation_items)) { // Get the remaining info from the commit log that we get from STDIN. list($branch_name, $message) = xcvs_parse_log(STDIN); // Add the real revision to deleted items. xcvs_fix_operation_items($operation_items, $branch_name); // Determine how many lines were added and removed for a given file. xcvs_fetch_item_line_changes($operation_items); // Prepare the data for passing it to Version Control API. $operation = array('type' => VERSIONCONTROL_OPERATION_COMMIT, 'repo_id' => $xcvs['repo_id'], 'date' => $date, 'username' => $username, 'message' => $message, 'revision' => '', 'labels' => array(array('type' => VERSIONCONTROL_OPERATION_BRANCH, 'name' => $branch_name, 'action' => VERSIONCONTROL_ACTION_MODIFIED))); _versioncontrol_cvs_fix_commit_operation_items($operation, $operation_items); $operation = versioncontrol_insert_operation($operation, $operation_items); if (!empty($operation)) { fwrite(STDERR, t("Recorded as commit !id.\n", array('!id' => versioncontrol_format_operation_revision_identifier($operation)))); } } // Clean up xcvs_exit(0, $lastlog, $summary); } exit(0); }
function xcvs_init($argc, $argv) { $this_file = array_shift($argv); // argv[0] if ($argc < 5) { xcvs_help($this_file, STDERR); exit(3); } $files = array_slice($argv, 4); $config_file = array_shift($argv); // argv[1] $username = array_shift($argv); // argv[2] $dir = array_shift($argv); // argv[3] $filenames = $argv; // the rest of the command line arguments // Load the configuration file and bootstrap Drupal. if (!file_exists($config_file)) { fwrite(STDERR, "Error: failed to load configuration file.\n"); exit(4); } include_once $config_file; // Check temporary file storage. $tempdir = xcvs_get_temp_directory($xcvs['temp']); // Admins and other privileged users don't need to go through any checks. if (!in_array($username, $xcvs['allowed_users'])) { // Do a full Drupal bootstrap. xcvs_bootstrap($xcvs); // Construct a minimal commit operation array. $operation = array('type' => VERSIONCONTROL_OPERATION_COMMIT, 'repo_id' => $xcvs['repo_id'], 'username' => $username, 'labels' => xcvs_commit_labels($xcvs['cwd'])); $operation_items = array(); foreach ($filenames as $filename) { list($path, $item) = xcvs_get_operation_item($filename, $dir, $xcvs['cwd']); $operation_items[$path] = $item; } $access = versioncontrol_has_write_access($operation, $operation_items); // Fail and print out error messages if commit access has been denied. if (!$access) { fwrite(STDERR, implode("\n\n", versioncontrol_get_access_errors()) . "\n\n"); exit(6); } } // If we get as far as this, the commit may happen. // Remember this directory so that loginfo can combine commits // from different directories in one commit entry. $lastlog = $tempdir . '/xcvs-lastlog.' . posix_getpgrp(); xcvs_log_add($lastlog, $dir); exit(0); }