Skip to content

Dependency Vendoring

Overview

CCGO supports dependency vendoring - caching all project dependencies locally in the vendor/ directory. This enables:

  • Offline builds - No network access required after vendoring
  • Reproducible builds - Exact dependency versions locked in vendor
  • Faster CI/CD - No dependency downloads during builds
  • Security - Review and audit vendored dependencies
  • Compliance - Meet requirements for air-gapped environments

Quick Start

# 1. Install dependencies first (generates CCGO.lock)
ccgo install

# 2. Vendor all dependencies to vendor/ directory
ccgo vendor

# 3. Commit vendor/ to version control
git add vendor/
git commit -m "vendor: cache dependencies for offline builds"

# 4. Now ccgo install will use vendored copies
ccgo install

Commands

ccgo vendor

Copies all locked dependencies from CCGO.lock to vendor/ directory.

Requirements: - CCGO.lock must exist (run ccgo install first) - Git must be installed (for git dependencies)

What it does: 1. Reads CCGO.lock to get exact dependency versions 2. Copies each dependency to vendor/{name}/ 3. Strips .git directories to save space 4. Generates vendor/.vendor.toml manifest 5. Cleans up unused vendored dependencies

Example:

$ ccgo vendor

================================================================================
CCGO Vendor - Vendor Dependencies for Offline Builds
================================================================================

Project directory: /path/to/project
Vendor directory: /path/to/project/vendor

📦 Vendoring 3 dependencies...
    Vendored fmt
    Vendored json
    Vendored gtest

================================================================================
Vendor Summary
================================================================================

 Vendored: 3

📁 Vendor directory: /path/to/project/vendor

💡 To use vendored dependencies:
   - Dependencies are now in vendor/
   - Commit vendor/ to version control for offline builds

ccgo vendor --verify

Verifies vendor/ directory integrity without modifying it.

Checks: - All locked dependencies are present in vendor/ - Vendored sources match lockfile - No missing or outdated dependencies

Example:

$ ccgo vendor --verify

🔍 Verifying vendor directory...

 Vendor directory is up-to-date
  3 packages verified

Error case:

$ ccgo vendor --verify

🔍 Verifying vendor directory...

⚠️  Vendor directory needs update:
   Missing: fmt
   Outdated: json (git URL changed)

   Run 'ccgo vendor --sync' to fix
Error: Vendor verification failed

ccgo vendor --sync

Re-vendors dependencies that have changed since last vendor.

Use cases: - After updating dependencies in CCGO.toml - After modifying CCGO.lock - To fix verification failures

Example:

$ ccgo vendor --sync

📦 Vendoring 3 dependencies...
   ⏭️  fmt already vendored
    Vendored json (updated)
   ⏭️  gtest already vendored

 Vendored: 1
⏭️  Skipped (already vendored): 2

ccgo vendor --no-delete

Vendor dependencies without cleaning up unused ones.

Useful when: - Debugging vendoring issues - Temporarily testing different dependency versions - Want to keep old vendored copies

Example:

$ ccgo vendor --no-delete

# Keeps old vendored dependencies even if not in CCGO.lock

ccgo vendor --path custom-vendor

Use a custom directory name instead of vendor/.

Example:

$ ccgo vendor --path .deps

# Vendors to .deps/ instead of vendor/

How Install Uses Vendor

When you run ccgo install, it automatically checks for vendored dependencies:

// Priority order:
1. Check vendor/{name}/ directory
2. If found  install from vendor (offline mode)
3. If not found  fetch from git/path (online mode)

Example output:

$ ccgo install

📦 Installing fmt...
   📦 Found in vendor/ directory (offline mode)
   Source: /path/to/project/vendor/fmt
    Installed from vendor to .ccgo/deps/fmt

📦 Installing json...
   📦 Found in vendor/ directory (offline mode)
   Source: /path/to/project/vendor/json
    Installed from vendor to .ccgo/deps/json

Vendor Directory Structure

vendor/
├── .vendor.toml          # Vendor manifest (auto-generated)
├── fmt/                  # Vendored dependency
│   ├── include/
│   ├── src/
│   └── CMakeLists.txt
├── json/
│   └── ...
└── gtest/
    └── ...

.vendor.toml Format

# Auto-generated by ccgo vendor
# Do not edit manually

version = 1

[metadata]
generated_at = "2026-01-21T10:30:00+08:00"
ccgo_version = "3.0.11"
lockfile_hash = "abc123..."

[[package]]
name = "fmt"
version = "10.0.0"
source = "git+https://github.com/fmtlib/fmt"
vendored_at = "2026-01-21T10:30:00+08:00"
checksum = "sha256:def456..."

[[package]]
name = "json"
version = "3.11.2"
source = "git+https://github.com/nlohmann/json"
vendored_at = "2026-01-21T10:30:00+08:00"
checksum = "sha256:ghi789..."

