build method

  1. @override
FutureOr<void> build(
  1. BuildStep buildStep
)

Generates the outputs for a given BuildStep.

Implementation

@override
FutureOr<void> build(BuildStep buildStep) async {
  final String baseLocale =
      Utils.normalize(options.config['base_locale'] ?? defaultBaseLocale);
  final String? inputDirectory = options.config['input_directory'];
  final String? outputDirectory = options.config['output_directory'];
  final String translateVar =
      options.config['translate_var'] ?? defaultTranslateVar;
  final String enumName = options.config['enum_name'] ?? defaultEnumName;
  final String? keyCase = options.config['key_case'];
  final List<String> maps = options.config['maps']?.cast<String>() ?? [];

  if (inputDirectory != null &&
      !buildStep.inputId.path.contains(inputDirectory)) return;

  // only generate once
  if (_generated) return;

  _generated = true;

  // detect all locales, their assetId and the baseName
  final Map<AssetId, String> locales = Map();
  String? baseName;

  final Glob findAssetsPattern = inputDirectory != null
      ? Glob('**$inputDirectory/*$inputFilePattern')
      : Glob('**$inputFilePattern');

  await buildStep.findAssets(findAssetsPattern).forEach((assetId) {
    final fileNameNoExtension =
        assetId.pathSegments.last.replaceAll(inputFilePattern, '');
    final match = Utils.localeRegex.firstMatch(fileNameNoExtension);

    if (match != null) {
      if (match.group(2) != null) {
        baseName = match.group(2);
      }

      final language = match.group(3);
      final country = match.group(5);

      if (country != null) {
        locales[assetId] = '$language-$country';
      } else if (language != null) {
        locales[assetId] = language;
      }
    } else {
      locales[assetId] = baseLocale;
      baseName = fileNameNoExtension;
    }
  });

  if (baseName == null) baseName = defaultBaseName;

  // build config which applies to all locales
  final config = I18nConfig(
      baseName: baseName!,
      baseLocale: baseLocale,
      maps: maps,
      keyCase: keyCase.toKeyCase(),
      translateVariable: translateVar,
      enumName: enumName);

  // map each assetId to I18nData
  final localesWithData = Map<AssetId, I18nData>();

  for (MapEntry<AssetId, String> asset in locales.entries) {
    String locale = asset.value;
    String content = await buildStep.readAsString(asset.key);
    I18nData representation = parseJSON(config, baseName!, locale, content);
    localesWithData[asset.key] = representation;
  }

  // generate
  final String output = generate(
      config: config,
      translations: localesWithData.values.toList()
        ..sort((a, b) => a.locale.compareTo(b.locale)));

  // write only to main locale
  final AssetId baseId =
      localesWithData.entries.firstWhere((element) => element.value.base).key;

  final finalOutputDirectory =
      outputDirectory ?? (baseId.pathSegments..removeLast()).join('/');
  final String outFilePath =
      '$finalOutputDirectory/$baseName$outputFilePattern';

  File(outFilePath).writeAsStringSync(output);
}