Caching

Overview

IVPM supports caching of package data to:

  • Reduce network traffic when fetching version-controlled files

  • Reduce disk space for shared dependencies that aren’t being edited

  • Speed up project initialization across multiple workspaces

Cached packages are always read-only and symlinked into the packages/ directory, allowing multiple projects to share the same cached package data.

Cache Modes

IVPM supports three caching modes per package, controlled by the cache attribute:

cache value

Cached?

History?

Editable?

Use Case

true

Yes

No

No

Production deps, stable releases

false

No

No

No

One-time use, temp deps

(unspecified)

No

Yes

Yes

Development, co-development

cache: true
  • Package stored in $IVPM_CACHE

  • Symlinked into packages/

  • Read-only (cannot modify)

  • No Git history (shallow clone)

  • Shared across projects

cache: false
  • Not cached

  • Cloned directly to packages/

  • Read-only (cannot modify)

  • No Git history (shallow clone)

  • Cannot be edited

cache not specified
  • Not cached

  • Cloned directly to packages/

  • Full Git history

  • Can be modified and committed

  • Development-friendly

Configuration

Enabling the Cache

Caching is enabled by setting the IVPM_CACHE environment variable to point to the cache directory:

export IVPM_CACHE=/path/to/cache

Add this to your shell rc file (.bashrc, .zshrc, etc.) to make it permanent.

Recommended cache locations:

  • Personal cache: ~/.cache/ivpm or ~/ivpm-cache

  • Shared cache: /shared/ivpm-cache or /opt/ivpm-cache

If IVPM_CACHE is not set, IVPM will fall back to full clones (no caching) with a warning message.

Initializing a Cache Directory

Create a new cache directory:

ivpm cache init /path/to/cache

For shared environments where multiple users access the cache, use the --shared option to set group inheritance permissions (chmod g+s):

sudo ivpm cache init --shared /shared/ivpm-cache
sudo chown :developers /shared/ivpm-cache
export IVPM_CACHE=/shared/ivpm-cache

This ensures new files inherit the group ownership of the cache directory.

Cache Organization

The cache is organized by package name, with version-specific subdirectories:

  • For Git packages, the version is the commit hash

  • For HTTP packages, the version is derived from the Last-Modified header or ETag

  • For GitHub Releases, the version includes the release tag and platform info

Example structure:

$IVPM_CACHE/
├── gtest/
│   ├── abc123def456.../           # Git commit hash
│   └── 789xyz012abc.../           # Different commit
├── boost/
│   ├── Thu_01-Jan-2024_120000/   # HTTP Last-Modified timestamp
│   └── Fri_15-Mar-2024_093000/
└── uv/
    ├── 0.1.0_linux_x86_64/       # GitHub Release with platform
    └── 0.1.1_darwin_arm64/

Each version directory contains the complete, read-only package content.

Package Caching

Enabling Caching for Packages

To enable caching for a package, set the cache attribute in your ivpm.yaml:

dep-sets:
  - name: default-dev
    deps:
      - name: gtest
        url: https://github.com/google/googletest.git
        branch: main
        cache: true

The cache attribute can be:

  • true - Enable caching (read-only, symlinked from cache)

  • false - No cache, read-only (clone without history, not cached)

  • Unspecified - No cache, editable (full history, can be modified)

Cached packages are always read-only and are symlinked into the packages/ directory.

Git Packages

IVPM supports caching for any Git repository, not just GitHub.

For GitHub URLs (recommended for speed):

  1. IVPM queries the GitHub API to get the commit hash of the target branch/tag

  2. If the commit exists in the cache, it symlinks to packages/

  3. If not cached, clones without history, stores in cache, and symlinks

For general Git URLs:

  1. IVPM uses git ls-remote to get the commit hash

  2. If the commit exists in the cache, it symlinks to packages/

  3. If not cached, clones without history, stores in cache, and symlinks

Examples:

