Skip to content

feat: add apm pack and apm unpack commands#218

Merged
danielmeppiel merged 7 commits intomainfrom
feat/pack-unpack
Mar 10, 2026
Merged

feat: add apm pack and apm unpack commands#218
danielmeppiel merged 7 commits intomainfrom
feat/pack-unpack

Conversation

@danielmeppiel
Copy link
Collaborator

Summary

Adds apm pack and apm unpack commands for creating and consuming self-contained bundles from the resolved dependency tree.

Commands

apm pack

Collects all deployed files from locked dependencies into a portable bundle.

apm pack                        # bundle into ./build/<name>-<version>/
apm pack --archive              # produce a .tar.gz
apm pack --target vscode        # only .github/ files
apm pack --dry-run              # list files without writing
apm pack -o dist/               # custom output directory

apm unpack

Extracts a bundle into the current project with completeness verification.

apm unpack ./build/my-pkg-1.0.0.tar.gz
apm unpack bundle.tar.gz --skip-verify
apm unpack bundle.tar.gz --dry-run

Architecture

Follows the commands/deps.py extraction pattern — no monolithic cli.py growth:

  • Service layer (src/apm_cli/bundle/):
    • packer.pypack_bundle() with target filtering, archive, dry-run
    • unpacker.pyunpack_bundle() with verification, additive merge, path-traversal protection
    • lockfile_enrichment.py — adds pack: metadata section to lockfile copy in bundle
  • Command layer (src/apm_cli/commands/pack.py) — thin Click orchestrators
  • Wiring: 3 lines added to cli.py

Key design decisions

  • Source of truth: lockfile deployed_files, not disk scan
  • Lockfile enrichment: bundle's apm.lock gets a pack: section (format, target, timestamp); project lockfile is never modified
  • No bundle.json — single manifest via enriched lockfile
  • Additive-only merge (v1): unpack only writes files; never deletes
  • Verification: completeness check (all deployed_files present), per-file hashes deferred to v2

Tests

  • 28 unit tests across test_packer.py (15), test_unpacker.py (9), test_lockfile_enrichment.py (4)
  • 2 integration tests in test_pack_unpack_e2e.py (round-trip + dry-run)
  • Full suite: 1757 passed, 0 failures

Manual validation

Verified on apm-sample-project:

$ apm install           # 8 dependencies
$ apm pack --archive    # Packed 20 file(s) → build/apm-sample-project-1.0.0.tar.gz
$ apm unpack <archive>  # Unpacked 20 file(s) (verified)

Documentation

  • Added docs/pack-unpack.md with command reference, options, merge semantics, and enriched lockfile format

Implements self-contained bundle creation and consumption from the
resolved dependency tree.

New commands:
- apm pack: collects deployed files into a portable bundle with
  target filtering, archive support, dry-run, and lockfile enrichment
- apm unpack: extracts bundles with completeness verification,
  additive-only merge semantics, and path-traversal protection

Architecture:
- New bundle/ service layer (packer.py, unpacker.py, lockfile_enrichment.py)
- New commands/pack.py command layer (following deps.py extraction pattern)
- 3 lines added to cli.py for wiring

Tests: 28 unit tests, 2 integration tests
Docs: docs/pack-unpack.md
Copilot AI review requested due to automatic review settings March 9, 2026 23:03
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds first-class bundling support to APM via new apm pack / apm unpack commands, enabling creation and consumption of portable bundles based on apm.lock’s deployed_files.

Changes:

  • Introduces a bundle service layer (packer, unpacker, lockfile_enrichment) plus a thin Click command wrapper.
  • Wires pack/unpack into the main CLI and adds dedicated docs (docs/pack-unpack.md).
  • Adds unit + integration tests covering pack/unpack behavior, dry-run, verification, and enrichment.

Reviewed changes

Copilot reviewed 11 out of 12 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
src/apm_cli/bundle/packer.py Implements bundle creation from lockfile deployed_files, with target filtering + optional archive output.
src/apm_cli/bundle/unpacker.py Implements bundle extraction, completeness verification, and additive merge semantics.
src/apm_cli/bundle/lockfile_enrichment.py Adds pack: metadata to the bundle’s lockfile copy.
src/apm_cli/bundle/__init__.py Exposes pack/unpack APIs from the bundle package.
src/apm_cli/commands/pack.py Adds Click commands/options and orchestrates pack/unpack output.
src/apm_cli/cli.py Registers the new pack and unpack commands.
docs/pack-unpack.md Documents usage, options, semantics, and enriched lockfile format.
tests/unit/test_packer.py Unit coverage for packer (filtering, archive, dry-run, errors, enrichment).
tests/unit/test_unpacker.py Unit coverage for unpacker (directory/archive, verify, dry-run, overwrite semantics).
tests/unit/test_lockfile_enrichment.py Unit coverage for pack metadata enrichment.
tests/integration/test_pack_unpack_e2e.py E2E round-trip tests for install → pack → unpack.

@danielmeppiel
Copy link
Collaborator Author

@copilot address unresolved pr review comments

Copy link
Contributor

Copilot AI commented Mar 9, 2026

@danielmeppiel I've opened a new pull request, #219, to work on those changes. Once the pull request is ready, I'll request review from you.

Copilot AI and others added 5 commits March 9, 2026 23:29
Co-authored-by: danielmeppiel <51440732+danielmeppiel@users.noreply.github.com>
fix: address unresolved review comments on apm pack/unpack
- Add 'agents' as accepted --target choice (alias for 'vscode'), matching compile command
- Add -t short flag for --target, matching compile command
- Add 'agents' prefix mapping in packer for consistency
@danielmeppiel danielmeppiel merged commit c97523a into main Mar 10, 2026
6 checks passed
@danielmeppiel danielmeppiel deleted the feat/pack-unpack branch March 10, 2026 00:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants