Skip to content

Commit

Permalink
Allow multiple space separated globs for artifacts specification (#109)
Browse files Browse the repository at this point in the history
Allow multiple globs for artifacts specification

- The globs shall be space-separated.
- This allows usage as: `--env BP_MAVEN_BUILT_ARTIFACT="target/*runner*.jar target/lib"`.
- If there's a bad pattern, the build will fail and the bad pattern(s) will be listed

Signed-off-by: Matej Vasek <[email protected]>
Co-authored-by: Daniel Mikusa <[email protected]>
  • Loading branch information
matejvasek and Daniel Mikusa authored Feb 16, 2022
1 parent 905f69b commit db786f0
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 17 deletions.
36 changes: 20 additions & 16 deletions resolvers.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ import (
"archive/zip"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"sort"
"strings"

"github.com/magiconair/properties"
"github.com/mattn/go-shellwords"
Expand Down Expand Up @@ -117,7 +117,7 @@ type ArtifactResolver struct {
AdditionalHelpMessage string
}

// Pattern returns the glob that ArtifactResolver will use for resolution.
// Pattern returns the space separated list of globs that ArtifactResolver will use for resolution.
func (a *ArtifactResolver) Pattern() string {
pattern, ok := a.ConfigurationResolver.Resolve(a.ArtifactConfigurationKey)
if ok {
Expand Down Expand Up @@ -165,29 +165,33 @@ func (a *ArtifactResolver) Resolve(applicationPath string) (string, error) {

func (a *ArtifactResolver) ResolveMany(applicationPath string) ([]string, error) {
pattern := a.Pattern()
file := filepath.Join(applicationPath, pattern)
candidates, err := filepath.Glob(file)

patterns, err := shellwords.Parse(pattern)
if err != nil {
return []string{}, fmt.Errorf("unable to find files with %s\n%w", pattern, err)
return []string{}, fmt.Errorf("unable to parse shellwords patterns\n%w", err)
}

if len(candidates) > 0 {
return candidates, nil
var candidates []string
var badPatterns []string
for _, pattern := range patterns {
file := filepath.Join(applicationPath, pattern)
cs, err := filepath.Glob(file)
if err != nil {
// err will only be ErrBadPattern / "syntax error in pattern"
badPatterns = append(badPatterns, pattern)
}
candidates = append(candidates, cs...)
}

entries, err := os.ReadDir(filepath.Dir(pattern))
if err != nil && os.IsNotExist(err) {
return []string{}, fmt.Errorf("unable to find directory referened by pattern: %s", pattern)
} else if err != nil {
return []string{}, fmt.Errorf("unable to read directory\n%w", err)
if len(badPatterns) > 0 {
return []string{}, fmt.Errorf("unable to proceed due to bad pattern(s):\n%s", strings.Join(badPatterns, "\n"))
}

contents := []string{}
for _, entry := range entries {
contents = append(contents, entry.Name())
if len(candidates) > 0 {
return candidates, nil
}

helpMsg := fmt.Sprintf("unable to find any built artifacts in %s, directory contains: %s", pattern, contents)
helpMsg := fmt.Sprintf("unable to find any built artifacts for pattern(s):\n%s", strings.Join(patterns, "\n"))
if len(a.AdditionalHelpMessage) > 0 {
helpMsg = fmt.Sprintf("%s. %s", helpMsg, a.AdditionalHelpMessage)
}
Expand Down
58 changes: 57 additions & 1 deletion resolvers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,63 @@ func testResolvers(t *testing.T, context spec.G, it spec.S) {
it("fails with zero candidates", func() {
_, err := resolver.ResolveMany(path)

Expect(err).To(MatchError(HavePrefix("unable to find any built artifacts in test-*, directory contains:")))
Expect(err).To(MatchError(HavePrefix("unable to find any built artifacts for pattern(s):\ntest-*")))
})

context("ResolveMany with multiple glob patterns", func() {
it.Before(func() {
resolver.ConfigurationResolver.Configurations[0] = libpak.BuildpackConfiguration{
Name: "TEST_ARTIFACT_CONFIGURATION_KEY", Default: "test-* target/*-runner.jar target/lib"}
})

it("passes with a single candidate", func() {
Expect(ioutil.WriteFile(filepath.Join(path, "test-file"), []byte{}, 0644)).To(Succeed())
Expect(resolver.ResolveMany(path)).To(Equal([]string{filepath.Join(path, "test-file")}))
})

it("passes with multiple space separated globs", func() {
Expect(os.Mkdir(filepath.Join(path, "target"), os.ModePerm)).To(Succeed())

runnerJarPath := filepath.Join(path, "target", "function-1.0.0-SNAPSHOT-runner.jar")
Expect(ioutil.WriteFile(runnerJarPath, []byte{}, 0644)).To(Succeed())

libPath := filepath.Join(path, "target", "lib")
Expect(os.Mkdir(libPath, os.ModePerm)).To(Succeed())

Expect(resolver.ResolveMany(path)).To(Equal([]string{runnerJarPath, libPath}))
})

it("fails with zero candidates", func() {
_, err := resolver.ResolveMany(path)

Expect(err).To(MatchError(HavePrefix("unable to find any built artifacts for pattern(s):\ntest-*\ntarget/*-runner.jar\ntarget/lib")))
})
})

context("ResolveMany with a bad pattern", func() {
it.Before(func() {
resolver.ConfigurationResolver.Configurations[0] = libpak.BuildpackConfiguration{
Name: "TEST_ARTIFACT_CONFIGURATION_KEY", Default: "["}
})

it("fails with a single error", func() {
_, err := resolver.ResolveMany(path)

Expect(err).To(MatchError("unable to proceed due to bad pattern(s):\n["))
})
})

context("ResolveMany with many bad patterns", func() {
it.Before(func() {
resolver.ConfigurationResolver.Configurations[0] = libpak.BuildpackConfiguration{
Name: "TEST_ARTIFACT_CONFIGURATION_KEY", Default: "first-bad-[ test-* second-bad-["}
})

it("fails with multiple errors", func() {
_, err := resolver.ResolveMany(path)

Expect(err).To(MatchError("unable to proceed due to bad pattern(s):\nfirst-bad-[\nsecond-bad-["))
})
})
})
}

0 comments on commit db786f0

Please sign in to comment.