Skip to content

Commit

Permalink
Merge pull request #152 from Kevin-Lee/task/146/add-find-github-release
Browse files Browse the repository at this point in the history
Issue #146 - Add 'find GitHub release'
  • Loading branch information
kevin-lee authored Jan 23, 2021
2 parents cc5a846 + d6bb9c4 commit a0a6f9e
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 0 deletions.
29 changes: 29 additions & 0 deletions src/main/scala/kevinlee/github/GitHubApi.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,20 @@ package kevinlee.github
import cats.Monad
import cats.syntax.all._
import io.circe._
import kevinlee.git.Git
import kevinlee.github.data._
import kevinlee.http.{HttpClient, HttpRequest}

/** @author Kevin Lee
* @since 2021-01-14
*/
trait GitHubApi[F[_]] {

def findReleaseByTagName(
tagName: Git.TagName,
repo: GitHubRepoWithAuth,
): F[Either[GitHubError, Option[GitHubRelease.Response]]]

def createRelease(
params: GitHubRelease.RequestParams,
repo: GitHubRepoWithAuth,
Expand All @@ -26,6 +33,28 @@ object GitHubApi {

val DefaultAccept: String = "application/vnd.github.v3+json"

def findReleaseByTagName(
tagName: Git.TagName,
repo: GitHubRepoWithAuth,
): F[Either[GitHubError, Option[GitHubRelease.Response]]] = {
val url = s"$baseUrl/repos/${repo.gitHubRepo.org.org}/${repo.gitHubRepo.repo.repo}/releases/tags/${tagName.value}"
val httpRequest = HttpRequest.withHeaders(
HttpRequest.Method.get,
HttpRequest.Uri(url),
HttpRequest.Header("accept" -> DefaultAccept) ::
repo
.accessToken
.toHeaderList,
)
httpClient
.request[Option[GitHubRelease.Response]](httpRequest)
.map(
_.toOptionIfNotFound
.leftMap(GitHubError.fromHttpError)
.flatMap(res => res.asRight[GitHubError])
)
}

override def createRelease(
params: GitHubRelease.RequestParams,
repo: GitHubRepoWithAuth,
Expand Down
3 changes: 3 additions & 0 deletions src/main/scala/kevinlee/http/HttpClient.scala
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@ object HttpClient {
maybeBody.map(HttpResponse.Body.apply),
)
failedResponse.status.code match {
case Status.NotFound.code =>
HttpError.notFound(httpRequest, httpResponse).asLeft[A]

case Status.BadRequest.code =>
HttpError.badRequest(httpRequest, httpResponse).asLeft[A]

Expand Down
25 changes: 25 additions & 0 deletions src/main/scala/kevinlee/http/HttpError.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ object HttpError {
final case class UnhandledThrowable(
throwable: Throwable
) extends HttpError
final case class NotFound(
httpRequest: HttpRequest,
httpResponse: HttpResponse,
) extends HttpError
final case class BadRequest(
httpRequest: HttpRequest,
httpResponse: HttpResponse,
Expand Down Expand Up @@ -51,6 +55,11 @@ object HttpError {

def unhandledThrowable(throwable: Throwable): HttpError = UnhandledThrowable(throwable)

def notFound(
httpRequest: HttpRequest,
httpResponse: HttpResponse,
): HttpError = NotFound(httpRequest, httpResponse)

def badRequest(httpRequest: HttpRequest, httpResponse: HttpResponse): HttpError =
BadRequest(httpRequest, httpResponse)

Expand All @@ -76,4 +85,20 @@ object HttpError {
@SuppressWarnings(Array("org.wartremover.warts.ToString"))
implicit final val show: Show[HttpError] = _.toString

def toOptionIfNotFound[A](httpErrorOrA: Either[HttpError, Option[A]]): Either[HttpError, Option[A]] =
httpErrorOrA match {
case Right(a) =>
a.asRight[HttpError]

case Left(HttpError.NotFound(_, _)) =>
none[A].asRight[HttpError]

case Left(_) =>
httpErrorOrA
}

implicit final class EitherHttpErrorOps[A](val httpError: Either[HttpError, Option[A]]) extends AnyVal {
def toOptionIfNotFound: Either[HttpError, Option[A]] =
HttpError.toOptionIfNotFound(httpError)
}
}
3 changes: 3 additions & 0 deletions src/main/scala/kevinlee/http/HttpRequest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,9 @@ object HttpRequest {
def withBody(httpMethod: Method, uri: Uri, body: Json): HttpRequest =
HttpRequest(httpMethod, uri, List.empty[Header], List.empty[Param], body.some)

def withHeaders(httpMethod: Method, uri: Uri, headers: List[Header]): HttpRequest =
HttpRequest(httpMethod, uri, headers, List.empty[Param], none[Json])

def withHeadersAndBody(httpMethod: Method, uri: Uri, headers: List[Header], body: Json): HttpRequest =
HttpRequest(httpMethod, uri, headers, List.empty[Param], body.some)

Expand Down

0 comments on commit a0a6f9e

Please sign in to comment.