-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Scalafix rewrites for 1.0.0 #1793
Merged
Merged
Changes from 18 commits
Commits
Show all changes
20 commits
Select commit
Hold shift + click to select a range
d537b03
Add RemoveUnapply and RemoveCartesianBuilder Scalafix rewrites
gabro b296330
Add RenameFreeSuspend Scalafix rewrite
gabro 090de4f
DRY and simplify renames
gabro e0e8401
Remove unused value
gabro aaa9c32
Add RenameReducibleMethods Scalafix rewrite
gabro 2512b3d
Add isSymbol utility method
gabro c2ad743
Add SimplifyEitherTLift Scalafix rewrite
gabro 9b04aeb
Add to All rewrite
gabro 1446aa4
Collapse all the Scalafix rewrites into a single file.
gabro 15a54bd
Update readme.md
gabro 6c8befa
Add test case for RemoveCartesianBuilder
gabro 718f7dc
Add isOneOfSymbols utility
gabro 73f744f
Handle cartesian builders without wrapping parenthesis
gabro c0eca72
Add more edge cases for RemoveCartesianBuilder
gabro 971c012
Don't remove cats.syntax.cartesian._ if *> or <* are used
gabro 42437bd
Add instructions to the README
gabro b6641a7
Add link to rewrites in CHANGES.md
gabro 9f82d24
Rename readme.md to README.md
gabro ea6729d
Remove duplicate plugin and update scalafix to M2
gabro 0311cc2
Micro-fix to indentation of apply import
gabro File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
align = none |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
# Scalafix rewrites for cats | ||
|
||
## Try this! | ||
|
||
Install the scalafix sbt plugin (globally or in a specific project): | ||
|
||
```scala | ||
addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.5.0-M2") | ||
``` | ||
|
||
run | ||
|
||
```sh | ||
sbt scalafix github:typelevel/cats/v1.0.0 | ||
``` | ||
|
||
## Available rewrites | ||
|
||
- [x] All Unapply enabled methods, e.g. sequenceU, traverseU, etc. are removed. Unapply enabled syntax ops are also removed. Please use the partial unification SI-2712 fix instead. The easiest way might be this sbt-plugin. | ||
|
||
- [x] The creation methods (left, right, apply, pure, etc.) in EitherT were improved to take less type arguments. | ||
|
||
- [x] CartesianBuilder (i.e. |@|) syntax is deprecated, use the apply syntax on tuples instead. E.g. (x |@| y |@| z).map(...) should be replaced by (x, y, z).mapN(...) | ||
|
||
- [x] Free.suspend is renamed to Free.defer for consistency. | ||
|
||
- [x] traverse1_, intercalate1 and sequence1_ in Reducible were renamed to nonEmptyTraverse_, nonEmptyIntercalate and nonEmptySequence_ respectively. | ||
|
||
# WIP | ||
|
||
- [ ] cats no longer publishes the all-inclusive bundle package "org.typelevel" % "cats", use cats-core, cats-free, or cats-law accordingly instead. If you need cats.free, use "org.typelevel" % "cats-free", if you need cats-laws use "org.typelevel" % "cats-laws", if neither, use "org.typelevel" % "cats-core". | ||
|
||
- [ ] cats.free.Inject is moved from cats-free to cats-core and renamed to cats.InjectK; cats.data.Prod is renamed to cats.data.Tuple2K; cats.data.Coproduct is renamed to cats.data.EitherK | ||
|
||
- [ ] FunctorFilter, MonadCombine, MonadFilter, MonadReader, MonadState, MonadTrans, MonadWriter and TraverseFilter are no longer in cats, the functionalities they provided are inhereted by the new cats-mtl project. Please check here for migration guide. | ||
|
||
- [ ] Apply syntax on tuple (e.g. (x, y, z).map3(...)) was moved from cats.syntax.tuple._ to cats.syntax.apply._ and renamed to mapN, contramapN and imapN respectively. | ||
|
||
- [ ] Several cats-core type class instances for cats.kernel were moved from their companion objects to separate traits and thus require imports from cats.instances.xxx._ (or the recommended import cats.implicits._) now. See #1659 for more details. | ||
|
||
- [ ] foldLeftM is removed from Free, use foldM on Foldable instead, see #1117 for detail. | ||
|
||
- [ ] iteratorFoldM was removed from Foldable due to #1716 | ||
|
||
- [ ] Split is removed, and the method split is moved to Arrow. Note that only under CommutativeArrow does it guarantee the non-interference between the effects. see #1567 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
// Use a scala version supported by scalafix. | ||
scalaVersion in ThisBuild := org.scalameta.BuildInfo.supportedScalaVersions.last | ||
|
||
lazy val rewrites = project.settings( | ||
libraryDependencies += "ch.epfl.scala" %% "scalafix-core" % "0.5.0-M1" | ||
) | ||
|
||
lazy val input = project.settings( | ||
scalametaSourceroot := sourceDirectory.in(Compile).value, | ||
libraryDependencies ++= Seq( | ||
"org.typelevel" %% "cats" % "0.9.0" | ||
) | ||
) | ||
|
||
lazy val output = project.settings( | ||
libraryDependencies ++= Seq( | ||
"org.typelevel" %% "cats-core" % "1.0.0-MF", | ||
"org.typelevel" %% "cats-free" % "1.0.0-MF" | ||
) | ||
) | ||
|
||
lazy val tests = project | ||
.settings( | ||
libraryDependencies += "ch.epfl.scala" % "scalafix-testkit" % "0.5.0-M1" % Test cross CrossVersion.full, | ||
buildInfoPackage := "fix", | ||
buildInfoKeys := Seq[BuildInfoKey]( | ||
"inputSourceroot" -> | ||
sourceDirectory.in(input, Compile).value, | ||
"outputSourceroot" -> | ||
sourceDirectory.in(output, Compile).value, | ||
"inputClassdirectory" -> | ||
classDirectory.in(input, Compile).value | ||
) | ||
) | ||
.dependsOn(input, rewrites) | ||
.enablePlugins(BuildInfoPlugin) |
41 changes: 41 additions & 0 deletions
41
scalafix/input/src/main/scala/fix/v1_0_0/RemoveCartesianBuilder.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
/* | ||
rewrite = "scala:fix.v1_0_0.RemoveCartesianBuilder" | ||
*/ | ||
package fix | ||
package to1_0_0 | ||
|
||
object RemoveCartesianBuilderTests { | ||
{ | ||
import cats.instances.option._ | ||
import cats.instances.int._ | ||
import cats.syntax.cartesian._ | ||
import cats.syntax.semigroup._ | ||
val o1: Option[Int] = Some(42) | ||
val o2: Option[String] = Some("hello") | ||
val o3: Option[Int] = Some(2) | ||
(o1 |@| o2).map((i: Int, s: String) => i.toString ++ s) | ||
(o1 |@| o2).tupled | ||
(o1 |@| o2 |@| o3).map(_ + _ + _) | ||
(o1 |+| o1 |@| o3).map(_ + _) | ||
o1 |@| o2 |@| o3 map (_ + _ + _) | ||
(o1 |+| o1 |@| o3) map (_ + _) | ||
o1 |+| o1 |@| o3 map (_ + _) | ||
|
||
(o1 |@| | ||
o2 |@| | ||
o3) map (_ + _ + _) | ||
} | ||
|
||
{ | ||
import cats.{Semigroup, Eq} | ||
import cats.implicits._ | ||
case class Foo(a: String, c: List[Double]) | ||
|
||
(Semigroup[String] |@| Semigroup[List[Double]]) | ||
.imap(Foo.apply)(Function.unlift(Foo.unapply)) | ||
|
||
(Eq[Double] |@| Eq[String]).contramap { (a: Foo) => | ||
(2, "bar") | ||
} | ||
} | ||
} |
15 changes: 15 additions & 0 deletions
15
scalafix/input/src/main/scala/fix/v1_0_0/RemoveCartesianBuilder2.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
/* ONLY | ||
rewrite = "scala:fix.v1_0_0.RemoveCartesianBuilder" | ||
*/ | ||
package fix | ||
package to1_0_0 | ||
|
||
object RemoveCartesianBuilderTests2 { | ||
import cats.instances.all._ | ||
import cats.syntax.cartesian._ | ||
val o1: Option[Int] = Some(2) | ||
val o2: Option[Int] = Some(2) | ||
o1 *> o2 | ||
(o1 |@| o2).map(_ + _) | ||
} | ||
|
44 changes: 44 additions & 0 deletions
44
scalafix/input/src/main/scala/fix/v1_0_0/RemoveUnapply.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
/* | ||
rewrite = "scala:fix.v1_0_0.RemoveUnapply" | ||
*/ | ||
package fix | ||
package to1_0_0 | ||
|
||
object RemoveUnapplyTests { | ||
import cats.implicits._ | ||
import cats.Foldable | ||
def parseInt(s: String): Either[String, Int] = | ||
Either.catchOnly[NumberFormatException](s.toInt).leftMap(_ => "no number") | ||
val ns = List("1", "2", "3") | ||
ns.traverseU(parseInt) | ||
ns.traverseU_(parseInt) | ||
Foldable[List].traverseU_(ns)(parseInt) | ||
|
||
import cats.data.{Validated, ValidatedNel} | ||
val x: List[ValidatedNel[String, Int]] = | ||
List(Validated.valid(1), Validated.invalid("a"), Validated.invalid("b")) | ||
.map(_.toValidatedNel) | ||
x.sequenceU | ||
x.sequenceU_ | ||
Foldable[List].sequenceU_(x) | ||
|
||
import cats.data.Func.{appFuncU, appFunc} | ||
import cats.data.State.{get, set} | ||
import cats.data.Const | ||
type Count[A] = Const[Int, A] | ||
def liftInt(i: Int): Count[Unit] = Const(i) | ||
def isSpace(c: Char): Boolean = (c == ' ' || c == '\n') | ||
def testIf(b: Boolean): Int = if (b) 1 else 0 | ||
appFuncU { (c: Char) => | ||
for { | ||
x <- get[Boolean] | ||
y = !isSpace(c) | ||
_ <- set(y) | ||
} yield testIf(y && !x) | ||
} andThen appFunc(liftInt) | ||
|
||
import cats.free.FreeT | ||
val a: Either[String, Int] = Right(42) | ||
FreeT.liftTU(a) | ||
|
||
} |
14 changes: 14 additions & 0 deletions
14
scalafix/input/src/main/scala/fix/v1_0_0/RenameFreeSuspend.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
/* | ||
rewrite = "scala:fix.v1_0_0.RenameFreeSuspend" | ||
*/ | ||
package fix | ||
package to1_0_0 | ||
|
||
object RenameFreeSuspendTests { | ||
import cats.free.{Free, Trampoline} | ||
|
||
val x = Free.pure[Option, Int](2) | ||
Free.suspend(x) | ||
|
||
Trampoline.suspend(Trampoline.done(2)) | ||
} |
22 changes: 22 additions & 0 deletions
22
scalafix/input/src/main/scala/fix/v1_0_0/RenameReducibleMethods.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
/* | ||
rewrite = "scala:fix.v1_0_0.RenameReducibleMethods" | ||
*/ | ||
package fix | ||
package to1_0_0 | ||
|
||
object RenameReducibleMethodsTests { | ||
import cats.data.NonEmptyList | ||
import cats.Reducible | ||
import cats.syntax.reducible._ | ||
import cats.instances.all._ | ||
|
||
val ns = NonEmptyList(1, List(2, 3)) | ||
Reducible[NonEmptyList].traverse1_(ns)(Option.apply) | ||
ns.traverse1_(Option.apply) | ||
|
||
Reducible[NonEmptyList].intercalate1(ns, 0) | ||
ns.intercalate1(0) | ||
|
||
Reducible[NonEmptyList].sequence1_(ns.map(Option.apply)) | ||
ns.map(Option.apply).sequence1_ | ||
} |
14 changes: 14 additions & 0 deletions
14
scalafix/input/src/main/scala/fix/v1_0_0/SimplifyEitherTLift.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
/* | ||
rewrite = "scala:fix.v1_0_0.SimplifyEitherTLift" | ||
*/ | ||
package fix | ||
package to1_0_0 | ||
|
||
object SimplifyEitherTLiftTests { | ||
import cats.Id | ||
import cats.data.EitherT | ||
val eithert = EitherT.left[Id, String, Int]("eithert") | ||
eithert.recoverWith { | ||
case "eithert" => EitherT.right[Id, String, Int](5) | ||
}.isRight | ||
} |
38 changes: 38 additions & 0 deletions
38
scalafix/output/src/main/scala/fix/v1_0_0/RemoveCartesianBuilder.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package fix | ||
package to1_0_0 | ||
|
||
object RemoveCartesianBuilderTests { | ||
{ | ||
import cats.instances.option._ | ||
import cats.instances.int._ | ||
import cats.syntax.apply._ | ||
import cats.syntax.semigroup._ | ||
val o1: Option[Int] = Some(42) | ||
val o2: Option[String] = Some("hello") | ||
val o3: Option[Int] = Some(2) | ||
(o1, o2).mapN((i: Int, s: String) => i.toString ++ s) | ||
(o1, o2).tupled | ||
(o1, o2, o3).mapN(_ + _ + _) | ||
(o1 |+| o1, o3).mapN(_ + _) | ||
(o1, o2, o3) mapN (_ + _ + _) | ||
(o1 |+| o1, o3) mapN (_ + _) | ||
(o1 |+| o1, o3) mapN (_ + _) | ||
|
||
(o1, | ||
o2, | ||
o3) mapN (_ + _ + _) | ||
} | ||
|
||
{ | ||
import cats.{Semigroup, Eq} | ||
import cats.implicits._ | ||
case class Foo(a: String, c: List[Double]) | ||
|
||
(Semigroup[String], Semigroup[List[Double]]) | ||
.imapN(Foo.apply)(Function.unlift(Foo.unapply)) | ||
|
||
(Eq[Double], Eq[String]).contramapN { (a: Foo) => | ||
(2, "bar") | ||
} | ||
} | ||
} |
13 changes: 13 additions & 0 deletions
13
scalafix/output/src/main/scala/fix/v1_0_0/RemoveCartesianBuilder2.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package fix | ||
package to1_0_0 | ||
|
||
object RemoveCartesianBuilderTests2 { | ||
import cats.instances.all._ | ||
import cats.syntax.cartesian._ | ||
import cats.syntax.apply._ | ||
val o1: Option[Int] = Some(2) | ||
val o2: Option[Int] = Some(2) | ||
o1 *> o2 | ||
(o1, o2).mapN(_ + _) | ||
} | ||
|
41 changes: 41 additions & 0 deletions
41
scalafix/output/src/main/scala/fix/v1_0_0/RemoveUnapply.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package fix | ||
package to1_0_0 | ||
|
||
object RemoveUnapplyTests { | ||
import cats.implicits._ | ||
import cats.Foldable | ||
def parseInt(s: String): Either[String, Int] = | ||
Either.catchOnly[NumberFormatException](s.toInt).leftMap(_ => "no number") | ||
val ns = List("1", "2", "3") | ||
ns.traverse(parseInt) | ||
ns.traverse_(parseInt) | ||
Foldable[List].traverse_(ns)(parseInt) | ||
|
||
import cats.data.{Validated, ValidatedNel} | ||
val x: List[ValidatedNel[String, Int]] = | ||
List(Validated.valid(1), Validated.invalid("a"), Validated.invalid("b")) | ||
.map(_.toValidatedNel) | ||
x.sequence | ||
x.sequence_ | ||
Foldable[List].sequence_(x) | ||
|
||
import cats.data.Func.appFunc | ||
import cats.data.State.{get, set} | ||
import cats.data.Const | ||
type Count[A] = Const[Int, A] | ||
def liftInt(i: Int): Count[Unit] = Const(i) | ||
def isSpace(c: Char): Boolean = (c == ' ' || c == '\n') | ||
def testIf(b: Boolean): Int = if (b) 1 else 0 | ||
appFunc { (c: Char) => | ||
for { | ||
x <- get[Boolean] | ||
y = !isSpace(c) | ||
_ <- set(y) | ||
} yield testIf(y && !x) | ||
} andThen appFunc(liftInt) | ||
|
||
import cats.free.FreeT | ||
val a: Either[String, Int] = Right(42) | ||
FreeT.liftT(a) | ||
|
||
} |
11 changes: 11 additions & 0 deletions
11
scalafix/output/src/main/scala/fix/v1_0_0/RenameFreeSuspend.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package fix | ||
package to1_0_0 | ||
|
||
object RenameFreeSuspendTests { | ||
import cats.free.{Free, Trampoline} | ||
|
||
val x = Free.pure[Option, Int](2) | ||
Free.defer(x) | ||
|
||
Trampoline.defer(Trampoline.done(2)) | ||
} |
19 changes: 19 additions & 0 deletions
19
scalafix/output/src/main/scala/fix/v1_0_0/RenameReducibleMethods.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package fix | ||
package to1_0_0 | ||
|
||
object RenameReducibleMethodsTests { | ||
import cats.data.NonEmptyList | ||
import cats.Reducible | ||
import cats.syntax.reducible._ | ||
import cats.instances.all._ | ||
|
||
val ns = NonEmptyList(1, List(2, 3)) | ||
Reducible[NonEmptyList].nonEmptyTraverse_(ns)(Option.apply) | ||
ns.nonEmptyTraverse_(Option.apply) | ||
|
||
Reducible[NonEmptyList].nonEmptyIntercalate(ns, 0) | ||
ns.nonEmptyIntercalate(0) | ||
|
||
Reducible[NonEmptyList].nonEmptySequence_(ns.map(Option.apply)) | ||
ns.map(Option.apply).nonEmptySequence_ | ||
} |
11 changes: 11 additions & 0 deletions
11
scalafix/output/src/main/scala/fix/v1_0_0/SimplifyEitherTLift.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package fix | ||
package to1_0_0 | ||
|
||
object SimplifyEitherTLiftTests { | ||
import cats.Id | ||
import cats.data.EitherT | ||
val eithert = EitherT.leftT[Id, Int]("eithert") | ||
eithert.recoverWith { | ||
case "eithert" => EitherT.pure[Id, String](5) | ||
}.isRight | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
sbt.version=0.13.13 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.5.0-M1") | ||
addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.5.0-M1") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Once is good enough, right? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. most definitely! Good catch, thanks :) |
||
addSbtPlugin("io.get-coursier" % "sbt-coursier" % "1.0.0-RC3") | ||
addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.6.1") | ||
addSbtPlugin("org.lyranthe.sbt" % "partial-unification" % "1.0.0") |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line is repeated :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good catch, thank you!