Implement qbit add with version constraints #28

Open
opened 2026-01-03 23:40:20 +00:00 by KofTwentyTwo · 0 comments
KofTwentyTwo commented 2026-01-03 23:40:20 +00:00 (Migrated from github.com)

Part of #11

User Story

As a developer, I want to add qbit packages to my project with version constraints so I can manage dependencies.

Design

Command Interface

qctl qbit add <package>[@version]

# Examples:
qctl qbit add @qrun/auth-sso           # Latest version
qctl qbit add @qrun/auth-sso@2.0.0     # Exact version
qctl qbit add @qrun/auth-sso@^2.0      # Compatible with 2.x
qctl qbit add @qrun/auth-sso@~2.0.1    # Patch updates only

Workflow

  1. Parse package spec (name + optional version constraint)
  2. Fetch package metadata from registry (reuse RegistryClient from #27)
  3. Resolve best matching version using SemVer logic (#32)
  4. Check for conflicts with existing packages (#33)
  5. Download package to vendor directory (#34)
  6. Verify integrity (#35)
  7. Update qbits.lock with new entry
  8. Print success message

Files to Create/Modify

File Action Description
qctl-qbit/src/main/java/io/qrun/qctl/qbit/AddCommand.java Create Picocli command for qbit add
qctl-qbit/src/main/java/io/qrun/qctl/qbit/PackageSpec.java Create Parse name@version strings
qctl-qbit/src/main/java/io/qrun/qctl/qbit/lock/LockfileIO.java Modify Add write/update methods
qctl-qbit/src/main/java/io/qrun/qctl/qbit/QbitCommand.java Modify Register AddCommand

Dependencies

  • #27 (qbit search) - Reuses RegistryClient and PackageInfo
  • #32 (SemVer resolution) - Version constraint matching
  • #34 (vendor layout) - Download destination

Implementation Tasks

  • Create PackageSpec class to parse name@version strings
  • Implement version constraint parsing (^, ~, exact, latest)
  • Create AddCommand with Picocli annotations
  • Add package resolution logic (fetch metadata, find matching version)
  • Implement lockfile update in LockfileIO.write()
  • Add atomic file write for lockfile (write to temp, then move)
  • Handle "already installed" case (same version = skip, different = prompt)
  • Register AddCommand in QbitCommand.subcommands
  • Add unit tests for PackageSpec parsing
  • Add integration test for add workflow

Acceptance Criteria

  • qbit add @qrun/auth-sso installs latest version
  • qbit add @qrun/auth-sso@2.0.0 installs exact version
  • qbit add @qrun/auth-sso@^2.0 installs latest 2.x
  • Lockfile is updated with package entry
  • Re-running same add is idempotent
  • Clear error if package not found
Part of #11 ## User Story As a developer, I want to add qbit packages to my project with version constraints so I can manage dependencies. ## Design ### Command Interface ```bash qctl qbit add <package>[@version] # Examples: qctl qbit add @qrun/auth-sso # Latest version qctl qbit add @qrun/auth-sso@2.0.0 # Exact version qctl qbit add @qrun/auth-sso@^2.0 # Compatible with 2.x qctl qbit add @qrun/auth-sso@~2.0.1 # Patch updates only ``` ### Workflow 1. Parse package spec (name + optional version constraint) 2. Fetch package metadata from registry (reuse `RegistryClient` from #27) 3. Resolve best matching version using SemVer logic (#32) 4. Check for conflicts with existing packages (#33) 5. Download package to vendor directory (#34) 6. Verify integrity (#35) 7. Update `qbits.lock` with new entry 8. Print success message ### Files to Create/Modify | File | Action | Description | |------|--------|-------------| | `qctl-qbit/src/main/java/io/qrun/qctl/qbit/AddCommand.java` | Create | Picocli command for `qbit add` | | `qctl-qbit/src/main/java/io/qrun/qctl/qbit/PackageSpec.java` | Create | Parse `name@version` strings | | `qctl-qbit/src/main/java/io/qrun/qctl/qbit/lock/LockfileIO.java` | Modify | Add write/update methods | | `qctl-qbit/src/main/java/io/qrun/qctl/qbit/QbitCommand.java` | Modify | Register `AddCommand` | ### Dependencies - #27 (qbit search) - Reuses `RegistryClient` and `PackageInfo` - #32 (SemVer resolution) - Version constraint matching - #34 (vendor layout) - Download destination ## Implementation Tasks - [ ] Create `PackageSpec` class to parse `name@version` strings - [ ] Implement version constraint parsing (^, ~, exact, latest) - [ ] Create `AddCommand` with Picocli annotations - [ ] Add package resolution logic (fetch metadata, find matching version) - [ ] Implement lockfile update in `LockfileIO.write()` - [ ] Add atomic file write for lockfile (write to temp, then move) - [ ] Handle "already installed" case (same version = skip, different = prompt) - [ ] Register `AddCommand` in `QbitCommand.subcommands` - [ ] Add unit tests for `PackageSpec` parsing - [ ] Add integration test for add workflow ## Acceptance Criteria - [ ] `qbit add @qrun/auth-sso` installs latest version - [ ] `qbit add @qrun/auth-sso@2.0.0` installs exact version - [ ] `qbit add @qrun/auth-sso@^2.0` installs latest 2.x - [ ] Lockfile is updated with package entry - [ ] Re-running same add is idempotent - [ ] Clear error if package not found
Sign in to join this conversation.