From a383988bb9b677dc9e109adac0f16fbdd87afa5f Mon Sep 17 00:00:00 2001 From: axtloss Date: Fri, 15 Nov 2024 15:35:25 +0100 Subject: [PATCH] fix: Handle includes module type like regular module Instead of processing includes modules during the recipe parsing, process them like any other module. This allows users to use the includes module as a nested module of a different module. --- core/build.go | 52 +++++++++++++++++++++++++++++++++++++++++- core/loader.go | 62 -------------------------------------------------- 2 files changed, 51 insertions(+), 63 deletions(-) diff --git a/core/build.go b/core/build.go index 9ef577d..7b1ad2d 100644 --- a/core/build.go +++ b/core/build.go @@ -1,6 +1,7 @@ package core import ( + "errors" "fmt" "os" "path/filepath" @@ -321,6 +322,55 @@ func BuildModules(recipe *api.Recipe, modules []interface{}) ([]ModuleCommand, e return cmds, nil } +func buildIncludesModule(moduleInterface interface{}, recipe *api.Recipe) (string, error) { + var include IncludesModule + err := mapstructure.Decode(moduleInterface, &include) + if err != nil { + return "", err + } + + if len(include.Includes) == 0 { + return "", errors.New("includes module must have at least one module to include") + } + + var commands []string + for _, include := range include.Includes { + var modulePath string + + // in case of a remote include, we need to download the + // recipe before including it + if include[:4] == "http" { + fmt.Printf("Downloading recipe from %s\n", include) + modulePath, err = downloadRecipe(include) + if err != nil { + return "", err + } + } else if followsGhPattern(include) { + // if the include follows the github pattern, we need to + // download the recipe from the github repository + fmt.Printf("Downloading recipe from %s\n", include) + modulePath, err = downloadGhRecipe(include) + if err != nil { + return "", err + } + } else { + modulePath = filepath.Join(recipe.ParentPath, include) + } + + includeModule, err := GenModule(modulePath) + if err != nil { + return "", err + } + + buildModule, err := BuildModule(recipe, includeModule) + if err != nil { + return "", err + } + commands = append(commands, buildModule...) + } + return strings.Join(commands, "\n"), nil +} + // Build a command string for the given module in the recipe func BuildModule(recipe *api.Recipe, moduleInterface interface{}) ([]string, error) { var module Module @@ -345,7 +395,7 @@ func BuildModule(recipe *api.Recipe, moduleInterface interface{}) ([]string, err moduleBuilders := map[string]func(interface{}, *api.Recipe) (string, error){ "shell": BuildShellModule, - "includes": func(interface{}, *api.Recipe) (string, error) { return "", nil }, + "includes": buildIncludesModule, } if moduleBuilder, ok := moduleBuilders[module.Type]; ok { diff --git a/core/loader.go b/core/loader.go index d9e5528..dd6e464 100644 --- a/core/loader.go +++ b/core/loader.go @@ -1,7 +1,6 @@ package core import ( - "errors" "fmt" "io" "net/http" @@ -9,7 +8,6 @@ import ( "path/filepath" "strings" - "github.com/mitchellh/mapstructure" "github.com/vanilla-os/vib/api" "gopkg.in/yaml.v3" ) @@ -120,66 +118,6 @@ func LoadRecipe(path string) (*api.Recipe, error) { } } - // here we expand modules of type "includes" - var newRecipeModules []interface{} - - for _, moduleInterface := range stage.Modules { - - var module Module - err := mapstructure.Decode(moduleInterface, &module) - if err != nil { - return nil, err - } - - if module.Type == "includes" { - var include IncludesModule - err := mapstructure.Decode(moduleInterface, &include) - if err != nil { - return nil, err - } - - if len(include.Includes) == 0 { - return nil, errors.New("includes module must have at least one module to include") - } - - for _, include := range include.Includes { - var modulePath string - - // in case of a remote include, we need to download the - // recipe before including it - if include[:4] == "http" { - fmt.Printf("Downloading recipe from %s\n", include) - modulePath, err = downloadRecipe(include) - if err != nil { - return nil, err - } - } else if followsGhPattern(include) { - // if the include follows the github pattern, we need to - // download the recipe from the github repository - fmt.Printf("Downloading recipe from %s\n", include) - modulePath, err = downloadGhRecipe(include) - if err != nil { - return nil, err - } - } else { - modulePath = filepath.Join(recipe.ParentPath, include) - } - - includeModule, err := GenModule(modulePath) - if err != nil { - return nil, err - } - - newRecipeModules = append(newRecipeModules, includeModule) - } - - continue - } - - newRecipeModules = append(newRecipeModules, moduleInterface) - } - - stage.Modules = newRecipeModules recipe.Stages[i] = stage }