Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Jan 31 2019 15:23
    ashabhasa starred pureconfig/pureconfig
  • Jan 30 2019 20:03

    ruippeixotog on master

    Update cats-effect, fs2 and htt… Merge pull request #448 from ba… (compare)

  • Jan 30 2019 20:03
    ruippeixotog closed #448
  • Jan 30 2019 08:05
    Mao1990 starred pureconfig/pureconfig
  • Jan 29 2019 13:08
    bardurdam opened #448
  • Jan 29 2019 10:20
    PatrykRudnicki starred pureconfig/pureconfig
  • Jan 28 2019 18:52

    ruippeixotog on master

    Create a FluentConfigCursor Merge branch 'master' into flue… Fix yaml module on Scala 2.11 and 3 more (compare)

  • Jan 28 2019 18:52
    ruippeixotog closed #443
  • Jan 28 2019 18:02
    ruippeixotog synchronize #443
  • Jan 28 2019 18:02

    ruippeixotog on fluent-cursor

    Create scalaz module for pureco… Merge branch 'master' into scal… Update module with latest Confi… and 19 more (compare)

  • Jan 27 2019 14:09
    esumitra starred pureconfig/pureconfig
  • Jan 27 2019 01:55

    ruippeixotog on master

    Create scalaz module for pureco… Merge branch 'master' into scal… Update module with latest Confi… and 6 more (compare)

  • Jan 27 2019 01:55
    ruippeixotog closed #444
  • Jan 27 2019 01:19
    ruippeixotog synchronize #444
  • Jan 27 2019 01:19

    ruippeixotog on master

    Add cron4s module - add cron4s… Merge pull request #446 from ba… (compare)

  • Jan 27 2019 01:19
    ruippeixotog closed #446
  • Jan 26 2019 22:51
    ChernikovP synchronize #444
  • Jan 26 2019 22:37
    bardurdam synchronize #446
  • Jan 26 2019 22:36
    bardurdam commented #446
  • Jan 26 2019 22:31
    bardurdam synchronize #446
David Geirola
@geirolz
@ruippeixotog Thank you :)
igroeg
@igroeg
Hi Guys :) Do you know a way I can convert Case class to java.util.Properties? Or already provided config instead to map it to case classes, just map to Properties class instead?
Pavel Khamutou
@pkhamutou

Hi! I have a question, is there a way to define a fallback key with a different name?
For example, if expected key is not present in the config file, read another one instead.

case class Api(host: String, port: Int)

// a.conf
{
  host: web
  default-host: defaultweb
  port: 8080
}

// b.conf
{
  default-host: defaultweb
  port: 8080
}

// 'host' is present then just load it
ConfigSource.file("a.conf").load[Api] // Api(web, 8080)

// 'host' isn't present so fallback to 'default-host' and map it to `host: String` in the case class
ConfigSource.file("b.conf").load[Api] // Api(defaultweb, 8080)

Thank you!

LeRiton
@LeRiton

Hi PureConfig!
Thanks for the clever work.
We are using Maven and shading some of our projects. maven-shade-plugin complains about overlapping classes between pureconfig-generic and pureconfig-generic-base.

\- com.github.pureconfig:pureconfig_2.12:jar:0.16.0:compile
   +- com.github.pureconfig:pureconfig-core_2.12:jar:0.16.0:compile
   \- com.github.pureconfig:pureconfig-generic_2.12:jar:0.16.0:compile
      +- (com.github.pureconfig:pureconfig-core_2.12:jar:0.16.0:compile - omitted for duplicate)
      \- com.github.pureconfig:pureconfig-generic-base_2.12:jar:0.16.0:compile
         \- (com.github.pureconfig:pureconfig-core_2.12:jar:0.16.0:compile - omitted for duplicate)

Is this something we have to deal with of some misconfiguration from us?
Thanks in advance!

Rui Gonçalves
@ruippeixotog

@pkhamutou I'm afraid there's no built-in support for something like that, you'd have to build your own ConfigReader for your class. I wouldn't recommend that though, as we recommend case classes to reflect the data model as closely as possible.

However, that seems like a non-idiomatic way of handling defaults. The normal approach is to use reference.conf (https://github.com/lightbend/config#standard-behavior) and leverage HOCON variable substitutions to encode default value handling in config files themselves, not in code.

Another approach would be to have something like this:

case class Api(host: Option[String], port: Int, defaultHost: String) {
  def resolvedHost = host.getOrElse(defaultHost)
}
@LeRiton that's a known problem, see #919
1 reply
Pavel Khamutou
@pkhamutou

@ruippeixotog
I was able to make it work by overwriting the ProductHint:

  implicit def hint[A](implicit prefix: Prefix = Prefix.Empty): ProductHint[A] = {
    val productHint = ProductHint[A](ConfigFieldMapping(CamelCase, ScreamingSnakeCase))

    prefix match {
      case Prefix.Empty => productHint
      case Prefix.NonEmpty(prefix) =>
        new ProductHint[A] {
          override def from(cursor: ConfigObjectCursor, fieldName: String): ProductHint.Action = {
            val prefixedFieldName: String = prefix + fieldName.capitalize // `api` -> `prefixApi`

            productHint.from(cursor, prefixedFieldName) match {
              case ProductHint.Use(cur, _) if cur.isUndefined =>
                productHint.from(cursor, fieldName) // fall back to default
              case ProductHint.UseOrDefault(cur, _) if cur.isUndefined =>
                productHint.from(cursor, fieldName) // fall back to default
              case other => other
            }
          }

          override def bottom(cursor: ConfigObjectCursor, usedFields: Set[String]): Option[ConfigReaderFailures] =
            productHint.bottom(cursor, usedFields)

          override def to(value: Option[ConfigValue], fieldName: String): Option[(String, ConfigValue)] =
            productHint.to(value, fieldName)
        }
    }
  }

it works well for Reader but i think Writer would produce an inconsistent result however it is never used.

Leif Battermann
@battermann
Hi, I am working on a project where they use Slick. And now we want to migrate to PureConfig. Is there a way to use PureConfig with Slick?
Leif Battermann
@battermann
I guess PureConfig is best used for all our own configurations, we’ll keep using TypeSafe Config with all external libraries...
Rui Gonçalves
@ruippeixotog
Hi @battermann, unfortunately there's currently no PureConfig module for reading Slick configs. You can find a list of modules in https://pureconfig.github.io/docs/library-integrations.html
Isaac Zeng
@gfZeng
How to load case class without derives ConfigReaderDerivation in scala 3?
zhukovgreen
@zhukovgreen
Hey, I have a default value in my case class, but receiving Key not found:. How to debug this?
I also wonder if I understood it properly, that I can create separate ProductHint for subclasses of my config, like
object Config {
  def from_config(file: File): Config = {

    // custom conversion hooks
    implicit val localDateConvert: ConfigConvert[LocalDate] =
      localDateConfigConvert(DateTimeFormatter.ISO_DATE)
    implicit val challengeProdHint: ProductHint[Challenge] =
      ProductHint[Challenge](new ConfigFieldMapping {
        def apply(fieldName: String): String =
          fieldName match {
            case "challengeId"    => "id"
            case "name"           => "name"
            case "description"    => "description"
            case "startDate"      => "start-date"
            case "endDate"        => "end-date"
            case "claimStartDate" => "claim-start-date"
            case "claimEndDate"   => "claim-end-date"
            case "extraOptions"   => "option"
          }
      })
    implicit val rootProdHint: ProductHint[Config] =
      ProductHint[Config](ConfigFieldMapping(CamelCase, CamelCase))

    ConfigSource.file(file).loadOrThrow[Config]
  }
}
zhukovgreen
@zhukovgreen
adding useDefaultArgs = true solved my problem, but why? I see that it is true by default :confused:
Lakshmanan Meiyappan
@laxmena

Looking for help.

I tried to run sbt clean compile run and I get the following error message in the shell

[error] (update) sbt.librarymanagement.ResolveException: Error downloading com.github.pureconfig:pureconfig_3:0.16.0
[error] Not found
[error] Not found
[error] not found: C:\Users\laksh.ivy2\localcom.github.pureconfig\pureconfig_3\0.16.0\ivys\ivy.xml
[error] not found: https://repo1.maven.org/maven2/com/github/pureconfig/pureconfig_3/0.16.0/pureconfig_3-0.16.0.pom
[error] not found: https://jcenter.bintray.com/com/github/pureconfig/pureconfig_3/0.16.0/pureconfig_3-0.16.0.pom
image.png

image.png

This is screenshot of my sbt.build file

Lakshmanan Meiyappan
@laxmena
I'm using Scala3
heksesang
@heksenlied:matrix.org
[m]
Use com.github.pureconfig:pureconfig-core_3:0.16.0 – the artifact you are trying to find includes the shapeless-based generic library which isn't supported on Scala 3. 😃
Matthew de Detrich
@mdedetrich
Hello! Would it be possible to make a release of pureconfig, there have been some additional changes (such as pureconfig/pureconfig#1117) that have been sitting there for a while?
Nik
@your-psychiatrist:ellipsen.net
[m]
Hello people :) Docs say auto derivation works for scala 3 but i am on 0.16 and import pureconfig.generic.derivation.default._ is not resolving for me, now i have to use semiauto for the entire domain model which is tiresome
Should autoderivation work or is that actually still in the making?
Clint Combs
@ClintCombs

I was recently able to cross build a Scala project with 2.12, 2.13, and 3 that depends on pureconfig-core and pureconfig-generic and uses Scala 3 derivation ( https://pureconfig.github.io/docs/scala-3-derivation.html ) with sbt 1.5.4 using the follow dependency:

  lazy val pureconfig = Seq(
    "com.github.pureconfig" %% "pureconfig-core" % V.Pureconfig,
    ("com.github.pureconfig" %% "pureconfig-generic" % V.Pureconfig).cross(CrossVersion.for3Use2_13)
  )

After upgrading to sbt 1.5.5 it now fails with [error] (update) Conflicting cross-version suffixes in: com.github.pureconfig:pureconfig-core due to this change: sbt/librarymanagement#383 For now I'll have to stick with sbt 1.5.4 to avoid this issue. Is the above dependency no longer allowed or is this an sbt bug?

I asked the above over on the sbt/sbt gitter channel - haven't seen any feedback yet. I'm repeating it here to see if I get a response. I assume the ultimate solution is to have both pureconfig-core and pureconfig-generic published for Scala 3, but it sounds like that's going to take a while. For now, I'm staying on sbt 1.5.4 until I have a better solution. Any thoughts on this?

Rui Gonçalves
@ruippeixotog
@mdedetrich I have just released PureConfig v0.17.0
balthz
@balthz

Hello folks! The KeyNotFound feature is very helpful to catch configuration errors early. One thing I found a bit difficult with it, though, is using it with sealed families. For example, assuming

sealed trait AnimalConf
case class DogConf(age: Int) extends AnimalConf
case class BirdConf(canFly: Boolean) extends AnimalConf

I'd like to make parsing of { type: dog-conf, age: 4 , canFly: true} succeed but parsing of { type: dog-conf, age: 4 , camFly: true}fail (because there's a typo in camFly). Is this possible?

The background is that I'd like to my default config to cover both cases and be able to switch between them easily, for example with a config override on just field type.

Cosmin Ciobanu
@cosminci

Hi! I'm trying to add support for CIString as a Map key type but am stuck with this error message from splain:

――――DerivedConfigReader.anyValReader invalid because
    !I ev (Cannot prove that scala.collection.immutable.Map[org.typelevel.ci.CIString,com.adobe.analytics.va.realtime.hermes.metadata.Organization] <:< AnyVal.): Map[CIString, Organization] <:< AnyVal

If the key type is String, everything combines nicely and works (Organization is a case class).

What I'm defining:

implicit val r: ConfigReader[CIString] = ConfigReader[String].map(CIString(_))

Any idea what's going on here?

The resolved maven dependency is org.typelevel:case-insensitive_2.12:jar:1.1.4:compile

heksesang
@heksenlied:matrix.org
[m]
You probably haven't created a ConfigReader for Map[CIString, Organization].
It doesn't automatically derive ConfigReader for Map[K, V], I mean to recall, even if you have defined a ConfigReader[K] and ConfigReader[V]. There is a genericMapReader method that can be used to create such a reader, though.
1 reply
David Geirola
@geirolz
Hi guys, how can I traverse the config with a path and then parse the object using PureConfig(deriving the reader) ? I'm migrating an already existent config to PureConfig, I have a long config path with only one object and the end, I don't want to create the path with a nested case class with only one field until the last one
Rui Gonçalves
@ruippeixotog
Yes, you can use the at method on ConfigSource to navigate in a config before you call load or loadOrThrow
Nitesh Singh Kataria
@NiteshSK

Hello folks,

I was trying to run the tests using '/test/resources/application.conf'
But it still pointing to the 'src/main/resources/application.conf'

Is it possible to change the application.conf in pureConfig ?
Thanks in advance

Jens Grassel
@jan0sch
Hi, is there a simple way to parse a Map[RefinedStringType, CustomType]? The docs mention converters but I was unable to find some example code regarding map keys conversion.
Jens Grassel
@jan0sch
I found something that works:
genericMapReader[RefinedStringType, CustomType](optF[RefinedStringType](s => RefinedStringType.from(s).toOption))
Leif Wickland
@leifwickland

@NiteshSK Are you trying to run the tests in your project or in the pureconfig project?

Either way, generally sbt puts src/test/resources ahead of src/main/resources in the classpath. The quick example I build loaded the test version of application.conf.

If you need more help, I'm afraid I'd need you to share an sample that replicates the problem you're running into.

David Geirola
@geirolz

There is a way to use genericMapReader where the key is not a string ? I'm configuring kafka and I have to pass a map String, String as configuration.
I've tried something like that

properties {
      security.protocol = "SASL_SSL"
      ssl.endpoint.identification.algorithm = "https"
      sasl.mechanism = "PLAIN"
    }

But using genericMapReader I have an error Expected type STRING. Found OBJECT instead., it makes sense but there is a way to read that config as a Map[String, String] ?

heksesang
@heksenlied:matrix.org
[m]
Might be the dot-syntax in the keys it doesn't like.
Rui Gonçalves
@ruippeixotog
Yes, properties { security.protocol = "SASL" } is equivalent to properties { security { protocol = "SASL" }} in HOCON configs, it's part of Lightbend Config's parsing behavior. You can create a reader that flattens all the keys, but PureConfig doesn't provide that out of the box
Alex
@unthingable
Curious why this is generating complaints of missing otlp key instead of returning None:
case class Config(tracing: TraceConfig) derives ConfigReader

case class HostPort(host: String, port: Int, auth: Option[String] = None)

case class TraceConfig(
  env: Option[String],
  otlp: Option[HostPort] = None,
) derives ConfigReader

...
tracing {
  env = "foo"
}
Ah, HostPort needed to derive ConfigReader.
Luís Campos
@LLCampos

Hello!
How can I load a config in a way that I can then overwrite the default conf file with e.g. sbt -Dconfig.resource=application.dev.conf run?

Expected ConfigSource.default.loadOrThrow[Config] to do it, but it keeps loading application.conf

k3rnL
@k3rnL

Hello 👋
I'm wondering why the default (and pretty useful) behavior of the default HOCON reader when reading list was drop in pureconfig ?
Ex.

list = toto
list = [toto]

Are both corrects when reading a StringList in the Java API.

I managed to re-implemented this behavior with a custom traversableReader, it's enough for my use cases. But I don't get why this behavior was drop. Is it for a problem of reading multiple time the cursor ? Or error management ?
Otherwise I would be grateful to merge request my changes.

Rui Gonçalves
@ruippeixotog
@LLCampos that shouldn't happen. ConfigSource.default ends up calling ConfigFactory.load() for config loading, so all the rules applied there also apply to PureConfig. Are you sure that system property is being propagated from the SBT process to your app process?
@k3rnL I don't think Typesafe config does what you suggested:
scala> com.typesafe.config.ConfigFactory.parseString("list = todo").getList("list")
com.typesafe.config.ConfigException$WrongType: String: 1: list has type STRING rather than LIST
  at com.typesafe.config.impl.SimpleConfig.findKeyOrNull(SimpleConfig.java:164)
  at com.typesafe.config.impl.SimpleConfig.findOrNull(SimpleConfig.java:175)
  at com.typesafe.config.impl.SimpleConfig.find(SimpleConfig.java:189)
  at com.typesafe.config.impl.SimpleConfig.find(SimpleConfig.java:194)
  at com.typesafe.config.impl.SimpleConfig.getList(SimpleConfig.java:263)
  ... 55 elided
k3rnL
@k3rnL

@ruippeixotog Oh right, I don't why I had this thought...
Not sure if it's still a good idea then. I implemented it like this :

implicit def traversableReader[A, F[B] <: TraversableOnce[B]](implicit configConvert: ConfigReader[A],
                                                                cbf: FactoryCompat[A, F[A]]
                                                               ): ConfigReader[F[A]] = {
    (cur: ConfigCursor) => {
      val builder = cbf.newBuilder()
      configConvert.map { v =>
        (builder += v).result()
      }.from(cur)
      match {
        case Left(_) => cur.fluent.mapList { valueCur => configConvert.from(valueCur) }.map { coll =>
          (builder ++= coll).result()
        }
        case Right(value) => Right(value)
      }
    }

  }

It allows me this write my confg like this :

sync = [
  {
    threading = 4
    from = {file-system = {type = local}, path = "/../../../../"}
    to = {file-system = {type = hdfs}, path = "/Users/../../.."}
  }
]

Or

sync = [
  {
    threading = 4
    from = [
      {file-system = {type = local}, path = "/../../../"}
      {file-system = {type = local}, path = "/../../../../"}
      {file-system = {type = local}, path = "/../../"}
    ]
    to = {file-system = {type = hdfs}, path = "/Users/.../../.."}
  }
]

It looks more natural to me.
Then in the code the config is like this :

case class Config(sync: List[Sync])

case class Sync(minimumModificationTimeDelta: Duration = Duration(10, SECONDS),
                maximumModificationTimeDelta: Option[Duration],
                from: List[Source], // <-- Here I get a list even in case of a single value
                to: Sink)
Rui Gonçalves
@ruippeixotog

If you only care about lists, you can write it in a much simpler manner, as:

def listReader[A: ConfigReader]: ConfigReader[List[A]] = ConfigReader[List[A]].orElse(ConfigReader[A].map(List(_)))

If you want all traversables you need a few more implicits, but you can still use the same structure.

I would personally disagree it's "natural". Scala codebases usually strive to be strict on types - if I have a list on a config object, I expect it to be represented as a list in a config without any "magic" coercion going on. But if you find it useful for your use cases, it's definitely possible to use something like this.

Think about what would happen if you wanted to read a list of lists - it could lead to confusion over what mode you intended to use
Faiaz Sanaulla
@fsanaulla

Hey, maybe someone faced such an issue in the past:

Exception in thread "main" java.lang.AbstractMethodError: pureconfig.ConfigFieldMapping$$$Lambda$40/1046545660.andThen(Lscala/Function1;)Lscala/Function1;
using pureconfig with spark

Thank you!

Faiaz Sanaulla
@fsanaulla
pureconfig - 0.17.1
spark - 2.4.8
Renan Rossignatti de França
@renanrfranca

Hi. I'm trying to load a config into a list of objects
It looks like this: Config(SimpleConfigObject({"list":[{"display-name":"dn1","domain":"@dm1","key":"key1"},{"display-name":"dn2","domain":"@dm2","key":"gnome"}]}))

I try to convert it withConfigSource.fromConfig(myConfig).loadOrThrow[ProductsConfig]

Relevant case classes:

final case class ProductsConfig(list: List[Product])

case class Product(key: String, displayName: String, domain: String)

which results in

Cannot convert configuration to a com.bt.fv.consumer.ncc.api.ProductsConfig. Failures are: at the root:

      - (String: 1) Expected type STRING. Found OBJECT instead