by

Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Jul 05 17:51
    scala-steward opened #357
  • Jun 28 01:51

    vlovgr on gh-pages

    Deploy website Deploy website … (compare)

  • Jun 28 01:41

    mergify[bot] on master

    Update sbt to 1.3.13 Merge pull request #356 from sc… (compare)

  • Jun 28 01:41
    mergify[bot] closed #356
  • Jun 28 01:40
    codecov[bot] commented #356
  • Jun 28 01:34
    scala-steward opened #356
  • Jun 26 14:28

    vlovgr on gh-pages

    Deploy website Deploy website … (compare)

  • Jun 26 14:19

    vlovgr on master

    Change to check compatibility f… (compare)

  • Jun 26 13:32

    vlovgr on gh-pages

    Deploy website Deploy website … (compare)

  • Jun 26 13:24

    vlovgr on gh-pages

    Deploy website Deploy website … (compare)

  • Jun 26 13:18

    vlovgr on v1.1.1

    (compare)

  • Jun 26 13:15

    vlovgr on circe

    (compare)

  • Jun 26 13:15

    vlovgr on master

    Add ciris-circe Merge pull request #355 from vl… (compare)

  • Jun 26 13:15
    vlovgr closed #355
  • Jun 26 13:13
    codecov[bot] commented #355
  • Jun 26 13:07
    vlovgr opened #355
  • Jun 26 13:07

    vlovgr on circe

    Add ciris-circe (compare)

  • Jun 25 17:24

    vlovgr on gh-pages

    Deploy website Deploy website … (compare)

  • Jun 25 17:15

    mergify[bot] on master

    Update sbt-mdoc to 2.2.3 Merge pull request #354 from sc… (compare)

  • Jun 25 17:15
    mergify[bot] closed #354
Wojtek Pituła
@Krever
Hey, I was wondering: why ConfigValue is a FlatMap and Apply but not a Monad? It clearly shows that pure is not achievable but why?
Viktor Lövgren
@vlovgr
@Krever really great question! You might also have noticed that we have ConfigValue.default with the same signature as pure (excluding the by-name).
It is technically possible to have a Monad, but pure cannot be ConfigValue.default to get the right semantics.
Instead, pure has to be what would be ConfigValue.loaded(value), i.e. the current loaded but without any key.
So now the user basically has to choose between ConfigValue.default(value) and ConfigValue.loaded(value).
The main difference is that loaded means we won't be able to use defaults later in our composition.
Viktor Lövgren
@vlovgr
So techincally, we could have a Monad and expose ConfigValue.loaded(value), but it puts a burden on the user: should I use ConfigValue.default, ConfigValue.loaded, and what does pure mean here?
Instead, I went for a simpler approach: anything not a ConfigValue.loaded(key, value) is a default value, and the only way to construct it is with ConfigValue.default.
Wojtek Pituła
@Krever
I see! In fact I would also assume pure to be default and so it might be confusing. Thanks for the detailed answer
Another question: have you considered abandoning FlatMap and adding ability to generate some sort of docs? With flatmap in place its not technically possible. Im not saying its something worth doing, just wondering if it was considered. Similarly to --help in decline
Viktor Lövgren
@vlovgr
(Regarding the second part of the question: the reason why ConfigValue.Par only has an Apply instance and not e.g. FlatMap, is because the flatMap consistent with ap cannot be expressed using tailRecM. In v1.0.2 we have ConfigValue#parFlatMap with that exact flatMap though, because it's useful in certain situations, see here: https://github.com/vlovgr/ciris/pull/273.)
Viktor Lövgren
@vlovgr
@Krever There was this pull request before 1.x: vlovgr/ciris#257. You're correct that we can't go beyond Applicative if we want to generate documentation in the general case. I find flatMap to have a clear and useful purpose (i.e. affect configuration loading depending on an earlier value), and so there's a good reason for it to exist. I think generating documentation is tempting, but not tempting enough to give up flatMap.
It should still be possible to generate documentation, but it won't work across flatMaps of course (and so might be surprising in that case).
Not ideal, but if you limit yourself to Applicative when writing the configuration, it should still do the right thing.
Wojtek Pituła
@Krever
Thanks :) Now it reminds me there was some new typeclass coming out of research, standing between Monad and Applicative. I have to check it out and see how it plays with graph introspection (which is basically what we need for docs gen).
Viktor Lövgren
@vlovgr
Are you thinking of Selective?
Wojtek Pituła
@Krever
yep
Viktor Lövgren
@vlovgr
Also very interested to see how we can make use of it. :)
Matheus Hoffmann
@h0ffmann
Hello folks, i'm constructing some custom configuration, ConfigValue instances for list of url/ips usually when connecting to distributed brokers like Cassandra/Kafka .... I did in this way, it worked, but can i create a pure config value in some way? The unique way that i found was using .default method.
  type HostList = NonEmpty And Forall[Or[IPv4, Url]]

  final val hostRefined: String => ConfigValue[List[String]] = string => {
    refineV[HostList](string.split(",").toList.map(_.replace(" ", "")))
      .fold(
        error => ConfigValue.failed[List[String]](ConfigError(error)),
        correct => ConfigValue.default[List[String]](correct.value)
      )
  }
