{"id":23999090,"url":"https://github.com/bytekeeper/whisk","last_synced_at":"2026-05-17T07:38:24.096Z","repository":{"id":85149958,"uuid":"188720264","full_name":"Bytekeeper/whisk","owner":"Bytekeeper","description":"Build system based on a functional build language","archived":false,"fork":false,"pushed_at":"2020-04-21T20:32:35.000Z","size":4244,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-08T23:24:16.656Z","etag":null,"topics":["build-system","build-tool","java","whisk"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Bytekeeper.png","metadata":{"files":{"readme":"readme.MD","changelog":null,"contributing":null,"funding":null,"license":null,"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-05-26T18:53:43.000Z","updated_at":"2020-04-21T20:32:38.000Z","dependencies_parsed_at":"2023-03-04T20:15:28.279Z","dependency_job_id":null,"html_url":"https://github.com/Bytekeeper/whisk","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Bytekeeper%2Fwhisk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Bytekeeper%2Fwhisk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Bytekeeper%2Fwhisk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Bytekeeper%2Fwhisk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Bytekeeper","download_url":"https://codeload.github.com/Bytekeeper/whisk/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240637122,"owners_count":19833006,"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":["build-system","build-tool","java","whisk"],"created_at":"2025-01-07T23:45:39.315Z","updated_at":"2026-05-17T07:38:19.077Z","avatar_url":"https://github.com/Bytekeeper.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Whisk (yet another build tool)\nUsing `phases` or `task` dependency graphs is good, but limited. The build system doesn't really understand what\nyou are trying to build. And without proper documentation, developers don't understand why a certain task depends\non another.\n\nWhisk tries to solve this by making dependencies explicit. Build steps depend on the output of other build steps instead \nof a generic execution of another task. This immediately makes clear if build steps could be removed, or why they are\nthere.\n\nThe build language to describe a build is a simple functional language based on goals and rules.\n\nGoals are parameter-less targets a build can produce. They define the rules to execute. They can be called by\nthe CLI or by rules.\n\nRules are parametrized descriptions on what step to perform. They can not be called from the CLI. They can be called\nby other rules or goals. Think of rules as a means to the end of executing a goal.\n\nWhen executing a rule (invoked by some goal), all rules it depends on will be executed - in parallel:\n![Goal and rule dependencies](dependencies.png) \n\nThe only \"primitive\" currently supported are `strings`. Besides that, rules can take various other resources as inputs.\nThey can also generate all kinds of resources.\n![Rule anatomy](rules.png)\n\n\n## Status\nCurrent CI uses gradle to build `whisk`. The resulting application is then used to build itself: \n\n![Build Status](https://api.travis-ci.org/Bytekeeper/whisk.svg?branch=master)\n\n## Examples\nThe `examples` folder has some simple examples for builds.\n\n## Why\nBesides being an interesting topic:\n* Maven\n    * Powerful and extendable\n    * Verbose \n    * Not all builds neatly fit into the lifecycle phases\n    * Calling a plugin multiple times in build can be difficult\n    * Parallel builds depend on plugin supporting it\n    * Incremental builds are \"kind of\" supported\n* Gradle\n    * Powerful and extendable and scriptable\n    * Lean build configs\n    * Breaks compatibility often\n    * Very fast\n    * Strange syntax sometimes\n    * Sometimes cryptic build files due to abusing groovy/kotlin\n    * Task based dependencies, but less knowledge about \"who built what exactly?\"\n    * Dependencies are not inferred, the dev has to actively \"know\" which task depend on one another\n* Bazel\n    * Powerful and extendable and scriptable\n    * Reduced python better than full programming language\n    * Strange folder linking\n    * Windows port \"works\"\n    * Good dependency graph\n    * Using maven dependencies required extra plugins\n* Buck\n    * See Bazel\n    * Can't use maven dependencies\n    \n\n## Design Goals\n* Based on dependencies and not tasks \n* Reproducible builds\n* A DSL build language as simple as possible\n* Control over build process\n    * No magic build steps\n    * Magic build steps if necessary\n    * Powerful like ant/make\n    * But with flexible order of execution\n    * Execution order like maven\n    * But not with \"fixed\" phases or static modules\n    * Execution order like gradle\n    * But not by declaring task dependencies \"indirectly\"\n\n# Guide\n\n## Build Lang\n```text\n# Load exposed goals/functions from the package whisk and core.test\nimport whisk,core.test\n\n# Expose doit and bla for other BL scripts\nexport doit, glob\n\n# Define blub as external rule/goal/function. It can only be used as 'name = blub(...)'. \nblub(a,b:[],c?)\n\n# Using the 'anon' keyword, define glob as callable without name, it can also be used as 'x(glob(y))'\nanon glob([])  \n\n# Define bla as helper function\nbla(a,b) = blub(a = a, b = [b]) \n\n# Declare doit as callable goal, ie. \"whisk doit\" \ndoit = bla('test', [])\n```\n\n## Rules\n\n### Anon Rules\nBy default, rules cannot be called from within other rules. This prevents complexity in build scripts and also allows \neasier management of generated file by Whisk. \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbytekeeper%2Fwhisk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbytekeeper%2Fwhisk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbytekeeper%2Fwhisk/lists"}