prepare method

Future<PreparedPackageRef> prepare(
  1. ArgResults argResults,
  2. PackageRef ref
)
inherited

prepares given ref. Depending on the type of ref this can include

  • copying the package to a temporary directory
  • running pub get If you use analyze with this result then it will take care to clean up everything (e.g. removing temp directory)

Implementation

Future<PreparedPackageRef> prepare(
  ArgResults argResults,
  PackageRef ref,
) async {
  final stdoutSession = StdoutSession();

  final forceUseFlutterTool =
      (argResults[_flagNameForceUseFlutter] as bool?) ?? false;

  List<SourceItem> sources = [];
  String? packageRelativePath;
  if (ref.isDirectoryPath) {
    String forceUseFlutterSuffix = '';
    if (forceUseFlutterTool) {
      forceUseFlutterSuffix = ' (forced Flutter)';
    }
    await stdoutSession.writeln('Preparing ${ref.ref}$forceUseFlutterSuffix');
    String sourceDir = ref.ref;
    if (sourceDir.endsWith(p.separator)) {
      sourceDir =
          sourceDir.substring(0, sourceDir.length - p.separator.length);
    }

    sources.add(SourceItem(
      sourceDir: sourceDir,
      isInCache: false,
    ));
  } else if (ref.isPubRef) {
    await stdoutSession.writeln(
        'Preparing ${ref.pubPackage!}:${ref.pubVersion ?? 'latest'}');
    await stdoutSession.writeln('Downloading');
    String sourceDir = await PubInteraction.installPackageToCache(
      ref.pubPackage!,
      ref.pubVersion,
      stdoutSession: stdoutSession,
    );
    sources.add(SourceItem(
      sourceDir: sourceDir,
      isInCache: true,
    ));
  } else if (ref.isGitRef) {
    final gitRefObj = ref.gitRef!;
    await stdoutSession.writeln('Preparing git repository: ${gitRefObj.uri}');
    if (gitRefObj.ref != null) {
      await stdoutSession.writeln('Using ref: ${gitRefObj.ref}');
    }
    // For git repositories, we'll clone directly to the temp directory later
    // Store the git info in a special SourceItem
    sources.add(SourceItem(
      sourceDir: gitRefObj.toInternalString(),
      isInCache: false, // Treat git repos like local dirs - they need pub get
    ));
  } else {
    throw ArgumentError('Unknown package ref: ${ref.ref}');
  }
  // merge sources to not copy children of a parent separately
  // => remove all sources that have a parent in the list
  sources.removeWhere((sToRemove) =>
      sources.any((s) => p.isWithin(s.sourceDir, sToRemove.sourceDir)));
  final tempDir = await Directory.systemTemp.createTemp();
  String? gitPackageRelativePath; // Store the relative path for git packages
  await Future.forEach<SourceItem>(sources, (sourceItem) async {
    if (sourceItem.sourceDir.startsWith('GIT:')) {
      // Handle git repository
      final gitRef = GitRef.fromInternalString(sourceItem.sourceDir);

      final targetDir = sourceItem.destinationPath(forPrefix: tempDir.path);
      final packageDir = await GitInteraction.cloneRepositoryToDirectory(
        gitRef.uri,
        targetDir,
        gitRef.ref,
        gitRef.path,
        stdoutSession: stdoutSession,
      );

      // Calculate the relative path from tempDir to packageDir
      gitPackageRelativePath = p.relative(packageDir, from: tempDir.path);

      String forceUseFlutterSuffix = '';
      if (forceUseFlutterTool) {
        forceUseFlutterSuffix = ' (forced Flutter)';
      }

      await stdoutSession.writeln(
          'Preparing package dependencies for git package ${gitRef.uri}$forceUseFlutterSuffix');
      await PubInteraction.runPubGet(
        packageDir,
        stdoutSession: stdoutSession,
        forceUseFlutterTool: forceUseFlutterTool,
      );
      await DartInteraction.transferPackageConfig(
        fromPackage: packageDir,
        toPackage: tempDir.path,
        stdoutSession: stdoutSession,
      );
    } else {
      // Handle regular directories and pub packages
      await stdoutSession
          .writeln('Copying sources from ${sourceItem.sourceDir}');
      await _copyPath(sourceItem.sourceDir,
          sourceItem.destinationPath(forPrefix: tempDir.path));
      if (!sourceItem.isInCache) {
        String forceUseFlutterSuffix = '';
        if (forceUseFlutterTool) {
          forceUseFlutterSuffix = ' (forced Flutter)';
        }

        await stdoutSession.writeln(
            'Preparing package dependencies for local package ${sourceItem.sourceDir}$forceUseFlutterSuffix');
        await PubInteraction.runPubGet(
          sourceItem.sourceDir,
          stdoutSession: stdoutSession,
          forceUseFlutterTool: forceUseFlutterTool,
        );
        await DartInteraction.transferPackageConfig(
          fromPackage: sourceItem.sourceDir,
          toPackage: tempDir.path,
          stdoutSession: stdoutSession,
        );
      } else {
        await stdoutSession.writeln('Cleaning up local copy of pub package');
        // Check if we have a pub package that bundles a pubspec_overrides.yaml (as this most probably destroys pub get)
        final pubspecOverrides = File(p.join(
            sourceItem.destinationPath(forPrefix: tempDir.path),
            'pubspec_overrides.yaml'));
        if (await pubspecOverrides.exists()) {
          await pubspecOverrides.delete();
          await stdoutSession.writeln('- Removed pubspec_overrides.yaml');
        }
      }
    }
  });
  return PreparedPackageRef(
      packageRef: ref,
      tempDirectory: tempDir.path,
      packageRelativePath: gitPackageRelativePath ?? packageRelativePath);
}