Common Workflows

CI/CD Pipeline with Vendoring

# .github/workflows/build.yml
name: Build

on: [push]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      # Dependencies are already in vendor/ - no download needed!
      - name: Install dependencies
        run: ccgo install

      - name: Build
        run: ccgo build linux

Benefits: - ⚡ No dependency download time - 🔒 No network failures during builds - 📦 Consistent builds across runs

Air-Gapped Environment

For environments without internet access:

# On connected machine:
ccgo install          # Download dependencies
ccgo vendor           # Cache to vendor/
tar czf project.tar.gz .

# Transfer project.tar.gz to air-gapped machine

# On air-gapped machine:
tar xzf project.tar.gz
cd project/
ccgo install          # Uses vendored copies
ccgo build linux      # Build offline

Updating Vendored Dependencies

# 1. Update dependency version in CCGO.toml
vim CCGO.toml

# 2. Update lockfile
ccgo install

# 3. Sync vendor/ with new versions
ccgo vendor --sync

# 4. Commit changes
git add CCGO.toml CCGO.lock vendor/
git commit -m "deps: update fmt to v10.1.0"

Best Practices

✅ DO

  • Vendor after locking - Always run ccgo install before ccgo vendor
  • Commit vendor/ - Include vendor/ in version control
  • Verify regularly - Run ccgo vendor --verify in CI
  • Document - Add note in README about vendoring
  • Review changes - Review vendored dependency changes in PRs

❌ DON'T

  • Don't edit manually - Never modify files in vendor/ directly
  • Don't mix modes - Don't mix vendored and non-vendored dependencies
  • Don't ignore lockfile - Always commit CCGO.lock with vendor/
  • Don't vendor build artifacts - .git/, target/, build/ are automatically excluded

Troubleshooting

Problem: "No CCGO.lock found"

Solution: Run ccgo install first to generate the lockfile:

$ ccgo install    # Generates CCGO.lock
$ ccgo vendor     # Now works

Problem: Vendor verification fails

Solution: Re-sync vendor directory:

$ ccgo vendor --verify   # Shows what's wrong
$ ccgo vendor --sync     # Fixes issues

Problem: Vendor directory too large

Causes: - Vendoring includes large test/doc files - .git directories not stripped

Solutions:

# Strip .git directories (default)
ccgo vendor --strip-git=true

# Manually clean up vendored dependencies:
rm -rf vendor/*/docs vendor/*/tests vendor/*/examples

Problem: Git clone fails during vendor

Possible causes: - Network issues - Git not installed - Invalid git URL in CCGO.toml

Solution:

# Check git installation
git --version

# Check dependency source
cat CCGO.toml | grep git

# Manually test clone
git clone <url>

Configuration

.gitignore

If you DON'T want to commit vendor/:

# Don't commit vendored dependencies
vendor/
!vendor/.vendor.toml

If you DO want to commit vendor/ (recommended):

# Commit vendor/ for offline builds
# (no entries needed)

CCGO.toml

No special configuration needed. Vendoring works with any dependency:

[[dependencies]]
name = "fmt"
version = "10.0.0"
git = "https://github.com/fmtlib/fmt"

[[dependencies]]
name = "mylib"
version = "1.0.0"
path = "../mylib"  # Path dependencies also vendored

Performance Impact

Vendor Time

Dependencies First Vendor Subsequent (--sync)
1-5 deps ~5-10s ~1-2s
5-10 deps ~10-30s ~2-5s
10+ deps ~30-60s ~5-10s

Install Time (with vendor)

Dependencies Without Vendor With Vendor Speedup
1-5 deps ~10-30s ~1-2s 10x
5-10 deps ~30-60s ~2-5s 10x
10+ deps ~60-120s ~5-10s 12x

Why so fast? - No git clone operations - No network latency - Simple file copy/symlink

Security Considerations

Auditing Vendored Dependencies

Review vendored code before committing:

# Vendor dependencies
ccgo vendor

# Review changes
git diff vendor/

# Check for suspicious files
find vendor/ -name "*.so" -o -name "*.dll" -o -name "*.exe"

# Commit after review
git add vendor/
git commit -m "vendor: add dependencies"

Checksum Verification

.vendor.toml includes SHA-256 checksums (TODO: implement):

[[package]]
name = "fmt"
checksum = "sha256:abc123..."  # Verifies integrity

To verify:

ccgo vendor --verify  # Checks checksums

See Also

Changelog

v3.0.11 (2026-01-21)

  • ✅ Implemented dependency vendoring
  • ✅ Added ccgo vendor command
  • ✅ Auto-detection of vendor/ in ccgo install
  • ✅ Vendor verification and sync
  • ✅ Generated .vendor.toml manifest

This feature enables offline builds and reproducible environments for enterprise and security-conscious users.