Skip to content
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

[5.x] Addon uninstallers #11057

Closed
wants to merge 1 commit into from
Closed

[5.x] Addon uninstallers #11057

wants to merge 1 commit into from

Conversation

jasonvarga
Copy link
Member

@jasonvarga jasonvarga commented Nov 5, 2024

This PR allows addons to run pre-removal or "uninstall" logic, letting them clean up after themselves.

If an addon has an Uninstall.php in their src directory, it's handle method will be run automatically.

my-addon
|-- src
|   |-- ServiceProvider.php
|   |-- Uninstall.php
|-- composer.json
<?php

namespace Me\MyAddon;

use Statamic\Extend\Uninstaller;
use Statamic\Facades\File;

class Uninstall extends Uninstaller
{
    public function handle()
    {
        File::delete(base_path('content/my-addon'));

        $this->output->writeln('Done!');
    }
}

A script will be need to be added to the project's composer.json. This will be added to the statamic/statamic skeleton so it will work for new Statamic sites.

    "scripts": {
        "pre-update-cmd": [
            "Statamic\\Console\\Composer\\Scripts::preUpdateCmd"
        ],
+       "pre-package-uninstall": [
+           "Statamic\\Console\\Composer\\Scripts::prePackageUninstall"
+       ]
    },

Naming is tough, but I went with "uninstall" because the convention is that you composer require a package, then you run artisan packagename:install to set it up. Here it's the opposite. You'd composer remove the addon, which would "uninstall" it just before it gets removed.

Closes statamic/ideas#1255

Copy link
Member

@duncanmcclean duncanmcclean left a comment

Choose a reason for hiding this comment

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

This works great for the addon I'm uninstalling (see the Importer stuffz has been uninstalled. line in the screenshot).

However, if the addon has any dependencies, like spatie/simple-excel in my example, it will error out due to the addon's ServiceProvider being missing because it's already been uninstalled.

CleanShot 2024-11-06 at 12 36 47

@jasonvarga
Copy link
Member Author

Shelving this for now. Can't figure out Composer's ordering logic.

Your importer package requires spatie/simple-excel so the dependency should get uninstalled first. It is removed first during the lockfile writing:

  - Removing openspout/openspout (v4.26.0)
  - Removing spatie/simple-excel (3.7.0)
  - Removing statamic/importer (v1.1.1)

But when it actually uninstalls it, it removes your package first, then spatie, then openspout. Don't know why.

When it gets to the spatie package, it fails in the artisan command because your service provider is still listed in bootstrap/cache/packages.php manifest.

The manifest is only updated later in the same composer process:

  - Removing openspout/openspout (v4.26.0)
Generating optimized autoload files
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover --ansi                              <--- here

When I was testing with my own package and dependencies it worked fine. I don't understand what's different.

So yeah, closing this for now but might pick it up again later.

@jasonvarga jasonvarga closed this Nov 7, 2024
@jasonvarga jasonvarga deleted the addon-uninstall branch November 7, 2024 19:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Give addons a way to clean up before they are removed
2 participants