Skip to content
Merged
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Propagate headers and environment variables through OpenCode MCP adapter with defensive copies to prevent mutation (#622)
- Fix `apm install` hanging indefinitely when corporate firewalls silently drop SSH packets by setting `GIT_SSH_COMMAND` with `ConnectTimeout=30` (#652)
- Fix `apm compile --target claude` silently skipping dependency instructions stored in `.github/instructions/` (#631)
- `_parse_artifactory_base_url()` now honours `PROXY_REGISTRY_URL` — lockfile reinstall no longer fails for virtual subdirectory packages (#614)

### Changed

Expand Down
31 changes: 16 additions & 15 deletions src/apm_cli/deps/github_downloader.py
Original file line number Diff line number Diff line change
Expand Up @@ -412,20 +412,16 @@ def _should_use_artifactory_proxy(self, dep_ref: 'DependencyReference') -> bool:
return is_github_hostname(host)

def _parse_artifactory_base_url(self) -> Optional[tuple]:
"""Parse ARTIFACTORY_BASE_URL into (host, prefix, scheme)."""
import urllib.parse as urlparse
base_url = os.environ.get('ARTIFACTORY_BASE_URL', '').strip().rstrip('/')
if not base_url:
return None
parsed = urlparse.urlparse(base_url)
if parsed.scheme not in ('https', 'http'):
_debug(f"ARTIFACTORY_BASE_URL has unsupported scheme: {parsed.scheme}")
return None
host = parsed.hostname
path = parsed.path.strip('/')
if not host or not path:
"""Return ``(host, prefix, scheme)`` from the registry proxy config, or ``None``.

Delegates to :meth:`~apm_cli.deps.registry_proxy.RegistryConfig.from_env`
so that env-var precedence and deprecation warnings are handled in one place.
"""
from .registry_proxy import RegistryConfig
cfg = RegistryConfig.from_env()
if cfg is None:
return None
return (host, path, parsed.scheme)
return (cfg.host, cfg.prefix, cfg.scheme)

def _resolve_dep_token(self, dep_ref: Optional[DependencyReference] = None) -> Optional[str]:
"""Resolve the per-dependency auth token via AuthResolver.
Expand Down Expand Up @@ -2125,8 +2121,13 @@ def download_package(
elif dep_ref.is_virtual_collection():
return self.download_collection_package(dep_ref, target_path, progress_task_id, progress_obj)
elif dep_ref.is_virtual_subdirectory():
# When PROXY_REGISTRY_ONLY is set, download full archive and extract subdir
art_proxy = self._parse_artifactory_base_url()
# Mode 1: explicit Artifactory FQDN from lockfile
if dep_ref.is_artifactory():
proxy_info = (dep_ref.host, dep_ref.artifactory_prefix, "https")
return self._download_subdirectory_from_artifactory(
dep_ref, target_path, proxy_info, progress_task_id, progress_obj
)
# Mode 2: transparent proxy via env var (art_proxy computed above)
if self._is_artifactory_only() and art_proxy:
return self._download_subdirectory_from_artifactory(
dep_ref, target_path, art_proxy, progress_task_id, progress_obj
Expand Down
Loading
Loading