{"id":20905001,"url":"https://github.com/pureharm/pureharm-config-ciris","last_synced_at":"2026-05-23T05:34:28.688Z","repository":{"id":48121907,"uuid":"353723044","full_name":"pureharm/pureharm-config-ciris","owner":"pureharm","description":"Pureharm style library for ciris config library","archived":false,"fork":false,"pushed_at":"2021-08-05T16:40:28.000Z","size":44,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-01-19T14:17:20.369Z","etag":null,"topics":["cats-effect","ciris","pureharm","scala"],"latest_commit_sha":null,"homepage":"","language":"Scala","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pureharm.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-04-01T14:14:48.000Z","updated_at":"2022-10-28T12:39:14.000Z","dependencies_parsed_at":"2022-08-12T19:01:06.399Z","dependency_job_id":null,"html_url":"https://github.com/pureharm/pureharm-config-ciris","commit_stats":null,"previous_names":["busymachines/pureharm-config-ciris"],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pureharm%2Fpureharm-config-ciris","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pureharm%2Fpureharm-config-ciris/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pureharm%2Fpureharm-config-ciris/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pureharm%2Fpureharm-config-ciris/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pureharm","download_url":"https://codeload.github.com/pureharm/pureharm-config-ciris/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243296194,"owners_count":20268544,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cats-effect","ciris","pureharm","scala"],"created_at":"2024-11-18T13:20:31.840Z","updated_at":"2025-12-27T08:35:39.580Z","avatar_url":"https://github.com/pureharm.png","language":"Scala","funding_links":[],"categories":[],"sub_categories":[],"readme":"# pureharm-config-ciris\n\nSee [changelog](./CHANGELOG.md).\n\n## scala versions\n- 2.13: JVM\n- 3: JVM\n\n## modules\n\nThe available modules are.\n\n- `\"com.busymachines\" %% s\"pureharm-config-ciris\" % \"0.2.0\"`. Which has these as its main dependencies:\n  - [cats-effect](https://github.com/typelevel/cats-effect) `3.2.1`\n  - [ciris](https://github.com/vlovgr/ciris/releases) `2.1.1`\n  - [ip4s](https://github.com/Comcast/ip4s/releases) `3.0.3`\n  - [pureharm-core-sprout](https://github.com/busymachines/pureharm-core/releases) `0.3.0`\n  - [pureharm-core-anomaly](https://github.com/busymachines/pureharm-core/releases) `0.3.0`\n\n- `\"com.busymachines\" %% s\"pureharm-config-ciris-ip4s\" % \"0.2.0\"`. This module brings in aliases, and `ciris.ConfigDecoder` for ip4s datatypes like `Port`, `Host,` etc. Extremely useful for strongly typed stuff \n  - [cats-effect](https://github.com/typelevel/cats-effect) `3.2.1`\n  - [ciris](https://github.com/vlovgr/ciris/releases) `2.1.1`\n  - [ip4s](https://github.com/Comcast/ip4s/releases) `3.0.3`\n\n## usage\n\nThe encouraged style to use this library is to create your own \"config\" package in your app, which contains the opiniated way of doing configs in your application. That's why `pureharm-config-ciris` provides a straightforward way of achieving this, while allowing you to add your own stuff on top.\n\n```scala\npackage busymachines.test\n\nimport cats._\nimport cats.effect._\nimport cats.implicits._\n\nimport busymachines.pureharm.sprout._\nimport busymachines.pureharm.config\n\n/** Recommended to do something similar once in your app. To define your prefered \"flavor\" of reading configs.\n  *\n  * In this case we basically explicitely say that we only get config values from environment variables.\n  */\nobject myconfig\n  extends config.PureharmConfigAllAliases with config.PureharmConfigAllImplicits with config.CirisIp4sInstances {\n  sealed trait EnvVar\n\n  /** Single source of truth for the env vars in the system\n    */\n  object EnvVar {\n    case object PH_DB_PORT     extends EnvVar\n    case object PH_DB_HOST     extends EnvVar\n    case object PH_DB_NAME     extends EnvVar\n    case object PH_SERVER_PORT extends EnvVar\n    case object PH_SERVER_HOST extends EnvVar\n  }\n\n  /** This alias allows us some bit of typesafety in our app\n    */\n  def env(s: EnvVar): ConfigValue[CirisEffect, String] = ciris.env(s.toString)\n}\n\n/** If it typechecks, ship it!\n  */\nobject CirisConfigExample {\n  import com.comcast.ip4s._\n  import myconfig._\n\n  type DBPort = DBPort.Type\n  object DBPort extends Sprout[Port]\n\n  type DBHost = DBHost.Type\n  object DBHost extends Sprout[Host]\n\n  type DBName = DBName.Type\n  object DBName extends Sprout[String]\n\n  //in a real world app these might come from a different module that doesn't even depend on config\n  case class DBConfig(\n    port: DBPort,\n    host: DBHost,\n    name: DBName,\n  )\n\n  type ServerPort = ServerPort.Type\n  object ServerPort extends Sprout[Port]\n\n  type ServerHost = ServerHost.Type\n  object ServerHost extends Sprout[Host]\n\n  //in a real world app these might come from a different module that doesn't even depend on config\n  case class ServerConfig(\n    port: ServerPort,\n    name: ServerHost,\n  )\n\n  //an example of a top-level module config that loads everything at once\n  case class ExampleConfig(\n    db:     DBConfig,\n    server: ServerConfig,\n  )\n\n  object ExampleConfig {\n\n    def load[F[_]: Config: Monad]: F[ExampleConfig] = for {\n      db     \u003c- DBConfigLoader.load[F]\n      server \u003c- ServerConfigLoader.load[F]\n    } yield ExampleConfig(\n      db,\n      server,\n    )\n\n    private object DBConfigLoader extends ConfigLoader[DBConfig] {\n\n      override def configValue: ConfigValue[CirisEffect, DBConfig] =\n        (\n          env(EnvVar.PH_DB_PORT).as[DBPort].default(DBPort(port\"5432\")),\n          env(EnvVar.PH_DB_HOST).as[DBHost].default(DBHost(host\"localhost\")),\n          env(EnvVar.PH_DB_NAME).as[DBName].default(DBName(\"example_db_name\")),\n        ).parMapN(DBConfig.apply)\n    }\n\n    private object ServerConfigLoader extends ConfigLoader[ServerConfig] {\n\n      override def configValue: ConfigValue[CirisEffect, ServerConfig] = (\n        env(EnvVar.PH_DB_PORT).as[ServerPort].default(ServerPort(port\"21312\")),\n        env(EnvVar.PH_DB_HOST).as[ServerHost].default(ServerHost(host\"localhost\")),\n      ).parMapN(ServerConfig.apply)\n\n    }\n  }\n\n  /** Instantiate the Config[F] capability once, pass along everywhere where used.\n    */\n  object MyIOApp extends cats.effect.IOApp.Simple {\n\n    override def run: IO[Unit] = runF[IO]\n\n    def runF[F[_]: Async]: F[Unit] = {\n      implicit val config: Config[F] = Config.async[F]\n\n      for {\n        exampleConfig \u003c- ExampleConfig.load[F]\n        _             \u003c- Async[F].blocking(\n          println(s\"pass along the $exampleConfig config to the rest of your app in bits and pieces you need\")\n        )\n      } yield ()\n    }\n  }\n\n}\n```\n\n## Copyright and License\n\nAll code is available to you under the Apache 2.0 license, available\nat [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0) and also in\nthe [LICENSE](./LICENSE) file.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpureharm%2Fpureharm-config-ciris","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpureharm%2Fpureharm-config-ciris","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpureharm%2Fpureharm-config-ciris/lists"}