Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Dec 30 2020 23:29
    dspasojevic opened #52
  • Oct 22 2020 19:56
    marko-asplund commented #44
  • Oct 22 2020 19:48
    marko-asplund commented #46
  • Oct 22 2020 10:59
    vil1 opened #51
  • Oct 22 2020 10:58
    vil1 edited #50
  • Oct 22 2020 10:58
    vil1 opened #50
  • Oct 22 2020 10:58
    vil1 labeled #50
  • Oct 22 2020 10:16
    vil1 commented #44
  • Oct 22 2020 10:15
    vil1 closed #46
  • Oct 22 2020 10:13

    vil1 on master

    Update README.md (compare)

  • Oct 21 2020 22:14
    vil1 commented #46
  • Oct 21 2020 21:52

    vil1 on v2.2.1

    (compare)

  • Oct 21 2020 21:25

    vil1 on master

    Fix cross-building definition a… (compare)

  • Oct 21 2020 21:25
    vil1 closed #49
  • Oct 21 2020 21:25
    vil1 opened #49
  • Oct 21 2020 21:25

    vil1 on cross-build

    Fix cross-building definition a… (compare)

  • Oct 21 2020 21:21

    vil1 on sbt-ci-release

    (compare)

  • Oct 21 2020 21:21

    vil1 on sbt-ci-release

    Setup sbt-ci-release Fix build.sbt compilation Fix tests compilation (warning) and 1 more (compare)

  • Oct 21 2020 21:21

    vil1 on sbt-ci-release

    (compare)

  • Oct 21 2020 21:17

    vil1 on sbt-ci-release

    Fix cross-building definition a… (compare)

Valentin Kasas
@vil1
hey, someone has been busy lately XD
Valentin Kasas
@vil1
I've rejected your last PR (#21) but just pushed the same mechanism using no symlink
(snapshots are published on central)
Valentin Kasas
@vil1
hmm, there seems to be a specs2 exception with that setup :/
[play-monadic-actions-scalaz_7.1] $ test
[error] 
[error] 
[error] This looks like a specs2 exception...
[error] Please report it with the preceding stacktrace at http://github.com/etorreborre/specs2/issues
[error]  
[error] Error: Total 1, Failed 0, Errors 1, Passed 0
[error] Error during tests:
[error]     io.kanaka.play.ScalazStepOpsSpec
[error] (scalaz71/test:test) sbt.TestsFailedException: Tests unsuccessful
[error] Total time: 1 s, completed 20 avr. 2016 16:22:38
this is not really helpful
David R. Bild
@drbild
Dropping to an earlier specs 2 version (3.1, I think) leads to the more useful:
[error] Uncaught exception when running io.kanaka.play.ScalazStepOpsSpec: java.lang.ClassCastException: scalaz.Free$Gosub cannot be cast to scala.Tuple2
[trace] Stack trace suppressed: run last scalaz72/test:test for the full output.
[error] Error: Total 1, Failed 0, Errors 1, Passed 0
[error] Error during tests:
[error]         io.kanaka.play.ScalazStepOpsSpec
[error] 
[error] java.lang.ClassNotFoundException: io.kanaka.play.ScalazStepOpsSpec
[error] 
[error] STACKTRACE
[error]   java.net.URLClassLoader.findClass(URLClassLoader.java:381)
...elided
[error]   java.lang.Thread.run(Thread.java:745)
[error] 
[error] 
[error] This looks like a specs2 exception...
[error] Please report it with the preceding stacktrace at http://github.com/etorreborre/specs2/issues
[error]  
[error] Error: Total 1, Failed 0, Errors 1, Passed 0
[error] Error during tests:
[error]         io.kanaka.play.ScalazStepOpsSpec
Looks like it's still a scalaz compatibility issue
David R. Bild
@drbild
Oh, target needs to be an absolute path. file("scalaz71/target") is relative.
David R. Bild
@drbild
Submitted a PR for this, but you might have a cleaner way of fixing it that it doesn't require so much manual path wrangling.
David R. Bild
@drbild
Generalizing the base monad with my initial approach leads to ambiguous implicit issues. The alternative I mentioned above (BaseMonadicActions[F[_]] and MonadicActions extends BaseMonadicActions[Future] may be the way forward. That's the approach I've used successfully in the past.
First though, a different concern. Right now the implicit toStepOps defs in the compat modules are brought into scope via imports but those in core are brought in by extending the MonadicActions trait. It'd be nice to standardize.
David R. Bild
@drbild
Assuming we'll be generalizing the base monad at some point, perhaps something like this would allow both:
trait  BaseMonadicActions[F[_]] {
   implicit def optionToStepOps[A](option: Option[A]): StepTOps[F, A, Unit] = ???
   ...
}

trait ScalazMonadicActions[F[_]] {
   implicit def disjunctionToStepOps[A, B](disjunction: A \/ B): StepTOps[F, B, A] = ???
   ...
}

trait MonadicActions extends BaseMonadicActions[Future] // backward compatibility

object io.kanaka.play.future extends BaseMonadicActions[Future]
object io.kanaka.play.compat.scalaz.future extends ScalazMonadicActions[Future]

class ControllerViaTraits() extends Controller with BaseMonadicActions[Future] with ScalazMonadicActions[Future] {
   ...
}

class ControllerViaImports() extends Controller {
   import io.kanaka.play.future._
   import io.kanaka.play.compat.scalaz.future._

   ...
}
Any initial thoughts here? I can flesh this out into a PR (without the base monad generalization initially) if you want to see more.
Valentin Kasas
@vil1
Hi
I'm a little more busy than usual right now, and it will be difficult to think more deeply about this during the next days
Valentin Kasas
@vil1
this StepT will look a lot like EitherT ^^
Valentin Kasas
@vil1
(but that more or less a naming question)
The layout you propose looks cleaner, I was thinking about something similar (without the carrier monad parametrization)
A thing that's worth keeping at mind is that at the end, even with another carrier monad, we need to end up with a Future[Either[Result, Result]] (that we "merge" to finally get a suitable Future[Result])
Daniel Spasojevic
@dspasojevic
@vil1 hi - I had a pebkac moment fooling around in our fork or play-monadic-actions - please ignore the PR.
Valentin Kasas
@vil1
ok then
Daniel Spasojevic
@dspasojevic
Thanks @vil1. We are looking forwards to 2.0
Valentin Kasas
@vil1
Great, this should come quite soon (there's already a 2.0.0-SNAPSHOT available on central, but it's still subject to important changes before the release)
David R. Bild
@drbild
Sorry I've been MIA; was on vacation for a long weekend. I'll get back to this later this week.
Valentin Kasas
@vil1
No worries, I've been quite busy too, should be a little better next week
Valentin Kasas
@vil1
Hi. I've just pushed some commits on 2.0 and published a fresh 2.0.0-SNAPSHOT, with some changes
  • upgraded to play 2.5.3
  • removed the MonadicActions trait
  • moved everything under io.kanaka.monadic.dsl (users only have to import io.kanaka.monadic.dsl._ to get the goodies)
  • got rid of the ExecutionContext in Step, it is now passed via an implicit parameter everywhere (meaning that users must have an implicit ExecutionContext in scope for the DSL to work)
I think we're ready for a first release candidate (I'm not yet settled on the idea of generalizing the base monad), we need to update the README though
Valentin Kasas
@vil1
I'm in the process of releasing a 2.0.0-RC1 on Central
2.0 has been merged into master
Valentin Kasas
@vil1
@drbild are you around ?
Jannes Stubbemann
@stubbi

