common/command: delete
This commit is contained in:
parent
d4b489a9ec
commit
dd0a775500
|
@ -1,39 +0,0 @@
|
|||
package command
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// BuildOptionFlags sets the proper command line flags needed for
|
||||
// build options.
|
||||
func BuildOptionFlags(fs *flag.FlagSet, f *BuildOptions) {
|
||||
fs.Var((*SliceValue)(&f.Except), "except", "build all builds except these")
|
||||
fs.Var((*SliceValue)(&f.Only), "only", "only build the given builds by name")
|
||||
fs.Var((*userVarValue)(&f.UserVars), "var", "specify a user variable")
|
||||
fs.Var((*AppendSliceValue)(&f.UserVarFiles), "var-file", "file with user variables")
|
||||
}
|
||||
|
||||
// userVarValue is a flag.Value that parses out user variables in
|
||||
// the form of 'key=value' and sets it on this map.
|
||||
type userVarValue map[string]string
|
||||
|
||||
func (v *userVarValue) String() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (v *userVarValue) Set(raw string) error {
|
||||
idx := strings.Index(raw, "=")
|
||||
if idx == -1 {
|
||||
return fmt.Errorf("No '=' value in arg: %s", raw)
|
||||
}
|
||||
|
||||
if *v == nil {
|
||||
*v = make(map[string]string)
|
||||
}
|
||||
|
||||
key, value := raw[0:idx], raw[idx+1:]
|
||||
(*v)[key] = value
|
||||
return nil
|
||||
}
|
|
@ -1,104 +0,0 @@
|
|||
package command
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestBuildOptionFlags(t *testing.T) {
|
||||
opts := new(BuildOptions)
|
||||
fs := flag.NewFlagSet("test", flag.ContinueOnError)
|
||||
BuildOptionFlags(fs, opts)
|
||||
|
||||
args := []string{
|
||||
"-except=foo,bar,baz",
|
||||
"-only=a,b",
|
||||
"-var=foo=bar",
|
||||
"-var", "bar=baz",
|
||||
"-var=foo=bang",
|
||||
"-var-file=foo",
|
||||
"-var-file=bar",
|
||||
}
|
||||
|
||||
err := fs.Parse(args)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
expected := []string{"foo", "bar", "baz"}
|
||||
if !reflect.DeepEqual(opts.Except, expected) {
|
||||
t.Fatalf("bad: %#v", opts.Except)
|
||||
}
|
||||
|
||||
expected = []string{"a", "b"}
|
||||
if !reflect.DeepEqual(opts.Only, expected) {
|
||||
t.Fatalf("bad: %#v", opts.Only)
|
||||
}
|
||||
|
||||
if len(opts.UserVars) != 2 {
|
||||
t.Fatalf("bad: %#v", opts.UserVars)
|
||||
}
|
||||
|
||||
if opts.UserVars["foo"] != "bang" {
|
||||
t.Fatalf("bad: %#v", opts.UserVars)
|
||||
}
|
||||
|
||||
if opts.UserVars["bar"] != "baz" {
|
||||
t.Fatalf("bad: %#v", opts.UserVars)
|
||||
}
|
||||
|
||||
expected = []string{"foo", "bar"}
|
||||
if !reflect.DeepEqual(opts.UserVarFiles, expected) {
|
||||
t.Fatalf("bad: %#v", opts.UserVarFiles)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUserVarValue_implements(t *testing.T) {
|
||||
var raw interface{}
|
||||
raw = new(userVarValue)
|
||||
if _, ok := raw.(flag.Value); !ok {
|
||||
t.Fatalf("userVarValue should be a Value")
|
||||
}
|
||||
}
|
||||
|
||||
func TestUserVarValueSet(t *testing.T) {
|
||||
sv := new(userVarValue)
|
||||
err := sv.Set("key=value")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
vars := map[string]string(*sv)
|
||||
if vars["key"] != "value" {
|
||||
t.Fatalf("Bad: %#v", vars)
|
||||
}
|
||||
|
||||
// Empty value
|
||||
err = sv.Set("key=")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
vars = map[string]string(*sv)
|
||||
if vars["key"] != "" {
|
||||
t.Fatalf("Bad: %#v", vars)
|
||||
}
|
||||
|
||||
// Equal in value
|
||||
err = sv.Set("key=foo=bar")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
vars = map[string]string(*sv)
|
||||
if vars["key"] != "foo=bar" {
|
||||
t.Fatalf("Bad: %#v", vars)
|
||||
}
|
||||
|
||||
// No equal
|
||||
err = sv.Set("key")
|
||||
if err == nil {
|
||||
t.Fatal("should have error")
|
||||
}
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
package command
|
||||
|
||||
import "strings"
|
||||
|
||||
// AppendSliceValue implements the flag.Value interface and allows multiple
|
||||
// calls to the same variable to append a list.
|
||||
type AppendSliceValue []string
|
||||
|
||||
func (s *AppendSliceValue) String() string {
|
||||
return strings.Join(*s, ",")
|
||||
}
|
||||
|
||||
func (s *AppendSliceValue) Set(value string) error {
|
||||
if *s == nil {
|
||||
*s = make([]string, 0, 1)
|
||||
}
|
||||
|
||||
*s = append(*s, value)
|
||||
return nil
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
|
@ -1,54 +0,0 @@
|
|||
package command
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAppendSliceValue_implements(t *testing.T) {
|
||||
var raw interface{}
|
||||
raw = new(AppendSliceValue)
|
||||
if _, ok := raw.(flag.Value); !ok {
|
||||
t.Fatalf("AppendSliceValue should be a Value")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppendSliceValueSet(t *testing.T) {
|
||||
sv := new(AppendSliceValue)
|
||||
err := sv.Set("foo")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
err = sv.Set("bar")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
expected := []string{"foo", "bar"}
|
||||
if !reflect.DeepEqual([]string(*sv), expected) {
|
||||
t.Fatalf("Bad: %#v", sv)
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
|
@ -1,162 +0,0 @@
|
|||
package command
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
jsonutil "github.com/mitchellh/packer/common/json"
|
||||
"github.com/mitchellh/packer/packer"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
)
|
||||
|
||||
// BuildOptions is a set of options related to builds that can be set
|
||||
// from the command line.
|
||||
type BuildOptions struct {
|
||||
UserVarFiles []string
|
||||
UserVars map[string]string
|
||||
Except []string
|
||||
Only []string
|
||||
}
|
||||
|
||||
// Validate validates the options
|
||||
func (f *BuildOptions) Validate() error {
|
||||
if len(f.Except) > 0 && len(f.Only) > 0 {
|
||||
return errors.New("Only one of '-except' or '-only' may be specified.")
|
||||
}
|
||||
|
||||
if len(f.UserVarFiles) > 0 {
|
||||
for _, path := range f.UserVarFiles {
|
||||
if _, err := os.Stat(path); err != nil {
|
||||
return fmt.Errorf("Cannot access: %s", path)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// AllUserVars returns the user variables, compiled from both the
|
||||
// file paths and the vars on the command line.
|
||||
func (f *BuildOptions) AllUserVars() (map[string]string, error) {
|
||||
all := make(map[string]string)
|
||||
|
||||
// Copy in the variables from the files
|
||||
for _, path := range f.UserVarFiles {
|
||||
fileVars, err := readFileVars(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for k, v := range fileVars {
|
||||
all[k] = v
|
||||
}
|
||||
}
|
||||
|
||||
// Copy in the command-line vars
|
||||
for k, v := range f.UserVars {
|
||||
all[k] = v
|
||||
}
|
||||
|
||||
return all, nil
|
||||
}
|
||||
|
||||
// Builds returns the builds out of the given template that pass the
|
||||
// configured options.
|
||||
func (f *BuildOptions) Builds(t *packer.Template, cf *packer.ComponentFinder) ([]packer.Build, error) {
|
||||
buildNames := t.BuildNames()
|
||||
|
||||
// Process the name
|
||||
tpl, _, err := t.NewConfigTemplate()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
checks := make(map[string][]string)
|
||||
checks["except"] = f.Except
|
||||
checks["only"] = f.Only
|
||||
for t, ns := range checks {
|
||||
for _, n := range ns {
|
||||
found := false
|
||||
for _, actual := range buildNames {
|
||||
var processed string
|
||||
processed, err = tpl.Process(actual, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if actual == n || processed == n {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
return nil, fmt.Errorf(
|
||||
"Unknown build in '%s' flag: %s", t, n)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
builds := make([]packer.Build, 0, len(buildNames))
|
||||
for _, buildName := range buildNames {
|
||||
var processedBuildName string
|
||||
processedBuildName, err = tpl.Process(buildName, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(f.Except) > 0 {
|
||||
found := false
|
||||
for _, except := range f.Except {
|
||||
if buildName == except || processedBuildName == except {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if found {
|
||||
log.Printf("Skipping build '%s' because specified by -except.", processedBuildName)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if len(f.Only) > 0 {
|
||||
found := false
|
||||
for _, only := range f.Only {
|
||||
if buildName == only || processedBuildName == only {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
log.Printf("Skipping build '%s' because not specified by -only.", processedBuildName)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
log.Printf("Creating build: %s", processedBuildName)
|
||||
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
|
||||
}
|
||||
|
||||
func readFileVars(path string) (map[string]string, error) {
|
||||
bytes, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
vars := make(map[string]string)
|
||||
err = jsonutil.Unmarshal(bytes, &vars)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return vars, nil
|
||||
}
|
|
@ -1,228 +0,0 @@
|
|||
package command
|
||||
|
||||
import (
|
||||
"github.com/mitchellh/packer/packer"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func testTemplate() (*packer.Template, *packer.ComponentFinder) {
|
||||
tplData := `{
|
||||
"variables": {
|
||||
"foo": null
|
||||
},
|
||||
|
||||
"builders": [
|
||||
{
|
||||
"type": "foo"
|
||||
},
|
||||
{
|
||||
"name": "{{user \"foo\"}}",
|
||||
"type": "bar"
|
||||
}
|
||||
]
|
||||
}
|
||||
`
|
||||
|
||||
tpl, err := packer.ParseTemplate([]byte(tplData), map[string]string{"foo": "bar"})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
cf := &packer.ComponentFinder{
|
||||
Builder: func(string) (packer.Builder, error) { return new(packer.MockBuilder), nil },
|
||||
}
|
||||
|
||||
return tpl, cf
|
||||
}
|
||||
|
||||
func TestBuildOptionsBuilds(t *testing.T) {
|
||||
opts := new(BuildOptions)
|
||||
bs, err := opts.Builds(testTemplate())
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
if len(bs) != 2 {
|
||||
t.Fatalf("bad: %d", len(bs))
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildOptionsBuilds_except(t *testing.T) {
|
||||
opts := new(BuildOptions)
|
||||
opts.Except = []string{"foo"}
|
||||
|
||||
bs, err := opts.Builds(testTemplate())
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
if len(bs) != 1 {
|
||||
t.Fatalf("bad: %d", len(bs))
|
||||
}
|
||||
|
||||
if bs[0].Name() != "bar" {
|
||||
t.Fatalf("bad: %s", bs[0].Name())
|
||||
}
|
||||
}
|
||||
|
||||
//Test to make sure the build name pattern matches
|
||||
func TestBuildOptionsBuilds_exceptConfigTemplateRaw(t *testing.T) {
|
||||
opts := new(BuildOptions)
|
||||
opts.Except = []string{"{{user \"foo\"}}"}
|
||||
|
||||
bs, err := opts.Builds(testTemplate())
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
if len(bs) != 1 {
|
||||
t.Fatalf("bad: %d", len(bs))
|
||||
}
|
||||
|
||||
if bs[0].Name() != "foo" {
|
||||
t.Fatalf("bad: %s", bs[0].Name())
|
||||
}
|
||||
}
|
||||
|
||||
//Test to make sure the processed build name matches
|
||||
func TestBuildOptionsBuilds_exceptConfigTemplateProcessed(t *testing.T) {
|
||||
opts := new(BuildOptions)
|
||||
opts.Except = []string{"bar"}
|
||||
|
||||
bs, err := opts.Builds(testTemplate())
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
if len(bs) != 1 {
|
||||
t.Fatalf("bad: %d", len(bs))
|
||||
}
|
||||
|
||||
if bs[0].Name() != "foo" {
|
||||
t.Fatalf("bad: %s", bs[0].Name())
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildOptionsBuilds_only(t *testing.T) {
|
||||
opts := new(BuildOptions)
|
||||
opts.Only = []string{"foo"}
|
||||
|
||||
bs, err := opts.Builds(testTemplate())
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
if len(bs) != 1 {
|
||||
t.Fatalf("bad: %d", len(bs))
|
||||
}
|
||||
|
||||
if bs[0].Name() != "foo" {
|
||||
t.Fatalf("bad: %s", bs[0].Name())
|
||||
}
|
||||
}
|
||||
|
||||
//Test to make sure the build name pattern matches
|
||||
func TestBuildOptionsBuilds_onlyConfigTemplateRaw(t *testing.T) {
|
||||
opts := new(BuildOptions)
|
||||
opts.Only = []string{"{{user \"foo\"}}"}
|
||||
|
||||
bs, err := opts.Builds(testTemplate())
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
if len(bs) != 1 {
|
||||
t.Fatalf("bad: %d", len(bs))
|
||||
}
|
||||
|
||||
if bs[0].Name() != "bar" {
|
||||
t.Fatalf("bad: %s", bs[0].Name())
|
||||
}
|
||||
}
|
||||
|
||||
//Test to make sure the processed build name matches
|
||||
func TestBuildOptionsBuilds_onlyConfigTemplateProcessed(t *testing.T) {
|
||||
opts := new(BuildOptions)
|
||||
opts.Only = []string{"bar"}
|
||||
|
||||
bs, err := opts.Builds(testTemplate())
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
if len(bs) != 1 {
|
||||
t.Fatalf("bad: %d", len(bs))
|
||||
}
|
||||
|
||||
if bs[0].Name() != "bar" {
|
||||
t.Fatalf("bad: %s", bs[0].Name())
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildOptionsBuilds_exceptNonExistent(t *testing.T) {
|
||||
opts := new(BuildOptions)
|
||||
opts.Except = []string{"i-dont-exist"}
|
||||
|
||||
_, err := opts.Builds(testTemplate())
|
||||
if err == nil {
|
||||
t.Fatal("err should not be nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildOptionsBuilds_onlyNonExistent(t *testing.T) {
|
||||
opts := new(BuildOptions)
|
||||
opts.Only = []string{"i-dont-exist"}
|
||||
|
||||
_, err := opts.Builds(testTemplate())
|
||||
if err == nil {
|
||||
t.Fatal("err should not be nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildOptionsValidate(t *testing.T) {
|
||||
bf := new(BuildOptions)
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildOptionsValidate_userVarFiles(t *testing.T) {
|
||||
bf := new(BuildOptions)
|
||||
|
||||
err := bf.Validate()
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
// Non-existent file
|
||||
bf.UserVarFiles = []string{"ireallyshouldntexistanywhere"}
|
||||
err = bf.Validate()
|
||||
if err == nil {
|
||||
t.Fatal("should error")
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue