core

package
v1.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 18, 2026 License: MIT Imports: 37 Imported by: 0

Documentation

Overview

Package core implements the business logic for git-vendor including configuration, syncing, and Git operations.

Index

Constants

View Source
const (
	ExitSuccess          = 0
	ExitGeneralError     = 1
	ExitVendorNotFound   = 2
	ExitInvalidArguments = 3
	ExitValidationFailed = 4
	ExitNetworkError     = 5
)

CLI exit codes for LLM-friendly commands (Spec 072).

View Source
const (
	ErrCodeVendorNotFound   = "VENDOR_NOT_FOUND"
	ErrCodeVendorExists     = "VENDOR_EXISTS"
	ErrCodeMappingNotFound  = "MAPPING_NOT_FOUND"
	ErrCodeMappingExists    = "MAPPING_EXISTS"
	ErrCodeInvalidArguments = "INVALID_ARGUMENTS"
	ErrCodeNotInitialized   = "NOT_INITIALIZED"
	ErrCodeConfigError      = "CONFIG_ERROR"
	ErrCodeValidationFailed = "VALIDATION_FAILED"
	ErrCodeNetworkError     = "NETWORK_ERROR"
	ErrCodeInternalError    = "INTERNAL_ERROR"
	ErrCodeRefNotFound      = "REF_NOT_FOUND"
	ErrCodeInvalidKey       = "INVALID_KEY"
)

CLI error codes for structured JSON error responses.

View Source
const (
	// VendorDir is the root directory for all vendor-related files.
	// Uses dotfile convention to avoid clashing with Go's vendor/ directory
	// and similar conventions in Ruby (Bundler), PHP (Composer), Rust (cargo vendor).
	VendorDir = ".git-vendor"
	// ConfigFile is the vendor configuration filename
	ConfigFile = "vendor.yml"
	// LockFile is the vendor lock filename
	LockFile = "vendor.lock"
	// LicensesDir is the directory containing cached license files
	LicensesDir = "licenses"
	// CacheDir is the directory for incremental sync cache
	CacheDir = ".cache"
)

File and directory names

View Source
const (
	// ConfigPath is the full path to vendor.yml
	ConfigPath = VendorDir + "/" + ConfigFile
	// LockPath is the full path to vendor.lock
	LockPath = VendorDir + "/" + LockFile
	// LicensesPath is the full path to the licenses directory
	LicensesPath = VendorDir + "/" + LicensesDir
	// CachePath is the full path to the cache directory
	CachePath = VendorDir + "/" + CacheDir
)

Full paths relative to project root. Use these instead of manually concatenating VendorDir + "/" + filename.

View Source
const (
	// DefaultRef is the default git ref used when none is specified
	DefaultRef = "main"
	// FetchHead is the git FETCH_HEAD reference
	FetchHead = "FETCH_HEAD"
	// RefLocal is the sentinel ref for internal vendors (no git operations)
	RefLocal = "local"
)

Git refs

View Source
const (
	// SourceInternal marks a vendor as sourced from within the same repository
	SourceInternal = "internal"
	// ComplianceSourceCanonical means source file is authoritative; dest overwrites are normal
	ComplianceSourceCanonical = "source-canonical"
	// ComplianceBidirectional means changes in either direction propagate to the other
	ComplianceBidirectional = "bidirectional"
)

Internal vendor constants (Spec 070)

View Source
const (
	// CurrentSchemaVersion is the version written to new lockfiles.
	// Bumped to 1.2 for Spec 070 (internal vendor Source/SourceFileHashes fields).
	CurrentSchemaVersion = "1.3"
	// MaxSupportedMajor is the maximum major version this CLI can handle
	MaxSupportedMajor = 1
	// MaxSupportedMinor is the maximum minor version this CLI fully understands
	MaxSupportedMinor = 3
)

Schema version constants

View Source
const (
	// PolicyFile is the license policy configuration file at the project root.
	PolicyFile = ".git-vendor-policy.yml"
)

Project-root configuration files (outside .git-vendor/).

View Source
const VendorNoteRef = "refs/notes/vendor"

VendorNoteRef is the git notes namespace for vendor metadata. Notes stored under refs/notes/vendor contain JSON with rich per-vendor provenance data that would be too verbose for inline trailers.

Variables

View Source
var (
	// ErrNotInitialized indicates the vendor directory doesn't exist
	ErrNotInitialized = errors.New("vendor directory not found. Run 'git-vendor init' first")

	// ErrComplianceFailed indicates a license compliance check failed
	ErrComplianceFailed = errors.New("compliance check failed")
)

Sentinel errors for common error conditions. Sentinel errors can be used with errors.Is() for error type checking.

View Source
var AllowedLicenses = []string{
	"MIT",
	"Apache-2.0",
	"BSD-3-Clause",
	"BSD-2-Clause",
	"ISC",
	"Unlicense",
	"CC0-1.0",
}

AllowedLicenses defines the list of open-source licenses permitted by default. AllowedLicenses uses SPDX license identifiers.

View Source
var ErrLockConflict = errors.New("git merge conflict detected in vendor.lock")

ErrLockConflict indicates git merge conflict markers were detected in vendor.lock.

View Source
var LicenseFileNames = []string{
	"LICENSE",
	"LICENSE.txt",
	"LICENSE.md",
	"COPYING",
}

LicenseFileNames lists standard filenames checked when searching for repository licenses. LicenseFileNames entries are checked in order when detecting licenses via file content.

View Source
var Verbose = false

Verbose controls whether git commands are logged

Functions

func AnnotateVendorCommit added in v1.1.0

func AnnotateVendorCommit(ctx context.Context, gitClient GitClient, configStore ConfigStore,
	lockStore LockStore, rootDir, commitHash, vendorFilter string) error

AnnotateVendorCommit retroactively attaches vendor metadata to an existing commit. AnnotateVendorCommit is used when a human manually commits vendor changes and wants to add structured provenance after the fact via "git vendor annotate".

commitHash is the commit to annotate (empty = HEAD). vendorFilter restricts to a single vendor (empty = all from lockfile).

func CLIErrorCodeForError added in v1.1.0

func CLIErrorCodeForError(err error) string

CLIErrorCodeForError maps structured error types to CLI error code strings.

func CLIExitCodeForError added in v1.1.0

func CLIExitCodeForError(err error) int

CLIExitCodeForError maps structured error types to CLI exit codes.

func CVSSToSeverity added in v1.1.0

func CVSSToSeverity(score float64) string

CVSSToSeverity converts a CVSS score to severity string. Thresholds based on CVSS v3.0 qualitative severity rating scale: - Critical: 9.0-10.0 - High: 7.0-8.9 - Medium: 4.0-6.9 - Low: 0.1-3.9 - Unknown: 0.0 (no score available)

func CommitVendorChanges added in v1.1.0

func CommitVendorChanges(ctx context.Context, gitClient GitClient, configStore ConfigStore,
	lockStore LockStore, rootDir, operation, vendorFilter string) error

CommitVendorChanges stages and commits all vendor changes in a single commit with multi-valued COMMIT-SCHEMA v1 trailers, then attaches a git note with rich per-vendor metadata under refs/notes/vendor.

Flow:

  1. Load config + lock
  2. Filter lock entries by vendorFilter (empty = all)
  3. Collect all affected paths across all matching vendors
  4. Stage all paths in one git add
  5. Build multi-valued trailers (one Vendor-Name/Ref/Commit group per vendor)
  6. Create single commit
  7. Read back HEAD hash
  8. Attach JSON note with rich metadata

CommitVendorChanges creates exactly one commit regardless of vendor count. For per-vendor provenance, consumers read the structured trailers or note.

func ComputeAutoPath

func ComputeAutoPath(sourcePath, defaultTarget, fallbackName string) string

ComputeAutoPath generates automatic path name with consistent logic. This consolidates 4 duplicate instances of auto-naming logic in vendor_syncer.go.

Parameters:

  • sourcePath: The source path from the remote repository
  • defaultTarget: Optional default target directory from spec.DefaultTarget
  • fallbackName: Fallback name to use if path cannot be derived (typically vendor name)

Returns: The computed destination path

func DefaultLicensePolicy added in v1.1.0

func DefaultLicensePolicy() types.LicensePolicy

DefaultLicensePolicy returns a policy based on the existing AllowedLicenses list. DefaultLicensePolicy is used when no .git-vendor-policy.yml file is found.

func EmitCLIError added in v1.1.0

func EmitCLIError(code string, message string, exitCode int) int

EmitCLIError writes an error CLIResponse as JSON to stdout and exits with the given code. Returns the exit code for the caller to use with os.Exit.

func EmitCLISuccess added in v1.1.0

func EmitCLISuccess(data interface{})

EmitCLISuccess writes a successful CLIResponse as JSON to stdout and exits with code 0.

func ExtractPosition added in v1.1.0

func ExtractPosition(filePath string, pos *types.PositionSpec) (string, string, error)

ExtractPosition reads a file and extracts the content specified by a PositionSpec. Returns the extracted content as a string and the SHA-256 hash of that content. Returns an error if the file appears to be binary (contains null bytes).

func ExtractVendorTouch added in v1.1.0

func ExtractVendorTouch(specs []*types.VendorSpec) []string

ExtractVendorTouch derives Touch area tags from vendor destination paths. ExtractVendorTouch converts directory paths to dot-separated area identifiers:

"pkg/git-plumbing/hook.go"    → "pkg.git-plumbing"
".claude/hooks/guard.sh"      → "claude.hooks"
"internal/core/engine.go"     → "internal.core"
"root.go"                     → "" (no directory = no area)

Results are deduplicated and sorted for deterministic trailer output. #vendor.touch #commit-schema

func FetchWithFallback added in v1.1.0

func FetchWithFallback(
	ctx context.Context,
	gitClient GitClient,
	fs FileSystem,
	ui UICallback,
	tempDir string,
	urls []string,
	ref string,
	depth int,
) (usedURL string, err error)

FetchWithFallback tries fetching from each URL in order until one succeeds. FetchWithFallback returns the URL that succeeded and nil error, or empty string and the last error if all URLs fail.

Strategy: the first URL is added as "origin" via AddRemote. Subsequent URLs are swapped in via SetRemoteURL to avoid multiple named remotes (which would complicate ref resolution like "origin/main" vs "mirror1/main").

func FindVendor

func FindVendor(vendors []types.VendorSpec, name string) *types.VendorSpec

FindVendor returns the vendor with matching name, or nil if not found. This consolidates 4 duplicate instances of vendor lookup across vendor_syncer.go

func FindVendorIndex

func FindVendorIndex(vendors []types.VendorSpec, name string) int

FindVendorIndex returns the index of vendor with matching name, or -1 if not found. Useful for update and delete operations that need the index.

func ForEachMapping

func ForEachMapping(vendor *types.VendorSpec, fn func(spec types.BranchSpec, mapping types.PathMapping) error) error

ForEachMapping iterates over all path mappings in a vendor. This replaces duplicate triple-nested loops (2 instances in vendor_syncer.go).

func ForEachVendor

func ForEachVendor(config types.VendorConfig, fn func(types.VendorSpec) error) error

ForEachVendor applies function to each vendor in config. Returns early if function returns an error.

func FormatAuditTable added in v1.1.0

func FormatAuditTable(result *types.AuditResult) string

FormatAuditTable formats an AuditResult as a human-readable table string.

func FormatCLIMessage added in v1.1.0

func FormatCLIMessage(format string, args ...interface{})

FormatCLIMessage formats a simple text message for non-JSON CLI output.

func FormatDiffOutput

func FormatDiffOutput(diff *types.VendorDiff) string

FormatDiffOutput formats a VendorDiff for display

func FormatDriftOutput added in v1.1.0

func FormatDriftOutput(dep *types.DriftDependency, offline bool) string

FormatDriftOutput formats a DriftDependency for human-readable display.

func GetGitUserIdentity added in v1.1.0

func GetGitUserIdentity() string

GetGitUserIdentity returns the git user identity in "Name <email>" format. Returns empty string if not configured. Uses git-plumbing with empty Dir to match original behavior (process working directory).

func IsBinaryContent added in v1.1.0

func IsBinaryContent(data []byte) bool

IsBinaryContent checks whether data appears to be binary by scanning for null bytes in the first 8000 bytes. Matches git's binary detection heuristic (xdiff/xutils.c:xdl_mmfile_istext). Position extraction on binary files produces garbage output, so ExtractPosition and PlaceContent reject binary content with a clear error.

SEC-023: Exported for use by file_copy_service.go to warn on whole-file binary copies and by tests to verify binary detection behavior.

func IsCheckoutError added in v1.1.0

func IsCheckoutError(err error) bool

IsCheckoutError returns true if err is a CheckoutError.

func IsComplianceConflictError added in v1.1.0

func IsComplianceConflictError(err error) bool

IsComplianceConflictError returns true if err is a ComplianceConflictError.

func IsCycleError added in v1.1.0

func IsCycleError(err error) bool

IsCycleError returns true if err is a CycleError.

func IsGitInstalled

func IsGitInstalled() bool

IsGitInstalled checks if git is available on the system

func IsGroupNotFound added in v1.1.0

func IsGroupNotFound(err error) bool

IsGroupNotFound returns true if err is a GroupNotFoundError.

func IsHookError added in v1.1.0

func IsHookError(err error) bool

IsHookError returns true if err is a HookError.

func IsLocalPath added in v1.1.0

func IsLocalPath(rawURL string) bool

IsLocalPath detects whether rawURL points to a local filesystem path. Matches file:// scheme, relative paths (./ ../), Unix absolute paths (/), and Windows drive letters (C:\, D:/).

func IsLockConflictError added in v1.1.0

func IsLockConflictError(err error) bool

IsLockConflictError returns true if err is a LockConflictError.

func IsOSVAPIError added in v1.1.0

func IsOSVAPIError(err error) bool

IsOSVAPIError returns true if err is an OSVAPIError.

func IsPathNotFound added in v1.1.0

func IsPathNotFound(err error) bool

IsPathNotFound returns true if err is a PathNotFoundError.

func IsStaleCommit added in v1.1.0

func IsStaleCommit(err error) bool

IsStaleCommit returns true if err is a StaleCommitError.

func IsValidationError added in v1.1.0

func IsValidationError(err error) bool

IsValidationError returns true if err is a ValidationError.

func IsVendorInitialized

func IsVendorInitialized() bool

IsVendorInitialized checks if the vendor directory structure exists

func IsVendorNotFound added in v1.1.0

func IsVendorNotFound(err error) bool

IsVendorNotFound returns true if err is a VendorNotFoundError.

func LoadLicensePolicy added in v1.1.0

func LoadLicensePolicy(path string) (types.LicensePolicy, error)

LoadLicensePolicy reads and parses a license policy file. LoadLicensePolicy returns DefaultLicensePolicy when the file does not exist. LoadLicensePolicy returns an error if the file exists but is malformed.

func MatchesExclude added in v1.1.0

func MatchesExclude(relPath string, patterns []string) bool

MatchesExclude reports whether relPath matches any of the given exclude patterns. Patterns use gitignore-style globs:

  • "*" matches any sequence of non-separator characters
  • "**" matches any sequence of characters including separators (recursive)
  • "?" matches any single non-separator character

Examples:

  • "*.md" matches "README.md" but not "docs/guide.md"
  • ".claude/**" matches ".claude/settings.json" and ".claude/rules/foo.md"
  • "docs/internal/**" matches "docs/internal/design.md"

All paths are normalized to forward slashes before matching.

func MergeLockEntries added in v1.1.0

func MergeLockEntries(ours, theirs *types.VendorLock) types.LockMergeResult

MergeLockEntries merges two VendorLock structs into one. Non-overlapping vendors are combined directly. For overlapping entries (same vendor name + ref), the entry with the later Updated timestamp wins. If timestamps are equal, the higher CommitHash (lexicographic) wins. If neither heuristic resolves the conflict, it is flagged in LockMergeResult.Conflicts for manual resolution.

func ParseSmartURL

func ParseSmartURL(rawURL string) (baseURL, ref, path string)

ParseSmartURL extracts repository, ref, and path from GitHub URLs

func PlaceContent added in v1.1.0

func PlaceContent(filePath string, content string, pos *types.PositionSpec) error

PlaceContent writes extracted content into a target file at the specified position. If pos is nil, the content replaces the entire file. If pos specifies a range, only that range in the target is replaced.

Security: PlaceContent self-validates relative paths via ValidateDestPath to block path traversal (e.g., "../../../etc/passwd"). Absolute paths bypass validation because absolute paths originate from internal/test usage with temp directories. Production callers also validate at the service layer — see file_copy_service.go:copyMapping.

func Pluralize

func Pluralize(count int, singular, plural string) string

Pluralize returns the singular or plural form based on count. Examples:

Pluralize(1, "vendor", "vendors") => "1 vendor"
Pluralize(2, "vendor", "vendors") => "2 vendors"
Pluralize(0, "vendor", "vendors") => "0 vendors"

func ResolveLocalURL added in v1.1.0

func ResolveLocalURL(rawURL, vendorDir string) (string, error)

ResolveLocalURL resolves a local vendor URL to an absolute file:// URL. Relative paths are resolved against filepath.Dir(vendorDir), which is the project root. Absolute file:// URLs pass through after path validation. Returns an error if the resolved path does not exist or is not a directory.

func ResolveVendorURLs added in v1.1.0

func ResolveVendorURLs(v *types.VendorSpec) []string

ResolveVendorURLs returns the ordered list of URLs to try for a vendor. Primary URL first, then mirrors in declaration order. Internal vendors (Source == "internal") return nil — they have no remote URLs.

func SanitizeURL added in v1.1.0

func SanitizeURL(rawURL string) string

SanitizeURL removes embedded credentials from a URL for safe logging. Strips userinfo (user:password@) from URLs with a scheme. SCP-style URLs (git@host:path) are returned unchanged because "git" is the username, not a secret.

func TopologicalSort added in v1.1.0

func TopologicalSort(graph map[string][]string) ([]string, error)

TopologicalSort performs a topological sort on the dependency graph using Kahn's algorithm. Returns the projects in dependency order (dependencies first) or an error if a cycle is detected.

TopologicalSort expects graph to contain all projects as keys, even if they have no dependencies (nil/empty slice).

func ValidateDestPath

func ValidateDestPath(destPath string) error

ValidateDestPath ensures destination path is safe and doesn't allow path traversal. ValidateDestPath strips any position specifier (e.g., ":L5-L10") before validation, so paths like "config.go:L5-L10" are accepted if the file path part is valid.

func ValidateVendorName added in v1.1.0

func ValidateVendorName(name string) error

ValidateVendorName ensures a vendor name is safe for use in filesystem paths. Rejects names containing path separators, traversal sequences, or null bytes. Called during config validation and before license file copy to block malicious vendor.yml entries before they reach any filesystem operation.

func ValidateVendorURL added in v1.1.0

func ValidateVendorURL(rawURL string) error

ValidateVendorURL checks that a repository URL uses a safe scheme. Rejects file://, ftp://, and other non-git schemes that could access the local filesystem or use insecure protocols.

SEC-011: Accepted schemes: https, http, ssh, git, git+ssh, and SCP-style (git@host:owner/repo). Bare hostnames without a scheme are also accepted for compatibility with custom git server configurations.

func VendorCommitSubject added in v1.1.0

func VendorCommitSubject(locks []types.LockDetails, operation string) string

VendorCommitSubject formats a conventional-commits subject line for vendor operations. VendorCommitSubject produces:

  • Single vendor: "chore(vendor): <operation> <name> to <ref>"
  • Multiple vendors: "chore(vendor): <operation> <N> vendors"

func VendorNoteJSON added in v1.1.0

func VendorNoteJSON(locks []types.LockDetails, specMap map[string]*types.VendorSpec) (string, error)

VendorNoteJSON builds the JSON note content for a vendor commit. VendorNoteJSON includes rich metadata (file hashes, URLs, paths) that would be too verbose for inline trailers.

func VendorTrailers added in v1.1.0

func VendorTrailers(locks []types.LockDetails) []types.Trailer

VendorTrailers builds COMMIT-SCHEMA v1 vendor/v1 trailers for one or more lock entries. VendorTrailers returns an ordered []types.Trailer suitable for multi-valued trailer composition.

For N vendors in a single commit, trailer keys repeat N times in order:

Commit-Schema: vendor/v1   (once)
Vendor-Name: lib-a         (Nth vendor)
Vendor-Ref: main
Vendor-Commit: abc123...
Vendor-Name: lib-b         (N+1th vendor)
Vendor-Ref: v2
Vendor-Commit: def456...

Optional trailers (Vendor-License, Vendor-Source-Tag) are included per-vendor only when the corresponding LockDetails field is non-empty.

Types

type AcceptOptions added in v1.1.0

type AcceptOptions struct {
	VendorName string // Target vendor (required)
	FilePath   string // Specific file to accept (empty = all modified files)
	Clear      bool   // Remove accepted_drift entries instead of adding
	NoCommit   bool   // Skip auto-commit of lockfile change
}

AcceptOptions configures the accept command behavior. #cli.accept #drift

type AcceptResult added in v1.1.0

type AcceptResult struct {
	VendorName    string   `json:"vendor_name"`              // Vendor that was operated on
	AcceptedFiles []string `json:"accepted_files,omitempty"` // Files whose drift was accepted (empty for --clear)
	ClearedFiles  []string `json:"cleared_files,omitempty"`  // Files whose accepted drift was cleared (empty for non-clear)
}

AcceptResult holds the outcome of an accept operation. AcceptResult reports which files were accepted or cleared for audit trail purposes.

type AcceptService added in v1.1.0

type AcceptService struct {
	// contains filtered or unexported fields
}

AcceptService handles drift acceptance for vendored files. AcceptService re-hashes local files and writes accepted_drift entries to the lockfile, allowing verify/status to report those files as "accepted" rather than "modified".

func NewAcceptService added in v1.1.0

func NewAcceptService(lockStore LockStore, cache CacheStore) *AcceptService

NewAcceptService creates a new AcceptService with the given dependencies.

func (*AcceptService) Accept added in v1.1.0

func (s *AcceptService) Accept(opts AcceptOptions) (*AcceptResult, error)

Accept processes drift acceptance or clearing for a vendor's files. When Clear is false, Accept computes local hashes for files with lock mismatches and writes them to accepted_drift. When Clear is true, Accept removes accepted_drift entries for the vendor (or a specific file).

type AuditOptions added in v1.1.0

type AuditOptions struct {
	SkipVerify  bool // Skip file integrity check
	SkipScan    bool // Skip vulnerability scan
	SkipLicense bool // Skip license compliance check
	SkipDrift   bool // Skip drift detection

	ScanFailOn        string // Severity threshold for scan (critical|high|medium|low)
	LicenseFailOn     string // License fail level: "deny" (default) or "warn"
	LicensePolicyPath string // Override license policy file path (empty = default)
}

AuditOptions configures which sub-checks the audit command runs and their thresholds.

type AuditService added in v1.1.0

type AuditService struct {
	// contains filtered or unexported fields
}

AuditService orchestrates verify, scan, license, and drift sub-checks into a unified audit report.

func NewAuditService added in v1.1.0

func NewAuditService(
	verifyService VerifyServiceInterface,
	vulnScanner VulnScannerInterface,
	driftService DriftServiceInterface,
	configStore ConfigStore,
	lockStore LockStore,
) *AuditService

NewAuditService creates a new AuditService with injected sub-service dependencies.

func (*AuditService) Audit added in v1.1.0

Audit runs all enabled sub-checks and produces a combined AuditResult. Each sub-check is independently error-handled — a failure in one does not prevent the others from running. Context cancellation aborts all remaining checks.

type AuditServiceInterface added in v1.1.0

type AuditServiceInterface interface {
	// Audit runs all enabled sub-checks (verify, scan, license, drift) and
	// returns a combined AuditResult. A failed sub-check does NOT abort the others.
	// ctx controls cancellation for network-dependent operations (scan, drift).
	Audit(ctx context.Context, opts AuditOptions) (*types.AuditResult, error)
}

AuditServiceInterface defines the contract for the unified audit command.

type CLIErrorDetail added in v1.1.0

type CLIErrorDetail struct {
	Code    string `json:"code"`
	Message string `json:"message"`
}

CLIErrorDetail contains machine-readable error code and human-readable message.

type CLIResponse added in v1.1.0

type CLIResponse struct {
	Success bool            `json:"success"`
	Data    interface{}     `json:"data,omitempty"`
	Error   *CLIErrorDetail `json:"error,omitempty"`
}

CLIResponse is the structured JSON output for LLM-friendly CLI commands (Spec 072). All new commands use this format. Existing commands retain their JSONOutput format for backward compatibility.

Schema:

{
  "success": true|false,
  "data": { ... },          // Command-specific payload (omitted on error)
  "error": {                 // Present only on failure
    "code": "VENDOR_NOT_FOUND",
    "message": "Human-readable description"
  }
}

type CacheStore

type CacheStore interface {
	Load(vendorName, ref string) (types.IncrementalSyncCache, error)
	Save(cache *types.IncrementalSyncCache) error
	Delete(vendorName, ref string) error
	ComputeFileChecksum(path string) (string, error)
	BuildCache(vendorName, ref, commitHash string, files []string) (types.IncrementalSyncCache, error)
}

CacheStore handles incremental sync cache I/O operations

type CascadeConfig added in v1.1.0

type CascadeConfig struct {
	Root          string `yaml:"root,omitempty"`
	VerifyCommand string `yaml:"verify_command,omitempty"`
	Commit        bool   `yaml:"commit,omitempty"`
}

CascadeConfig represents the optional cascade section in vendor.yml. CascadeConfig is read from each sibling project's vendor.yml to configure cascade behavior for that project.

type CascadeFailure added in v1.1.0

type CascadeFailure struct {
	Project string `json:"project"` // Project directory name
	Phase   string `json:"phase"`   // "pull", "verify", "commit", or "push"
	Error   string `json:"error"`   // Error message
}

CascadeFailure records a project that failed during cascade.

type CascadeOptions added in v1.1.0

type CascadeOptions struct {
	Root          string // Parent directory containing sibling repos (default: "..")
	DryRun        bool   // Preview the graph walk without executing
	Verify        bool   // Run verify_command after each pull
	Commit        bool   // Auto-commit after each pull
	Push          bool   // Auto-push after each commit
	PR            bool   // Create branch + PR instead of direct commit
	VerifyCommand string // Override verify command (default from vendor.yml or "go build ./...")
}

CascadeOptions configures the cascade command behavior. CascadeOptions controls how the dependency graph is walked and what side effects (verify, commit, push) are performed after each pull.

type CascadeProjectResult added in v1.1.0

type CascadeProjectResult struct {
	Name         string      `json:"name"`                    // Project directory name
	Dir          string      `json:"dir"`                     // Absolute path to the project directory
	PullResult   *PullResult `json:"pull_result,omitempty"`   // Result from pull operation (nil if skipped/failed)
	VerifyPassed bool        `json:"verify_passed"`           // Whether verify command succeeded (false if not run)
	VerifyOutput string      `json:"verify_output,omitempty"` // Stdout/stderr from verify command
	PRInfo       string      `json:"pr_info,omitempty"`       // PR URL or manual instructions (populated when --pr is used)
	Error        error       `json:"-"`                       // Non-nil if pull or verify failed (excluded from JSON; use Failed slice)
}

CascadeProjectResult holds the pull outcome for a single project in the cascade.

type CascadeResult added in v1.1.0

type CascadeResult struct {
	Order          []string                         `json:"order"`                     // Topological order of projects walked
	Updated        []string                         `json:"updated,omitempty"`         // Projects that had files updated by pull
	Current        []string                         `json:"current,omitempty"`         // Projects that were already current (no changes)
	Failed         []CascadeFailure                 `json:"failed,omitempty"`          // Projects that encountered errors
	Skipped        []string                         `json:"skipped,omitempty"`         // Projects skipped (no vendor.yml)
	ProjectResults map[string]*CascadeProjectResult `json:"project_results,omitempty"` // Per-project details keyed by project name
}

CascadeResult summarizes the outcome of a cascade operation.

type CascadeService added in v1.1.0

type CascadeService struct {
	// contains filtered or unexported fields
}

CascadeService implements the cascade command's dependency graph walk. CascadeService discovers sibling repos, builds a DAG from vendor relationships, topologically sorts, and runs pull in order.

func NewCascadeService added in v1.1.0

func NewCascadeService(rootDir string) *CascadeService

NewCascadeService creates a CascadeService rooted at the given directory. NewCascadeService expects rootDir to be an absolute path to the parent directory containing sibling project directories.

func (*CascadeService) BuildDAG added in v1.1.0

func (cs *CascadeService) BuildDAG() (graph map[string][]string, projectDirs map[string]string, err error)

BuildDAG constructs a directed acyclic graph from vendor.yml files across sibling projects. An edge from project A to project B exists when A vendors files from B's URL (matched by checking if any vendor URL contains B's directory name or remote URL).

BuildDAG returns:

  • graph: adjacency list mapping project name to its dependencies
  • projectDirs: map of project name to absolute directory path
  • error: if sibling discovery or config loading fails

func (*CascadeService) Cascade added in v1.1.0

func (cs *CascadeService) Cascade(ctx context.Context, opts CascadeOptions) (*CascadeResult, error)

Cascade walks the dependency graph in topological order and runs pull in each project directory. Cascade respects context cancellation for Ctrl+C support.

Flow:

  1. Validate mutually exclusive options (--pr vs --push)
  2. Build DAG from sibling vendor.yml files
  3. Topological sort (error on cycles)
  4. Walk in order: cd into each project and run pull
  5. Optionally: verify, commit/PR, push after each pull
  6. Return summary of results

type CheckoutError added in v1.1.0

type CheckoutError struct {
	Target     string // commit hash or ref being checked out
	VendorName string
	Cause      error
}

CheckoutError is returned when git checkout fails.

func NewCheckoutError added in v1.1.0

func NewCheckoutError(target, vendorName string, cause error) *CheckoutError

NewCheckoutError creates a CheckoutError.

func (*CheckoutError) Error added in v1.1.0

func (e *CheckoutError) Error() string

func (*CheckoutError) Unwrap added in v1.1.0

func (e *CheckoutError) Unwrap() error

type ComplianceConflictError added in v1.1.0

type ComplianceConflictError struct {
	VendorName string
	From       string
	To         string
}

ComplianceConflictError is returned when both source and destination have drifted for an internal vendor mapping, requiring manual resolution.

func NewComplianceConflictError added in v1.1.0

func NewComplianceConflictError(vendorName, from, to string) *ComplianceConflictError

NewComplianceConflictError creates a ComplianceConflictError.

func (*ComplianceConflictError) Error added in v1.1.0

func (e *ComplianceConflictError) Error() string

type ComplianceOptions added in v1.1.0