Hi! I have a case where I am retrieving an optional user (to see whether there exists already a user with the email adress that tries to sign up). And the happy path would be the case when there is None returned (then signup process goes on). Otherwise I want to return and tell the user that his email is already signed up. For me, the library seems not to be designed for such a use case. But maybe you can tell me some smart way to do it? Here is the code I want to transform:

def submit = silhouette.UnsecuredAction.async { implicit request: Request[AnyContent] =>
    SignUpForm.form.bindFromRequest.fold(
      form => Future.successful(BadRequest(views.html.signUp(form))),
      data => {
        val result = Redirect(routes.SignUpController.view()).flashing("info" -> Messages("sign.up.email.sent", data.email))
        val loginInfo = LoginInfo(CredentialsProvider.ID, data.email)
        userService.retrieve(loginInfo).flatMap {
          case Some(user) =>
            val url = routes.SignInController.view().absoluteURL()
            mailerClient.send(Email(
              subject = Messages("email.already.signed.up.subject"),
              from = Messages("email.from"),
              to = Seq(data.email),
              bodyText = Some(views.txt.emails.alreadySignedUp(user, url).body),
              bodyHtml = Some(views.html.emails.alreadySignedUp(user, url).body)
            ))

            Future.successful(result)
          case None =>
            val authInfo = passwordHasherRegistry.current.hash(data.password)
            val user = User(
              userID = UUID.randomUUID(),
              loginInfo = loginInfo,
              firstName = Some(data.firstName),
              lastName = Some(data.lastName),
              fullName = Some(data.firstName + " " + data.lastName),
              email = Some(data.email),
              avatarURL = None,
              activated = false
            )
            for {
              avatar <- avatarService.retrieveURL(data.email)
              user <- userService.save(user.copy(avatarURL = avatar))
              authInfo <- authInfoRepository.add(loginInfo, authInfo)
              authToken <- authTokenService.create(user.userID)
            } yield {
              val url = routes.ActivateAccountController.activate(authToken.id).absoluteURL()
              mailerClient.send(Email(
                subject = Messages("email.sign.up.subject"),
                from = Messages("email.from"),
                to = Seq(data.email),
                bodyText = Some(views.txt.emails.signUp(user, url).body),
                bodyHtml = Some(views.html.emails.signUp(user, url).body)
              ))

              silhouette.env.eventBus.publish(SignUpEvent(user, request))
              result
            }
        }
      }

(from here)

Valentin Kasas
@vil1
Oh dear, I'm so sorry I missed your message for 3 months+
You're right, what you want isn't achievable out of the box, but you can map your Future[Option] to a Future[Either[UserAlreadyDefined, Unit]]