Documentation
¶
Overview ¶
Package language provides the base implementation and error types for language-specific builders in engine-ci.
This package eliminates code duplication across language packages by providing:
- BaseLanguageBuilder: Common functionality shared by all language builders
- Standardized error types: ValidationError, BuildError, ContainerError, CacheError
- Interface compliance: Implements LanguageBuilder and BuildStep interfaces
- Configuration integration: Centralized configuration management
The BaseLanguageBuilder replaces duplicated code patterns that were scattered across individual language packages (golang, python, maven, etc.) with a shared implementation that handles:
- Container management and lifecycle
- Configuration access and validation
- Logging and error handling
- Cache management
- Image tagging and metadata
Language packages should embed BaseLanguageBuilder and implement language-specific build logic while leveraging the shared infrastructure.
Example usage in a language package:
type PythonContainer struct {
*language.BaseLanguageBuilder
// Language-specific fields
}
func New(build container.Build) *PythonContainer {
cfg := &config.LanguageConfig{
BaseImage: "python:3.11-slim-bookworm",
CacheLocation: "/root/.cache/pip",
// ... other config
}
baseBuilder := language.NewBaseLanguageBuilder("python", cfg, container.New(build), nil)
return &PythonContainer{BaseLanguageBuilder: baseBuilder}
}
This file provides standardized error types for language builders.
These error types replace the antipattern of os.Exit(1) calls scattered throughout the codebase. They provide:
- Structured error information with context
- Error wrapping for better debugging
- Consistent error messages across all language packages
- Support for error recovery and handling strategies
The error types follow Go's error handling best practices and integrate with the standard errors package for error unwrapping and type checking.
Package language provides container build orchestration that eliminates code duplication across all language implementations.
The ContainerBuildOrchestrator centralizes the ~90% of container orchestration logic that was previously duplicated across golang/alpine, golang/debian, golang/debiancgo, python, maven, and other language packages.
Key benefits:
- Eliminates duplicated SSH forwarding setup across all language packages
- Centralizes container configuration and environment variable handling
- Provides uniform volume mounting for source code and caches
- Standardizes image pulling and management workflows
- Reduces maintenance burden by consolidating container orchestration logic
- Enables consistent error handling and logging across all languages
The orchestrator uses the Strategy pattern to delegate only the truly language-specific behavior (intermediate image creation, build scripts, commit decisions) while handling all the shared container orchestration.
Example usage:
// Create a language strategy (e.g., for Go)
strategy := &GoLanguageStrategy{
container: goContainer,
baseBuilder: baseLanguageBuilder,
}
// Create orchestrator with the strategy
orchestrator := NewContainerBuildOrchestrator(strategy, baseLanguageBuilder)
// Execute unified build workflow
imageID, err := orchestrator.Build(ctx)
if err != nil {
return fmt.Errorf("build failed: %w", err)
}
// Pull all required images
if err := orchestrator.Pull(); err != nil {
return fmt.Errorf("pull failed: %w", err)
}
// Get all images needed
images := orchestrator.Images()
This design eliminates the need for each language package to implement the same container orchestration logic repeatedly, reducing the codebase from O(n) duplicated implementations to O(1) orchestrator + O(n) simple strategy implementations.
Package language provides common interfaces and utilities for language-specific container builds. This package defines the LanguageStrategy interface that abstracts language-specific behaviors used by the ContainerBuildOrchestrator to eliminate code duplication across different language implementations.
Index ¶
- Constants
- type BaseLanguageBuilder
- func (b *BaseLanguageBuilder) BaseImage() string
- func (b *BaseLanguageBuilder) Build() (string, error)
- func (b *BaseLanguageBuilder) BuildImage() (string, error)
- func (b *BaseLanguageBuilder) BuildScript() string
- func (b *BaseLanguageBuilder) BuildTimeout() time.Duration
- func (b *BaseLanguageBuilder) CacheLocation() string
- func (b *BaseLanguageBuilder) ComputeImageTag(data []byte) string
- func (b *BaseLanguageBuilder) CreateBuildStepAdapter() build.BuildStep
- func (b *BaseLanguageBuilder) DefaultEnvironment() []string
- func (b *BaseLanguageBuilder) GetCacheManager() build.CacheManager
- func (b *BaseLanguageBuilder) GetConfig() *config.LanguageConfig
- func (b *BaseLanguageBuilder) GetContainer() *container.Container
- func (b *BaseLanguageBuilder) GetLogger() *slog.Logger
- func (b *BaseLanguageBuilder) Images() []string
- func (b *BaseLanguageBuilder) IsAsync() bool
- func (b *BaseLanguageBuilder) Name() string
- func (b *BaseLanguageBuilder) PostBuild() error
- func (b *BaseLanguageBuilder) PreBuild() error
- func (b *BaseLanguageBuilder) Pull() error
- func (b *BaseLanguageBuilder) SetValidator(validator build.Validator)
- func (b *BaseLanguageBuilder) Validate() error
- func (b *BaseLanguageBuilder) ValidateWithValidator(ctx context.Context) (*build.ValidationResult, error)
- type BuildError
- type CacheError
- type ContainerBuildOrchestrator
- func (o *ContainerBuildOrchestrator) Build(ctx context.Context) (string, error)
- func (o *ContainerBuildOrchestrator) GetBaseBuilder() *BaseLanguageBuilder
- func (o *ContainerBuildOrchestrator) GetLogger() *slog.Logger
- func (o *ContainerBuildOrchestrator) GetStrategy() LanguageStrategy
- func (o *ContainerBuildOrchestrator) Images() []string
- func (o *ContainerBuildOrchestrator) Pull() error
- func (o *ContainerBuildOrchestrator) SetStrategy(strategy LanguageStrategy)
- func (o *ContainerBuildOrchestrator) Validate() error
- type ContainerError
- type GolangStrategyConfig
- type LanguageBuilderStep
- func (s *LanguageBuilderStep) Dependencies() []string
- func (s *LanguageBuilderStep) Execute(ctx context.Context) error
- func (s *LanguageBuilderStep) IsAsync() bool
- func (s *LanguageBuilderStep) Name() string
- func (s *LanguageBuilderStep) Timeout() time.Duration
- func (s *LanguageBuilderStep) Validate() error
- type LanguageStrategy
- func NewAlpineStrategy(build container.Build, embedFS embed.FS, platforms []*types.PlatformSpec) LanguageStrategy
- func NewDebianCGOStrategy(build container.Build, embedFS embed.FS, platforms []*types.PlatformSpec) LanguageStrategy
- func NewDebianStrategy(build container.Build, embedFS embed.FS, platforms []*types.PlatformSpec) LanguageStrategy
- type LanguageStrategyConfig
- type ValidationError
Constants ¶
const (
DEFAULT_GO = "1.24.2"
)
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type BaseLanguageBuilder ¶
type BaseLanguageBuilder struct {
// contains filtered or unexported fields
}
BaseLanguageBuilder provides common functionality for all language builders. This eliminates code duplication across language packages by implementing shared behavior that all language builders need.
func NewBaseLanguageBuilder ¶
func NewBaseLanguageBuilder( name string, config *config.LanguageConfig, container *container.Container, cache build.CacheManager, ) *BaseLanguageBuilder
NewBaseLanguageBuilder creates a new base language builder
func (*BaseLanguageBuilder) BaseImage ¶
func (b *BaseLanguageBuilder) BaseImage() string
BaseImage returns the base container image for this language
func (*BaseLanguageBuilder) Build ¶
func (b *BaseLanguageBuilder) Build() (string, error)
Build executes the build process and returns the resulting image ID This method must be implemented by specific language builders
func (*BaseLanguageBuilder) BuildImage ¶
func (b *BaseLanguageBuilder) BuildImage() (string, error)
BuildImage builds the intermediate language-specific image This method must be implemented by specific language builders
func (*BaseLanguageBuilder) BuildScript ¶
func (b *BaseLanguageBuilder) BuildScript() string
BuildScript generates the build script for this language This method must be implemented by specific language builders
func (*BaseLanguageBuilder) BuildTimeout ¶
func (b *BaseLanguageBuilder) BuildTimeout() time.Duration
BuildTimeout returns the maximum build time allowed for this language
func (*BaseLanguageBuilder) CacheLocation ¶
func (b *BaseLanguageBuilder) CacheLocation() string
CacheLocation returns the cache directory path inside the container
func (*BaseLanguageBuilder) ComputeImageTag ¶
func (b *BaseLanguageBuilder) ComputeImageTag(data []byte) string
ComputeImageTag computes a deterministic tag from dockerfile content This replaces the duplicated ComputeChecksum functions across packages
func (*BaseLanguageBuilder) CreateBuildStepAdapter ¶
func (b *BaseLanguageBuilder) CreateBuildStepAdapter() build.BuildStep
CreateBuildStepAdapter creates a BuildStep adapter for this language builder This allows language builders to be used in build pipelines
func (*BaseLanguageBuilder) DefaultEnvironment ¶
func (b *BaseLanguageBuilder) DefaultEnvironment() []string
DefaultEnvironment returns the default environment variables for this language
func (*BaseLanguageBuilder) GetCacheManager ¶
func (b *BaseLanguageBuilder) GetCacheManager() build.CacheManager
GetCacheManager returns the cache manager instance
func (*BaseLanguageBuilder) GetConfig ¶
func (b *BaseLanguageBuilder) GetConfig() *config.LanguageConfig
GetConfig returns the language configuration
func (*BaseLanguageBuilder) GetContainer ¶
func (b *BaseLanguageBuilder) GetContainer() *container.Container
GetContainer returns the underlying container instance
func (*BaseLanguageBuilder) GetLogger ¶
func (b *BaseLanguageBuilder) GetLogger() *slog.Logger
GetLogger returns the logger instance
func (*BaseLanguageBuilder) Images ¶
func (b *BaseLanguageBuilder) Images() []string
Images returns all images required by this builder This method must be implemented by specific language builders
func (*BaseLanguageBuilder) IsAsync ¶
func (b *BaseLanguageBuilder) IsAsync() bool
IsAsync returns whether this builder supports async execution Most language builders are synchronous by default
func (*BaseLanguageBuilder) Name ¶
func (b *BaseLanguageBuilder) Name() string
Name returns the name of the language builder
func (*BaseLanguageBuilder) PostBuild ¶
func (b *BaseLanguageBuilder) PostBuild() error
PostBuild executes common post-build operations
func (*BaseLanguageBuilder) PreBuild ¶
func (b *BaseLanguageBuilder) PreBuild() error
PreBuild executes common pre-build operations
func (*BaseLanguageBuilder) Pull ¶
func (b *BaseLanguageBuilder) Pull() error
Pull pulls the required base images for this language
func (*BaseLanguageBuilder) SetValidator ¶
func (b *BaseLanguageBuilder) SetValidator(validator build.Validator)
SetValidator sets the validator for this builder
func (*BaseLanguageBuilder) Validate ¶
func (b *BaseLanguageBuilder) Validate() error
Validate validates the builder configuration and dependencies
func (*BaseLanguageBuilder) ValidateWithValidator ¶
func (b *BaseLanguageBuilder) ValidateWithValidator(ctx context.Context) (*build.ValidationResult, error)
ValidateWithValidator uses the configured validator if available
type BuildError ¶
type BuildError struct {
Cause error
Context map[string]interface{}
Operation string
Language string
}
BuildError represents a build-related error
func NewBuildError ¶
func NewBuildError(operation, language string, cause error) *BuildError
NewBuildError creates a new build error
func (*BuildError) Unwrap ¶
func (e *BuildError) Unwrap() error
Unwrap returns the underlying error for error unwrapping
func (*BuildError) WithContext ¶
func (e *BuildError) WithContext(key string, value interface{}) *BuildError
WithContext adds context information to the build error
type CacheError ¶
CacheError represents a cache-related error
func NewCacheError ¶
func NewCacheError(operation, language string, cause error) *CacheError
NewCacheError creates a new cache error
func (*CacheError) Unwrap ¶
func (e *CacheError) Unwrap() error
Unwrap returns the underlying error for error unwrapping
func (*CacheError) WithPath ¶
func (e *CacheError) WithPath(cachePath string) *CacheError
WithPath adds cache path to the error
type ContainerBuildOrchestrator ¶ added in v0.20.1
type ContainerBuildOrchestrator struct {
// contains filtered or unexported fields
}
ContainerBuildOrchestrator eliminates ~90% of duplicated container orchestration code across all language packages by centralizing the shared build workflow logic.
This orchestrator handles all the common container operations that were previously duplicated across golang/alpine, golang/debian, golang/debiancgo, python, maven, and other language implementations:
- SSH forwarding setup (identical across all languages)
- Container configuration and environment variables (identical pattern)
- Working directory and volume mount setup (identical logic)
- Source code and cache volume mounting (identical implementation)
- BuildingContainer execution (identical call pattern)
- Image pulling workflows (100% identical)
- Images list generation (90% identical pattern)
The orchestrator uses composition with BaseLanguageBuilder for shared functionality and delegation to LanguageStrategy for language-specific behavior. This eliminates code duplication while maintaining the flexibility for language-specific customization.
Performance benefits:
- Reduces duplicated code by ~90% across language packages
- Centralizes container orchestration logic for easier maintenance
- Provides consistent error handling and logging
- Enables uniform caching and volume management
- Standardizes SSH forwarding and security setup
func NewContainerBuildOrchestrator ¶ added in v0.20.1
func NewContainerBuildOrchestrator(strategy LanguageStrategy, baseBuilder *BaseLanguageBuilder) *ContainerBuildOrchestrator
NewContainerBuildOrchestrator creates a new container build orchestrator that eliminates duplicated container orchestration code across language implementations.
The orchestrator centralizes the shared build workflow logic while delegating language-specific behavior to the provided strategy. This design reduces code duplication from O(n) language implementations to O(1) orchestrator + O(n) strategies.
Parameters:
- strategy: Language-specific strategy implementing LanguageStrategy interface
- baseBuilder: Shared base functionality from BaseLanguageBuilder
Returns:
- *ContainerBuildOrchestrator: Configured orchestrator ready for build operations
Example usage:
strategy := &GoLanguageStrategy{container: goContainer}
orchestrator := NewContainerBuildOrchestrator(strategy, baseBuilder)
// Orchestrator now handles all shared container logic
imageID, err := orchestrator.Build(ctx)
func (*ContainerBuildOrchestrator) Build ¶ added in v0.20.1
func (o *ContainerBuildOrchestrator) Build(ctx context.Context) (string, error)
Build executes the complete container build workflow, centralizing the ~90% of duplicated orchestration code that was scattered across language packages.
This method eliminates the following duplicated patterns:
- SSH forwarding setup (identical across golang/debian, golang/alpine, python)
- Container configuration setup (identical pattern in all language packages)
- Environment variables from config (identical logic everywhere)
- Working directory setup (identical implementation)
- Source volume mount (identical across all languages)
- Cache volume mount (identical logic)
- SSH application to config (identical call)
- Build script setting (identical pattern)
- BuildingContainer call (identical across all packages)
- Optional commit step (varies by language via strategy)
The method delegates only the truly language-specific parts to the strategy:
- GetIntermediateImage(): Language-specific image creation (GoImage(), PythonImage(), etc.)
- GenerateBuildScript(): Language-specific build commands
- ShouldCommitResult(): Language-specific commit decision
- GetCommitCommand(): Language-specific commit configuration
Parameters:
- ctx: Context for cancellation and timeouts
Returns:
- string: Container/image ID of the build result
- error: Build error with proper context and error wrapping
Error handling:
- SSH forwarding errors → BuildError with "ssh_forward" operation
- Container configuration errors → BuildError with appropriate operation context
- Build execution errors → BuildError with "building_container" operation
- Commit errors → BuildError with "commit_container" operation
func (*ContainerBuildOrchestrator) GetBaseBuilder ¶ added in v0.20.1
func (o *ContainerBuildOrchestrator) GetBaseBuilder() *BaseLanguageBuilder
GetBaseBuilder returns the base language builder for shared functionality access. This provides access to configuration, container, logging, and other shared services.
func (*ContainerBuildOrchestrator) GetLogger ¶ added in v0.20.1
func (o *ContainerBuildOrchestrator) GetLogger() *slog.Logger
GetLogger returns the orchestrator's logger for consistent logging integration.
func (*ContainerBuildOrchestrator) GetStrategy ¶ added in v0.20.1
func (o *ContainerBuildOrchestrator) GetStrategy() LanguageStrategy
GetStrategy returns the language strategy for advanced usage. This allows access to language-specific functionality when needed.
func (*ContainerBuildOrchestrator) Images ¶ added in v0.20.1
func (o *ContainerBuildOrchestrator) Images() []string
Images returns all container images required for the build, eliminating 90% duplicated image list logic across all language packages.
This method centralizes the nearly identical Images() patterns from:
- golang/debian/golang.go: Images() method (lines 134-142)
- golang/alpine/golang.go: Images() method
- python/python.go: Images() method (lines 80-87)
- All other language packages with similar logic
The method:
- Gets base image (identical across all languages)
- Gets intermediate image via strategy (replaces GoImage(), PythonImage(), etc.)
- Gets additional images via strategy (replaces hardcoded lists)
- Handles errors gracefully with fallback (identical error handling pattern)
- Returns combined list (identical return pattern)
Returns:
- []string: Complete list of images required for the build
func (*ContainerBuildOrchestrator) Pull ¶ added in v0.20.1
func (o *ContainerBuildOrchestrator) Pull() error
Pull executes the image pulling workflow, eliminating 100% duplicated pull logic that was scattered across all language packages.
This method centralizes the identical pull patterns from:
- golang/debian/golang.go: Pull() method (lines 97-110)
- golang/alpine/golang.go: Pull() method
- golang/debiancgo/golang.go: Pull() method
- python/python.go: Pull() method (line 76-78)
- All other language packages with identical logic
The method:
- Pulls the base image (identical across all languages)
- Pulls additional images via strategy (replaces hardcoded alpine:latest, etc.)
- Provides consistent error handling and logging
Returns:
- error: Pull error with proper context (ContainerError with image information)
func (*ContainerBuildOrchestrator) SetStrategy ¶ added in v0.20.1
func (o *ContainerBuildOrchestrator) SetStrategy(strategy LanguageStrategy)
SetStrategy updates the language strategy. This enables runtime strategy switching for advanced use cases or testing scenarios.
func (*ContainerBuildOrchestrator) Validate ¶ added in v0.20.1
func (o *ContainerBuildOrchestrator) Validate() error
Validate validates the orchestrator configuration and strategy. This provides comprehensive validation across the orchestrator and strategy.
type ContainerError ¶
ContainerError represents a container-related error
func NewContainerError ¶
func NewContainerError(operation string, cause error) *ContainerError
NewContainerError creates a new container error
func (*ContainerError) Error ¶
func (e *ContainerError) Error() string
Error implements the error interface
func (*ContainerError) Unwrap ¶
func (e *ContainerError) Unwrap() error
Unwrap returns the underlying error for error unwrapping
func (*ContainerError) WithContainer ¶
func (e *ContainerError) WithContainer(containerID string) *ContainerError
WithContainer adds container ID to the error
func (*ContainerError) WithImage ¶
func (e *ContainerError) WithImage(imageName string) *ContainerError
WithImage adds image name to the error
type GolangStrategyConfig ¶ added in v0.20.2
type GolangStrategyConfig struct {
ImageSuffix string // e.g., "-alpine", "", "-cgo"
DockerFile string // e.g., "Dockerfilego"
GoVersion string // e.g., "1.24.2"
}
GolangStrategyConfig defines the configuration for different golang strategies
type LanguageBuilderStep ¶
type LanguageBuilderStep struct {
// contains filtered or unexported fields
}
LanguageBuilderStep adapts a LanguageBuilder to the BuildStep interface
func (*LanguageBuilderStep) Dependencies ¶
func (s *LanguageBuilderStep) Dependencies() []string
Dependencies returns the dependencies for this build step
func (*LanguageBuilderStep) Execute ¶
func (s *LanguageBuilderStep) Execute(ctx context.Context) error
Execute executes the language builder as a build step
func (*LanguageBuilderStep) IsAsync ¶
func (s *LanguageBuilderStep) IsAsync() bool
IsAsync returns whether this step can run asynchronously
func (*LanguageBuilderStep) Name ¶
func (s *LanguageBuilderStep) Name() string
Name returns the name of this build step
func (*LanguageBuilderStep) Timeout ¶
func (s *LanguageBuilderStep) Timeout() time.Duration
Timeout returns the timeout for this build step
func (*LanguageBuilderStep) Validate ¶
func (s *LanguageBuilderStep) Validate() error
Validate validates this build step
type LanguageStrategy ¶ added in v0.20.1
type LanguageStrategy interface {
// GetIntermediateImage returns the language-specific intermediate container image
// that contains the build tools and dependencies needed for compilation.
//
// This method abstracts the language-specific image creation logic:
// - Go: Returns result of GoImage() method with golang base image
// - Python: Returns result of PythonImage() method with python base image
// - Java: Would return JavaImage() with JDK base image
//
// The orchestrator uses this image for the build container where compilation occurs.
// The image typically includes language runtime, build tools, and cached dependencies.
//
// Returns:
// - string: Fully qualified image URI (e.g., "registry.io/golang-1.24.2-alpine:abc123")
// - error: If image cannot be determined or built
//
// Example implementations:
// - Go Alpine: "containify.io/golang-1.24.2-alpine:sha256hash"
// - Python Slim: "containify.io/python-3.11-slim-bookworm:sha256hash"
GetIntermediateImage(ctx context.Context) (string, error)
// GenerateBuildScript returns the language-specific build script that will be
// executed inside the build container to compile/build the application.
//
// This method eliminates duplication of build script generation logic:
// - Go: Returns BuildScript() with go build, test, and platform-specific commands
// - Python: Returns BuildScript() with pip install, pytest, and package commands
// - Java: Would return Maven/Gradle build commands
//
// The generated script should handle:
// - Dependency installation/resolution
// - Compilation or build process
// - Testing execution
// - Artifact generation
// - Platform-specific optimizations
//
// Returns:
// - string: Shell script content to execute in the build container
//
// Example Go script:
// #!/bin/bash
// set -e
// go mod download
// go test ./...
// CGO_ENABLED=0 GOOS=linux go build -o /out/app ./main.go
//
// Example Python script:
// #!/bin/bash
// set -e
// pip install -r requirements.txt
// python -m pytest
// python -m build --wheel --outdir /out/
GenerateBuildScript() string
// GetAdditionalImages returns a list of additional container images that need
// to be pulled before the build process can start.
//
// This method abstracts language-specific image dependencies:
// - Go: Returns ["alpine:latest"] for final lightweight runtime image
// - Python: Returns ["python:3.11-slim"] for runtime image
// - Node.js: Would return ["node:18-alpine"] for runtime
//
// The orchestrator uses this list to:
// - Pre-pull all required images in parallel for better performance
// - Ensure all dependencies are available before starting build
// - Enable offline/air-gapped builds by pre-staging images
//
// Returns:
// - []string: List of fully qualified image names to pull
//
// Example return values:
// - Go: ["alpine:latest", "scratch"]
// - Python: ["python:3.11-slim-bookworm"]
// - Java: ["openjdk:11-jre-slim"]
GetAdditionalImages() []string
// ShouldCommitResult determines whether the orchestrator should commit the
// final build result to create a new container image.
//
// This method allows language-specific control over result handling:
// - Go: Returns true to create optimized final image with compiled binary
// - Python: Returns true to create image with installed packages and code
// - Script languages: Might return false if only artifacts are needed
//
// When true, the orchestrator will:
// - Commit the final container state after build completion
// - Tag the resulting image appropriately
// - Make the image available for deployment or further processing
//
// When false, the orchestrator will:
// - Extract build artifacts from the container
// - Clean up the build container without committing
// - Provide artifacts through alternative means (volumes, copying)
//
// Returns:
// - bool: true if result should be committed as container image
ShouldCommitResult() bool
// GetCommitCommand returns the container commit command to use when
// ShouldCommitResult() returns true.
//
// This method provides language-specific commit behavior:
// - Go: Returns optimized commit command with minimal layers
// - Python: Returns commit with proper Python entrypoint and metadata
// - Web apps: Might return commit with web server configuration
//
// The command should specify:
// - Appropriate entrypoint for the language/application type
// - Required environment variables
// - Working directory
// - Exposed ports (if applicable)
// - Metadata labels for traceability
//
// Returns:
// - string: Container commit command with appropriate configuration
//
// Example Go commit command:
// --change 'ENTRYPOINT ["/app"]' --change 'WORKDIR /app' --change 'EXPOSE 8080'
//
// Example Python commit command:
// --change 'ENTRYPOINT ["python", "/app/main.py"]' --change 'WORKDIR /app'
//
// If ShouldCommitResult() returns false, this method may return empty string
// or may not be called by the orchestrator.
GetCommitCommand() string
// GetIntermediateImageDockerfile returns the dockerfile content used to build
// the intermediate image for this language strategy.
//
// This method enables the orchestrator to build the intermediate image when needed.
// The dockerfile should contain all build tools, dependencies, and language-specific
// setup required for the compilation process.
//
// Returns:
// - []byte: Raw dockerfile content
// - error: If dockerfile cannot be read or accessed
GetIntermediateImageDockerfile(ctx context.Context) ([]byte, error)
// GetIntermediateImagePlatforms returns the platforms for which the intermediate
// image should be built.
//
// This method provides platform information for multi-platform builds:
// - Single platform: []*types.PlatformSpec{types.ParsePlatform("linux/amd64")}
// - Multi-platform: []*types.PlatformSpec{types.ParsePlatform("linux/amd64"), types.ParsePlatform("linux/arm64")}
//
// Returns:
// - []*types.PlatformSpec: List of target platforms for the intermediate image
GetIntermediateImagePlatforms() []*types.PlatformSpec
// GetCacheDirectory returns the language-specific cache directory path that should
// be mounted as a volume in the build container.
//
// This method abstracts language-specific cache resolution:
// - Go: Returns result of 'go env GOMODCACHE' (e.g., "/Users/user/go/pkg/mod")
// - Python: Returns result of 'pip cache dir' (e.g., "/Users/user/.cache/pip")
// - Node.js: Would return npm cache directory
//
// The orchestrator uses this directory to:
// - Mount the host cache directory as a volume in the build container
// - Persist downloaded dependencies between builds for faster builds
// - Respect language tooling's native cache mechanisms
//
// Returns:
// - string: Absolute path to the cache directory on the host system
// - error: If cache directory cannot be determined or accessed
//
// Example implementations:
// - Go: Executes 'go env GOMODCACHE' and returns the result
// - Python: Executes 'pip cache dir' and returns the result
// - Java: Returns Maven local repository path (~/.m2/repository)
//
// If this method returns an error, the orchestrator will fall back to using
// a temporary cache directory specific to the language (e.g., .tmp/golang-alpine).
GetCacheDirectory() (string, error)
}
LanguageStrategy defines the contract for language-specific behavior that enables the ContainerBuildOrchestrator to handle different programming languages uniformly. This interface eliminates code duplication by abstracting the language-specific methods that were previously scattered across individual language implementations.
The strategy pattern allows the orchestrator to work with any language implementation without knowing the specific details of how each language handles builds, images, or scripts. This promotes maintainability and extensibility when adding new language support.
Key benefits:
- Eliminates duplicated orchestration logic across language implementations
- Provides a uniform interface for container build operations
- Enables easy addition of new programming languages
- Centralizes build workflow logic in the orchestrator
- Maintains language-specific customization through strategy implementations
Example usage:
// Go language strategy implementation
goStrategy := &GoLanguageStrategy{
container: goContainer,
version: "1.24.2",
}
// Python language strategy implementation
pythonStrategy := &PythonLanguageStrategy{
container: pythonContainer,
version: "3.11",
}
// Orchestrator can work with any language uniformly
orchestrator := NewContainerBuildOrchestrator(goStrategy)
err := orchestrator.ExecuteBuild(ctx)
// Same orchestrator logic works for Python
orchestrator = NewContainerBuildOrchestrator(pythonStrategy)
err = orchestrator.ExecuteBuild(ctx)
func NewAlpineStrategy ¶ added in v0.20.2
func NewAlpineStrategy(build container.Build, embedFS embed.FS, platforms []*types.PlatformSpec) LanguageStrategy
NewAlpineStrategy creates a golang strategy for Alpine builds
func NewDebianCGOStrategy ¶ added in v0.20.2
func NewDebianCGOStrategy(build container.Build, embedFS embed.FS, platforms []*types.PlatformSpec) LanguageStrategy
NewDebianCGOStrategy creates a golang strategy for Debian CGO builds
func NewDebianStrategy ¶ added in v0.20.2
func NewDebianStrategy(build container.Build, embedFS embed.FS, platforms []*types.PlatformSpec) LanguageStrategy
NewDebianStrategy creates a golang strategy for Debian builds
type LanguageStrategyConfig ¶ added in v0.20.1
type LanguageStrategyConfig struct {
Environment map[string]string
Registry string
BuildTimeout string
Platform string
Tags []string
Verbose bool
}
LanguageStrategyConfig provides configuration options for language strategy implementations. This struct can be embedded or used as a parameter to provide common configuration values that strategies might need.
type ValidationError ¶
type ValidationError struct {
Field string // The field that failed validation
Value interface{} // The value that failed validation
Message string // Human-readable error message
}
ValidationError represents a validation error in language builders
func NewValidationError ¶
func NewValidationError(field string, value interface{}, message string) *ValidationError
NewValidationError creates a new validation error
func (*ValidationError) Error ¶
func (e *ValidationError) Error() string
Error implements the error interface