Skip to content
Snippets Groups Projects
Commit 44a56935 authored by Jan-Hendrik Willms's avatar Jan-Hendrik Willms
Browse files

wip

parent 2b79c1a3
No related branches found
No related tags found
No related merge requests found
#!/usr/bin/env php
<?php
require_once __DIR__ . '/vendor/autoload.php';
require_once __DIR__ . '/includes/functions.php';
$config = require __DIR__ . '/includes/config.php';
$steps = [
1 => __DIR__ . '/steps/convert-tickets-to-issues.php',
// 2 => '',
'issues' => __DIR__ . '/steps/convert-tickets-to-issues.php',
'commits' => __DIR__ . '/steps/clone-svn-repository.php',
'history' => __DIR__ . '/steps/rewrite-history.php',
'push' => __DIR__ . '/steps/push-repository.php',
'comments' => __DIR__ . '/steps/add-comments.php',
];
$result = [];
$result = ['issues' => [8641 => 398]];
foreach ($steps as $number => $step) {
$result[$number] = require $step;
}
<?php
return [
// Temp paths
'temp-path' => '/tmp/studip-svn-git',
// Trac
'trac-url' => 'https://<username>:<password>@develop.studip.de/trac/login',
'trac-query' => 'id=8682',
'trac-query' => 'version=trunk&order=id&resolution=fixed&resolution=wontfix&resolution=duplicate&resolution=worksforme',
'trac-revision' => 47000, // 43791 <- 4.0 started here
'trac-users' => __DIR__ . '/trac-users.txt',
// GitLab
'gitlab-url' => 'http://gitlabdev01.virt.uni-oldenburg.de',
'gitlab-api-url' => 'http://gitlabdev01.virt.uni-oldenburg.de',
'gitlab-repo-url' => 'git@gitlabdev01.virt.uni-oldenburg.de:studip/trunk.git',
'gitlab-project' => 'studip/trunk',
'gitlab-access-token' => '<gitlab-token>',
'gitlab-admin-token' => true,
......
<?php
function my_exec($command) {
static $level = 0;
$level += 1;
if (func_num_args() === 1 && is_array($command)) {
return array_map(function ($args) {
return call_user_func_array('my_exec', $args);
}, $command);
}
$args = func_get_args();
$command = array_shift($args);
$callback = is_callable(end($args))
? array_pop($args)
: function ($i) { return $i; };
$command = vsprintf($command, array_slice(func_get_args(), 1));
exec($command, $output);
$result = $callback(implode("\n", $output));
$level -= 1;
return $result;
}
function removeDirectory($directory)
{
$it = new RecursiveDirectoryIterator($directory, RecursiveDirectoryIterator::SKIP_DOTS);
$files = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::CHILD_FIRST);
foreach ($files as $file) {
if ($file->isDir()){
rmdir($file->getRealPath());
} else {
unlink($file->getRealPath());
}
}
rmdir($directory);
}
......@@ -78,7 +78,7 @@ class GitLab
} catch (\Gitlab\Exception\RuntimeException $e) {
// If adding has failed because of SUDO (author does not have access to the project), create an issue without SUDO (as the Admin user whose token is configured)
if ($this->isAdmin) {
$issue = $this->doCreateIssue($projectId, $title, $description, $createdAt, $assigneeId, $authorId, $labels, false);
$issue = $this->doCreateIssue($projectId, $title, $description, $createdAt, $assigneeId, $authorId, $labels, $confidential, false);
} else {
// If adding has failed for some other reason, propagate the exception back
throw $e;
......@@ -206,5 +206,10 @@ class GitLab
public function getUrl() {
return $this->url;
}
public function getClient()
{
return $this->client;
}
}
?>
......@@ -10,8 +10,8 @@ namespace Trac2GitLab;
class Migration
{
// Communicators
private $gitLab;
private $trac;
public $gitLab;
public $trac;
// Configuration
private $addLinkToOriginalTicket;
private $userMapping;
......@@ -92,7 +92,7 @@ class Migration
* @param array $openTickets Array of Trac tickets to be migrated
* @param string $gitLabProject GitLab project in which the issues should be created
*/
private function migrate($openTickets, $gitLabProject) {
public function migrate($openTickets, $gitLabProject) {
$mapping = [];
foreach($openTickets as $ticket) {
$originalTicketId = $ticket[0];
......@@ -108,7 +108,7 @@ class Migration
$labels = $ticket[3]['keywords'];
$dateCreated = $ticket[3]['time']['__jsonclass__'][1];
$dateUpdated = $ticket[3]['_ts'];
$confidential = $ticket[3]['sensitive'];
$confidential = (bool) @$ticket[3]['sensitive'];
$attachments = $this->trac->getAttachments($originalTicketId);
......@@ -162,7 +162,7 @@ class Migration
* @return string
*/
// Adapted from: https://gitlab.dyomedea.com/vdv/trac-to-gitlab/blob/master/trac2down/Trac2Down.py
private function translateTracToMarkdown($text) {
public function translateTracToMarkdown($text) {
$text = str_replace("\r\n", "\n", $text);
// Inline code block
$text = preg_replace('/{{{(.*?)}}}/', '`$1`', $text);
......
......@@ -48,7 +48,6 @@ class Trac
$ticketIds = $this->client->execute('ticket.query', array($query));
foreach($ticketIds as $id) {
$tickets[$id] = $this->getTicket($id);
$tickets[$id][] = $this->getComments($id);
}
return $tickets;
}
......@@ -111,5 +110,10 @@ class Trac
public function getUrl() {
return $this->url;
}
public function getClient()
{
return $this->client;
}
}
?>
<?php
use Trac2GitLab\Migration;
$migration = new Migration(
$config['gitlab-api-url'],
$config['gitlab-access-token'],
$config['gitlab-admin-token'],
$config['trac-url'],
$config['create-trac-links'],
$userMapping = []
);
$trac = $migration->trac;
$gitlab = $migration->gitLab->getClient();
var_dump($trac->getClient()->execute('ticket.query', ['version=trunk&max=0']));
die;
foreach ($result['issues'] as $trac_id => $gitlab_id) {
$comments = $trac->getComments($trac_id);
foreach ($comments as $comment) {
$text = $comment['text'];
// In [changeset:"48002"]:
// {{{
// #!CommitTicketReference repository="" revision="48002"
// fixes #8641
// }}}
// try {
// $gitlab->api('issues')->addComment($config['gitlab-project'], $gitlab_id, [
// 'body' => $comment['text'],
// 'sudo' => $comment['author'],
// 'created_at' => $comment['time']['__jsonclass__'][1],
// ]);
// } catch (Exception $e) {
$gitlab->api('issues')->addComment($config['gitlab-project'], $gitlab_id, [
'body' => $text,
'created_at' => $comment['time']['__jsonclass__'][1],
'updated_at' => $comment['time']['__jsonclass__'][1],
]);
// }
}
}
<?php
define('LOG_REGEXP', '~^r(\d+) = ([0-9a-f]+) \(refs/remotes/git-svn\)~');
// Remove old git directory
if (file_exists($config['temp-path'])) {
rename($config['temp-path'], $config['temp-path'] . '-' . md5(uniqid('conversion', true)));
}
// Clone svn repository as git
$commit_mapping = [];
echo "> git svn clone...";
my_exec(
'git svn clone -r%u:HEAD --no-metadata --authors-file=%s svn://develop.studip.de/studip/trunk %s 2> /dev/null',
$config['trac-revision'],
$config['trac-users'],
$config['temp-path'],
function ($output) use (&$commit_mapping) {
$lines = explode("\n", $output);
foreach ($lines as $line) {
if (!preg_match(LOG_REGEXP, $line, $match)) {
continue;
}
$commit_mapping[$match[1]] = $match[2];
}
return $output;
}
);
echo "done\n";
return $commit_mapping;
......@@ -5,13 +5,29 @@ $issue_mapping = [];
// Actually migrate
$migration = new Migration(
$config['gitlab-url'],
$config['gitlab-api-url'],
$config['gitlab-access-token'],
$config['gitlab-admin-token'],
$config['trac-url'],
$config['create-trac-links'],
$userMapping = []
);
$trac = $migration->trac->getClient();
$step_size = 50;
$page = 1;
do {
$query = "{$config['trac-query']}&page={$page}&max={$step_size}";
try {
$ticket_ids = $trac->execute('ticket.query', [$query]);
$migration->migrate($ticket_ids, $config['gitlab-project']);
} catch (Exception $e) {
$ticket_ids = [];
}
$page += 1;
} while (count($ticket_ids) > 0);
return $migration->migrateQuery(
$config['trac-query'],
$config['gitlab-project']
......
<?php
echo "> Pushing repository...";
my_exec([
['git -C %s remote add origin %s', $config['temp-path'], $config['gitlab-repo-url']],
['git -C %s push origin master', $config['temp-path']]
]);
echo "done\n";
<?php
// Rewrite ticket numbers to issue numbers in commits
echo "> rewrite commit messages...";
$index = 0;
// Skip latest entry for now
foreach (array_reverse(array_slice($commit_mapping, 1)) as $sha1) {
$command = sprintf(
"git log -C %s --color=never --format=%%B -1 %s",
$config['temp-path'],
$sha1
);
$message = my_exec(
"git -C %s log --color=never --format=%%B -1 %s",
$config['temp-path'],
$sha1,
function ($message) use ($result) {
// Replace tickets/issues
$message = preg_replace_callback('/(?<=\s|^|,)#(\d+)\b/', function ($match) use ($result) {
if (isset($result['issues'][$match[1]])) {
return '#' . $result['issues'][$match[1]];
}
return $match[0];
}, $message);
// Replace changesets/commits
$message = preg_replace_callback('/(?<=\s|^|,)\[(\d+(?:,\d+)*)\](?=\s|$|,)/', function ($match) use ($result) {
$changesets = explode(',', $match[1]);
foreach ($changesets as $index => $changeset) {
if (isset($result['commits'][$changeset])) {
$changesets[$index] = $result['commits'][$changeset];
}
}
return '[' . implode(',', $changesets) . ']';
}, $message);
return $message;
}
);
my_exec([
['git -C %s checkout -b amending HEAD~%u', $config['temp-path'], $index + 1],
['git -C %s cherry-pick %s', $config['temp-path'], $sha1],
['git -C %s commit --amend -m "%s"', $config['temp-path'], addslashes($message)],
['git -C %s rebase --onto amending %s master', $config['temp-path'], $sha1],
['git -C %s branch -d amending', $config['temp-path']],
]);
unset($commit_mapping[$sha1]);
$index += 1;
}
echo "done\n";
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment