diff --git a/CHANGELOG.txt b/CHANGELOG.txt
new file mode 100644
index 0000000000000000000000000000000000000000..6d07ad585f3627694c24aed4005343c746957884
--- /dev/null
+++ b/CHANGELOG.txt
@@ -0,0 +1,5 @@
+1.0.1
+ - Added support for migrating comments on tickets
+
+1.0.0
+ - Initial release
\ No newline at end of file
diff --git a/README.md b/README.md
index 0e04c3fd9fba1287ed52be69c8a737f21437654e..60d53f19ce0f84e26f95877b0aab7e8ee4362c01 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,8 @@ This command line utility migrates Trac tickets to GitLab issues using Trac and
* Migrates open tickets of a single Trac component
* Migrates any tickets matching a specific Trac query
-* Keeps the original author and assignee when migrating
+* Migrates comments on the tickets to notes on the issues
+* Keeps the original author and assignee when migrating (also for comments)
* Supports mapping Trac usernames to GitLab usernames
* Converts WikiFormatting into GitLab Flavoured Markdown
* Optionally generates a link back to the original Ticket in the GitLab issue
@@ -36,7 +37,7 @@ All configuration options are passed as arguments on the command line. To get an
## As a pre-compiled phar
```bash
-curl -O http://apps.dachaz.net/trac-to-gitlab/bin/1.0.0/trac-to-gitlab.phar
+curl -O http://apps.dachaz.net/trac-to-gitlab/bin/1.0.1/trac-to-gitlab.phar
php trac-to-gitlab.phar
```
diff --git a/composer.json b/composer.json
index bde91682e2b71f11b5994daeaed3cca45a028ed2..9a75e44aaec401a93c740892c82f8e31959c18cc 100644
--- a/composer.json
+++ b/composer.json
@@ -1,6 +1,6 @@
{
"name": "dachaz/trac-to-gitlab",
- "version": "1.0.0",
+ "version": "1.0.1",
"type": "CLI utility",
"description": "Command line utility to migrate Trac tickets to GitLab issues",
"homepage": "https://github.com/Dachaz/trac-to-gitlab",
diff --git a/src/GitLab.php b/src/GitLab.php
index 787873b93d1cc0f88a87403f4bef3c481fe324f3..621edd5fc79fb3f1486cbb845e7c2c7eb2d620ca 100644
--- a/src/GitLab.php
+++ b/src/GitLab.php
@@ -84,6 +84,31 @@ class GitLab
return $issue;
}
+ /**
+ * Creates a new note in the given project and on the given issue id (NOTE: id, not iid). When working in admin mode, tries to create the note
+ * as the given author (SUDO) and if that fails, tries creating the note again as the admin.
+ * @param mixed $projectId Numeric project id (e.g. 17) or the unique string identifier (e.g. 'dachaz/trac-to-gitlab')
+ * @param int $issueId Unique identifier of the issue
+ * @param string $text Text of the note
+ * @param int $authorId Numeric user id of the user who created the issue. Only used in admin mode. Can be null.
+ * @return Gitlab\Model\Note
+ */
+ public function createNote($projectId, $issueId, $text, $authorId) {
+ try {
+ // Try to add, potentially as an admin (SUDO authorId)
+ $note = $this->doCreateNote($projectId, $issueId, $text, $authorId, $this->isAdmin);
+ } 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) {
+ $note = $this->doCreateNote($projectId, $issueId, $text, $authorId, false);
+ } else {
+ // If adding has failed for some other reason, propagate the exception back
+ throw $e;
+ }
+ }
+ return $note;
+ }
+
// Actually creates the issue
private function doCreateIssue($projectId, $title, $description, $assigneeId, $authorId, $labels, $isAdmin) {
$issueProperties = array(
@@ -98,6 +123,17 @@ class GitLab
return $this->client->api('issues')->create($projectId, $issueProperties);
}
+ // Actually creates the note
+ private function doCreateNote($projectId, $issueId, $text, $authorId, $isAdmin) {
+ $noteProperties = array(
+ 'body' => $text
+ );
+ if ($isAdmin) {
+ $noteProperties['sudo'] = $authorId;
+ }
+ return $this->client->api('issues')->addComment($projectId, $issueId, $noteProperties);
+ }
+
/**
* Returns the URL of this GitLab installation.
* @return string
diff --git a/src/Migration.php b/src/Migration.php
index 660f01f2b40b9f1f6bac90070eefda065aa7bf08..aafab8ac60caed5dfa53c31bcdd26b742bc97cfb 100644
--- a/src/Migration.php
+++ b/src/Migration.php
@@ -109,6 +109,17 @@ class Migration
$issue = $this->gitLab->createIssue($gitLabProject, $title, $description, $assigneeId, $creatorId, $labels);
echo 'Created a GitLab issue #' . $issue['iid'] . ' for Trac ticket #' . $originalTicketId . ' : ' . $this->gitLab->getUrl() . '/' . $gitLabProject . '/issues/' . $issue['iid'] . "\n";
+
+ // If there are comments on the ticket, create notes on the issue
+ if (is_array($ticket[4]) && count($ticket[4])) {
+ foreach($ticket[4] as $comment) {
+ $commentAuthor = $this->getGitLabUser($comment['author']);
+ $commentAuthorId = is_array($commentAuthor) ? $commentAuthor['id'] : null;
+ $commentText = $this->translateTracToMarkdown($comment['text']);
+ $note = $this->gitLab->createNote($gitLabProject, $issue['id'], $commentText, $commentAuthorId);
+ }
+ echo "\tAlso created " . count($ticket[4]) . " note(s)\n";
+ }
}
}
diff --git a/src/Trac.php b/src/Trac.php
index ebebe6ab03e772fb6850e1da7b5b5c136c3f96db..02e2bb6b85bcfd29e981afc0e005da88752c83da 100644
--- a/src/Trac.php
+++ b/src/Trac.php
@@ -26,7 +26,7 @@ class Trac
/**
* Returns all open tickets for the given component name.
- * Each ticket is an array of [id, time_created, time_changed, attributes]
+ * Each ticket is an array of [id, time_created, time_changed, attributes, comments]
*
* @param string $component Name of the component.
* @return array
@@ -37,7 +37,7 @@ class Trac
/**
* Returns all tickets matching the given query.
- * Each ticket is an array of [id, time_created, time_changed, attributes]
+ * Each ticket is an array of [id, time_created, time_changed, attributes, comments]
*
* @param string $query Custom query to be executed in order to obtain tickets.
* @return array
@@ -47,6 +47,7 @@ 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;
}
@@ -62,6 +63,28 @@ class Trac
return $this->client->execute('ticket.get', array($id));
}
+ /**
+ * Returns an array of comments on an individual ticket.
+ * Each individual comment is itself an associative array of [time, author, text]
+ *
+ * @param int $id Id of the ticket.
+ * @return array
+ */
+ public function getComments($ticketId) {
+ $comments = array();
+ $changes = $this->client->execute('ticket.changeLog', array($ticketId));
+ foreach ($changes as $change) {
+ if ($change[2] == "comment" && trim($change[4])) {
+ $comments[] = array(
+ "time" => $change[0],
+ "author" => $change[1],
+ "text" => $change[4]
+ );
+ }
+ }
+ return $comments;
+ }
+
/**
* Returns the URL of this Trac installation.
* @return string