Skip to content

helpers

flavor.commands.helpers

Helper management commands for the flavor CLI.

Functions

helper_build

helper_build(lang: str, force: bool) -> None

Build helper binaries from source.

Source code in flavor/commands/helpers.py
@helper_group.command("build")
@click.option(
    "--lang",
    type=click.Choice(["go", "rust", "all"], case_sensitive=False),
    default="all",
    help="Language to build helpers for (default: all)",
)
@click.option(
    "--force",
    "-f",
    is_flag=True,
    help="Force rebuild even if binaries exist",
)
def helper_build(lang: str, force: bool) -> None:
    """Build helper binaries from source."""
    from flavor.helpers.manager import HelperManager

    manager = HelperManager()

    language = None if lang == "all" else lang

    pout(f"๐Ÿ”จ Building {lang} helpers...")

    built = manager.build_helpers(language=language, force=force)

    if built:
        pout(f"โœ… Built {len(built)} helper(s):")
        for path in built:
            size_mb = path.stat().st_size / (1024 * 1024)
            pout(f"  โ€ข {path.name} ({size_mb:.1f} MB)")
    else:
        pout("โš ๏ธ  No helpers were built")
        pout("Make sure you have the required compilers installed:")
        pout("  โ€ข Go: go version")
        pout("  โ€ข Rust: cargo --version")

helper_clean

helper_clean(lang: str, yes: bool) -> None

Remove built helper binaries.

Source code in flavor/commands/helpers.py
@helper_group.command("clean")
@click.option(
    "--lang",
    type=click.Choice(["go", "rust", "all"], case_sensitive=False),
    default="all",
    help="Language to clean helpers for (default: all)",
)
@click.option(
    "--yes",
    "-y",
    is_flag=True,
    help="Skip confirmation prompt",
)
def helper_clean(lang: str, yes: bool) -> None:
    """Remove built helper binaries."""
    from flavor.helpers.manager import HelperManager

    manager = HelperManager()

    if not yes and not click.confirm(f"Remove {lang} helper binaries?"):
        pout("Aborted.")
        return

    language = None if lang == "all" else lang

    removed = manager.clean_helpers(language=language)

    if removed:
        pout(f"โœ… Removed {len(removed)} helper(s):")
        for path in removed:
            pout(f"  โ€ข {path.name}")
    else:
        pout("No helpers to remove")

helper_group

helper_group() -> None

Manage Flavor helper binaries (launchers and builders).

Source code in flavor/commands/helpers.py
@click.group("helpers")
def helper_group() -> None:
    """Manage Flavor helper binaries (launchers and builders)."""
    pass

helper_info

helper_info(name: str) -> None

Show detailed information about a specific helper.

Source code in flavor/commands/helpers.py
@helper_group.command("info")
@click.argument("name")
def helper_info(name: str) -> None:
    """Show detailed information about a specific helper."""
    from flavor.helpers.manager import HelperManager

    manager = HelperManager()
    info = manager.get_helper_info(name)

    if not info:
        perr(f"โŒ Helper '{name}' not found")
        return

    pout(f"๐Ÿ”ง Helper Information: {info.name}")
    pout("=" * 60)
    pout(f"Type: {info.type}")
    pout(f"Language: {info.language}")
    pout(f"Path: {info.path}")
    pout(f"Size: {info.size / (1024 * 1024):.1f} MB")

    if info.version:
        pout(f"Version: {info.version}")

    if info.checksum:
        pout(f"Checksum: {info.checksum}")

    if info.built_from:
        pout(f"Source: {info.built_from}")
        if info.built_from.exists():
            pout("  โœ… Source directory exists")
        else:
            pout("  โš ๏ธ  Source directory not found")

    # Check if executable
    if info.path.exists():
        if os.access(info.path, os.X_OK):
            pass
        else:
            pout("Status: โŒ Not executable")
    else:
        pout("Status: โŒ File not found")

helper_list

helper_list(verbose: bool) -> None

List available helper binaries.

Source code in flavor/commands/helpers.py
@helper_group.command("list")
@click.option(
    "--verbose",
    "-v",
    is_flag=True,
    help="Show detailed information",
)
def helper_list(verbose: bool) -> None:  # noqa: C901
    """List available helper binaries."""
    from flavor.helpers.manager import HelperManager

    manager = HelperManager()
    helpers = manager.list_helpers()

    if not helpers["launchers"] and not helpers["builders"]:
        pout("No helpers found. Build them with: flavor helpers build")
        return

    pout("๐Ÿ”ง Available Flavor Helpers")
    pout("=" * 60)

    # Helper function to get version
    def get_version(helper_path: Path) -> str | None:
        try:
            result = run(
                [str(helper_path), "--version"],
                capture_output=True,
                check=False,
                timeout=2,
            )
            if result.returncode == 0:
                # Parse version from output (first line usually)
                lines = result.stdout.strip().split("\n")
                if lines:
                    return lines[0]
        except Exception:
            pass
        return None

    if helpers["launchers"]:
        pout("\n๐Ÿ“ฆ Launchers:")
        launchers = sorted(helpers["launchers"], key=lambda h: h.name)
        for i, launcher in enumerate(launchers):
            if i > 0:
                pout("")  # Add newline between entries
            size_mb = launcher.size / (1024 * 1024)
            version = get_version(launcher.path) or launcher.version or "unknown"
            pout(f"  โ€ข {launcher.name} ({launcher.language}, {size_mb:.1f} MB) - {version}")
            pout(f"    Path: {launcher.path}")
            if launcher.checksum:
                pout(f"    SHA256: {launcher.checksum}")
            if verbose and launcher.built_from:
                pout(f"    Source: {launcher.built_from}")

    if helpers["builders"]:
        pout("\n๐Ÿ”จ Builders:")
        builders = sorted(helpers["builders"], key=lambda h: h.name)
        for i, builder in enumerate(builders):
            if i > 0:
                pout("")  # Add newline between entries
            size_mb = builder.size / (1024 * 1024)
            version = get_version(builder.path) or builder.version or "unknown"
            pout(f"  โ€ข {builder.name} ({builder.language}, {size_mb:.1f} MB) - {version}")
            pout(f"    Path: {builder.path}")
            if builder.checksum:
                pout(f"    SHA256: {builder.checksum}")
            if verbose and builder.built_from:
                pout(f"    Source: {builder.built_from}")

helper_test

helper_test(lang: str) -> None

Test helper binaries.

Source code in flavor/commands/helpers.py
@helper_group.command("test")
@click.option(
    "--lang",
    type=click.Choice(["go", "rust", "all"], case_sensitive=False),
    default="all",
    help="Language to test helpers for (default: all)",
)
def helper_test(lang: str) -> None:
    """Test helper binaries."""
    from flavor.helpers.manager import HelperManager

    manager = HelperManager()

    language = None if lang == "all" else lang

    pout(f"๐Ÿงช Testing {lang} helpers...")

    results = manager.test_helpers(language=language)

    # Show results
    if results["passed"]:
        pout(f"โœ… Passed: {len(results['passed'])}")
        for name in results["passed"]:
            pout(f"  โ€ข {name}")

    if results["failed"]:
        perr(f"โŒ Failed: {len(results['failed'])}")
        for failure in results["failed"]:
            pout(f"  โ€ข {failure['name']}: {failure['error']}")
            if failure.get("stderr"):
                pout(f"    {failure['stderr']}")

    if results["skipped"]:
        pout(f"โญ๏ธ  Skipped: {len(results['skipped'])}")
        for name in results["skipped"]:
            pout(f"  โ€ข {name}")

    # Overall status
    if results["failed"]:
        perr("\nโŒ Some tests failed")
        raise click.Abort()
    elif results["passed"]:
        pout("\nโœ… All tests passed")
    else:
        pout("\nโš ๏ธ  No tests were run")