Repository: repobee/repobee (language: python)

Issue:
Upgrade to v3.7.0 not happy with existing plugins
To upgrade from v3.5.0 I re-ran the installer script for Zsh from the homepage (https://repobee.org/). Install script seems to run fine. I get this feedback for a version request:

```zsh
% repobee -v          
exception was raised before pre-initialization was complete. This is usually due to incorrect settings. Try running the `verify-settings` command and see if the problem can be resolved. If all fails, please open an issue at https://github.com/repobee/repobee/issues/new and supply the stack trace below.
[ERROR] PluginLoadError: failed to load plugin module sanitizer
[ERROR] RepoBee exited unexpectedly. Please visit the FAQ to try to resolve the problem: https://repobee.readthedocs.io/en/stable/faq.html
```

Running `verify-settings` did not work either (same feedback as above).

Removing the all plugins from block from `~/.repobee/installed_plugins.json` resolved the issue for me:

```json
"_metainfo": {
        "active_plugins": [
            "sanitizer",
            "csvgrades"
        ]
    }
```

Is it best to nuke the .repobee folder before upgrading? Perhaps we need to modify the homepage to include advice for upgrading.

Cheers!


Discussion / hints:
Note, I probably should have tried `repobee manage upgrade` first, but I guess others might make this blunder :-)
The problem here is likely that the install script nuked the virtual environment, but didn't nuke the installed plugins file. While you're not supposed to use the install script to upgrade, it's intended to be a last resort to fix a failing installation. So, it should nuke all preexisting state in the install directory, so there might be a bug there.

Of course `repobee manage upgrade` is the intended way to upgrade, but perhaps that should be more front-and-center on the website and the user guide (in fact, I think it isn't even mentioned in the user guide).
On a side note, the [FAQ](https://docs.repobee.org/en/stable/faq.html#repobee-crashes) has a bunch of tips for how to fix a broken install. When a plugin breaks, the easiest way to get back to a working installation is to run `repobee --no-plugins plugin uninstall` and uninstall the offending plugin.

Fix patch:
diff --git a/scripts/install.sh b/scripts/install.sh
index e074b43f..052f67b2 100755
--- a/scripts/install.sh
+++ b/scripts/install.sh
@@ -81,9 +81,9 @@ function install_repobee() {
     REPOBEE_INSTALL_DIR="$REPOBEE_INSTALL_DIR" pip_install_quiet_failfast "$repobee_pip_uri"
     create_repobee_executable
 
-    if [ ! -f "$REPOBEE_INSTALLED_PLUGINS" ]; then
-        echo "{}" > "$REPOBEE_INSTALLED_PLUGINS"
-    fi
+    # we intentionally clobber the installed plugins file to fix installations
+    # broken by failing or missing plugins
+    echo "{}" > "$REPOBEE_INSTALLED_PLUGINS"
 
     echo "Checking PATH"
     pip_install_quiet_failfast userpath


Test patch:
diff --git a/tests/new_integration_tests/test_dist.py b/tests/new_integration_tests/test_dist.py
index 1781b2d3..f8a26450 100644
--- a/tests/new_integration_tests/test_dist.py
+++ b/tests/new_integration_tests/test_dist.py
@@ -41,6 +41,25 @@ def test_install_dist(install_dir):
     assert (install_dir / "completion" / "bash_completion.sh").is_file()
 
 
+def test_install_dist_resets_installed_plugins(install_dir):
+    """Test that the install script resets the installed_plugins.json file.
+    This is important as running the install script on an existing installation
+    may wipe the virtual environment depending on the virtual environment
+    backend, thus removing any installed plugins.
+    """
+    # arrange
+    installed_plugins = disthelpers.get_installed_plugins_path()
+    original_content = installed_plugins.read_bytes()
+    installed_plugins.write_text("absolute garbage")
+
+    # act
+    run_install_script(install_dir)
+
+    # assert
+    reset_content = installed_plugins.read_bytes()
+    assert reset_content == original_content
+
+
 class TestPluginInstall:
     """Tests for the ``plugin install`` command.
 
@@ -488,14 +507,17 @@ def install_dir():
     """Install the RepoBee distribution into a temporary directory."""
     with tempfile.TemporaryDirectory() as install_dirname:
         install_dir = pathlib.Path(install_dirname)
-        env = dict(os.environ)
-        env["REPOBEE_INSTALL_DIR"] = str(install_dir)
+        run_install_script(install_dir)
+        yield install_dir
 
-        proc = subprocess.Popen(str(INSTALL_SCRIPT), env=env)
-        proc.communicate("n")  # 'n' in answering whether or not to add to PATH
-        assert proc.returncode == 0
 
-        yield install_dir
+def run_install_script(install_dir: pathlib.Path) -> None:
+    env = dict(os.environ)
+    env["REPOBEE_INSTALL_DIR"] = str(install_dir)
+
+    proc = subprocess.Popen(str(INSTALL_SCRIPT), env=env)
+    proc.communicate("n")  # 'n' in answering whether or not to add to PATH
+    assert proc.returncode == 0
 
 
 @pytest.fixture(scope="session")