run method
Runs this command.
The return value is wrapped in a Future if necessary and returned by
CommandRunner.runCommand.
Implementation
@override
void run() async {
// Get the list of packages to install.
List<String> packagesRequested = argResults!.rest;
showUsage(packagesRequested.isEmpty, () => printUsage());
String nativeMode = argResults!['native'];
// Get the Bash instance.
final bash = await XPM.bash;
// Get the local database instance.
final db = await DB.instance();
// Install each package.
for (String packageRequested in packagesRequested) {
Package? packageInDB;
if (nativeMode != 'only') {
packageInDB = await db.packages.filter().nameEqualTo(packageRequested).findFirst();
}
if (packageInDB == null) {
if (nativeMode != 'off') {
final nativeManager = await NativePackageManagerDetector.detect();
if (nativeManager != null) {
Logger.info('Installing "$packageRequested" from native package manager...');
try {
await nativeManager.install(packageRequested);
final nativePackage = await nativeManager.get(packageRequested);
if (nativePackage != null) {
// Add the package to the local database to be managed by xpm
await db.writeTxn(() async {
final newPackage = Package()
..name = nativePackage.name
..version = nativePackage.version ?? 'native'
..desc = nativePackage.description
..installed = nativePackage.version ?? 'native'
..isNative = true;
await db.packages.put(newPackage);
});
Logger.success('Successfully installed "$packageRequested".');
} else {
Logger.error('Failed to install "$packageRequested".');
}
} catch (e) {
leave(message: 'Failed to install "$packageRequested": $e', exitCode: generalError);
}
} else {
leave(message: 'Package "{@gold}$packageRequested{@end}" not found.', exitCode: cantExecute);
}
} else {
leave(message: 'Package "{@gold}$packageRequested{@end}" not found.', exitCode: cantExecute);
}
} else {
var repo = packageInDB.repo.value!;
final prepare = Prepare(repo, packageInDB, args: argResults);
if (packageInDB.installed != null && await Executable(packageRequested).exists()) {
Logger.info('Reinstalling "$packageRequested"...');
} else {
Logger.info('Installing "$packageRequested"...');
}
// Run the installation script.
final runner = Run();
try {
await runner.simple(bash, ['-c', 'source ${await prepare.toInstall()}']);
} on ShellException catch (e) {
sharedStdIn.terminate();
String error = 'Failed to install "$packageRequested"';
if (argResults!['verbose'] == true) {
error += ': ${e.message}';
} else {
error += '.';
}
leave(message: error, exitCode: e.result?.exitCode ?? generalError);
}
// Check if the package was installed successfully.
final script = packageInDB.script;
if (script != null) {
final bashScript = BashScript(script);
bool hasValidation = await bashScript.hasFunction('validate');
String? error;
if (hasValidation) {
Logger.info('Checking installation of $packageRequested...');
try {
await runner.simple(bash, ['-c', 'source ${await prepare.toValidate()}']);
} on ShellException catch (e) {
error = 'Package "$packageRequested" installed with errors';
if (argResults!['verbose'] == true) {
error += ': ${e.message}';
} else {
error += '.';
}
}
} else {
Logger.warning('No validation found for $packageRequested.');
}
// Update the local database to reflect the installation.
await db.writeTxn(() async {
if (packageInDB != null) {
packageInDB.installed = packageInDB.version;
packageInDB.method = argResults!['method'];
packageInDB.channel = argResults!['channel'];
await db.packages.put(packageInDB);
}
});
// Log the result of the installation.
if (error != null) {
Logger.error(error);
} else {
Logger.success('Successfully installed "$packageRequested".');
}
}
}
}
sharedStdIn.terminate();
}