deps:
  # GitHub repo (uses API)
  - name: my-lib
    url: https://github.com/org/lib.git
    branch: v1.0
    cache: true

  # GitLab repo (uses git ls-remote)
  - name: other-lib
    url: https://gitlab.com/org/lib.git
    tag: release-1.0
    cache: true

  # Self-hosted Git (uses git ls-remote)
  - name: internal-lib
    url: https://git.company.com/team/lib.git
    branch: stable
    cache: true

Cache key: The full commit hash (40 characters)

Benefits:

  • Multiple projects can share the same cached version

  • Updates only download if the commit hash changes

  • Significant time savings for large repositories

HTTP/URL Packages

For cacheable HTTP URLs (e.g., .tar.gz files):

  1. IVPM fetches the Last-Modified date or ETag via HTTP HEAD request

  2. If a matching entry exists in the cache, it symlinks to packages/

  3. If not cached, downloads, unpacks, stores in cache, and symlinks

Examples:

deps:
  - name: boost
    url: https://boostorg.jfrog.io/artifactory/main/release/1.82.0/source/boost_1_82_0.tar.gz
    cache: true

  - name: test-data
    url: https://cdn.example.com/vectors-v2.tar.gz
    cache: true

Cache key: Last-Modified header (converted to safe filename) or ETag

Benefits:

  • Avoid re-downloading large archives

  • CDN files are often stable and benefit from caching

GitHub Releases

GitHub Release packages support platform-specific caching:

deps:
  - name: uv
    url: https://github.com/astral-sh/uv
    src: gh-rls
    version: latest
    cache: true

Cache key: <release-tag>_<platform>_<architecture>

Examples:

  • 0.1.0_linux_x86_64

  • 0.1.0_darwin_arm64

  • 0.1.0_windows_x86_64

This allows different platforms to cache different binaries for the same release.

Benefits:

  • Cache platform-specific binaries separately

  • Share cache across team members on the same platform

  • Avoid re-downloading large binary releases

Cache Management

IVPM provides commands to manage the cache.

Viewing Cache Information

See packages, number of cached versions, and total size:

ivpm cache info

Use --verbose for detailed version information:

ivpm cache info --verbose

Example output:

Cache directory: /home/user/.cache/ivpm
Total packages: 15
Total versions: 47
Total size: 2.3 GB

Package: gtest
  Versions: 3
  Size: 45 MB

Package: boost
  Versions: 2
  Size: 856 MB

If IVPM_CACHE is not set, specify the cache directory:

ivpm cache info --cache-dir /path/to/cache

Cleaning the Cache

Remove cache entries older than a specified number of days:

ivpm cache clean --days 7

This removes entries that haven’t been accessed in 7 days (the default).

To remove old entries:

# Remove entries older than 30 days
ivpm cache clean --days 30

# Use a specific cache directory
ivpm cache clean --cache-dir /shared/cache --days 14

What gets removed:

  • Version directories with access time (atime) older than specified days

  • Empty package directories after version removal

  • Symlinks in projects will become broken and need ivpm update to recreate

Practical Examples

Example 1: Development with Caching

ivpm.yaml:

package:
  name: my-project
  dep-sets:
    - name: default-dev
      deps:
        # Stable library - cache it
        - name: googletest
          url: https://github.com/google/googletest.git
          tag: v1.14.0
          cache: true

        # Co-developed library - don't cache
        - name: my-lib
          url: https://github.com/org/my-lib.git
          # No cache attribute - editable

        # Test data - cache it
        - name: test-vectors
          url: https://cdn.example.com/vectors.tar.gz
          cache: true

Result:

  • googletest → Cached, read-only, symlinked

  • my-lib → Not cached, full history, editable

  • test-vectors → Cached, read-only, symlinked

Example 2: Shared Team Cache

Setup:

# Admin sets up shared cache
sudo mkdir -p /shared/ivpm-cache
sudo ivpm cache init --shared /shared/ivpm-cache
sudo chown :devteam /shared/ivpm-cache

