Skip to content

Commit 93a6db4

Browse files
authored
Merge pull request #11 from TatsuUkraine/release-2.2.0
Release 2.2.0 -> master
2 parents af5f667 + 4a0a453 commit 93a6db4

File tree

10 files changed

+385
-145
lines changed

10 files changed

+385
-145
lines changed

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
## [2.2.0] - 26.03.2020
2+
3+
Features:
4+
- added extension support
5+
- added dev extension support
6+
- added toggle for `static` modifier
7+
8+
Bug fixes:
9+
- changed rules for constructor generation
10+
111
## [2.1.0+1] - 09.03.2020
212

313
Minor changes in README.md

README.md

Lines changed: 157 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,24 @@ folder.
2424
So by default `.env` file will be generated alongside with
2525
`pubspec.yaml` and other root files.
2626

27+
## Table of contents
28+
29+
- [Getting Started](#getting-started)
30+
- [Configuration](#config)
31+
- [Command options](#command-options)
32+
- [Class configuration](#class-configuration)
33+
- [Class configuration examples](#config-examples)
34+
- [Field configuration](#field-configuration)
35+
- [Fields config examples](#fields-config-examples)
36+
- [Pattern example](#pattern-example)
37+
- [DotEnv example](#dotenv-example)
38+
- [Global environment variable example](#global-environment-variable-example)
39+
- [Extensions](#extensions)
40+
- [Basic Extension config usage](#basic-extension-config-usage)
41+
- [Development Extension example](#development-extension-example)
42+
- [Integration with CI/CD](#integration-with-cicd)
43+
- [Integration with other packages](#integration-with-other-packages)
44+
2745
## Getting Started
2846

2947
Install package as dependency.
@@ -37,6 +55,7 @@ environment_config:
3755
path: environment_config.dart # optional, result file path against `lib/` folder
3856
dotenv_path: .env # optional, result file path for .env file against project root folder
3957
class: EnvironmentConfig # optional, class name
58+
dev_extension: # optional, by default undefined, allows to specify command option to use extension
4059

4160
fields: # set of fields for command
4261
some_key: # key name
@@ -48,9 +67,22 @@ environment_config:
4867
dotenv: # optional, default to FALSE, if this field should be added to .env file
4968
config_field: # optional, default to TRUE, if this field should be added to Dart file
5069
env_var: # optional, global environment variable name
70+
static: # options, default to TRUE, if this field should be static, if FALSE, `const` will be be ignored
5171

5272
imports: # optional, array of imports, to include in config file
5373
- package:some_package
74+
75+
extensions: # set of extensions for default field list
76+
some_extension: # extension name
77+
some_key:
78+
const: # optional, overrides `const` value for the field
79+
pattern: # optional, overrides `pattern` value for the field
80+
default: # optional, overrides `default` value for the field
81+
env_var: # optional, overrides `env_var` value for the field
82+
83+
imports: # optional, adds set of imports to main configulration
84+
- package:some_other_package
85+
5486
```
5587
5688
Run `pub get` to install dependencies.
@@ -102,7 +134,10 @@ Also this package allows to generate `.env` file with same key value pairs
102134
During command run YAML file will be parsed to define keys for command.
103135
104136
- `config` - path to custom yaml file with package configuration
137+
- `config_extension` - name of the extension, that should be used for
138+
config generation
105139
- any key name, that specified in yaml file under `fields` key
140+
- `dev_extension` key name, allows to use this key as bool flag
106141
107142
For example. If you have next yaml config
108143
@@ -157,13 +192,14 @@ Class and file can be configured with next options
157192
defined as `const`.
158193
- `imports` - array of imports to add to generated config file
159194
- `fields`- set of fields, that should be defined in configuration files
195+
- `dev_extension` - defines which extension should be treated as dev
196+
extension, if specified - it's value can be used during command run as
197+
bool flag
198+
- `extensions` - set of configurations, that can extend default config
160199

161-
If `class` is not specified value for class name will be generate based on
162-
file name in `path` field. It will convert `snake_case` into `CamelCase`.
163-
164-
If `const` not provided builder will analyze each field and if all of them
165-
are `const` - it will add const constructor. Otherwise generated class
166-
will be without any constructor
200+
If `class` is not specified value for class name will be generate based
201+
on file name in `path` field. It will convert `snake_case` into
202+
`CamelCase`.
167203

168204
Field `dotenv_path` will be used only if at least one field contains `dotenv: true`
169205

@@ -222,9 +258,6 @@ class OtherClass {
222258
```
223259

224260
If `const` is used it will force class to have const constructor or without it.
225-
Without it, builder will analyze each field, and if **ALL** of them are
226-
`const`, builder will generate `const` constructor, otherwise - class will
227-
be generated without any constructor
228261

229262
## Field configuration
230263

@@ -236,11 +269,17 @@ should be specified
236269
**Note:** `config` key can't be used for field definition. It's reserved
237270
by command itself to define path to custom config yaml file
238271

272+
**Note** If `dev_extension` is defined, its value can't be used as field
273+
name
274+
239275
Each field accepts next params, each param is **optional**
240276
- `type` - field type, default to `String`
241277
- `const` - if field should be `const`, default to `TRUE`. If `FALSE`, `final` modifier will be used instead
242-
- `pattern` - pattern for field value. Inside value for this
243-
field `__VALUE__` can be used. It will be replaced with actual entered value or with default value
278+
- `static` - if field should be `static`, default to `TRUE`. If `FALSE`,
279+
`const` option will be ignored
280+
- `pattern` - pattern for field value. Inside value for this field
281+
`__VALUE__` can be used. It will be replaced with actual entered value
282+
or with default value
244283
- `default` - default value for the field. If not specified, field will be treated as required
245284
- `short_name` - short key name, that can be used during command run
246285
instead of full field name. Accepts 1 symbol values only
@@ -364,8 +403,115 @@ for your key.
364403
Generator will use next priority:
365404
- value from command arguments
366405
- value from environment variable `PATH`
406+
- value from [Extensions](#extensions) `default` key (if extension was
407+
used that has `default` key)
367408
- value from `default` key (if it was specified)
368409

410+
## Extensions
411+
412+
Extensions allows you to define set of override rules for fields and
413+
imports.
414+
415+
Primarily extensions are needed to override main configuration and
416+
provide some specific settings for environment like dev. That is why it
417+
allows to override just specific set of configuration keys for specific
418+
field:
419+
- const
420+
- pattern
421+
- default
422+
- env_var
423+
424+
Extension won't override other field keys to keep config class signature
425+
consistent (if you need to add other keys in this list, feel free to
426+
open an issue for that).
427+
428+
Also extension allows you to define import list in addition to default
429+
config. If extension is used - import list will be merged from default
430+
config and extension config
431+
432+
### Basic Extension config usage
433+
434+
To use extension define it in config:
435+
436+
```yaml
437+
environment_config:
438+
fields:
439+
first_key:
440+
441+
imports:
442+
- some:package
443+
444+
extensions:
445+
dev: # your extension name
446+
fields:
447+
first_key:
448+
default: some value
449+
450+
imports:
451+
- other:package
452+
```
453+
454+
Then if you run command like this
455+
456+
```
457+
flutter pub run environment_config:generate
458+
```
459+
460+
It will throw an error that `first_key` is required. But you use
461+
extension
462+
463+
```
464+
flutter pub run environment_config:generate --config-extension=dev
465+
```
466+
467+
It will generate following config class
468+
469+
```dart
470+
import 'some:package';
471+
import 'other:package';
472+
473+
class EnvironmentConfig {
474+
static const String first_key = 'some value';
475+
}
476+
```
477+
478+
### Development Extension example
479+
480+
**Note** Don't use development extension in your automated build tools.
481+
There is a plan add verbose command run support eventually.
482+
483+
Most common case when extension can be used is for your Dev environment.
484+
In that way your default config will ensure that all fields are provided
485+
by build tool, and in same time - to generate config for dev
486+
environment, you won't need to define values for your fields.
487+
488+
To enable dev extension just add `dev_extension`
489+
490+
```diff
491+
environment_config:
492+
+ dev_extension: dev
493+
fields:
494+
first_key:
495+
496+
imports:
497+
- some:package
498+
499+
extensions:
500+
dev:
501+
fields:
502+
first_key:
503+
default: some value
504+
505+
imports:
506+
- other:package
507+
```
508+
509+
Then you can run command like this
510+
511+
```
512+
flutter pub run environment_config:generate --dev
513+
```
514+
369515
## Integration with CI/CD
370516

371517
To add config generation into any CI/CD, add command execution after

lib/argument_parser.dart

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import 'package:args/args.dart';
22
import 'package:yaml/yaml.dart';
33

4-
import 'platform_value_provider.dart';
54
import 'config_field_type.dart';
65
import 'errors/malformed_config_error.dart';
76
import 'errors/validation_error.dart';
@@ -11,9 +10,7 @@ class ArgumentParser {
1110
/// Arguments from command params
1211
final List<String> arguments;
1312

14-
final PlatformValueProvider valueProvider;
15-
16-
ArgumentParser(this.arguments, this.valueProvider);
13+
ArgumentParser(this.arguments);
1714

1815
/// Defines if `config` key was specified
1916
/// during command run
@@ -31,7 +28,7 @@ class ArgumentParser {
3128
}
3229

3330
/// Provides arguments from command based on YAML fields config
34-
ArgResults parseArguments(YamlMap config) {
31+
Map<String, dynamic> parseArguments(YamlMap config) {
3532
final ArgParser parser = ArgParser();
3633

3734
if (!config.containsKey(ConfigFieldType.FIELDS)) {
@@ -45,7 +42,13 @@ class ArgumentParser {
4542

4643
final params = config[ConfigFieldType.FIELDS];
4744

48-
parser.addOption(ConfigFieldType.CONFIG);
45+
if (config.containsKey(ConfigFieldType.DEV_EXTENSION)) {
46+
parser.addFlag(config[ConfigFieldType.DEV_EXTENSION]);
47+
}
48+
49+
parser
50+
..addOption(ConfigFieldType.CONFIG)
51+
..addOption(ConfigFieldType.CONFIG_EXTENSION);
4952

5053
params.keys.forEach((key) {
5154
if (params[key] != null && params[key] is! Map) {
@@ -54,20 +57,18 @@ class ArgumentParser {
5457

5558
final Map<dynamic, dynamic> value = params[key] ?? {};
5659

57-
final String globalKey = value[ConfigFieldType.ENV_VAR];
58-
String defaultValue;
59-
60-
if ((globalKey ?? '').isNotEmpty) {
61-
defaultValue = valueProvider.getValue(globalKey);
62-
}
63-
6460
parser.addOption(
6561
key,
6662
abbr: value[ConfigFieldType.SHORT_NAME],
67-
defaultsTo: defaultValue,
6863
);
6964
});
7065

71-
return parser.parse(arguments);
66+
final parsedArguments = parser.parse(arguments);
67+
68+
return Map.fromIterable(
69+
parsedArguments.options,
70+
key: (dynamic key) => key,
71+
value: (dynamic key) => parsedArguments[key],
72+
);
7273
}
7374
}

0 commit comments

Comments
 (0)