Viktor Lövgren
@vlovgr
@Hoffmannxd when decoding types you most often only want to use .as and write a custom ConfigDecoder if needed.
Something like the following should work.
import $ivy.`is.cir::ciris-refined:1.0.2`, cats.implicits._, ciris._, refined._
import eu.timepit.refined._, api._, boolean._, collection._, string._

type HostList = List[String] Refined (NonEmpty And Forall[Or[IPv4, Url]])

implicit val hostListConfigDecoder: ConfigDecoder[String, HostList] = 
  ConfigDecoder
    .identity[String]
    .map(_.split(",").toList.map(_.replace(" ", "")))
    .mapEither(ConfigDecoder[List[String], HostList].decode)

env("KAFKA_HOSTS").as[HostList]
Note the ConfigDecoder[List[String], HostList] comes from import ciris.refined._ (with the ciris-refined module).
We should probably add a convenience function for that last mapEither, so we could say e.g. mapDecode[HostList] instead.
Matheus Hoffmann
@h0ffmann
Thanks @vlovgr , this solution seems much more cleaner.
Wojtek Pituła
@Krever
Hey @vlovgr, would you be interested in incorporating ciris-hocon into ciris repo? I could contact author to check if thats ok. Currently cirisi-hocon is on ciris 0.12 and I can imagine it would be more maintanable in a long term to keep it together with ciris. In the end the integration is rather small, single file: https://github.com/2m/ciris-hocon/blob/master/src/main/scala/Hocon.scala
Viktor Lövgren
@vlovgr
Yes, great idea @Krever! :+1:
I believe @2m is in the channel, not sure if he's checking notifications though. :)
Wojtek Pituła
@Krever
I started to migrate the codebase and ended up reimplementing it from scratch with user-api similarities. I will try to make a PR to discuss what would be nice to have there
Viktor Lövgren
@vlovgr
:+1:
Wojtek Pituła
@Krever
Martynas Mickevičius
@2m
I am glad to see hocon support land to ciris. Thanks for pushing it @Krever !
rabzu
@rabzu
How to show print the config in new ciris
Viktor Lövgren
@vlovgr
@rabzu Do you mean generating a Show instance with kittens? If so, nothing has changed. It's not really a feature of ciris, as much as kittens.
SealBadger
@SealBadger_twitter
Hi, I think I would really benefit from seeing a project using this library for some ideas. Are there any you can point me to on gitlab, github etc.?
SealBadger
@SealBadger_twitter
Ah, just found some. If there are any "great" examples feel free to share :).
ricardo amaral
@rmsam
@SealBadger_twitter Maybe you can have a look at Gabriel Volpe's repo for his "Practical FP in Scala" book: https://github.com/gvolpe/pfps-shopping-cart/blob/master/modules/core/src/main/scala/shop/config/loader.scala
Bunyod
@Bunyod

Hello guys!

I have a small question. If I understand correctly we cannot load configuration from resources folder (as we do with pureconfig) and ciris is environment based config loader, right?

what I'm trying to do is like this:
env("APP_ENV").as[AppEnvironment].option.flatMap {
      case Some(AppEnvironment.Dev) | None =>
        ConfigValue.default[Config](ConfigSource.default.loadOrThrow[Config]) // trying to load with pure config. there are refined types 
      case _ =>
        (
          ... // read from env and validate, build ConfigValue with parMapN manually
        )
}
Cory Parent
@goedelsoup
there is also https://github.com/2m/ciris-hocon but I'm not sure if it's compatible with the version of ciris you are running
Cory Parent
@goedelsoup
ciris is really a configuration algebra which provides a few implementations in the core. you can really read anything using the functions provided in the companion object of ConfigValue. for example, i've created methods to read from hashicorp consul and vault for my company's internal use.
Viktor Lövgren
@vlovgr
@Krever has started working on a ciris-hocon integration (vlovgr/ciris#284) if that's what you're looking for @Bunyod
Bunyod
@Bunyod
OK, thank you very much guys. l look forward to that pr merged
Wojtek Pituła
@Krever
Sadly I had to stop in the middle. You can pick it up if you wish. I planned to get back to it as soon as I have a need for this again, which I estimate to happen in 3-6 months...
Bunyod
@Bunyod
@Krever I see, will try
Jente Hidskes
@Hjdskes
Hey people! Awesome library, I'm really enjoying it :) The SSM integration module especially is nice!
That said, I do have a question. Is there already a ConfigDecoder[String, Json] out there, or maybe even something more generic that allows me to have a ConfigDecoder[String, A] for any A with a Circe Decoder[A]?
Jente Hidskes
@Hjdskes

I've written one for the latter case:

  implicit def circeConfigDecoder[A: Decoder]: ConfigDecoder[String, A] =
    ConfigDecoder[String].mapEither {
      (_, s) => decode[A](s).leftMap {
          case ParsingFailure(message, _) => ConfigError(message)
          case DecodingFailure(message, _) => ConfigError(message)
      }
    }

This requires the circe-parser module from circe.

Viktor Lövgren
@vlovgr
@Hjdskes I'd happily accept a pull request for a ciris-circe module. :)
Jente Hidskes
@Hjdskes
@vlovgr I'll see what I can do in the time that I have :)