type ComplianceOptions struct {
	VendorName string // Empty = all internal vendors
	DryRun     bool
	Reverse    bool // Apply dest->source for source-canonical mode
}

ComplianceOptions configures compliance check and propagation behavior.

type ComplianceService added in v1.1.0

type ComplianceService struct {
	// contains filtered or unexported fields
}

ComplianceService handles drift detection and propagation for internal vendors.

func NewComplianceService added in v1.1.0

func NewComplianceService(
	configStore ConfigStore,
	lockStore LockStore,
	cache CacheStore,
	fs FileSystem,
	rootDir string,
) *ComplianceService

NewComplianceService creates a new ComplianceService.

func (*ComplianceService) Check added in v1.1.0

Check computes current drift state for all internal vendor mappings.

func (*ComplianceService) Propagate added in v1.1.0

Propagate checks for drift and copies files according to compliance rules.

type ComplianceServiceInterface added in v1.1.0

type ComplianceServiceInterface interface {
	// Check computes drift direction for all internal vendor mappings.
	Check(opts ComplianceOptions) (*types.ComplianceResult, error)
	// Propagate performs Check, then copies changed files per compliance mode.
	Propagate(opts ComplianceOptions) (*types.ComplianceResult, error)
}

ComplianceServiceInterface defines the contract for internal vendor compliance operations.

type ConfigStore

type ConfigStore interface {
	Load() (types.VendorConfig, error)
	Save(config types.VendorConfig) error
	Path() string
}

ConfigStore handles vendor.yml I/O operations

type CopyStats

type CopyStats struct {
	FileCount int
	ByteCount int64
	Excluded  int              // Files skipped due to exclude patterns
	Positions []positionRecord // Position-extracted mappings (for lockfile tracking)
	Warnings  []string         // Non-fatal warnings generated during copy
	Removed   []string         // Destination paths removed because upstream source was deleted
}

CopyStats tracks file copy statistics

func (*CopyStats) Add

func (s *CopyStats) Add(other CopyStats)

Add adds another CopyStats to CopyStats, merging all fields.

type CycleError added in v1.1.0

type CycleError struct {
	Path []string // Ordered list of files forming the cycle
}

CycleError is returned when internal vendor mappings form a circular dependency.

func NewCycleError added in v1.1.0

func NewCycleError(path []string) *CycleError

NewCycleError creates a CycleError.

func (*CycleError) Error added in v1.1.0

func (e *CycleError) Error() string

type DiffOptions added in v1.1.0

type DiffOptions struct {
	VendorName string // Filter to a single vendor by name
	Ref        string // Filter to a specific ref within matched vendors
	Group      string // Filter vendors by group membership
}

DiffOptions configures filtering for DiffVendorWithOptions. All non-empty filters are AND'd together: a vendor must match VendorName AND belong to Group AND match Ref to be included. Empty fields mean "no filter" (match all).

type DriftOptions added in v1.1.0

type DriftOptions struct {
	Dependency string // Scope to specific vendor (empty = all)
	Offline    bool   // Skip upstream fetch, report only local drift
	Detail     bool   // Include unified diff output per file
}

DriftOptions configures drift detection behavior.

type DriftService added in v1.1.0

type DriftService struct {
	// contains filtered or unexported fields
}

DriftService detects drift between vendored files, their locked origin state, and (optionally) the latest upstream state.

func NewDriftService added in v1.1.0

func NewDriftService(
	configStore ConfigStore,
	lockStore LockStore,
	gitClient GitClient,
	fs FileSystem,
	ui UICallback,
	rootDir string,
) *DriftService

NewDriftService creates a new DriftService with the given dependencies.

func (*DriftService) Drift added in v1.1.0

Drift runs drift detection across all (or a specific) vendored dependency. For each dependency, Drift compares local files against the locked commit state and (unless offline) against the latest upstream commit. ctx controls cancellation of git operations (clone, fetch, checkout).

type DriftServiceInterface added in v1.1.0

type DriftServiceInterface interface {
	Drift(ctx context.Context, opts DriftOptions) (*types.DriftResult, error)
}

DriftServiceInterface defines the contract for drift detection. DriftServiceInterface enables mocking in tests and alternative drift strategies. ctx is accepted for cancellation of network operations (git fetch/clone).

type FallbackLicenseChecker

type FallbackLicenseChecker struct {
	// contains filtered or unexported fields
}

FallbackLicenseChecker implements license detection by reading LICENSE files This is used when no API is available (Bitbucket, generic git, or API failures)

func NewFallbackLicenseChecker

func NewFallbackLicenseChecker(fs FileSystem, gitClient GitClient) *FallbackLicenseChecker

NewFallbackLicenseChecker creates a new fallback license checker

func (*FallbackLicenseChecker) CheckLicense

func (c *FallbackLicenseChecker) CheckLicense(repoURL string) (string, error)

CheckLicense reads LICENSE file from repository and attempts to detect license

type FileCacheStore

type FileCacheStore struct {
	// contains filtered or unexported fields
}

FileCacheStore implements CacheStore using JSON files in vendor/.cache/

func NewFileCacheStore

func NewFileCacheStore(fs FileSystem, rootDir string) *FileCacheStore

NewFileCacheStore creates a new FileCacheStore

func (*FileCacheStore) BuildCache

func (s *FileCacheStore) BuildCache(vendorName, ref, commitHash string, files []string) (types.IncrementalSyncCache, error)

BuildCache creates a cache entry by computing checksums for all files

func (*FileCacheStore) ComputeFileChecksum

func (s *FileCacheStore) ComputeFileChecksum(path string) (string, error)

ComputeFileChecksum computes SHA-256 hash of a file

func (*FileCacheStore) Delete

func (s *FileCacheStore) Delete(vendorName, ref string) error

Delete removes the cache file for a vendor@ref

func (*FileCacheStore) Load

func (s *FileCacheStore) Load(vendorName, ref string) (types.IncrementalSyncCache, error)

Load reads the cache file for a vendor@ref

func (*FileCacheStore) Save

Save writes the cache file for a vendor@ref

type FileConfigStore

type FileConfigStore struct {
	// contains filtered or unexported fields
}

FileConfigStore implements ConfigStore using YAMLStore

func NewFileConfigStore

func NewFileConfigStore(rootDir string) *FileConfigStore

NewFileConfigStore creates a new FileConfigStore

func (*FileConfigStore) Load

func (s *FileConfigStore) Load() (types.VendorConfig, error)

Load reads and parses vendor.yml

func (*FileConfigStore) Path

func (s *FileConfigStore) Path() string

Path returns the config file path

func (*FileConfigStore) Save

func (s *FileConfigStore) Save(cfg types.VendorConfig) error

Save writes vendor.yml

type FileCopyService

type FileCopyService struct {
	// contains filtered or unexported fields
}

FileCopyService handles copying files according to path mappings

func NewFileCopyService

func NewFileCopyService(fs FileSystem) *FileCopyService

NewFileCopyService creates a new FileCopyService

func (*FileCopyService) CopyMappings

func (s *FileCopyService) CopyMappings(tempDir string, vendor *types.VendorSpec, spec types.BranchSpec) (CopyStats, error)

CopyMappings copies all files according to path mappings for a vendor spec. Security: CopyMappings validates all destination paths via ValidateDestPath in copyMapping before any file I/O occurs.

type FileCopyServiceInterface added in v1.1.0

type FileCopyServiceInterface interface {
	CopyMappings(tempDir string, vendor *types.VendorSpec, spec types.BranchSpec) (CopyStats, error)
}

FileCopyServiceInterface defines the contract for copying files according to path mappings.

type FileLockStore

type FileLockStore struct {
	// contains filtered or unexported fields
}

FileLockStore implements LockStore using YAMLStore

func NewFileLockStore

func NewFileLockStore(rootDir string) *FileLockStore

NewFileLockStore creates a new FileLockStore

func (*FileLockStore) DetectConflicts added in v1.1.0

func (s *FileLockStore) DetectConflicts() error

DetectConflicts scans the raw lock file for git merge conflict markers (<<<<<<<, =======, >>>>>>>) and returns a LockConflictError if any are found. DetectConflicts is called before YAML parsing to provide a clear error instead of a cryptic parse failure.

func (*FileLockStore) GetHash

func (s *FileLockStore) GetHash(vendorName, ref string) string

GetHash retrieves the locked commit hash for a vendor@ref

func (*FileLockStore) Load

func (s *FileLockStore) Load() (types.VendorLock, error)

Load reads and parses vendor.lock, validating schema version compatibility. Load first checks for git merge conflict markers — returns a LockConflictError if found, providing a clear error instead of a cryptic YAML parse failure. Returns an error if the major version is unsupported. Writes a warning to stderr if minor version is newer than expected.

func (*FileLockStore) Path

func (s *FileLockStore) Path() string

Path returns the lock file path

func (*FileLockStore) Save

func (s *FileLockStore) Save(lock types.VendorLock) error

Save writes vendor.lock, always setting the current schema version.

type FileSystem

type FileSystem interface {
	CopyFile(src, dst string) (CopyStats, error)
	CopyDir(src, dst string) (CopyStats, error)
	MkdirAll(path string, perm os.FileMode) error
	ReadDir(path string) ([]string, error)
	Stat(path string) (os.FileInfo, error)
	Remove(path string) error
	CreateTemp(dir, pattern string) (string, error)
	RemoveAll(path string) error
	// ValidateWritePath checks that path is a safe write destination.
	// For rooted filesystems, this verifies the resolved path is within projectRoot.
	// For unrooted filesystems, this returns nil (no restriction).
	ValidateWritePath(path string) error
}

FileSystem abstracts file system operations for testing. Implementations that support write validation (e.g., rooted filesystems) SHOULD enforce path containment in ValidateWritePath, CopyFile, and CopyDir.

type GitClient

type GitClient interface {
	Init(ctx context.Context, dir string) error
	AddRemote(ctx context.Context, dir, name, url string) error
	Fetch(ctx context.Context, dir, remote string, depth int, ref string) error
	FetchAll(ctx context.Context, dir, remote string) error
	SetRemoteURL(ctx context.Context, dir, name, url string) error
	Checkout(ctx context.Context, dir, ref string) error
	GetHeadHash(ctx context.Context, dir string) (string, error)
	Clone(ctx context.Context, dir, url string, opts *types.CloneOptions) error
	ListTree(ctx context.Context, dir, ref, subdir string) ([]string, error)
	GetCommitLog(ctx context.Context, dir, oldHash, newHash string, maxCount int) ([]types.CommitInfo, error)
	GetTagForCommit(ctx context.Context, dir, commitHash string) (string, error)
	Add(ctx context.Context, dir string, paths ...string) error
	Commit(ctx context.Context, dir string, opts types.CommitOptions) error
	AddNote(ctx context.Context, dir, noteRef, commitHash, content string) error
	GetNote(ctx context.Context, dir, noteRef, commitHash string) (string, error)
	ConfigSet(ctx context.Context, dir, key, value string) error
	ConfigGet(ctx context.Context, dir, key string) (string, error)
	LsRemote(ctx context.Context, url, ref string) (string, error)
	Push(ctx context.Context, dir, remote, branch string) error
	CreateBranch(ctx context.Context, dir, name, startPoint string) error
}

GitClient handles git command operations

type GitHubLicenseChecker

type GitHubLicenseChecker struct {
	// contains filtered or unexported fields
}

GitHubLicenseChecker implements LicenseChecker for GitHub

func NewGitHubLicenseChecker

func NewGitHubLicenseChecker(httpClient *http.Client, allowedLicenses []string) *GitHubLicenseChecker

NewGitHubLicenseChecker creates a new GitHubLicenseChecker

func (*GitHubLicenseChecker) CheckLicense

func (c *GitHubLicenseChecker) CheckLicense(rawURL string) (string, error)

CheckLicense queries GitHub API for repository license

func (*GitHubLicenseChecker) IsAllowed

func (c *GitHubLicenseChecker) IsAllowed(license string) bool

IsAllowed checks if a license is in the allowed list

type GitLabAPIChecker

type GitLabAPIChecker struct {
	// contains filtered or unexported fields
}

GitLabAPIChecker implements license detection via GitLab API

func NewGitLabAPIChecker

func NewGitLabAPIChecker() *GitLabAPIChecker

NewGitLabAPIChecker creates a new GitLab API license checker

func (*GitLabAPIChecker) CheckLicense

func (c *GitLabAPIChecker) CheckLicense(repoURL string) (string, error)

CheckLicense queries the GitLab API for license information

GitLab API endpoint: GET /api/v4/projects/:id Documentation: https://docs.gitlab.com/ee/api/projects.html#get-single-project

Supports both gitlab.com and self-hosted instances

type GroupNotFoundError added in v1.1.0

type GroupNotFoundError struct {
	Name string
}

GroupNotFoundError is returned when a group doesn't exist in any vendor.

func NewGroupNotFoundError added in v1.1.0

func NewGroupNotFoundError(name string) *GroupNotFoundError

NewGroupNotFoundError creates a GroupNotFoundError.

func (*GroupNotFoundError) Error added in v1.1.0

func (e *GroupNotFoundError) Error() string

type HookError added in v1.1.0

type HookError struct {
	VendorName string
	Phase      string // "pre-sync" or "post-sync"
	Command    string // The hook command (truncated to 80 chars in Error() output)
	Cause      error
}

HookError is returned when a pre/post-sync hook fails.

func NewHookError added in v1.1.0

func NewHookError(vendorName, phase, command string, cause error) *HookError

NewHookError creates a HookError.

func (*HookError) Error added in v1.1.0

func (e *HookError) Error() string

func (*HookError) Unwrap added in v1.1.0

func (e *HookError) Unwrap() error

type HookExecutor

type HookExecutor interface {
	// ExecutePreSync runs pre-sync hook if configured
	ExecutePreSync(vendor *types.VendorSpec, ctx *types.HookContext) error

	// ExecutePostSync runs post-sync hook if configured
	ExecutePostSync(vendor *types.VendorSpec, ctx *types.HookContext) error
}

HookExecutor handles pre/post sync hook execution.

Hook Execution Security Model (SEC-012): git-vendor hooks follow the same trust model as npm scripts, git hooks, and Makefile targets: the user who controls vendor.yml controls the commands. Hooks are NOT sandboxed.

Security properties:

  • Hooks execute via sh -c (Unix) or cmd /c (Windows) in the project root
  • hookTimeout (5 min) prevents indefinite hangs via context.WithTimeout
  • sanitizeEnvValue strips \n, \r, \x00 from GIT_VENDOR_* env values
  • Hooks inherit the parent environment (including GITHUB_TOKEN etc.)
  • Hook output passes directly to stdout/stderr (unfiltered)
  • Pre-sync hooks run BEFORE clone; temp clone dir is not exposed
  • Post-sync hook failure does NOT roll back already-copied files

Accepted risks: unsandboxed execution, credential access via env, unfiltered output. These match the accepted trust model for configuration-driven tools.

func NewHookService

func NewHookService(ui UICallback) HookExecutor

NewHookService creates a new hook executor

type InternalSyncService added in v1.1.0

type InternalSyncService struct {
	// contains filtered or unexported fields
}

InternalSyncService handles syncing files within the same repository.

func NewInternalSyncService added in v1.1.0

func NewInternalSyncService(
	configStore ConfigStore,
	lockStore LockStore,
	fileCopy FileCopyServiceInterface,
	cache CacheStore,
	fs FileSystem,
	rootDir string,
) *InternalSyncService

NewInternalSyncService creates a new InternalSyncService.

func (*InternalSyncService) SyncInternalVendor added in v1.1.0

func (s *InternalSyncService) SyncInternalVendor(v *types.VendorSpec, opts SyncOptions) (map[string]RefMetadata, CopyStats, error)

SyncInternalVendor syncs all mappings for an internal vendor by copying files from source to destination within the project.

type InternalSyncServiceInterface added in v1.1.0

type InternalSyncServiceInterface interface {
	// SyncInternalVendor syncs all mappings for an internal vendor.
	// Returns per-ref metadata (keyed by RefLocal), copy stats, and any error.
	SyncInternalVendor(v *types.VendorSpec, opts SyncOptions) (map[string]RefMetadata, CopyStats, error)
}

InternalSyncServiceInterface defines the contract for syncing internal (same-repo) vendors. Internal vendors copy files from one location in the project to another, without any git clone operations.

type JSONError

type JSONError struct {
	Title   string `json:"title"`   // Error title
	Message string `json:"message"` // Error message
}

JSONError represents error information in JSON output

type JSONOutput

type JSONOutput struct {
	Status  string                 `json:"status"`            // "success", "error", "warning"
	Message string                 `json:"message,omitempty"` // Optional message
	Data    map[string]interface{} `json:"data,omitempty"`    // Command-specific data
	Error   *JSONError             `json:"error,omitempty"`   // Error details
}

JSONOutput represents structured output

type LicenseChecker

type LicenseChecker interface {
	CheckLicense(url string) (string, error)
	IsAllowed(license string) bool
}

LicenseChecker checks repository licenses

type LicensePolicyService added in v1.1.0

type LicensePolicyService struct {
	// contains filtered or unexported fields
}

LicensePolicyService evaluates licenses against a loaded LicensePolicy.

func NewLicensePolicyService added in v1.1.0

func NewLicensePolicyService(
	policy *types.LicensePolicy,
	policyFile string,
	configStore ConfigStore,
	lockStore LockStore,
) *LicensePolicyService

NewLicensePolicyService creates a LicensePolicyService from a loaded policy.

func (*LicensePolicyService) Evaluate added in v1.1.0

func (s *LicensePolicyService) Evaluate(license string) string

Evaluate determines the policy decision for a given SPDX license identifier. Evaluation order: deny list → allow list → warn list → unknown rule.

func (*LicensePolicyService) GenerateReport added in v1.1.0

func (s *LicensePolicyService) GenerateReport(failOn string) (*types.LicenseReportResult, error)

GenerateReport builds a license compliance report for all vendored dependencies. failOn: "deny" (default) means only denied licenses cause FAIL. failOn: "warn" means both denied and warned licenses cause FAIL.

func (*LicensePolicyService) PolicyFile added in v1.1.0

func (s *LicensePolicyService) PolicyFile() string

PolicyFile returns the path to the loaded policy file.

type LicensePolicyServiceInterface added in v1.1.0

type LicensePolicyServiceInterface interface {
	// Evaluate determines the policy decision for a given SPDX license identifier.
	// Evaluate returns one of types.PolicyAllow, types.PolicyDeny, or types.PolicyWarn.
	Evaluate(license string) string

	// GenerateReport produces a full license compliance report for all vendored dependencies.
	// failOn specifies which decision level triggers a FAIL result ("deny" or "warn").
	GenerateReport(failOn string) (*types.LicenseReportResult, error)

	// PolicyFile returns the path to the policy file that was loaded (or "default").
	PolicyFile() string
}

LicensePolicyServiceInterface defines the contract for license policy evaluation. LicensePolicyServiceInterface enables mocking in tests and alternative policy backends.

type LicenseService

type LicenseService struct {
	// contains filtered or unexported fields
}

LicenseService handles license checking and file management

func NewLicenseService

func NewLicenseService(licenseChecker LicenseChecker, fs FileSystem, rootDir string, ui UICallback) *LicenseService

NewLicenseService creates a new LicenseService

func (*LicenseService) CheckCompliance

func (s *LicenseService) CheckCompliance(url string) (string, error)

CheckCompliance checks license compliance for a URL. When a .git-vendor-policy.yml file exists on disk, CheckCompliance evaluates the detected license against the policy's deny/warn/allow lists. Denied licenses block the add (no user override). Warned licenses prompt for confirmation. Allowed licenses pass silently. A malformed policy file returns an error (no silent fallback). When no policy file exists, CheckCompliance falls back to the legacy AllowedLicenses list with a confirmation prompt for unlisted licenses.

func (*LicenseService) CheckLicense

func (s *LicenseService) CheckLicense(url string) (string, error)

CheckLicense checks the license for a URL (delegates to checker)

func (*LicenseService) CopyLicense

func (s *LicenseService) CopyLicense(tempDir, vendorName string) error

CopyLicense copies license file from temp repo to .git-vendor/licenses. Validates vendorName to prevent path traversal via malicious vendor.yml entries.

func (*LicenseService) GetLicensePath

func (s *LicenseService) GetLicensePath(vendorName string) string

GetLicensePath returns the path to a vendor's license file

type LicenseServiceInterface added in v1.1.0

type LicenseServiceInterface interface {
	CheckCompliance(url string) (string, error)
	CopyLicense(tempDir, vendorName string) error
	GetLicensePath(vendorName string) string
	CheckLicense(url string) (string, error)
}

LicenseServiceInterface defines the contract for license checking and file management. LicenseServiceInterface enables mocking in tests and alternative license backends.

type LockConflictError added in v1.1.0

type LockConflictError struct {
	Conflicts []types.LockConflict
}

LockConflictError provides structured details about merge conflicts in vendor.lock. LockConflictError wraps ErrLockConflict so callers can use errors.Is for detection.

func (*LockConflictError) Error added in v1.1.0

func (e *LockConflictError) Error() string

func (*LockConflictError) Unwrap added in v1.1.0

func (e *LockConflictError) Unwrap() error

type LockStore

type LockStore interface {
	Load() (types.VendorLock, error)
	Save(lock types.VendorLock) error
	Path() string
	GetHash(vendorName, ref string) string
}

LockStore handles vendor.lock I/O operations

type Manager

type Manager struct {
	RootDir string
	// contains filtered or unexported fields
}

Manager provides the main API for git-vendor operations. Manager delegates to VendorSyncer for all business logic. All long-running methods accept context.Context for cancellation support.

func NewManager

func NewManager() *Manager

NewManager creates a new Manager with default dependencies

func NewManagerWithSyncer

func NewManagerWithSyncer(syncer *VendorSyncer) *Manager

NewManagerWithSyncer creates a Manager with a custom VendorSyncer (useful for testing)

func (*Manager) Accept added in v1.1.0

func (m *Manager) Accept(opts AcceptOptions) (*AcceptResult, error)

Accept acknowledges local drift to vendored files, legitimizing intentional modifications. Accept writes accepted_drift entries to the lockfile so verify/status report "accepted" not "modified". With Clear=true, Accept removes accepted_drift entries.

func (*Manager) AddMappingToVendor added in v1.1.0

func (m *Manager) AddMappingToVendor(vendorName, from, to, ref string) error

AddMappingToVendor adds a path mapping to an existing vendor.

func (*Manager) AddMirror added in v1.1.0

func (m *Manager) AddMirror(vendorName, mirrorURL string) error

AddMirror appends a mirror URL to a vendor's Mirrors slice.

func (*Manager) AddVendor

func (m *Manager) AddVendor(spec *types.VendorSpec) error

AddVendor adds a new vendor with license compliance check

func (*Manager) AnnotateVendorCommit added in v1.1.0

func (m *Manager) AnnotateVendorCommit(commitHash, vendorFilter string) error

AnnotateVendorCommit retroactively attaches vendor metadata as a git note to an existing commit. Used by "git vendor annotate" for human-created commits. commitHash is the target commit (empty = HEAD). vendorFilter restricts to a single vendor (empty = all).

func (*Manager) Cascade added in v1.1.0

func (m *Manager) Cascade(ctx context.Context, opts CascadeOptions) (*CascadeResult, error)

Cascade walks the dependency graph across sibling projects and runs pull in topological order. ctx controls cancellation of pull and verify operations.

Cascade discovers sibling repos in the root directory (default: parent of current project), builds a DAG from vendor relationships, topological sorts, and pulls in dependency order. Optional verify/commit/push after each pull.

func (*Manager) CheckGitHubLicense

func (m *Manager) CheckGitHubLicense(rawURL string) (string, error)

CheckGitHubLicense checks a repository's license via GitHub API

func (*Manager) CheckSyncStatus

func (m *Manager) CheckSyncStatus() (types.SyncStatus, error)

CheckSyncStatus checks if local files are in sync with the lockfile

func (*Manager) CheckUpdates

func (m *Manager) CheckUpdates(ctx context.Context) ([]types.UpdateCheckResult, error)

CheckUpdates checks for available updates for all vendors. ctx controls cancellation of git fetch operations for each vendor.

func (*Manager) CheckVendorStatus added in v1.1.0

func (m *Manager) CheckVendorStatus(vendorName string) (map[string]interface{}, error)

CheckVendorStatus checks the sync status of a single vendor.

func (*Manager) CommitVendorChanges added in v1.1.0

func (m *Manager) CommitVendorChanges(operation, vendorFilter string) error

CommitVendorChanges stages and commits vendored files in a single commit with multi-valued COMMIT-SCHEMA v1 trailers and a git note under refs/notes/vendor. CommitVendorChanges delegates to the package-level CommitVendorChanges function.

func (*Manager) ComplianceCheck added in v1.1.0

func (m *Manager) ComplianceCheck(opts ComplianceOptions) (*types.ComplianceResult, error)

ComplianceCheck computes drift state for all internal vendor mappings.

func (*Manager) CompliancePropagate added in v1.1.0

func (m *Manager) CompliancePropagate(opts ComplianceOptions) (*types.ComplianceResult, error)

CompliancePropagate checks drift and copies files per compliance rules.

func (*Manager) ConfigPath

func (m *Manager) ConfigPath() string

ConfigPath returns the path to vendor.yml

func (*Manager) CreateVendorEntry added in v1.1.0

func (m *Manager) CreateVendorEntry(name, url, ref, license string) error

CreateVendorEntry adds a new vendor to config without triggering sync/update.

func (*Manager) DetectConflicts

func (m *Manager) DetectConflicts() ([]types.PathConflict, error)

DetectConflicts checks for path conflicts between vendors

func (*Manager) DiffVendor

func (m *Manager) DiffVendor(vendorName string) ([]types.VendorDiff, error)

DiffVendor shows commit differences between locked and latest versions for a single vendor. DiffVendor is a convenience wrapper; use DiffVendorWithOptions for ref/group filtering.

func (*Manager) DiffVendorWithOptions added in v1.1.0

func (m *Manager) DiffVendorWithOptions(opts DiffOptions) ([]types.VendorDiff, error)

DiffVendorWithOptions shows commit differences with optional vendor/ref/group filtering. Empty DiffOptions fields match all (e.g., empty Ref diffs all refs).

func (*Manager) Drift added in v1.1.0

func (m *Manager) Drift(ctx context.Context, opts DriftOptions) (*types.DriftResult, error)

Drift detects drift between vendored files and their origin. ctx controls cancellation of git operations (clone, fetch, checkout).

func (*Manager) EvaluateLicensePolicy added in v1.1.0

func (m *Manager) EvaluateLicensePolicy(license, policyPath string) string

EvaluateLicensePolicy loads the policy and evaluates a single license. EvaluateLicensePolicy is used during "add" to check a license against the policy. policyPath overrides the default policy file location; empty string uses PolicyFile constant.

func (*Manager) FetchRepoDir

func (m *Manager) FetchRepoDir(ctx context.Context, url, ref, subdir string) ([]string, error)

FetchRepoDir fetches directory listing from a remote repository. ctx controls cancellation of git clone/fetch/ls-tree operations.

func (*Manager) GenerateSBOM added in v1.1.0

func (m *Manager) GenerateSBOM(format SBOMFormat, projectName string) ([]byte, error)

GenerateSBOM generates a Software Bill of Materials in the specified format

func (*Manager) GetConfig

func (m *Manager) GetConfig() (types.VendorConfig, error)

GetConfig returns the vendor configuration

func (*Manager) GetConfigValue added in v1.1.0

func (m *Manager) GetConfigValue(key string) (interface{}, error)

GetConfigValue retrieves a config value by dotted key path.

func (*Manager) GetLock added in v1.1.0

func (m *Manager) GetLock() (types.VendorLock, error)

GetLock returns the current lockfile

func (*Manager) GetLockHash

func (m *Manager) GetLockHash(vendorName, ref string) string

GetLockHash retrieves the locked commit hash for a vendor@ref

func (*Manager) GetRemoteURL added in v1.1.0

func (m *Manager) GetRemoteURL(ctx context.Context, remoteName string) string

GetRemoteURL returns the sanitized URL for a git remote (e.g. "origin"). Returns empty string on any error — not a git repo, no remote configured, etc. SEC-013: Output is sanitized via SanitizeURL to strip embedded credentials.

func (*Manager) Init

func (m *Manager) Init() error

Init initializes the vendor directory structure

func (*Manager) LicensePath

func (m *Manager) LicensePath(name string) string

LicensePath returns the path for a vendor's license file

func (*Manager) LicenseReport added in v1.1.0

func (m *Manager) LicenseReport(policyPath, failOn string) (*types.LicenseReportResult, error)

LicenseReport generates a license compliance report. policyPath overrides the default policy file location; empty string uses PolicyFile constant. failOn: "deny" (default) or "warn" to also fail on warnings.

func (*Manager) ListLocalDir

func (m *Manager) ListLocalDir(path string) ([]string, error)

ListLocalDir lists contents of a local directory

func (*Manager) ListMirrors added in v1.1.0

func (m *Manager) ListMirrors(vendorName string) (map[string]interface{}, error)

ListMirrors returns the primary URL and all mirrors for a vendor.

func (*Manager) LockPath

func (m *Manager) LockPath() string

LockPath returns the path to vendor.lock

func (*Manager) MigrateLockfile added in v1.1.0

func (m *Manager) MigrateLockfile() (int, error)

MigrateLockfile updates an existing lockfile to add missing metadata fields

func (*Manager) Outdated added in v1.1.0

func (m *Manager) Outdated(ctx context.Context, opts OutdatedOptions) (*types.OutdatedResult, error)

Outdated checks if locked versions are behind upstream HEAD using lightweight ls-remote queries (no cloning). Returns aggregated results with per-dependency detail. ctx controls cancellation of ls-remote operations.

func (*Manager) ParseSmartURL

func (m *Manager) ParseSmartURL(rawURL string) (string, string, string)

ParseSmartURL extracts repository, ref, and path from URLs

func (*Manager) Pull added in v1.1.0

func (m *Manager) Pull(ctx context.Context, opts PullOptions) (*PullResult, error)

Pull performs the combined update+sync operation ("get the latest from upstream"). ctx controls cancellation of git operations during pull.

Default: fetch latest → update lock → copy files to disk. With Locked: skip fetch, use existing lock hashes (deterministic rebuild). With Prune: remove dead mappings from vendor.yml after sync. With KeepLocal: detect locally modified files and warn (not overwritten).

func (*Manager) Push added in v1.1.0

func (m *Manager) Push(ctx context.Context, opts PushOptions) (*PushResult, error)

Push proposes local changes to vendored files back to the source repo via PR. ctx controls cancellation of git clone/push operations.

Push detects locally modified vendored files (lock hash mismatch), clones the source repo, applies diffs via reverse path mapping, and creates a PR (or prints manual instructions if the gh CLI is unavailable).

func (*Manager) RemoveMappingFromVendor added in v1.1.0

func (m *Manager) RemoveMappingFromVendor(vendorName, from string) error

RemoveMappingFromVendor removes a path mapping from a vendor by source path.

func (*Manager) RemoveMirror added in v1.1.0

func (m *Manager) RemoveMirror(vendorName, mirrorURL string) error

RemoveMirror removes a mirror URL from a vendor's Mirrors slice.

func (*Manager) RemoveVendor

func (m *Manager) RemoveVendor(name string) error

RemoveVendor removes a vendor by name

func (*Manager) RenameVendor added in v1.1.0

func (m *Manager) RenameVendor(oldName, newName string) error

RenameVendor renames a vendor across config, lockfile, and license file.

func (*Manager) RunAudit added in v1.1.0

func (m *Manager) RunAudit(ctx context.Context, opts AuditOptions) (*types.AuditResult, error)

RunAudit runs the unified audit (verify + scan + license + drift) and returns a combined result. ctx controls cancellation for network-dependent sub-checks (scan, drift).

func (*Manager) SaveVendor

func (m *Manager) SaveVendor(spec *types.VendorSpec) error

SaveVendor saves or updates a vendor spec

func (*Manager) Scan added in v1.1.0

func (m *Manager) Scan(ctx context.Context, failOn string) (*types.ScanResult, error)

Scan performs vulnerability scanning against OSV.dev. ctx controls cancellation of in-flight HTTP requests to OSV.dev.

func (*Manager) SetConfigValue added in v1.1.0

func (m *Manager) SetConfigValue(key, value string) error

SetConfigValue sets a config value by dotted key path.

func (*Manager) SetUICallback

func (m *Manager) SetUICallback(ui UICallback)

SetUICallback sets the UI callback for user interactions

func (*Manager) ShowVendor added in v1.1.0

func (m *Manager) ShowVendor(name string) (map[string]interface{}, error)

ShowVendor returns detailed vendor info combining config and lockfile data.

func (*Manager) Status added in v1.1.0

func (m *Manager) Status(ctx context.Context, opts StatusOptions) (*types.StatusResult, error)

Status runs the unified status command, combining verify (offline/disk) and outdated (remote/upstream) checks into a single per-vendor report. ctx controls cancellation of verify and ls-remote operations.

func (*Manager) Sync

func (m *Manager) Sync(ctx context.Context) error

Sync performs locked synchronization. ctx controls cancellation of git operations during sync.

func (*Manager) SyncWithFullOptions added in v1.1.0

func (m *Manager) SyncWithFullOptions(ctx context.Context, opts SyncOptions) error

SyncWithFullOptions performs sync using a full SyncOptions struct. Supports InternalOnly and Reverse flags for internal vendor compliance.

func (*Manager) SyncWithGroup

func (m *Manager) SyncWithGroup(ctx context.Context, groupName string, force, noCache bool) error

SyncWithGroup performs sync for all vendors in a group. ctx controls cancellation of git operations during sync.

func (*Manager) SyncWithOptions

func (m *Manager) SyncWithOptions(ctx context.Context, vendorName string, force, noCache bool) error

SyncWithOptions performs sync with vendor filter, force, and cache options. ctx controls cancellation of git operations during sync.

func (*Manager) SyncWithParallel

func (m *Manager) SyncWithParallel(ctx context.Context, vendorName string, force, noCache bool, parallelOpts types.ParallelOptions) error

SyncWithParallel performs sync with parallel processing. ctx controls cancellation of git operations during sync.

func (*Manager) UpdateAll

func (m *Manager) UpdateAll(ctx context.Context) error

UpdateAll updates all vendors and regenerates lockfile. ctx controls cancellation of git operations during update.

func (*Manager) UpdateAllWithOptions added in v1.1.0

func (m *Manager) UpdateAllWithOptions(ctx context.Context, opts UpdateOptions) error

UpdateAllWithOptions updates all vendors with optional parallel processing and local path support. ctx controls cancellation of git operations during update.

func (*Manager) UpdateMappingInVendor added in v1.1.0

func (m *Manager) UpdateMappingInVendor(vendorName, from, newTo string) error

UpdateMappingInVendor changes the destination of an existing mapping.

func (*Manager) UpdateVerboseMode

func (m *Manager) UpdateVerboseMode(verbose bool)

UpdateVerboseMode updates the verbose flag for git operations

func (*Manager) ValidateConfig

func (m *Manager) ValidateConfig() error

ValidateConfig performs comprehensive config validation

func (*Manager) Verify added in v1.1.0

func (m *Manager) Verify(ctx context.Context) (*types.VerifyResult, error)

Verify checks all vendored files against the lockfile. ctx is accepted for cancellation support and future network-based verification.

func (*Manager) WatchConfig

func (m *Manager) WatchConfig(callback func() error) error

WatchConfig watches for changes to vendor.yml and triggers a callback

type MultiPlatformLicenseChecker

type MultiPlatformLicenseChecker struct {
	// contains filtered or unexported fields
}

MultiPlatformLicenseChecker implements LicenseChecker interface with support for multiple git hosting platforms

func NewMultiPlatformLicenseChecker

func NewMultiPlatformLicenseChecker(
	registry *providers.ProviderRegistry,
	fs FileSystem,
	gitClient GitClient,
	allowedLicenses []string,
) *MultiPlatformLicenseChecker

NewMultiPlatformLicenseChecker creates a new multi-platform license checker

func (*MultiPlatformLicenseChecker) CheckLicense

func (c *MultiPlatformLicenseChecker) CheckLicense(url string) (string, error)

CheckLicense detects license using platform-specific API or fallback

Strategy:

  1. Detect provider from URL (GitHub, GitLab, Bitbucket, or generic)
  2. Try platform-specific API if available (GitHub, GitLab)
  3. If API fails or unavailable, fall back to reading LICENSE file
  4. Return normalized SPDX license identifier

func (*MultiPlatformLicenseChecker) GetProviderName

func (c *MultiPlatformLicenseChecker) GetProviderName(url string) string

GetProviderName returns the detected provider name for debugging

func (*MultiPlatformLicenseChecker) IsAllowed

func (c *MultiPlatformLicenseChecker) IsAllowed(license string) bool

IsAllowed checks if the given license is in the allowed list

type NoOpProgressTracker

type NoOpProgressTracker struct{}

NoOpProgressTracker is a no-op implementation for testing

func (*NoOpProgressTracker) Complete

func (t *NoOpProgressTracker) Complete()

Complete does nothing (no-op implementation).

func (*NoOpProgressTracker) Fail

func (t *NoOpProgressTracker) Fail(_ error)

Fail does nothing (no-op implementation).

func (*NoOpProgressTracker) Increment

func (t *NoOpProgressTracker) Increment(_ string)

Increment does nothing (no-op implementation).

func (*NoOpProgressTracker) SetTotal

func (t *NoOpProgressTracker) SetTotal(_ int)

SetTotal does nothing (no-op implementation).

type NonInteractiveFlags

type NonInteractiveFlags struct {
	Yes  bool       // Auto-approve prompts
	Mode OutputMode // Output formatting mode
}

NonInteractiveFlags groups all non-interactive options

type OSFileSystem

type OSFileSystem struct {
	// contains filtered or unexported fields
}

OSFileSystem implements FileSystem using standard os package. When projectRoot is set (via NewRootedFileSystem), write operations self-validate that destinations resolve within the root — preventing path traversal even if callers forget to call ValidateDestPath.

func NewOSFileSystem

func NewOSFileSystem() *OSFileSystem

NewOSFileSystem creates an unrooted OSFileSystem with no write validation. Use NewRootedFileSystem for production code that handles user-controlled paths.

func NewRootedFileSystem added in v1.1.0

func NewRootedFileSystem(projectRoot string) *OSFileSystem

NewRootedFileSystem creates an OSFileSystem that validates all write destinations resolve within projectRoot. Production code SHOULD use this constructor.

func (*OSFileSystem) CopyDir

func (fs *OSFileSystem) CopyDir(src, dst string) (CopyStats, error)

CopyDir recursively copies a directory from src to dst.

Security: When the filesystem is rooted (created via NewRootedFileSystem), CopyDir self-validates that dst resolves within projectRoot. For unrooted filesystems, callers MUST call ValidateDestPath(dst) before invoking CopyDir with user-controlled destination paths. See file_copy_service.go:copyMapping for the caller-level validation.

func (*OSFileSystem) CopyFile

func (fs *OSFileSystem) CopyFile(src, dst string) (CopyStats, error)

CopyFile copies a single file from src to dst.

Security: When the filesystem is rooted (created via NewRootedFileSystem), CopyFile self-validates that dst resolves within projectRoot. For unrooted filesystems, callers MUST call ValidateDestPath(dst) before invoking CopyFile with user-controlled destination paths. See file_copy_service.go:copyMapping for the caller-level validation.

func (*OSFileSystem) CreateTemp

func (fs *OSFileSystem) CreateTemp(dir, pattern string) (string, error)

CreateTemp creates a temporary directory

func (*OSFileSystem) MkdirAll

func (fs *OSFileSystem) MkdirAll(path string, perm os.FileMode) error

MkdirAll creates a directory path

func (*OSFileSystem) ReadDir

func (fs *OSFileSystem) ReadDir(path string) ([]string, error)

ReadDir lists directory contents

func (*OSFileSystem) Remove

func (fs *OSFileSystem) Remove(path string) error

Remove removes a file

func (*OSFileSystem) RemoveAll

func (fs *OSFileSystem) RemoveAll(path string) error

RemoveAll removes a directory tree

func (*OSFileSystem) Stat

func (fs *OSFileSystem) Stat(path string) (os.FileInfo, error)

Stat returns file info

func (*OSFileSystem) ValidateWritePath added in v1.1.0

func (fs *OSFileSystem) ValidateWritePath(path string) error

ValidateWritePath checks that path resolves within projectRoot. Returns nil if the filesystem is unrooted (projectRoot is empty).

type OSVAPIError added in v1.1.0

type OSVAPIError struct {
	StatusCode int
	Body       string // Truncated response body for diagnostics
}

OSVAPIError is returned when the OSV.dev API returns a non-OK response.

func NewOSVAPIError added in v1.1.0

func NewOSVAPIError(statusCode int, body string) *OSVAPIError

NewOSVAPIError creates an OSVAPIError.

func (*OSVAPIError) Error added in v1.1.0

func (e *OSVAPIError) Error() string

type OutdatedOptions added in v1.1.0

type OutdatedOptions struct {
	Vendor string // Filter to a specific vendor name (empty = all)
}

OutdatedOptions configures the outdated check.

type OutdatedService added in v1.1.0

type OutdatedService struct {
	// contains filtered or unexported fields
}

OutdatedService checks whether locked vendor commits are behind upstream HEAD using git ls-remote (one command per vendor, no cloning).

func NewOutdatedService added in v1.1.0

func NewOutdatedService(configStore ConfigStore, lockStore LockStore, gitClient GitClient) *OutdatedService

NewOutdatedService creates a new OutdatedService with the given dependencies.

func (*OutdatedService) Outdated added in v1.1.0

Outdated compares locked commit hashes against upstream HEAD for each dependency. Internal vendors (Source == "internal") are skipped. Unsynced vendors (no lock entry) are skipped. LsRemote errors are non-fatal: the vendor is skipped with the Skipped count incremented.

type OutdatedServiceInterface added in v1.1.0

type OutdatedServiceInterface interface {
	Outdated(ctx context.Context, opts OutdatedOptions) (*types.OutdatedResult, error)
}

OutdatedServiceInterface defines the contract for checking vendor staleness via lightweight ls-remote queries (no temp dirs, no clones).

type OutputMode

type OutputMode int

OutputMode controls how output is displayed

const (
	OutputNormal OutputMode = iota // Default: styled output
	OutputQuiet                    // Minimal output
	OutputJSON                     // Structured JSON
)

OutputMode constants define available output formatting modes.

type ParallelExecutor

type ParallelExecutor struct {
	// contains filtered or unexported fields
}

ParallelExecutor handles concurrent processing of multiple vendors

func NewParallelExecutor

func NewParallelExecutor(opts types.ParallelOptions, ui UICallback) *ParallelExecutor

NewParallelExecutor creates a new parallel executor

func (*ParallelExecutor) ExecuteParallelSync

func (p *ParallelExecutor) ExecuteParallelSync(
	ctx context.Context,
	vendors []types.VendorSpec,
	lockMap map[string]map[string]string,
	opts SyncOptions,
	syncFunc SyncVendorFunc,
) ([]VendorResult, error)

ExecuteParallelSync processes vendors in parallel using a worker pool. ctx controls cancellation — passed to each worker goroutine.

func (*ParallelExecutor) ExecuteParallelUpdate

func (p *ParallelExecutor) ExecuteParallelUpdate(
	ctx context.Context,
	vendors []types.VendorSpec,
	updateFunc UpdateVendorFunc,
) ([]VendorResult, error)

ExecuteParallelUpdate processes vendor updates in parallel. ctx controls cancellation — passed to each worker goroutine.

type PathNotFoundError added in v1.1.0

type PathNotFoundError struct {
	Path       string
	VendorName string
	Ref        string
}

PathNotFoundError is returned when a source path doesn't exist.

func NewPathNotFoundError added in v1.1.0

func NewPathNotFoundError(path, vendorName, ref string) *PathNotFoundError

NewPathNotFoundError creates a PathNotFoundError.

func (*PathNotFoundError) Error added in v1.1.0

func (e *PathNotFoundError) Error() string

type PathOwner

type PathOwner struct {
	VendorName string
	Mapping    types.PathMapping
	Ref        string
}

PathOwner tracks which vendor owns a path

type PolicyService added in v1.1.0

type PolicyService struct{}

PolicyService evaluates vendor policy rules against status results. PolicyService resolves per-vendor policy overrides against global defaults and produces PolicyViolation entries for drift and staleness conditions. #guard #policy #drift-detection

func NewPolicyService added in v1.1.0

func NewPolicyService() *PolicyService

NewPolicyService creates a PolicyService.

func (*PolicyService) EvaluatePolicy added in v1.1.0

func (p *PolicyService) EvaluatePolicy(config *types.VendorConfig, statusResult *types.StatusResult) []types.PolicyViolation

EvaluatePolicy checks all vendors in a StatusResult against the policy defined in VendorConfig. EvaluatePolicy returns a slice of PolicyViolation for each vendor that violates its resolved policy (global merged with per-vendor overrides).

Violation types:

  • "drift": vendor has unacknowledged modified files and BlockOnDrift is true
  • "stale": vendor is behind upstream and BlockOnStale is true

Severity mapping:

  • BlockOnDrift=true + drift present -> severity "error"
  • BlockOnDrift=false + drift present -> severity "warning"
  • BlockOnStale=false + stale -> severity "warning"
  • BlockOnStale=true + stale + MaxStalenessDays=0 -> severity "error" (no grace)
  • BlockOnStale=true + stale + age > MaxStalenessDays -> severity "error"
  • BlockOnStale=true + stale + age <= MaxStalenessDays -> severity "warning" (within grace)
  • BlockOnStale=true + stale + unknown age -> severity "error" (conservative)

#guard #policy #drift-detection #staleness

type PullOptions added in v1.1.0

type PullOptions struct {
	Locked      bool   // Use existing lock hashes, don't fetch latest (old sync behavior)
	Prune       bool   // Remove dead mappings from vendor.yml when upstream file is missing
	KeepLocal   bool   // Skip overwriting locally modified files (lock hash mismatch)
	Interactive bool   // Prompt per-file on conflicts (deferred — prints message for now)
	Force       bool   // Skip cache, force re-fetch
	NoCache     bool   // Don't persist cache after pull
	VendorName  string // Empty = all vendors
	Local       bool   // Allow file:// and local path vendor URLs

}

PullOptions configures pull operation behavior. PullOptions merges update + sync into a single "get the latest" operation.

type PullResult added in v1.1.0

type PullResult struct {
	Updated        int      `json:"updated"`                 // Vendors whose lock entries were refreshed
	Synced         int      `json:"synced"`                  // Vendors whose files were copied to disk
	FilesWritten   int      `json:"files_written"`           // Total files written
	FilesSkipped   int      `json:"files_skipped"`           // Files skipped due to --keep-local
	FilesRemoved   int      `json:"files_removed"`           // Files removed (upstream deletion)
	MappingsPruned int      `json:"mappings_pruned"`         // Mappings removed from vendor.yml (--prune)
	Warnings       []string `json:"warnings,omitempty"`      // Non-fatal warnings
	DriftCleared   int      `json:"drift_cleared,omitempty"` // AcceptedDrift entries cleared after overwrite
}

PullResult summarizes what a pull operation did.

type PushOptions added in v1.1.0

type PushOptions struct {
	VendorName string // Required: which vendor to push changes for
	FilePath   string // Optional: push only a specific file (empty = all modified files)
	DryRun     bool   // Show what would be pushed without actually doing it
}

PushOptions configures the push operation behavior. PushOptions controls which vendor's local modifications are proposed upstream.

type PushResult added in v1.1.0

type PushResult struct {
	FilesModified      []string          `json:"files_modified,omitempty"`      // Local paths with modifications relative to lockfile
	ReverseMapping     map[string]string `json:"reverse_mapping,omitempty"`     // local path -> source repo path
	BranchName         string            `json:"branch_name,omitempty"`         // Branch created in source repo
	PRUrl              string            `json:"pr_url,omitempty"`              // URL of created PR (empty if manual fallback)
	ManualInstructions string            `json:"manual_instructions,omitempty"` // Manual git instructions when gh CLI unavailable
	DryRun             bool              `json:"dry_run"`                       // Whether this was a dry-run
}

PushResult summarizes what a push operation did or would do.

type RefMetadata added in v1.1.0

type RefMetadata struct {
	CommitHash string
	VersionTag string           // Git tag pointing to commit, if any
	Positions  []positionRecord // Position extractions performed during sync
	SourceURL  string           // Which mirror URL succeeded (empty = primary URL)
}

RefMetadata holds per-ref metadata collected during sync

type RemoteExplorer

type RemoteExplorer struct {
	// contains filtered or unexported fields
}

RemoteExplorer handles remote repository browsing and URL parsing

func NewRemoteExplorer

func NewRemoteExplorer(gitClient GitClient, fs FileSystem) *RemoteExplorer

NewRemoteExplorer creates a new RemoteExplorer

func (*RemoteExplorer) FetchRepoDir

func (e *RemoteExplorer) FetchRepoDir(ctx context.Context, url, ref, subdir string) ([]string, error)

FetchRepoDir fetches directory listing from remote repository. ctx controls cancellation of git clone/fetch/ls-tree operations. The 30-second ls-tree timeout derives from the parent context.

func (*RemoteExplorer) GetProviderName

func (e *RemoteExplorer) GetProviderName(url string) string

GetProviderName returns the detected provider name for a URL Useful for debugging and logging

func (*RemoteExplorer) ListLocalDir

func (e *RemoteExplorer) ListLocalDir(path string) ([]string, error)

ListLocalDir lists local directory contents

func (*RemoteExplorer) ParseSmartURL

func (e *RemoteExplorer) ParseSmartURL(rawURL string) (string, string, string)

ParseSmartURL parses URLs from any supported git hosting platform Supports GitHub, GitLab, Bitbucket, and generic git URLs

type RemoteExplorerInterface added in v1.1.0

type RemoteExplorerInterface interface {
	FetchRepoDir(ctx context.Context, url, ref, subdir string) ([]string, error)
	ListLocalDir(path string) ([]string, error)
	ParseSmartURL(rawURL string) (string, string, string)
}

RemoteExplorerInterface defines the contract for remote repository browsing and URL parsing. RemoteExplorerInterface enables mocking in tests and alternative exploration strategies. FetchRepoDir accepts ctx for cancellation; the 30s ls-tree timeout derives from the parent context.

type SBOMFormat added in v1.1.0

type SBOMFormat string

SBOMFormat represents supported SBOM output formats

const (
	// SBOMFormatCycloneDX is the CycloneDX 1.5 JSON format
	SBOMFormatCycloneDX SBOMFormat = "cyclonedx"
	// SBOMFormatSPDX is the SPDX 2.3 JSON format
	SBOMFormatSPDX SBOMFormat = "spdx"
)

type SBOMGenerator added in v1.1.0

type SBOMGenerator struct {
	// contains filtered or unexported fields
}

SBOMGenerator generates Software Bill of Materials from vendor lockfiles

func NewSBOMGenerator added in v1.1.0

func NewSBOMGenerator(lockStore LockStore, configStore ConfigStore, projectName string) *SBOMGenerator

NewSBOMGenerator creates a new SBOMGenerator with the given dependencies

func NewSBOMGeneratorWithOptions added in v1.1.0

func NewSBOMGeneratorWithOptions(lockStore LockStore, configStore ConfigStore, opts SBOMOptions) *SBOMGenerator

NewSBOMGeneratorWithOptions creates a new SBOMGenerator with full options

func (*SBOMGenerator) Generate added in v1.1.0

func (g *SBOMGenerator) Generate(format SBOMFormat) ([]byte, error)

Generate creates an SBOM in the specified format

type SBOMOptions added in v1.1.0

type SBOMOptions struct {
	// ProjectName is the name of the project being documented.
	// If empty, defaults to "unknown-project".
	// Used as: CycloneDX metadata.component.name, SPDX document name prefix.
	ProjectName string

	// SPDXNamespace is the base URL for SPDX document namespaces.
	// If empty, defaults to "https://spdx.org/spdxdocs".
	// The final namespace will be: {SPDXNamespace}/{ProjectName}/{UUID}
	SPDXNamespace string

	// Validate enables schema validation of generated SBOM.
	// When true, the generated SBOM is parsed back to verify it's valid.
	// For CycloneDX: round-trip through cyclonedx-go decoder.
	// For SPDX: JSON structure validation with required field checks.
	Validate bool
}

SBOMOptions holds configuration for SBOM generation. All fields are optional with sensible defaults.

type ServiceOverrides added in v1.1.0

type ServiceOverrides struct {
	Repository        VendorRepositoryInterface
	Sync              SyncServiceInterface
	Update            UpdateServiceInterface
	License           LicenseServiceInterface
	Validation        ValidationServiceInterface
	Explorer          RemoteExplorerInterface
	UpdateChecker     UpdateCheckerInterface
	VerifyService     VerifyServiceInterface
	VulnScanner       VulnScannerInterface
	DriftService      DriftServiceInterface
	AuditService      AuditServiceInterface
	ComplianceService ComplianceServiceInterface
	OutdatedService   OutdatedServiceInterface
}

ServiceOverrides allows injecting custom service implementations into VendorSyncer. All fields are optional — nil values cause the default implementation to be created. This enables targeted mocking in tests without affecting other services.

type SilentUICallback

type SilentUICallback struct{}

SilentUICallback is a no-op implementation (for testing/CI)

func (*SilentUICallback) AskConfirmation

func (s *SilentUICallback) AskConfirmation(_, _ string) bool

AskConfirmation implements UICallback for silent operation (always returns false).

func (*SilentUICallback) FormatJSON

func (s *SilentUICallback) FormatJSON(_ JSONOutput) error

FormatJSON implements UICallback for silent operation (does nothing).

func (*SilentUICallback) GetOutputMode

func (s *SilentUICallback) GetOutputMode() OutputMode

GetOutputMode implements UICallback for silent operation (returns OutputNormal).

func (*SilentUICallback) IsAutoApprove

func (s *SilentUICallback) IsAutoApprove() bool

IsAutoApprove implements UICallback for silent operation (returns false).

func (*SilentUICallback) ShowError

func (s *SilentUICallback) ShowError(_, _ string)

ShowError implements UICallback for silent operation (no output).

func (*SilentUICallback) ShowLicenseCompliance

func (s *SilentUICallback) ShowLicenseCompliance(_ string)

ShowLicenseCompliance implements UICallback for silent operation (no output).

func (*SilentUICallback) ShowSuccess

func (s *SilentUICallback) ShowSuccess(_ string)

ShowSuccess implements UICallback for silent operation (no output).

func (*SilentUICallback) ShowWarning

func (s *SilentUICallback) ShowWarning(_, _ string)

ShowWarning implements UICallback for silent operation (no output).

func (*SilentUICallback) StartProgress

func (s *SilentUICallback) StartProgress(_ int, _ string) types.ProgressTracker

StartProgress implements UICallback for silent operation (no-op).

func (*SilentUICallback) StyleTitle

func (s *SilentUICallback) StyleTitle(title string) string

StyleTitle implements UICallback for silent operation (returns plain text).

type StaleCommitError added in v1.1.0

type StaleCommitError struct {
	CommitHash string
	VendorName string
	Ref        string
}

StaleCommitError is returned when a locked commit no longer exists in the remote.

func NewStaleCommitError added in v1.1.0

func NewStaleCommitError(commitHash, vendorName, ref string) *StaleCommitError

NewStaleCommitError creates a StaleCommitError.

func (*StaleCommitError) Error added in v1.1.0

func (e *StaleCommitError) Error() string

type StatusOptions added in v1.1.0

type StatusOptions struct {
	Offline    bool // Skip remote checks (only lock-vs-disk)
	RemoteOnly bool // Skip disk checks (only lock-vs-upstream)
}

StatusOptions configures the status command behavior.

type StatusService added in v1.1.0

type StatusService struct {
	// contains filtered or unexported fields
}

StatusService merges verify and outdated results into a unified per-vendor view. StatusService delegates to VerifyServiceInterface and OutdatedServiceInterface rather than reimplementing their logic.

func NewStatusService added in v1.1.0

func NewStatusService(
	verifySvc VerifyServiceInterface,
	outdatedSvc OutdatedServiceInterface,
	configStore ConfigStore,
	lockStore LockStore,
) *StatusService

NewStatusService creates a StatusService with injected verify and outdated services.

func (*StatusService) Status added in v1.1.0

Status runs offline and/or remote checks based on StatusOptions and returns a combined StatusResult with per-vendor detail and aggregate summary.

Execution order per spec:

  1. Offline checks first (lock vs disk — fast, always runs unless RemoteOnly)
  2. Remote checks second (lock vs upstream — requires network, unless Offline)

Exit code semantics (applied by caller):

  • 0 = PASS (everything matches)
  • 1 = FAIL (modified, deleted, or upstream stale)
  • 2 = WARN (added files only, no failures)

type StatusServiceInterface added in v1.1.0

type StatusServiceInterface interface {
	Status(ctx context.Context, opts StatusOptions) (*types.StatusResult, error)
}

StatusServiceInterface defines the contract for the unified status command. StatusServiceInterface combines verify (offline) and outdated (remote) checks into a single per-vendor report.

type SyncOptions

type SyncOptions struct {
	DryRun       bool
	VendorName   string // Empty = all vendors
	GroupName    string // Empty = all groups, filters vendors by group
	Force        bool
	NoCache      bool                  // Disable incremental sync cache
	Parallel     types.ParallelOptions // Parallel processing options
	Commit       bool                  // Auto-commit after sync with vendor trailers
	InternalOnly bool                  // Only sync internal vendors (Spec 070)
	Reverse      bool                  // Propagate dest changes back to source (Spec 070)
	Local        bool                  // Allow file:// and local path vendor URLs
}

SyncOptions configures sync operation behavior

type SyncService

type SyncService struct {
	// contains filtered or unexported fields
}

SyncService handles vendor synchronization operations

func NewSyncService

func NewSyncService(
	configStore ConfigStore,
	lockStore LockStore,
	gitClient GitClient,
	fs FileSystem,
	fileCopy FileCopyServiceInterface,
	license LicenseServiceInterface,
	cache CacheStore,
	hooks HookExecutor,
	ui UICallback,
	rootDir string,
	internalSync InternalSyncServiceInterface,
) *SyncService

NewSyncService creates a new SyncService. internalSync may be nil if no internal vendor support is needed (will be set by VendorSyncer).

func (*SyncService) Sync

func (s *SyncService) Sync(ctx context.Context, opts SyncOptions) error

Sync performs synchronization based on the provided options. ctx controls cancellation of git operations during sync. Note: Caller should check for lockfile existence before calling this.

func (*SyncService) SyncVendor added in v1.1.0

func (s *SyncService) SyncVendor(ctx context.Context, v *types.VendorSpec, lockedRefs map[string]string, opts SyncOptions) (map[string]RefMetadata, CopyStats, error)

SyncVendor syncs a single vendor. ctx controls cancellation of git operations during sync. Returns a map of ref to RefMetadata and total stats for all synced refs.

type SyncServiceInterface added in v1.1.0

type SyncServiceInterface interface {
	// Sync synchronizes vendors based on the provided options, loading config and lock internally.
	// ctx controls cancellation of git operations during sync.
	Sync(ctx context.Context, opts SyncOptions) error

	// SyncVendor syncs a single vendor's refs and returns per-ref metadata and copy stats.
	// ctx controls cancellation of git operations during sync.
	//
	// lockedRefs controls the sync mode:
	//   - nil: update mode — fetches the latest commit on each ref (FETCH_HEAD).
	//   - non-nil map: sync mode — checks out the exact commit hash for each ref.
	//     Missing or empty entries within the map are treated as unlocked for that ref.
	SyncVendor(ctx context.Context, v *types.VendorSpec, lockedRefs map[string]string, opts SyncOptions) (map[string]RefMetadata, CopyStats, error)
}

SyncServiceInterface defines the contract for vendor synchronization. SyncServiceInterface enables mocking in tests and alternative sync strategies. All methods accept a context.Context for cancellation support (e.g., Ctrl+C).

type SyncVendorFunc

type SyncVendorFunc func(ctx context.Context, v types.VendorSpec, lockedRefs map[string]string, opts SyncOptions) (map[string]RefMetadata, CopyStats, error)

SyncVendorFunc is a function type that syncs a single vendor. ctx controls cancellation of git operations for this vendor.

type SystemGitClient

type SystemGitClient struct {
	// contains filtered or unexported fields
}

SystemGitClient implements GitClient using system git commands

func NewSystemGitClient

func NewSystemGitClient(verbose bool) *SystemGitClient

NewSystemGitClient creates a new SystemGitClient

func (*SystemGitClient) Add added in v1.1.0

func (g *SystemGitClient) Add(ctx context.Context, dir string, paths ...string) error

Add stages files for the next commit. Add delegates to git-plumbing's Add method with the specified paths.

func (*SystemGitClient) AddNote added in v1.1.0

func (g *SystemGitClient) AddNote(ctx context.Context, dir, noteRef, commitHash, content string) error

AddNote adds or overwrites a git note on a commit under the given note ref namespace. AddNote delegates to git-plumbing's AddNote with NoteRef type conversion.

func (*SystemGitClient) AddRemote

func (g *SystemGitClient) AddRemote(ctx context.Context, dir, name, url string) error

AddRemote adds a git remote

