{"id":18011645,"url":"https://github.com/renatoathaydes/dartle","last_synced_at":"2025-08-31T08:40:53.666Z","repository":{"id":48413512,"uuid":"206880692","full_name":"renatoathaydes/dartle","owner":"renatoathaydes","description":"A simple build system written in Dart.","archived":false,"fork":false,"pushed_at":"2025-06-06T13:41:17.000Z","size":626,"stargazers_count":14,"open_issues_count":0,"forks_count":0,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-06-06T14:33:46.646Z","etag":null,"topics":["automation","build-tool","dart"],"latest_commit_sha":null,"homepage":null,"language":"Dart","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/renatoathaydes.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","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-09-06T22:05:09.000Z","updated_at":"2025-06-06T13:40:27.000Z","dependencies_parsed_at":"2024-07-25T22:16:41.094Z","dependency_job_id":"832ef315-855b-41dd-b5c0-7fe26f6ec57a","html_url":"https://github.com/renatoathaydes/dartle","commit_stats":null,"previous_names":[],"tags_count":36,"template":false,"template_full_name":null,"purl":"pkg:github/renatoathaydes/dartle","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/renatoathaydes%2Fdartle","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/renatoathaydes%2Fdartle/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/renatoathaydes%2Fdartle/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/renatoathaydes%2Fdartle/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/renatoathaydes","download_url":"https://codeload.github.com/renatoathaydes/dartle/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/renatoathaydes%2Fdartle/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272959406,"owners_count":25022056,"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","status":"online","status_checked_at":"2025-08-31T02:00:09.071Z","response_time":79,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["automation","build-tool","dart"],"created_at":"2024-10-30T03:12:17.229Z","updated_at":"2025-08-31T08:40:53.636Z","avatar_url":"https://github.com/renatoathaydes.png","language":"Dart","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Dartle\n\n![Dartle CI](https://github.com/renatoathaydes/dartle/workflows/Dartle%20CI/badge.svg)\n[![pub package](https://img.shields.io/pub/v/dartle.svg)](https://pub.dev/packages/dartle)\n\nA simple _task runner_/_build system_/_build library_ written in Dart.\n\n[📚 Dartle Documentation](https://renatoathaydes.github.io/dartle-website/)\n\n## Purpose\n\nThe goal with Dartle is to define a (sometimes large) number of tasks where only a few of them\nare explicitly invoked by a human. This is accomplished by defining task phases and\ndeclaring interdependencies between tasks.\n\nDartle makes sure that every task that _needs to run_, but no others, actually run when you ask it to run\none or more tasks.\n\nTasks on the same phase run in parallel, on their own [_isolates_](https://dart.dev/guides/language/concurrency#how-isolates-work),\nand if a task fails, all running tasks are immediately cancelled.\n\n## What can I do with Dartle?\n\n* use it as a Dart-based task runner or build system (write tasks in Dart).\n* build Dart projects using `DartleDart` support.\n* use it as a file system _diff_ tool. Know when things have changed since last _cached_.\n* create your own build system using Dartle as a library! See [`jb`](https://github.com/renatoathaydes/jb), for example.\n\n## Using Dartle\n\nFor example, Dartle's own build (which uses Dartle's own support for Dart) has the following tasks\n(as shown by running `dartle --show-tasks`):\n \n```\n======== Showing build information only, no tasks will be executed ========\n\nTasks declared in this build:\n\n==\u003e Setup Phase:\n  * clean\n      Deletes the outputs of all other tasks in this build.\n  * cleanWorkingDirs [up-to-date]\n      Cleanup working dir before builds. Avoids caching generated files.\n==\u003e Build Phase:\n  * analyzeCode [up-to-date]\n      Analyzes Dart source code\n  * build [default] [always-runs]\n      Runs all enabled tasks.\n  * checkImports [up-to-date]\n      Checks dart file imports are allowed\n  * compileExe\n      Compiles Dart executables declared in pubspec. Argument may specify the name(s) of the executable(s) to compile.\n  * format [up-to-date]\n      Formats all Dart source code.\n  * generateDartSources [up-to-date]\n      Generates Dart source files\n  * runBuildRunner [up-to-date]\n      Runs the Dart build_runner tool.\n  * runPubGet [up-to-date]\n      Runs \"pub get\" in order to update dependencies.\n  * test [out-of-date]\n      Runs Dart tests.\n==\u003e TearDown Phase:\n  No tasks in this phase.\n\nThe following tasks were selected to run, in order:\n\n  cleanWorkingDirs\n      runPubGet\n      generateDartSources\n          runBuildRunner\n              checkImports\n              format\n                  analyzeCode\n                      test\n                          build\n```\n\n\u003e Note: Tasks on the same _column_ may run in parallel.\n\nWhen you invoke, say, `dartle analyzeCode`, Dartle will make sure that the\n`analyseCode` task will run, but also that all its dependencies, `generateDartSources`,\n`format`, `checkImports` and `runPubGet` will run first as long as their `runCondition`\nrequires them to run. If any of these tasks doesn't need to run, it is automatically\nskipped.\n\nDartle has several `RunCondition`s to determine when a task is up-to-date or needs to run:\n\n- `RunOnChanges` - run task if any inputs/outputs changed since last run.\n- `RunAtMostEvery` - run task at most every T, where T is a period of time.\n- `RunToDelete` - run task if any of its outputs _exists_.\n\nThere are also combiners like `AndCondition` and `OrCondition` (and you can define your own conditions).\n\nFor example, the `runPubGet` task runs if `pubspec.yaml` changes OR if it has not been run for\none week.\n\n## How to use\n\n#### Add `dartle` to your `dev_dependencies`:\n\n```bash\ndart pub add -d dartle\n```\n\n#### Write a dartle build file\n\n\u003e A basic `dartle.dart` file can be automatically generated by invoking `dartle`\n\u003e on a directory where `dartle.dart` does not exist yet.\n\n_dartle.dart_\n\n```dart\nimport 'package:dartle/dartle.dart';\n\nfinal helloTask = Task(hello, argsValidator: const ArgsCount.range(min: 0, max: 1));\nfinal byeTask = Task(bye, dependsOn: const {'hello'});\nfinal cleanTask = createCleanTask(tasks: {helloTask, byeTask});\n\nmain(List\u003cString\u003e args) async =\u003e\n    run(args, tasks: {helloTask, byeTask, cleanTask}, defaultTasks: {helloTask});\n\n/// To pass an argument to a task, use a ':' prefix, e.g.:\n/// dartle hello :joe\nhello(List\u003cString\u003e args) =\u003e\n    print(\"Hello ${args.isEmpty ? 'World' : args[0]}!\");\n\n/// If no arguments are expected, use `_` as the function parameter.\nbye(_) =\u003e print(\"Bye!\");\n```\n\nNotice that the `dartle.dart` script should be very simple (a basic invocation to Dartle's `run`, ideally), so it's clear at a\nglance what the tasks are.\n\nPut any logic you may need to write for tasks (and even the task declarations) in source file inside the\n`dartle-src` directory, as that's where Dartle looks for changes to the build (besides `dartle.dart` and `pubspec.*`).\n\n\u003e Check [Dartle's own dartle.dart](https://github.com/renatoathaydes/dartle/blob/master/dartle.dart) file for a good example.\n\n#### Run your build!\n\nIn **dev mode** (while you're setting up your build), use `dart` to run the build file directly:\n\n```bash\ndart dartle.dart \u003ctasks\u003e\n```\n\n\u003e Notice that all `dev_dependencies` can be used in your build! And all Dart tools work with it, \n\u003e including the Observatory and debugger, after all this is just plain Dart!\n\nOnce you're done with the basics of your build, it is recommended to install Dartle for faster\nperformance.\n\nTo install Dartle:\n\n```bash\ndart pub global activate dartle\n```\n\nNow, you can run your build with the `dartle` command:\n\n```bash\ndartle \u003ctasks\u003e\n```\n\n\u003e `dartle` automatically re-compiles the `dartle.dart` script into an executable if necessary\n\u003e to make builds run so fast they feel instant!\n\n### Selecting tasks\n\nIf no task is explicitly invoked, Dartle runs the `defaultTasks` defined in the build, or does nothing if none was defined.\n\nTo run specific task(s), give them as arguments when invoking `dartle`:\n\n```bash\ndartle hello bye\n```\n\nOutput:\n\n```\n2020-02-06 20:53:26.917795 - dartle[main] - INFO - Executing 2 tasks out of a total of 4 tasks: 2 tasks selected, 0 due to dependencies\n2020-02-06 20:53:26.918155 - dartle[main] - INFO - Running task 'hello'\nHello World!\n2020-02-06 20:53:26.918440 - dartle[main] - INFO - Running task 'bye'\nBye!\n✔ Build succeeded in 3 ms\n```\n\n\u003e Notice that Dartle will cache resources to make builds run faster.\n\u003e It uses the `.dartle_tool/` directory, in the working directory, to manage the cache.\n\u003e **You should not commit the `.dartle_tool/` directory into source control**.\n\nTo provide arguments to a task, provide the argument immediately following the task invocation, prefixing it with `:`:\n\n```bash\n./dartle hello :Joe\n```\n\nPrints:\n\n```\n2020-02-06 20:55:00.502056 - dartle[main] - INFO - Executing 1 task out of a total of 4 tasks: 1 task selected, 0 due to dependencies\n2020-02-06 20:55:00.502270 - dartle[main] - INFO - Running task 'hello'\nHello Joe!\n✔ Build succeeded in 1 ms\n```\n\n### Declaring tasks\n\nThe preferred way to declare a task is by wrapping a top-level function, as shown in the example above.\n\nBasically:\n\n```dart\nimport 'package:dartle/dartle.dart';\n\nfinal allTasks = {Task(hello)};\n\nmain(List\u003cString\u003e args) async =\u003e run(args, tasks: allTasks);\n\nhello(_) =\u003e print(\"Hello Dartle!\");\n```\n\nThis allows the task to run in parallel with other tasks on different `Isolate`s (potentially on different CPU cores).\n\n\u003e Notice that because the task may run on an `Isolate`, it must not depend on any global state. The function will not _see_ changes made from the main `Isolate` or any other.\n\nIf that's not important, a lambda can be used, but in such case the task's name must be provided explicitly (because\nlambdas have no name):\n\n```dart\nimport 'package:dartle/dartle.dart';\n\nfinal allTasks = {Task((_) =\u003e print(\"Hello Dartle!\"), name: 'hello')};\n\nmain(List\u003cString\u003e args) async =\u003e run(args, tasks: allTasks);\n```\n\nA Task's function should only take arguments if it declares an `ArgsValidator`, as shown in the example:\n\n```dart\nTask(hello, argsValidator: const ArgsCount.range(min: 0, max: 1))\n\n...\n\nhello(List\u003cString\u003e args) =\u003e ...\n```\n\nA Task will not be executed if its `argsValidator` is not satisfied (Dartle will fail the build if that happens).\n\n### Incremental Tasks\n\nFor a Dartle task to become incremental, it only needs to have an action function that accepts an optional argument containing the `ChangeSet` since the last build.\n\nFor example, the `hello` function from the previous example would need to be declared as shown below to become an incremental task:\n\n```dart\nhello(List\u003cString\u003e args, [ChangeSet? changeSet]) async {\n    // TODO inspect changes to know what needs to be done\n}\n```\n\nImportantly, the `ChangeSet` must be an optional argument, otherwise the function won't match the signature expected by Dartle.\n\n### Task dependencies and run conditions\n\nA Task can depend on other task(s), so that whenever it runs, its dependencies also run\n(as long as they are not up-to-date).\n\nIn the example above, the `bye` task depends on the `hello` task:\n\n```dart\nTask(bye, dependsOn: const {'hello'})\n```\n\nThis means that whenever `bye` runs, `hello` runs first.\n\n\u003e Notice that tasks that have no dependencies between themselves can run _at the same time_ -\n\u003e either on the same `Isolate` or in separate `Isolates` (use the `-p` flag to indicate that tasks may\n\u003e run in different `Isolate`s when possible, i.e. when their action is a top-level function and there's no dependencies\n\u003e with the other tasks).\n\nA task may be skipped if it's up-to-date according to its `RunCondition`. The example Dart file demonstrates that:\n\n```dart\nTask(encodeBase64,\n  description: 'Encodes input.txt in base64, writing to output.txt',\n  runCondition: RunOnChanges(\n    inputs: file('input.txt'),\n    outputs: file('output.txt'),\n  ))\n```\n\nThe above task only runs if at least one of these conditions is true:\n\n* `output.txt` does not yet exist.\n* either `input.txt` or `output.txt` changed since last time this task ran.\n* the `-f` or `--force-tasks` flag is used.\n\nIf a `RunCondition` is not provided, the task is always considered out-of-date.\n\n\u003e To force all tasks to run, use the `-z` or `--reset-cache` flag.\n\n### Help\n\nFor more help, run `dartle -h`. Proper documentation is going to be available soon! \n\n## Prior Art\n\nDartle is inspired by [Gradle](https://gradle.org/) and, loosely,\n[Make](https://www.gnu.org/software/make/) and [Apache Ant](https://ant.apache.org/).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frenatoathaydes%2Fdartle","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frenatoathaydes%2Fdartle","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frenatoathaydes%2Fdartle/lists"}