generate method

  1. @override
Future<GenerationResult> generate(
  1. GeneratorContext context
)
override

Generates the Flutter project using context.

Implementation

@override
Future<GenerationResult> generate(GeneratorContext context) async {
  // 1. Run flutter create
  final String? workingDir;
  if (context.targetDirectory != context.projectName) {
    final parentDir = p.dirname(context.targetDirectory);
    workingDir =
        (parentDir != '.' && parentDir.isNotEmpty) ? parentDir : null;
  } else {
    workingDir = null;
  }

  final projectPath = await _creator.createProject(
    projectName: context.projectName,
    workingDirectory: workingDir,
  );

  try {
    // 2. Resolve variable map
    final variables = VariableResolver.resolve(
      rawProjectName: context.projectName,
    );

    // 3. Render template files & YAML folders over baseline project
    final renderResult = _renderer.render(
      template: context.template,
      variables: variables,
      destinationPath: projectPath,
      overwriteExisting: true,
    );

    // 4. Install dependencies & dev_dependencies + run flutter pub get
    final installResult = await _packageManager.installAll(
      projectPath: projectPath,
      dependencies: context.template.config.dependencies,
      devDependencies: context.template.config.devDependencies,
    );

    // 5. Scan, register, and generate asset constants if assets exist
    final discoveredAssets = _assetScanner.scan(projectPath);
    int discoveredAssetsCount = 0;
    String? generatedAssetsClassPath;

    if (discoveredAssets.isNotEmpty) {
      discoveredAssetsCount = discoveredAssets.length;
      _pubspecAssetWriter.write(projectPath, discoveredAssets);
      generatedAssetsClassPath = _assetsClassGenerator.generate(
        projectPath: projectPath,
        assets: discoveredAssets,
        relativeFilePath: context.template.config.assetsClassPath,
      );
    }

    return GenerationResult(
      projectPath: projectPath,
      template: context.template,
      renderResult: renderResult,
      installResult: installResult,
      discoveredAssetsCount: discoveredAssetsCount,
      assetsClassPath: generatedAssetsClassPath,
    );
  } catch (e) {
    // Rollback: delete partially-created project directory
    final dir = Directory(projectPath);
    if (dir.existsSync()) {
      try {
        dir.deleteSync(recursive: true);
      } catch (_) {}
    }

    if (e is PackageInstallException) {
      throw PackageInstallException(
        packageName: e.packageName,
        errorDetails:
            '${e.errorDetails}\n\nThe partially-created project has been removed. No changes were left on disk.',
        installedBeforeFailure: e.installedBeforeFailure,
        isDevDependency: e.isDevDependency,
      );
    } else if (e is CliException) {
      throw CliException(
        '${e.message}\n\nThe partially-created project has been removed. No changes were left on disk.',
        exitCode: e.exitCode,
      );
    }

    throw CliException(
      'Project generation failed: $e\n\nThe partially-created project has been removed. No changes were left on disk.',
      exitCode: 1,
    );
  }
}