build method

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

Generates the outputs for a given BuildStep.

Implementation

@override
Future<void> build(BuildStep buildStep) async {
  final config = await _loadConfig(buildStep);
  if (config == null) {
    log.fine('No excel_translator section in pubspec.yaml — skipping');
    return;
  }

  final excelFile = config['excel_file'] as String?;
  if (excelFile == null) {
    log.warning('excel_translator.excel_file not specified in pubspec.yaml');
    return;
  }

  final excelAsset = AssetId(buildStep.inputId.package, excelFile);
  if (!await buildStep.canRead(excelAsset)) {
    log.warning('Excel file not found: $excelFile');
    return;
  }

  // Reading registers excelAsset as a dependency → builder reruns on change.
  final bytes = await buildStep.readAsBytes(excelAsset);

  final parser = FileParserFactory.createParser(excelFile);
  final sheets = await parser.parseFileFromBytes(
    bytes,
    languageService: LanguageService(
      logInfo: log.info,
      logWarning: log.warning,
    ),
  );

  if (sheets.isEmpty) {
    log.warning('No sheets found in $excelFile');
    return;
  }

  sheets.sort((a, b) => a.name.compareTo(b.name));

  final pubspecOutputDir = config['output_dir'] as String?;
  if (pubspecOutputDir != null && pubspecOutputDir != _outputDir) {
    log.warning(
      'excel_translator: output_dir "$pubspecOutputDir" in pubspec.yaml is '
      'ignored when using build_runner. Set output_dir via build.yaml options '
      'instead (currently using "$_outputDir"). '
      'See package README for details.',
    );
  }
  final outputDir = _outputDir;
  final className = config['class_name'] as String? ?? 'AppLocalizations';
  final includeDelegates =
      config['include_flutter_delegates'] as bool? ?? true;

  // ── generated_localizations.dart ─────────────────────────────────────────
  // Inline mode: sheet classes + main class in one file (no per-sheet imports).
  final mainBuffer = StringBuffer();

  // 1. File header + Flutter imports
  mainBuffer.writeln('// GENERATED CODE - DO NOT MODIFY BY HAND');
  mainBuffer.writeln('// Generated by Excel Translator');
  mainBuffer.writeln();
  if (includeDelegates) {
    mainBuffer.writeln("import 'package:flutter/material.dart';");
    mainBuffer.writeln("import 'package:flutter/cupertino.dart';");
    mainBuffer.writeln(
      "import 'package:excel_translator/excel_translator.dart';",
    );
    mainBuffer.writeln("import 'dart:ui' show PlatformDispatcher;");
    mainBuffer.writeln();
  }

  // 2. Sheet class bodies (inlined — no separate files, no import lines)
  for (final sheet in sheets) {
    mainBuffer.write(_sheetGenerator.generateClassBody(sheet));
    mainBuffer.writeln();
  }

  // 3. Main class + delegate (shares logic with CLI, just no imports block)
  mainBuffer.write(
    _mainGenerator.generateClassAndDelegate(sheets, className, includeDelegates),
  );

  await buildStep.writeAsString(
    AssetId(buildStep.inputId.package,
        '$outputDir/generated_localizations.dart'),
    mainBuffer.toString(),
  );

  // ── build_context_extension.dart ─────────────────────────────────────────
  await buildStep.writeAsString(
    AssetId(buildStep.inputId.package,
        '$outputDir/build_context_extension.dart'),
    _extensionGenerator.generateContent(className),
  );

  log.info('excel_translator: generated localizations from $excelFile');
}