Skip to content

Commit

Permalink
feat: optional path build.yaml option (#83)
Browse files Browse the repository at this point in the history
* Update to have optional path

* 🔀 resolve merge conflicts

* ♻️ refactor code

* ♻️ refactor code

* ✅ add path override tests

* ✅ add path override tests

* 📝 update readme

---------

Co-authored-by: Marcel Ploch <[email protected]>
  • Loading branch information
techouse and Marcel Ploch authored Jan 3, 2024
1 parent 79c2043 commit 31d4655
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 10 deletions.
16 changes: 16 additions & 0 deletions packages/envied/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,22 @@ static const String apiKey; // Searches for a variable named 'DEBUG_API_KEY' ins

These example illustrates how the field name `apiKey` is automatically transformed to `API_KEY`, adhering to the `CONSTANT_CASE` convention commonly used as the variable name inside the `.env` file. This feature contributes to improved code consistency and readability, while also aligning with [Effective Dart](https://dart.dev/effective-dart) naming conventions.

### **Build configuration overrides**

You can override the default `.env` file path by creating a `build.yaml` file in the root of your project.

```yaml
targets:
$default:
builders:
envied_generator|envied:
options:
path: .env.custom
override: true
```
Note that **both** `path` and `override` must be set for the override to work.

### Known issues

When modifying the `.env` file, the generator might not pick up the change due to [dart-lang/build#967](https://github.com/dart-lang/build/issues/967).
Expand Down
11 changes: 9 additions & 2 deletions packages/envied_generator/lib/builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,15 @@ library envied.builder;

import 'package:build/build.dart';
import 'package:envied_generator/envied_generator.dart';
import 'package:envied_generator/src/build_options.dart';
import 'package:source_gen/source_gen.dart';

/// Primary builder to build the generated code from the `EnviedGenerator`
Builder enviedBuilder(BuilderOptions options) =>
SharedPartBuilder([const EnviedGenerator()], 'envied');
Builder enviedBuilder(BuilderOptions options) => SharedPartBuilder(
[
EnviedGenerator(
BuildOptions.fromMap(options.config),
)
],
'envied',
);
27 changes: 27 additions & 0 deletions packages/envied_generator/lib/src/build_options.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/// Represents the options passed to the build runner via build.yaml.
///
/// For example
///
/// ```yaml
/// targets:
/// $default:
/// builders:
/// envied_generator|envied:
/// options:
/// path: .env.test
/// override: true
/// ```
class BuildOptions {
const BuildOptions({
this.override,
this.path,
});

final String? path;
final bool? override;

factory BuildOptions.fromMap(Map<String, dynamic> map) => BuildOptions(
override: map['override'] as bool?,
path: map['path'] as String?,
);
}
10 changes: 8 additions & 2 deletions packages/envied_generator/lib/src/generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import 'package:build/build.dart';
import 'package:code_builder/code_builder.dart';
import 'package:dart_style/dart_style.dart';
import 'package:envied/envied.dart';
import 'package:envied_generator/src/build_options.dart';
import 'package:envied_generator/src/generate_field.dart';
import 'package:envied_generator/src/generate_field_encrypted.dart';
import 'package:envied_generator/src/load_envs.dart';
Expand All @@ -19,7 +20,9 @@ import 'package:source_gen/source_gen.dart';
/// Will throw an [InvalidGenerationSourceError] if the annotated
/// element is not a [classElement].
final class EnviedGenerator extends GeneratorForAnnotation<Envied> {
const EnviedGenerator();
const EnviedGenerator(this._buildOptions);

final BuildOptions _buildOptions;

@override
Future<String> generateForAnnotatedElement(
Expand All @@ -36,7 +39,10 @@ final class EnviedGenerator extends GeneratorForAnnotation<Envied> {
}

final Envied config = Envied(
path: annotation.read('path').literalValue as String?,
path: _buildOptions.override == true &&
_buildOptions.path?.isNotEmpty == true
? _buildOptions.path
: annotation.read('path').literalValue as String?,
requireEnvFile:
annotation.read('requireEnvFile').literalValue as bool? ?? false,
name: annotation.read('name').literalValue as String?,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
foo=bar
baz=qux
27 changes: 21 additions & 6 deletions packages/envied_generator/test/envy_generator_test.dart
Original file line number Diff line number Diff line change
@@ -1,18 +1,33 @@
import 'package:envied_generator/envied_generator.dart';
import 'package:envied_generator/src/build_options.dart';
import 'package:source_gen_test/source_gen_test.dart';

Future<void> main() async {
// for annotated elements
initializeBuildLogTracking();
final reader = await initializeLibraryReaderForDirectory(
'test/src',
'generator_tests.dart',
);

// print(Platform.environment['SYSTEM_VAR']);

testAnnotatedElements(
reader,
EnviedGenerator(),
await initializeLibraryReaderForDirectory(
'test/src',
'generator_tests.dart',
),
EnviedGenerator(
const BuildOptions(),
),
);

testAnnotatedElements(
await initializeLibraryReaderForDirectory(
'test/src',
'generator_tests_with_path_override.dart',
),
EnviedGenerator(
const BuildOptions(
path: 'test/.env.example_with_path_override',
override: true,
),
),
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// ignore_for_file: unnecessary_nullable_for_final_variable_declarations

import 'package:envied/envied.dart';
import 'package:source_gen_test/annotations.dart';

@ShouldGenerate('''
// coverage:ignore-file
// ignore_for_file: type=lint
final class _EnvWithPathOverride0 {}
''')
@Envied()
abstract class EnvWithPathOverride0 {}

@ShouldGenerate('''
// coverage:ignore-file
// ignore_for_file: type=lint
final class _EnvWithPathOverride1 {}
''')
@Envied(requireEnvFile: true)
abstract class EnvWithPathOverride1 {}

@ShouldGenerate('''
// coverage:ignore-file
// ignore_for_file: type=lint
final class _EnvWithPathOverride2 {
static const String foo = 'bar';
static const String baz = 'qux';
}
''')
@Envied()
abstract class EnvWithPathOverride2 {
@EnviedField()
static const String? foo = null;
@EnviedField()
static const String? baz = null;
}

0 comments on commit 31d4655

Please sign in to comment.