applyClientFonts method

Future<bool> applyClientFonts(
  1. String clientName,
  2. String clientAssetsPath
)

Swaps the project fonts for the client's and updates the pubspec fonts: section. Returns true when fonts were changed.

The font folder is snapshotted first (and pubspec.yaml is backed up by every caller), so cleanup — or, after whitelabel --keep, the next run or clean — restores the original fonts and pubspec entry exactly. Every run starts from that original state, so a client without fonts never inherits the previous client's, and two clients' fonts never mix.

Implementation

Future<bool> applyClientFonts(
    String clientName, String clientAssetsPath) async {
  final clientFontsDir = findClientFontsDir(clientName, clientAssetsPath);
  final targetFontsDir =
      Directory(p.join(projectDir, ConfigService.fontsDir));

  if (clientFontsDir == null) {
    Logger.info(
        'No custom fonts found for this client; keeping the project fonts.');
    return false;
  }

  final hasFontFiles = clientFontsDir
      .listSync()
      .whereType<File>()
      .any((f) => !p.basename(f.path).startsWith('.'));
  if (!hasFontFiles) {
    Logger.info(
        'Client fonts directory is empty; keeping the project fonts.');
    return false;
  }

  await config.snapshotFonts();
  if (targetFontsDir.existsSync()) {
    await targetFontsDir.delete(recursive: true);
  }
  await targetFontsDir.create(recursive: true);
  await _copyDirectory(clientFontsDir, targetFontsDir);

  final fontsConfigFile = File(p.join(clientFontsDir.path, 'fonts.yaml'));
  if (fontsConfigFile.existsSync()) {
    Logger.info('Applying client font configuration to pubspec...');

    try {
      final fontsContent = await fontsConfigFile.readAsString();
      final fontsList = loadYaml(fontsContent);

      if (fontsList is YamlList || fontsList is List) {
        await config.updatePubspecFonts(fontsList);
        Logger.success('Client font configuration applied to pubspec.yaml');
      } else {
        throw BuildException(
          'Invalid format in fonts.yaml: must be a YAML list of font configurations.',
          fix:
              'Check "${fontsConfigFile.path}" and ensure it is structured as a YAML list.',
        );
      }
    } on BuildException {
      rethrow;
    } catch (e, s) {
      throw BuildException(
        'Failed to parse or apply font configuration from "${fontsConfigFile.path}"',
        fix: 'Check fonts.yaml syntax for formatting errors.',
        originalStackTrace: s,
      );
    }
  } else {
    Logger.warning(
        'Fonts copied but no fonts.yaml found in "${clientFontsDir.path}"; '
        'pubspec font families were not updated.');
  }
  return true;
}