From 8fb8b90f1466ba40cc02af75bf21af1d08448e23 Mon Sep 17 00:00:00 2001 From: Shoma Nishitateno Date: Fri, 8 Dec 2017 15:10:09 +0900 Subject: [PATCH 01/10] next version --- README.md | 4 ++-- build.sbt | 2 +- src/main/resources/application.conf | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index ff9acf1f..ea966595 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ Download Please download the jar file from this link, and run from the command line as follows. -https://github.com/nulab/BacklogMigration-Jira/releases/download/0.1.0b1/backlog-migration-jira-0.1.0b1.jar +https://github.com/nulab/BacklogMigration-Jira/releases/download/0.1.0b2-SNAPSHOT/backlog-migration-jira-0.1.0b2-SNAPSHOT.jar java -jar backlog-migration-jira-[latest version].jar @@ -227,7 +227,7 @@ https://github.com/nulab/BacklogMigration-Jira/releases こちらのリンクからjarファイルをダウンロードし、以下のようにコマンドラインから実行します。 -https://github.com/nulab/BacklogMigration-Jira/releases/download/0.1.0b1/backlog-migration-jira-0.1.0b1.jar +https://github.com/nulab/BacklogMigration-Jira/releases/download/0.1.0b2-SNAPSHOT/backlog-migration-jira-0.1.0b2-SNAPSHOT.jar java -jar backlog-migration-jira-[最新バージョン].jar diff --git a/build.sbt b/build.sbt index eec44634..d136ef66 100644 --- a/build.sbt +++ b/build.sbt @@ -1,6 +1,6 @@ import sbt.Keys._ -lazy val projectVersion = "0.1.0b1" +lazy val projectVersion = "0.1.0b2-SNAPSHOT" lazy val commonSettings = Seq( organization := "com.nulabinc", diff --git a/src/main/resources/application.conf b/src/main/resources/application.conf index c9c3ae22..d82744c7 100644 --- a/src/main/resources/application.conf +++ b/src/main/resources/application.conf @@ -1,9 +1,9 @@ application { name = "Backlog Migration for Jira" - version = "0.1.0b1" + version = "0.1.0b2-SNAPSHOT" title = ${application.name} ${application.version} (c) nulab.inc export-limit-at-once = 100 - mixpanel.token = "5be8b628b7103858164142d02cb38347" + mixpanel.token = "6aad3862b3514d664ebb4501f86f42c8" mixpanel.product = "jira" language=default akka.mailbox-pool = 100 From 87eda0d1ed350b42aeb39ae9f0ebaf147ae4c272 Mon Sep 17 00:00:00 2001 From: Shoma Nishitateno Date: Fri, 8 Dec 2017 16:53:57 +0900 Subject: [PATCH 02/10] Add demo --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index ea966595..489ddea9 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,12 @@ Migrate your projects from JIRA to [Backlog]. * Backlog * [https://backlog.com](https://backlog.com/) + +## DEMO + +![Demo](https://www.backlog.jp/backlog-migration/backlog-jira-migration.gif) + + ## Requirements * **Java 8** * The Backlog Space's **administrator** roles. From c47f4317a378e9f0aed4fbb0c220bd63cf8a4302 Mon Sep 17 00:00:00 2001 From: Shoma Nishitateno Date: Mon, 11 Dec 2017 11:46:21 +0900 Subject: [PATCH 03/10] Trim body --- src/test/scala/com/nulabinc/backlog/j2b/CompareSpec.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/scala/com/nulabinc/backlog/j2b/CompareSpec.scala b/src/test/scala/com/nulabinc/backlog/j2b/CompareSpec.scala index 4bada080..60905ec1 100644 --- a/src/test/scala/com/nulabinc/backlog/j2b/CompareSpec.scala +++ b/src/test/scala/com/nulabinc/backlog/j2b/CompareSpec.scala @@ -270,7 +270,7 @@ class CompareSpec extends FlatSpec jiraCommentService.issueComments(jiraIssue).filterNot { jiraComment => attachmentCommentPattern.findFirstIn(jiraComment.body).isDefined }.map { jiraComment => - val backlogComment = backlogAllComments.find(_.getContent == jiraComment.body) + val backlogComment = backlogAllComments.find(_.getContent == jiraComment.body.trim) backlogComment should not be empty assertUser(jiraComment.author, backlogComment.get.getCreatedUser) timestampToString(jiraComment.createdAt.toDate) should be(timestampToString(backlogComment.get.getCreated)) From dff055b0d7677b30e7770ee05ebf9191d5463181 Mon Sep 17 00:00:00 2001 From: Shoma Nishitateno Date: Mon, 11 Dec 2017 15:03:01 +0900 Subject: [PATCH 04/10] Add to description --- .../ChangeLogIssueLinkConverter.scala | 44 +++++++++++++++++++ .../backlog/j2b/exporter/Exporter.scala | 4 +- .../client/domain/changeLog/ChangeLog.scala | 2 + 3 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 exporter/src/main/scala/com/nulabinc/backlog/j2b/exporter/ChangeLogIssueLinkConverter.scala diff --git a/exporter/src/main/scala/com/nulabinc/backlog/j2b/exporter/ChangeLogIssueLinkConverter.scala b/exporter/src/main/scala/com/nulabinc/backlog/j2b/exporter/ChangeLogIssueLinkConverter.scala new file mode 100644 index 00000000..a267913e --- /dev/null +++ b/exporter/src/main/scala/com/nulabinc/backlog/j2b/exporter/ChangeLogIssueLinkConverter.scala @@ -0,0 +1,44 @@ +package com.nulabinc.backlog.j2b.exporter + +import com.nulabinc.backlog.migration.common.domain.BacklogIssue +import com.nulabinc.jira.client.domain.changeLog._ + +object ChangeLogIssueLinkConverter { + + def convert(changeLogs: Seq[ChangeLog], backlogIssue: BacklogIssue): Seq[ChangeLog] = { + val displayStrings = changeLogs.flatMap { changeLog => + changeLog.items + .filter { item => item.field == DefaultField("link_issue") } + .flatMap { _.toDisplayString } + } + + val linkedIssueChangeLogItems = if (displayStrings.nonEmpty) { + val lastDescription = changeLogs.reverse.flatMap { changeLog => + changeLog.items.reverse.find(_.field == DescriptionChangeLogItemField) + }.headOption.flatMap(_.toDisplayString) + + Seq( + ChangeLog( + id = 0, // TODO: Check + author = changeLogs.last.author, + createdAt = changeLogs.last.createdAt, + items = Seq( + ChangeLogItem( + field = DescriptionChangeLogItemField, + fieldType = ChangeLogItem.FieldType.JIRA, + fieldId = Some(DescriptionFieldId), + from = None, + fromDisplayString = lastDescription, + to = None, + toDisplayString = Some(lastDescription.getOrElse("") + backlogIssue.description + "\n\n" + displayStrings.mkString("\n")) + ) + ) + ) + ) + } else { + Seq.empty[ChangeLog] + } + + changeLogs ++ linkedIssueChangeLogItems + } +} diff --git a/exporter/src/main/scala/com/nulabinc/backlog/j2b/exporter/Exporter.scala b/exporter/src/main/scala/com/nulabinc/backlog/j2b/exporter/Exporter.scala index 79e0ba59..c5d2d5b5 100644 --- a/exporter/src/main/scala/com/nulabinc/backlog/j2b/exporter/Exporter.scala +++ b/exporter/src/main/scala/com/nulabinc/backlog/j2b/exporter/Exporter.scala @@ -155,7 +155,9 @@ class Exporter @Inject()(projectKey: JiraProjectKey, // export issue comments val categoryPlayedChangeLogs = ChangeLogsPlayer.play(ComponentChangeLogItemField, initializedBacklogIssue.categoryNames, issueWithFilteredChangeLogs.changeLogs) val versionPlayedChangeLogs = ChangeLogsPlayer.play(FixVersion, initializedBacklogIssue.versionNames, categoryPlayedChangeLogs) - val changeLogs = ChangeLogStatusConverter.convert(versionPlayedChangeLogs, statuses) + val statusPlayedChangeLogs = ChangeLogStatusConverter.convert(versionPlayedChangeLogs, statuses) + val changeLogs = ChangeLogIssueLinkConverter.convert(statusPlayedChangeLogs, initializedBacklogIssue) + commentWriter.write(initializedBacklogIssue, comments, changeLogs, issue.attachments) console(i + index.toInt, total.toInt) diff --git a/jira-client/src/main/scala/com/nulabinc/jira/client/domain/changeLog/ChangeLog.scala b/jira-client/src/main/scala/com/nulabinc/jira/client/domain/changeLog/ChangeLog.scala index 92877737..8c98572a 100644 --- a/jira-client/src/main/scala/com/nulabinc/jira/client/domain/changeLog/ChangeLog.scala +++ b/jira-client/src/main/scala/com/nulabinc/jira/client/domain/changeLog/ChangeLog.scala @@ -35,6 +35,7 @@ case object TimeSpentChangeLogItemField extends ChangeLogItemField("timespent") case object WorkIdChangeLogItemField extends ChangeLogItemField("WorklogId") case object TimeEstimateChangeLogItemField extends ChangeLogItemField("timeestimate") case object SprintChangeLogItemField extends ChangeLogItemField("Sprint") +case object DescriptionChangeLogItemField extends ChangeLogItemField("description") case class DefaultField(name: String) extends ChangeLogItemField(name) object ChangeLogItemField { @@ -53,6 +54,7 @@ object ChangeLogItemField { case WorkIdChangeLogItemField.value => WorkIdChangeLogItemField case TimeEstimateChangeLogItemField.value => TimeEstimateChangeLogItemField case SprintChangeLogItemField.value => SprintChangeLogItemField + case DescriptionChangeLogItemField.value => DescriptionChangeLogItemField case v => DefaultField(v) } } From 388efb02a87a3b937f1c3c48595ff0c3b9cd455d Mon Sep 17 00:00:00 2001 From: Shoma Nishitateno Date: Mon, 11 Dec 2017 15:24:50 +0900 Subject: [PATCH 05/10] Modify test --- .../com/nulabinc/backlog/j2b/CompareSpec.scala | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/test/scala/com/nulabinc/backlog/j2b/CompareSpec.scala b/src/test/scala/com/nulabinc/backlog/j2b/CompareSpec.scala index 60905ec1..82914d48 100644 --- a/src/test/scala/com/nulabinc/backlog/j2b/CompareSpec.scala +++ b/src/test/scala/com/nulabinc/backlog/j2b/CompareSpec.scala @@ -9,6 +9,7 @@ import com.nulabinc.backlog.migration.common.convert.writes.UserWrites import com.nulabinc.backlog4j.{CustomFieldSetting, IssueComment, ResponseList} import com.nulabinc.backlog4j.api.option.{GetIssuesParams, QueryParams} import com.nulabinc.backlog4j.internal.json.customFields._ +import com.nulabinc.jira.client.domain.changeLog.LinkChangeLogItemField import com.nulabinc.jira.client.domain.field._ import com.nulabinc.jira.client.domain.issue._ import org.scalatest.{DiagrammedAssertions, FlatSpec, Matchers} @@ -132,9 +133,6 @@ class CompareSpec extends FlatSpec maybeBacklogIssue.map { backlogIssue => - // description - jiraIssue.description.getOrElse("") should equal(backlogIssue.getDescription) - // issue type jiraIssue.issueType.name should equal(backlogIssue.getIssueType.getName) @@ -280,7 +278,8 @@ class CompareSpec extends FlatSpec // Test // - creator is same // - created at is same - jiraIssueService.changeLogs(jiraIssue).map { jiraChangeLog => + val jiraChangeLogs = jiraIssueService.changeLogs(jiraIssue) + jiraChangeLogs.map { jiraChangeLog => val backlogChangelog = backlogAllComments.find { backlogComment => timestampToString(backlogComment.getCreated) == timestampToString(jiraChangeLog.createdAt.toDate) } @@ -288,6 +287,12 @@ class CompareSpec extends FlatSpec assertUser(jiraChangeLog.author, backlogChangelog.get.getCreatedUser) } + // description + val links = jiraChangeLogs.flatMap(_.items.filter(_.field == LinkChangeLogItemField).flatMap(_.toDisplayString)) + val linksReplace = "\n\n" + links.mkString("\n") + val backlogDescription = backlogIssue.getDescription.replace(linksReplace, "") + jiraIssue.description.getOrElse("") should equal(backlogDescription) + } } From 1eaa33e239ac54b5e6f545075c3162281833d56a Mon Sep 17 00:00:00 2001 From: Shoma Nishitateno Date: Mon, 11 Dec 2017 15:45:05 +0900 Subject: [PATCH 06/10] Fix when received invalid arguments. --- src/main/resources/messages.txt | 1 + src/main/resources/messages_ja.txt | 1 + .../scala/com/nulabinc/backlog/j2b/Main.scala | 23 +++++++++++++------ 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/main/resources/messages.txt b/src/main/resources/messages.txt index c1e64255..cd8b8e16 100644 --- a/src/main/resources/messages.txt +++ b/src/main/resources/messages.txt @@ -53,6 +53,7 @@ cli.help.projectKey=Your JIRA project identifier.(required) Example:--projectKey cli.confirm_recreate=The mapping file {0} already exists. Do you want to overwrite it? (y/n [n]): cli.backlog_project_already_exist=Project "{0}" already exists. Do you want to import issues and wikis to project "{0}"? (Check the README file for details.) (y/n [n]): cli.error.unknown=Unknown error +cli.error.args=Invalid arguments. Please check the following. cli.cancel=Import has been canceled. cli.invalid_setup=Setup is incomplete. Please complete the set up with the sub-command "export". Add "--help" option to know about the "export" command. cli.warn.not.latest=The latest version [{0}] has been released. The current version is [{1}]. diff --git a/src/main/resources/messages_ja.txt b/src/main/resources/messages_ja.txt index d7027560..d7489f80 100644 --- a/src/main/resources/messages_ja.txt +++ b/src/main/resources/messages_ja.txt @@ -54,6 +54,7 @@ cli.help.projectKey=移行したいJIRAプロジェクトのプロジェクト cli.confirm_recreate={0}マッピングファイルが既にあります。上書きしますか? (y/n [n]): cli.backlog_project_already_exist=プロジェクト[{0}]はBacklog内に既に存在します。\nプロジェクト[{0}]に課題とWikiをインポートしますか?(追加インポートの仕様については、詳細READMEを参照ください) (y/n [n]): cli.error.unknown=予期しないエラーが発生しました。 +cli.error.args=不正な引数です。以下をご確認下さい。 cli.cancel=インポートを中止しました。 cli.invalid_setup=エクスポートが不十分です。サブコマンド[export]を使用し再度エクスポートしてください。[export]コマンドについて知るには、[--help]オプションをつけて実行してください。 cli.warn.not.latest=最新バージョン[{0}]がリリースされています。現在のバージョンは[{1}]です。 diff --git a/src/main/scala/com/nulabinc/backlog/j2b/Main.scala b/src/main/scala/com/nulabinc/backlog/j2b/Main.scala index ab336871..e894acd4 100644 --- a/src/main/scala/com/nulabinc/backlog/j2b/Main.scala +++ b/src/main/scala/com/nulabinc/backlog/j2b/Main.scala @@ -12,6 +12,8 @@ import com.osinka.i18n.Messages import org.fusesource.jansi.AnsiConsole import org.rogach.scallop.{ScallopConf, Subcommand} +import scala.util.{Failure, Success, Try} + class CommandLineInterface(arguments: Seq[String]) extends ScallopConf(arguments) with BacklogConfiguration with Logging { banner( @@ -105,15 +107,22 @@ object J2B extends BacklogConfiguration with Logging { // Run try { val cli = new CommandLineInterface(args) - val config = getConfiguration(cli) val nextCommand = new NextCommand(args) - cli.subcommand match { - case Some(cli.importCommand) => J2BCli.`import`(config) - case Some(cli.exportCommand) => J2BCli.export(config, nextCommand) - case _ => J2BCli.help() + getConfiguration(cli) match { + case Success(config) => + cli.subcommand match { + case Some(cli.importCommand) => J2BCli.`import`(config) + case Some(cli.exportCommand) => J2BCli.export(config, nextCommand) + case _ => J2BCli.help() + } + exit(0) + case Failure(failure) => + ConsoleOut.error(s"${Messages("cli.error.args")}") + logger.error(failure.getMessage) + J2BCli.help() + exit(1) } - exit(0) } catch { case e: Throwable => logger.error(e.getMessage, e) @@ -122,7 +131,7 @@ object J2B extends BacklogConfiguration with Logging { } } - private[this] def getConfiguration(cli: CommandLineInterface) = { + private[this] def getConfiguration(cli: CommandLineInterface) = Try { val keys: Array[String] = cli.importCommand.projectKey().split(":") val jira: String = keys(0) val backlog: String = if (keys.length == 2) keys(1) else keys(0).toUpperCase.replaceAll("-", "_") From 4ff76cc0fd0399b06abae61be732c040e5e95b05 Mon Sep 17 00:00:00 2001 From: Shoma Nishitateno Date: Mon, 11 Dec 2017 17:58:32 +0900 Subject: [PATCH 07/10] Add export remaining time calculator --- .../backlog/j2b/exporter/Exporter.scala | 13 ++- .../console/RemainingTimeCalculator.scala | 106 ++++++++++++++++++ src/main/resources/messages.txt | 3 + src/main/resources/messages_ja.txt | 3 + 4 files changed, 121 insertions(+), 4 deletions(-) create mode 100644 exporter/src/main/scala/com/nulabinc/backlog/j2b/exporter/console/RemainingTimeCalculator.scala diff --git a/exporter/src/main/scala/com/nulabinc/backlog/j2b/exporter/Exporter.scala b/exporter/src/main/scala/com/nulabinc/backlog/j2b/exporter/Exporter.scala index c5d2d5b5..76c1aca2 100644 --- a/exporter/src/main/scala/com/nulabinc/backlog/j2b/exporter/Exporter.scala +++ b/exporter/src/main/scala/com/nulabinc/backlog/j2b/exporter/Exporter.scala @@ -2,6 +2,7 @@ package com.nulabinc.backlog.j2b.exporter import javax.inject.Inject +import com.nulabinc.backlog.j2b.exporter.console.RemainingTimeCalculator import com.nulabinc.backlog.j2b.jira.conf.JiraBacklogPaths import com.nulabinc.backlog.j2b.jira.domain.mapping.MappingCollectDatabase import com.nulabinc.backlog.j2b.jira.domain.{CollectData, JiraProjectKey} @@ -65,7 +66,8 @@ class Exporter @Inject()(projectKey: JiraProjectKey, val statuses = statusService.all() val total = issueService.count() val fields = fieldService.all() - fetchIssue(statuses, categories, versions, fields, 1, total, 0, 100) + val calculator = new RemainingTimeCalculator(total) + fetchIssue(calculator, statuses, categories, versions, fields, 1, total, 0, 100) // version & milestone versionsWriter.write(versions, mappingCollectDatabase.milestones) @@ -86,7 +88,8 @@ class Exporter @Inject()(projectKey: JiraProjectKey, collectedData } - private def fetchIssue(statuses: Seq[Status], + private def fetchIssue(calculator: RemainingTimeCalculator, + statuses: Seq[Status], components: Seq[Component], versions: Seq[Version], fields: Seq[Field], @@ -160,7 +163,9 @@ class Exporter @Inject()(projectKey: JiraProjectKey, commentWriter.write(initializedBacklogIssue, comments, changeLogs, issue.attachments) - console(i + index.toInt, total.toInt) +// console(i + index.toInt, total.toInt) + + calculator.progress(i + index.toInt, total.toInt, issue.summary) val changeLogUsers = changeLogs.map(u => Some(u.author.name)) val changeLogItemUsers = changeLogs.flatMap { changeLog => @@ -196,7 +201,7 @@ class Exporter @Inject()(projectKey: JiraProjectKey, } } } - fetchIssue(statuses, components, versions, fields, index + issues.length , total, startAt + maxResults, maxResults) + fetchIssue(calculator, statuses, components, versions, fields, index + issues.length , total, startAt + maxResults, maxResults) } } diff --git a/exporter/src/main/scala/com/nulabinc/backlog/j2b/exporter/console/RemainingTimeCalculator.scala b/exporter/src/main/scala/com/nulabinc/backlog/j2b/exporter/console/RemainingTimeCalculator.scala new file mode 100644 index 00000000..5933565e --- /dev/null +++ b/exporter/src/main/scala/com/nulabinc/backlog/j2b/exporter/console/RemainingTimeCalculator.scala @@ -0,0 +1,106 @@ +package com.nulabinc.backlog.j2b.exporter.console + +import java.util.Date + +import com.nulabinc.backlog.migration.common.utils.{ConsoleOut, DateUtil, Logging, ProgressBar} +import com.osinka.i18n.Messages +import org.fusesource.jansi.Ansi +import org.fusesource.jansi.Ansi.Color._ +import org.fusesource.jansi.Ansi.ansi + +class RemainingTimeCalculator(totalSize: Long) extends Logging { + + var failed = 0 + var date = "" + + private case class RemainingTime(totalSize: Long, lastTime: Long = System.currentTimeMillis(), totalElapsedTime: Long = 0, count: Long = 0) { + + def action(): RemainingTime = { + val elapsedTime: Long = System.currentTimeMillis() - this.lastTime + this.copy( + lastTime = System.currentTimeMillis(), + totalElapsedTime = totalElapsedTime + elapsedTime, + count = count + 1 + ) + } + + def average: Float = totalElapsedTime.toFloat / count.toFloat + + def remaining: Long = totalSize - count + + def remainingTime: Long = (remaining * average).toLong + } + + private var remainingTime = RemainingTime(totalSize) + + private[this] var newLine = false + private[this] var isMessageMode = false + + def warning(indexOfDate: Int, totalOfDate: Int, value: String) = { + message(indexOfDate: Int, totalOfDate: Int, value: String, YELLOW) + } + + def error(indexOfDate: Int, totalOfDate: Int, value: String) = { + message(indexOfDate: Int, totalOfDate: Int, value: String, RED) + } + + private[this] def message(indexOfDate: Int, totalOfDate: Int, value: String, color: Ansi.Color): Unit = { + clear() + val message = + s"""${(" " * 11) + ansi().fg(color).a(value.replaceAll("\n", "")).reset().toString} + |${current(indexOfDate, totalOfDate, value)} + |-------------------------------------------------- + |${remaining()}""".stripMargin + + ConsoleOut.outStream.println(message) + isMessageMode = true + } + + def progress(indexOfDate: Int, totalOfDate: Int, summary: String) = { + newLine = (indexOfDate == 1) + clear() + remainingTime = remainingTime.action() + val message = + s"""${current(indexOfDate, totalOfDate, summary)} + |-------------------------------------------------- + |${remaining()}""".stripMargin + ConsoleOut.outStream.println(message) + isMessageMode = false + } + + private[this] def clear() = { + if (newLine && !isMessageMode) { + ConsoleOut.outStream.println() + } + (0 until 3).foreach { _ => + ConsoleOut.outStream.print(ansi.cursorLeft(999).cursorUp(1).eraseLine(Ansi.Erase.ALL)) + } + ConsoleOut.outStream.flush() + newLine = false + } + + private[this] def current(indexOfDate: Int, totalOfDate: Int, summary: String): String = { + val progressBar = ProgressBar.progressBar(indexOfDate, totalOfDate) + val resultString = if (failed == 0) Messages("common.result_success") else Messages("common.result_failed", failed) + val result = if (resultString.nonEmpty) { + if (resultString == Messages("common.result_success")) + s"[${ansi().fg(GREEN).a(resultString).reset()}]" + else s"[${ansi().fg(RED).a(resultString).reset()}]" + } else resultString + + val message = + Messages("export.date.execute", + summary, + Messages("common.issues"), + if (indexOfDate == totalOfDate) Messages("message.exported") else Messages("message.exporting")) + + s"$progressBar$result $message" + } + + private[this] def remaining(): String = { + val progressBar = ProgressBar.progressBar(remainingTime.count.toInt, remainingTime.totalSize.toInt) + val message = Messages("export.progress", remainingTime.count, remainingTime.totalSize) + val time = Messages("export.remaining_time", DateUtil.timeFormat(new Date(remainingTime.remainingTime))) + s"$progressBar $message$time" + } +} diff --git a/src/main/resources/messages.txt b/src/main/resources/messages.txt index cd8b8e16..e9fb997d 100644 --- a/src/main/resources/messages.txt +++ b/src/main/resources/messages.txt @@ -169,6 +169,9 @@ import.error.failed.comment=Could not register comment on issue [{0}]. : {1} export.start=Start export. export.finish=Export completed. Next step \n\n1. Edit mapping files.\n2. Execute the following command to import (replace with your JIRA password).\n\n--------------------------------------\n\n{0}\n\n-------------------------------------- export.attachment.empty=Attachment: {0} -> {1} +export.progress=Progress...({0,number,#}/{1,number,#}) +export.remaining_time=[Remaining time:{0}] +export.date.execute={2} {1} about {0}. # ----------------------------------------------------------------------------- # Convert diff --git a/src/main/resources/messages_ja.txt b/src/main/resources/messages_ja.txt index d7489f80..8bb7a96a 100644 --- a/src/main/resources/messages_ja.txt +++ b/src/main/resources/messages_ja.txt @@ -170,6 +170,9 @@ import.error.failed.comment=コメントを課題[{0}]に登録できません export.start=エクスポートを開始します。 export.finish=エクスポートが完了しました。 次のステップは \n\n1. マッピングファイルを編集します。\n2. インポートするために以下のコメントを実行します。 (JIRAのパスワードは修正してください)\n\n--------------------------------------\n\n{0}\n\n-------------------------------------- export.attachment.empty=添付ファイル: {0} -> {1} +export.progress=進行状況...({0,number,#}/{1,number,#}) +export.remaining_time=[残り時間:{0}] +export.date.execute={0}の{1}を{2} # ----------------------------------------------------------------------------- # Convert From 582c11d2ca7e8ab3a7edf7a1e4359bf921fa302b Mon Sep 17 00:00:00 2001 From: Shoma Nishitateno Date: Tue, 12 Dec 2017 13:21:30 +0900 Subject: [PATCH 08/10] Modify display format --- .../console/RemainingTimeCalculator.scala | 59 +++---------------- src/main/resources/messages.txt | 1 - src/main/resources/messages_ja.txt | 1 - 3 files changed, 8 insertions(+), 53 deletions(-) diff --git a/exporter/src/main/scala/com/nulabinc/backlog/j2b/exporter/console/RemainingTimeCalculator.scala b/exporter/src/main/scala/com/nulabinc/backlog/j2b/exporter/console/RemainingTimeCalculator.scala index 5933565e..4296e740 100644 --- a/exporter/src/main/scala/com/nulabinc/backlog/j2b/exporter/console/RemainingTimeCalculator.scala +++ b/exporter/src/main/scala/com/nulabinc/backlog/j2b/exporter/console/RemainingTimeCalculator.scala @@ -5,13 +5,12 @@ import java.util.Date import com.nulabinc.backlog.migration.common.utils.{ConsoleOut, DateUtil, Logging, ProgressBar} import com.osinka.i18n.Messages import org.fusesource.jansi.Ansi -import org.fusesource.jansi.Ansi.Color._ import org.fusesource.jansi.Ansi.ansi class RemainingTimeCalculator(totalSize: Long) extends Logging { - var failed = 0 - var date = "" + private var failed = 0 + private var date = "" private case class RemainingTime(totalSize: Long, lastTime: Long = System.currentTimeMillis(), totalElapsedTime: Long = 0, count: Long = 0) { @@ -36,39 +35,16 @@ class RemainingTimeCalculator(totalSize: Long) extends Logging { private[this] var newLine = false private[this] var isMessageMode = false - def warning(indexOfDate: Int, totalOfDate: Int, value: String) = { - message(indexOfDate: Int, totalOfDate: Int, value: String, YELLOW) - } - - def error(indexOfDate: Int, totalOfDate: Int, value: String) = { - message(indexOfDate: Int, totalOfDate: Int, value: String, RED) - } - - private[this] def message(indexOfDate: Int, totalOfDate: Int, value: String, color: Ansi.Color): Unit = { - clear() - val message = - s"""${(" " * 11) + ansi().fg(color).a(value.replaceAll("\n", "")).reset().toString} - |${current(indexOfDate, totalOfDate, value)} - |-------------------------------------------------- - |${remaining()}""".stripMargin - - ConsoleOut.outStream.println(message) - isMessageMode = true - } - - def progress(indexOfDate: Int, totalOfDate: Int, summary: String) = { - newLine = (indexOfDate == 1) + def progress(indexOfDate: Int, totalOfDate: Int, summary: String): Unit = { + newLine = indexOfDate == 1 clear() remainingTime = remainingTime.action() - val message = - s"""${current(indexOfDate, totalOfDate, summary)} - |-------------------------------------------------- - |${remaining()}""".stripMargin + val message = remaining() ConsoleOut.outStream.println(message) isMessageMode = false } - private[this] def clear() = { + private def clear(): Unit = { if (newLine && !isMessageMode) { ConsoleOut.outStream.println() } @@ -79,28 +55,9 @@ class RemainingTimeCalculator(totalSize: Long) extends Logging { newLine = false } - private[this] def current(indexOfDate: Int, totalOfDate: Int, summary: String): String = { - val progressBar = ProgressBar.progressBar(indexOfDate, totalOfDate) - val resultString = if (failed == 0) Messages("common.result_success") else Messages("common.result_failed", failed) - val result = if (resultString.nonEmpty) { - if (resultString == Messages("common.result_success")) - s"[${ansi().fg(GREEN).a(resultString).reset()}]" - else s"[${ansi().fg(RED).a(resultString).reset()}]" - } else resultString - - val message = - Messages("export.date.execute", - summary, - Messages("common.issues"), - if (indexOfDate == totalOfDate) Messages("message.exported") else Messages("message.exporting")) - - s"$progressBar$result $message" - } - - private[this] def remaining(): String = { + private def remaining(): String = { val progressBar = ProgressBar.progressBar(remainingTime.count.toInt, remainingTime.totalSize.toInt) - val message = Messages("export.progress", remainingTime.count, remainingTime.totalSize) val time = Messages("export.remaining_time", DateUtil.timeFormat(new Date(remainingTime.remainingTime))) - s"$progressBar $message$time" + s"$progressBar $time" } } diff --git a/src/main/resources/messages.txt b/src/main/resources/messages.txt index e9fb997d..39945cd1 100644 --- a/src/main/resources/messages.txt +++ b/src/main/resources/messages.txt @@ -169,7 +169,6 @@ import.error.failed.comment=Could not register comment on issue [{0}]. : {1} export.start=Start export. export.finish=Export completed. Next step \n\n1. Edit mapping files.\n2. Execute the following command to import (replace with your JIRA password).\n\n--------------------------------------\n\n{0}\n\n-------------------------------------- export.attachment.empty=Attachment: {0} -> {1} -export.progress=Progress...({0,number,#}/{1,number,#}) export.remaining_time=[Remaining time:{0}] export.date.execute={2} {1} about {0}. diff --git a/src/main/resources/messages_ja.txt b/src/main/resources/messages_ja.txt index 8bb7a96a..0025fce3 100644 --- a/src/main/resources/messages_ja.txt +++ b/src/main/resources/messages_ja.txt @@ -170,7 +170,6 @@ import.error.failed.comment=コメントを課題[{0}]に登録できません export.start=エクスポートを開始します。 export.finish=エクスポートが完了しました。 次のステップは \n\n1. マッピングファイルを編集します。\n2. インポートするために以下のコメントを実行します。 (JIRAのパスワードは修正してください)\n\n--------------------------------------\n\n{0}\n\n-------------------------------------- export.attachment.empty=添付ファイル: {0} -> {1} -export.progress=進行状況...({0,number,#}/{1,number,#}) export.remaining_time=[残り時間:{0}] export.date.execute={0}の{1}を{2} From 8f16895337c8b865ae4d7756a553a39f9f6f7085 Mon Sep 17 00:00:00 2001 From: Shoma Nishitateno Date: Tue, 12 Dec 2017 13:50:42 +0900 Subject: [PATCH 09/10] Add backlogtool token --- common | 2 +- src/main/resources/application.conf | 1 + .../nulabinc/backlog/j2b/cli/Tracker.scala | 24 ++++++++++++------- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/common b/common index 37c3db85..7c751d81 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit 37c3db85c40a1ce52894a884e8a71c27770dc864 +Subproject commit 7c751d810d0a2ac92db22ccad469005c07d5b542 diff --git a/src/main/resources/application.conf b/src/main/resources/application.conf index d82744c7..d3c79ce2 100644 --- a/src/main/resources/application.conf +++ b/src/main/resources/application.conf @@ -4,6 +4,7 @@ application { title = ${application.name} ${application.version} (c) nulab.inc export-limit-at-once = 100 mixpanel.token = "6aad3862b3514d664ebb4501f86f42c8" + mixpanel.backlogtool.token = "6aad3862b3514d664ebb4501f86f42c8" mixpanel.product = "jira" language=default akka.mailbox-pool = 100 diff --git a/src/main/scala/com/nulabinc/backlog/j2b/cli/Tracker.scala b/src/main/scala/com/nulabinc/backlog/j2b/cli/Tracker.scala index 0eb9c9d9..96c90de3 100644 --- a/src/main/scala/com/nulabinc/backlog/j2b/cli/Tracker.scala +++ b/src/main/scala/com/nulabinc/backlog/j2b/cli/Tracker.scala @@ -12,17 +12,23 @@ trait Tracker extends BacklogConfiguration { def tracking(config: AppConfiguration, spaceService: SpaceService, userService: UserService) = { Try { val environment = spaceService.environment() - val data = TrackingData(product = mixpanelProduct, - envname = environment.name, - spaceId = environment.spaceId, - userId = userService.myself().id, - srcUrl = config.jiraConfig.url, - dstUrl = config.backlogConfig.url, - srcProjectKey = config.jiraConfig.projectKey, - dstProjectKey = config.backlogConfig.projectKey, + val data = TrackingData( + product = mixpanelProduct, + envname = environment.name, + spaceId = environment.spaceId, + userId = userService.myself().id, + srcUrl = config.jiraConfig.url, + dstUrl = config.backlogConfig.url, + srcProjectKey = config.jiraConfig.projectKey, + dstProjectKey = config.backlogConfig.projectKey, srcSpaceCreated = "", dstSpaceCreated = spaceService.space().created) - MixpanelUtil.track(token = mixpanelToken, data = data) + val backlogToolEnvNames = Seq( + "backlogtool", + "us-6" + ) + val token = if (backlogToolEnvNames.contains(environment.name)) mixpanelBacklogtoolToken else mixpanelToken + MixpanelUtil.track(token = token, data = data) } } } From 4a96234669d3b2fe8dfbc349e70c40dfce9c2e4c Mon Sep 17 00:00:00 2001 From: Shoma Nishitateno Date: Tue, 12 Dec 2017 18:05:01 +0900 Subject: [PATCH 10/10] Increment version --- README.md | 4 ++-- build.sbt | 2 +- src/main/resources/application.conf | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 489ddea9..96ee81fd 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ Download Please download the jar file from this link, and run from the command line as follows. -https://github.com/nulab/BacklogMigration-Jira/releases/download/0.1.0b2-SNAPSHOT/backlog-migration-jira-0.1.0b2-SNAPSHOT.jar +https://github.com/nulab/BacklogMigration-Jira/releases/download/0.1.0b2/backlog-migration-jira-0.1.0b2.jar java -jar backlog-migration-jira-[latest version].jar @@ -233,7 +233,7 @@ https://github.com/nulab/BacklogMigration-Jira/releases こちらのリンクからjarファイルをダウンロードし、以下のようにコマンドラインから実行します。 -https://github.com/nulab/BacklogMigration-Jira/releases/download/0.1.0b2-SNAPSHOT/backlog-migration-jira-0.1.0b2-SNAPSHOT.jar +https://github.com/nulab/BacklogMigration-Jira/releases/download/0.1.0b2/backlog-migration-jira-0.1.0b2.jar java -jar backlog-migration-jira-[最新バージョン].jar diff --git a/build.sbt b/build.sbt index d136ef66..c1db3913 100644 --- a/build.sbt +++ b/build.sbt @@ -1,6 +1,6 @@ import sbt.Keys._ -lazy val projectVersion = "0.1.0b2-SNAPSHOT" +lazy val projectVersion = "0.1.0b2" lazy val commonSettings = Seq( organization := "com.nulabinc", diff --git a/src/main/resources/application.conf b/src/main/resources/application.conf index d3c79ce2..4cb8642e 100644 --- a/src/main/resources/application.conf +++ b/src/main/resources/application.conf @@ -1,10 +1,10 @@ application { name = "Backlog Migration for Jira" - version = "0.1.0b2-SNAPSHOT" + version = "0.1.0b2" title = ${application.name} ${application.version} (c) nulab.inc export-limit-at-once = 100 - mixpanel.token = "6aad3862b3514d664ebb4501f86f42c8" - mixpanel.backlogtool.token = "6aad3862b3514d664ebb4501f86f42c8" + mixpanel.token = "5be8b628b7103858164142d02cb38347" + mixpanel.backlogtool.token = "0512c52e553b9283143bed99e61c27e4" mixpanel.product = "jira" language=default akka.mailbox-pool = 100