/
recipes.go
89 lines (70 loc) · 2.05 KB
/
recipes.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
package recipes
import (
"fmt"
"github.com/godarch/darch/pkg/utils"
)
// Recipe A struct representing a recipe to be built.
type Recipe struct {
Name string
RecipeDir string
RecipesDir string
Inherits string
InheritsExternal bool
}
func verifyDependencies(recipe Recipe, recipes map[string]Recipe, currentStack map[string]bool) error {
if currentStack == nil {
currentStack = make(map[string]bool, 0)
}
if recipe.InheritsExternal {
// we reached the end, all good!
return nil
}
if _, ok := currentStack[recipe.Inherits]; ok {
// Cyclical dependency detected!
return fmt.Errorf("Recipe %s has a cyclical dependency", recipe.Name)
}
// Make this image as having been traversed.
currentStack[recipe.Name] = true
if parent, ok := recipes[recipe.Inherits]; ok {
return verifyDependencies(parent, recipes, currentStack)
}
return fmt.Errorf("Recipe defintion %s inherits from %s, which doesn't exist", recipe.Name, recipe.Inherits)
}
// GetAllRecipes Return all the recipes in a recipe directory
func GetAllRecipes(recipesDir string) (map[string]Recipe, error) {
if len(recipesDir) == 0 {
return nil, fmt.Errorf("An image directory must be provided")
}
recipeNames, err := utils.GetChildDirectories(recipesDir)
if err != nil {
return nil, err
}
recipes := make(map[string]Recipe, 0)
for _, recipeName := range recipeNames {
recipe, err := parseRecipe(recipesDir, recipeName)
if err != nil {
return nil, err
}
recipes[recipeName] = recipe
}
// verify dependencies are satisfied and no circular dependencies
for _, recipe := range recipes {
err := verifyDependencies(recipe, recipes, nil)
if err != nil {
return nil, err
}
}
return recipes, nil
}
// GetRecipe Get a single recipe by name
func GetRecipe(recipesDir string, recipeName string) (Recipe, error) {
allRecipes, err := GetAllRecipes(recipesDir)
if err != nil {
return Recipe{}, err
}
current, ok := allRecipes[recipeName]
if !ok {
return Recipe{}, fmt.Errorf("recipe %s doesn't exist", recipeName)
}
return current, nil
}