load static method
Create a new GeneratorConfig by loading the configuration in the serverRootDir.
If serverRootDir is empty, the server directory will be automatically
detected by searching the current directory and nearby locations.
The interactive parameter controls whether interactive prompts are enabled.
Defaults to true unless running in a CI environment (detected via ci package).
Explicit flag value overrides CI detection.
Implementation
static Future<GeneratorConfig> load({
String serverRootDir = '',
required bool? interactive,
}) async {
// Auto-detect server directory if not specified
if (serverRootDir.isEmpty) {
// Determine if we should use interactive mode
// Priority: explicit flag > CI detection > default (true)
final isInteractive = interactive ?? !ci.isCI;
var serverDir = await ServerDirectoryFinder.findOrPrompt(
interactive: isInteractive,
);
serverRootDir = serverDir.path;
}
var serverPackageDirectoryPathParts = p.split(serverRootDir);
Pubspec? pubspec;
try {
pubspec = parsePubspec(File(p.join(serverRootDir, 'pubspec.yaml')));
} catch (_) {}
if (pubspec == null) {
throw const ServerpodProjectNotFoundException(
'Failed to load pubspec.yaml. Are you running serverpod from your '
'projects server root directory?',
);
}
if (!isServerDirectory(Directory(serverRootDir))) {
throw ServerpodProjectNotFoundException(
'Could not find the Serverpod dependency in the directory '
'$serverRootDir. Are you running serverpod from your '
'projects root directory?',
);
}
var serverPackage = pubspec.name;
var name = _stripPackage(serverPackage);
var file = File(p.join(serverRootDir, 'config', 'generator.yaml'));
YamlMap generatorConfig = await file.exists()
? loadYamlMap(await file.readAsString(), sourceUrl: file.uri)
: YamlMap();
var type = getPackageType(generatorConfig);
var relativeDartClientPackagePathParts = ['..', '${name}_client'];
if (generatorConfig['client_package_path'] != null) {
relativeDartClientPackagePathParts = p.split(
generatorConfig['client_package_path'],
);
}
List<String>? relativeServerTestToolsPathParts;
if (generatorConfig['server_test_tools_path'] != null) {
relativeServerTestToolsPathParts = p.split(
generatorConfig['server_test_tools_path'],
);
}
late String dartClientPackage;
late bool dartClientDependsOnServiceClient;
try {
var file = File(
p.joinAll([
...serverPackageDirectoryPathParts,
...relativeDartClientPackagePathParts,
'pubspec.yaml',
]),
);
var yamlStr = file.readAsStringSync();
Map yaml = loadYaml(yamlStr);
dartClientPackage = yaml['name'];
dartClientDependsOnServiceClient = (yaml['dependencies'] as Map)
.containsKey('serverpod_service_client');
} catch (_) {
throw const ServerpodProjectNotFoundException(
'Failed to load client pubspec.yaml. If you are using a none default '
'path it has to be specified in the config/generator.yaml file!',
);
}
var packageConfig = await findPackageConfig(Directory(serverRootDir));
if (packageConfig == null) {
throw const ServerpodProjectNotFoundException(
'Failed to read your server\'s package configuration. Have you run '
'`dart pub get` in your server directory?',
);
}
if (relativeServerTestToolsPathParts != null &&
packageConfig['serverpod_test'] == null) {
log.warning(
'A `server_test_tools_path` was set in the generator config, '
'but the `serverpod_test` package is not installed. '
"Make sure it's part of your pubspec.yaml file and run `dart pub get`. "
"If you don't want to use `serverpod_test`, then remove `server_test_tools_path`.",
);
}
var allPackagesAreInstalled = pubspec.dependencies.keys.every(
(dependencyName) => packageConfig[dependencyName] != null,
);
if (!allPackagesAreInstalled) {
log.warning(
'Not all dependencies are installed, which might cause errors in your Serverpod code. Run `dart pub get`.',
);
}
var manualModules = <String, String?>{};
if (generatorConfig['modules'] != null) {
Map modulesData = generatorConfig['modules'];
for (var package in modulesData.keys) {
var packageValue = modulesData[package];
var nickname = packageValue is Map ? packageValue['nickname'] : null;
manualModules[package] = nickname is String ? nickname : null;
}
}
var modules = loadModuleConfigs(
packageConfig: packageConfig,
projectPubspec: pubspec,
nickNameOverrides: manualModules,
);
// Load extraClasses
var extraClasses = <TypeDefinition>[];
var configExtraClasses = generatorConfig['extraClasses'];
if (configExtraClasses != null) {
try {
for (var extraClassConfig in configExtraClasses) {
extraClasses.add(
parseType(
extraClassConfig,
extraClasses: null,
),
);
}
} on SourceSpanException catch (_) {
rethrow;
} catch (e) {
throw SourceSpanFormatException(
'Failed to load \'extraClasses\' config',
configExtraClasses is YamlNode ? configExtraClasses.span : null,
);
}
}
var enabledFeatures = _enabledFeatures(file, generatorConfig);
var enabledExperimentalFeatures = [
..._enabledExperimentalFeatures(file, generatorConfig),
...CommandLineExperimentalFeatures.instance.features,
];
return GeneratorConfig(
name: name,
type: type,
serverPackage: serverPackage,
dartClientPackage: dartClientPackage,
dartClientDependsOnServiceClient: dartClientDependsOnServiceClient,
serverPackageDirectoryPathParts: serverPackageDirectoryPathParts,
relativeServerTestToolsPathParts: relativeServerTestToolsPathParts,
relativeDartClientPackagePathParts: relativeDartClientPackagePathParts,
modules: modules,
extraClasses: extraClasses,
enabledFeatures: enabledFeatures,
experimentalFeatures: enabledExperimentalFeatures,
);
}