loadConfig function

Future<ConfigData> loadConfig(
  1. Directory directory
)

Implementation

Future<ConfigData> loadConfig(Directory directory) async {
  final pubspecFile = File(join(directory.path, 'pubspec.yaml'));

  if (!pubspecFile.existsSync()) {
    throw StateError('pubspec.yaml not found in ${directory.path}');
  }

  // Get workspace information
  final workspaceInfo = await getWorkspaceInfo(directory);

  // Load and merge dpk.yaml files
  Map dpkYaml = {};
  Map? workspaceRootPubspec;

  if (workspaceInfo.isWorkspacePackage) {
    // In a workspace package (not at root)

    // Load workspace root pubspec to get workspace field
    if (workspaceInfo.workspaceRoot != null) {
      final rootPubspecFile = File(
        join(workspaceInfo.workspaceRoot!.path, 'pubspec.yaml'),
      );
      if (rootPubspecFile.existsSync()) {
        // Load workspace root dpk.yaml first to check for workspace globs
        final rootDpk = loadDpkYamlRaw(workspaceInfo.workspaceRoot!);
        if (rootDpk == null) {
          throw StateError(
            'dpk.yaml not found in workspace root ${workspaceInfo.workspaceRoot!.path}',
          );
        }
        dpkYaml = rootDpk as Map;

        // Expand workspace globs and write to root pubspec
        final dpkWorkspace = dpkYaml['workspace'] as List?;
        if (dpkWorkspace != null) {
          final expandedWorkspace = expandWorkspaceGlobs(
            dpkWorkspace,
            workspaceInfo.workspaceRoot!,
          );
          if (expandedWorkspace != null) {
            _writeWorkspaceToPubspec(rootPubspecFile, expandedWorkspace);
          }
        }

        workspaceRootPubspec =
            loadYaml(rootPubspecFile.readAsStringSync()) as Map;
      }
    }

    // Load package dpk.yaml if it exists
    final packageDpk = loadDpkYamlRaw(directory);
    if (packageDpk != null) {
      final packageDpkMap = packageDpk as Map;

      // Validate that package dpk.yaml doesn't contain forbidden fields
      validatePackageDpkYaml(packageDpkMap);

      // Merge scripts only (package scripts override root scripts)
      if (packageDpkMap.containsKey('scripts')) {
        final rootScripts = dpkYaml['scripts'] as Map? ?? {};
        final packageScripts = packageDpkMap['scripts'] as Map;
        // Create merged scripts map
        final mergedScripts = {...rootScripts, ...packageScripts};
        dpkYaml = {...dpkYaml, 'scripts': mergedScripts};
      }
    }
  } else {
    // Not in a workspace or at workspace root: load single dpk.yaml
    final localDpk = loadDpkYamlRaw(directory);
    if (localDpk == null) {
      throw StateError('dpk.yaml not found in ${directory.path}');
    }
    dpkYaml = localDpk as Map;

    // Expand workspace globs and write to pubspec
    final dpkWorkspace = dpkYaml['workspace'] as List?;
    if (dpkWorkspace != null) {
      final expandedWorkspace = expandWorkspaceGlobs(dpkWorkspace, directory);
      if (expandedWorkspace != null) {
        _writeWorkspaceToPubspec(pubspecFile, expandedWorkspace);
      }
    }
  }

  // Re-read pubspec after potential workspace expansion
  YamlMap pubspecYaml = loadYaml(pubspecFile.readAsStringSync()) as YamlMap;

  // If in a workspace package, also add the workspace field from root pubspec to pubspecYaml
  if (workspaceInfo.isWorkspacePackage && workspaceRootPubspec != null) {
    if (workspaceRootPubspec.containsKey('workspace')) {
      final pubspecMap = Map<String, dynamic>.from(pubspecYaml);
      pubspecMap['workspace'] = workspaceRootPubspec['workspace'];
      pubspecYaml = loadYaml(jsonEncode(pubspecMap)) as YamlMap;
    }
  }

  // Parse into ConfigData with separate pubspec and dpk yamls
  final configData = ConfigData.fromYaml(
    pubspecYaml: pubspecYaml,
    dpkYaml: loadYaml(jsonEncode(dpkYaml)) as YamlMap,
    workingDirectory: directory.path,
    workspaceRoot: workspaceInfo.workspaceRoot?.path,
  );

  return configData;
}