The version we used to actually import
[mantis2gitlab] / m2gl.js
diff --git a/m2gl.js b/m2gl.js
old mode 100755 (executable)
new mode 100644 (file)
index 67c0a3b..2a13ff5
--- a/m2gl.js
+++ b/m2gl.js
@@ -26,10 +26,10 @@ var argv = require('optimist')
     .describe('f', 'The first issue # to import (Example: 123)')
     .argv;
 
-var inputFile = __dirname + '/' + argv.input;
-var configFile = __dirname + '/' + argv.config;
+var inputFile = argv.input;
+var configFile = argv.config;
 var fromIssueId = Number(argv.from||0);
-var gitlabAPIURLBase = argv.gitlaburl + '/api/v3';
+var gitlabAPIURLBase = argv.gitlaburl + '/api/v4';
 var gitlabProjectName = argv.project;
 var gitlabAdminPrivateToken = argv.token;
 var gitlabSudo = argv.sudo;
@@ -38,6 +38,7 @@ var config = {};
 var gitLab = {};
 var promise = getConfig()
         .then(readMantisIssues)
+        .then((JSON.stringify(gitLab.mantisIssues)))
         .then(getGitLabProject)
         .then(getGitLabProjectMembers)
         .then(mapGitLabUserIds)
@@ -57,9 +58,10 @@ promise.then(function() {
  */
 function getConfig() {
   log_progress("Reading configuration...");
-  return FS.read(configFile, {encoding: 'utf8'})
+  return FS.read(configFile)
       .then(function(data) {
         var config = JSON.parse(data);
+
         config.users = _.extend({
           "": {
             name: "Unknown",
@@ -83,7 +85,7 @@ function readMantisIssues() {
     var rows = [];
     var dfd = Q.defer();
 
-    csv().from(data, {delimiter: ',', escape: '"', columns: true})
+    csv().from(data, {delimiter: '\t', quote: '~', escape: '~', columns: true})
         .on('record', function(row, index) { rows.push(row) })
         .on('end', function(error, data) {
           dfd.resolve(rows);
@@ -116,8 +118,11 @@ function getGitLabProject() {
   var url = gitlabAPIURLBase + '/projects';
   var data = { per_page: 100, private_token: gitlabAdminPrivateToken, sudo: gitlabSudo };
 
-  return rest.get(url, {data: data}).then(function(result) {
-
+  return rest.get(url, {data: data})
+  .fail(function(err) {
+    console.log(err);
+  })
+  .then(function(result) {
     gitLab.project = _.find(result, { path_with_namespace : gitlabProjectName }) || null;
 
     if (!gitLab.project) {
@@ -152,7 +157,7 @@ function mapGitLabUserIds() {
   var users = config.users,
       gitlabUsers = gitLab.gitlabUsers;
   _.forEach(users, function(user) {
-    user.gl_id = (_.find(gitlabUsers, { id: user.gl_username }) || {}).id;
+    user.gl_id = (_.find(gitlabUsers, { username: user.gl_username }) || {}).id;
   });
 }
 
@@ -211,6 +216,7 @@ function importIssue(mantisIssue) {
   var milestoneId = '';
   var labels = getLabels(mantisIssue);
   var author = getUserByMantisUsername(mantisIssue.Reporter);
+  var created = mantisIssue.Created.replace(" ", "T") + "Z";
 
   log_progress("Importing: #" + issueId + " - " + title + " ...");
 
@@ -220,59 +226,55 @@ function importIssue(mantisIssue) {
     assignee_id: assignee && assignee.gl_id,
     milestone_id: milestoneId,
     labels: labels,
+    created_at: created,
     sudo: gitlabSudo,
     private_token: gitlabAdminPrivateToken
   };
 
   return getIssue(gitLab.project.id, issueId)
       .then(function(gitLabIssue) {
-        if (gitLabIssue) {
-          return updateIssue(gitLab.project.id, gitLabIssue.id, _.extend({
+        if (gitLab.gitlabIssues[issueId]) {
+          // update
+          console.log("updating: " + data.title + " (Issueid: " + issueId + ")");
+          return updateIssue(gitLab.project.id, gitLabIssue.iid, _.extend({
             state_event: isClosed(mantisIssue) ? 'close' : 'reopen'
           }, data))
               .then(function() {
-                console.log(("#" + issueId + ": Updated successfully.").green);
+                console.log(("#" + gitLabIssue.iid + ": Updated successfully.").green);
               });
         } else {
+          // insert
+          console.log("inserting: " + data.title + " (Issueid: " + issueId + ")");
+          data.iid = issueId;
+          return insertAndCloseIssue(issueId, data, isClosed(mantisIssue));
+/*
           return insertSkippedIssues(issueId-1)
               .then(function() {
                 return insertAndCloseIssue(issueId, data, isClosed(mantisIssue));
               });
+*/
         }
       });
 }
 
 function insertSkippedIssues(issueId) {
-  if (gitLab.gitlabIssues[issueId]) {
+  if (issueId < 1 || gitLab.gitlabIssues[issueId]) {
     return Q();
   }
 
-  console.warn(("Skipping Missing Mantis Issue (<= #" + issueId + ") ...").yellow);
+  console.log(("Adding placeholder ...").yellow);
 
   var data = {
-    title: "Skipped Mantis Issue",
+    title: "-- Platzhalter --",
+    description: "Diese Bugnummer war in Mantis einem anderen Projekt zugeordnet. Dieser Platzhalter sorgt dafuer, dass die Bugnummern in Mantis mit denen in Gitlab uebereinstimmen.",
     sudo: gitlabSudo,
     private_token: gitlabAdminPrivateToken
   };
 
-  return insertAndCloseIssue(issueId, data, true, getSkippedIssueData)
+  return insertAndCloseIssue(issueId, data, true)
       .then(function() {
         return insertSkippedIssues(issueId);
       });
-
-  function getSkippedIssueData(gitLabIssue) {
-    var issueId = gitLabIssue.iid;
-    var description;
-    if (config.mantisUrl) {
-      description = "[Mantis Issue " + issueId + "](" + config.mantisUrl + "/view.php?id=" + issueId + ")";
-    } else {
-      description = "Mantis Issue " + issueId;
-    }
-    return {
-      title: "Skipped Mantis Issue " + issueId,
-      description: "_Skipped " + description + "_"
-    };
-  }
 }
 
 function insertAndCloseIssue(issueId, data, close, custom) {
@@ -282,15 +284,15 @@ function insertAndCloseIssue(issueId, data, close, custom) {
     if (close) {
       return closeIssue(issue, custom && custom(issue)).then(
           function() {
-            console.log((issueId + ': Inserted and closed successfully. #' + issue.iid).green);
+            console.log((issue.iid + ': Inserted and closed successfully. #' + issue.iid).green);
           }, function(error) {
-            console.warn((issueId + ': Inserted successfully but failed to close. #' + issue.iid).yellow);
+            console.warn((issue.iid + ': Inserted successfully but failed to close. #' + issue.iid).yellow);
           });
     }
 
-    console.log((issueId + ': Inserted successfully. #' + issue.iid).green);
+    console.log((issue.iid + ': Inserted successfully. #' + issue.iid).green);
   }, function(error) {
-    console.error((issueId + ': Failed to insert.').red, error);
+    console.error((issue.iid + ': Failed to insert.').red, error);
   });
 }
 
@@ -318,10 +320,13 @@ function getRemainingGitLabProjectIssues(page, per_page) {
   var data = {
     page: page,
     per_page: per_page,
-    order_by: 'id',
     private_token: gitlabAdminPrivateToken, sudo: gitlabSudo };
 
-  return rest.get(url, {data: data}).then(function(issues) {
+  return rest.get(url, {data: data})
+  .fail(function(err) {
+    console.log(err);
+  })
+  .then(function(issues) {
     if(issues.length < per_page) {
       return issues;
     }
@@ -352,9 +357,11 @@ function getDescription(row) {
     attributes.push("Reported By: " + value);
   }
 
+/* omit ...
   if (value = row["Assigned To"]) {
     attributes.push("Assigned To: " + value);
   }
+*/
 
   if (value = row.Created) {
     attributes.push("Created: " + value);
@@ -376,6 +383,24 @@ function getDescription(row) {
     description += "\n\n" + value.split("$$$$").join("\n\n")
   }
 
+  if (value = row.Attachments) {
+    description += "\n\n" + value.split("$$$$").join("\n\n")
+  }
+
+  description = description.replace(/\\n/g, "\n");
+  description = description.replace(/\\t/g, "  ");
+  description = description.replace(/``/g, '"');
+  description = description.replace(/''/g, '"');
+  description = description.replace(/\n *----/g, "\n>>>");
+
+  Object.keys(config.users).forEach(function(muser) {
+    if (muser != "") {
+        var gluser = config.users[muser].gl_username;
+        var re = new RegExp(muser, "g");
+        description = description.replace(re, "@" + gluser);
+    }
+  });
+
   return description;
 }
 
@@ -427,8 +452,8 @@ function insertIssue(projectId, data) {
       });
 }
 
-function updateIssue(projectId, issueId, data) {
-  var url = gitlabAPIURLBase + '/projects/' + projectId + '/issues/' + issueId;
+function updateIssue(projectId, issueIId, data) {
+  var url = gitlabAPIURLBase + '/projects/' + projectId + '/issues/' + issueIId;
 
   return rest.put(url, {data: data})
       .then(null, function(error) {
@@ -437,7 +462,7 @@ function updateIssue(projectId, issueId, data) {
 }
 
 function closeIssue(issue, custom) {
-  var url = gitlabAPIURLBase + '/projects/' + issue.project_id + '/issues/' + issue.id;
+  var url = gitlabAPIURLBase + '/projects/' + issue.project_id + '/issues/' + issue.iid;
   var data = _.extend({
     state_event: 'close',
     private_token: gitlabAdminPrivateToken,
@@ -453,4 +478,4 @@ function closeIssue(issue, custom) {
 
 function log_progress(message) {
   console.log(message.grey);
-}
\ No newline at end of file
+}