Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
packer
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Kristopher Ruzic
packer
Commits
86973282
Commit
86973282
authored
May 07, 2013
by
Mitchell Hashimoto
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
packer, packer/rpc: Make command/builderFunc support errors
parent
fbc2013b
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
96 additions
and
52 deletions
+96
-52
packer/environment.go
packer/environment.go
+34
-15
packer/environment_test.go
packer/environment_test.go
+27
-16
packer/rpc/environment.go
packer/rpc/environment.go
+21
-11
packer/rpc/environment_test.go
packer/rpc/environment_test.go
+6
-6
packer/template.go
packer/template.go
+6
-2
packer/template_test.go
packer/template_test.go
+2
-2
No files found.
packer/environment.go
View file @
86973282
...
@@ -9,9 +9,9 @@ import (
...
@@ -9,9 +9,9 @@ import (
"strings"
"strings"
)
)
type
BuilderFunc
func
(
name
string
)
Builder
type
BuilderFunc
func
(
name
string
)
(
Builder
,
error
)
type
CommandFunc
func
(
name
string
)
Command
type
CommandFunc
func
(
name
string
)
(
Command
,
error
)
// The environment interface provides access to the configuration and
// The environment interface provides access to the configuration and
// state of a single Packer run.
// state of a single Packer run.
...
@@ -19,8 +19,8 @@ type CommandFunc func(name string) Command
...
@@ -19,8 +19,8 @@ type CommandFunc func(name string) Command
// It allows for things such as executing CLI commands, getting the
// It allows for things such as executing CLI commands, getting the
// list of available builders, and more.
// list of available builders, and more.
type
Environment
interface
{
type
Environment
interface
{
Builder
(
name
string
)
Builder
Builder
(
name
string
)
(
Builder
,
error
)
Cli
(
args
[]
string
)
int
Cli
(
args
[]
string
)
(
int
,
error
)
Ui
()
Ui
Ui
()
Ui
}
}
...
@@ -45,8 +45,8 @@ type EnvironmentConfig struct {
...
@@ -45,8 +45,8 @@ type EnvironmentConfig struct {
// be used to create a new enviroment with NewEnvironment with sane defaults.
// be used to create a new enviroment with NewEnvironment with sane defaults.
func
DefaultEnvironmentConfig
()
*
EnvironmentConfig
{
func
DefaultEnvironmentConfig
()
*
EnvironmentConfig
{
config
:=
&
EnvironmentConfig
{}
config
:=
&
EnvironmentConfig
{}
config
.
BuilderFunc
=
func
(
string
)
Builder
{
return
nil
}
config
.
BuilderFunc
=
func
(
string
)
(
Builder
,
error
)
{
return
nil
,
nil
}
config
.
CommandFunc
=
func
(
string
)
Command
{
return
nil
}
config
.
CommandFunc
=
func
(
string
)
(
Command
,
error
)
{
return
nil
,
nil
}
config
.
Commands
=
make
([]
string
,
0
)
config
.
Commands
=
make
([]
string
,
0
)
config
.
Ui
=
&
ReaderWriterUi
{
os
.
Stdin
,
os
.
Stdout
}
config
.
Ui
=
&
ReaderWriterUi
{
os
.
Stdin
,
os
.
Stdout
}
return
config
return
config
...
@@ -71,16 +71,25 @@ func NewEnvironment(config *EnvironmentConfig) (resultEnv Environment, err error
...
@@ -71,16 +71,25 @@ func NewEnvironment(config *EnvironmentConfig) (resultEnv Environment, err error
// Returns a builder of the given name that is registered with this
// Returns a builder of the given name that is registered with this
// environment.
// environment.
func
(
e
*
coreEnvironment
)
Builder
(
name
string
)
Builder
{
func
(
e
*
coreEnvironment
)
Builder
(
name
string
)
(
b
Builder
,
err
error
)
{
return
e
.
builderFunc
(
name
)
b
,
err
=
e
.
builderFunc
(
name
)
if
err
!=
nil
{
return
}
if
b
==
nil
{
err
=
fmt
.
Errorf
(
"No builder returned for name: %s"
,
name
)
}
return
}
}
// Executes a command as if it was typed on the command-line interface.
// Executes a command as if it was typed on the command-line interface.
// The return value is the exit code of the command.
// The return value is the exit code of the command.
func
(
e
*
coreEnvironment
)
Cli
(
args
[]
string
)
int
{
func
(
e
*
coreEnvironment
)
Cli
(
args
[]
string
)
(
result
int
,
err
error
)
{
if
len
(
args
)
==
0
||
args
[
0
]
==
"--help"
||
args
[
0
]
==
"-h"
{
if
len
(
args
)
==
0
||
args
[
0
]
==
"--help"
||
args
[
0
]
==
"-h"
{
e
.
printHelp
()
e
.
printHelp
()
return
1
return
1
,
nil
}
}
version
:=
args
[
0
]
==
"version"
version
:=
args
[
0
]
==
"version"
...
@@ -99,16 +108,19 @@ func (e *coreEnvironment) Cli(args []string) int {
...
@@ -99,16 +108,19 @@ func (e *coreEnvironment) Cli(args []string) int {
}
}
if
command
==
nil
{
if
command
==
nil
{
command
=
e
.
commandFunc
(
args
[
0
])
command
,
err
=
e
.
commandFunc
(
args
[
0
])
if
err
!=
nil
{
return
}
// If we still don't have a command, show the help.
// If we still don't have a command, show the help.
if
command
==
nil
{
if
command
==
nil
{
e
.
printHelp
()
e
.
printHelp
()
return
1
return
1
,
nil
}
}
}
}
return
command
.
Run
(
e
,
args
[
1
:
])
return
command
.
Run
(
e
,
args
[
1
:
])
,
nil
}
}
// Prints the CLI help to the UI.
// Prints the CLI help to the UI.
...
@@ -131,13 +143,20 @@ func (e *coreEnvironment) printHelp() {
...
@@ -131,13 +143,20 @@ func (e *coreEnvironment) printHelp() {
e
.
ui
.
Say
(
"usage: packer [--version] [--help] <command> [<args>]
\n\n
"
)
e
.
ui
.
Say
(
"usage: packer [--version] [--help] <command> [<args>]
\n\n
"
)
e
.
ui
.
Say
(
"Available commands are:
\n
"
)
e
.
ui
.
Say
(
"Available commands are:
\n
"
)
for
_
,
key
:=
range
e
.
commands
{
for
_
,
key
:=
range
e
.
commands
{
command
:=
e
.
commandFunc
(
key
)
var
synopsis
string
command
,
err
:=
e
.
commandFunc
(
key
)
if
err
!=
nil
{
synopsis
=
fmt
.
Sprintf
(
"Error loading command: %s"
,
err
.
Error
())
}
else
{
synopsis
=
command
.
Synopsis
()
}
// Pad the key with spaces so that they're all the same width
// Pad the key with spaces so that they're all the same width
key
=
fmt
.
Sprintf
(
"%v%v"
,
key
,
strings
.
Repeat
(
" "
,
maxKeyLen
-
len
(
key
)))
key
=
fmt
.
Sprintf
(
"%v%v"
,
key
,
strings
.
Repeat
(
" "
,
maxKeyLen
-
len
(
key
)))
// Output the command and the synopsis
// Output the command and the synopsis
e
.
ui
.
Say
(
" %v %v
\n
"
,
key
,
command
.
Synopsis
()
)
e
.
ui
.
Say
(
" %v %v
\n
"
,
key
,
synopsis
)
}
}
}
}
...
...
packer/environment_test.go
View file @
86973282
...
@@ -3,6 +3,7 @@ package packer
...
@@ -3,6 +3,7 @@ package packer
import
(
import
(
"bytes"
"bytes"
"cgl.tideland.biz/asserts"
"cgl.tideland.biz/asserts"
"fmt"
"os"
"os"
"strings"
"strings"
"testing"
"testing"
...
@@ -58,10 +59,12 @@ func TestEnvironment_Builder(t *testing.T) {
...
@@ -58,10 +59,12 @@ func TestEnvironment_Builder(t *testing.T) {
builders
[
"foo"
]
=
builder
builders
[
"foo"
]
=
builder
config
:=
DefaultEnvironmentConfig
()
config
:=
DefaultEnvironmentConfig
()
config
.
BuilderFunc
=
func
(
n
string
)
Builder
{
return
builders
[
n
]
}
config
.
BuilderFunc
=
func
(
n
string
)
(
Builder
,
error
)
{
return
builders
[
n
],
nil
}
env
,
_
:=
NewEnvironment
(
config
)
env
,
_
:=
NewEnvironment
(
config
)
assert
.
Equal
(
env
.
Builder
(
"foo"
),
builder
,
"should return correct builder"
)
returnedBuilder
,
err
:=
env
.
Builder
(
"foo"
)
assert
.
Nil
(
err
,
"should be no error"
)
assert
.
Equal
(
returnedBuilder
,
builder
,
"should return correct builder"
)
}
}
func
TestEnvironment_Cli_CallsRun
(
t
*
testing
.
T
)
{
func
TestEnvironment_Cli_CallsRun
(
t
*
testing
.
T
)
{
...
@@ -73,10 +76,12 @@ func TestEnvironment_Cli_CallsRun(t *testing.T) {
...
@@ -73,10 +76,12 @@ func TestEnvironment_Cli_CallsRun(t *testing.T) {
config
:=
&
EnvironmentConfig
{}
config
:=
&
EnvironmentConfig
{}
config
.
Commands
=
[]
string
{
"foo"
}
config
.
Commands
=
[]
string
{
"foo"
}
config
.
CommandFunc
=
func
(
n
string
)
Command
{
return
commands
[
n
]
}
config
.
CommandFunc
=
func
(
n
string
)
(
Command
,
error
)
{
return
commands
[
n
],
nil
}
env
,
_
:=
NewEnvironment
(
config
)
env
,
_
:=
NewEnvironment
(
config
)
assert
.
Equal
(
env
.
Cli
([]
string
{
"foo"
,
"bar"
,
"baz"
}),
0
,
"runs foo command"
)
exitCode
,
err
:=
env
.
Cli
([]
string
{
"foo"
,
"bar"
,
"baz"
})
assert
.
Nil
(
err
,
"should be no error"
)
assert
.
Equal
(
exitCode
,
0
,
"runs foo command"
)
assert
.
True
(
command
.
runCalled
,
"run should've been called"
)
assert
.
True
(
command
.
runCalled
,
"run should've been called"
)
assert
.
Equal
(
command
.
runEnv
,
env
,
"should've ran with env"
)
assert
.
Equal
(
command
.
runEnv
,
env
,
"should've ran with env"
)
assert
.
Equal
(
command
.
runArgs
,
[]
string
{
"bar"
,
"baz"
},
"should have right args"
)
assert
.
Equal
(
command
.
runArgs
,
[]
string
{
"bar"
,
"baz"
},
"should have right args"
)
...
@@ -87,7 +92,8 @@ func TestEnvironment_DefaultCli_Empty(t *testing.T) {
...
@@ -87,7 +92,8 @@ func TestEnvironment_DefaultCli_Empty(t *testing.T) {
defaultEnv
:=
testEnvironment
()
defaultEnv
:=
testEnvironment
()
assert
.
Equal
(
defaultEnv
.
Cli
([]
string
{}),
1
,
"CLI with no args"
)
exitCode
,
_
:=
defaultEnv
.
Cli
([]
string
{})
assert
.
Equal
(
exitCode
,
1
,
"CLI with no args"
)
}
}
func
TestEnvironment_DefaultCli_Help
(
t
*
testing
.
T
)
{
func
TestEnvironment_DefaultCli_Help
(
t
*
testing
.
T
)
{
...
@@ -104,11 +110,13 @@ func TestEnvironment_DefaultCli_Help(t *testing.T) {
...
@@ -104,11 +110,13 @@ func TestEnvironment_DefaultCli_Help(t *testing.T) {
}
}
// Test "--help"
// Test "--help"
assert
.
Equal
(
defaultEnv
.
Cli
([]
string
{
"--help"
}),
1
,
"--help should print"
)
exitCode
,
_
:=
defaultEnv
.
Cli
([]
string
{
"--help"
})
assert
.
Equal
(
exitCode
,
1
,
"--help should print"
)
testOutput
()
testOutput
()
// Test "-h"
// Test "-h"
assert
.
Equal
(
defaultEnv
.
Cli
([]
string
{
"-h"
}),
1
,
"--help should print"
)
exitCode
,
_
=
defaultEnv
.
Cli
([]
string
{
"--help"
})
assert
.
Equal
(
exitCode
,
1
,
"--help should print"
)
testOutput
()
testOutput
()
}
}
...
@@ -117,17 +125,20 @@ func TestEnvironment_DefaultCli_Version(t *testing.T) {
...
@@ -117,17 +125,20 @@ func TestEnvironment_DefaultCli_Version(t *testing.T) {
defaultEnv
:=
testEnvironment
()
defaultEnv
:=
testEnvironment
()
// Test the basic version options
versionCommands
:=
[]
string
{
"version"
,
"--version"
,
"-v"
}
assert
.
Equal
(
defaultEnv
.
Cli
([]
string
{
"version"
}),
0
,
"version should work"
)
for
_
,
command
:=
range
versionCommands
{
assert
.
Equal
(
defaultEnv
.
Cli
([]
string
{
"--version"
}),
0
,
"--version should work"
)
exitCode
,
_
:=
defaultEnv
.
Cli
([]
string
{
command
}
)
assert
.
Equal
(
defaultEnv
.
Cli
([]
string
{
"-v"
}),
0
,
"-v should work"
)
assert
.
Equal
(
exitCode
,
0
,
fmt
.
Sprintf
(
"%s should work"
,
command
)
)
// Test the --version and -v can appear anywhere
// Test the --version and -v can appear anywhere
assert
.
Equal
(
defaultEnv
.
Cli
([]
string
{
"bad"
,
"-v"
}),
0
,
"-v should work anywhere"
)
exitCode
,
_
=
defaultEnv
.
Cli
([]
string
{
"bad"
,
command
})
assert
.
Equal
(
defaultEnv
.
Cli
([]
string
{
"bad"
,
"--version"
}),
0
,
"--version should work anywhere"
)
// Test that "version" can't appear anywhere
if
command
!=
"version"
{
assert
.
Equal
(
defaultEnv
.
Cli
([]
string
{
"bad"
,
"version"
}),
1
,
"version should NOT work anywhere"
)
assert
.
Equal
(
exitCode
,
0
,
fmt
.
Sprintf
(
"%s should work anywhere"
,
command
))
}
else
{
assert
.
Equal
(
exitCode
,
1
,
fmt
.
Sprintf
(
"%s should NOT work anywhere"
,
command
))
}
}
}
}
func
TestEnvironment_SettingUi
(
t
*
testing
.
T
)
{
func
TestEnvironment_SettingUi
(
t
*
testing
.
T
)
{
...
...
packer/rpc/environment.go
View file @
86973282
...
@@ -21,18 +21,25 @@ type EnvironmentCliArgs struct {
...
@@ -21,18 +21,25 @@ type EnvironmentCliArgs struct {
Args
[]
string
Args
[]
string
}
}
func
(
e
*
Environment
)
Builder
(
name
string
)
packer
.
Builder
{
func
(
e
*
Environment
)
Builder
(
name
string
)
(
b
packer
.
Builder
,
err
error
)
{
var
reply
string
var
reply
string
e
.
client
.
Call
(
"Environment.Builder"
,
name
,
&
reply
)
err
=
e
.
client
.
Call
(
"Environment.Builder"
,
name
,
&
reply
)
if
err
!=
nil
{
return
}
// TODO: error handling
client
,
err
:=
rpc
.
Dial
(
"tcp"
,
reply
)
client
,
_
:=
rpc
.
Dial
(
"tcp"
,
reply
)
if
err
!=
nil
{
return
&
Builder
{
client
}
return
}
b
=
&
Builder
{
client
}
return
}
}
func
(
e
*
Environment
)
Cli
(
args
[]
string
)
(
result
int
)
{
func
(
e
*
Environment
)
Cli
(
args
[]
string
)
(
result
int
,
err
error
)
{
rpcArgs
:=
&
EnvironmentCliArgs
{
args
}
rpcArgs
:=
&
EnvironmentCliArgs
{
args
}
e
.
client
.
Call
(
"Environment.Cli"
,
rpcArgs
,
&
result
)
e
rr
=
e
.
client
.
Call
(
"Environment.Cli"
,
rpcArgs
,
&
result
)
return
return
}
}
...
@@ -46,7 +53,10 @@ func (e *Environment) Ui() packer.Ui {
...
@@ -46,7 +53,10 @@ func (e *Environment) Ui() packer.Ui {
}
}
func
(
e
*
EnvironmentServer
)
Builder
(
name
*
string
,
reply
*
string
)
error
{
func
(
e
*
EnvironmentServer
)
Builder
(
name
*
string
,
reply
*
string
)
error
{
builder
:=
e
.
env
.
Builder
(
*
name
)
builder
,
err
:=
e
.
env
.
Builder
(
*
name
)
if
err
!=
nil
{
return
err
}
// Wrap it
// Wrap it
server
:=
rpc
.
NewServer
()
server
:=
rpc
.
NewServer
()
...
@@ -56,9 +66,9 @@ func (e *EnvironmentServer) Builder(name *string, reply *string) error {
...
@@ -56,9 +66,9 @@ func (e *EnvironmentServer) Builder(name *string, reply *string) error {
return
nil
return
nil
}
}
func
(
e
*
EnvironmentServer
)
Cli
(
args
*
EnvironmentCliArgs
,
reply
*
int
)
error
{
func
(
e
*
EnvironmentServer
)
Cli
(
args
*
EnvironmentCliArgs
,
reply
*
int
)
(
err
error
)
{
*
reply
=
e
.
env
.
Cli
(
args
.
Args
)
*
reply
,
err
=
e
.
env
.
Cli
(
args
.
Args
)
return
nil
return
}
}
func
(
e
*
EnvironmentServer
)
Ui
(
args
*
interface
{},
reply
*
string
)
error
{
func
(
e
*
EnvironmentServer
)
Ui
(
args
*
interface
{},
reply
*
string
)
error
{
...
...
packer/rpc/environment_test.go
View file @
86973282
...
@@ -18,16 +18,16 @@ type testEnvironment struct {
...
@@ -18,16 +18,16 @@ type testEnvironment struct {
uiCalled
bool
uiCalled
bool
}
}
func
(
e
*
testEnvironment
)
Builder
(
name
string
)
packer
.
Builder
{
func
(
e
*
testEnvironment
)
Builder
(
name
string
)
(
packer
.
Builder
,
error
)
{
e
.
builderCalled
=
true
e
.
builderCalled
=
true
e
.
builderName
=
name
e
.
builderName
=
name
return
testEnvBuilder
return
testEnvBuilder
,
nil
}
}
func
(
e
*
testEnvironment
)
Cli
(
args
[]
string
)
int
{
func
(
e
*
testEnvironment
)
Cli
(
args
[]
string
)
(
int
,
error
)
{
e
.
cliCalled
=
true
e
.
cliCalled
=
true
e
.
cliArgs
=
args
e
.
cliArgs
=
args
return
42
return
42
,
nil
}
}
func
(
e
*
testEnvironment
)
Ui
()
packer
.
Ui
{
func
(
e
*
testEnvironment
)
Ui
()
packer
.
Ui
{
...
@@ -52,7 +52,7 @@ func TestEnvironmentRPC(t *testing.T) {
...
@@ -52,7 +52,7 @@ func TestEnvironmentRPC(t *testing.T) {
eClient
:=
&
Environment
{
client
}
eClient
:=
&
Environment
{
client
}
// Test Builder
// Test Builder
builder
:=
eClient
.
Builder
(
"foo"
)
builder
,
_
:=
eClient
.
Builder
(
"foo"
)
assert
.
True
(
e
.
builderCalled
,
"Builder should be called"
)
assert
.
True
(
e
.
builderCalled
,
"Builder should be called"
)
assert
.
Equal
(
e
.
builderName
,
"foo"
,
"Correct name for Builder"
)
assert
.
Equal
(
e
.
builderName
,
"foo"
,
"Correct name for Builder"
)
...
@@ -61,7 +61,7 @@ func TestEnvironmentRPC(t *testing.T) {
...
@@ -61,7 +61,7 @@ func TestEnvironmentRPC(t *testing.T) {
// Test Cli
// Test Cli
cliArgs
:=
[]
string
{
"foo"
,
"bar"
}
cliArgs
:=
[]
string
{
"foo"
,
"bar"
}
result
:=
eClient
.
Cli
(
cliArgs
)
result
,
_
:=
eClient
.
Cli
(
cliArgs
)
assert
.
True
(
e
.
cliCalled
,
"CLI should be called"
)
assert
.
True
(
e
.
cliCalled
,
"CLI should be called"
)
assert
.
Equal
(
e
.
cliArgs
,
cliArgs
,
"args should match"
)
assert
.
Equal
(
e
.
cliArgs
,
cliArgs
,
"args should match"
)
assert
.
Equal
(
result
,
42
,
"result shuld be 42"
)
assert
.
Equal
(
result
,
42
,
"result shuld be 42"
)
...
...
packer/template.go
View file @
86973282
...
@@ -102,9 +102,13 @@ func (t *Template) Build(name string, bf BuilderFunc) (b Build, err error) {
...
@@ -102,9 +102,13 @@ func (t *Template) Build(name string, bf BuilderFunc) (b Build, err error) {
return
return
}
}
builder
:=
bf
(
builderConfig
.
builderName
)
builder
,
err
:=
bf
(
builderConfig
.
builderName
)
if
err
!=
nil
{
return
}
if
builder
==
nil
{
if
builder
==
nil
{
err
=
fmt
.
Errorf
(
"Builder
could not be found: %s"
,
builderConfig
.
builderN
ame
)
err
=
fmt
.
Errorf
(
"Builder
not found: %s"
,
n
ame
)
return
return
}
}
...
...
packer/template_test.go
View file @
86973282
...
@@ -157,7 +157,7 @@ func TestTemplate_BuildUnknownBuilder(t *testing.T) {
...
@@ -157,7 +157,7 @@ func TestTemplate_BuildUnknownBuilder(t *testing.T) {
template
,
err
:=
ParseTemplate
([]
byte
(
data
))
template
,
err
:=
ParseTemplate
([]
byte
(
data
))
assert
.
Nil
(
err
,
"should not error"
)
assert
.
Nil
(
err
,
"should not error"
)
builderFactory
:=
func
(
string
)
Builder
{
return
nil
}
builderFactory
:=
func
(
string
)
(
Builder
,
error
)
{
return
nil
,
nil
}
build
,
err
:=
template
.
Build
(
"test1"
,
builderFactory
)
build
,
err
:=
template
.
Build
(
"test1"
,
builderFactory
)
assert
.
Nil
(
build
,
"build should be nil"
)
assert
.
Nil
(
build
,
"build should be nil"
)
assert
.
NotNil
(
err
,
"should have error"
)
assert
.
NotNil
(
err
,
"should have error"
)
...
@@ -191,7 +191,7 @@ func TestTemplate_Build(t *testing.T) {
...
@@ -191,7 +191,7 @@ func TestTemplate_Build(t *testing.T) {
"test-builder"
:
builder
,
"test-builder"
:
builder
,
}
}
builderFactory
:=
func
(
n
string
)
Builder
{
return
builderMap
[
n
]
}
builderFactory
:=
func
(
n
string
)
(
Builder
,
error
)
{
return
builderMap
[
n
],
nil
}
// Get the build, verifying we can get it without issue, but also
// Get the build, verifying we can get it without issue, but also
// that the proper builder was looked up and used for the build.
// that the proper builder was looked up and used for the build.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment