Skip to content
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
10 changes: 5 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -93,13 +93,13 @@ ignore = [
# High initial thresholds set just above current codebase maximums.
# Prevents new code from exceeding the worst existing violations.
# Tighten these over time via dedicated refactoring PRs.
max-statements = 275 # current max: 269 (mcp_integrator.py::install)
max-args = 18 # current max: 16 (commands/install.py)
max-branches = 115 # current max: 108 (mcp_integrator.py::install)
max-returns = 18 # current max: 16 (marketplace/publisher.py)
max-statements = 200 # Stage 1 strangler threshold
max-args = 15 # Stage 1 strangler threshold
max-branches = 60 # Stage 1 strangler threshold
max-returns = 12 # Stage 1 strangler threshold

[tool.ruff.lint.mccabe]
max-complexity = 100 # current max: 97 (mcp_integrator.py::install)
max-complexity = 50 # Stage 1 strangler threshold

[tool.ruff.lint.per-file-ignores]
# Subprocess calls are intentional in a CLI tool
Expand Down
53 changes: 20 additions & 33 deletions src/apm_cli/commands/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -680,7 +680,7 @@ def _validate_and_add_packages_to_apm_yml(
# ---------------------------------------------------------------------------


def _handle_mcp_install(
def _handle_mcp_install( # noqa: PLR0913
*,
mcp_name,
transport,
Expand Down Expand Up @@ -1779,26 +1779,12 @@ def _post_install_summary(
#
# The real implementation lives in ``apm_cli.install.pipeline`` (F2).
# ---------------------------------------------------------------------------
def _install_apm_dependencies( # noqa: PLR0913
def _install_apm_dependencies(
apm_package: "APMPackage",
update_refs: bool = False,
verbose: bool = False,
only_packages: "builtins.list" = None, # noqa: RUF013
force: bool = False,
parallel_downloads: int = 4,
logger: "InstallLogger" = None,
scope=None,
auth_resolver: "AuthResolver" = None,
target: str = None, # noqa: RUF013
allow_insecure: bool = False,
allow_insecure_hosts=(),
marketplace_provenance: dict = None,
protocol_pref=None,
allow_protocol_fallback: "bool | None" = None,
no_policy: bool = False,
skill_subset: "builtins.tuple | None" = None,
skill_subset_from_cli: bool = False,
legacy_skill_paths: bool = False,
**kwargs,
):
"""Thin wrapper -- builds an :class:`InstallRequest` and delegates to
:class:`apm_cli.install.service.InstallService`.
Expand All @@ -1811,28 +1797,29 @@ def _install_apm_dependencies( # noqa: PLR0913
if not APM_DEPS_AVAILABLE:
raise RuntimeError("APM dependency system not available")

from apm_cli.install.request import InstallRequest
from apm_cli.install.request import InstallApmDependenciesOptions, InstallRequest
from apm_cli.install.service import InstallService

options = InstallApmDependenciesOptions.from_kwargs(kwargs)
request = InstallRequest(
apm_package=apm_package,
update_refs=update_refs,
verbose=verbose,
only_packages=only_packages,
force=force,
parallel_downloads=parallel_downloads,
logger=logger,
scope=scope,
auth_resolver=auth_resolver,
target=target,
allow_insecure=allow_insecure,
allow_insecure_hosts=allow_insecure_hosts,
marketplace_provenance=marketplace_provenance,
protocol_pref=protocol_pref,
allow_protocol_fallback=allow_protocol_fallback,
no_policy=no_policy,
skill_subset=skill_subset,
skill_subset_from_cli=skill_subset_from_cli,
legacy_skill_paths=legacy_skill_paths,
force=options.force,
parallel_downloads=options.parallel_downloads,
logger=options.logger,
scope=options.scope,
auth_resolver=options.auth_resolver,
target=options.target,
allow_insecure=options.allow_insecure,
allow_insecure_hosts=options.allow_insecure_hosts,
marketplace_provenance=options.marketplace_provenance,
protocol_pref=options.protocol_pref,
allow_protocol_fallback=options.allow_protocol_fallback,
no_policy=options.no_policy,
skill_subset=options.skill_subset,
skill_subset_from_cli=options.skill_subset_from_cli,
legacy_skill_paths=options.legacy_skill_paths,
)
return InstallService().run(request)
2 changes: 1 addition & 1 deletion src/apm_cli/install/mcp/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
pass


def run_mcp_install(
def run_mcp_install( # noqa: PLR0913
*,
mcp_name: str,
transport: str | None,
Expand Down
2 changes: 1 addition & 1 deletion src/apm_cli/install/mcp/conflicts.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
)


def validate_mcp_conflicts(
def validate_mcp_conflicts( # noqa: PLR0913
*,
mcp_name: str | None,
packages: Sequence[str],
Expand Down
2 changes: 1 addition & 1 deletion src/apm_cli/install/phases/resolve.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
_logger = logging.getLogger(__name__)


def run(ctx: InstallContext) -> None:
def run(ctx: InstallContext) -> None: # noqa: C901
"""Execute the resolve phase.

On return every field listed in the *Resolve phase outputs* section of
Expand Down
32 changes: 31 additions & 1 deletion src/apm_cli/install/request.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

from __future__ import annotations

from dataclasses import dataclass
from dataclasses import dataclass, fields
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple # noqa: F401, UP035

if TYPE_CHECKING:
Expand Down Expand Up @@ -45,3 +45,33 @@ class InstallRequest:
skill_subset: tuple[str, ...] | None = None # --skill filter for SKILL_BUNDLE packages
skill_subset_from_cli: bool = False # True when user passed --skill (even --skill '*')
legacy_skill_paths: bool = False # --legacy-skill-paths / APM_LEGACY_SKILL_PATHS


@dataclass(frozen=True)
class InstallApmDependenciesOptions:
"""Compatibility options for the legacy commands.install wrapper."""

force: bool = False
parallel_downloads: int = 4
logger: InstallLogger | None = None
scope: InstallScope | None = None
auth_resolver: AuthResolver | None = None
target: str | None = None
allow_insecure: bool = False
allow_insecure_hosts: tuple[str, ...] = ()
marketplace_provenance: dict[str, Any] | None = None
protocol_pref: Any | None = None
allow_protocol_fallback: bool | None = None
no_policy: bool = False
skill_subset: tuple[str, ...] | None = None
skill_subset_from_cli: bool = False
legacy_skill_paths: bool = False

@classmethod
def from_kwargs(cls, kwargs: dict[str, Any]) -> InstallApmDependenciesOptions:
known = {field.name for field in fields(cls)}
unknown = set(kwargs) - known
if unknown:
unknown_list = ", ".join(sorted(unknown))
raise TypeError(f"unexpected install option(s): {unknown_list}")
return cls(**kwargs)
2 changes: 1 addition & 1 deletion src/apm_cli/install/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ def _deployed_path_entry(
)


def integrate_package_primitives(
def integrate_package_primitives( # noqa: PLR0913
package_info: Any,
project_root: Path,
*,
Expand Down
2 changes: 1 addition & 1 deletion src/apm_cli/install/validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ def _local_path_no_markers_hint(local_dir, logger=None):
_rich_echo(f" ... and {len(found) - 5} more", color="dim")


def _validate_package_exists(package, verbose=False, auth_resolver=None, logger=None):
def _validate_package_exists(package, verbose=False, auth_resolver=None, logger=None): # noqa: C901, PLR0911, PLR0915
"""Validate that a package exists and is accessible on GitHub, Azure DevOps, or locally."""
import os
import subprocess
Expand Down
Loading