How to Uninstall a Module in Magento 2

magento2moduleuninstall

I'm trying to uninstall a module (my own) that I've installed via composer using CLI with this command:

bin/magento module:uninstall -r [Namespace]_[Module]  

Based on the answer provided here by @RyanH I've created the Setup/Uninstall.php file that removes database related data of the module.

This works perfectly but the uninstall procedure hangs.

I've even left the script running over night and still the same result.
The extension files are still there in the vendor module.
I didn't touch the file permissions or owner.

What goes right:

  • the database related data is removed
  • the module name is removed from the table setup_module
  • the module name is removed from app/etc/config.php.

What goes wrong:

  • the module files are still there in the vendor folder.
  • the console command does not finish.

Console output:

You are about to remove code and/or database tables. Are you sure?[y/N]y
Enabling maintenance mode
You are removing data without a database backup.
Removing data of [Namespace]_[Module]
Removing [Namespace]_[Module] from module registry in database
Removing [Namespace]_[Module] from module list in deployment configuration
Removing code from Magento codebase:

After this it just hangs.

Is there anyway to finish the uninstall process, or at least debug it?

Best Answer

The part of the uninstall process were it hands can be found under setup/src/Magento/Setup/Model/ModuleUninstaller.php :

public function uninstallCode(OutputInterface $output, array $modules)
{
    $output->writeln('<info>Removing code from Magento codebase:</info>');
    $packages = [];
    /** @var \Magento\Framework\Module\PackageInfo $packageInfo */
    $packageInfo = $this->objectManager->get('Magento\Framework\Module\PackageInfoFactory')->create();
    foreach ($modules as $module) {
        $packages[] = $packageInfo->getPackageName($module);
    }
    $this->remove->remove($packages);
}

Basically it lists the packages to remove and then run a composer remove command on those packages via lib/internal/Magento/Framework/Composer/Remove.php :

public function remove(array $packages)
{
    $composerApplication = $this->composerApplicationFactory->create();

    return $composerApplication->runComposerCommand(
        [
            'command' => 'remove',
            'packages' => $packages
        ]
    );
}

You can find the runComposerCommand method in vendor/magento/composer/src/MagentoComposerApplication.php :

public function runComposerCommand(array $commandParams, $workingDir = null)
{
    $this->consoleApplication->resetComposer();

    if ($workingDir) {
        $commandParams[self::COMPOSER_WORKING_DIR] = $workingDir;
    } else {
        $commandParams[self::COMPOSER_WORKING_DIR] = dirname($this->composerJson);
    }

    $input = $this->consoleArrayInputFactory->create($commandParams);

    $exitCode = $this->consoleApplication->run($input, $this->consoleOutput);

    if ($exitCode) {
        throw new \RuntimeException(
            sprintf('Command "%s" failed: %s', $commandParams['command'], $this->consoleOutput->fetch())
        );
    }

    return $this->consoleOutput->fetch();
}

To me something happens along the way here and those functions are where you should start debugging.

Maybe you module composer.json file is missing or has an error.

Related Topic