# Team members add to their ~/.bashrc
export IVPM_CACHE=/shared/ivpm-cache

ivpm.yaml:

deps:
  - name: large-dataset
    url: https://cdn.example.com/data-10GB.tar.gz
    cache: true

  - name: big-library
    url: https://github.com/org/big-lib.git
    branch: stable
    cache: true

Benefits:

  • First team member downloads, all others get instant symlink

  • Saves bandwidth and disk space across the team

  • Managed with ivpm cache clean periodically

Example 3: Multi-Project Workflow

Scenario: Working on three related projects

Project A:

deps:
  - name: common-lib
    url: https://github.com/org/common.git
    tag: v2.0
    cache: true

Project B:

deps:
  - name: common-lib
    url: https://github.com/org/common.git
    tag: v2.0
    cache: true

Project C:

deps:
  - name: common-lib
    url: https://github.com/org/common.git
    tag: v2.0
    cache: true

Result: All three projects share the same cached common-lib at commit corresponding to tag v2.0. Total disk usage: 1× instead of 3×.

When to Use Caching

Use cache: true when:

✅ Stable, released versions (tags) ✅ Large repositories you don’t modify ✅ Third-party dependencies ✅ Shared across multiple projects ✅ Team environments with shared cache ✅ CI/CD builds ✅ Binary releases from GitHub

Use cache: false when:

⚠️ You want read-only but not cached ⚠️ One-time use packages ⚠️ Testing package updates ⚠️ Temporary dependencies

Use no cache attribute when:

✅ Actively developing/modifying ✅ Co-developed packages ✅ Need full Git history ✅ Making commits to the package ✅ Branching or rebasing

Troubleshooting

Cache Not Working

Problem: Packages not being cached

Check:

  1. Is IVPM_CACHE set?

    echo $IVPM_CACHE
    
  2. Does the cache directory exist?

    ls -la $IVPM_CACHE
    
  3. Is cache: true in your ivpm.yaml?

  4. Check IVPM output for cache hit/miss messages

Solution: If not set, initialize:

export IVPM_CACHE=~/.cache/ivpm
ivpm cache init $IVPM_CACHE
ivpm update  # Re-run to use cache

Permission Denied (Shared Cache)

Problem: Cannot write to shared cache

Check permissions:

ls -la /shared/ivpm-cache

Solution:

# Add yourself to the group
sudo usermod -a -G devteam $USER

# Re-login or newgrp
newgrp devteam

# Verify permissions
ls -la /shared/ivpm-cache

Cache Growing Too Large

Problem: Cache directory taking too much space

Solutions:

# View cache size
ivpm cache info

# Clean old entries
ivpm cache clean --days 30

# Manual cleanup (advanced)
du -sh $IVPM_CACHE/*/ | sort -h

Performance Tips

  1. Enable caching for large dependencies - Saves significant time

  2. Use shallow clones when not caching - Combine depth: 1 with cache: false

  3. Shared cache for teams - Set up once, benefits everyone

  4. Regular cleanup - Schedule ivpm cache clean monthly

  5. Monitor cache size - Use ivpm cache info periodically

  6. Cache stable versions - Use tags or specific commits with cache: true

  7. Don’t cache development deps - Leave packages you’re actively modifying uncached

Command Reference

cache init

ivpm cache init [-s/--shared] [-f/--force] <cache_dir>

Options:

  • -s, --shared: Set group inheritance (chmod g+s) for shared cache usage

  • -f, --force: Force reinitialization of an existing directory

cache info

ivpm cache info [-c/--cache-dir <dir>] [-v/--verbose]

Options:

  • -c, --cache-dir: Cache directory (default: $IVPM_CACHE)

  • -v, --verbose: Show detailed version information

cache clean

ivpm cache clean [-c/--cache-dir <dir>] [-d/--days <n>]

Options:

  • -c, --cache-dir: Cache directory (default: $IVPM_CACHE)

  • -d, --days: Remove entries older than this many days (default: 7)

See Also