diff --git a/api/download.go b/api/download.go index 2b4aef0..24e7fdd 100644 --- a/api/download.go +++ b/api/download.go @@ -141,7 +141,7 @@ func DownloadGitSource(downloadPath string, source Source, moduleName string) er } // Default to latest commit - if source.Commit == "" || source.Commit == "latest" { + if len(strings.TrimSpace(source.Commit)) == 0 || strings.EqualFold(source.Commit, "latest") { source.Commit, err = gitGetLatestCommit(source.Branch, dest) if err != nil { return fmt.Errorf("could not get latest commit: %s", err.Error()) diff --git a/finalize-plugins/systemd-repart.go b/finalize-plugins/systemd-repart.go index 455f91c..3cd2e8a 100644 --- a/finalize-plugins/systemd-repart.go +++ b/finalize-plugins/systemd-repart.go @@ -20,6 +20,8 @@ type SystemdRepart struct { Size string `json:"size"` Seed string `json:"seed"` Split bool `json:"split"` + Empty string `json:"empty"` + Root string `json:"root"` DeferPartitions []string `json:"defer_partitions"` } @@ -42,6 +44,15 @@ func PluginScope() int32 { // int32 is defined as GoInt32 in cgo which is the sa return api.IMAGENAME | api.FS | api.RECIPE } +// Replace placeholders in the path with actual values from ScopeData +// $PROJROOT -> Recipe.ParentPath +// $FSROOT -> FS +func parsePath(path string, data *api.ScopeData) string { + path = strings.ReplaceAll(path, "$PROJROOT", data.Recipe.ParentPath) + path = strings.ReplaceAll(path, "$FSROOT", data.FS) + return path +} + // Finalize the build by executing systemd-repart with the provided configuration // to generate and apply partitioning specifications and output results // @@ -69,9 +80,19 @@ func FinalizeBuild(moduleInterface *C.char, extraData *C.char) *C.char { module.Json = "off" } + if len(strings.TrimSpace(module.Empty)) == 0 { + module.Empty = "create" + } + + if len(strings.TrimSpace(module.Root)) == 0 { + module.Root = data.FS + } else { + module.Root = parsePath(module.Root, data) + } + args := []string{ "--definitions=definitions", - "--empty=create", + fmt.Sprintf("--empty=%s", module.Empty), fmt.Sprintf("--size=%s", module.Size), "--dry-run=no", "--discard=no", diff --git a/plugins/apt.go b/plugins/apt.go index 6a4541f..9cfdee2 100644 --- a/plugins/apt.go +++ b/plugins/apt.go @@ -11,16 +11,15 @@ import ( "github.com/vanilla-os/vib/api" ) import ( - "path/filepath" "strings" ) // Configuration for an APT module type AptModule struct { - Name string `json:"name"` - Type string `json:"type"` - Options AptOptions `json:"options"` - Source api.Source `json:"source"` + Name string `json:"name"` + Type string `json:"type"` + Options AptOptions `json:"options"` + Sources []api.Source `json:"sources"` } // Options for APT package management @@ -75,32 +74,23 @@ func BuildModule(moduleInterface *C.char, recipeInterface *C.char) *C.char { args += "--fix-broken " } - if len(module.Source.Packages) > 0 { - packages := "" - for _, pkg := range module.Source.Packages { - packages += pkg + " " + packages := "" + for _, source := range module.Sources { + if len(source.Packages) > 0 { + for _, pkg := range source.Packages { + packages += pkg + " " + } } - return C.CString(fmt.Sprintf("apt-get install -y %s %s && apt-get clean", args, packages)) - } - - if len(strings.TrimSpace(module.Source.Path)) > 0 { - cmd := "" - installFiles, err := os.ReadDir(module.Source.Path) - if err != nil { - return C.CString(fmt.Sprintf("ERROR: %s", err.Error())) - } - for i, path := range installFiles { - fullPath := filepath.Join(module.Source.Path, path.Name()) - fileInfo, err := os.Stat(fullPath) + if len(strings.TrimSpace(source.Path)) > 0 { + fileInfo, err := os.Stat(source.Path) if err != nil { return C.CString(fmt.Sprintf("ERROR: %s", err.Error())) } if !fileInfo.Mode().IsRegular() { continue } - packages := "" - file, err := os.Open(fullPath) + file, err := os.Open(source.Path) if err != nil { return C.CString(fmt.Sprintf("ERROR: %s", err.Error())) } @@ -114,15 +104,11 @@ func BuildModule(moduleInterface *C.char, recipeInterface *C.char) *C.char { if err := scanner.Err(); err != nil { return C.CString(fmt.Sprintf("ERROR: %s", err.Error())) } - - cmd += fmt.Sprintf("apt-get install -y %s %s", args, packages) - - if i != len(installFiles)-1 { - cmd += "&& " - } else { - cmd += "&& apt-get clean" - } } + } + + if len(packages) >= 1 { + cmd := fmt.Sprintf("apt-get install -y %s %s && apt-get clean", args, packages) return C.CString(cmd) } diff --git a/plugins/cmake.go b/plugins/cmake.go index 2e6b9d7..5c084cf 100644 --- a/plugins/cmake.go +++ b/plugins/cmake.go @@ -67,7 +67,7 @@ func BuildModule(moduleInterface *C.char, recipeInterface *C.char) *C.char { } cmd := fmt.Sprintf( - "cd /sources/%s && mkdir -p build && cd build && cmake ..%s && make", + "cd /sources/%s && mkdir -p build && cd build && cmake ../%s && make", filepath.Join(recipe.SourcesPath, api.GetSourcePath(module.Source, module.Name)), buildFlags, ) diff --git a/plugins/make.go b/plugins/make.go index ac926fb..eb3cf1d 100644 --- a/plugins/make.go +++ b/plugins/make.go @@ -11,12 +11,12 @@ import "strings" // Configuration for building a project using Make type MakeModule struct { - Name string `json:"name"` - Type string `json:"type"` - BuildCommand string `json:"buildcommand"` - InstallCommand string `json:"installcommand"` - IntermediateSteps []string `json:"intermediatesteps"` - Source api.Source + Name string `json:"name"` + Type string `json:"type"` + BuildCommand string `json:"buildcommand"` + InstallCommand string `json:"installcommand"` + IntermediateSteps []string `json:"intermediatesteps"` + Sources []api.Source `json:"sources"` } // Provide plugin information as a JSON string @@ -50,13 +50,15 @@ func BuildModule(moduleInterface *C.char, recipeInterface *C.char) *C.char { return C.CString(fmt.Sprintf("ERROR: %s", err.Error())) } - err = api.DownloadSource(recipe, module.Source, module.Name) - if err != nil { - return C.CString(fmt.Sprintf("ERROR: %s", err.Error())) - } - err = api.MoveSource(recipe.DownloadsPath, recipe.SourcesPath, module.Source, module.Name) - if err != nil { - return C.CString(fmt.Sprintf("ERROR: %s", err.Error())) + for _, source := range module.Sources { + err = api.DownloadSource(recipe, source, module.Name) + if err != nil { + return C.CString(fmt.Sprintf("ERROR: %s", err.Error())) + } + err = api.MoveSource(recipe.DownloadsPath, recipe.SourcesPath, source, module.Name) + if err != nil { + return C.CString(fmt.Sprintf("ERROR: %s", err.Error())) + } } buildCommand := "make" @@ -75,7 +77,7 @@ func BuildModule(moduleInterface *C.char, recipeInterface *C.char) *C.char { intermediateSteps = " && " + strings.Join(module.IntermediateSteps, " && ") + " && " } - cmd := "cd /sources/" + api.GetSourcePath(module.Source, module.Name) + " && " + buildCommand + intermediateSteps + installCommand + cmd := "cd /sources/" + api.GetSourcePath(module.Sources[0], module.Name) + " && " + buildCommand + intermediateSteps + installCommand return C.CString(cmd) } diff --git a/plugins/meson.go b/plugins/meson.go index 617cfde..46238b0 100644 --- a/plugins/meson.go +++ b/plugins/meson.go @@ -8,13 +8,14 @@ import ( "github.com/vanilla-os/vib/api" ) +import "crypto/sha1" // Configuration for building a Meson project type MesonModule struct { Name string Type string - BuildFlags []string `json:"buildflags"` - Source api.Source + BuildFlags []string `json:"buildflags"` + Sources []api.Source `json"sources"` } // Provide plugin information as a JSON string @@ -47,21 +48,28 @@ func BuildModule(moduleInterface *C.char, recipeInterface *C.char) *C.char { return C.CString(fmt.Sprintf("ERROR: %s", err.Error())) } - err = api.DownloadSource(recipe, module.Source, module.Name) - if err != nil { - return C.CString(fmt.Sprintf("ERROR: %s", err.Error())) - } - err = api.MoveSource(recipe.DownloadsPath, recipe.SourcesPath, module.Source, module.Name) - if err != nil { - return C.CString(fmt.Sprintf("ERROR: %s", err.Error())) + for _, source := range module.Sources { + err = api.DownloadSource(recipe, source, module.Name) + if err != nil { + return C.CString(fmt.Sprintf("ERROR: %s", err.Error())) + } + err = api.MoveSource(recipe.DownloadsPath, recipe.SourcesPath, source, module.Name) + if err != nil { + return C.CString(fmt.Sprintf("ERROR: %s", err.Error())) + } } - // Since the downloaded source goes through checksum verification already - // it is safe to simply use the specified checksum from the module definition - tmpDir := fmt.Sprintf("/tmp/%s-%s", module.Source.Checksum, module.Name) + var tmpDir string + if strings.EqualFold(module.Sources[0].Type, "git") == true { + tmpDir = fmt.Sprintf("/tmp/%s-%s", module.Sources[0].Commit, module.Name) + } else if module.Sources[0].Type == "tar" || module.Sources[0].Type == "local" { + tmpDir = fmt.Sprintf("/tmp/%s-%s", module.Sources[0].Checksum, module.Name) + } else { + tmpDir = fmt.Sprintf("/tmp/%s-%s", sha1.Sum([]byte(module.Sources[0].URL)), module.Name) + } cmd := fmt.Sprintf( "cd /sources/%s && meson %s %s && ninja -C %s && ninja -C %s install", - api.GetSourcePath(module.Source, module.Name), + api.GetSourcePath(module.Sources[0], module.Name), strings.Join(module.BuildFlags, " "), tmpDir, tmpDir,