Repository: meltano/meltano

Issue:
Proposed: Should we add explicit `virtualenv` dependency
Follows from:

- https://github.com/meltano/meltano/issues/6882

We used to recommend _first_ installing `virtualenv`, then using `virtualenv` to install Meltano. This meant that Meltano was able to use `virtualenv` for plugin installation even without any explicit dependency declaration.

Today, if the user installs with `pipx`, then they also get `virtualenv` installed, since `pipx` ships with `virtualenv`.

Question: Should we just create an explicit `virtualenv` dependency so we can be sure it is available during plugin installation?

A valid scenario where `pip` would be fine for Meltano installation would be on a new+dedicated docker image. Presumably, that would be a safe time to install with `pip` and skip `pipx` installation - without requiring virtualenv isolation for Meltano itself. However, even in those cases, Meltano still needs `virtualenv` for plugin installation, and plugin installations would likely fail unless the image already contains `virtualenv` installed.



Discussion:
From the `virtualenv` docs:

<blockquote>

<p><code class="docutils literal notranslate"><span class="pre">virtualenv</span></code> is a tool to create isolated Python environments. Since Python <code class="docutils literal notranslate"><span class="pre">3.3</span></code>, a subset of it has been
integrated into the standard library under the <a class="reference external" href="https://docs.python.org/3/library/venv.html">venv module</a>. The
<code class="docutils literal notranslate"><span class="pre">venv</span></code> module does not offer all features of this library, to name just a few more prominent:</p>

<ul class="simple">
<li><p>is slower (by not having the <code class="docutils literal notranslate"><span class="pre">app-data</span></code> seed method),</p></li>
<li><p>is not as extendable,</p></li>
<li><p>cannot create virtual environments for arbitrarily installed python versions (and automatically discover these),</p></li>
<li><p>is not upgrade-able via <a class="reference external" href="https://pip.pypa.io/en/stable/installing/">pip</a>,</p></li>
<li><p>does not have as rich programmatic API (describe virtual environments without creating them).</p></li>
</ul>

</blockquote>

I'm sold 😍 
In addition to adding `virtualenv` as a dependency, we should also use its API in Meltano's venv service rather than using a subprocess to run `python -m venv`. This should let us gain the purported performance benefits. 

Resolving patch:
diff --git a/src/meltano/core/venv_service.py b/src/meltano/core/venv_service.py
--- a/src/meltano/core/venv_service.py
+++ b/src/meltano/core/venv_service.py
@@ -227,7 +227,10 @@ async def create(self) -> Process:
         """
         logger.debug(f"Creating virtual environment for '{self.namespace}/{self.name}'")
         try:
-            return await exec_async(sys.executable, "-m", "venv", str(self.venv))
+            return await exec_async(
+                str(Path(sys.executable).parent / "virtualenv"),
+                str(self.venv),
+            )
         except AsyncSubprocessError as err:
             raise AsyncSubprocessError(
                 f"Could not create the virtualenv for '{self.namespace}/{self.name}'",


Test patch: