Skip to content

Commit b1416d2

Browse files
committed
feat: Support custom cache location
1 parent febe972 commit b1416d2

10 files changed

Lines changed: 136 additions & 34 deletions

File tree

CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
## 4.1.0
2+
3+
### Features
4+
5+
#### Cache location
6+
7+
You're now able to set a custom cache location by setting `catalyst_builder: { cacheDir: 'a/cache/path' }` property in the pubspec.yaml
8+
9+
Take a look in [pubspec.yaml](example/pubspec.yaml) for an example.
10+
11+
### Internal
12+
13+
- The `CacheHelper` is no longer static.
14+
115
## 4.0.0
216

317
This major update has breaking changes.
@@ -28,6 +42,7 @@ Bump the minimum Dart SDK version to 3.5.0
2842
- `analyzer`: `'>=5.2.0 <7.0.0'` => `'>=5.2.0 <8.0.0'`
2943

3044
#### Annotations
45+
3146
Removed the deprecated `@Parameter` annotation. Use `@Inject` instead.
3247

3348
#### Build customization

README.md

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,24 @@ dev_dependencies:
3535
3636
Don't forget to exclude the `.catalyst_builder_cache` directory from VCS.
3737

38+
## Config reference
39+
40+
Some parts of the builder can be configured by adding a `catalyst_builder` section to the `pubspec.yaml`
41+
42+
```yaml
43+
# pubspec.yaml
44+
name: your_package
45+
# dependencies:
46+
# catalyst_builder:
47+
# ...
48+
catalyst_builder:
49+
cacheDir: '.cache/catalyst_builder'
50+
```
51+
52+
| Property | Type | Description | Default |
53+
|------------|---------|------------------------------------------------------|-------------------------|
54+
| `cacheDir` | String? | The path to the cache directory for preflight files. | .catalyst_builder_cache |
55+
3856
## Usage
3957

