# 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
```bash
# 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**:
```bash
$ 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**:
```bash
$ ccgo vendor --verify
🔍 Verifying vendor directory...
✓ Vendor directory is up-to-date
3 packages verified
```
**Error case**:
```bash
$ 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**:
```bash
$ 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**:
```bash
$ 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**:
```bash
$ 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:
```rust
// 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**:
```bash
$ 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
```toml
# 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
```yaml
# .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:
```bash
# 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
```bash
# 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:
```bash
$ ccgo install # Generates CCGO.lock
$ ccgo vendor # Now works
```
### Problem: Vendor verification fails
**Solution**: Re-sync vendor directory:
```bash
$ 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**:
```bash
# 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**:
```bash
# Check git installation
git --version
# Check dependency source
# Manually test clone
git clone <url>
```
## Configuration
### .gitignore
If you **DON'T** want to commit vendor/:
```gitignore
# Don't commit vendored dependencies
vendor/
!vendor/.vendor.toml
```
If you **DO** want to commit vendor/ (recommended):
```gitignore
# Commit vendor/ for offline builds
# (no entries needed)
```
### CCGO.toml
No special configuration needed. Vendoring works with any dependency:
```toml
[[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
| 1-5 deps | ~5-10s | ~1-2s |
| 5-10 deps | ~10-30s | ~2-5s |
| 10+ deps | ~30-60s | ~5-10s |
### Install Time (with vendor)
| 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:
```bash
# 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):
```toml
[[package]]
name = "fmt"
checksum = "sha256:abc123..." # Verifies integrity
```
To verify:
```bash
ccgo vendor --verify # Checks checksums
```
## See Also
- [Dependency Resolution](dependency-resolution.md) - Transitive dependency handling
- [CCGO.toml Reference](reference/ccgo-toml.md) - Configuration file specification
- [CLI Reference](reference/cli.md) - Command line interface
## 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.*