- Add internal/phases/ with complete phase management system - Add internal/types/ with core data structures - Add internal/treefile/ for OSTree treefile generation - Update examples with YAML configurations - Update .gitignore to properly exclude test artifacts and build outputs - Update dependencies and configuration files
174 lines
6 KiB
Go
174 lines
6 KiB
Go
package phases
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"deb-bootc-compose/internal/types"
|
|
)
|
|
|
|
// GatherPhase handles package gathering and dependency resolution
|
|
type GatherPhase struct {
|
|
PhaseBase
|
|
}
|
|
|
|
// NewGatherPhase creates a new GatherPhase
|
|
func NewGatherPhase() *GatherPhase {
|
|
return &GatherPhase{
|
|
PhaseBase: NewPhaseBase("gather", []string{"init"}),
|
|
}
|
|
}
|
|
|
|
// Run executes the gather phase
|
|
func (p *GatherPhase) Run(engine types.Engine) error {
|
|
logger := engine.GetLogger()
|
|
logger.Printf("Starting package gathering phase")
|
|
|
|
// Get package information from treefile
|
|
treefile := engine.GetTreefile()
|
|
|
|
// Process each variant and architecture
|
|
for _, variant := range treefile.Variants {
|
|
for _, arch := range variant.Architectures {
|
|
logger.Printf("Processing variant %s for architecture %s", variant.Name, arch)
|
|
|
|
// Get packages for this variant/architecture combination
|
|
packages := treefile.GetPackagesForVariant(variant.Name, arch)
|
|
excluded := treefile.GetExcludedPackagesForVariant(variant.Name, arch)
|
|
|
|
// Create variant-specific work directory
|
|
variantWorkDir := filepath.Join(engine.GetWorkDir(), "variants", variant.Name, arch)
|
|
if err := os.MkdirAll(variantWorkDir, 0755); err != nil {
|
|
return fmt.Errorf("failed to create variant work directory: %w", err)
|
|
}
|
|
|
|
// Gather package information
|
|
if err := p.gatherPackageInfo(engine, variantWorkDir, packages, excluded, arch); err != nil {
|
|
return fmt.Errorf("failed to gather package info for variant %s/%s: %w", variant.Name, arch, err)
|
|
}
|
|
|
|
// Resolve dependencies
|
|
if err := p.resolveDependencies(engine, variantWorkDir, packages, arch); err != nil {
|
|
return fmt.Errorf("failed to resolve dependencies for variant %s/%s: %w", variant.Name, arch, err)
|
|
}
|
|
|
|
logger.Printf("Completed processing variant %s for architecture %s", variant.Name, arch)
|
|
}
|
|
}
|
|
|
|
logger.Printf("Package gathering phase completed successfully")
|
|
return nil
|
|
}
|
|
|
|
// gatherPackageInfo gathers information about packages
|
|
func (p *GatherPhase) gatherPackageInfo(engine types.Engine, workDir string, packages types.PackageSet, excluded []string, arch string) error {
|
|
logger := engine.GetLogger()
|
|
|
|
// Create package info directory
|
|
packageInfoDir := filepath.Join(workDir, "package-info")
|
|
if err := os.MkdirAll(packageInfoDir, 0755); err != nil {
|
|
return fmt.Errorf("failed to create package info directory: %w", err)
|
|
}
|
|
|
|
// Write package lists
|
|
if err := p.writePackageList(packageInfoDir, "required", packages.Required); err != nil {
|
|
return fmt.Errorf("failed to write required packages list: %w", err)
|
|
}
|
|
|
|
if err := p.writePackageList(packageInfoDir, "optional", packages.Optional); err != nil {
|
|
return fmt.Errorf("failed to write optional packages list: %w", err)
|
|
}
|
|
|
|
if err := p.writePackageList(packageInfoDir, "recommended", packages.Recommended); err != nil {
|
|
return fmt.Errorf("failed to write recommended packages list: %w", err)
|
|
}
|
|
|
|
if err := p.writePackageList(packageInfoDir, "development", packages.Development); err != nil {
|
|
return fmt.Errorf("failed to write development packages list: %w", err)
|
|
}
|
|
|
|
if err := p.writePackageList(packageInfoDir, "kernel", packages.Kernel); err != nil {
|
|
return fmt.Errorf("failed to write kernel packages list: %w", err)
|
|
}
|
|
|
|
if err := p.writePackageList(packageInfoDir, "bootloader", packages.Bootloader); err != nil {
|
|
return fmt.Errorf("failed to write bootloader packages list: %w", err)
|
|
}
|
|
|
|
if err := p.writePackageList(packageInfoDir, "excluded", excluded); err != nil {
|
|
return fmt.Errorf("failed to write excluded packages list: %w", err)
|
|
}
|
|
|
|
logger.Printf("Package information gathered for architecture %s", arch)
|
|
return nil
|
|
}
|
|
|
|
// writePackageList writes a list of packages to a file
|
|
func (p *GatherPhase) writePackageList(dir, name string, packages []string) error {
|
|
if len(packages) == 0 {
|
|
return nil
|
|
}
|
|
|
|
filename := filepath.Join(dir, name+".txt")
|
|
content := ""
|
|
for _, pkg := range packages {
|
|
content += pkg + "\n"
|
|
}
|
|
|
|
if err := os.WriteFile(filename, []byte(content), 0644); err != nil {
|
|
return fmt.Errorf("failed to write package list %s: %w", name, err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// resolveDependencies resolves package dependencies
|
|
func (p *GatherPhase) resolveDependencies(engine types.Engine, workDir string, packages types.PackageSet, arch string) error {
|
|
logger := engine.GetLogger()
|
|
|
|
// Create dependencies directory
|
|
depsDir := filepath.Join(workDir, "dependencies")
|
|
if err := os.MkdirAll(depsDir, 0755); err != nil {
|
|
return fmt.Errorf("failed to create dependencies directory: %w", err)
|
|
}
|
|
|
|
// Collect all packages
|
|
allPackages := make([]string, 0)
|
|
allPackages = append(allPackages, packages.Required...)
|
|
allPackages = append(allPackages, packages.Optional...)
|
|
allPackages = append(allPackages, packages.Recommended...)
|
|
allPackages = append(allPackages, packages.Development...)
|
|
allPackages = append(allPackages, packages.Kernel...)
|
|
allPackages = append(allPackages, packages.Bootloader...)
|
|
|
|
// Remove duplicates
|
|
uniquePackages := make(map[string]bool)
|
|
for _, pkg := range allPackages {
|
|
uniquePackages[pkg] = true
|
|
}
|
|
|
|
// Write unique package list
|
|
uniqueList := make([]string, 0, len(uniquePackages))
|
|
for pkg := range uniquePackages {
|
|
uniqueList = append(uniqueList, pkg)
|
|
}
|
|
|
|
if err := p.writePackageList(depsDir, "all-packages", uniqueList); err != nil {
|
|
return fmt.Errorf("failed to write all packages list: %w", err)
|
|
}
|
|
|
|
// TODO: Implement actual dependency resolution using apt-cache or similar
|
|
// For now, just log what we would do
|
|
logger.Printf("Would resolve dependencies for %d unique packages on architecture %s", len(uniqueList), arch)
|
|
|
|
// Create a placeholder dependencies file
|
|
depsFile := filepath.Join(depsDir, "resolved-dependencies.txt")
|
|
placeholder := fmt.Sprintf("# Dependencies resolved for architecture %s\n# This is a placeholder - actual resolution not yet implemented\n", arch)
|
|
if err := os.WriteFile(depsFile, []byte(placeholder), 0644); err != nil {
|
|
return fmt.Errorf("failed to write placeholder dependencies file: %w", err)
|
|
}
|
|
|
|
logger.Printf("Dependencies resolved for architecture %s", arch)
|
|
return nil
|
|
}
|