From 2cac48713cfad224470b2d3bc5713c893830a288 Mon Sep 17 00:00:00 2001 From: Jan-Hendrik Willms <tleilax+github@gmail.com> Date: Fri, 19 Mar 2021 16:28:20 +0100 Subject: [PATCH] more adjustments, cache current progress and allow stopping by pressing q, fixes #2 --- .gitignore | 1 + composer.json | 2 +- convert.php | 5 ++ src/Cache.php | 72 +++++++++++++++++++++++++++++ steps/convert-tickets-to-issues.php | 51 ++++++++++++++------ 5 files changed, 115 insertions(+), 16 deletions(-) create mode 100644 src/Cache.php diff --git a/.gitignore b/.gitignore index 42c8849..ba24927 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ includes/config.php includes/trac-users.txt trac-to-gitlab.phar +cache/* vendor/* puli.phar puli.json diff --git a/composer.json b/composer.json index 5c7c683..198a3d3 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,7 @@ } ], "require": { - "php": ">=5.6.0", + "php": ">=7.0", "ext-mbstring": "*", "ext-json": "*", "m4tthumphrey/php-gitlab-api": "9.9.0", diff --git a/convert.php b/convert.php index e237099..a2dd842 100755 --- a/convert.php +++ b/convert.php @@ -3,6 +3,11 @@ require_once __DIR__ . '/vendor/autoload.php'; require_once __DIR__ . '/includes/functions.php'; +Trac2GitLab\Cache::setPath(__DIR__ . '/cache'); +if ($_SERVER['argc'] > 1 && $_SERVER['argv'][1] === '--clear-cache') { + Trac2GitLab\Cache::getInstance()->clear(); +} + $config = require __DIR__ . '/includes/config.php'; $config['trac-clean-url'] = preg_replace('/(?<=:\/\/).*?:.*?@|\/login/', '${1}', $config['trac-url']); diff --git a/src/Cache.php b/src/Cache.php new file mode 100644 index 0000000..3ddbe57 --- /dev/null +++ b/src/Cache.php @@ -0,0 +1,72 @@ +<?php +namespace Trac2GitLab; + +final class Cache +{ + private static $instance = null; + private static $path = null; + + public static function setPath($path) + { + if (file_exists($path) && !is_dir($path)) { + throw new \Exception("Path {$path} exists and is no folder"); + } elseif (!file_exists($path)) { + mkdir($path); + } + + if (!is_writable($path)) { + throw new \Exception("Path {$path} is not writable"); + } + self::$path = rtrim($path, '/'); + } + + public static function getInstance() + { + if (!isset(self::$path)) { + throw new \Exception('No path has been defined, use Cache::setPath().'); + } + + if (self::$instance === null) { + self::$instance = new self(self::$path); + } + return self::$instance; + } + + private $cache_path; + private $cache; + + private function __construct($path) + { + $this->cache = []; + $this->cache_path = $path; + } + + public function clear() + { + array_map('unlink', glob($this->cache_path . '/*')); + $this->cache = []; + } + + public function get($key, $default = null) + { + $this->cache[$key] = $default; + + $filename = $this->getCacheFilenameForKey($key); + if (file_exists($filename)) { + $this->cache[$key] = json_decode(file_get_contents($filename), true); + } + + return $this->cache[$key]; + } + + public function set($key, $value) + { + $this->cache[$key] = $value; + file_put_contents($this->getCacheFilenameForKey($key), json_encode($value)); + } + + private function getCacheFilenameForKey($key) + { + return $this->cache_path . '/' . md5($key) . '.json'; + } +} diff --git a/steps/convert-tickets-to-issues.php b/steps/convert-tickets-to-issues.php index 47816d3..530c692 100644 --- a/steps/convert-tickets-to-issues.php +++ b/steps/convert-tickets-to-issues.php @@ -1,7 +1,13 @@ <?php use Trac2GitLab\Migration; -$issue_mapping = []; +$cache = Trac2GitLab\Cache::getInstance(); +// Maps svn tickets to gitlab issues +$issue_mapping = $cache->get('issue-mapping', []); +// Trac Milestones that have already been created in Gitlab. +$milestones = $cache->get('milestones', []); +// Milestones that have already been migrated and closed. +$closedMilestones = $cache->get('closed-milestones', []); // Actually migrate $migration = new Migration( @@ -16,14 +22,12 @@ $trac = $migration->trac; $trac_client = $trac->getClient(); $gitlab = $migration->gitLab; -$gitlab_users = $gitlab->listUsers(); +$gitlab_users = []; // $gitlab->listUsers(); $step_size = 50; $page = 1; -// Trac Milestones that have already been created in Gitlab. -$milestones = []; -// Milestones that have already been migrated and closed. -$closedMilestones = []; + +stream_set_blocking(STDIN, 0); do { $query = "{$config['trac-query']}&page={$page}&max={$step_size}"; @@ -35,6 +39,16 @@ do { foreach ($ticket_ids as $ticket_id) { + while ($c = fgetc(STDIN)) { + if ($c === 'q') { + echo "! Stopping process\n"; + exit; + } + } + if (isset($issue_mapping[$ticket_id])) { + continue; + } + try { $ticket = $trac_client->execute('ticket.get', [$ticket_id]); @@ -66,6 +80,7 @@ do { 'id' => $g['id'], 'closed' => is_array($m['completed']) ]; + $cache->set('milestones', $milestones); echo "Created milestone " . $ticket[3]['milestone'] . ".\n"; } } @@ -79,9 +94,10 @@ do { $description, $dateCreated, $assigneeId, $creatorId, $labels, $confidential, $milestone); - echo "Created a GitLab issue #{$issue['iid']} for Trac ticket #{$ticket_id} : {$config['trac-clean-url']}/tickets/{$ticket_id}\n"; + echo "Created a GitLab issue #{$issue['iid']} for Trac ticket #{$ticket_id} : {$config['trac-clean-url']}/ticket/{$ticket_id}\n"; - $mapping[$ticket_id] = $issue['iid']; + $issue_mapping[$ticket_id] = $issue['iid']; + $cache->set('issue-mapping', $issue_mapping); $attachments = $trac->getAttachments($ticket_id); @@ -100,10 +116,11 @@ do { file_put_contents($filename, base64_decode($a['content'])); - $gitlab->createIssueAttachment($config['gitlab-project'], $issue['iid'], $filename, $a['author']); +// $gitlab->createIssueAttachment($config['gitlab-project'], $issue['iid'], $filename, $a['author']); + $gitlab->createIssueAttachment($config['gitlab-project'], $issue['iid'], $filename, null); unlink($filename); - echo "\tAttached file " . $filename . " to issue " . $issue['iid'] . ".\n"; + echo "\tAttached file {$filename} to issue {$issue['iid']}\n"; } // Close issue if Trac ticket was closed. @@ -111,7 +128,8 @@ do { if (isset($ticket[4])) { $gitlab->closeIssue( $config['gitlab-project'], $issue['iid'], - $ticket[4][0]['time']['__jsonclass__'][1], $ticket[4][0]['author'] + $ticket[4][0]['time']['__jsonclass__'][1] +// $ticket[4][0]['time']['__jsonclass__'][1], $ticket[4][0]['author'] ); } else { $gitlab->closeIssue($config['gitlab-project'], $issue['iid']); @@ -124,6 +142,8 @@ do { ) { $gitlab->closeMilestone($config['gitlab-project'], $milestones[$ticket[3]['milestone']]['id']); $closedMilestones[] = $milestones[$ticket[3]['milestone']]['id']; + $cache->set('closed-milestones', $closedMilestones); + echo "\tClosed milestone " . $ticket[3]['milestone'] . ".\n"; } @@ -138,7 +158,8 @@ do { } while (count($ticket_ids) > 0); -return $migration->migrateQuery( - $config['trac-query'], - $config['gitlab-project'] -); +return $issue_mapping; +//$migration->migrateQuery( +// $config['trac-query'], +// $config['gitlab-project'] +//); -- GitLab