Skip to content

Commit f232f0e

Browse files
committed
test: make sure paths are saved to recipe with slashes
1 parent 4e8e035 commit f232f0e

10 files changed

+86
-68
lines changed

internal/cli/create_recipe.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,11 @@ my-recipe
3838
└── README.md
3939
%[1]s`,
4040
"```",
41-
recipe.RecipeFileName+recipe.YAMLExtension,
42-
recipe.RecipeTemplatesDirName,
43-
recipe.RecipeTestsDirName,
44-
recipe.RecipeTestMetaFileName+recipe.YAMLExtension,
45-
recipe.RecipeTestFilesDirName,
41+
recipe.MetadataFileName+recipe.YAMLExtension,
42+
recipe.TemplatesDirName,
43+
recipe.TestsDirName,
44+
recipe.TestMetaFileName+recipe.YAMLExtension,
45+
recipe.TestFilesDirName,
4646
),
4747
Example: `jalapeno create recipe my-recipe`,
4848
Args: cobra.ExactArgs(1),

pkg/recipe/loader.go

+13-13
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,14 @@ import (
1414
)
1515

1616
const (
17-
YAMLExtension = ".yml"
18-
RecipeFileName = "recipe"
19-
RecipeTemplatesDirName = "templates"
20-
RecipeTestsDirName = "tests"
21-
RecipeTestMetaFileName = "test"
22-
RecipeTestFilesDirName = "files"
23-
IgnoreFileName = ".jalapenoignore"
24-
ManifestFileName = "manifest"
17+
YAMLExtension = ".yml"
18+
MetadataFileName = "recipe"
19+
TemplatesDirName = "templates"
20+
TestsDirName = "tests"
21+
TestMetaFileName = "test"
22+
TestFilesDirName = "files"
23+
IgnoreFileName = ".jalapenoignore"
24+
ManifestFileName = "manifest"
2525
)
2626

