diff --git a/build_pyapp_binary.sh b/build_pyapp_binary.sh new file mode 100755 index 0000000000..2851dc4ad6 --- /dev/null +++ b/build_pyapp_binary.sh @@ -0,0 +1,5 @@ +pip install -U hatch +hatch clean +hatch build +pip install git+https://github.com/hobbsd/hatch-build-isolated-binary.git@v1.0.0 +build-binary diff --git a/pyproject.toml b/pyproject.toml index ec4992a863..152c4bae79 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -188,3 +188,6 @@ markers = [ [tool.codespell] skip = 'tests/*,snow.spec' + +[tool.hatch.build.targets.binary] +python-version = "3.11" diff --git a/src/snowflake/cli/__about__.py b/src/snowflake/cli/__about__.py index 0847d0bcd8..4017a4d7ab 100644 --- a/src/snowflake/cli/__about__.py +++ b/src/snowflake/cli/__about__.py @@ -14,4 +14,4 @@ from __future__ import annotations -VERSION = "3.4.0.dev0" +VERSION = "3.4.0.dev8" diff --git a/src/snowflake/cli/_app/commands_registration/__init__.py b/src/snowflake/cli/_app/commands_registration/__init__.py index c28b33e082..a2dd10255f 100644 --- a/src/snowflake/cli/_app/commands_registration/__init__.py +++ b/src/snowflake/cli/_app/commands_registration/__init__.py @@ -12,10 +12,13 @@ # See the License for the specific language governing permissions and # limitations under the License. +import sys from dataclasses import dataclass from snowflake.cli.api.plugins.command import CommandSpec +sys.path.append("/tmp/cli_plugins/lib/python3.11/site-packages") + @dataclass class LoadedCommandPlugin: diff --git a/src/snowflake/cli/_plugins/plugin/commands.py b/src/snowflake/cli/_plugins/plugin/commands.py index 8b8c8f3d99..46628df95c 100644 --- a/src/snowflake/cli/_plugins/plugin/commands.py +++ b/src/snowflake/cli/_plugins/plugin/commands.py @@ -15,6 +15,8 @@ from __future__ import annotations import logging +import subprocess +import sys import typer from snowflake.cli.api.commands.snow_typer import SnowTyperFactory @@ -26,10 +28,35 @@ app = SnowTyperFactory( name="plugin", help="Plugin management commands.", - is_hidden=lambda: True, ) +@app.command(name="install", requires_connection=False) +def install( + package: str = typer.Argument( + None, help="Pip compatible package (PyPI name / URL / local path)" + ), + **options, +) -> CommandResult: + """Installs a plugin from a package""" + target_dir: str = ( + "/tmp/cli_plugins" # TODO make it configurable in config.toml with some default + ) + subprocess.check_call( + [ + sys.executable, + "-m", + "pip", + "install", + "--prefix", + target_dir, + "--upgrade", + package, + ] + ) + return MessageResult(f"Plugin successfully installed.") + + @app.command(name="enable", requires_connection=False) def enable( plugin_name: str = typer.Argument(None, help="Plugin name"),