Skip to content

Resolving module:uninstall hanging without response #32955

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: 2.4-develop
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions setup/src/Magento/Setup/Model/ModuleUninstaller.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

use Magento\Framework\Setup\Patch\PatchApplier;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Filesystem\Exception\FileNotFoundException;

/**
* Class to uninstall a module component
Expand Down Expand Up @@ -94,6 +95,19 @@ public function uninstallData(OutputInterface $output, array $modules)
$this->getPatchApplier()->revertDataPatches($module);
}
}

/**
* Checks wether auth.json exists in the Magento root.
* @throws FileNotFoundException when auth.json is not found with a reference to the developer documentation.
*/
private function failOnMissingAuthJson()
{
$auth_json_path = BP . DIRECTORY_SEPARATOR . 'auth.json';
if (!file_exists($auth_json_path)) {
$error_message = sprintf('auth.json at %s could not be found. Refer to https://devdocs.magento.com/guides/v2.4/install-gde/prereq/dev_install.html#authentication-file how to install this file.', $auth_json_path);
throw new FileNotFoundException($error_message);
}
}
Comment on lines +103 to +110
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure it's ok to make the auth.json mandatory? I don't think so, as we might set the credentials globally.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have set my auth.json globally, via ~/.composer/auth.json and that works fine when a manual ~ composer update or ~ composer remove xxx is run. But when this composer sub process is started up, via the ~ bin/magento module:uninstall it doesn't read from ~/.composer/auth.json for whatever reason, which then leads to the bug as is set out in the related issue as it prompts for the password behind the scenes. It only continues on when the data is present in the auth.json file.

I've made a dummy repo here of the plugin that demonstrates the issue. https://github.com/tschallacka/mage2-dummy-test

When there is an auth.json in the root it runs fine, as is highlighted in my blog post. If there is no auth.json in the root, it hangs and gives issues.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like the issue is related to incorrect composer usage, so it's not reading the global auth.json file. The correct fix should fix this inconsistent behavior.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd be amenable to make a more comprehensive test if you could point me to where the wrapped composer instance tries to read auth.json and when it fails, if you have a better suggested course of action, to prevent the hanging screen i'm open. Just an error message like in my plugin perhaps?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know exactly where that code located, but it looks like the composer remove logic is here:

public function remove(array $packages)
{
$composerApplication = $this->composerApplicationFactory->create();
return $composerApplication->runComposerCommand(
[
'command' => 'remove',
'packages' => $packages,
'--no-update-with-dependencies' => true,
]
);
}

Please set the breakpoint on this code and debug deeper.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like the issue is related to incorrect composer usage, so it's not reading the global auth.json file. The correct fix should fix this inconsistent behavior.

totally agree, that composer should read auth.json anywhere

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ihor-sviziev if you read my blog post at https://blog.tschallacka.de/2021/05/binmagento-moduleuninstall-never.html you can follow my tracking process how I traced the composer path related to the output. I never delved into the actual process of composer itself as it takes so many twists and turns that after 15 minutes of pressing step into I still wasn't at the auth.json search steps. I must admit I kinda gave up.


/**
* Run 'composer remove' to remove code
Expand All @@ -104,6 +118,7 @@ public function uninstallData(OutputInterface $output, array $modules)
*/
public function uninstallCode(OutputInterface $output, array $modules)
{
$this->failOnMissingAuthJson();
$output->writeln('<info>Removing code from Magento codebase:</info>');
$packages = [];
/** @var \Magento\Framework\Module\PackageInfo $packageInfo */
Expand Down