Engine: builtin command 'commands' returns a list of registered commands
| ... | ... |
@@ -9,6 +9,7 @@ import ( |
| 9 | 9 |
"os" |
| 10 | 10 |
"path/filepath" |
| 11 | 11 |
"runtime" |
| 12 |
+ "sort" |
|
| 12 | 13 |
"strings" |
| 13 | 14 |
) |
| 14 | 15 |
|
| ... | ... |
@@ -29,6 +30,10 @@ func Register(name string, handler Handler) error {
|
| 29 | 29 |
return nil |
| 30 | 30 |
} |
| 31 | 31 |
|
| 32 |
+func unregister(name string) {
|
|
| 33 |
+ delete(globalHandlers, name) |
|
| 34 |
+} |
|
| 35 |
+ |
|
| 32 | 36 |
// The Engine is the core of Docker. |
| 33 | 37 |
// It acts as a store for *containers*, and allows manipulation of these |
| 34 | 38 |
// containers by executing *jobs*. |
| ... | ... |
@@ -106,6 +111,12 @@ func New(root string) (*Engine, error) {
|
| 106 | 106 |
Stderr: os.Stderr, |
| 107 | 107 |
Stdin: os.Stdin, |
| 108 | 108 |
} |
| 109 |
+ eng.Register("commands", func(job *Job) Status {
|
|
| 110 |
+ for _, name := range eng.commands() {
|
|
| 111 |
+ job.Printf("%s\n", name)
|
|
| 112 |
+ } |
|
| 113 |
+ return StatusOK |
|
| 114 |
+ }) |
|
| 109 | 115 |
// Copy existing global handlers |
| 110 | 116 |
for k, v := range globalHandlers {
|
| 111 | 117 |
eng.handlers[k] = v |
| ... | ... |
@@ -117,6 +128,17 @@ func (eng *Engine) String() string {
|
| 117 | 117 |
return fmt.Sprintf("%s|%s", eng.Root(), eng.id[:8])
|
| 118 | 118 |
} |
| 119 | 119 |
|
| 120 |
+// Commands returns a list of all currently registered commands, |
|
| 121 |
+// sorted alphabetically. |
|
| 122 |
+func (eng *Engine) commands() []string {
|
|
| 123 |
+ names := make([]string, 0, len(eng.handlers)) |
|
| 124 |
+ for name := range eng.handlers {
|
|
| 125 |
+ names = append(names, name) |
|
| 126 |
+ } |
|
| 127 |
+ sort.Strings(names) |
|
| 128 |
+ return names |
|
| 129 |
+} |
|
| 130 |
+ |
|
| 120 | 131 |
// Job creates a new job which can later be executed. |
| 121 | 132 |
// This function mimics `Command` from the standard os/exec package. |
| 122 | 133 |
func (eng *Engine) Job(name string, args ...string) *Job {
|
| ... | ... |
@@ -1,6 +1,7 @@ |
| 1 | 1 |
package engine |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
+ "bytes" |
|
| 4 | 5 |
"io/ioutil" |
| 5 | 6 |
"os" |
| 6 | 7 |
"path" |
| ... | ... |
@@ -17,6 +18,8 @@ func TestRegister(t *testing.T) {
|
| 17 | 17 |
if err := Register("dummy1", nil); err == nil {
|
| 18 | 18 |
t.Fatalf("Expecting error, got none")
|
| 19 | 19 |
} |
| 20 |
+ // Register is global so let's cleanup to avoid conflicts |
|
| 21 |
+ defer unregister("dummy1")
|
|
| 20 | 22 |
|
| 21 | 23 |
eng := newTestEngine(t) |
| 22 | 24 |
|
| ... | ... |
@@ -33,6 +36,7 @@ func TestRegister(t *testing.T) {
|
| 33 | 33 |
if err := eng.Register("dummy2", nil); err == nil {
|
| 34 | 34 |
t.Fatalf("Expecting error, got none")
|
| 35 | 35 |
} |
| 36 |
+ defer unregister("dummy2")
|
|
| 36 | 37 |
} |
| 37 | 38 |
|
| 38 | 39 |
func TestJob(t *testing.T) {
|
| ... | ... |
@@ -49,6 +53,7 @@ func TestJob(t *testing.T) {
|
| 49 | 49 |
} |
| 50 | 50 |
|
| 51 | 51 |
eng.Register("dummy2", h)
|
| 52 |
+ defer unregister("dummy2")
|
|
| 52 | 53 |
job2 := eng.Job("dummy2", "--level=awesome")
|
| 53 | 54 |
|
| 54 | 55 |
if job2.handler == nil {
|
| ... | ... |
@@ -60,6 +65,24 @@ func TestJob(t *testing.T) {
|
| 60 | 60 |
} |
| 61 | 61 |
} |
| 62 | 62 |
|
| 63 |
+func TestEngineCommands(t *testing.T) {
|
|
| 64 |
+ eng := newTestEngine(t) |
|
| 65 |
+ defer os.RemoveAll(eng.Root()) |
|
| 66 |
+ handler := func(job *Job) Status { return StatusOK }
|
|
| 67 |
+ eng.Register("foo", handler)
|
|
| 68 |
+ eng.Register("bar", handler)
|
|
| 69 |
+ eng.Register("echo", handler)
|
|
| 70 |
+ eng.Register("die", handler)
|
|
| 71 |
+ var output bytes.Buffer |
|
| 72 |
+ commands := eng.Job("commands")
|
|
| 73 |
+ commands.Stdout.Add(&output) |
|
| 74 |
+ commands.Run() |
|
| 75 |
+ expected := "bar\ncommands\ndie\necho\nfoo\n" |
|
| 76 |
+ if result := output.String(); result != expected {
|
|
| 77 |
+ t.Fatalf("Unexpected output:\nExpected = %v\nResult = %v\n", expected, result)
|
|
| 78 |
+ } |
|
| 79 |
+} |
|
| 80 |
+ |
|
| 63 | 81 |
func TestEngineRoot(t *testing.T) {
|
| 64 | 82 |
tmp, err := ioutil.TempDir("", "docker-test-TestEngineCreateDir")
|
| 65 | 83 |
if err != nil {
|