func (*SystemGitClient) Checkout

func (g *SystemGitClient) Checkout(ctx context.Context, dir, ref string) error

Checkout checks out a git ref

func (*SystemGitClient) Clone

func (g *SystemGitClient) Clone(ctx context.Context, dir, url string, opts *types.CloneOptions) error

Clone clones a repository with options. Converts types.CloneOptions to git.CloneOpts for the git-plumbing layer.

func (*SystemGitClient) Commit added in v1.1.0

func (g *SystemGitClient) Commit(ctx context.Context, dir string, opts types.CommitOptions) error

Commit creates a new commit with structured trailers. Commit converts []types.Trailer to []git.Trailer for the git-plumbing layer. Both types have identical Key/Value fields but are distinct Go types across packages.

func (*SystemGitClient) ConfigGet added in v1.1.0

func (g *SystemGitClient) ConfigGet(ctx context.Context, dir, key string) (string, error)

ConfigGet reads a git config value by key. ConfigGet delegates to git-plumbing's ConfigGet for the given directory.

func (*SystemGitClient) ConfigSet added in v1.1.0

func (g *SystemGitClient) ConfigSet(ctx context.Context, dir, key, value string) error

ConfigSet writes a git config key-value pair. ConfigSet delegates to git-plumbing's ConfigSet for the given directory.

func (*SystemGitClient) CreateBranch added in v1.1.0

func (g *SystemGitClient) CreateBranch(ctx context.Context, dir, name, startPoint string) error

CreateBranch creates a new branch at the given start point without checking it out. CreateBranch delegates to git-plumbing's CreateBranch method for the given directory.

func (*SystemGitClient) Fetch

func (g *SystemGitClient) Fetch(ctx context.Context, dir, remote string, depth int, ref string) error

Fetch fetches from the named remote with optional depth.

func (*SystemGitClient) FetchAll

func (g *SystemGitClient) FetchAll(ctx context.Context, dir, remote string) error

FetchAll fetches all refs from the named remote.

func (*SystemGitClient) GetCommitLog

func (g *SystemGitClient) GetCommitLog(ctx context.Context, dir, oldHash, newHash string, maxCount int) ([]types.CommitInfo, error)

GetCommitLog retrieves commit history between two commits. Delegates to git-plumbing Log() and converts git.Commit to types.CommitInfo.

func (*SystemGitClient) GetHeadHash

func (g *SystemGitClient) GetHeadHash(ctx context.Context, dir string) (string, error)

GetHeadHash returns the current HEAD commit hash

func (*SystemGitClient) GetNote added in v1.1.0

func (g *SystemGitClient) GetNote(ctx context.Context, dir, noteRef, commitHash string) (string, error)

GetNote retrieves a git note from a commit under the given note ref namespace. GetNote delegates to git-plumbing's GetNote with NoteRef type conversion.

func (*SystemGitClient) GetTagForCommit added in v1.1.0

func (g *SystemGitClient) GetTagForCommit(ctx context.Context, dir, commitHash string) (string, error)

GetTagForCommit returns a git tag that points to the given commit hash, if any. Prefers semver-looking tags (v1.0.0, 1.0.0) over other tags. Delegates to git-plumbing TagsAt() for tag retrieval, applies semver preference locally.

func (*SystemGitClient) Init

func (g *SystemGitClient) Init(ctx context.Context, dir string) error

Init initializes a git repository

func (*SystemGitClient) ListTree

func (g *SystemGitClient) ListTree(ctx context.Context, dir, ref, subdir string) ([]string, error)

ListTree lists files/directories at a given ref and subdir. The caller should set a deadline on ctx if a timeout is desired. Delegates to git-plumbing which handles ls-tree parsing internally.

func (*SystemGitClient) LsRemote added in v1.1.0

func (g *SystemGitClient) LsRemote(ctx context.Context, url, ref string) (string, error)

LsRemote queries a remote repository for the commit hash of a ref without cloning. LsRemote delegates to git-plumbing's LsRemote. Dir is not needed since ls-remote operates on the remote URL, but git-plumbing requires a Git instance; "." is used.

func (*SystemGitClient) Push added in v1.1.0

func (g *SystemGitClient) Push(ctx context.Context, dir, remote, branch string) error

Push pushes a local branch to a remote. Push delegates to git-plumbing's Push method for the given directory.

func (*SystemGitClient) SetRemoteURL added in v1.1.0

func (g *SystemGitClient) SetRemoteURL(ctx context.Context, dir, name, url string) error

SetRemoteURL updates the URL of an existing remote. SetRemoteURL uses git config directly (no git-plumbing SetRemoteURL method).

type UICallback

type UICallback interface {
	ShowError(title, message string)
	ShowSuccess(message string)
	ShowWarning(title, message string)
	AskConfirmation(title, message string) bool
	ShowLicenseCompliance(license string)
	StyleTitle(title string) string

	// New methods for non-interactive mode
	GetOutputMode() OutputMode
	IsAutoApprove() bool
	FormatJSON(output JSONOutput) error

	// Progress tracking
	StartProgress(total int, label string) types.ProgressTracker
}

UICallback handles user interaction during vendor operations

type UpdateChecker

type UpdateChecker struct {
	// contains filtered or unexported fields
}

UpdateChecker handles checking for vendor updates

func NewUpdateChecker

func NewUpdateChecker(
	configStore ConfigStore,
	lockStore LockStore,
	gitClient GitClient,
	fs FileSystem,
	ui UICallback,
) *UpdateChecker

NewUpdateChecker creates a new UpdateChecker

func (*UpdateChecker) CheckUpdates

func (c *UpdateChecker) CheckUpdates(ctx context.Context) ([]types.UpdateCheckResult, error)

CheckUpdates compares lockfile commit hashes with latest available commits. ctx controls cancellation of git fetch operations for each vendor.

type UpdateCheckerInterface added in v1.1.0

type UpdateCheckerInterface interface {
	CheckUpdates(ctx context.Context) ([]types.UpdateCheckResult, error)
}

UpdateCheckerInterface defines the contract for checking vendor updates. UpdateCheckerInterface enables mocking in tests and alternative update check strategies. ctx is accepted for cancellation of network operations (git fetch).

type UpdateOptions added in v1.1.0

type UpdateOptions struct {
	Parallel   types.ParallelOptions
	Local      bool   // Allow file:// and local path vendor URLs
	VendorName string // Filter to single vendor by name (empty = all)
	Group      string // Filter to vendor group (empty = all)
}

UpdateOptions configures update operation behavior. VendorName and Group are mutually exclusive filters; when set, only matching vendors are re-fetched and their lock entries regenerated. Non-matching vendors retain their existing lock entries unchanged.

type UpdateService

type UpdateService struct {
	// contains filtered or unexported fields
}

UpdateService handles update operations and lockfile regeneration

func NewUpdateService

func NewUpdateService(
	configStore ConfigStore,
	lockStore LockStore,
	syncService SyncServiceInterface,
	internalSync InternalSyncServiceInterface,
	cache CacheStore,
	ui UICallback,
	rootDir string,
) *UpdateService

NewUpdateService creates a new UpdateService

func (*UpdateService) UpdateAll

func (s *UpdateService) UpdateAll(ctx context.Context) error

UpdateAll updates all vendors and regenerates the lockfile. ctx controls cancellation of git operations during update.

func (*UpdateService) UpdateAllWithOptions

func (s *UpdateService) UpdateAllWithOptions(ctx context.Context, opts UpdateOptions) error

UpdateAllWithOptions updates vendors with optional parallel processing, local path support, and vendor name/group filtering. When VendorName or Group is set, only matching vendors are re-fetched; non-matching vendors retain their existing lock entries. ctx controls cancellation of git operations during update.

type UpdateServiceInterface added in v1.1.0

type UpdateServiceInterface interface {
	UpdateAll(ctx context.Context) error
	UpdateAllWithOptions(ctx context.Context, opts UpdateOptions) error
}

UpdateServiceInterface defines the contract for update operations and lockfile regeneration. UpdateServiceInterface enables mocking in tests and alternative update strategies. All methods accept a context.Context for cancellation support (e.g., Ctrl+C).

type UpdateVendorFunc

type UpdateVendorFunc func(ctx context.Context, v types.VendorSpec, opts SyncOptions) (map[string]RefMetadata, error)

UpdateVendorFunc is a function type that updates a single vendor. ctx controls cancellation of git operations for this vendor.

type ValidationError added in v1.1.0

type ValidationError struct {
	VendorName string
	Ref        string
	Field      string
	Message    string
}

ValidationError is returned when configuration validation fails.

func NewValidationError added in v1.1.0

func NewValidationError(vendorName, ref, field, message string) *ValidationError

NewValidationError creates a ValidationError.

func (*ValidationError) Error added in v1.1.0

func (e *ValidationError) Error() string

type ValidationService

type ValidationService struct {
	// contains filtered or unexported fields
}

ValidationService handles config validation and conflict detection

func NewValidationService

func NewValidationService(configStore ConfigStore) *ValidationService

NewValidationService creates a new ValidationService

func (*ValidationService) DetectConflicts

func (s *ValidationService) DetectConflicts() ([]types.PathConflict, error)

DetectConflicts checks for path conflicts between vendors

func (*ValidationService) ValidateConfig

func (s *ValidationService) ValidateConfig() error

ValidateConfig performs comprehensive configuration validation

type ValidationServiceInterface added in v1.1.0

type ValidationServiceInterface interface {
	ValidateConfig() error
	DetectConflicts() ([]types.PathConflict, error)
}

ValidationServiceInterface defines the contract for config validation and conflict detection. ValidationServiceInterface enables mocking in tests and alternative validation strategies.

type VendorConfigWithCascade added in v1.1.0

type VendorConfigWithCascade struct {
	Vendors []types.VendorSpec `yaml:"vendors"`
	Cascade *CascadeConfig     `yaml:"cascade,omitempty"`
}

VendorConfigWithCascade extends VendorConfig with optional cascade settings. VendorConfigWithCascade is used only for parsing the cascade section from vendor.yml files during graph discovery.

type VendorNotFoundError added in v1.1.0

type VendorNotFoundError struct {
	Name string
}

VendorNotFoundError is returned when a vendor name doesn't exist in config.

func NewVendorNotFoundError added in v1.1.0

func NewVendorNotFoundError(name string) *VendorNotFoundError

NewVendorNotFoundError creates a VendorNotFoundError.

func (*VendorNotFoundError) Error added in v1.1.0

func (e *VendorNotFoundError) Error() string

type VendorNoteData added in v1.1.0

type VendorNoteData struct {
	Schema  string            `json:"schema"`            // "vendor/v1"
	Vendors []VendorNoteEntry `json:"vendors"`           // One entry per lock entry in this commit
	Created string            `json:"created,omitempty"` // ISO 8601 timestamp
}

VendorNoteData is the JSON structure stored in git notes under VendorNoteRef. VendorNoteData provides rich per-vendor provenance metadata that supplements the compact trailer representation in the commit message.

type VendorNoteEntry added in v1.1.0

type VendorNoteEntry struct {
	Name             string            `json:"name"`
	URL              string            `json:"url,omitempty"`
	Ref              string            `json:"ref"`
	CommitHash       string            `json:"commit_hash"`
	LicenseSPDX      string            `json:"license_spdx,omitempty"`
	SourceVersionTag string            `json:"source_version_tag,omitempty"`
	FileHashes       map[string]string `json:"file_hashes,omitempty"`
	Paths            []string          `json:"paths,omitempty"` // Destination paths affected
}

VendorNoteEntry contains per-vendor metadata for a single lock entry in a note.

type VendorRepository

type VendorRepository struct {
	// contains filtered or unexported fields
}

VendorRepository handles vendor CRUD operations

func NewVendorRepository

func NewVendorRepository(configStore ConfigStore) *VendorRepository

NewVendorRepository creates a new VendorRepository

func (*VendorRepository) Delete

func (r *VendorRepository) Delete(name string) error

Delete removes a vendor by name

func (*VendorRepository) Exists

func (r *VendorRepository) Exists(name string) (bool, error)

Exists checks if a vendor with the given name exists

func (*VendorRepository) Find

func (r *VendorRepository) Find(name string) (*types.VendorSpec, error)

Find returns the vendor with the given name, or nil if not found

func (*VendorRepository) FindAll

func (r *VendorRepository) FindAll() ([]types.VendorSpec, error)

FindAll returns all vendors

func (*VendorRepository) GetConfig

func (r *VendorRepository) GetConfig() (types.VendorConfig, error)

GetConfig returns the vendor configuration

func (*VendorRepository) Save

func (r *VendorRepository) Save(vendor *types.VendorSpec) error

Save adds or updates a vendor

type VendorRepositoryInterface added in v1.1.0

type VendorRepositoryInterface interface {
	Find(name string) (*types.VendorSpec, error)
	FindAll() ([]types.VendorSpec, error)
	Exists(name string) (bool, error)
	Save(vendor *types.VendorSpec) error
	Delete(name string) error
	GetConfig() (types.VendorConfig, error)
}

VendorRepositoryInterface defines the contract for vendor CRUD operations. VendorRepositoryInterface enables mocking in tests and alternative storage backends.

type VendorResult

type VendorResult struct {
	Vendor      types.VendorSpec
	UpdatedRefs map[string]RefMetadata // ref -> metadata (commit hash, version tag)
	Stats       CopyStats
	Error       error
}

VendorResult represents the result of processing a single vendor

type VendorSyncer

type VendorSyncer struct {
	// contains filtered or unexported fields
}

VendorSyncer orchestrates vendor operations using domain services

func NewVendorSyncer

func NewVendorSyncer(
	configStore ConfigStore,
	lockStore LockStore,
	gitClient GitClient,
	fs FileSystem,
	licenseChecker LicenseChecker,
	rootDir string,
	ui UICallback,
	overrides *ServiceOverrides,
) *VendorSyncer

NewVendorSyncer creates a new VendorSyncer with injected dependencies. overrides is optional — pass nil to use all default service implementations. Individual service fields within overrides that are nil also use defaults.

func (*VendorSyncer) Accept added in v1.1.0

func (s *VendorSyncer) Accept(opts AcceptOptions) (*AcceptResult, error)

Accept processes drift acceptance or clearing for a vendor's files. Accept creates an AcceptService on demand (no DI overhead — accept is infrequent).

func (*VendorSyncer) AddMappingToVendor added in v1.1.0

func (s *VendorSyncer) AddMappingToVendor(vendorName, from, to, ref string) error

AddMappingToVendor adds a path mapping to an existing vendor's ref. If ref is empty, the mapping is added to the first (default) BranchSpec.

func (*VendorSyncer) AddMirror added in v1.1.0

func (s *VendorSyncer) AddMirror(vendorName, mirrorURL string) error

AddMirror appends a mirror URL to a vendor's Mirrors slice. AddMirror validates the URL format and rejects duplicates (same as primary URL or already present).

func (*VendorSyncer) AddVendor

func (s *VendorSyncer) AddVendor(spec *types.VendorSpec) error

AddVendor adds a new vendor with license compliance check

func (*VendorSyncer) CheckGitHubLicense

func (s *VendorSyncer) CheckGitHubLicense(url string) (string, error)

CheckGitHubLicense delegates to the license service

func (*VendorSyncer) CheckSyncStatus

func (s *VendorSyncer) CheckSyncStatus() (types.SyncStatus, error)

CheckSyncStatus checks if local files are in sync with the lockfile

func (*VendorSyncer) CheckUpdates

func (s *VendorSyncer) CheckUpdates(ctx context.Context) ([]types.UpdateCheckResult, error)

