Skip to content

Commit

Permalink
Merge pull request #121 from icapps/feature/ModelDirectories
Browse files Browse the repository at this point in the history
Add support for model directories
  • Loading branch information
vanlooverenkoen committed Oct 17, 2022
2 parents 240e733 + ec76434 commit 69fe304
Show file tree
Hide file tree
Showing 14 changed files with 219 additions and 66 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
# Changelog
## [6.1.0] - 2022-10-14
- Support passing a directory instead of a file. All .yaml files inside this folder (recursively) will be used to build the final model data.

## [6.0.2] - 2022-10-06
- Updated travis to use linux instead of macOS

Expand Down
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ This model generator can be used to generate JsonSerializable models

`flutter packages run model_generator`

## Model file
## Model file(s)

By default, the model generator looks for the model yaml file in `model_generator/config.yaml`. If you want to overwrite this, specify it in your `pubspec.yaml` file by
using `config_path`. Example of the `pubspec.yaml` file if you want to use a custom model file location:
Expand All @@ -27,6 +27,9 @@ You can also specify a command line parameter to override the location for a sin
flutter packages run model_generator --path my_other_model_dir/config.yaml
```

**Note**: Since version 6.1.0, instead of a single model file, you can specify a directory containing multiple model files.
The generator will then generate models for all `.yaml` (or `.yml`) files in the directory. References across files are supported.

## Default setup

Example of the `pubspec.yaml` file if you want to use a custom base_directory for all your models Default is `/lib/model` you can override it for all your models like this:
Expand Down
47 changes: 39 additions & 8 deletions bin/model_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -36,25 +36,56 @@ Future<void> main(List<String> args) async {
final pubspecConfig = PubspecConfig(pubspecContent);

final configPath = results['path'] ?? pubspecConfig.configPath;
File configFile;
String absolutePath;
if (isAbsolute(configPath)) {
configFile = File(configPath);
absolutePath = configPath;
} else {
configFile = File(join(Directory.current.path, configPath));
absolutePath = join(Directory.current.path, configPath);
}
final FileSystemEntity configEntity;
switch (FileSystemEntity.typeSync(absolutePath)) {
case FileSystemEntityType.directory:
configEntity = Directory(absolutePath);
break;
case FileSystemEntityType.file:
default:
configEntity = File(absolutePath);
break;
}

if (!configFile.existsSync()) {
throw Exception('This program requires a config file. `$configPath`');
if (!configEntity.existsSync()) {
throw Exception(
'This program requires a config file/dir. `$configPath` does not exist');
}
final YmlGeneratorConfig modelGeneratorConfig;
if (configEntity is Directory) {
modelGeneratorConfig =
readConfigFilesInDirectory(pubspecConfig, configEntity, configPath);
} else {
final modelGeneratorContent = (configEntity as File).readAsStringSync();
modelGeneratorConfig =
YmlGeneratorConfig(pubspecConfig, modelGeneratorContent, configPath);
}
final modelGeneratorContent = configFile.readAsStringSync();
final modelGeneratorConfig =
YmlGeneratorConfig(pubspecConfig, modelGeneratorContent);
modelGeneratorConfig.checkIfTypesAvailable();

writeToFiles(pubspecConfig, modelGeneratorConfig);
await generateJsonGeneratedModels(useFvm: pubspecConfig.useFvm);
print('Done!!!');
}

YmlGeneratorConfig readConfigFilesInDirectory(
PubspecConfig config, Directory configEntity, String directoryPath) {
final configFiles = configEntity
.listSync(recursive: true)
.whereType<File>()
.where((element) =>
extension(element.path) == '.yaml' ||
extension(element.path) == '.yml');
final configs = configFiles.map((e) =>
YmlGeneratorConfig(config, e.readAsStringSync(), relative(e.path)));
return YmlGeneratorConfig.merge(configs, directoryPath);
}

void writeToFiles(
PubspecConfig pubspecConfig, YmlGeneratorConfig modelGeneratorConfig) {
for (final model in modelGeneratorConfig.models) {
Expand Down
21 changes: 0 additions & 21 deletions example/model_generator/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -137,27 +137,6 @@ Person:
unknown_enum_value: X
type: Gender

Gender:
path: user/person/
type: enum
properties:
MALE:
value: _mAl3
FEMALE:
value: femAle
X:
value: X
GENDER_X:
GENDER_Y:
value:
GENDER_z:
value: gender_z
GENDER_abC:
GENDER_def:
value:
GENDER_lap:
value: GENDER_lap

Duration:
path: data/custom/
type: custom
Expand Down
20 changes: 20 additions & 0 deletions example/model_generator/enums.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
Gender:
path: user/person/
type: enum
properties:
MALE:
value: _mAl3
FEMALE:
value: femAle
X:
value: X
GENDER_X:
GENDER_Y:
value:
GENDER_z:
value: gender_z
GENDER_abC:
GENDER_def:
value:
GENDER_lap:
value: GENDER_lap
2 changes: 1 addition & 1 deletion example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ dev_dependencies:
#In the model_generator/config.yaml you will see a object with a custom base_directory
#
model_generator:
config_path: model_generator/config.yaml
config_path: model_generator/
extra_imports:
- 'package:flutter/foundation.dart'
extra_annotations:
Expand Down
21 changes: 18 additions & 3 deletions lib/config/yml_generator_config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@ import 'package:model_generator/util/type_checker.dart';
import 'package:yaml/yaml.dart';

class YmlGeneratorConfig {
final String fileName;
final _models = <Model>[];

List<Model> get models => _models;

YmlGeneratorConfig(PubspecConfig pubspecConfig, String configContent) {
YmlGeneratorConfig(
PubspecConfig pubspecConfig, String configContent, this.fileName) {
loadYaml(configContent).forEach((key, value) {
final String baseDirectory =
value['base_directory'] ?? pubspecConfig.baseDirectory;
Expand Down Expand Up @@ -158,8 +160,6 @@ class YmlGeneratorConfig {
));
}
});

checkIfTypesAvailable();
}

Field getField(String name, YamlMap property,
Expand Down Expand Up @@ -399,4 +399,19 @@ class YmlGeneratorConfig {
}
return ObjectType(type);
}

YmlGeneratorConfig.merge(Iterable<YmlGeneratorConfig> configs, String dirName)
: fileName = dirName {
final names = <String, YmlGeneratorConfig>{};
for (final config in configs) {
for (final model in config.models) {
if (names.containsKey(model.name)) {
throw Exception(
'Model with same name ${model.name} found in multiple files: ${names[model.name]!.fileName} and ${config.fileName}');
}
names[model.name] = config;
}
_models.addAll(config.models);
}
}
}
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: model_generator
description: Dart tool to automaticly generate models from a yml file to speed up your development flow.
version: 6.0.2
version: 6.1.0
homepage: https://github.com/icapps/flutter-model-generator

environment:
Expand Down
2 changes: 1 addition & 1 deletion test/config/yml_generator_config/enum-normal.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Person:
User:
type: object
properties:
gender:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Person:
type: object
properties:
gender: SpecialGender
4 changes: 4 additions & 0 deletions test/config/yml_generator_config/object-reference-other.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Person:
type: object
properties:
gender: Gender

0 comments on commit 69fe304

Please sign in to comment.