####### 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: .. list-table:: :header-rows: 1 :widths: 20 15 15 15 35 * - 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: .. code-block:: bash 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: .. code-block:: bash 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``): .. code-block:: bash 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``: .. code-block:: 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:** .. code-block:: yaml 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:** .. code-block:: yaml 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: .. code-block:: yaml deps: - name: uv url: https://github.com/astral-sh/uv src: gh-rls version: latest cache: true **Cache key:** ``__`` 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: .. code-block:: bash ivpm cache info Use ``--verbose`` for detailed version information: .. code-block:: bash 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: .. code-block:: bash ivpm cache info --cache-dir /path/to/cache Cleaning the Cache ------------------ Remove cache entries older than a specified number of days: .. code-block:: bash ivpm cache clean --days 7 This removes entries that haven't been accessed in 7 days (the default). **To remove old entries:** .. code-block:: bash # 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:** .. code-block:: 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:** .. code-block:: bash # 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:** .. code-block:: 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:** .. code-block:: yaml deps: - name: common-lib url: https://github.com/org/common.git tag: v2.0 cache: true **Project B:** .. code-block:: yaml deps: - name: common-lib url: https://github.com/org/common.git tag: v2.0 cache: true **Project C:** .. code-block:: yaml 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? .. code-block:: bash echo $IVPM_CACHE 2. Does the cache directory exist? .. code-block:: bash 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: .. code-block:: bash export IVPM_CACHE=~/.cache/ivpm ivpm cache init $IVPM_CACHE ivpm update # Re-run to use cache Broken Symlinks --------------- **Problem:** Symlinks in ``packages/`` pointing to non-existent cache entries **Cause:** Cache was cleaned or manually deleted **Solution:** .. code-block:: bash # Remove broken symlinks find packages/ -type l ! -exec test -e {} \; -delete # Re-run update to recreate ivpm update Permission Denied (Shared Cache) --------------------------------- **Problem:** Cannot write to shared cache **Check permissions:** .. code-block:: bash ls -la /shared/ivpm-cache **Solution:** .. code-block:: bash # 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:** .. code-block:: bash # 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 ---------- .. code-block:: text ivpm cache init [-s/--shared] [-f/--force] Options: - ``-s, --shared``: Set group inheritance (``chmod g+s``) for shared cache usage - ``-f, --force``: Force reinitialization of an existing directory cache info ---------- .. code-block:: text ivpm cache info [-c/--cache-dir ] [-v/--verbose] Options: - ``-c, --cache-dir``: Cache directory (default: ``$IVPM_CACHE``) - ``-v, --verbose``: Show detailed version information cache clean ----------- .. code-block:: text ivpm cache clean [-c/--cache-dir ] [-d/--days ] Options: - ``-c, --cache-dir``: Cache directory (default: ``$IVPM_CACHE``) - ``-d, --days``: Remove entries older than this many days (default: 7) See Also ======== - :doc:`package_types` - Understanding cache attribute on different package types - :doc:`getting_started` - Basic cache setup