From 3cf9906753293048759ff5208516d5a6f8b27f38 Mon Sep 17 00:00:00 2001 From: Chris Rebert Date: Thu, 6 Aug 2015 17:50:20 -0700 Subject: Fix #5 --- src/main/scala/com/getbootstrap/no_carrier/Main.scala | 14 ++++++++------ .../com/getbootstrap/no_carrier/github/FancyIssue.scala | 6 +++++- .../scala/com/getbootstrap/no_carrier/util/package.scala | 11 +++-------- src/test/scala/RichInstantSpec.scala | 5 +++++ 4 files changed, 21 insertions(+), 15 deletions(-) diff --git a/src/main/scala/com/getbootstrap/no_carrier/Main.scala b/src/main/scala/com/getbootstrap/no_carrier/Main.scala index ab1781a..9660868 100644 --- a/src/main/scala/com/getbootstrap/no_carrier/Main.scala +++ b/src/main/scala/com/getbootstrap/no_carrier/Main.scala @@ -55,26 +55,28 @@ object Main extends App with StrictLogging { val repo = github.repos.get(args.repoId) logger.info(s"Repo(${args.repoId}), ${args.creds}, Label(${args.label}), Timeout(${args.timeout})") - val waitingOnOp = repo.issues.openWithLabel(args.label) + val waitingOnOp = repo.issues.openWithLabel(args.label).map{ issue => + new FancyIssue(issue = issue, label = args.label, timeout = args.timeout) + } val opNeverDelivered = waitingOnOp.filter{ issue => { logger.info(s"GitHub rate limit status: ${rateLimit.summary}") - logger.info(s"Checking issue #${issue.number} ...") - new FancyIssue(issue = issue, label = args.label, timeout = args.timeout).opNeverDelivered + logger.info(s"Checking issue #${issue.issue.number} ...") + issue.opNeverDelivered } } val totalClosed = opNeverDelivered.map { issue => - if (closeOut(issue, args.timeout)) 1 else 0 + if (closeOut(issue.issue, issue.elapsed.get)) 1 else 0 }.sum logger.info(s"Closed ${totalClosed} issues.") logger.info("Session complete; exiting.") } - def closeOut(issue: Issue, timeout: Duration): Boolean = { + def closeOut(issue: Issue, elapsed: Duration): Boolean = { logger.info(s"OP never delivered on issue #${issue.number}. Going to close it out.") if (enabled) { val explanatoryComment = s"""Hey there! | - |We're automatically closing this issue since the original poster (or another commenter) hasn't yet responded to the question or request made to them ${timeout.toDays} days ago. We therefore assume that the user has lost interest or resolved the problem on their own. Closed issues that remain inactive for a long period may get automatically locked. + |We're automatically closing this issue since the original poster (or another commenter) hasn't yet responded to the question or request made to them ${elapsed.toDays} days ago. We therefore assume that the user has lost interest or resolved the problem on their own. Closed issues that remain inactive for a long period may get automatically locked. | |Don't worry though; if this is in error, let us know with a comment and we'll be happy to reopen the issue. | diff --git a/src/main/scala/com/getbootstrap/no_carrier/github/FancyIssue.scala b/src/main/scala/com/getbootstrap/no_carrier/github/FancyIssue.scala index ba6f692..48e6ec0 100644 --- a/src/main/scala/com/getbootstrap/no_carrier/github/FancyIssue.scala +++ b/src/main/scala/com/getbootstrap/no_carrier/github/FancyIssue.scala @@ -24,7 +24,11 @@ class FancyIssue(val issue: Issue, val label: String, val timeout: Duration)(imp case _ => false } lazy val opennessChangedAfterLabelling: Boolean = wasClosedAfterLabelling || wasReopenedAfterLabelling - lazy val isPastDeadline: Boolean = lastLabelledAt.exists{ _ isBeyondTimeout timeout } + lazy val elapsed: Option[Duration] = lastLabelledAt.map { Instant.now(clock) - _ } + lazy val isPastDeadline: Boolean = { + import DurationOrdering._ + elapsed.exists{ _ > timeout } + } lazy val opNeverDelivered: Boolean = { val res = issue.smart.isOpen && issue.labels.smart.contains(label) && isPastDeadline && !opennessChangedAfterLabelling && !hasSubsequentComment print(".") diff --git a/src/main/scala/com/getbootstrap/no_carrier/util/package.scala b/src/main/scala/com/getbootstrap/no_carrier/util/package.scala index f143bb6..6dec5ce 100644 --- a/src/main/scala/com/getbootstrap/no_carrier/util/package.scala +++ b/src/main/scala/com/getbootstrap/no_carrier/util/package.scala @@ -1,20 +1,15 @@ package com.getbootstrap.no_carrier -import java.time.{Clock, Instant, Duration} +import java.time.{Instant, Duration} import com.google.common.base.{Optional=>GuavaOptional} package object util { val InstantOrdering = implicitly[Ordering[Instant]] + val DurationOrdering = implicitly[Ordering[Duration]] implicit class RichInstant(instant: Instant) { - import InstantOrdering._ - def +(duration: Duration): Instant = instant.plus(duration) - def isBeyondTimeout(timeout: Duration)(implicit clock: Clock): Boolean = { - val now = Instant.now(clock) - val deadline = instant + timeout - deadline < now - } + def -(earlier: Instant): Duration = Duration.between(earlier, instant) } implicit class GoogleToScalaOptional[T](option: GuavaOptional[T]) { diff --git a/src/test/scala/RichInstantSpec.scala b/src/test/scala/RichInstantSpec.scala index 59c3c69..94a3ff4 100644 --- a/src/test/scala/RichInstantSpec.scala +++ b/src/test/scala/RichInstantSpec.scala @@ -1,8 +1,13 @@ import java.time._ import org.specs2.mutable._ import com.getbootstrap.no_carrier.util.RichInstant +import com.getbootstrap.no_carrier.util.DurationOrdering._ class RichInstantSpec extends Specification { + private implicit class RicherInstant(instant: Instant) { + def isBeyondTimeout(timeout: Duration)(implicit clk: Clock): Boolean = (clk.instant() - instant) > timeout + } + val utc = ZoneId.of("UTC") val pseudoNow = ZonedDateTime.of(LocalDateTime.of(2015, 3, 17, 1, 2), utc).toInstant implicit val clock = StoppedClock(pseudoNow) -- cgit v1.2.3