run method

  1. @override
void run()
override

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 remove.
  List<String> packagesRequested = argResults!.rest;

  showUsage(packagesRequested.isEmpty, () => printUsage());

  // Get the Bash instance.
  final bash = await XPM.bash;

  // Get the local database instance.
  final db = await DB.instance();

  // Remove each package.
  for (String packageRequested in packagesRequested) {
    // Find the package in the local database.
    final packageInDB = await db.packages.filter().nameEqualTo(packageRequested).findFirst();
    if (packageInDB == null) {
      leave(message: 'Package "{@gold}$packageRequested{@end}" not found.', exitCode: cantExecute);
    }

    if (packageInDB.installed == null && !argResults!['force']) {
      // Check if the package is installed in the system but not for me.
      leave(message: 'Package "{@gold}$packageRequested{@end}" is not installed.', exitCode: cantExecute);
    }

    var repo = packageInDB.repo.value!;

    final prepare = Prepare(repo, packageInDB, args: argResults);
    out('Removing "{@blue}$packageRequested{@end}"...');

    // Run the removal script.
    final runner = Run();
    try {
      await runner.simple(bash, ['-c', 'source ${await prepare.toRemove()}']);
    } on ShellException catch (e) {
      sharedStdIn.terminate();

      String error = 'Failed to remove "{@red}$packageRequested{@end}"';
      if (argResults!['verbose'] == true) {
        error += ': ${e.message}';
      } else {
        error += '.';
      }

      leave(message: error, exitCode: e.result?.exitCode ?? generalError);
    }

    // Validate the removal of the package.
    try {
      await runner.simple(bash, ['-c', 'source ${await prepare.toValidate(removing: true)}']);
      String error = 'Failed to validate uninstall of "{@red}$packageRequested{@end}"';
      Logger.warning(error);
    } on ShellException {
      // If the package is not installed, the validation should pass
    }
    // Update the local database to reflect the removal.
    await db.writeTxn(() async {
      packageInDB.installed = null;
      packageInDB.method = null;
      packageInDB.channel = null;
      await db.packages.put(packageInDB);
    });

    // Log the result of the removal.
    Logger.success('Successfully removed "$packageRequested".');
  }
  sharedStdIn.terminate();
}