mirror of https://github.com/hashicorp/packer
parent
643d9033ad
commit
089df41aac
@ -1,14 +0,0 @@
|
|||||||
package build
|
|
||||||
|
|
||||||
import "strings"
|
|
||||||
|
|
||||||
type stringSliceValue []string
|
|
||||||
|
|
||||||
func (s *stringSliceValue) String() string {
|
|
||||||
return strings.Join(*s, ",")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *stringSliceValue) Set(value string) error {
|
|
||||||
*s = strings.Split(value, ",")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
package command
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
)
|
||||||
|
|
||||||
|
// BuildFilterFlags sets the proper command line flags needed for
|
||||||
|
// build filters.
|
||||||
|
func BuildFilterFlags(fs *flag.FlagSet, f *BuildFilters) {
|
||||||
|
fs.Var((*SliceValue)(&f.Except), "except", "build all builds except these")
|
||||||
|
fs.Var((*SliceValue)(&f.Only), "only", "only build the given builds by name")
|
||||||
|
}
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
package command
|
||||||
|
|
||||||
|
import "strings"
|
||||||
|
|
||||||
|
// SliceValue implements the flag.Value interface and allows a list of
|
||||||
|
// strings to be given on the command line and properly parsed into a slice
|
||||||
|
// of strings internally.
|
||||||
|
type SliceValue []string
|
||||||
|
|
||||||
|
func (s *SliceValue) String() string {
|
||||||
|
return strings.Join(*s, ",")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SliceValue) Set(value string) error {
|
||||||
|
*s = strings.Split(value, ",")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@ -0,0 +1,28 @@
|
|||||||
|
package command
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSliceValue_implements(t *testing.T) {
|
||||||
|
var raw interface{}
|
||||||
|
raw = new(SliceValue)
|
||||||
|
if _, ok := raw.(flag.Value); !ok {
|
||||||
|
t.Fatalf("SliceValue should be a Value")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSliceValueSet(t *testing.T) {
|
||||||
|
sv := new(SliceValue)
|
||||||
|
err := sv.Set("foo,bar,baz")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
expected := []string{"foo", "bar", "baz"}
|
||||||
|
if !reflect.DeepEqual([]string(*sv), expected) {
|
||||||
|
t.Fatalf("Bad: %#v", sv)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,71 @@
|
|||||||
|
package command
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"github.com/mitchellh/packer/packer"
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
// BuildFilters is a set of options to filter the builds out of a template.
|
||||||
|
type BuildFilters struct {
|
||||||
|
Except []string
|
||||||
|
Only []string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate validates the filter settings
|
||||||
|
func (f *BuildFilters) Validate() error {
|
||||||
|
if len(f.Except) > 0 && len(f.Only) > 0 {
|
||||||
|
return errors.New("Only one of '-except' or '-only' may be specified.")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Builds returns the builds out of the given template that pass the
|
||||||
|
// configured filters.
|
||||||
|
func (f *BuildFilters) Builds(t *packer.Template, cf *packer.ComponentFinder) ([]packer.Build, error) {
|
||||||
|
buildNames := t.BuildNames()
|
||||||
|
builds := make([]packer.Build, 0, len(buildNames))
|
||||||
|
for _, buildName := range buildNames {
|
||||||
|
if len(f.Except) > 0 {
|
||||||
|
found := false
|
||||||
|
for _, except := range f.Except {
|
||||||
|
if buildName == except {
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if found {
|
||||||
|
log.Printf("Skipping build '%s' because specified by -except.", buildName)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(f.Only) > 0 {
|
||||||
|
found := false
|
||||||
|
for _, only := range f.Only {
|
||||||
|
if buildName == only {
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !found {
|
||||||
|
log.Printf("Skipping build '%s' because not specified by -only.", buildName)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("Creating build: %s", buildName)
|
||||||
|
build, err := t.Build(buildName, cf)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("Failed to create build '%s': \n\n%s", buildName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
builds = append(builds, build)
|
||||||
|
}
|
||||||
|
|
||||||
|
return builds, nil
|
||||||
|
}
|
||||||
@ -0,0 +1,37 @@
|
|||||||
|
package command
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestBuildFiltersValidate(t *testing.T) {
|
||||||
|
bf := new(BuildFilters)
|
||||||
|
|
||||||
|
err := bf.Validate()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Both set
|
||||||
|
bf.Except = make([]string, 1)
|
||||||
|
bf.Only = make([]string, 1)
|
||||||
|
err = bf.Validate()
|
||||||
|
if err == nil {
|
||||||
|
t.Fatal("should error")
|
||||||
|
}
|
||||||
|
|
||||||
|
// One set
|
||||||
|
bf.Except = make([]string, 1)
|
||||||
|
bf.Only = make([]string, 0)
|
||||||
|
err = bf.Validate()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
bf.Except = make([]string, 0)
|
||||||
|
bf.Only = make([]string, 1)
|
||||||
|
err = bf.Validate()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in new issue