LoomFlavorSelection.load constructor
LoomFlavorSelection.load(})
Loads inline flavor defaults from projectFile and an optional override.
Implementation
factory LoomFlavorSelection.load(
List<String> arguments, {
required File projectFile,
Map<String, String>? environmentVariables,
}) {
final processEnvironment = environmentVariables ?? Platform.environment;
final forwarded = [...arguments];
final environmentOption = _takeOption(forwarded, '--env');
final flavorOption = _takeOption(forwarded, '--flavor');
if (environmentOption != null && flavorOption != null) {
throw const FormatException('Use either --env or --flavor, not both.');
}
final explicit = flavorOption ?? environmentOption;
final document = loadYaml(projectFile.readAsStringSync());
if (document is! YamlMap || document['runner'] is! YamlMap) {
throw FormatException('${projectFile.path} has no runner configuration.');
}
final runner = document['runner']! as YamlMap;
final flavors = document['flavors'];
if (flavors is! YamlMap || flavors.isEmpty) {
throw FormatException('${projectFile.path} must define flavors.');
}
final fallback = runner['default_flavor'];
final name =
explicit ??
processEnvironment['SQLITE_LOOM_FLAVOR'] ??
processEnvironment['CLIENT'] ??
processEnvironment['APP_FLAVOR'] ??
(fallback is String ? fallback : 'development');
_validateFlavorName(name);
final inline = flavors[name];
if (inline is! YamlMap) {
throw FormatException('SQLite Loom flavor is not defined: $name');
}
final values = _stringMap(inline);
final overrides = runner['flavor_overrides_directory'];
if (overrides is String && overrides.trim().isNotEmpty) {
final root = p.normalize(
p.absolute(projectFile.parent.path, overrides.trim()),
);
final override = File(p.join(root, '$name.yaml'));
if (!p.isWithin(root, p.normalize(p.absolute(override.path)))) {
throw FormatException('Flavor override escapes its directory: $name');
}
if (override.existsSync()) {
final overrideYaml = loadYaml(override.readAsStringSync());
if (overrideYaml is! YamlMap) {
throw FormatException('${override.path} must contain a YAML map.');
}
_merge(values, _stringMap(overrideYaml));
}
}
final database = values['database'];
final safety = values['safety'];
if (database is! Map || database['path'] is! String) {
throw FormatException('Flavor $name must define database.path.');
}
final configuredEnvironment = values['environment'];
final configuredDestructive = safety is Map
? safety['allow_destructive']
: null;
return LoomFlavorSelection(
name: name,
databasePath: _environmentValue(
'SQLITE_LOOM_DATABASE',
database['path']! as String,
processEnvironment,
),
environment: _environmentValue(
'SQLITE_LOOM_ENVIRONMENT',
configuredEnvironment is String ? configuredEnvironment : name,
processEnvironment,
),
allowDestructive: _environmentBoolean(
'SQLITE_LOOM_ALLOW_DESTRUCTIVE',
configuredDestructive is bool ? configuredDestructive : false,
processEnvironment,
),
arguments: List.unmodifiable(forwarded),
);
}