Skip to content
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

JP - Upgrades Libraries #32

Merged
merged 4 commits into from
Oct 12, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,20 @@ lazy val buildSettings = Seq(
licenses := Seq("Apache License, Version 2.0" -> url("http://www.apache.org/licenses/LICENSE-2.0.txt"))
)

lazy val cats = "0.6.0"
lazy val circe = "0.5.0-M2"
lazy val cats = "0.7.2"
lazy val circe = "0.5.2"

lazy val dependencies = libraryDependencies ++= Seq(
"org.typelevel" %% "cats-free" % cats,
"org.scalaj" %% "scalaj-http" % "2.2.1",
"io.circe" %% "circe-core" % circe,
"io.circe" %% "circe-generic" % circe,
"io.circe" %% "circe-parser" % circe,
"com.github.mpilquist" %% "simulacrum" % "0.8.0",
"org.scalatest" %% "scalatest" % "2.2.6" % "test",
"com.ironcorelabs" %% "cats-scalatest" % "1.1.2" % "test",
"org.mock-server" % "mockserver-netty" % "3.10.4" % "test"
"org.mock-server" % "mockserver-netty" % "3.10.4" % "test",
compilerPlugin("org.scalamacros" % "paradise" % "2.1.0" cross CrossVersion.full)
)

lazy val scalariformSettings = SbtScalariform.scalariformSettings ++ Seq(
Expand Down Expand Up @@ -84,7 +86,7 @@ lazy val docs = (project in file("docs"))
.dependsOn(scalaz)

lazy val scalazDependencies = libraryDependencies ++= Seq(
"org.scalaz" %% "scalaz-concurrent" % "7.1.4"
"org.scalaz" %% "scalaz-concurrent" % "7.3.0-M5"
)

lazy val scalazSettings = buildSettings ++ scalazDependencies ++ scalariformSettings
Expand Down
2 changes: 1 addition & 1 deletion docs/src/tut/docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ val u2 = Github(accessToken).users.get("raulraja").exec[Id]
WIP: With `Future`

```tut:silent
import cats.std.future._
import github4s.implicits._
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._
Expand Down
2 changes: 1 addition & 1 deletion project/build.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
sbt.version = 0.13.8
sbt.version = 0.13.12
20 changes: 18 additions & 2 deletions scalaz/src/main/scala/github4s/scalaz/Implicits.scala
Original file line number Diff line number Diff line change
@@ -1,21 +1,37 @@
package github4s.scalaz

import cats.MonadError
import cats.implicits._
import github4s.Github._
import cats.{ MonadError, RecursiveTailRecM }
import scalaz.concurrent.Task
import github4s.free.interpreters.Capture
import scalaz._

object implicits {

implicit val g4sTaskMonadError: MonadError[Task, Throwable] = new MonadError[Task, Throwable] {
implicit val taskCaptureInstance = new Capture[Task] {
override def capture[A](a: ⇒ A): Task[A] = Task.now(a)
}

implicit val g4sTaskcatsRecursiveTailRecM: RecursiveTailRecM[Task] = new RecursiveTailRecM[Task] {}

implicit def g4sTaskMonadError: MonadError[Task, Throwable] = new MonadError[Task, Throwable] {

override def pure[A](x: A): Task[A] = Task.now(x)

override def map[A, B](fa: Task[A])(f: A ⇒ B): Task[B] = fa.map(f)

override def flatMap[A, B](fa: Task[A])(ff: A ⇒ Task[B]): Task[B] = fa.flatMap(ff)

override def tailRecM[A, B](a: A)(f: A ⇒ Task[Either[A, B]]): Task[B] =
Task.tailrecM(a)(A ⇒ f(a) map (t ⇒ toScalazDisjunction(t)))

override def raiseError[A](e: Throwable): Task[A] = Task.fail(e)

override def handleErrorWith[A](fa: Task[A])(f: Throwable ⇒ Task[A]): Task[A] = fa.handleWith({ case x ⇒ f(x) })

}

private[this] def toScalazDisjunction[A, B](disj: Either[A, B]): A \/ B =
disj.fold(l ⇒ -\/(l), r ⇒ \/-(r))
}
7 changes: 4 additions & 3 deletions src/main/scala/github4s/Github.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package github4s

import cats.data.{ OptionT, XorT }
import cats.{ MonadError, ~> }
import cats.{ MonadError, ~>, RecursiveTailRecM }
import cats.implicits._
import github4s.GithubResponses._
import github4s.app._

Expand All @@ -24,9 +25,9 @@ object Github {

implicit class GithubIOSyntaxXOR[A](gio: GHIO[GHResponse[A]]) {

def exec[M[_]](implicit I: (GitHub4s ~> M), A: MonadError[M, Throwable]): M[GHResponse[A]] = gio foldMap I
def exec[M[_]](implicit I: (GitHub4s ~> M), A: MonadError[M, Throwable], TR: RecursiveTailRecM[M]): M[GHResponse[A]] = gio foldMap I

def liftGH: XorT[GHIO, GHException, GHResult[A]] = XorT[GHIO, GHException, GHResult[A]](gio)

}
}
}
33 changes: 26 additions & 7 deletions src/main/scala/github4s/Implicits.scala
Original file line number Diff line number Diff line change
@@ -1,16 +1,27 @@
package github4s

import cats.std.FutureInstances
import cats.std.future._
import cats.{ Monad, Id, Eval, MonadError }
import github4s.free.interpreters.Interpreters
import cats.implicits._
import cats.instances.FutureInstances
import cats.{ Monad, Id, Eval, MonadError, FlatMap }
import github4s.free.interpreters._
import scala.concurrent.{ ExecutionContext, Future }

object implicits extends Interpreters with EvalInstances with IdInstances with FutureInstances
object implicits extends Interpreters with EvalInstances with IdInstances with FutureInstances {

//Future Capture evidence:
implicit val futureCaptureInstance = new Capture[Future] {
override def capture[A](a: ⇒ A): Future[A] = Future.successful(a)
}

}

trait EvalInstances {

implicit val evalMonadError: MonadError[Eval, Throwable] = new MonadError[Eval, Throwable] {
implicit val evalCaptureInstance = new Capture[Eval] {
override def capture[A](a: ⇒ A): Eval[A] = Eval.later(a)
}

implicit def evalMonadError(implicit FM: FlatMap[Eval]): MonadError[Eval, Throwable] = new MonadError[Eval, Throwable] {

override def pure[A](x: A): Eval[A] = Eval.now(x)

Expand All @@ -19,6 +30,8 @@ trait EvalInstances {
override def flatMap[A, B](fa: Eval[A])(ff: A ⇒ Eval[B]): Eval[B] =
fa.flatMap(ff)

override def tailRecM[A, B](a: A)(f: A ⇒ Eval[Either[A, B]]): Eval[B] = FM.tailRecM(a)(f)

override def raiseError[A](e: Throwable): Eval[A] =
Eval.later({ throw e })

Expand All @@ -36,7 +49,11 @@ trait EvalInstances {

trait IdInstances {

implicit def idMonadError(implicit I: Monad[Id]): MonadError[Id, Throwable] = new MonadError[Id, Throwable] {
implicit val idCaptureInstance = new Capture[Id] {
override def capture[A](a: ⇒ A): Id[A] = idMonad.pure(a)
}

implicit def idMonad(implicit I: Monad[Id], FM: FlatMap[Id]): MonadError[Id, Throwable] = new MonadError[Id, Throwable] {

override def pure[A](x: A): Id[A] = I.pure(x)

Expand All @@ -46,6 +63,8 @@ trait IdInstances {

override def flatMap[A, B](fa: Id[A])(f: A ⇒ Id[B]): Id[B] = I.flatMap(fa)(f)

override def tailRecM[A, B](a: A)(f: A ⇒ Id[Either[A, B]]): Id[B] = FM.tailRecM(a)(f)

override def raiseError[A](e: Throwable): Id[A] = throw e

override def handleErrorWith[A](fa: Id[A])(f: Throwable ⇒ Id[A]): Id[A] = {
Expand Down
35 changes: 21 additions & 14 deletions src/main/scala/github4s/free/interpreters/Interpreters.scala
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
package github4s.free.interpreters

import cats.implicits._
import cats.{ MonadError, ApplicativeError, ~>, Eval }
import github4s.GithubDefaultUrls._
import github4s.api.{ Users, Auth, Repos }
import github4s.app.{ COGH01, GitHub4s }
import github4s.free.algebra._
import io.circe.Decoder

import simulacrum.typeclass

@typeclass trait Capture[M[_]] {
def capture[A](a: ⇒ A): M[A]
}

trait Interpreters {

implicit def interpreters[M[_]](
implicit
A: MonadError[M, Throwable]
A: MonadError[M, Throwable],
C: Capture[M]
): GitHub4s ~> M = {
val c01interpreter: COGH01 ~> M = repositoryOpsInterpreter[M] or userOpsInterpreter[M]
val all: GitHub4s ~> M = authOpsInterpreter[M] or c01interpreter
Expand All @@ -21,44 +29,43 @@ trait Interpreters {
/**
* Lifts Repository Ops to an effect capturing Monad such as Task via natural transformations
*/
def repositoryOpsInterpreter[M[_]](implicit A: ApplicativeError[M, Throwable]): RepositoryOp ~> M = new (RepositoryOp ~> M) {
def repositoryOpsInterpreter[M[_]](implicit A: ApplicativeError[M, Throwable], C: Capture[M]): RepositoryOp ~> M = new (RepositoryOp ~> M) {

val repos = new Repos()

def apply[A](fa: RepositoryOp[A]): M[A] = fa match {
case GetRepo(owner, repo, accessToken) ⇒ A.pureEval(Eval.later(repos.get(accessToken, owner, repo)))
case ListCommits(owner, repo, sha, path, author, since, until, pagination, accessToken) ⇒ A.pureEval(Eval.later(repos.listCommits(accessToken, owner, repo, sha, path, author, since, until, pagination)))
case ListContributors(owner, repo, anon, accessToken) ⇒ A.pureEval(Eval.later(repos.listContributors(accessToken, owner, repo, anon)))
case GetRepo(owner, repo, accessToken) ⇒ C.capture(repos.get(accessToken, owner, repo))
case ListCommits(owner, repo, sha, path, author, since, until, pagination, accessToken) ⇒ C.capture(repos.listCommits(accessToken, owner, repo, sha, path, author, since, until, pagination))
case ListContributors(owner, repo, anon, accessToken) ⇒ C.capture(repos.listContributors(accessToken, owner, repo, anon))
}
}

/**
* Lifts User Ops to an effect capturing Monad such as Task via natural transformations
*/
def userOpsInterpreter[M[_]](implicit A: ApplicativeError[M, Throwable]): UserOp ~> M = new (UserOp ~> M) {
def userOpsInterpreter[M[_]](implicit A: ApplicativeError[M, Throwable], C: Capture[M]): UserOp ~> M = new (UserOp ~> M) {

val users = new Users()

def apply[A](fa: UserOp[A]): M[A] = fa match {
case GetUser(username, accessToken) ⇒ A.pureEval(Eval.later(users.get(accessToken, username)))
case GetAuthUser(accessToken) ⇒ A.pureEval(Eval.later(users.getAuth(accessToken)))
case GetUsers(since, pagination, accessToken) ⇒ A.pureEval(Eval.later(users.getUsers(accessToken, since, pagination)))
case GetUser(username, accessToken) ⇒ C.capture(users.get(accessToken, username))
case GetAuthUser(accessToken) ⇒ C.capture(users.getAuth(accessToken))
case GetUsers(since, pagination, accessToken) ⇒ C.capture(users.getUsers(accessToken, since, pagination))
}
}

/**
* Lifts Auth Ops to an effect capturing Monad such as Task via natural transformations
*/
def authOpsInterpreter[M[_]](implicit A: ApplicativeError[M, Throwable]): AuthOp ~> M = new (AuthOp ~> M) {
def authOpsInterpreter[M[_]](implicit A: ApplicativeError[M, Throwable], C: Capture[M]): AuthOp ~> M = new (AuthOp ~> M) {

val auth = new Auth()

def apply[A](fa: AuthOp[A]): M[A] = fa match {
case NewAuth(username, password, scopes, note, client_id, client_secret) ⇒ A.pureEval(Eval.later(auth.newAuth(username, password, scopes, note, client_id, client_secret)))
case AuthorizeUrl(client_id, redirect_uri, scopes) ⇒ A.pureEval(Eval.later(auth.authorizeUrl(client_id, redirect_uri, scopes)))
case GetAccessToken(client_id, client_secret, code, redirect_uri, state) ⇒ A.pureEval(Eval.later(auth.getAccessToken(client_id, client_secret, code, redirect_uri, state)))
case NewAuth(username, password, scopes, note, client_id, client_secret) ⇒ C.capture(auth.newAuth(username, password, scopes, note, client_id, client_secret))
case AuthorizeUrl(client_id, redirect_uri, scopes) ⇒ C.capture(auth.authorizeUrl(client_id, redirect_uri, scopes))
case GetAccessToken(client_id, client_secret, code, redirect_uri, state) ⇒ C.capture(auth.getAccessToken(client_id, client_secret, code, redirect_uri, state))
}
}

}

2 changes: 1 addition & 1 deletion src/test/scala/github4s/integration/GHAuthSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package github4s.integration
import cats.Id
import cats.scalatest.{ XorMatchers, XorValues }
import github4s.Github._
import github4s.implicits._
import github4s.Github
import github4s.implicits._
import github4s.utils.TestUtils
import org.scalatest._

Expand Down
2 changes: 1 addition & 1 deletion src/test/scala/github4s/integration/GHReposSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,4 @@ class GHReposSpec extends FlatSpec with Matchers with XorMatchers with XorValues
response shouldBe left
}

}
}
2 changes: 1 addition & 1 deletion version.sbt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
version in ThisBuild := "0.6-SNAPSHOT"
version in ThisBuild := "0.7-SNAPSHOT"