diff --git a/pkg/cnb/project_descriptor.go b/pkg/cnb/project_descriptor.go index 69616a004..e0d357c64 100644 --- a/pkg/cnb/project_descriptor.go +++ b/pkg/cnb/project_descriptor.go @@ -13,10 +13,6 @@ import ( const defaultProjectDescriptorPath = "project.toml" func ProcessProjectDescriptor(appDir, descriptorPath, platformDir string, logger *log.Logger) error { - var ( - d descriptor - ) - file := filepath.Join(appDir, defaultProjectDescriptorPath) if descriptorPath != "" { file = filepath.Join(appDir, descriptorPath) @@ -31,24 +27,56 @@ func ProcessProjectDescriptor(appDir, descriptorPath, platformDir string, logger return fmt.Errorf("unable to determine if project descriptor file exists: %w", err) } - _, err := toml.DecodeFile(file, &d) + d, err := parseProjectDescriptor(file, logger) if err != nil { return err } - if d.Build.Buildpacks != nil { + if d.IO.Buildpacks.Group != nil { logger.Println("info: buildpacks provided in project descriptor file will be ignored") } - if d.Build.Builder != "" { + if d.IO.Buildpacks.Builder != "" { logger.Println("info: builder provided in project descriptor file will be ignored") } - if err := processFiles(appDir, d); err != nil { + if err := processFiles(appDir, d.IO.Buildpacks.build); err != nil { return err } - return serializeEnvVars(d.Build.Env, platformDir) + return serializeEnvVars(d.IO.Buildpacks.Env, platformDir) } -func processFiles(appDir string, d descriptor) error { +func parseProjectDescriptor(file string, logger *log.Logger) (descriptorV2, error) { + var d descriptorV2 + if _, err := toml.DecodeFile(file, &d); err != nil { + return descriptorV2{}, err + } + + switch sv := d.Project.SchemaVersion; sv { + case "0.2": + return d, nil + case "": // v1 descriptor + var dV1 descriptorV1 + if _, err := toml.DecodeFile(file, &dV1); err != nil { + return descriptorV2{}, err + } + return v1ToV2(dV1), nil + default: + logger.Println(fmt.Sprintf("warning: project descriptor version %s is unsupported and %s will be ignored", sv, file)) + return descriptorV2{}, nil + } +} + +func v1ToV2(v1 descriptorV1) descriptorV2 { + return descriptorV2{ + IO: ioTable{ + Buildpacks: cnbTableV2{ + build: v1.Build.build, + Group: v1.Build.Buildpacks, + }, + }, + } +} + +func processFiles(appDir string, d build) error { fileFilter, err := getFileFilter(d) if err != nil { return err @@ -77,39 +105,61 @@ func processFiles(appDir string, d descriptor) error { }) } -func getFileFilter(d descriptor) (func(string) bool, error) { - if d.Build.Exclude != nil && d.Build.Include != nil { - return nil, fmt.Errorf("%s: cannot have both include and exclude defined", defaultProjectDescriptorPath) +func getFileFilter(d build) (func(string) bool, error) { + if d.Exclude != nil && d.Include != nil { + return nil, fmt.Errorf("project descriptor cannot have both include and exclude defined") } - if len(d.Build.Exclude) > 0 { - excludes := ignore.CompileIgnoreLines(d.Build.Exclude...) + if len(d.Exclude) > 0 { + excludes := ignore.CompileIgnoreLines(d.Exclude...) return func(fileName string) bool { return !excludes.MatchesPath(fileName) }, nil } - if len(d.Build.Include) > 0 { - includes := ignore.CompileIgnoreLines(d.Build.Include...) + if len(d.Include) > 0 { + includes := ignore.CompileIgnoreLines(d.Include...) return includes.MatchesPath, nil } return nil, nil } +type descriptorV2 struct { + Project project `toml:"_"` + IO ioTable `toml:"io"` +} + +type project struct { + SchemaVersion string `toml:"schema-version"` +} + +type ioTable struct { + Buildpacks cnbTableV2 `toml:"buildpacks"` +} + +type cnbTableV2 struct { + build `toml:",inline"` + Group []buildpack `toml:"group"` +} + +type build struct { + Include []string `toml:"include"` + Exclude []string `toml:"exclude"` + Builder string `toml:"builder"` + Env []envVariable `toml:"env"` +} + type buildpack struct { Id string `json:"id" toml:"id"` Version string `json:"version" toml:"version"` Uri string `json:"uri" toml:"uri"` } -type build struct { - Include []string `toml:"include"` - Exclude []string `toml:"exclude"` - Buildpacks []buildpack `toml:"buildpacks"` - Builder string `toml:"builder"` - Env []envVariable `toml:"env"` +type descriptorV1 struct { + Build cnbTableV1 `toml:"build"` } -type descriptor struct { - Build build `toml:"build"` +type cnbTableV1 struct { + build `toml:",inline"` + Buildpacks []buildpack `toml:"buildpacks"` } diff --git a/pkg/cnb/project_descriptor_test.go b/pkg/cnb/project_descriptor_test.go index 7d544d56a..fd92c4fef 100644 --- a/pkg/cnb/project_descriptor_test.go +++ b/pkg/cnb/project_descriptor_test.go @@ -2,6 +2,7 @@ package cnb_test import ( "bytes" + "fmt" "io/ioutil" "log" "os" @@ -23,7 +24,7 @@ func testProcessProjectDescriptor(t *testing.T, when spec.G, it spec.S) { var buf *bytes.Buffer var logger *log.Logger var ( - appDir, platformDir, descriptorPath, projectToml string + appDir, descriptorPath, platformDir, projectToml string ) it.Before(func() { @@ -34,6 +35,7 @@ func testProcessProjectDescriptor(t *testing.T, when spec.G, it spec.S) { require.NoError(t, err) platformDir, err = ioutil.TempDir("", "platform") require.NoError(t, err) + projectToml = filepath.Join(appDir, "project.toml") }) it.After(func() { @@ -41,174 +43,358 @@ func testProcessProjectDescriptor(t *testing.T, when spec.G, it spec.S) { os.RemoveAll(platformDir) }) + when("unsupported project descriptor version", func() { + it.Before(func() { + ioutil.WriteFile(projectToml, []byte(` +[_] +schema-version = "0.99" + `), 0644) + }) + it("logs a warning the project descriptor will be ignored", func() { + assert.Nil(t, cnb.ProcessProjectDescriptor(appDir, descriptorPath, platformDir, logger)) + assert.Equal(t, fmt.Sprintf("warning: project descriptor version 0.99 is unsupported and %s will be ignored\n", projectToml), buf.String()) + }) + }) + when("#ProcessProjectDescriptor", func() { - when("the descriptor path is not set", func() { - it.Before(func() { - projectToml = filepath.Join(appDir, "project.toml") - descriptorPath = "" - }) + when("the descriptor path is unset", func() { + descriptorPath = "" - when("the descriptor has build env vars", func() { - it.Before(func() { - ioutil.WriteFile(projectToml, []byte(` + when("using descriptor v1", func() { + when("the descriptor has build env vars", func() { + it.Before(func() { + ioutil.WriteFile(projectToml, []byte(` [[build.env]] name = "keyA" value = "valueA" - [[build.env]] name = "keyB" value = "valueB" - [[build.env]] name = "keyC" value = "valueC" - # check that later keys override previous ones [[build.env]] name = "keyC" value = "valueAnotherC" - `), 0644) - }) - it("writes all env var files to the platform dir", func() { - assert.Nil(t, cnb.ProcessProjectDescriptor(appDir, descriptorPath, platformDir, logger)) - checkEnvVar(t, platformDir, "keyA", "valueA") - checkEnvVar(t, platformDir, "keyB", "valueB") - checkEnvVar(t, platformDir, "keyC", "valueAnotherC") - }) - }) - - when("the descriptor has includes and excludes", func() { - it.Before(func() { - var err error - // Create test directories and files: - // - // ├── cookie.jar - // ├── other-cookie.jar - // ├── nested-cookie.jar - // ├── nested - // │ └── nested-cookie.jar - // ├── secrets - // │ ├── api_keys.json - // | |── user_token - // ├── media - // │ ├── mountain.jpg - // │ └── person.png - // └── test.sh - - err = os.Mkdir(filepath.Join(appDir, "secrets"), 0755) - assert.Nil(t, err) - err = ioutil.WriteFile(filepath.Join(appDir, "secrets", "api_keys.json"), []byte("{}"), 0755) - assert.Nil(t, err) - err = ioutil.WriteFile(filepath.Join(appDir, "secrets", "user_token"), []byte("token"), 0755) - assert.Nil(t, err) - - err = os.Mkdir(filepath.Join(appDir, "nested"), 0755) - assert.Nil(t, err) - err = ioutil.WriteFile(filepath.Join(appDir, "nested", "nested-cookie.jar"), []byte("chocolate chip"), 0755) - assert.Nil(t, err) - - err = ioutil.WriteFile(filepath.Join(appDir, "other-cookie.jar"), []byte("chocolate chip"), 0755) - assert.Nil(t, err) - - err = ioutil.WriteFile(filepath.Join(appDir, "nested-cookie.jar"), []byte("chocolate chip"), 0755) - assert.Nil(t, err) - - err = os.Mkdir(filepath.Join(appDir, "media"), 0755) - assert.Nil(t, err) - err = ioutil.WriteFile(filepath.Join(appDir, "media", "mountain.jpg"), []byte("fake image bytes"), 0755) - assert.Nil(t, err) - err = ioutil.WriteFile(filepath.Join(appDir, "media", "person.png"), []byte("fake image bytes"), 0755) - assert.Nil(t, err) - - err = ioutil.WriteFile(filepath.Join(appDir, "cookie.jar"), []byte("chocolate chip"), 0755) - assert.Nil(t, err) - err = ioutil.WriteFile(filepath.Join(appDir, "test.sh"), []byte("echo test"), 0755) - assert.Nil(t, err) + }) + it("writes all env var files to the platform dir", func() { + assert.Nil(t, cnb.ProcessProjectDescriptor(appDir, descriptorPath, platformDir, logger)) + checkEnvVar(t, platformDir, "keyA", "valueA") + checkEnvVar(t, platformDir, "keyB", "valueB") + checkEnvVar(t, platformDir, "keyC", "valueAnotherC") + }) }) - when("it has excludes", func() { + when("the descriptor has includes and excludes", func() { it.Before(func() { - ioutil.WriteFile(projectToml, []byte(` + var err error + // Create test directories and files: + // + // ├── cookie.jar + // ├── other-cookie.jar + // ├── nested-cookie.jar + // ├── nested + // │ └── nested-cookie.jar + // ├── secrets + // │ ├── api_keys.json + // | |── user_token + // ├── media + // │ ├── mountain.jpg + // │ └── person.png + // └── test.sh + + err = os.Mkdir(filepath.Join(appDir, "secrets"), 0755) + assert.Nil(t, err) + err = ioutil.WriteFile(filepath.Join(appDir, "secrets", "api_keys.json"), []byte("{}"), 0755) + assert.Nil(t, err) + err = ioutil.WriteFile(filepath.Join(appDir, "secrets", "user_token"), []byte("token"), 0755) + assert.Nil(t, err) + + err = os.Mkdir(filepath.Join(appDir, "nested"), 0755) + assert.Nil(t, err) + err = ioutil.WriteFile(filepath.Join(appDir, "nested", "nested-cookie.jar"), []byte("chocolate chip"), 0755) + assert.Nil(t, err) + + err = ioutil.WriteFile(filepath.Join(appDir, "other-cookie.jar"), []byte("chocolate chip"), 0755) + assert.Nil(t, err) + + err = ioutil.WriteFile(filepath.Join(appDir, "nested-cookie.jar"), []byte("chocolate chip"), 0755) + assert.Nil(t, err) + + err = os.Mkdir(filepath.Join(appDir, "media"), 0755) + assert.Nil(t, err) + err = ioutil.WriteFile(filepath.Join(appDir, "media", "mountain.jpg"), []byte("fake image bytes"), 0755) + assert.Nil(t, err) + err = ioutil.WriteFile(filepath.Join(appDir, "media", "person.png"), []byte("fake image bytes"), 0755) + assert.Nil(t, err) + + err = ioutil.WriteFile(filepath.Join(appDir, "cookie.jar"), []byte("chocolate chip"), 0755) + assert.Nil(t, err) + err = ioutil.WriteFile(filepath.Join(appDir, "test.sh"), []byte("echo test"), 0755) + assert.Nil(t, err) + }) + + when("it has excludes", func() { + it.Before(func() { + ioutil.WriteFile(projectToml, []byte(` [build] exclude = ["*.sh", "secrets/", "media/metadata", "/other-cookie.jar" ,"/nested-cookie.jar"] `), 0644) + }) + it("removes the excluded files", func() { + assert.Nil(t, cnb.ProcessProjectDescriptor(appDir, descriptorPath, platformDir, logger)) + assert.NoFileExists(t, filepath.Join(appDir, "api_keys.json")) + assert.NoFileExists(t, filepath.Join(appDir, "user_token")) + assert.NoFileExists(t, filepath.Join(appDir, "test.sh")) + assert.NoFileExists(t, filepath.Join(appDir, "other-cookie.jar")) + assert.NoFileExists(t, filepath.Join(appDir, "nested-cookie.jar")) + assert.FileExists(t, filepath.Join(appDir, "cookie.jar")) + assert.FileExists(t, filepath.Join(appDir, "nested", "nested-cookie.jar")) + assert.FileExists(t, filepath.Join(appDir, "media", "mountain.jpg")) + assert.FileExists(t, filepath.Join(appDir, "media", "person.png")) + }) }) - it("removes the excluded files", func() { - assert.Nil(t, cnb.ProcessProjectDescriptor(appDir, descriptorPath, platformDir, logger)) - assert.NoFileExists(t, filepath.Join(appDir, "api_keys.json")) - assert.NoFileExists(t, filepath.Join(appDir, "user_token")) - assert.NoFileExists(t, filepath.Join(appDir, "test.sh")) - assert.NoFileExists(t, filepath.Join(appDir, "other-cookie.jar")) - assert.NoFileExists(t, filepath.Join(appDir, "nested-cookie.jar")) - assert.FileExists(t, filepath.Join(appDir, "cookie.jar")) - assert.FileExists(t, filepath.Join(appDir, "nested", "nested-cookie.jar")) - assert.FileExists(t, filepath.Join(appDir, "media", "mountain.jpg")) - assert.FileExists(t, filepath.Join(appDir, "media", "person.png")) + + when("it has includes", func() { + it.Before(func() { + ioutil.WriteFile(projectToml, []byte(` +[build] +include = [ "*.jar", "media/mountain.jpg", "/media/person.png", ] + `), 0644) + }) + + it("keeps only the included files", func() { + assert.Nil(t, cnb.ProcessProjectDescriptor(appDir, descriptorPath, platformDir, logger)) + assert.NoFileExists(t, filepath.Join(appDir, "api_keys.json")) + assert.NoFileExists(t, filepath.Join(appDir, "user_token")) + assert.NoFileExists(t, filepath.Join(appDir, "test.sh")) + assert.FileExists(t, filepath.Join(appDir, "other-cookie.jar")) + assert.FileExists(t, filepath.Join(appDir, "nested-cookie.jar")) + assert.FileExists(t, filepath.Join(appDir, "cookie.jar")) + assert.FileExists(t, filepath.Join(appDir, "nested", "nested-cookie.jar")) + assert.FileExists(t, filepath.Join(appDir, "media", "mountain.jpg")) + assert.FileExists(t, filepath.Join(appDir, "media", "person.png")) + }) + }) + + when("it has both excludes and includes", func() { + it.Before(func() { + ioutil.WriteFile(projectToml, []byte(` +[build] +include = [ "test", ] +exclude = ["test", ] + `), 0644) + }) + it("throws an error", func() { + assert.NotNil(t, cnb.ProcessProjectDescriptor(appDir, descriptorPath, platformDir, logger)) + }) + }) }) - when("it has includes", func() { + when("the descriptor has builder", func() { it.Before(func() { ioutil.WriteFile(projectToml, []byte(` [build] -include = [ "*.jar", "media/mountain.jpg", "/media/person.png", ] - `), 0644) +builder = "my-super-cool-builder" + `), 0644) + }) + it("logs a warning that the builder will be ignored", func() { + assert.Nil(t, cnb.ProcessProjectDescriptor(appDir, descriptorPath, platformDir, logger)) + assert.Equal(t, "info: builder provided in project descriptor file will be ignored\n", buf.String()) }) + }) - it("keeps only the included files", func() { + when("the descriptor has buildpacks", func() { + it.Before(func() { + ioutil.WriteFile(projectToml, []byte(` +[[build.buildpacks]] +id = "cool-buildpack" +version = "v4.2" +uri = "check-this-out.com" + `), 0644) + }) + it("logs a warning that the buildpacks will be ignored", func() { assert.Nil(t, cnb.ProcessProjectDescriptor(appDir, descriptorPath, platformDir, logger)) - assert.NoFileExists(t, filepath.Join(appDir, "api_keys.json")) - assert.NoFileExists(t, filepath.Join(appDir, "user_token")) - assert.NoFileExists(t, filepath.Join(appDir, "test.sh")) - assert.FileExists(t, filepath.Join(appDir, "other-cookie.jar")) - assert.FileExists(t, filepath.Join(appDir, "nested-cookie.jar")) - assert.FileExists(t, filepath.Join(appDir, "cookie.jar")) - assert.FileExists(t, filepath.Join(appDir, "nested", "nested-cookie.jar")) - assert.FileExists(t, filepath.Join(appDir, "media", "mountain.jpg")) - assert.FileExists(t, filepath.Join(appDir, "media", "person.png")) + assert.Equal(t, "info: buildpacks provided in project descriptor file will be ignored\n", buf.String()) }) }) + }) - when("it has both excludes and includes", func() { + when("using descriptor v2", func() { + when("the descriptor has build env vars", func() { it.Before(func() { ioutil.WriteFile(projectToml, []byte(` -[build] -include = [ "test", ] -exclude = ["test", ] +[_] +schema-version = "0.2" +[[io.buildpacks.env]] +name = "keyA" +value = "valueA" +[[io.buildpacks.env]] +name = "keyB" +value = "valueB" +[[io.buildpacks.env]] +name = "keyC" +value = "valueC" +# check that later keys override previous ones +[[io.buildpacks.env]] +name = "keyC" +value = "valueAnotherC" + `), 0644) + }) + it("writes all env var files to the platform dir", func() { + assert.Nil(t, cnb.ProcessProjectDescriptor(appDir, descriptorPath, platformDir, logger)) + checkEnvVar(t, platformDir, "keyA", "valueA") + checkEnvVar(t, platformDir, "keyB", "valueB") + checkEnvVar(t, platformDir, "keyC", "valueAnotherC") + }) + }) + + when("the descriptor has includes and excludes", func() { + it.Before(func() { + var err error + // Create test directories and files: + // + // ├── cookie.jar + // ├── other-cookie.jar + // ├── nested-cookie.jar + // ├── nested + // │ └── nested-cookie.jar + // ├── secrets + // │ ├── api_keys.json + // | |── user_token + // ├── media + // │ ├── mountain.jpg + // │ └── person.png + // └── test.sh + + err = os.Mkdir(filepath.Join(appDir, "secrets"), 0755) + assert.Nil(t, err) + err = ioutil.WriteFile(filepath.Join(appDir, "secrets", "api_keys.json"), []byte("{}"), 0755) + assert.Nil(t, err) + err = ioutil.WriteFile(filepath.Join(appDir, "secrets", "user_token"), []byte("token"), 0755) + assert.Nil(t, err) + + err = os.Mkdir(filepath.Join(appDir, "nested"), 0755) + assert.Nil(t, err) + err = ioutil.WriteFile(filepath.Join(appDir, "nested", "nested-cookie.jar"), []byte("chocolate chip"), 0755) + assert.Nil(t, err) + + err = ioutil.WriteFile(filepath.Join(appDir, "other-cookie.jar"), []byte("chocolate chip"), 0755) + assert.Nil(t, err) + + err = ioutil.WriteFile(filepath.Join(appDir, "nested-cookie.jar"), []byte("chocolate chip"), 0755) + assert.Nil(t, err) + + err = os.Mkdir(filepath.Join(appDir, "media"), 0755) + assert.Nil(t, err) + err = ioutil.WriteFile(filepath.Join(appDir, "media", "mountain.jpg"), []byte("fake image bytes"), 0755) + assert.Nil(t, err) + err = ioutil.WriteFile(filepath.Join(appDir, "media", "person.png"), []byte("fake image bytes"), 0755) + assert.Nil(t, err) + + err = ioutil.WriteFile(filepath.Join(appDir, "cookie.jar"), []byte("chocolate chip"), 0755) + assert.Nil(t, err) + err = ioutil.WriteFile(filepath.Join(appDir, "test.sh"), []byte("echo test"), 0755) + assert.Nil(t, err) + }) + + when("it has excludes", func() { + it.Before(func() { + ioutil.WriteFile(projectToml, []byte(` +[_] +schema-version = "0.2" +[io.buildpacks] +exclude = ["*.sh", "secrets/", "media/metadata", "/other-cookie.jar" ,"/nested-cookie.jar"] `), 0644) + }) + it("removes the excluded files", func() { + assert.Nil(t, cnb.ProcessProjectDescriptor(appDir, descriptorPath, platformDir, logger)) + assert.NoFileExists(t, filepath.Join(appDir, "api_keys.json")) + assert.NoFileExists(t, filepath.Join(appDir, "user_token")) + assert.NoFileExists(t, filepath.Join(appDir, "test.sh")) + assert.NoFileExists(t, filepath.Join(appDir, "other-cookie.jar")) + assert.NoFileExists(t, filepath.Join(appDir, "nested-cookie.jar")) + assert.FileExists(t, filepath.Join(appDir, "cookie.jar")) + assert.FileExists(t, filepath.Join(appDir, "nested", "nested-cookie.jar")) + assert.FileExists(t, filepath.Join(appDir, "media", "mountain.jpg")) + assert.FileExists(t, filepath.Join(appDir, "media", "person.png")) + }) }) - it("throws an error", func() { - assert.NotNil(t, cnb.ProcessProjectDescriptor(appDir, descriptorPath, platformDir, logger)) + + when("it has includes", func() { + it.Before(func() { + ioutil.WriteFile(projectToml, []byte(` +[_] +schema-version = "0.2" +[io.buildpacks] +include = [ "*.jar", "media/mountain.jpg", "/media/person.png", ] + `), 0644) + }) + + it("keeps only the included files", func() { + assert.Nil(t, cnb.ProcessProjectDescriptor(appDir, descriptorPath, platformDir, logger)) + assert.NoFileExists(t, filepath.Join(appDir, "api_keys.json")) + assert.NoFileExists(t, filepath.Join(appDir, "user_token")) + assert.NoFileExists(t, filepath.Join(appDir, "test.sh")) + assert.FileExists(t, filepath.Join(appDir, "other-cookie.jar")) + assert.FileExists(t, filepath.Join(appDir, "nested-cookie.jar")) + assert.FileExists(t, filepath.Join(appDir, "cookie.jar")) + assert.FileExists(t, filepath.Join(appDir, "nested", "nested-cookie.jar")) + assert.FileExists(t, filepath.Join(appDir, "media", "mountain.jpg")) + assert.FileExists(t, filepath.Join(appDir, "media", "person.png")) + }) }) + when("it has both excludes and includes", func() { + it.Before(func() { + ioutil.WriteFile(projectToml, []byte(` +[_] +schema-version = "0.2" +[io.buildpacks] +include = [ "test", ] +exclude = ["test", ] + `), 0644) + }) + it("throws an error", func() { + assert.NotNil(t, cnb.ProcessProjectDescriptor(appDir, descriptorPath, platformDir, logger)) + }) + + }) }) - }) - when("the descriptor has builder", func() { - it.Before(func() { - ioutil.WriteFile(projectToml, []byte(` -[build] -builder = "my-super-cool-builder" + when("the descriptor has builder", func() { + it.Before(func() { + ioutil.WriteFile(projectToml, []byte(` +[_] +schema-version = "0.2" +[io.buildpacks] +builder = "my-super-cool-builder" `), 0644) + }) + it("logs a warning that the builder will be ignored", func() { + assert.Nil(t, cnb.ProcessProjectDescriptor(appDir, descriptorPath, platformDir, logger)) + assert.Equal(t, "info: builder provided in project descriptor file will be ignored\n", buf.String()) + }) }) - it("logs a warning that the builder will be ignored", func() { - assert.Nil(t, cnb.ProcessProjectDescriptor(appDir, descriptorPath, platformDir, logger)) - assert.Equal(t, "info: builder provided in project descriptor file will be ignored\n", buf.String()) - }) - }) - when("the descriptor has buildpacks", func() { - it.Before(func() { - ioutil.WriteFile(projectToml, []byte(` -[[build.buildpacks]] + + when("the descriptor has buildpack groups", func() { + it.Before(func() { + ioutil.WriteFile(projectToml, []byte(` +[_] +schema-version = "0.2" +[[io.buildpacks.group]] id = "cool-buildpack" version = "v4.2" uri = "check-this-out.com" `), 0644) - }) - it("logs a warning that the buildpacks will be ignored", func() { - assert.Nil(t, cnb.ProcessProjectDescriptor(appDir, descriptorPath, platformDir, logger)) - assert.Equal(t, "info: buildpacks provided in project descriptor file will be ignored\n", buf.String()) + }) + it("logs a warning that the buildpacks will be ignored", func() { + assert.Nil(t, cnb.ProcessProjectDescriptor(appDir, descriptorPath, platformDir, logger)) + assert.Equal(t, "info: buildpacks provided in project descriptor file will be ignored\n", buf.String()) + }) }) }) }) @@ -219,20 +405,16 @@ uri = "check-this-out.com" [[build.env]] name = "keyA" value = "valueA" - [[build.env]] name = "keyB" value = "valueB" - [[build.env]] name = "keyC" value = "valueC" - # check that later keys override previous ones [[build.env]] name = "keyC" value = "valueAnotherC" - `), 0644) require.NoError(t, err) })