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

Add Archive Bundler #72

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions src/poetry_plugin_bundle/bundlers/archive_bundler.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
from __future__ import annotations

import tempfile

from pathlib import Path
from typing import TYPE_CHECKING

from cleo.io.null_io import NullIO

from poetry_plugin_bundle.bundlers.venv_bundler import VenvBundler


if TYPE_CHECKING:
from cleo.io.io import IO
from poetry.poetry import Poetry
from typing_extensions import Self


class ArchiveBundler(VenvBundler):
name = "archive"

def __init__(self) -> None:
super().__init__()
self._ar_path = Path("output")
self._format = "zip"
self._site_packages_only = False

def set_path(self, path: Path) -> Self:
self._ar_path = path
return self

def set_format(self, ar_format: str) -> Self:
self._format = ar_format

return self

def set_site_packages_only(self, value: bool) -> Self:
self._site_packages_only = value

return self

def bundle(self, poetry: Poetry, io: IO) -> bool:
with tempfile.TemporaryDirectory() as temp_dir:
self._path = Path(temp_dir)

if not super().bundle(poetry, NullIO()):
return False

import shutil

dir_path = self._path
if self._site_packages_only:
dir_path = dir_path.joinpath("Lib", "site-packages")

self._write(
io, f"Creating archive {self._ar_path} using format {self._format}"
)

try:
shutil.make_archive(str(self._ar_path), self._format, dir_path)
except (ValueError, PermissionError) as e:
self._write(io, f"Error while creating archive: <red>{e!s}</red>")
return False

return True
2 changes: 2 additions & 0 deletions src/poetry_plugin_bundle/bundlers/bundler_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@

class BundlerManager:
def __init__(self) -> None:
from poetry_plugin_bundle.bundlers.archive_bundler import ArchiveBundler
from poetry_plugin_bundle.bundlers.venv_bundler import VenvBundler

self._bundler_classes: dict[str, type[Bundler]] = {}

# Register default bundlers
self.register_bundler_class(VenvBundler)
self.register_bundler_class(ArchiveBundler)

def bundler(self, name: str) -> Bundler:
if name.lower() not in self._bundler_classes:
Expand Down
64 changes: 64 additions & 0 deletions src/poetry_plugin_bundle/console/commands/bundle/archive.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
from __future__ import annotations

from pathlib import Path
from typing import TYPE_CHECKING

from cleo.helpers import argument
from cleo.helpers import option

from poetry_plugin_bundle.console.commands.bundle.bundle_command import BundleCommand


if TYPE_CHECKING:
from poetry_plugin_bundle.bundlers.archive_bundler import ArchiveBundler


class BundleArchiveCommand(BundleCommand):
name = "bundle archive"
description = "Bundle the current project into an archive (.zip, .tar)"

arguments = [argument("path", "Path to save archive in")] # noqa: RUF012

options = [ # noqa: RUF012
*BundleCommand._group_dependency_options(),
option(
"python",
"p",
"The Python executable to use to create the virtual environment. "
"Defaults to the current Python executable",
flag=False,
value_required=True,
),
option(
"clear",
None,
"Clear the existing virtual environment if it exists. ",
flag=True,
),
option(
"format",
"f",
"Archive format as supported by shutil.make_archive",
flag=False,
default="zip",
),
option(
"site-packages-only",
None,
"Only archive the Lib/site-packages directory",
flag=True,
),
]

bundler_name = "archive"

def configure_bundler(
self, bundler: ArchiveBundler # type: ignore[override]
) -> None:
bundler.set_path(Path(self.argument("path")))
bundler.set_executable(self.option("python"))
bundler.set_remove(self.option("clear"))
bundler.set_activated_groups(self.activated_groups)

bundler.set_format(self.option("format"))
bundler.set_site_packages_only(self.option("site-packages-only"))
3 changes: 2 additions & 1 deletion src/poetry_plugin_bundle/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from cleo.events.console_events import COMMAND
from poetry.plugins.application_plugin import ApplicationPlugin

from poetry_plugin_bundle.console.commands.bundle.archive import BundleArchiveCommand
from poetry_plugin_bundle.console.commands.bundle.venv import BundleVenvCommand


Expand All @@ -19,7 +20,7 @@
class BundleApplicationPlugin(ApplicationPlugin):
@property
def commands(self) -> list[type[Command]]:
return [BundleVenvCommand]
return [BundleVenvCommand, BundleArchiveCommand]

def activate(self, application: Application) -> None:
assert application.event_dispatcher
Expand Down