run method
Runs this command.
The return value is wrapped in a Future if necessary and returned by
CommandRunner.runCommand.
Implementation
@override
Future<void> run() async {
bool exact = argResults!['exact'];
bool all = argResults!['all'];
String nativeMode = argResults!['native'];
int limit = int.tryParse(argResults!['limit']) ?? 20;
List<String> words = argResults!.rest;
showUsage(words.isEmpty && !all, () => printUsage());
final db = await DB.instance();
List<Package> xpmResults = [];
List<NativePackage> nativeResults = [];
if (nativeMode != 'only') {
if (all) {
xpmResults = await db.packages.where().limit(limit).findAll();
} else if (exact) {
xpmResults = await db.packages.filter().nameEqualTo(words[0]).limit(limit).findAll();
} else {
xpmResults = await db.packages
.filter()
.anyOf(words, (q, w) => q.nameMatches('*$w*', caseSensitive: false))
.or()
.anyOf(words, (q, w) => q.descMatches('*$w*', caseSensitive: false))
.or()
.anyOf(words, (q, w) => q.titleMatches('*$w*', caseSensitive: false))
.sortByName()
.thenByTitle()
.thenByDesc()
.limit(limit)
.findAll();
}
}
if (nativeMode != 'off' && !all) {
final nativeManager = await NativePackageManagerDetector.detect();
if (nativeManager != null) {
if (nativeMode == 'only' || (nativeMode == 'auto' && xpmResults.length < 6)) {
nativeResults = await nativeManager.search(words.join(' '), limit: limit);
}
}
}
final currentArch = getArchitecture();
final currentOS = Platform.operatingSystem;
final platform = "$currentOS-$currentArch";
if (xpmResults.isEmpty && nativeResults.isEmpty) {
print('No packages found.');
} else {
print('Found ${xpmResults.length + nativeResults.length} packages:');
// Separate native results by type for proper ordering
final extraChaoticPackages = <NativePackage>[];
final otherOfficialPackages = <NativePackage>[];
final aurPackages = <NativePackage>[];
for (final result in nativeResults) {
if (result.repo == 'aur') {
aurPackages.add(result);
} else if (result.repo == 'extra' || result.repo == 'chaotic-aur') {
extraChaoticPackages.add(result);
} else {
otherOfficialPackages.add(result);
}
}
// Sort official packages alphabetically
extraChaoticPackages.sort((a, b) => a.name.compareTo(b.name));
otherOfficialPackages.sort((a, b) => a.name.compareTo(b.name));
// Sort AUR packages by popularity (ascending - less popular first so user sees most popular first)
aurPackages.sort((a, b) {
final aPop = a.popularity ?? 0;
final bPop = b.popularity ?? 0;
return aPop.compareTo(bPop);
});
// Display native results first: extra/chaotic-aur, then others, then AUR
final allNativePackages = <NativePackage>[];
allNativePackages.addAll(extraChaoticPackages);
allNativePackages.addAll(otherOfficialPackages);
allNativePackages.addAll(aurPackages);
for (final result in allNativePackages) {
final version = result.version != null && result.version!.isNotEmpty ? ' {@green}${result.version}{@end}' : '';
final popularity = result.popularity != null && result.popularity! > 0
? ' {@yellow}(${result.popularity} votes){@end}'
: '';
final repoInfo = result.repo != null && result.repo != 'aur' ? '${result.repo}/' : '';
final packageLabel = result.repo == 'aur' ? 'AUR' : 'PM';
final fullName = repoInfo.isNotEmpty ? '$repoInfo${result.name}' : result.name;
out('{@yellow}[$packageLabel]{@end} {@blue}$fullName{@end}$version$popularity - ${result.description ?? ''}');
}
// Then display xpm results (moved after native results)
for (final result in xpmResults) {
final installed = result.installed != null ? '[{@green}installed{@end}] ' : '';
final unavailable = result.arch != null && !result.arch!.contains('any') && !result.arch!.contains(platform)
? '[{@red}unavailable for $platform{@end}]'
: '';
out(
'$unavailable{@blue}${result.name}{@end} {@green}${result.version}{@end} $installed- ${result.title != result.name ? "${result.title} - " : ""}${result.desc}',
);
}
}
}