MCPcopy Index your code
hub / github.com/github/spec-kit / bundle_install

Function bundle_install

src/specify_cli/commands/bundle/__init__.py:314–391  ·  view source on GitHub ↗

Install a bundle's full component set through each primitive's machinery. ``bundle_id`` may be a catalog bundle id, or a local path to a built artifact (``.zip``), a bundle directory, or a ``bundle.yml`` file. Local sources install directly without consulting the catalog stack.

(
    bundle_id: str = typer.Argument(
        ...,
        help="Bundle id (from the catalog stack) or a local path to a .zip "
        "artifact, bundle directory, or bundle.yml",
    ),
    integration: str = typer.Option(None, "--integration", help="Override integration"),
    offline: bool = typer.Option(False, "--offline", help="Do not access the network"),
)

Source from the content-addressed store, hash-verified

312
313@bundle_app.command("install")
314def bundle_install(
315 bundle_id: str = typer.Argument(
316 ...,
317 help="Bundle id (from the catalog stack) or a local path to a .zip "
318 "artifact, bundle directory, or bundle.yml",
319 ),
320 integration: str = typer.Option(None, "--integration", help="Override integration"),
321 offline: bool = typer.Option(False, "--offline", help="Do not access the network"),
322) -> None:
323 """Install a bundle's full component set through each primitive's machinery.
324
325 ``bundle_id`` may be a catalog bundle id, or a local path to a built
326 artifact (``.zip``), a bundle directory, or a ``bundle.yml`` file. Local
327 sources install directly without consulting the catalog stack.
328 """
329 try:
330 from ...bundler.lib.project import find_project_root
331 from ...bundler.services.adapters import DefaultPrimitiveInstaller
332 from ...bundler.services.installer import install_bundle
333 from ...bundler.services.resolver import resolve_install_plan
334
335 project_root = find_project_root()
336
337 local_manifest = _local_manifest_source(bundle_id)
338 if local_manifest is not None:
339 manifest = local_manifest
340 else:
341 stack = _build_stack(project_root or Path.cwd(), offline=offline)
342 resolved = stack.resolve(bundle_id)
343
344 if not resolved.install_allowed:
345 raise BundlerError(
346 f"Bundle '{bundle_id}' resolves only from a discovery-only source "
347 f"('{resolved.source.id}'); it cannot be installed from there."
348 )
349 manifest = _download_manifest(resolved, offline=offline)
350
351 if project_root is None:
352 init_integration = _resolve_init_integration(integration, manifest)
353 console.print(
354 f"[cyan]No Spec Kit project here; initializing with integration "
355 f"'{init_integration}'…[/cyan]"
356 )
357 _run_init(init_integration, script_type=_default_script_type(), offline=offline)
358 project_root = require_project_root()
359
360 for overlap in _bundle_overlaps(project_root, manifest, offline=offline):
361 console.print(f"[yellow]![/yellow] {overlap}")
362
363 # For an already-initialized project, the project's recorded active
364 # integration is authoritative — an explicit --integration must not be
365 # able to bypass the FR-019 integration-clash guard. The override only
366 # selects the integration at init time (handled above) or confirms the
367 # target when the active integration cannot be determined.
368 detected = active_integration(project_root)
369 plan = resolve_install_plan(
370 manifest,
371 speckit_version=_speckit_version(),

Callers 1

bundle_initFunction · 0.85

Calls 15

find_project_rootFunction · 0.85
_local_manifest_sourceFunction · 0.85
_build_stackFunction · 0.85
BundlerErrorClass · 0.85
_download_manifestFunction · 0.85
_default_script_typeFunction · 0.85
require_project_rootFunction · 0.85
_bundle_overlapsFunction · 0.85
active_integrationFunction · 0.85
resolve_install_planFunction · 0.85
_speckit_versionFunction · 0.85

Tested by

no test coverage detected