prepare method
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);
}