4058
Decorate your services with `@Service`:
@@ -45,6 +63,7 @@ class MyService {}
4563
```
4664

4765
Decorate in your entry point file any top level symbol with `@GenerateServiceProvider`:
66+
4867
```dart
4968
// my_entrypoint.dart
5069
@@ -72,7 +91,7 @@ import 'my_entrypoint.catalyst_builder.g.dart';
7291
void main() {
7392
// Create a new instance of the service provider
7493
var provider = DefaultServiceProvider();
75-
94+
7695
// Boot it to wire services
7796
provider.boot();
7897
@@ -102,10 +121,10 @@ class SingletonService {}
102121
class TransientService {}
103122
```
104123

105-
| Lifetime | Description |
106-
| --------- | ----------- |
124+
| Lifetime | Description |
125+
|-----------|----------------------------------------------------------------------------------|
107126
| Singleton | The instance is stored in the provider. You'll always receive the same instance. |
108-
| Transient | Everytime you call `resolve` or `tryResolve` you'll receive a fresh instance. |
127+
| Transient | Everytime you call `resolve` or `tryResolve` you'll receive a fresh instance. |
109128

110129
### Exposing
111130

@@ -241,6 +260,7 @@ void main() {}
241260
## Registering services at runtime (v2.1.0+)
242261

243262
Sometimes you need to register services at runtime. For this, you can use the `register` method:
263+
244264
```dart
245265
void main() {
246266
var provider = ExampleProvider();
@@ -255,10 +275,11 @@ void main() {
255275
```
256276

257277
## Create a sub-provider with additional services / parameters (v2.2.0+)
278+
258279
In some cases, you want to register services or parameters only for a specific service.
259-
The services or parameters should not be placed inside the global service provider.
260-
To solve this problem, you can use the `enhance` method, which accepts an array of additional services and
261-
a map of additional parameters. These are only available in the returned ServiceProvider.
280+
The services or parameters should not be placed inside the global service provider.
281+
To solve this problem, you can use the `enhance` method, which accepts an array of additional services and
282+
a map of additional parameters. These are only available in the returned ServiceProvider.
262283

263284
```dart
264285
void main() {
@@ -271,7 +292,7 @@ void main() {
271292
services: [
272293
// Important: Specify the type explicitly or cast the outer array to dynamic. Otherwise dart can not infer the
273294
// correct return type!
274-
LazyServiceDescriptor<MySelfRegisteredService>(
295+
LazyServiceDescriptor<MySelfRegisteredService>(
275296
(p) => MySelfRegisteredService(p.resolve(), p.parameters['foo']),
276297
const Service(exposeAs: SelfRegisteredService),
277298
),
@@ -284,8 +305,10 @@ void main() {
284305
```
285306

286307
## Tagged services (v2.3.0+)
308+
287309
You can tag services using the `tags` property on the `Service` annotation. This is useful if you need to group services
288310
and load all services with a certain tag at once.
311+
289312
```dart
290313
@Service(tags: [#groupTag, #anotherTag])
291314
class MyService1 {}
@@ -315,6 +338,7 @@ void main() {
315338
## Inject tagged services (v3.2.0+)
316339

317340
The `@Inject` annotation allows you to inject a list of services tagged with a certain tag.
341+
318342
```dart
319343
abstract class MyServiceBase {}
320344
@@ -326,10 +350,8 @@ class MyService2 extends MyServiceBase {}
326350
327351
@Service()
328352
class ServiceWithDeps {
329-
330-
ServiceWithDeps(
331-
@Inject(tag: #groupTag) List<MyServiceBase> services,
332-
) {
353+
354+
ServiceWithDeps(@Inject(tag: #groupTag) List<MyServiceBase> services,) {
333355
// services includes MyService1 and MyService2
334356
}
335357
}
@@ -339,10 +361,12 @@ class ServiceWithDeps {
339361
## Include services from dependencies
340362

341363
By default, the builder includes only services from the root package.
342-
If you've dependencies that provides decorated services (`@Service`) you need to set `includePackageDependencies` to true.
364+
If you've dependencies that provides decorated services (`@Service`) you need to set `includePackageDependencies` to
365+
true.
366+
343367
```dart
344368
@GenerateServiceProvider(
345369
providerClassName: 'ExampleProvider',
346-
includePackageDependencies: true, // Set this to true
370+
includePackageDependencies: true, // Set this to true
347371
)
348372
```

example/.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@
66
build/
77
*.g.dart
88

9-
.catalyst_builder_cache/
9+
.cache/

example/pubspec.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,6 @@ dependencies:
1616
dev_dependencies:
1717
lints: ^5.1.1
1818
build_runner: ^2.0.1
19+
20+
catalyst_builder:
21+
cacheDir: '.cache/catalyst_builder'

lib/src/builder/dto/config.dart

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import 'dart:convert';
2+
import 'dart:io';
3+
4+
import 'package:path/path.dart' as p;
5+
import 'package:yaml/yaml.dart';
6+
7+
import '../constants.dart' as c;
8+
9+
/// Represents the config file for advanced configuration
10+
class Config {
11+
/// The directory for the builder cache.
12+
/// This could be an relative or absolute path.
13+
String cacheDir;
14+
15+
/// Creates the config object
16+
Config({
17+
this.cacheDir = c.cacheDir,
18+
});
19+
20+
/// Load the configuration from [configFileName] or fallback to the default.
21+
factory Config.load() {
22+
var configFile = File(p.join(p.current, 'pubspec.yaml'));
23+
24+
if (configFile.existsSync()) {
25+
var content = loadYaml(configFile.readAsStringSync()) as YamlMap;
26+
if (content.containsKey('catalyst_builder')) {
27+
var yamlJson = jsonEncode(content['catalyst_builder']);
28+
var configFromYaml = jsonDecode(yamlJson) as Map;
29+
return Config.fromJson(configFromYaml.cast());
30+
}
31+
}
32+
33+
return Config();
34+
}
35+
36+
/// Creates a new instance from the result of [toJson].
37+
factory Config.fromJson(Map<String, dynamic> json) {
38+
return Config(
39+
cacheDir: json['cacheDir']?.toString() ?? c.cacheDir,
40+
);
41+
}
42+
}

lib/src/builder/dto/dto.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
export 'config.dart';
12
export 'constructor_arg.dart';
23
export 'extracted_service.dart';
34
export 'inject_annotation.dart';

lib/src/builder/preflight_builder.dart

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ import 'helpers.dart';
1616
/// The PreflightBuilder scans the files for @Service annotations.
1717
/// The result is stored in preflight.json files.
1818
class PreflightBuilder implements Builder {
19+
final CacheHelper _cacheHelper = CacheHelper();
20+
1921
@override
2022
final Map<String, List<String>> buildExtensions = {
2123
r'$lib$': [],
@@ -34,11 +36,11 @@ class PreflightBuilder implements Builder {
3436

3537
final cachedPath = _getFilename(buildStep);
3638
if (extractedAnnotations.services.isEmpty) {
37-
await CacheHelper.deleteFileFromCache(cachedPath);
39+
await _cacheHelper.deleteFileFromCache(cachedPath);
3840
return;
3941
}
4042

41-
await CacheHelper.writeFileToCache(
43+
await _cacheHelper.writeFileToCache(
4244
cachedPath,
4345
jsonEncode(extractedAnnotations),
4446
);

lib/src/builder/service_provider_builder.dart

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ import 'generator/service_provider/service_provider.dart';
1414
/// The ServiceProviderBuilder creates a service provider from the resulting
1515
/// preflight .json files.
1616
class ServiceProviderBuilder implements Builder {
17+
final CacheHelper _cacheHelper = CacheHelper();
18+
1719
@override
1820
FutureOr<void> build(BuildStep buildStep) async {
1921
if (!buildStep.inputId.path.endsWith(entrypointExtension)) {
@@ -40,8 +42,8 @@ class ServiceProviderBuilder implements Builder {
4042
final services = <ExtractedService>[];
4143

4244
final source = entrypoint.includePackageDependencies
43-
? CacheHelper.preflightFiles
44-
: CacheHelper.getPreflightFilesForPackage(
45+
? _cacheHelper.preflightFiles
46+
: _cacheHelper.getPreflightFilesForPackage(
4547
entrypoint.assetId.pathSegments.first,
4648
);
4749

lib/src/cache_helper.dart

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,47 +5,52 @@ import 'package:glob/list_local_fs.dart';
55
import 'package:path/path.dart' as p;
66

77
import './builder/constants.dart';
8+
import './builder/dto/dto.dart';
89

9-
abstract final class CacheHelper {
10-
static final _filePattern = '**/*$preflightExtension';
10+
final class CacheHelper {
11+
static const _filePattern = '**/*$preflightExtension';
1112
static final _preflightFiles = Glob(_filePattern, recursive: true);
1213

1314
/// Returns the path to the cache directory
14-
static final String _cachePath = p.join(
15-
p.current,
16-
cacheDir,
17-
);
15+
late final String _cachePath;
1816

19-
static final Directory _cacheDir = Directory(_cachePath);
17+
late final Directory _cacheDir = Directory(_cachePath);
2018

21-
static Stream<FileSystemEntity> get preflightFiles =>
19+
CacheHelper() {
20+
var config = Config.load();
21+
_cachePath = p.isAbsolute(config.cacheDir)
22+
? config.cacheDir
23+
: p.join(p.current, config.cacheDir);
24+
}
25+
26+
Stream<FileSystemEntity> get preflightFiles =>
2227
_preflightFiles.list(root: _cachePath);
2328

24-
static Stream<FileSystemEntity> getPreflightFilesForPackage(String package) {
29+
Stream<FileSystemEntity> getPreflightFilesForPackage(String package) {
2530
return Glob('$package/$_filePattern', recursive: true)
2631
.list(root: _cachePath);
2732
}
2833

29-
static Future<void> cleanCacheDir() async {
34+
Future<void> cleanCacheDir() async {
3035
if (await _cacheDir.exists()) {
3136
await _cacheDir.delete(recursive: true);
3237
}
3338
}
3439

35-
static Future<void> createCacheDirectory() async {
40+
Future<void> createCacheDirectory() async {
3641
if (!(await _cacheDir.exists())) {
3742
await _cacheDir.create(recursive: true);
3843
}
3944
}
4045

41-
static Future<void> deleteFileFromCache(String filename) async {
46+
Future<void> deleteFileFromCache(String filename) async {
4247
var f = _getCacheFile(filename);
4348
if (await f.exists()) {
4449
await f.delete(recursive: true);
4550
}
4651
}
4752

48-
static Future<void> writeFileToCache(
53+
Future<void> writeFileToCache(
4954
String filename,
5055
String contents,
5156
) async {
@@ -56,7 +61,7 @@ abstract final class CacheHelper {
5661
await f.writeAsString(contents, mode: FileMode.writeOnly);
5762
}
5863

59-
static File _getCacheFile(String filename) {
64+
File _getCacheFile(String filename) {
6065
var cachedName = p.join(_cachePath, filename);
6166
var f = File(cachedName);
6267
return f;

pubspec.yaml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
11
name: catalyst_builder
22
description: A lightweight and easy to use dependency injection provider builder for dart.
3-
version: 4.0.0
3+
version: 4.1.0
44
homepage: 'https://github.com/mintware-de/catalyst_builder'
55
repository: 'https://github.com/mintware-de/catalyst_builder'
66

7+
topics:
8+
- code-generation
9+
- builder
10+
- dependency-injection
11+
- annotations
12+
- service-provider
13+
714
environment:
815
sdk: ">=3.5.0 <4.0.0"
916

@@ -14,6 +21,7 @@ dependencies:
1421
glob: ^2.1.0
1522
path: ^1.8.0
1623
analyzer: '>=6.2.0 <8.0.0'
24+
yaml: ^3.0.0
1725

1826
dev_dependencies:
1927
test: any

0 commit comments

Comments
 (0)