Commit bbafcfa9 authored by Mitchell Hashimoto's avatar Mitchell Hashimoto

packer, etc: added Help method to Command interface

This will be used for long-form help when "packer help foo"
or "packer foo --help" is called.
parent cf732a91
......@@ -10,6 +10,10 @@ import (
type Command byte
func (Command) Help() string {
return "help"
}
func (Command) Run(env packer.Environment, args []string) int {
if len(args) != 1 {
env.Ui().Error("A single template argument is required.")
......
......@@ -22,6 +22,13 @@ func testEnvironment() packer.Environment {
return env
}
func TestCommand_Implements(t *testing.T) {
assert := asserts.NewTestingAsserts(t, true)
var actual packer.Command
assert.Implementor(new(Command), &actual, "should be a Command")
}
func TestCommand_Run_NoArgs(t *testing.T) {
assert := asserts.NewTestingAsserts(t, true)
command := new(Command)
......
......@@ -6,14 +6,18 @@ package packer
//
// The mapping of command names to command interfaces is in the
// Environment struct.
//
// Run should run the actual command with the given environmet and
// command-line arguments. It should return the exit status when it is
// finished.
//
// Synopsis should return a one-line, short synopsis of the command.
// This should be less than 50 characters ideally.
type Command interface {
// Help should return long-form help text that includes the command-line
// usage, a brief few sentences explaining the function of the command,
// and the complete list of flags the command accepts.
Help() string
// Run should run the actual command with the given environmet and
// command-line arguments. It should return the exit status when it is
// finished.
Run(env Environment, args []string) int
// Synopsis should return a one-line, short synopsis of the command.
// This should be less than 50 characters ideally.
Synopsis() string
}
......@@ -6,6 +6,10 @@ type TestCommand struct {
runEnv Environment
}
func (tc *TestCommand) Help() string {
return "bar"
}
func (tc *TestCommand) Run(env Environment, args []string) int {
tc.runCalled = true
tc.runArgs = args
......
......@@ -13,6 +13,16 @@ type cmdCommand struct {
client *client
}
func (c *cmdCommand) Help() (result string) {
defer func() {
r := recover()
c.checkExit(r, func() { result = "" })
}()
result = c.command.Help()
return
}
func (c *cmdCommand) Run(e packer.Environment, args []string) (exitCode int) {
defer func() {
r := recover()
......
......@@ -7,11 +7,12 @@ import (
"testing"
)
// TODO: Test command cleanup functionality
// TODO: Test timeout functionality
type helperCommand byte
func (helperCommand) Help() string {
return "2"
}
func (helperCommand) Run(packer.Environment, []string) int {
return 42
}
......@@ -37,6 +38,9 @@ func TestCommand_Good(t *testing.T) {
if command != nil {
result := command.Synopsis()
assert.Equal(result, "1", "should return result")
result = command.Help()
assert.Equal(result, "2", "should return result")
}
}
......
......@@ -28,6 +28,15 @@ func Command(client *rpc.Client) *command {
return &command{client}
}
func (c *command) Help() (result string) {
err := c.client.Call("Command.Help", new(interface{}), &result)
if err != nil {
panic(err)
}
return
}
func (c *command) Run(env packer.Environment, args []string) (result int) {
// Create and start the server for the Environment
server := rpc.NewServer()
......@@ -51,6 +60,11 @@ func (c *command) Synopsis() (result string) {
return
}
func (c *CommandServer) Help(args *interface{}, reply *string) error {
*reply = c.command.Help()
return nil
}
func (c *CommandServer) Run(args *CommandRunArgs, reply *int) error {
client, err := rpc.Dial("tcp", args.RPCAddress)
if err != nil {
......
......@@ -13,6 +13,10 @@ type TestCommand struct {
runEnv packer.Environment
}
func (tc *TestCommand) Help() string {
return "bar"
}
func (tc *TestCommand) Run(env packer.Environment, args []string) int {
tc.runCalled = true
tc.runArgs = args
......@@ -42,6 +46,10 @@ func TestRPCCommand(t *testing.T) {
clientComm := Command(client)
//Test Help
help := clientComm.Help()
assert.Equal(help, "bar", "helps hould be correct")
// Test run
runArgs := []string{"foo", "bar"}
testEnv := &testEnvironment{}
......@@ -59,3 +67,12 @@ func TestRPCCommand(t *testing.T) {
synopsis := clientComm.Synopsis()
assert.Equal(synopsis, "foo", "Synopsis should be correct")
}
func TestCommand_Implements(t *testing.T) {
assert := asserts.NewTestingAsserts(t, true)
var r packer.Command
c := Command(nil)
assert.Implementor(c, &r, "should be a Builder")
}
......@@ -7,7 +7,13 @@ const Version = "0.1.0.dev"
type versionCommand byte
// Implement the Command interface by simply showing the version
func (versionCommand) Help() string {
return `usage: packer version
Outputs the version of Packer that is running. There are no additional
command-line flags for this command.`
}
func (versionCommand) Run(env Environment, args []string) int {
env.Ui().Say(fmt.Sprintf("Packer v%v\n", Version))
return 0
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment