We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Meltano remove lock file bug
From #5977 I was removing an installed plugin and got this on the command line:

```
❯ meltano remove orchestrator airflow
2022-06-02T15:20:50.385299Z [info     ] Environment 'dev' is active

Removing orchestrator 'airflow'...

Reset orchestrator 'airflow' plugin settings in the system database
Removed orchestrator 'airflow' from meltano.yml
Removed orchestrator 'airflow' from .meltano/orchestrators
Could not find orchestrator 'airflow' in /Users/taylormurphy/Documents/Projects/dev/meltano/addfromhub/plugins/orchestrators/airflow--original.lock to remove
```

In my `plugins/` folder I still have:

```
plugins
  files/
     airflow--meltano.lock
  orchestrators/
     airflow--apache.lock
```

@edgarrmondragon cc @aaronsteers 

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/meltano/core/plugin_location_remove.py`
Content:
```
1 """Defines PluginLocationRemoveStatus, PluginLocationRemoveManager, DbRemoveManager, MeltanoYmlRemoveManager and InstallationRemoveManager."""
2 
3 import shutil
4 from abc import ABC, abstractmethod
5 from enum import Enum
6 
7 import sqlalchemy
8 
9 from meltano.core.db import project_engine
10 from meltano.core.plugin.error import PluginNotFoundError
11 from meltano.core.plugin.project_plugin import ProjectPlugin
12 from meltano.core.plugin.settings_service import PluginSettingsService
13 from meltano.core.project_plugins_service import ProjectPluginsService
14 
15 from .project import Project
16 from .settings_store import SettingValueStore
17 
18 
19 class PluginLocationRemoveStatus(Enum):
20     """Possible remove statuses."""
21 
22     REMOVED = "removed"
23     ERROR = "error"
24     NOT_FOUND = "not found"
25 
26 
27 class PluginLocationRemoveManager(ABC):
28     """Handle removal of a plugin from a given location."""
29 
30     def __init__(self, plugin: ProjectPlugin, location):
31         """Construct a PluginLocationRemoveManager instance.
32 
33         Args:
34             plugin: The plugin to remove.
35             location: The location to remove the plugin from.
36         """
37         self.plugin = plugin
38         self.plugin_descriptor = f"{plugin.type.descriptor} '{plugin.name}'"
39         self.location = location
40         self.remove_status = None
41         self.remove_message = None
42 
43     @abstractmethod
44     def remove(self):
45         """Abstract remove method."""
46         pass
47 
48     @property
49     def plugin_removed(self) -> bool:
50         """Wether or not the plugin was successfully removed.
51 
52         Returns:
53             True if the plugin was successfully removed, False otherwise.
54         """
55         return self.remove_status is PluginLocationRemoveStatus.REMOVED
56 
57     @property
58     def plugin_not_found(self) -> bool:
59         """Wether or not the plugin was not found to remove.
60 
61         Returns:
62             True if the plugin was not found, False otherwise.
63         """
64         return self.remove_status is PluginLocationRemoveStatus.NOT_FOUND
65 
66     @property
67     def plugin_error(self) -> bool:
68         """Wether or not an error was encountered the plugin removal process.
69 
70         Returns:
71             True if an error was encountered, False otherwise.
72         """
73         return self.remove_status is PluginLocationRemoveStatus.ERROR
74 
75 
76 class DbRemoveManager(PluginLocationRemoveManager):
77     """Handle removal of a plugin's settings from the system database `plugin_settings` table."""
78 
79     def __init__(self, plugin, project):
80         """Construct a DbRemoveManager instance.
81 
82         Args:
83             plugin: The plugin to remove.
84             project: The Meltano project.
85         """
86         super().__init__(plugin, "system database")
87         self.plugins_settings_service = PluginSettingsService(project, plugin)
88         self.session = project_engine(project)[1]
89 
90     def remove(self):
91         """Remove the plugin's settings from the system database `plugin_settings` table.
92 
93         Returns:
94             The remove status.
95         """
96         session = self.session()
97         try:
98             self.plugins_settings_service.reset(
99                 store=SettingValueStore.DB, session=session
100             )
101         except sqlalchemy.exc.OperationalError as err:
102             self.remove_status = PluginLocationRemoveStatus.ERROR
103             self.message = err.orig
104             return
105 
106         self.remove_status = PluginLocationRemoveStatus.REMOVED
107 
108 
109 class MeltanoYmlRemoveManager(PluginLocationRemoveManager):
110     """Handle removal of a plugin from `meltano.yml`."""
111 
112     def __init__(self, plugin, project: Project):
113         """Construct a MeltanoYmlRemoveManager instance.
114 
115         Args:
116             plugin: The plugin to remove.
117             project: The Meltano project.
118         """
119         super().__init__(plugin, str(project.meltanofile.relative_to(project.root)))
120         self.project_plugins_service = ProjectPluginsService(project)
121 
122     def remove(self):
123         """Remove the plugin from `meltano.yml`."""
124         try:
125             self.project_plugins_service.remove_from_file(self.plugin)
126         except PluginNotFoundError:
127             self.remove_status = PluginLocationRemoveStatus.NOT_FOUND
128             return
129         except OSError as err:
130             self.remove_status = PluginLocationRemoveStatus.ERROR
131             self.message = err.strerror
132             return
133 
134         self.remove_status = PluginLocationRemoveStatus.REMOVED
135 
136 
137 class LockedDefinitionRemoveManager(PluginLocationRemoveManager):
138     """Handle removal of a plugin locked definition from `plugins/`."""
139 
140     def __init__(self, plugin, project: Project):
141         """Construct a LockedDefinitionRemoveManager instance.
142 
143         Args:
144             plugin: The plugin to remove.
145             project: The Meltano project.
146         """
147         path = project.plugin_lock_path(plugin.type, plugin.name, plugin.variant)
148         super().__init__(plugin, str(path))
149         self.path = path
150 
151     def remove(self):
152         """Remove the plugin from `plugins/`."""
153         try:
154             self.path.unlink()
155         except FileNotFoundError:
156             self.remove_status = PluginLocationRemoveStatus.NOT_FOUND
157             return
158         except OSError as err:
159             self.remove_status = PluginLocationRemoveStatus.ERROR
160             self.message = err.strerror
161             return
162 
163         self.remove_status = PluginLocationRemoveStatus.REMOVED
164 
165 
166 class InstallationRemoveManager(PluginLocationRemoveManager):
167     """Handle removal of a plugin installation from `.meltano`."""
168 
169     def __init__(self, plugin, project: Project):
170         """Construct a InstallationRemoveManager instance.
171 
172         Args:
173             plugin: The plugin to remove.
174             project: The Meltano project.
175         """
176         path = project.plugin_dir(plugin, make_dirs=False)
177         super().__init__(plugin, str(path.parent.relative_to(project.root)))
178         self.path = path
179 
180     def remove(self):
181         """Remove the plugin installation from `.meltano`."""
182         if not self.path.exists():
183             self.remove_status = PluginLocationRemoveStatus.NOT_FOUND
184             self.message = f"{self.plugin_descriptor} not found in {self.path.parent}"
185             return
186 
187         try:
188             shutil.rmtree(self.path)
189         except OSError as err:
190             self.remove_status = PluginLocationRemoveStatus.ERROR
191             self.message = err.strerror
192             return
193 
194         self.remove_status = PluginLocationRemoveStatus.REMOVED
195
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/meltano/core/plugin_location_remove.py b/src/meltano/core/plugin_location_remove.py
--- a/src/meltano/core/plugin_location_remove.py
+++ b/src/meltano/core/plugin_location_remove.py
@@ -144,21 +144,28 @@
             plugin: The plugin to remove.
             project: The Meltano project.
         """
-        path = project.plugin_lock_path(plugin.type, plugin.name, plugin.variant)
-        super().__init__(plugin, str(path))
-        self.path = path
+        lockfile_dir = project.root_plugins_dir(plugin.type)
+        glob_expr = f"{plugin.name}*.lock"
+        super().__init__(
+            plugin,
+            str(lockfile_dir.relative_to(project.root).joinpath(glob_expr)),
+        )
+
+        self.paths = list(lockfile_dir.glob(glob_expr))
 
     def remove(self):
         """Remove the plugin from `plugins/`."""
-        try:
-            self.path.unlink()
-        except FileNotFoundError:
+        if not self.paths:
             self.remove_status = PluginLocationRemoveStatus.NOT_FOUND
             return
-        except OSError as err:
-            self.remove_status = PluginLocationRemoveStatus.ERROR
-            self.message = err.strerror
-            return
+
+        for path in self.paths:
+            try:
+                path.unlink()
+            except OSError as err:
+                self.remove_status = PluginLocationRemoveStatus.ERROR
+                self.message = err.strerror
+                return
 
         self.remove_status = PluginLocationRemoveStatus.REMOVED

{"golden_diff": "diff --git a/src/meltano/core/plugin_location_remove.py b/src/meltano/core/plugin_location_remove.py\n--- a/src/meltano/core/plugin_location_remove.py\n+++ b/src/meltano/core/plugin_location_remove.py\n@@ -144,21 +144,28 @@\n             plugin: The plugin to remove.\n             project: The Meltano project.\n         \"\"\"\n-        path = project.plugin_lock_path(plugin.type, plugin.name, plugin.variant)\n-        super().__init__(plugin, str(path))\n-        self.path = path\n+        lockfile_dir = project.root_plugins_dir(plugin.type)\n+        glob_expr = f\"{plugin.name}*.lock\"\n+        super().__init__(\n+            plugin,\n+            str(lockfile_dir.relative_to(project.root).joinpath(glob_expr)),\n+        )\n+\n+        self.paths = list(lockfile_dir.glob(glob_expr))\n \n     def remove(self):\n         \"\"\"Remove the plugin from `plugins/`.\"\"\"\n-        try:\n-            self.path.unlink()\n-        except FileNotFoundError:\n+        if not self.paths:\n             self.remove_status = PluginLocationRemoveStatus.NOT_FOUND\n             return\n-        except OSError as err:\n-            self.remove_status = PluginLocationRemoveStatus.ERROR\n-            self.message = err.strerror\n-            return\n+\n+        for path in self.paths:\n+            try:\n+                path.unlink()\n+            except OSError as err:\n+                self.remove_status = PluginLocationRemoveStatus.ERROR\n+                self.message = err.strerror\n+                return\n \n         self.remove_status = PluginLocationRemoveStatus.REMOVED\n", "issue": "Meltano remove lock file bug\nFrom #5977 I was removing an installed plugin and got this on the command line:\r\n\r\n```\r\n\u276f meltano remove orchestrator airflow\r\n2022-06-02T15:20:50.385299Z [info     ] Environment 'dev' is active\r\n\r\nRemoving orchestrator 'airflow'...\r\n\r\nReset orchestrator 'airflow' plugin settings in the system database\r\nRemoved orchestrator 'airflow' from meltano.yml\r\nRemoved orchestrator 'airflow' from .meltano/orchestrators\r\nCould not find orchestrator 'airflow' in /Users/taylormurphy/Documents/Projects/dev/meltano/addfromhub/plugins/orchestrators/airflow--original.lock to remove\r\n```\r\n\r\nIn my `plugins/` folder I still have:\r\n\r\n```\r\nplugins\r\n  files/\r\n     airflow--meltano.lock\r\n  orchestrators/\r\n     airflow--apache.lock\r\n```\r\n\r\n@edgarrmondragon cc @aaronsteers \n", "before_files": [{"content": "\"\"\"Defines PluginLocationRemoveStatus, PluginLocationRemoveManager, DbRemoveManager, MeltanoYmlRemoveManager and InstallationRemoveManager.\"\"\"\n\nimport shutil\nfrom abc import ABC, abstractmethod\nfrom enum import Enum\n\nimport sqlalchemy\n\nfrom meltano.core.db import project_engine\nfrom meltano.core.plugin.error import PluginNotFoundError\nfrom meltano.core.plugin.project_plugin import ProjectPlugin\nfrom meltano.core.plugin.settings_service import PluginSettingsService\nfrom meltano.core.project_plugins_service import ProjectPluginsService\n\nfrom .project import Project\nfrom .settings_store import SettingValueStore\n\n\nclass PluginLocationRemoveStatus(Enum):\n    \"\"\"Possible remove statuses.\"\"\"\n\n    REMOVED = \"removed\"\n    ERROR = \"error\"\n    NOT_FOUND = \"not found\"\n\n\nclass PluginLocationRemoveManager(ABC):\n    \"\"\"Handle removal of a plugin from a given location.\"\"\"\n\n    def __init__(self, plugin: ProjectPlugin, location):\n        \"\"\"Construct a PluginLocationRemoveManager instance.\n\n        Args:\n            plugin: The plugin to remove.\n            location: The location to remove the plugin from.\n        \"\"\"\n        self.plugin = plugin\n        self.plugin_descriptor = f\"{plugin.type.descriptor} '{plugin.name}'\"\n        self.location = location\n        self.remove_status = None\n        self.remove_message = None\n\n    @abstractmethod\n    def remove(self):\n        \"\"\"Abstract remove method.\"\"\"\n        pass\n\n    @property\n    def plugin_removed(self) -> bool:\n        \"\"\"Wether or not the plugin was successfully removed.\n\n        Returns:\n            True if the plugin was successfully removed, False otherwise.\n        \"\"\"\n        return self.remove_status is PluginLocationRemoveStatus.REMOVED\n\n    @property\n    def plugin_not_found(self) -> bool:\n        \"\"\"Wether or not the plugin was not found to remove.\n\n        Returns:\n            True if the plugin was not found, False otherwise.\n        \"\"\"\n        return self.remove_status is PluginLocationRemoveStatus.NOT_FOUND\n\n    @property\n    def plugin_error(self) -> bool:\n        \"\"\"Wether or not an error was encountered the plugin removal process.\n\n        Returns:\n            True if an error was encountered, False otherwise.\n        \"\"\"\n        return self.remove_status is PluginLocationRemoveStatus.ERROR\n\n\nclass DbRemoveManager(PluginLocationRemoveManager):\n    \"\"\"Handle removal of a plugin's settings from the system database `plugin_settings` table.\"\"\"\n\n    def __init__(self, plugin, project):\n        \"\"\"Construct a DbRemoveManager instance.\n\n        Args:\n            plugin: The plugin to remove.\n            project: The Meltano project.\n        \"\"\"\n        super().__init__(plugin, \"system database\")\n        self.plugins_settings_service = PluginSettingsService(project, plugin)\n        self.session = project_engine(project)[1]\n\n    def remove(self):\n        \"\"\"Remove the plugin's settings from the system database `plugin_settings` table.\n\n        Returns:\n            The remove status.\n        \"\"\"\n        session = self.session()\n        try:\n            self.plugins_settings_service.reset(\n                store=SettingValueStore.DB, session=session\n            )\n        except sqlalchemy.exc.OperationalError as err:\n            self.remove_status = PluginLocationRemoveStatus.ERROR\n            self.message = err.orig\n            return\n\n        self.remove_status = PluginLocationRemoveStatus.REMOVED\n\n\nclass MeltanoYmlRemoveManager(PluginLocationRemoveManager):\n    \"\"\"Handle removal of a plugin from `meltano.yml`.\"\"\"\n\n    def __init__(self, plugin, project: Project):\n        \"\"\"Construct a MeltanoYmlRemoveManager instance.\n\n        Args:\n            plugin: The plugin to remove.\n            project: The Meltano project.\n        \"\"\"\n        super().__init__(plugin, str(project.meltanofile.relative_to(project.root)))\n        self.project_plugins_service = ProjectPluginsService(project)\n\n    def remove(self):\n        \"\"\"Remove the plugin from `meltano.yml`.\"\"\"\n        try:\n            self.project_plugins_service.remove_from_file(self.plugin)\n        except PluginNotFoundError:\n            self.remove_status = PluginLocationRemoveStatus.NOT_FOUND\n            return\n        except OSError as err:\n            self.remove_status = PluginLocationRemoveStatus.ERROR\n            self.message = err.strerror\n            return\n\n        self.remove_status = PluginLocationRemoveStatus.REMOVED\n\n\nclass LockedDefinitionRemoveManager(PluginLocationRemoveManager):\n    \"\"\"Handle removal of a plugin locked definition from `plugins/`.\"\"\"\n\n    def __init__(self, plugin, project: Project):\n        \"\"\"Construct a LockedDefinitionRemoveManager instance.\n\n        Args:\n            plugin: The plugin to remove.\n            project: The Meltano project.\n        \"\"\"\n        path = project.plugin_lock_path(plugin.type, plugin.name, plugin.variant)\n        super().__init__(plugin, str(path))\n        self.path = path\n\n    def remove(self):\n        \"\"\"Remove the plugin from `plugins/`.\"\"\"\n        try:\n            self.path.unlink()\n        except FileNotFoundError:\n            self.remove_status = PluginLocationRemoveStatus.NOT_FOUND\n            return\n        except OSError as err:\n            self.remove_status = PluginLocationRemoveStatus.ERROR\n            self.message = err.strerror\n            return\n\n        self.remove_status = PluginLocationRemoveStatus.REMOVED\n\n\nclass InstallationRemoveManager(PluginLocationRemoveManager):\n    \"\"\"Handle removal of a plugin installation from `.meltano`.\"\"\"\n\n    def __init__(self, plugin, project: Project):\n        \"\"\"Construct a InstallationRemoveManager instance.\n\n        Args:\n            plugin: The plugin to remove.\n            project: The Meltano project.\n        \"\"\"\n        path = project.plugin_dir(plugin, make_dirs=False)\n        super().__init__(plugin, str(path.parent.relative_to(project.root)))\n        self.path = path\n\n    def remove(self):\n        \"\"\"Remove the plugin installation from `.meltano`.\"\"\"\n        if not self.path.exists():\n            self.remove_status = PluginLocationRemoveStatus.NOT_FOUND\n            self.message = f\"{self.plugin_descriptor} not found in {self.path.parent}\"\n            return\n\n        try:\n            shutil.rmtree(self.path)\n        except OSError as err:\n            self.remove_status = PluginLocationRemoveStatus.ERROR\n            self.message = err.strerror\n            return\n\n        self.remove_status = PluginLocationRemoveStatus.REMOVED\n", "path": "src/meltano/core/plugin_location_remove.py"}], "after_files": [{"content": "\"\"\"Defines PluginLocationRemoveStatus, PluginLocationRemoveManager, DbRemoveManager, MeltanoYmlRemoveManager and InstallationRemoveManager.\"\"\"\n\nimport shutil\nfrom abc import ABC, abstractmethod\nfrom enum import Enum\n\nimport sqlalchemy\n\nfrom meltano.core.db import project_engine\nfrom meltano.core.plugin.error import PluginNotFoundError\nfrom meltano.core.plugin.project_plugin import ProjectPlugin\nfrom meltano.core.plugin.settings_service import PluginSettingsService\nfrom meltano.core.project_plugins_service import ProjectPluginsService\n\nfrom .project import Project\nfrom .settings_store import SettingValueStore\n\n\nclass PluginLocationRemoveStatus(Enum):\n    \"\"\"Possible remove statuses.\"\"\"\n\n    REMOVED = \"removed\"\n    ERROR = \"error\"\n    NOT_FOUND = \"not found\"\n\n\nclass PluginLocationRemoveManager(ABC):\n    \"\"\"Handle removal of a plugin from a given location.\"\"\"\n\n    def __init__(self, plugin: ProjectPlugin, location):\n        \"\"\"Construct a PluginLocationRemoveManager instance.\n\n        Args:\n            plugin: The plugin to remove.\n            location: The location to remove the plugin from.\n        \"\"\"\n        self.plugin = plugin\n        self.plugin_descriptor = f\"{plugin.type.descriptor} '{plugin.name}'\"\n        self.location = location\n        self.remove_status = None\n        self.remove_message = None\n\n    @abstractmethod\n    def remove(self):\n        \"\"\"Abstract remove method.\"\"\"\n        pass\n\n    @property\n    def plugin_removed(self) -> bool:\n        \"\"\"Wether or not the plugin was successfully removed.\n\n        Returns:\n            True if the plugin was successfully removed, False otherwise.\n        \"\"\"\n        return self.remove_status is PluginLocationRemoveStatus.REMOVED\n\n    @property\n    def plugin_not_found(self) -> bool:\n        \"\"\"Wether or not the plugin was not found to remove.\n\n        Returns:\n            True if the plugin was not found, False otherwise.\n        \"\"\"\n        return self.remove_status is PluginLocationRemoveStatus.NOT_FOUND\n\n    @property\n    def plugin_error(self) -> bool:\n        \"\"\"Wether or not an error was encountered the plugin removal process.\n\n        Returns:\n            True if an error was encountered, False otherwise.\n        \"\"\"\n        return self.remove_status is PluginLocationRemoveStatus.ERROR\n\n\nclass DbRemoveManager(PluginLocationRemoveManager):\n    \"\"\"Handle removal of a plugin's settings from the system database `plugin_settings` table.\"\"\"\n\n    def __init__(self, plugin, project):\n        \"\"\"Construct a DbRemoveManager instance.\n\n        Args:\n            plugin: The plugin to remove.\n            project: The Meltano project.\n        \"\"\"\n        super().__init__(plugin, \"system database\")\n        self.plugins_settings_service = PluginSettingsService(project, plugin)\n        self.session = project_engine(project)[1]\n\n    def remove(self):\n        \"\"\"Remove the plugin's settings from the system database `plugin_settings` table.\n\n        Returns:\n            The remove status.\n        \"\"\"\n        session = self.session()\n        try:\n            self.plugins_settings_service.reset(\n                store=SettingValueStore.DB, session=session\n            )\n        except sqlalchemy.exc.OperationalError as err:\n            self.remove_status = PluginLocationRemoveStatus.ERROR\n            self.message = err.orig\n            return\n\n        self.remove_status = PluginLocationRemoveStatus.REMOVED\n\n\nclass MeltanoYmlRemoveManager(PluginLocationRemoveManager):\n    \"\"\"Handle removal of a plugin from `meltano.yml`.\"\"\"\n\n    def __init__(self, plugin, project: Project):\n        \"\"\"Construct a MeltanoYmlRemoveManager instance.\n\n        Args:\n            plugin: The plugin to remove.\n            project: The Meltano project.\n        \"\"\"\n        super().__init__(plugin, str(project.meltanofile.relative_to(project.root)))\n        self.project_plugins_service = ProjectPluginsService(project)\n\n    def remove(self):\n        \"\"\"Remove the plugin from `meltano.yml`.\"\"\"\n        try:\n            self.project_plugins_service.remove_from_file(self.plugin)\n        except PluginNotFoundError:\n            self.remove_status = PluginLocationRemoveStatus.NOT_FOUND\n            return\n        except OSError as err:\n            self.remove_status = PluginLocationRemoveStatus.ERROR\n            self.message = err.strerror\n            return\n\n        self.remove_status = PluginLocationRemoveStatus.REMOVED\n\n\nclass LockedDefinitionRemoveManager(PluginLocationRemoveManager):\n    \"\"\"Handle removal of a plugin locked definition from `plugins/`.\"\"\"\n\n    def __init__(self, plugin, project: Project):\n        \"\"\"Construct a LockedDefinitionRemoveManager instance.\n\n        Args:\n            plugin: The plugin to remove.\n            project: The Meltano project.\n        \"\"\"\n        lockfile_dir = project.root_plugins_dir(plugin.type)\n        glob_expr = f\"{plugin.name}*.lock\"\n        super().__init__(\n            plugin,\n            str(lockfile_dir.relative_to(project.root).joinpath(glob_expr)),\n        )\n\n        self.paths = list(lockfile_dir.glob(glob_expr))\n\n    def remove(self):\n        \"\"\"Remove the plugin from `plugins/`.\"\"\"\n        if not self.paths:\n            self.remove_status = PluginLocationRemoveStatus.NOT_FOUND\n            return\n\n        for path in self.paths:\n            try:\n                path.unlink()\n            except OSError as err:\n                self.remove_status = PluginLocationRemoveStatus.ERROR\n                self.message = err.strerror\n                return\n\n        self.remove_status = PluginLocationRemoveStatus.REMOVED\n\n\nclass InstallationRemoveManager(PluginLocationRemoveManager):\n    \"\"\"Handle removal of a plugin installation from `.meltano`.\"\"\"\n\n    def __init__(self, plugin, project: Project):\n        \"\"\"Construct a InstallationRemoveManager instance.\n\n        Args:\n            plugin: The plugin to remove.\n            project: The Meltano project.\n        \"\"\"\n        path = project.plugin_dir(plugin, make_dirs=False)\n        super().__init__(plugin, str(path.parent.relative_to(project.root)))\n        self.path = path\n\n    def remove(self):\n        \"\"\"Remove the plugin installation from `.meltano`.\"\"\"\n        if not self.path.exists():\n            self.remove_status = PluginLocationRemoveStatus.NOT_FOUND\n            self.message = f\"{self.plugin_descriptor} not found in {self.path.parent}\"\n            return\n\n        try:\n            shutil.rmtree(self.path)\n        except OSError as err:\n            self.remove_status = PluginLocationRemoveStatus.ERROR\n            self.message = err.strerror\n            return\n\n        self.remove_status = PluginLocationRemoveStatus.REMOVED\n", "path": "src/meltano/core/plugin_location_remove.py"}]}