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
3e1f4ae1
Commit
3e1f4ae1
authored
Oct 27, 2014
by
Mitchell Hashimoto
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
packer: remove Command
parent
fa36cf82
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
0 additions
and
342 deletions
+0
-342
packer/command.go
packer/command.go
+0
-23
packer/command_test.go
packer/command_test.go
+0
-22
packer/environment.go
packer/environment.go
+0
-176
packer/environment_test.go
packer/environment_test.go
+0
-121
No files found.
packer/command.go
deleted
100644 → 0
View file @
fa36cf82
package
packer
// A command is a runnable sub-command of the `packer` application.
// When `packer` is called with the proper subcommand, this will be
// called.
//
// The mapping of command names to command interfaces is in the
// Environment struct.
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
}
packer/command_test.go
deleted
100644 → 0
View file @
fa36cf82
package
packer
type
TestCommand
struct
{
runArgs
[]
string
runCalled
bool
runEnv
Environment
}
func
(
tc
*
TestCommand
)
Help
()
string
{
return
"bar"
}
func
(
tc
*
TestCommand
)
Run
(
env
Environment
,
args
[]
string
)
int
{
tc
.
runCalled
=
true
tc
.
runArgs
=
args
tc
.
runEnv
=
env
return
0
}
func
(
tc
*
TestCommand
)
Synopsis
()
string
{
return
"foo"
}
packer/environment.go
View file @
3e1f4ae1
...
...
@@ -4,19 +4,12 @@ package packer
import
(
"errors"
"fmt"
"log"
"os"
"sort"
"strings"
"sync"
)
// The function type used to lookup Builder implementations.
type
BuilderFunc
func
(
name
string
)
(
Builder
,
error
)
// The function type used to lookup Command implementations.
type
CommandFunc
func
(
name
string
)
(
Command
,
error
)
// The function type used to lookup Hook implementations.
type
HookFunc
func
(
name
string
)
(
Hook
,
error
)
...
...
@@ -31,7 +24,6 @@ type ProvisionerFunc func(name string) (Provisioner, error)
// commands, etc.
type
ComponentFinder
struct
{
Builder
BuilderFunc
Command
CommandFunc
Hook
HookFunc
PostProcessor
PostProcessorFunc
Provisioner
ProvisionerFunc
...
...
@@ -45,7 +37,6 @@ type ComponentFinder struct {
type
Environment
interface
{
Builder
(
string
)
(
Builder
,
error
)
Cache
()
Cache
Cli
([]
string
)
(
int
,
error
)
Hook
(
string
)
(
Hook
,
error
)
PostProcessor
(
string
)
(
PostProcessor
,
error
)
Provisioner
(
string
)
(
Provisioner
,
error
)
...
...
@@ -56,7 +47,6 @@ type Environment interface {
// environment.
type
coreEnvironment
struct
{
cache
Cache
commands
[]
string
components
ComponentFinder
ui
Ui
}
...
...
@@ -64,22 +54,14 @@ type coreEnvironment struct {
// This struct configures new environments.
type
EnvironmentConfig
struct
{
Cache
Cache
Commands
[]
string
Components
ComponentFinder
Ui
Ui
}
type
helpCommandEntry
struct
{
i
int
key
string
synopsis
string
}
// DefaultEnvironmentConfig returns a default EnvironmentConfig that can
// be used to create a new enviroment with NewEnvironment with sane defaults.
func
DefaultEnvironmentConfig
()
*
EnvironmentConfig
{
config
:=
&
EnvironmentConfig
{}
config
.
Commands
=
make
([]
string
,
0
)
config
.
Ui
=
&
BasicUi
{
Reader
:
os
.
Stdin
,
Writer
:
os
.
Stdout
,
...
...
@@ -98,7 +80,6 @@ func NewEnvironment(config *EnvironmentConfig) (resultEnv Environment, err error
env
:=
&
coreEnvironment
{}
env
.
cache
=
config
.
Cache
env
.
commands
=
config
.
Commands
env
.
components
=
config
.
Components
env
.
ui
=
config
.
Ui
...
...
@@ -109,10 +90,6 @@ func NewEnvironment(config *EnvironmentConfig) (resultEnv Environment, err error
env
.
components
.
Builder
=
func
(
string
)
(
Builder
,
error
)
{
return
nil
,
nil
}
}
if
env
.
components
.
Command
==
nil
{
env
.
components
.
Command
=
func
(
string
)
(
Command
,
error
)
{
return
nil
,
nil
}
}
if
env
.
components
.
Hook
==
nil
{
env
.
components
.
Hook
=
func
(
string
)
(
Hook
,
error
)
{
return
nil
,
nil
}
}
...
...
@@ -199,159 +176,6 @@ func (e *coreEnvironment) Provisioner(name string) (p Provisioner, err error) {
return
}
// Executes a command as if it was typed on the command-line interface.
// The return value is the exit code of the command.
func
(
e
*
coreEnvironment
)
Cli
(
args
[]
string
)
(
result
int
,
err
error
)
{
log
.
Printf
(
"Environment.Cli: %#v
\n
"
,
args
)
// If we have no arguments, just short-circuit here and print the help
if
len
(
args
)
==
0
{
e
.
printHelp
()
return
1
,
nil
}
// This variable will track whether or not we're supposed to print
// the help or not.
isHelp
:=
false
for
_
,
arg
:=
range
args
{
if
arg
==
"-h"
||
arg
==
"--help"
{
isHelp
=
true
break
}
}
// Trim up to the command name
for
i
,
v
:=
range
args
{
if
len
(
v
)
>
0
&&
v
[
0
]
!=
'-'
{
args
=
args
[
i
:
]
break
}
}
log
.
Printf
(
"command + args: %#v"
,
args
)
version
:=
args
[
0
]
==
"version"
if
!
version
{
for
_
,
arg
:=
range
args
{
if
arg
==
"--version"
||
arg
==
"-v"
{
version
=
true
break
}
}
}
var
command
Command
if
version
{
command
=
new
(
versionCommand
)
}
if
command
==
nil
{
command
,
err
=
e
.
components
.
Command
(
args
[
0
])
if
err
!=
nil
{
return
}
// If we still don't have a command, show the help.
if
command
==
nil
{
e
.
ui
.
Error
(
fmt
.
Sprintf
(
"Unknown command: %s
\n
"
,
args
[
0
]))
e
.
printHelp
()
return
1
,
nil
}
}
// If we're supposed to print help, then print the help of the
// command rather than running it.
if
isHelp
{
e
.
ui
.
Say
(
command
.
Help
())
return
0
,
nil
}
log
.
Printf
(
"Executing command: %s
\n
"
,
args
[
0
])
return
command
.
Run
(
e
,
args
[
1
:
]),
nil
}
// Prints the CLI help to the UI.
func
(
e
*
coreEnvironment
)
printHelp
()
{
// Created a sorted slice of the map keys and record the longest
// command name so we can better format the output later.
maxKeyLen
:=
0
for
_
,
command
:=
range
e
.
commands
{
if
len
(
command
)
>
maxKeyLen
{
maxKeyLen
=
len
(
command
)
}
}
// Sort the keys
sort
.
Strings
(
e
.
commands
)
// Create the communication/sync mechanisms to get the synopsis' of
// the various commands. We do this in parallel since the overhead
// of the subprocess underneath is very expensive and this speeds things
// up an incredible amount.
var
wg
sync
.
WaitGroup
ch
:=
make
(
chan
*
helpCommandEntry
)
for
i
,
key
:=
range
e
.
commands
{
wg
.
Add
(
1
)
// Get the synopsis in a goroutine since it may take awhile
// to subprocess out.
go
func
(
i
int
,
key
string
)
{
defer
wg
.
Done
()
var
synopsis
string
command
,
err
:=
e
.
components
.
Command
(
key
)
if
err
!=
nil
{
synopsis
=
fmt
.
Sprintf
(
"Error loading command: %s"
,
err
.
Error
())
}
else
if
command
==
nil
{
return
}
else
{
synopsis
=
command
.
Synopsis
()
}
// Pad the key with spaces so that they're all the same width
key
=
fmt
.
Sprintf
(
"%s%s"
,
key
,
strings
.
Repeat
(
" "
,
maxKeyLen
-
len
(
key
)))
// Output the command and the synopsis
ch
<-
&
helpCommandEntry
{
i
:
i
,
key
:
key
,
synopsis
:
synopsis
,
}
}(
i
,
key
)
}
e
.
ui
.
Say
(
"usage: packer [--version] [--help] <command> [<args>]
\n
"
)
e
.
ui
.
Say
(
"Available commands are:"
)
// Make a goroutine that just waits for all the synopsis gathering
// to complete, and then output it.
synopsisDone
:=
make
(
chan
struct
{})
go
func
()
{
defer
close
(
synopsisDone
)
entries
:=
make
([]
string
,
len
(
e
.
commands
))
for
entry
:=
range
ch
{
e
.
ui
.
Machine
(
"command"
,
entry
.
key
,
entry
.
synopsis
)
message
:=
fmt
.
Sprintf
(
" %s %s"
,
entry
.
key
,
entry
.
synopsis
)
entries
[
entry
.
i
]
=
message
}
for
_
,
message
:=
range
entries
{
if
message
!=
""
{
e
.
ui
.
Say
(
message
)
}
}
}()
// Wait to complete getting the synopsis' then close the channel
wg
.
Wait
()
close
(
ch
)
<-
synopsisDone
e
.
ui
.
Say
(
"
\n
Globally recognized options:"
)
e
.
ui
.
Say
(
" -machine-readable Machine-readable output format."
)
}
// Returns the UI for the environment. The UI is the interface that should
// be used for all communication with the outside world.
func
(
e
*
coreEnvironment
)
Ui
()
Ui
{
...
...
packer/environment_test.go
View file @
3e1f4ae1
...
...
@@ -6,8 +6,6 @@ import (
"io/ioutil"
"log"
"os"
"reflect"
"strings"
"testing"
)
...
...
@@ -43,13 +41,6 @@ func testEnvironment() Environment {
return
env
}
func
TestEnvironment_DefaultConfig_Commands
(
t
*
testing
.
T
)
{
config
:=
DefaultEnvironmentConfig
()
if
len
(
config
.
Commands
)
!=
0
{
t
.
Fatalf
(
"bad: %#v"
,
config
.
Commands
)
}
}
func
TestEnvironment_DefaultConfig_Ui
(
t
*
testing
.
T
)
{
config
:=
DefaultEnvironmentConfig
()
if
config
.
Ui
==
nil
{
...
...
@@ -91,7 +82,6 @@ func TestEnvironment_NilComponents(t *testing.T) {
// anything but if there is a panic in the test then yeah, something
// went wrong.
env
.
Builder
(
"foo"
)
env
.
Cli
([]
string
{
"foo"
})
env
.
Hook
(
"foo"
)
env
.
PostProcessor
(
"foo"
)
env
.
Provisioner
(
"foo"
)
...
...
@@ -154,117 +144,6 @@ func TestEnvironment_Cache(t *testing.T) {
}
}
func
TestEnvironment_Cli_Error
(
t
*
testing
.
T
)
{
config
:=
DefaultEnvironmentConfig
()
config
.
Components
.
Command
=
func
(
n
string
)
(
Command
,
error
)
{
return
nil
,
errors
.
New
(
"foo"
)
}
env
,
_
:=
NewEnvironment
(
config
)
_
,
err
:=
env
.
Cli
([]
string
{
"foo"
})
if
err
==
nil
{
t
.
Fatal
(
"should have error"
)
}
if
err
.
Error
()
!=
"foo"
{
t
.
Fatalf
(
"bad: %s"
,
err
)
}
}
func
TestEnvironment_Cli_CallsRun
(
t
*
testing
.
T
)
{
command
:=
&
TestCommand
{}
commands
:=
make
(
map
[
string
]
Command
)
commands
[
"foo"
]
=
command
config
:=
&
EnvironmentConfig
{}
config
.
Commands
=
[]
string
{
"foo"
}
config
.
Components
.
Command
=
func
(
n
string
)
(
Command
,
error
)
{
return
commands
[
n
],
nil
}
env
,
_
:=
NewEnvironment
(
config
)
exitCode
,
err
:=
env
.
Cli
([]
string
{
"foo"
,
"bar"
,
"baz"
})
if
err
!=
nil
{
t
.
Fatalf
(
"err: %s"
,
err
)
}
if
exitCode
!=
0
{
t
.
Fatalf
(
"bad: %d"
,
exitCode
)
}
if
!
command
.
runCalled
{
t
.
Fatal
(
"command should be run"
)
}
if
command
.
runEnv
!=
env
{
t
.
Fatalf
(
"bad env: %#v"
,
command
.
runEnv
)
}
if
!
reflect
.
DeepEqual
(
command
.
runArgs
,
[]
string
{
"bar"
,
"baz"
})
{
t
.
Fatalf
(
"bad: %#v"
,
command
.
runArgs
)
}
}
func
TestEnvironment_DefaultCli_Empty
(
t
*
testing
.
T
)
{
defaultEnv
:=
testEnvironment
()
// Test with no args
exitCode
,
_
:=
defaultEnv
.
Cli
([]
string
{})
if
exitCode
!=
1
{
t
.
Fatalf
(
"bad: %d"
,
exitCode
)
}
// Test with only blank args
exitCode
,
_
=
defaultEnv
.
Cli
([]
string
{
""
})
if
exitCode
!=
1
{
t
.
Fatalf
(
"bad: %d"
,
exitCode
)
}
}
func
TestEnvironment_DefaultCli_Help
(
t
*
testing
.
T
)
{
defaultEnv
:=
testEnvironment
()
// A little lambda to help us test the output actually contains help
testOutput
:=
func
()
{
buffer
:=
defaultEnv
.
Ui
()
.
(
*
BasicUi
)
.
Writer
.
(
*
bytes
.
Buffer
)
output
:=
buffer
.
String
()
buffer
.
Reset
()
if
!
strings
.
Contains
(
output
,
"usage: packer"
)
{
t
.
Fatalf
(
"should contain help: %#v"
,
output
)
}
}
// Test "--help"
exitCode
,
_
:=
defaultEnv
.
Cli
([]
string
{
"--help"
})
if
exitCode
!=
1
{
t
.
Fatalf
(
"bad: %d"
,
exitCode
)
}
testOutput
()
// Test "-h"
exitCode
,
_
=
defaultEnv
.
Cli
([]
string
{
"--help"
})
if
exitCode
!=
1
{
t
.
Fatalf
(
"bad: %d"
,
exitCode
)
}
testOutput
()
}
func
TestEnvironment_DefaultCli_Version
(
t
*
testing
.
T
)
{
defaultEnv
:=
testEnvironment
()
versionCommands
:=
[]
string
{
"version"
,
"--version"
,
"-v"
}
for
_
,
command
:=
range
versionCommands
{
exitCode
,
_
:=
defaultEnv
.
Cli
([]
string
{
command
})
if
exitCode
!=
0
{
t
.
Fatalf
(
"bad: %d"
,
exitCode
)
}
// Test the --version and -v can appear anywhere
exitCode
,
_
=
defaultEnv
.
Cli
([]
string
{
"bad"
,
command
})
if
command
!=
"version"
{
if
exitCode
!=
0
{
t
.
Fatalf
(
"bad: %d"
,
exitCode
)
}
}
else
{
if
exitCode
!=
1
{
t
.
Fatalf
(
"bad: %d"
,
exitCode
)
}
}
}
}
func
TestEnvironment_Hook
(
t
*
testing
.
T
)
{
hook
:=
&
MockHook
{}
hooks
:=
make
(
map
[
string
]
Hook
)
...
...
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