Unpac CLI Workflow#
Overview#
Unpac is a vendoring tool that lets you maintain local patches to dependencies while tracking upstream changes. This document describes the ideal CLI workflow.
Quick Start#
# Initialize a new unpac workspace
unpac init myworkspace
cd myworkspace
# Configure an opam repository
unpac opam repo add opam-repository /path/to/opam-repository
# Create a project
unpac project new myapp
# Add a dependency (looks up dev-repo in opam repository)
unpac opam add cmdliner
# Edit the vendored package (opens patches worktree)
unpac opam edit cmdliner
# ... make changes, e.g., port to dune ...
cd opam/patches/cmdliner
git add -A && git commit -m "Port cmdliner to dune"
cd ../../..
# Add the patched package to your project
unpac opam merge cmdliner myapp
# Build your project
cd project/myapp
dune build
Commands#
Initialization#
unpac init <path>#
Initialize a new unpac workspace at the given path.
unpac init myworkspace
Creates:
git/- bare git repository (shared object store)main/- metadata branch withunpac.toml
Project Management#
unpac project new <name>#
Create a new project branch.
unpac project new myapp
Creates an orphan branch project/<name> with:
dune-projectwith dune lang 3.20dunewith(vendored_dirs vendor)vendor/opam/directory structure
unpac project list#
List all projects in the workspace.
unpac project list
Opam Repository Management#
unpac opam repo add <name> <path-or-url>#
Add an opam repository for package lookups.
# Local repository
unpac opam repo add opam-repository /workspace/opam/opam-repository
# Remote repository (planned)
unpac opam repo add opam-repository https://github.com/ocaml/opam-repository
unpac opam repo list#
List configured opam repositories.
unpac opam repo list
unpac opam repo remove <name>#
Remove an opam repository.
unpac opam repo remove opam-repository
Package Vendoring#
unpac opam add <package-or-url> [--name <name>] [--version <version>]#
Vendor a package. Can specify either:
- A package name (looks up dev-repo in configured repositories)
- A git URL directly
# By package name (recommended)
unpac opam add cmdliner
unpac opam add cmdliner --version 1.3.0
# By URL (for packages not in a repository)
unpac opam add https://github.com/dbuenzli/cmdliner.git --name cmdliner
This creates three branches:
opam/upstream/<pkg>- pristine upstream codeopam/vendor/<pkg>- code withvendor/opam/<pkg>/path prefixopam/patches/<pkg>- your local modifications (initially same as vendor)
unpac opam list#
List all vendored packages.
unpac opam list
unpac opam edit <package>#
Open the patches worktree for editing a package.
unpac opam edit cmdliner
Creates/checks out opam/patches/cmdliner/ worktree. Make your changes there, then commit:
cd opam/patches/cmdliner
# ... edit files ...
git add -A
git commit -m "Port to dune build system"
unpac opam done <package>#
Close the patches worktree (cleanup after editing).
unpac opam done cmdliner
unpac opam update <package>#
Update a package from upstream.
unpac opam update cmdliner
This:
- Fetches latest from upstream
- Updates
opam/upstream/<pkg>andopam/vendor/<pkg> - Prints instructions for rebasing patches if needed
unpac opam rebase <package>#
Rebase your patches onto the updated vendor branch.
unpac opam rebase cmdliner
Opens the patches worktree for conflict resolution if needed.
unpac opam merge <package> <project>#
Merge a vendored package into a project.
unpac opam merge cmdliner myapp
Merges opam/patches/<pkg> into project/<name>, placing files under vendor/opam/<pkg>/.
unpac opam remove <package>#
Remove a vendored package.
unpac opam remove cmdliner
Package Information#
unpac opam info <package>#
Show information about a vendored package.
unpac opam info cmdliner
Shows:
- Upstream URL
- Current upstream SHA
- Current patches SHA
- Number of local commits
- Projects using this package
unpac opam diff <package>#
Show the diff between vendor and patches (your local changes).
unpac opam diff cmdliner
Workflow Examples#
Porting a Package to Dune#
# Setup
unpac init myworkspace && cd myworkspace
unpac opam repo add opam-repository /workspace/opam/opam-repository
unpac project new myapp
# Vendor and patch
unpac opam add cmdliner
unpac opam edit cmdliner
cd opam/patches/cmdliner
# Add dune files, remove _tags, etc.
git add -A
git commit -m "Port cmdliner to dune"
cd ../../..
unpac opam done cmdliner
# Use in project
unpac opam merge cmdliner myapp
cd project/myapp
dune build
Updating a Patched Package#
# Update from upstream
unpac opam update cmdliner
# Rebase your patches
unpac opam rebase cmdliner
# If conflicts, resolve them:
cd opam/patches/cmdliner
# ... resolve conflicts ...
git add -A
git rebase --continue
cd ../../..
unpac opam done cmdliner
# Re-merge into project
unpac opam merge cmdliner myapp
Adding Multiple Dependencies#
unpac opam add fmt
unpac opam add logs
unpac opam add cmdliner
# Merge all into project
unpac opam merge fmt myapp
unpac opam merge logs myapp
unpac opam merge cmdliner myapp
Directory Structure#
After setup, your workspace looks like:
myworkspace/
├── git/ # Bare git repo (shared objects)
├── main/ # Metadata worktree
│ └── unpac.toml # Configuration
├── project/
│ └── myapp/ # Project worktree
│ ├── dune-project
│ ├── dune
│ └── vendor/
│ └── opam/
│ ├── cmdliner/ # Merged vendor code
│ └── fmt/
└── opam/ # Package worktrees (on-demand)
└── patches/
└── cmdliner/ # When editing
Configuration (unpac.toml)#
[opam]
repositories = [
{ name = "opam-repository", path = "/workspace/opam/opam-repository" }
]
# compiler = "5.4.0" # Optional: pin compiler version
[projects]
myapp = {}