CheckUpdates checks for available updates for all vendors. ctx controls cancellation of git fetch operations for each vendor.

func (*VendorSyncer) CheckVendorStatus added in v1.1.0

func (s *VendorSyncer) CheckVendorStatus(vendorName string) (map[string]interface{}, error)

CheckVendorStatus checks the sync status of a single vendor.

func (*VendorSyncer) ComplianceCheck added in v1.1.0

func (s *VendorSyncer) ComplianceCheck(opts ComplianceOptions) (*types.ComplianceResult, error)

ComplianceCheck runs compliance check for internal vendors.

func (*VendorSyncer) CompliancePropagate added in v1.1.0

func (s *VendorSyncer) CompliancePropagate(opts ComplianceOptions) (*types.ComplianceResult, error)

CompliancePropagate runs compliance check and propagates changes for internal vendors.

func (*VendorSyncer) CreateVendorEntry added in v1.1.0

func (s *VendorSyncer) CreateVendorEntry(name, url, ref, license string) error

CreateVendorEntry adds a new vendor to vendor.yml without triggering sync or update. CreateVendorEntry is the non-interactive counterpart to AddVendor — suitable for LLM and scripted workflows.

func (*VendorSyncer) DetectConflicts

func (s *VendorSyncer) DetectConflicts() ([]types.PathConflict, error)

DetectConflicts checks for path conflicts between vendors

func (*VendorSyncer) DiffVendor

func (s *VendorSyncer) DiffVendor(vendorName string) ([]types.VendorDiff, error)

DiffVendor compares the locked version with the latest available version for a single vendor. DiffVendor is a backward-compatible wrapper around DiffVendorWithOptions that filters by vendor name only.

func (*VendorSyncer) DiffVendorWithOptions added in v1.1.0

func (s *VendorSyncer) DiffVendorWithOptions(opts DiffOptions) ([]types.VendorDiff, error)

DiffVendorWithOptions compares locked versions with the latest available versions, applying optional filters. When all filter fields are empty, DiffVendorWithOptions diffs every vendor. When VendorName is set, only that vendor is diffed. When Group is set, only vendors in that group are diffed. When Ref is set, only specs matching that ref are diffed within matched vendors.

func (*VendorSyncer) Drift added in v1.1.0

Drift detects drift between vendored files and their origin. ctx controls cancellation of git operations (clone, fetch, checkout).

func (*VendorSyncer) FetchRepoDir

func (s *VendorSyncer) FetchRepoDir(ctx context.Context, url, ref, subdir string) ([]string, error)

FetchRepoDir fetches directory listing from remote repository. ctx controls cancellation of git clone/fetch/ls-tree operations.

func (*VendorSyncer) GetConfig

func (s *VendorSyncer) GetConfig() (types.VendorConfig, error)

GetConfig returns the vendor configuration

func (*VendorSyncer) GetConfigValue added in v1.1.0

func (s *VendorSyncer) GetConfigValue(key string) (interface{}, error)

GetConfigValue retrieves a config value by dotted key path. Supported keys: vendors.<name>.url, vendors.<name>.license, vendors.<name>.ref, vendors.<name>.groups, vendor_count.

func (*VendorSyncer) GetLockHash

func (s *VendorSyncer) GetLockHash(vendorName, ref string) string

GetLockHash retrieves the locked commit hash for a vendor@ref

func (*VendorSyncer) Init

func (s *VendorSyncer) Init() error

Init initializes vendor directory structure and configures git hooks. Init creates the .git-vendor/ tree, saves an empty config, and sets core.hooksPath to .githooks if that directory already exists in the project root. Hook setup is best-effort — failures do not fail Init() since the core vendor directory setup already succeeded.

func (*VendorSyncer) LicenseReport added in v1.1.0

func (s *VendorSyncer) LicenseReport(policyService LicensePolicyServiceInterface, failOn string) (*types.LicenseReportResult, error)

LicenseReport generates a license compliance report using the provided policy service.

func (*VendorSyncer) ListLocalDir

func (s *VendorSyncer) ListLocalDir(path string) ([]string, error)

ListLocalDir lists local directory contents

func (*VendorSyncer) ListMirrors added in v1.1.0

func (s *VendorSyncer) ListMirrors(vendorName string) (map[string]interface{}, error)

ListMirrors returns the primary URL and all mirror URLs for a vendor. ListMirrors returns a map with "primary" (string) and "mirrors" ([]string) keys.

func (*VendorSyncer) MigrateLockfile added in v1.1.0

func (s *VendorSyncer) MigrateLockfile() (int, error)

MigrateLockfile updates an existing lockfile to add missing metadata fields. For fields that can't be computed (VendoredAt, VendoredBy), it uses best guesses. Returns the number of entries migrated and any error.

func (*VendorSyncer) Outdated added in v1.1.0

Outdated checks if locked versions are behind upstream HEAD using git ls-remote. ctx controls cancellation of ls-remote operations.

func (*VendorSyncer) ParseSmartURL

func (s *VendorSyncer) ParseSmartURL(rawURL string) (string, string, string)

ParseSmartURL delegates to the remote explorer

func (*VendorSyncer) PullVendors added in v1.1.0

func (s *VendorSyncer) PullVendors(ctx context.Context, opts PullOptions) (*PullResult, error)

PullVendors performs the combined update+sync operation.

Default flow (no --locked):

  1. Update: fetch latest commit for each vendor ref, regenerate lock
  2. Sync: copy locked files to disk

With --locked:

  1. Sync only: use existing lock hashes (deterministic rebuild)

With --keep-local:

  1. Before overwriting, check if local file hash matches lock hash
  2. If mismatch (local modification detected), skip that file

With --prune:

  1. After sync, remove mappings from vendor.yml whose upstream source no longer exists

func (*VendorSyncer) PushVendor added in v1.1.0

func (s *VendorSyncer) PushVendor(ctx context.Context, opts PushOptions) (*PushResult, error)

PushVendor detects locally modified vendored files, clones the source repo, applies the reverse-mapped diffs, and creates a PR (or prints manual instructions).

PushVendor requires the vendor to be an external vendor (not internal). Internal vendors use compliance propagation instead.

func (*VendorSyncer) RemoveMappingFromVendor added in v1.1.0

func (s *VendorSyncer) RemoveMappingFromVendor(vendorName, from string) error

RemoveMappingFromVendor removes a path mapping from a vendor by its source path. RemoveMappingFromVendor searches all specs (refs) within the vendor.

func (*VendorSyncer) RemoveMirror added in v1.1.0

func (s *VendorSyncer) RemoveMirror(vendorName, mirrorURL string) error

RemoveMirror removes a mirror URL from a vendor's Mirrors slice. RemoveMirror returns an error if the mirror URL is not found.

func (*VendorSyncer) RemoveVendor

func (s *VendorSyncer) RemoveVendor(name string) error

RemoveVendor removes a vendor by name. Uses context.Background() because RemoveVendor is called from interactive wizards where signal handling is not wired.

func (*VendorSyncer) RenameVendor added in v1.1.0

func (s *VendorSyncer) RenameVendor(oldName, newName string) error

RenameVendor renames a vendor in config, lockfile, and license file.

func (*VendorSyncer) RunAudit added in v1.1.0

func (s *VendorSyncer) RunAudit(ctx context.Context, opts AuditOptions) (*types.AuditResult, error)

RunAudit runs the unified audit (verify + scan + license + drift) and returns a combined result. ctx controls cancellation for network-dependent sub-checks.

func (*VendorSyncer) SaveVendor

func (s *VendorSyncer) SaveVendor(spec *types.VendorSpec) error

SaveVendor saves or updates a vendor spec. Uses context.Background() because SaveVendor is called from interactive wizards where signal handling is not wired.

func (*VendorSyncer) Scan added in v1.1.0

func (s *VendorSyncer) Scan(ctx context.Context, failOn string) (*types.ScanResult, error)

Scan performs vulnerability scanning against OSV.dev. ctx controls cancellation of in-flight HTTP requests.

func (*VendorSyncer) SetConfigValue added in v1.1.0

func (s *VendorSyncer) SetConfigValue(key, value string) error

SetConfigValue sets a config value by dotted key path. Supported keys: vendors.<name>.url, vendors.<name>.license, vendors.<name>.ref.

func (*VendorSyncer) ShowVendor added in v1.1.0

func (s *VendorSyncer) ShowVendor(name string) (map[string]interface{}, error)

ShowVendor returns detailed information about a vendor, combining config and lockfile data.

func (*VendorSyncer) Status added in v1.1.0

Status runs the unified status command combining verify and outdated checks. ctx controls cancellation of verify and ls-remote operations.

func (*VendorSyncer) Sync

func (s *VendorSyncer) Sync(ctx context.Context) error

Sync performs locked synchronization. ctx controls cancellation of git operations during sync.

func (*VendorSyncer) SyncWithFullOpts added in v1.1.0

func (s *VendorSyncer) SyncWithFullOpts(ctx context.Context, opts SyncOptions) error

SyncWithFullOpts performs sync with a full SyncOptions struct. Supports DryRun, InternalOnly, Reverse, and Local flags.

func (*VendorSyncer) SyncWithGroup

func (s *VendorSyncer) SyncWithGroup(ctx context.Context, groupName string, force, noCache bool) error

SyncWithGroup performs sync for all vendors in a group. ctx controls cancellation of git operations during sync.

func (*VendorSyncer) SyncWithOptions

func (s *VendorSyncer) SyncWithOptions(ctx context.Context, vendorName string, force, noCache bool) error

SyncWithOptions performs sync with vendor filter, force, and cache options. ctx controls cancellation of git operations during sync.

func (*VendorSyncer) SyncWithParallel

func (s *VendorSyncer) SyncWithParallel(ctx context.Context, vendorName string, force, noCache bool, parallelOpts types.ParallelOptions) error

SyncWithParallel performs sync with parallel processing. ctx controls cancellation of git operations during sync.

func (*VendorSyncer) UpdateAll

func (s *VendorSyncer) UpdateAll(ctx context.Context) error

UpdateAll updates all vendors and regenerates lockfile. ctx controls cancellation of git operations during update.

func (*VendorSyncer) UpdateAllWithOptions added in v1.1.0

func (s *VendorSyncer) UpdateAllWithOptions(ctx context.Context, opts UpdateOptions) error

UpdateAllWithOptions updates all vendors with optional parallel processing and local path support. ctx controls cancellation of git operations during update.

func (*VendorSyncer) UpdateMappingInVendor added in v1.1.0

func (s *VendorSyncer) UpdateMappingInVendor(vendorName, from, newTo string) error

UpdateMappingInVendor changes the destination of an existing mapping.

func (*VendorSyncer) ValidateConfig

func (s *VendorSyncer) ValidateConfig() error

ValidateConfig performs comprehensive config validation

func (*VendorSyncer) Verify added in v1.1.0

func (s *VendorSyncer) Verify(ctx context.Context) (*types.VerifyResult, error)

Verify checks all vendored files against the lockfile. ctx is accepted for cancellation support and future network-based verification.

func (*VendorSyncer) WatchConfig

func (s *VendorSyncer) WatchConfig(callback func() error) error

WatchConfig watches for changes to vendor.yml and triggers sync

type VerifyService added in v1.1.0

type VerifyService struct {
	// contains filtered or unexported fields
}

VerifyService handles verification of vendored files against lockfile

func NewVerifyService added in v1.1.0

func NewVerifyService(
	configStore ConfigStore,
	lockStore LockStore,
	cache CacheStore,
	fs FileSystem,
	rootDir string,
) *VerifyService

NewVerifyService creates a new VerifyService

func (*VerifyService) Verify added in v1.1.0

Verify checks all vendored files against the lockfile. ctx is accepted for cancellation support and future network-based verification.

type VerifyServiceInterface added in v1.1.0

type VerifyServiceInterface interface {
	Verify(ctx context.Context) (*types.VerifyResult, error)
}

VerifyServiceInterface defines the contract for file verification against lockfile. VerifyServiceInterface enables mocking in tests and alternative verification strategies. ctx is accepted for cancellation support and future network-based verification.

type VulnScanner added in v1.1.0

type VulnScanner struct {
	// contains filtered or unexported fields
}

VulnScanner handles vulnerability scanning against OSV.dev. The batch API endpoint is configurable via the GIT_VENDOR_OSV_ENDPOINT environment variable (defaults to https://api.osv.dev). This enables testing against local servers and air-gapped proxy deployments.

func NewVulnScanner added in v1.1.0

func NewVulnScanner(lockStore LockStore, configStore ConfigStore) *VulnScanner

NewVulnScanner creates a new vulnerability scanner. Reads GIT_VENDOR_OSV_ENDPOINT env var to override the default OSV.dev base URL. Reads GIT_VENDOR_CACHE_TTL env var to override the default 24-hour cache TTL.

func (*VulnScanner) ClearCache added in v1.1.0

func (s *VulnScanner) ClearCache() error

ClearCache removes all cached OSV responses

func (*VulnScanner) GetCacheKey added in v1.1.0

func (s *VulnScanner) GetCacheKey(dep *types.LockDetails, repoURL string) string

GetCacheKey returns the cache key for testing purposes. repoURL is used to prevent cache collisions between repos with same version.

func (*VulnScanner) Scan added in v1.1.0

func (s *VulnScanner) Scan(ctx context.Context, failOn string) (*types.ScanResult, error)

Scan performs vulnerability scanning on all vendored dependencies. ctx controls cancellation — a cancelled context aborts in-flight HTTP requests. failOn specifies the severity threshold for failing (critical|high|medium|low). An empty string means no threshold check.

type VulnScannerInterface added in v1.1.0

type VulnScannerInterface interface {
	// Scan performs vulnerability scanning on all vendored dependencies.
	// ctx controls cancellation — a cancelled context aborts in-flight HTTP requests.
	// failOn specifies the severity threshold (critical|high|medium|low) for failing.
	// Returns nil error even if vulnerabilities are found; check result.Summary.Result.
	Scan(ctx context.Context, failOn string) (*types.ScanResult, error)

	// ClearCache removes all cached OSV responses.
	ClearCache() error
}

VulnScannerInterface defines the contract for vulnerability scanning. VulnScannerInterface enables mocking in tests and alternative implementations.

type YAMLStore

type YAMLStore[T any] struct {
	// contains filtered or unexported fields
}

YAMLStore provides generic YAML file I/O operations. YAMLStore consolidates duplicate code between ConfigStore and LockStore using Go 1.18+ generics.

func NewYAMLStore

func NewYAMLStore[T any](rootDir, filename string, allowMissing bool) *YAMLStore[T]

NewYAMLStore creates a new YAML store for type T.

Parameters:

  • rootDir: Directory containing the YAML file
  • filename: Name of the YAML file (e.g., "vendor.yml", "vendor.lock")
  • allowMissing: If true, Load() returns zero value for missing files instead of error

func (*YAMLStore[T]) Load

func (s *YAMLStore[T]) Load() (T, error)

Load reads and unmarshals the YAML file into type T. SEC-020: Rejects files larger than maxYAMLFileSize (1 MB) to prevent memory exhaustion from oversized config files.

func (*YAMLStore[T]) Path

func (s *YAMLStore[T]) Path() string

Path returns the full file path

func (*YAMLStore[T]) Save

func (s *YAMLStore[T]) Save(data T) error

Save marshals and writes type T to the YAML file

Directories

Path Synopsis
Package providers implements git platform-specific URL parsing and operations.
Package providers implements git platform-specific URL parsing and operations.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL