initializePuro function

Future<void> initializePuro(
  1. SdkInitializerContext context
)

Implementation

Future<void> initializePuro(SdkInitializerContext context) async {
  // Create folder for flutter sdk symlink
  final symlinkPath = flutterSdkSymlink();

  Directory? puroRootDir;
  final puroPath = getPuroPath();
  bool checkForUpdates = false;

  // Check if puro is already installed
  if (puroPath != null && puroPath.existsSync()) {
    puroRootDir = puroPath.parent.parent;
    printVerbose('Puro is already installed at ${puroRootDir.absolute.path}');
    checkForUpdates = true;
  } else {
    puroRootDir = installPuro();
  }
  dcli.env['PURO_ROOT'] = puroRootDir.absolute.path;
  printVerbose('PURO_ROOT: ${puroRootDir.absolute.path}');

  // Check if puro is up to date
  if (checkForUpdates && !_alreadyCheckedForUpdate) {
    _alreadyCheckedForUpdate = true;
    printVerbose('Checking for updates...');
    final latestVersion = Version.parse(getLatestPuroVersion());
    printVerbose('Latest Puro version: $latestVersion');

    final currentPuro = await getCurrentPuroVersion();
    final currentVersion = Version.parse(currentPuro.version);
    printVerbose(
      'Current Puro version: $currentVersion - Standalone: ${currentPuro.standalone}',
    );
    if (currentVersion < latestVersion) {
      print('Puro is outdated. Updating to $latestVersion');
      if (currentPuro.standalone) {
        puroRootDir = installPuro();
      } else {
        final progress = Progress.capture();
        try {
          await puro(['upgrade-puro'], progress: progress);
        } catch (e, stackTrace) {
          print('puro upgrade-puro failed: $e');
          print(stackTrace);
          if (progress.lines.isNotEmpty) {
            print('output:\n${progress.lines.join('\n')}');
          }
        }
        puroRootDir = puroPath!.parent.parent;
      }
      dcli.env['PURO_ROOT'] = puroRootDir.absolute.path;
    } else {
      printVerbose('Puro is up to date.');
    }
  }

  // getting the puro flutter sdk path only work when no bin override is set
  // https://github.com/pingbird/puro/blob/46d9753ffe8e60f0efa7256fad8e5efbf107e39a/puro/lib/src/config.dart#L147
  dcli.env['PURO_FLUTTER_BIN'] = null;

  final packageDir = context.packageDir?.root ?? SidekickContext.projectRoot;
  final package = DartPackage.fromDirectory(packageDir);
  final versions = await VersionParser(
    packagePath: packageDir,
    projectRoot: SidekickContext.projectRoot,
    useBeta: true,
  ).getMaxFlutterSdkVersionFromPubspec();

  // Setup puro environment
  final versionString = versions.flutterVersion.toString();
  printVerbose('Required Flutter version: $versionString');

  final existingEnvs = await _getPuroEnvs();
  printVerbose('Existing puro environments: ${existingEnvs.join(', ')}');

  String? cachedFlutterPath;
  if (!existingEnvs.contains(versionString)) {
    printVerbose('Environment $versionString does not exist, creating it');
    cachedFlutterPath = await _createPuroEnv(versions.flutterVersion);
  } else {
    printVerbose('Environment $versionString already exists');
  }

  await _bindPuroToProject(packageDir, versions.flutterVersion);

  // Create symlink to puro flutter sdk
  // Construct path directly instead of calling puro flutter --version
  String flutterPath;
  if (cachedFlutterPath != null) {
    flutterPath = cachedFlutterPath;
    printVerbose('Using cached path from puro create');
  } else {
    final constructedPath =
        Directory('${puroRootDir.path}/envs/$versionString/flutter');
    if (constructedPath.existsSync()) {
      flutterPath = constructedPath.absolute.path;
      printVerbose('Using constructed path: $flutterPath');
    } else {
      printVerbose(
          'Constructed path not found, falling back to puro flutter --version');
      flutterPath = await puroFlutterSdkPath(packageDir);
    }
  }
  final flutterBinPath = Directory(flutterPath).directory('bin');
  printVerbose('Flutter SDK: $flutterPath');

  dcli.env['PURO_FLUTTER_BIN'] = flutterBinPath.absolute.path;
  createSymlink(symlinkPath, flutterPath);

  final isFlutterPackage = package?.isFlutterPackage ?? false;
  if (isFlutterPackage) {
    print(
      'Using Flutter ${versions.flutterVersion} (Dart ${versions.dartVersion})',
    );
  } else {
    print(
      'Using Dart ${versions.dartVersion} (via Flutter ${versions.flutterVersion})',
    );
  }
}