|
16 | 16 |
|
17 | 17 | package org.typelevel.sbt.mergify |
18 | 18 |
|
19 | | -import cats.data.* |
20 | | -import cats.syntax.all.* |
21 | | -import io.circe.* |
22 | | -import io.circe.syntax.* |
| 19 | +import cats.data._ |
| 20 | +import cats.syntax.all._ |
| 21 | +import io.circe._ |
| 22 | +import io.circe.syntax._ |
| 23 | +import org.typelevel.sbt.mergify.MergifyAction.RequestReviews._ |
23 | 24 | import sbt.librarymanagement.Developer |
24 | 25 |
|
25 | 26 | sealed abstract class MergifyAction { |
@@ -62,51 +63,93 @@ object MergifyAction { |
62 | 63 | } |
63 | 64 | } |
64 | 65 |
|
65 | | - final class RequestReviews( |
66 | | - val users: Either[NonEmptyList[String], NonEmptyMap[String, Int]], |
67 | | - val randomCount: Option[Int]) |
| 66 | + class RequestReviews private ( |
| 67 | + private val users: Option[OptionallyWeighted], |
| 68 | + private val teams: Option[OptionallyWeighted], |
| 69 | + private val usersFromTeams: Option[OptionallyWeighted], |
| 70 | + private val randomCount: Option[Int]) |
68 | 71 | extends MergifyAction { |
69 | 72 | override private[mergify] def name = "request_reviews" |
70 | | - } |
71 | 73 |
|
72 | | - object RequestReviews { |
73 | | - def apply(user: String, users: String*) = |
74 | | - new RequestReviews(NonEmptyList.of(user, users: _*).asLeft, None) |
| 74 | + private def copy( |
| 75 | + users: Option[OptionallyWeighted] = users, |
| 76 | + teams: Option[OptionallyWeighted] = teams, |
| 77 | + usersFromTeams: Option[OptionallyWeighted] = usersFromTeams, |
| 78 | + randomCount: Option[Int] = randomCount): RequestReviews = |
| 79 | + new RequestReviews(users, teams, usersFromTeams, randomCount) {} |
75 | 80 |
|
76 | | - def apply(weightedUser: (String, Int), weightedUsers: (String, Int)*) = |
77 | | - new RequestReviews(NonEmptyMap.of(weightedUser, weightedUsers: _*).asRight, None) |
| 81 | + def andUsers(user: String, users: String*): RequestReviews = |
| 82 | + copy(users = Unweighted(NonEmptyList.of(user, users: _*)).some) |
78 | 83 |
|
79 | | - def apply(randomCount: Int, user: String, users: String*) = |
80 | | - new RequestReviews(NonEmptyList.of(user, users: _*).asLeft, Option(randomCount)) |
| 84 | + def andUsers(user: (String, Int), users: (String, Int)*): RequestReviews = |
| 85 | + copy(users = Weighted(NonEmptyList.of(user, users: _*)).some) |
81 | 86 |
|
82 | | - def apply(randomCount: Int, weightedUser: (String, Int), weightedUsers: (String, Int)*) = |
83 | | - new RequestReviews( |
84 | | - NonEmptyMap.of(weightedUser, weightedUsers: _*).asRight, |
85 | | - Option(randomCount) |
86 | | - ) |
| 87 | + def andTeams(team: String, teams: String*): RequestReviews = |
| 88 | + copy(teams = Unweighted(NonEmptyList.of(team, teams: _*)).some) |
| 89 | + |
| 90 | + def andTeams(team: (String, Int), teams: (String, Int)*): RequestReviews = |
| 91 | + copy(teams = Weighted(NonEmptyList.of(team, teams: _*)).some) |
| 92 | + |
| 93 | + def andUsersFromTeams(team: String, teams: String*): RequestReviews = |
| 94 | + copy(usersFromTeams = Unweighted(NonEmptyList.of(team, teams: _*)).some) |
| 95 | + |
| 96 | + def andUsersFromTeams(team: (String, Int), teams: (String, Int)*): RequestReviews = |
| 97 | + copy(usersFromTeams = Weighted(NonEmptyList.of(team, teams: _*)).some) |
| 98 | + |
| 99 | + def withRandomCount(count: Int): RequestReviews = |
| 100 | + copy(randomCount = Option(count)) |
| 101 | + |
| 102 | + def andDevelopers(developers: List[Developer]): RequestReviews = |
| 103 | + copy(users = NonEmptyList.fromList(developers.map(_.id)).map(Unweighted)) |
| 104 | + } |
| 105 | + |
| 106 | + object RequestReviews { |
| 107 | + def fromUsers(user: String, users: String*) = |
| 108 | + new RequestReviews(Unweighted(NonEmptyList.of(user, users: _*)).some, None, None, None) |
| 109 | + def fromUsers(user: (String, Int), users: (String, Int)*) = |
| 110 | + new RequestReviews(Weighted(NonEmptyList.of(user, users: _*)).some, None, None, None) |
| 111 | + def fromTeams(team: String, teams: String*) = |
| 112 | + new RequestReviews(None, Unweighted(NonEmptyList.of(team, teams: _*)).some, None, None) |
| 113 | + def fromTeams(team: (String, Int), teams: (String, Int)*) = |
| 114 | + new RequestReviews(None, Weighted(NonEmptyList.of(team, teams: _*)).some, None, None) |
| 115 | + def fromUsersOfTeams(team: String, teams: String*) = |
| 116 | + new RequestReviews(None, None, Unweighted(NonEmptyList.of(team, teams: _*)).some, None) |
| 117 | + def fromUsersOfTeams(team: (String, Int), teams: (String, Int)*) = |
| 118 | + new RequestReviews(None, None, Weighted(NonEmptyList.of(team, teams: _*)).some, None) |
87 | 119 |
|
88 | 120 | def apply(developers: List[Developer]) = |
89 | 121 | new RequestReviews( |
90 | | - developers |
91 | | - .map(_.id) |
92 | | - .toNel |
93 | | - .getOrElse(throw new RuntimeException("developers must be non-empty")) |
94 | | - .asLeft, |
| 122 | + Unweighted( |
| 123 | + developers |
| 124 | + .map(_.id) |
| 125 | + .toNel |
| 126 | + .getOrElse(throw new RuntimeException("developers must be non-empty")) |
| 127 | + ).some, |
| 128 | + None, |
| 129 | + None, |
95 | 130 | None) |
96 | 131 |
|
97 | | - def apply(developers: List[Developer], randomCount: Int) = |
98 | | - new RequestReviews( |
99 | | - developers |
100 | | - .map(_.id) |
101 | | - .toNel |
102 | | - .getOrElse(throw new RuntimeException("developers must be non-empty")) |
103 | | - .asLeft, |
104 | | - randomCount.some) |
105 | | - |
106 | 132 | implicit def encoder: Encoder[RequestReviews] = |
107 | | - Encoder.forProduct2("users", "random_count") { requestReviews => |
108 | | - (requestReviews.users.fold(_.asJson, _.asJson), requestReviews.randomCount) |
| 133 | + Encoder.forProduct4("users", "teams", "users_from_teams", "random_count") { |
| 134 | + requestReviews => |
| 135 | + ( |
| 136 | + requestReviews.users, |
| 137 | + requestReviews.teams, |
| 138 | + requestReviews.usersFromTeams, |
| 139 | + requestReviews.randomCount |
| 140 | + ) |
| 141 | + } |
| 142 | + |
| 143 | + private sealed trait OptionallyWeighted |
| 144 | + private case class Weighted(value: NonEmptyList[(String, Int)]) extends OptionallyWeighted |
| 145 | + private case class Unweighted(value: NonEmptyList[String]) extends OptionallyWeighted |
| 146 | + |
| 147 | + private object OptionallyWeighted { |
| 148 | + implicit val encoder: Encoder[OptionallyWeighted] = { |
| 149 | + case Weighted(value) => value.asJson |
| 150 | + case Unweighted(value) => value.asJson |
109 | 151 | } |
| 152 | + } |
110 | 153 | } |
111 | 154 |
|
112 | 155 | object Update extends MergifyAction { |
|
0 commit comments