Skip to content

Commit 1d4f890

Browse files
committed
Allow updates.limit option to be zero
This allows the repo config option `updates.limit` to be zero so that it can now be zero or positive instead of positive only. A zero `updates.limit` means that Scala Steward will not create or update PRs. It can be used to temporarily disable Scala Steward in a repo or if it is used in the default repo config it would be similar to a hypothetical dry-run option.
1 parent 055819b commit 1d4f890

File tree

7 files changed

+40
-26
lines changed

7 files changed

+40
-26
lines changed

modules/core/src/main/scala/org/scalasteward/core/nurture/NurtureAlg.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ package org.scalasteward.core.nurture
1919
import cats.Applicative
2020
import cats.effect.BracketThrow
2121
import cats.implicits._
22-
import eu.timepit.refined.types.numeric.PosInt
22+
import eu.timepit.refined.types.numeric.NonNegInt
2323
import fs2.Stream
2424
import io.chrisdavenport.log4cats.Logger
2525
import org.http4s.Uri
@@ -239,15 +239,15 @@ object NurtureAlg {
239239
def processUpdates[F[_]](
240240
updates: List[Update],
241241
updateF: Update => F[ProcessResult],
242-
updatesLimit: Option[PosInt]
242+
updatesLimit: Option[NonNegInt]
243243
)(implicit streamCompiler: Stream.Compiler[F, F], F: Applicative[F]): F[Unit] =
244244
updatesLimit match {
245245
case None => updates.traverse_(updateF)
246246
case Some(limit) =>
247247
Stream
248248
.emits(updates)
249249
.evalMap(updateF)
250-
.through(util.takeUntil(limit.value) {
250+
.through(util.takeUntil(0, limit.value) {
251251
case Ignored => 0
252252
case Updated => 1
253253
})

modules/core/src/main/scala/org/scalasteward/core/repoconfig/UpdatesConfig.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ package org.scalasteward.core.repoconfig
1818

1919
import cats.implicits._
2020
import cats.kernel.Semigroup
21-
import eu.timepit.refined.types.numeric.PosInt
21+
import eu.timepit.refined.types.numeric.NonNegInt
2222
import io.circe.generic.extras.Configuration
2323
import io.circe.generic.extras.semiauto._
2424
import io.circe.refined._
@@ -36,7 +36,7 @@ final case class UpdatesConfig(
3636
pin: List[UpdatePattern] = List.empty,
3737
allow: List[UpdatePattern] = List.empty,
3838
ignore: List[UpdatePattern] = List.empty,
39-
limit: Option[PosInt] = None,
39+
limit: Option[NonNegInt] = None,
4040
includeScala: Option[Boolean] = None,
4141
fileExtensions: Option[List[String]] = None
4242
) {
@@ -186,5 +186,5 @@ object UpdatesConfig {
186186
combineOptions(x, y)(_.intersect(_))
187187

188188
// prevent IntelliJ from removing the import of io.circe.refined._
189-
locally(refinedDecoder: Decoder[PosInt])
189+
locally(refinedDecoder: Decoder[NonNegInt])
190190
}

modules/core/src/main/scala/org/scalasteward/core/util/package.scala

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -68,21 +68,23 @@ package object util {
6868
fa.exists(a => ga.exists(b => a === b))
6969

7070
/** Adds a weight to each element and cuts the stream when the total
71-
* weight is greater or equal to `limit`.
71+
* weight is greater or equal to `limit`. `init` is the initial weight.
7272
*
7373
* @example {{{
74-
* scala> fs2.Stream.emits("Hello, world!").through(takeUntil(3) {
74+
* scala> fs2.Stream.emits("Hello, world!").through(takeUntil(0, 3) {
7575
* | case 'a' | 'e' | 'i' | 'o' | 'u' => 1
7676
* | case _ => 0
7777
* | }).toList.mkString
7878
* res1: String = Hello, wo
7979
* }}}
8080
*/
81-
def takeUntil[F[_], A, N](limit: N)(weight: A => N)(implicit N: Numeric[N]): Pipe[F, A, A] = {
82-
import N._
83-
_.map(a => (a, weight(a)))
84-
.scan1[(A, N)] { case ((_, total), (a, i)) => (a, total + i) }
85-
.takeThrough { case (_, total) => total < limit }
86-
.map { case (a, _) => a }
87-
}
81+
def takeUntil[F[_], A, N](init: N, limit: N)(weight: A => N)(implicit
82+
N: Numeric[N]
83+
): Pipe[F, A, A] =
84+
if (N.gteq(init, limit))
85+
_ => fs2.Stream.empty
86+
else
87+
_.mapAccumulate(init) { case (i, a) => (N.plus(i, weight(a)), a) }
88+
.takeThrough { case (total, _) => N.lt(total, limit) }
89+
.map { case (_, a) => a }
8890
}

modules/core/src/test/scala/org/scalasteward/core/nurture/NurtureAlgTest.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package org.scalasteward.core.nurture
22

33
import cats.data.StateT
44
import cats.effect.IO
5-
import eu.timepit.refined.types.numeric.PosInt
5+
import eu.timepit.refined.types.numeric.NonNegInt
66
import munit.ScalaCheckSuite
77
import org.scalacheck.Prop._
88
import org.scalasteward.core.TestInstances._
@@ -35,7 +35,7 @@ class NurtureAlgTest extends ScalaCheckSuite {
3535
.processUpdates(
3636
ignorableUpdates ++ appliableUpdates,
3737
f,
38-
PosInt.unapply(appliableUpdates.size)
38+
NonNegInt.unapply(appliableUpdates.size)
3939
)
4040
.runS(0)
4141
.unsafeRunSync()

modules/core/src/test/scala/org/scalasteward/core/repoconfig/RepoConfigAlgTest.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package org.scalasteward.core.repoconfig
22

33
import better.files.File
4-
import eu.timepit.refined.types.numeric.PosInt
4+
import eu.timepit.refined.types.numeric.NonNegInt
55
import munit.FunSuite
66
import org.scalasteward.core.TestSyntax._
77
import org.scalasteward.core.data.{GroupId, Update}
@@ -62,7 +62,7 @@ class RepoConfigAlgTest extends FunSuite {
6262
ignore = List(
6363
UpdatePattern(GroupId("org.acme"), None, Some(UpdatePattern.Version(Some("1.0"), None)))
6464
),
65-
limit = Some(PosInt.unsafeFrom(4)),
65+
limit = Some(NonNegInt.unsafeFrom(4)),
6666
includeScala = Some(true),
6767
fileExtensions = Some(List(".txt"))
6868
),

modules/core/src/test/scala/org/scalasteward/core/repoconfig/UpdatesConfigTest.scala

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package org.scalasteward.core.repoconfig
22

33
import cats.syntax.semigroup._
4-
import eu.timepit.refined.types.numeric.PosInt
4+
import eu.timepit.refined.types.numeric.NonNegInt
55
import munit.FunSuite
66
import org.scalasteward.core.data.GroupId
77
import org.scalasteward.core.repoconfig.UpdatePattern.Version
@@ -30,7 +30,7 @@ class UpdatesConfigTest extends FunSuite {
3030
pin = List(aa0),
3131
allow = List(aa0),
3232
ignore = List(aa0),
33-
limit = Some(PosInt.unsafeFrom(10)),
33+
limit = Some(NonNegInt.unsafeFrom(10)),
3434
includeScala = Some(false),
3535
fileExtensions = Some(List(".txt", ".scala", ".sbt"))
3636
)
@@ -43,7 +43,7 @@ class UpdatesConfigTest extends FunSuite {
4343
pin = List(ab0),
4444
allow = List(ab0),
4545
ignore = List(ab0),
46-
limit = Some(PosInt.unsafeFrom(20)),
46+
limit = Some(NonNegInt.unsafeFrom(20)),
4747
includeScala = Some(true),
4848
fileExtensions = Some(List(".sbt", ".scala"))
4949
)
@@ -54,7 +54,7 @@ class UpdatesConfigTest extends FunSuite {
5454
pin = List(aa0, ab0),
5555
allow = UpdatesConfig.nonExistingUpdatePattern,
5656
ignore = List(aa0, ab0),
57-
limit = Some(PosInt.unsafeFrom(10)),
57+
limit = Some(NonNegInt.unsafeFrom(10)),
5858
includeScala = Some(false),
5959
fileExtensions = Some(List(".scala", ".sbt"))
6060
)
@@ -66,7 +66,7 @@ class UpdatesConfigTest extends FunSuite {
6666
pin = List(ab0, aa0),
6767
allow = UpdatesConfig.nonExistingUpdatePattern,
6868
ignore = List(ab0, aa0),
69-
limit = Some(PosInt.unsafeFrom(20)),
69+
limit = Some(NonNegInt.unsafeFrom(20)),
7070
includeScala = Some(true),
7171
fileExtensions = Some(List(".sbt", ".scala"))
7272
)

modules/core/src/test/scala/org/scalasteward/core/util/utilTest.scala

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
package org.scalasteward.core.util
22

3-
import munit.FunSuite
3+
import cats.effect.IO
4+
import munit.ScalaCheckSuite
5+
import org.scalacheck.Gen
6+
import org.scalacheck.Prop._
47
import scala.collection.mutable.ListBuffer
58

6-
class utilTest extends FunSuite {
9+
class utilTest extends ScalaCheckSuite {
710
test("appendBounded") {
811
val lb = new ListBuffer[Int]
912
lb.appendAll(List(1, 2, 3))
@@ -35,4 +38,13 @@ class utilTest extends FunSuite {
3538
assert(!intersects(List(1, 3, 5), Vector(2, 4, 6)))
3639
assert(intersects(List(1, 3, 5), Vector(2, 3, 6)))
3740
}
41+
42+
test("takeUntil") {
43+
forAll(Gen.choose(0, 16)) { (n: Int) =>
44+
var count = 0
45+
val s = fs2.Stream.eval(IO(count += 1)).repeat.through(takeUntil(0, n)(_ => 1))
46+
s.compile.drain.unsafeRunSync()
47+
assertEquals(count, n)
48+
}
49+
}
3850
}

0 commit comments

Comments
 (0)