2727
var (
@@ -36,7 +36,7 @@ func LoadRecipe(path string) (*Recipe, error) {
3636
return nil, err
3737
}
3838

39-
recipeFile := filepath.Join(rootDir, RecipeFileName+YAMLExtension)
39+
recipeFile := filepath.Join(rootDir, MetadataFileName+YAMLExtension)
4040
dat, err := os.ReadFile(recipeFile)
4141
if err != nil {
4242
return nil, err
@@ -48,12 +48,12 @@ func LoadRecipe(path string) (*Recipe, error) {
4848
return nil, err
4949
}
5050

51-
recipe.Templates, err = loadTemplates(filepath.Join(rootDir, RecipeTemplatesDirName))
51+
recipe.Templates, err = loadTemplates(filepath.Join(rootDir, TemplatesDirName))
5252
if err != nil {
5353
return nil, fmt.Errorf("error when loading recipe templates: %w", err)
5454
}
5555

56-
recipe.Tests, err = loadTests(filepath.Join(rootDir, RecipeTestsDirName))
56+
recipe.Tests, err = loadTests(filepath.Join(rootDir, TestsDirName))
5757
if err != nil {
5858
return nil, fmt.Errorf("error when loading recipe tests: %w", err)
5959
}
@@ -117,7 +117,7 @@ func loadTests(path string) ([]Test, error) {
117117

118118
test := Test{}
119119
testDirPath := filepath.Join(path, dir.Name())
120-
contents, err := os.ReadFile(filepath.Join(testDirPath, RecipeTestMetaFileName+YAMLExtension))
120+
contents, err := os.ReadFile(filepath.Join(testDirPath, TestMetaFileName+YAMLExtension))
121121
if err != nil {
122122
return nil, err
123123
}
@@ -129,7 +129,7 @@ func loadTests(path string) ([]Test, error) {
129129

130130
test.Name = dir.Name()
131131
test.Files = make(map[string]File)
132-
testFileDirPath := filepath.Join(testDirPath, RecipeTestFilesDirName)
132+
testFileDirPath := filepath.Join(testDirPath, TestFilesDirName)
133133

134134
walk := func(path string, info os.FileInfo, err error) error {
135135
if err != nil {

pkg/recipe/loader_test.go

+7-7
Original file line numberDiff line numberDiff line change
@@ -139,12 +139,12 @@ func TestLoadTests(t *testing.T) {
139139
}
140140
defer os.RemoveAll(dir)
141141

142-
if err = os.MkdirAll(filepath.Join(dir, RecipeTemplatesDirName), 0755); err != nil {
142+
if err = os.MkdirAll(filepath.Join(dir, TemplatesDirName), 0755); err != nil {
143143
t.Fatalf("cannot create templates dir: %s", err)
144144
}
145145

146146
contents := "# file"
147-
if err = os.WriteFile(filepath.Join(dir, RecipeTemplatesDirName, "file.md"), []byte(contents), 0644); err != nil {
147+
if err = os.WriteFile(filepath.Join(dir, TemplatesDirName, "file.md"), []byte(contents), 0644); err != nil {
148148
t.Fatalf("cannot write rendered template: %s", err)
149149
}
150150

@@ -154,24 +154,24 @@ version: v1.0.0
154154
description: foo recipe
155155
`
156156

157-
if err = os.WriteFile(filepath.Join(dir, RecipeFileName+YAMLExtension), []byte(recipe), 0644); err != nil {
157+
if err = os.WriteFile(filepath.Join(dir, MetadataFileName+YAMLExtension), []byte(recipe), 0644); err != nil {
158158
t.Fatal("cannot write recipe file", err)
159159
}
160160

161161
testMetaFile := "values: {}"
162-
if err = os.MkdirAll(filepath.Join(dir, RecipeTestsDirName, "test_foo"), 0755); err != nil {
162+
if err = os.MkdirAll(filepath.Join(dir, TestsDirName, "test_foo"), 0755); err != nil {
163163
t.Fatalf("cannot create test dir: %s", err)
164164
}
165165

166-
if err = os.WriteFile(filepath.Join(dir, RecipeTestsDirName, "test_foo", RecipeTestMetaFileName+YAMLExtension), []byte(testMetaFile), 0644); err != nil {
166+
if err = os.WriteFile(filepath.Join(dir, TestsDirName, "test_foo", TestMetaFileName+YAMLExtension), []byte(testMetaFile), 0644); err != nil {
167167
t.Fatalf("cannot write recipe test file: %s", err)
168168
}
169169

170-
if err = os.MkdirAll(filepath.Join(dir, RecipeTestsDirName, "test_foo", RecipeTestFilesDirName), 0755); err != nil {
170+
if err = os.MkdirAll(filepath.Join(dir, TestsDirName, "test_foo", TestFilesDirName), 0755); err != nil {
171171
t.Fatalf("cannot create test file dir: %s", err)
172172
}
173173

174-
if err = os.WriteFile(filepath.Join(dir, RecipeTestsDirName, "test_foo", RecipeTestFilesDirName, "file.md"), []byte(contents), 0644); err != nil {
174+
if err = os.WriteFile(filepath.Join(dir, TestsDirName, "test_foo", TestFilesDirName, "file.md"), []byte(contents), 0644); err != nil {
175175
t.Fatalf("cannot create test file dir: %s", err)
176176
}
177177

pkg/recipe/saver.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ func (re *Recipe) Save(dest string) error {
4343
return fmt.Errorf("can not create directory %s: %v", dest, err)
4444
}
4545

46-
recipeFilepath := filepath.Join(dest, RecipeFileName+YAMLExtension)
46+
recipeFilepath := filepath.Join(dest, MetadataFileName+YAMLExtension)
4747
file, err := os.Create(recipeFilepath)
4848
if err != nil {
4949
return fmt.Errorf("failed to create recipe file: %w", err)
@@ -80,7 +80,7 @@ func (re *Recipe) saveTests(dest string) error {
8080
return nil
8181
}
8282

83-
testRootDir := filepath.Join(dest, RecipeTestsDirName)
83+
testRootDir := filepath.Join(dest, TestsDirName)
8484

8585
err := os.MkdirAll(testRootDir, defaultFileMode)
8686
if err != nil {
@@ -94,7 +94,7 @@ func (re *Recipe) saveTests(dest string) error {
9494
return fmt.Errorf("failed to create test directory for test '%s': %w", test.Name, err)
9595
}
9696

97-
meta, err := os.Create(filepath.Join(testDirPath, RecipeTestMetaFileName+YAMLExtension))
97+
meta, err := os.Create(filepath.Join(testDirPath, TestMetaFileName+YAMLExtension))
9898
if err != nil {
9999
return fmt.Errorf("failed to create recipe test file: %w", err)
100100
}
@@ -108,7 +108,7 @@ func (re *Recipe) saveTests(dest string) error {
108108
return fmt.Errorf("failed to write recipe test to a file: %w", err)
109109
}
110110

111-
testFileDirPath := filepath.Join(testDirPath, RecipeTestFilesDirName)
111+
testFileDirPath := filepath.Join(testDirPath, TestFilesDirName)
112112
err = os.RemoveAll(testFileDirPath)
113113
if err != nil {
114114
return fmt.Errorf("failed to clean up test file directory for test '%s': %w", test.Name, err)
@@ -131,7 +131,7 @@ func (re *Recipe) saveTests(dest string) error {
131131
}
132132

133133
func (re *Recipe) saveTemplates(dest string) error {
134-
templateDir := filepath.Join(dest, RecipeTemplatesDirName)
134+
templateDir := filepath.Join(dest, TemplatesDirName)
135135
err := os.MkdirAll(templateDir, defaultFileMode)
136136
if err != nil {
137137
return fmt.Errorf("can not save templates to the directory: %w", err)

pkg/recipe/saver_test.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,14 @@ func TestSaveRecipe(t *testing.T) {
4747
}
4848

4949
expectedFiles := []string{
50-
filepath.Join(RecipeFileName + YAMLExtension),
50+
filepath.Join(MetadataFileName + YAMLExtension),
5151
filepath.Join("templates", "foo.md"),
5252
filepath.Join("templates", "foo", "bar.md"),
5353
filepath.Join("templates", "foo", "bar", "baz.md"),
54-
filepath.Join("tests", re.Tests[0].Name, RecipeTestMetaFileName+YAMLExtension),
55-
filepath.Join("tests", re.Tests[0].Name, RecipeTestFilesDirName, "foo.md"),
56-
filepath.Join("tests", re.Tests[0].Name, RecipeTestFilesDirName, "foo", "bar.md"),
57-
filepath.Join("tests", re.Tests[0].Name, RecipeTestFilesDirName, "foo", "bar", "baz.md"),
54+
filepath.Join("tests", re.Tests[0].Name, TestMetaFileName+YAMLExtension),
55+
filepath.Join("tests", re.Tests[0].Name, TestFilesDirName, "foo.md"),
56+
filepath.Join("tests", re.Tests[0].Name, TestFilesDirName, "foo", "bar.md"),
57+
filepath.Join("tests", re.Tests[0].Name, TestFilesDirName, "foo", "bar", "baz.md"),
5858
}
5959

6060
checkFiles(t, dir, expectedFiles)

test/features/check-recipes.feature

+1-1
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ Feature: Check for new recipe versions
125125
And the recipe "foo" is pushed to the local OCI repository "foo:v0.0.2"
126126
And I check new versions for recipe "foo" from the local OCI repository "foo"
127127
Then CLI produced an output "new versions found: v0\.0\.2"
128-
And the sauce in index 0 which should have property "CheckFrom" with value "^oci://localhost:\d+/foo$"
128+
And the sauce in index 0 should have property "CheckFrom" with value "^oci://localhost:\d+/foo$"
129129

130130
@docker
131131
Scenario: Find and upgrade newer version for recipes

test/features/execute-recipes.feature

+26-18
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,16 @@ Feature: Execute recipes
77
When I execute recipe "foo"
88
Then execution of the recipe has succeeded
99
And the project directory should contain file "README.md"
10-
And the sauce in index 0 which should have property "Recipe.Name" with value "^foo$"
11-
And the sauce in index 0 which has a valid ID
10+
And the sauce in index 0 should have property "Recipe::Name" with value "^foo$"
11+
And the sauce in index 0 has a valid ID
12+
13+
Scenario: Execute single recipe with directory hierarcy
14+
Given a recipe "foo"
15+
And recipe "foo" generates file "foo/bar.md" with content "initial"
16+
When I execute recipe "foo"
17+
Then execution of the recipe has succeeded
18+
And the project directory should contain file "foo/bar.md"
19+
And the sauce in index 0 should have property "Files::foo/bar.md"
1220

1321
@docker
1422
Scenario: Execute single recipe from remote registry
@@ -20,7 +28,7 @@ Feature: Execute recipes
2028
Then execution of the recipe has succeeded
2129
And no errors were printed
2230
And the project directory should contain file "README.md"
23-
And the sauce in index 0 which should have property "CheckFrom" with value "^oci://.+/foo$"
31+
And the sauce in index 0 should have property "CheckFrom" with value "^oci://.+/foo$"
2432

2533
Scenario: Execute multiple recipes
2634
Given a recipe "foo"
@@ -34,8 +42,8 @@ Feature: Execute recipes
3442
And no errors were printed
3543
And the project directory should contain file "README.md"
3644
And the project directory should contain file "Taskfile.yml"
37-
And the sauce in index 0 which should have property "Recipe.Name" with value "^foo$"
38-
And the sauce in index 1 which should have property "Recipe.Name" with value "^bar$"
45+
And the sauce in index 0 should have property "Recipe::Name" with value "^foo$"
46+
And the sauce in index 1 should have property "Recipe::Name" with value "^bar$"
3947

4048
Scenario: New recipe conflicts with the previous recipe
4149
Given a recipe "foo"
@@ -55,19 +63,19 @@ Feature: Execute recipes
5563

5664
Scenario: Execute single recipe to a subpath
5765
Given a recipe "foo"
58-
And recipe "foo" generates file "README" with content "initial"
59-
And recipes will be executed to the subpath "docs"
66+
And recipe "foo" generates file "README.md" with content "initial"
67+
And recipes will be executed to the subpath "docs/pages"
6068
When I execute recipe "foo"
6169
And no errors were printed
6270
Then execution of the recipe has succeeded
63-
And CLI produced an output "docs[\S\s]+└── README"
64-
And the project directory should contain file "docs/README"
65-
And the sauce in index 0 which should have property "Files.README"
66-
And the sauce in index 0 which should have property "SubPath" with value "^docs$"
71+
And CLI produced an output "docs[\S\s]+└── pages[\S\s]+└── README\.md"
72+
And the project directory should contain file "docs/pages/README.md"
73+
And the sauce in index 0 should have property "Files::README.md"
74+
And the sauce in index 0 should have property "SubPath" with value "^docs/pages$"
6775

6876
Scenario: Execute multiple recipes to different subpaths
6977
Given a recipe "foo"
70-
And recipe "foo" generates file "README" with content "initial"
78+
And recipe "foo" generates file "README.md" with content "initial"
7179
And recipes will be executed to the subpath "foo"
7280
When I execute recipe "foo"
7381
Then no errors were printed
@@ -76,12 +84,12 @@ Feature: Execute recipes
7684
And I execute recipe "foo"
7785
Then no errors were printed
7886
And execution of the recipe has succeeded
79-
And the project directory should contain file "foo/README"
80-
And the project directory should contain file "bar/README"
81-
And the sauce in index 0 which should have property "Files.README"
82-
And the sauce in index 0 which should have property "SubPath" with value "^foo$"
83-
And the sauce in index 1 which should have property "Files.README"
84-
And the sauce in index 1 which should have property "SubPath" with value "^bar$"
87+
And the project directory should contain file "foo/README.md"
88+
And the project directory should contain file "bar/README.md"
89+
And the sauce in index 0 should have property "Files::README.md"
90+
And the sauce in index 0 should have property "SubPath" with value "^foo$"
91+
And the sauce in index 1 should have property "Files::README.md"
92+
And the sauce in index 1 should have property "SubPath" with value "^bar$"
8593

8694
Scenario: Try to execute recipe which escapes the project root
8795
Given a recipe "foo"

test/features/jalapenoignore.feature

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,4 @@ Feature: Jalapenoignore
4040
Then no conflicts were reported
4141
And no errors were printed
4242
And the project directory should contain file "will-be-removed-in-next-version" with "modified"
43-
And the sauce in index 0 which should not have property "Files.will-be-removed-in-next-version"
43+
And the sauce in index 0 should not have property "Files::will-be-removed-in-next-version"

test/features/upgrade-recipe.feature

+4-4
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,12 @@ Feature: Upgrade sauce
6161
And recipes will be executed to the subpath "foo"
6262
And I execute recipe "shared"
6363
Then execution of the recipe has succeeded
64-
And the sauce in index 0 which should have property "SubPath" with value "^foo$"
64+
And the sauce in index 0 should have property "SubPath" with value "^foo$"
6565
And the project directory should contain file "./foo/README.md"
6666
When recipes will be executed to the subpath "bar"
6767
And I execute recipe "shared"
6868
Then execution of the recipe has succeeded
69-
And the sauce in index 1 which should have property "SubPath" with value "^bar$"
69+
And the sauce in index 1 should have property "SubPath" with value "^bar$"
7070
And the project directory should contain file "./bar/README.md"
7171
When I change recipe "shared" to version "v0.0.2"
7272
And I change recipe "shared" template "README.md" to render "New version"
@@ -79,12 +79,12 @@ Feature: Upgrade sauce
7979
And recipes will be executed to the subpath "foo"
8080
And I execute recipe "shared"
8181
Then execution of the recipe has succeeded
82-
And the sauce in index 0 which should have property "SubPath" with value "^foo$"
82+
And the sauce in index 0 should have property "SubPath" with value "^foo$"
8383
And the project directory should contain file "./foo/README.md"
8484
When recipes will be executed to the subpath "bar"
8585
And I execute recipe "shared"
8686
Then execution of the recipe has succeeded
87-
And the sauce in index 1 which should have property "SubPath" with value "^bar$"
87+
And the sauce in index 1 should have property "SubPath" with value "^bar$"
8888
And the project directory should contain file "./bar/README.md"
8989
When I change recipe "shared" to version "v0.0.2"
9090
And I change recipe "shared" template "README.md" to render "New version"

test/main_test.go

+19-9
Original file line numberDiff line numberDiff line change
@@ -158,10 +158,10 @@ func AddCommonSteps(s *godog.ScenarioContext) {
158158
s.Step(`^no errors were printed$`, noErrorsWerePrinted)
159159
s.Step(`^CLI produced an output "([^"]*)"$`, expectGivenOutput)
160160
s.Step(`^CLI produced an error "(.*)"$`, expectGivenError)
161-
s.Step(`^the sauce in index (\d) which should have property "([^"]*)"$`, theSauceShouldHaveProperty)
162-
s.Step(`^the sauce in index (\d) which should not have property "([^"]*)"$`, theSauceFileShouldNotHaveProperty)
163-
s.Step(`^the sauce in index (\d) which should have property "([^"]*)" with value "([^"]*)"$`, theSauceFileShouldHavePropertyWithValue)
164-
s.Step(`^the sauce in index (\d) which has a valid ID$`, theSauceFileShouldHasAValidID)
161+
s.Step(`^the sauce in index (\d) should have property "([^"]*)"$`, theSauceShouldHaveProperty)
162+
s.Step(`^the sauce in index (\d) should not have property "([^"]*)"$`, theSauceFileShouldNotHaveProperty)
163+
s.Step(`^the sauce in index (\d) should have property "([^"]*)" with value "([^"]*)"$`, theSauceFileShouldHavePropertyWithValue)
164+
s.Step(`^the sauce in index (\d) has a valid ID$`, theSauceFileShouldHasAValidID)
165165
s.Step(`^the project directory should contain file "([^"]*)"$`, theProjectDirectoryShouldContainFile)
166166
s.Step(`^the project directory should contain file "([^"]*)" with "([^"]*)"$`, theProjectDirectoryShouldContainFileWith)
167167
s.Step(`^the project directory should not contain file "([^"]*)"$`, theProjectDirectoryShouldNotContainFile)
@@ -318,14 +318,24 @@ func aRecipe(ctx context.Context, recipeName string) (context.Context, error) {
318318

319319
func recipeGeneratesFileWithContent(ctx context.Context, recipeName, filename, content string) (context.Context, error) {
320320
dir := ctx.Value(recipesDirectoryPathCtxKey{}).(string)
321-
re, err := recipe.LoadRecipe(filepath.Join(dir, recipeName))
321+
322+
recipePath := filepath.Join(dir, recipeName)
323+
filePath := filepath.Join(recipePath, recipe.TemplatesDirName, filename)
324+
325+
err := os.MkdirAll(filepath.Dir(filePath), 0700)
326+
if err != nil {
327+
return ctx, err
328+
}
329+
330+
file, err := os.Create(filepath.Join(recipePath, recipe.TemplatesDirName, filename))
322331
if err != nil {
323332
return ctx, err
324333
}
325334

326-
re.Templates[filename] = recipe.NewFile([]byte(content))
335+
defer file.Close()
327336

328-
if err := re.Save(filepath.Join(dir, recipeName)); err != nil {
337+
_, err = file.WriteString(content)
338+
if err != nil {
329339
return ctx, err
330340
}
331341

@@ -335,7 +345,7 @@ func recipeGeneratesFileWithContent(ctx context.Context, recipeName, filename, c
335345
func iRemoveFileFromTheRecipe(ctx context.Context, filename, recipeName string) (context.Context, error) {
336346
recipesDir := ctx.Value(recipesDirectoryPathCtxKey{}).(string)
337347

338-
templateDir := filepath.Join(recipesDir, recipeName, recipe.RecipeTemplatesDirName)
348+
templateDir := filepath.Join(recipesDir, recipeName, recipe.TemplatesDirName)
339349

340350
err := os.Remove(filepath.Join(templateDir, filename))
341351
return ctx, err
@@ -757,7 +767,7 @@ func addRegistryRelatedFlags(ctx context.Context) context.Context {
757767

758768
func getDeepPropertyFromStruct(v any, key string) reflect.Value {
759769
r := reflect.ValueOf(v)
760-
for _, k := range strings.Split(key, ".") {
770+
for _, k := range strings.Split(key, "::") {
761771
switch reflect.Indirect(r).Kind() {
762772
case reflect.Struct:
763773
r = reflect.Indirect(r).FieldByName(k)

0 commit comments

Comments
 (0)