{"id":19177009,"url":"https://github.com/joomcode/colonist","last_synced_at":"2025-10-14T08:37:00.848Z","repository":{"id":38240475,"uuid":"194266327","full_name":"joomcode/colonist","owner":"joomcode","description":"Compile time class discovery framework for JVM languages","archived":false,"fork":false,"pushed_at":"2023-10-02T18:23:28.000Z","size":465,"stargazers_count":23,"open_issues_count":1,"forks_count":3,"subscribers_count":76,"default_branch":"develop","last_synced_at":"2025-05-07T20:06:53.508Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Kotlin","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/joomcode.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-06-28T11:58:22.000Z","updated_at":"2024-04-05T19:25:43.000Z","dependencies_parsed_at":"2023-10-03T18:30:37.608Z","dependency_job_id":null,"html_url":"https://github.com/joomcode/colonist","commit_stats":null,"previous_names":[],"tags_count":23,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joomcode%2Fcolonist","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joomcode%2Fcolonist/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joomcode%2Fcolonist/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joomcode%2Fcolonist/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/joomcode","download_url":"https://codeload.github.com/joomcode/colonist/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252949272,"owners_count":21830151,"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":[],"created_at":"2024-11-09T10:31:35.160Z","updated_at":"2025-10-14T08:36:55.820Z","avatar_url":"https://github.com/joomcode.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Build](https://github.com/joomcode/colonist/workflows/Build/badge.svg)](https://github.com/joomcode/colonist/actions)\n\nColonist\n========\n\nCompile time class discovery framework for JVM languages.\n\nWhy?\n----\n\nSometimes you may want to find all classes that match some condition and perform\nan action on every such class. On Android it could be quite a challenging task\nsince there's no documented way to enumerate all classes from an APK using\nreflection. Moreover, solving this problem with reflection would affect \napplication performance negatively.\n\nColonist offers a solution by moving class discovery step to the compile-time.\nAnd at the runtime you just need to iterate through a precomputed list of\nclasses and do whatever you need.\n\nUsage\n-----\n\n### Attention\n\nThe library is experimental. Its API isn't stable yet and may change dramatically.\n\n### Configuration\n\n```groovy\nbuildscript {\n  repositories {\n    mavenCentral()\n  }\n\n  dependencies {\n    classpath 'com.joom.colonist:colonist-gradle-plugin:0.1.0-alpha12'\n  }\n}\n\n// For Android projects.\napply plugin: 'com.android.application'\napply plugin: 'com.joom.colonist.android'\n\n// For other projects.\napply plugin: 'java'\napply plugin: 'com.joom.colonist'\n```\n\n### Colonies\n\nColonist requires three steps to be defined in order to describe how to deal\nwith classes (settlers): selection, production, and acceptance. And that's what\na colony is for.\n\nThe colony is an annotation that, in its turn, is annotated with `@Colony`\nmeta-annotation. Moreover, the colony must be annotated with another three\nannotations that define steps of settlers discovery.\n\n#### Selection\n\nThe first step in class discovery is selection that specifies a common attribute\nclasses must have to be discovered. At the moment there're just two ways to\nselect classes:\n\n- `@SelectSettlersByAnnotation` discovers all classes annotated with a specified\nannotation class.\n- `@SelectSettlersBySuperType` selects all classes that extend a given class. \n\n#### Production\n\nThe second step is production and it specifies what the discovered classes are\ngoing to be converted to:\n\n- `@ProduceSettlersAsClasses` is an identity conversion. In other words it\nproduces the same classes it receives.\n- `@ProduceSettlersViaCallback` invokes a user-defined callback for every\ndiscovered class and uses its return values as the result.\n- `@ProduceSettlersViaConstructor` instantiates classes using their default\nconstructors. The default constructors for all discovered classes **must exist**. \n\n#### Acceptance\n\nThe third and the last step is acceptance and it's responsible for collecting\nthe results of the previous two steps (i.e. settlers):\n- `@AcceptSettlersAndForget` just ignores all the settlers. This behavior may be\nuseful if settlers are autonomous and just need to be created in order to do\ntheir stuff.\n- `@AcceptSettlersViaCallback` invokes a user-defined callback for every \nproduced settler.\n\n#### All together\n\nIt's much easier to understand what's going on using a simple example. Let's\nwrite a class that finds all plugins and initializes them. And we'll start with\na plugin interface:\n\n```kotlin\ninterface Plugin {\n  fun initialize(context: Context)\n}\n```\n\nWe'll be looking only for plugin classes annotated with a particular annotation\nthat we need to define:\n\n```kotlin\n@Target(AnnotationTarget.CLASS)\nannotation class AutoPlugin\n```\n\nThen we need a couple of plugin implementations that we'll use in our sample.\nLet's make it a bit more complex and also create a base plugin implementation: \n\n```kotlin\nabstract class BasePlugin(private val name: String) : Plugin {\n  override fun initialize(context: Context) = println(\"Initialize $name\")\n}\n\n@AutoPlugin\nclass Plugin1 : BasePlugin(\"Plugin1\")\n\n@AutoPlugin\nclass Plugin2 : BasePlugin(\"Plugin2\")\n```\n\nNow we need to define a colony annotation that will discover and instantiate all\nexisting plugins:\n\n```kotlin\n@Colony\n@SelectSettlersByAnnotation(AutoPlugin::class)\n@ProduceSettlersViaConstructor\n@AcceptSettlersViaCallback\n@Target(AnnotationTarget.CLASS)\nannotation class PluginColony\n```\n\nSome entity should be responsible for plugin initialization so let's assume we\nhave a plugin manager:\n\n```kotlin\n@PluginColony\nclass PluginManager(private val context: Context) {\n  init {\n    Colonist.settle(this)\n  }\n\n  @OnAcceptSettler(colonyAnnotation = PluginColony::class)\n  fun onAcceptPlugin(plugin: Plugin) {\n    plugin.initialize(context)\n  }\n}\n```\n\nAfter running the application you'll the following lines in the log but the order may differ:\n```\nInitialize Plugin1\nInitialize Plugin2\n```\n\nLicense\n-------\n\n    Copyright 2021 SIA Joom\n\n    Licensed under the Apache License, Version 2.0 (the \"License\");\n    you may not use this file except in compliance with the License.\n    You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing, software\n    distributed under the License is distributed on an \"AS IS\" BASIS,\n    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n    See the License for the specific language governing permissions and\n    limitations under the License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjoomcode%2Fcolonist","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjoomcode%2Fcolonist","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjoomcode%2Fcolonist/lists"}