Dartle Documentation
The Dartle Cache
For a build system to work intelligently, it needs to know what exactly it’s building. This is so that the system can sort the tasks that it needs to execute in the correct order, and avoid work that has already been done on subsequent runs.
This is what the Dartle Cache allows Dartle to achieve. The cache is implemented as a library within the Dartle project, so it’s possible to use it as a stand-alone Dart library!
For an example of using the DartleCache
, check the example DartleCache CLI
code, which can be used to keep track of changes on a certain directory.
DartleCache API
This section shows the most important parts of the API.
The full API can be found in pub.dev.
Caching file collections
The DartleCache
can be used as a function to cache FileCollections:
import 'package:dartle/dartle_cache.dart';
final cache = DartleCache('.cache-directory');
// cache everything in the `source` dir:
main() async {
await cache(dir('source'));
}
The next examples will omit the imports and
cache
declarations for brevity.
A second argument, key
may be provided to scope changes. This is used in Dartle to make
sure that files changes between invocations of different tasks can be recognized. For example,
two tasks may have the same inputs, but that doesn’t mean that just because one task ran, the
other doesn’t need to also run later, despite the fact that the previous task had cached the files.
// cache everything in the `source` dir, but only for a key `my-key`:
main() async {
await cache(dir('source'), key: 'my-key');
}
To cache only files with a certain extension:
// cache *.txt in the `source` dir:
main() async {
await cache(dir('source', fileExtensions: const {'.txt'}));
}
Checking for changes
The simplest way to check for changes is by calling hasChanged
,
which takes the same arguments as the cache function:
main() async {
bool changed = await cache.hasChanged(dir('source'));
print(changed);
}
To find out exactly what has changed, use findChanges
instead:
main() async {
final changes = await cache.findChanges(dir('source'));
await for (final change in changes) {
print('${change.entity.path} - ${change.kind}');
}
}
This is used by Dartle to implement incremental builds.
Task invocation support
DartleCache
also supports caching task invocations. For example:
main(List<String> args) async {
await cache.cacheTaskInvocation('myTask', args);
}
To check if the invocation is the same as last time (i.e. whether the arguments are the same as last time):
main(List<String> args) async {
bool changed =await cache.hasTaskInvocationChanged('myTask', args);
print(changed);
}
It’s also possible to check at what time the latest invocation of a task happened:
main() async {
DateTime? dateTime = await cache.getLatestInvocationTime('myTask');
print(dateTime);
}
Cleaning up
To completely cleanup the cache, call clean
without any arguments:
main() async {
await cache.clean();
}
To only cleanup cached artifacts for a particular key, pass the key as an argument:
main() async {
await cache.clean('key');
}
It’s also possible to remove only a provided FileCollection
or task invocation.
main() async {
await cache.remove(dir('source'), key: 'key');
await cache.removeTaskInvocation('myTask');
}