forked from buildpacks/pack
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
flags: Add
--cache
flag for build cache as image
- Add `flag` definition - Integrate flag options with image cache - Add tests for flag options Signed-off-by: Nitish Gupta <imnitish.ng@gmail.com>
- Loading branch information
1 parent
21a3f40
commit 6504e87
Showing
6 changed files
with
210 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
package cache | ||
|
||
import ( | ||
"encoding/csv" | ||
"fmt" | ||
"strings" | ||
|
||
"github.com/pkg/errors" | ||
) | ||
|
||
type CacheOpts struct { | ||
CacheType string | ||
Format string | ||
Source string | ||
} | ||
|
||
func (c *CacheOpts) Set(value string) error { | ||
csvReader := csv.NewReader(strings.NewReader(value)) | ||
csvReader.Comma = ';' | ||
fields, err := csvReader.Read() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
for _, field := range fields { | ||
parts := strings.SplitN(field, "=", 2) | ||
|
||
if len(parts) == 2 { | ||
key := strings.ToLower(parts[0]) | ||
value := strings.ToLower(parts[1]) | ||
switch key { | ||
case "type": | ||
if value != "build" { | ||
return errors.Errorf("invalid cache type '%s'", value) | ||
} | ||
c.CacheType = value | ||
case "format": | ||
if value != "image" { | ||
return errors.Errorf("invalid cache format '%s'", value) | ||
} | ||
c.Format = value | ||
case "name": | ||
c.Source = value | ||
} | ||
} | ||
|
||
if len(parts) != 2 { | ||
return errors.Errorf("invalid field '%s' must be a key=value pair", field) | ||
} | ||
} | ||
|
||
err = populateMissing(c) | ||
if err != nil { | ||
return err | ||
} | ||
return nil | ||
} | ||
|
||
func (c *CacheOpts) String() string { | ||
var cacheFlag string | ||
if c.CacheType != "" { | ||
cacheFlag += fmt.Sprintf("type=%s;", c.CacheType) | ||
} | ||
if c.Format != "" { | ||
cacheFlag += fmt.Sprintf("format=%s;", c.Format) | ||
} | ||
if c.Source != "" { | ||
cacheFlag += fmt.Sprintf("name=%s", c.Source) | ||
} | ||
return cacheFlag | ||
} | ||
|
||
func (c *CacheOpts) Type() string { | ||
return "cache" | ||
} | ||
|
||
func populateMissing(c *CacheOpts) error { | ||
if c.CacheType == "" { | ||
c.CacheType = "build" | ||
} | ||
if c.Format == "" { | ||
c.Format = "volume" | ||
} | ||
if c.Source == "" { | ||
return errors.Errorf("cache 'name' is required") | ||
} | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
package cache | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/heroku/color" | ||
"github.com/sclevine/spec" | ||
"github.com/sclevine/spec/report" | ||
|
||
h "github.com/buildpacks/pack/testhelpers" | ||
) | ||
|
||
type CacheOptTestCase struct { | ||
name string | ||
input string | ||
output string | ||
shouldFail bool | ||
} | ||
|
||
func TestMetadata(t *testing.T) { | ||
color.Disable(true) | ||
defer color.Disable(false) | ||
spec.Run(t, "Metadata", testCacheOpts, spec.Sequential(), spec.Report(report.Terminal{})) | ||
} | ||
|
||
func testCacheOpts(t *testing.T, when spec.G, it spec.S) { | ||
when("cache options are passed", func() { | ||
it("image cache format with complete options", func() { | ||
testcases := []CacheOptTestCase{ | ||
{ | ||
name: "Build cache as Image", | ||
input: "type=build;format=image;name=io.test.io/myorg/my-cache:build", | ||
output: "type=build;format=image;name=io.test.io/myorg/my-cache:build", | ||
}, | ||
} | ||
|
||
for _, testcase := range testcases { | ||
var cacheFlags CacheOpts | ||
t.Logf("Testing cache type: %s", testcase.name) | ||
err := cacheFlags.Set(testcase.input) | ||
h.AssertNil(t, err) | ||
h.AssertEq(t, testcase.output, cacheFlags.String()) | ||
} | ||
}) | ||
|
||
it("image cache format with missing options", func() { | ||
successTestCases := []CacheOptTestCase{ | ||
{ | ||
name: "Build cache as Image missing: type", | ||
input: "format=image;name=io.test.io/myorg/my-cache:build", | ||
output: "type=build;format=image;name=io.test.io/myorg/my-cache:build", | ||
}, | ||
{ | ||
name: "Build cache as Image missing: format", | ||
input: "type=build;name=io.test.io/myorg/my-cache:build", | ||
output: "type=build;format=volume;name=io.test.io/myorg/my-cache:build", | ||
}, | ||
{ | ||
name: "Build cache as Image missing: type, format", | ||
input: "name=io.test.io/myorg/my-cache:build", | ||
output: "type=build;format=volume;name=io.test.io/myorg/my-cache:build", | ||
}, | ||
{ | ||
name: "Build cache as Image missing: name", | ||
input: "type=build;format=image", | ||
output: "cache 'name' is required", | ||
shouldFail: true, | ||
}, | ||
{ | ||
name: "Build cache as Image missing: format, name", | ||
input: "type=build", | ||
output: "cache 'name' is required", | ||
shouldFail: true, | ||
}, | ||
{ | ||
name: "Build cache as Image missing: type, name", | ||
input: "format=image", | ||
output: "cache 'name' is required", | ||
shouldFail: true, | ||
}, | ||
} | ||
|
||
for _, testcase := range successTestCases { | ||
var cacheFlags CacheOpts | ||
t.Logf("Testing cache type: %s", testcase.name) | ||
err := cacheFlags.Set(testcase.input) | ||
|
||
if testcase.shouldFail { | ||
h.AssertError(t, err, testcase.output) | ||
} else { | ||
h.AssertNil(t, err) | ||
output := cacheFlags.String() | ||
h.AssertEq(t, testcase.output, output) | ||
} | ||
} | ||
}) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters