@@ -14,39 +14,50 @@ import (
14
14
// that plugins declaring support for hooks get passed when
15
15
// being invoked following a CLI command execution.
16
16
type HookPluginData struct {
17
+ // RootCmd is a string representing the matching hook configuration
18
+ // which is currently being invoked. If a hook for `docker context` is
19
+ // configured and the user executes `docker context ls`, the plugin will
20
+ // be invoked with `context`.
17
21
RootCmd string
18
22
Flags map [string ]string
19
23
}
20
24
21
- // RunPluginHooks calls the hook subcommand for all present
22
- // CLI plugins that declare support for hooks in their metadata
23
- // and parses/prints their responses.
24
- func RunPluginHooks (dockerCli command.Cli , rootCmd , subCommand * cobra.Command , plugin string , args []string ) error {
25
- subCmdName := subCommand .Name ()
26
- if plugin != "" {
27
- subCmdName = plugin
28
- }
29
- var flags map [string ]string
30
- if plugin == "" {
31
- flags = getCommandFlags (subCommand )
32
- } else {
33
- flags = getNaiveFlags (args )
34
- }
35
- nextSteps := invokeAndCollectHooks (dockerCli , rootCmd , subCommand , subCmdName , flags )
25
+ // RunCLICommandHooks is the entrypoint into the hooks execution flow after
26
+ // a main CLI command was executed. It calls the hook subcommand for all
27
+ // present CLI plugins that declare support for hooks in their metadata and
28
+ // parses/prints their responses.
29
+ func RunCLICommandHooks (dockerCli command.Cli , rootCmd , subCommand * cobra.Command ) {
30
+ commandName := strings .TrimPrefix (subCommand .CommandPath (), rootCmd .Name ()+ " " )
31
+ flags := getCommandFlags (subCommand )
32
+
33
+ runHooks (dockerCli , rootCmd , subCommand , commandName , flags )
34
+ }
35
+
36
+ // RunPluginHooks is the entrypoint for the hooks execution flow
37
+ // after a plugin command was just executed by the CLI.
38
+ func RunPluginHooks (dockerCli command.Cli , rootCmd , subCommand * cobra.Command , args []string ) {
39
+ commandName := strings .Join (args , " " )
40
+ flags := getNaiveFlags (args )
41
+
42
+ runHooks (dockerCli , rootCmd , subCommand , commandName , flags )
43
+ }
44
+
45
+ func runHooks (dockerCli command.Cli , rootCmd , subCommand * cobra.Command , invokedCommand string , flags map [string ]string ) {
46
+ nextSteps := invokeAndCollectHooks (dockerCli , rootCmd , subCommand , invokedCommand , flags )
36
47
37
48
hooks .PrintNextSteps (dockerCli .Err (), nextSteps )
38
- return nil
39
49
}
40
50
41
- func invokeAndCollectHooks (dockerCli command.Cli , rootCmd , subCmd * cobra.Command , hookCmdName string , flags map [string ]string ) []string {
51
+ func invokeAndCollectHooks (dockerCli command.Cli , rootCmd , subCmd * cobra.Command , subCmdStr string , flags map [string ]string ) []string {
42
52
pluginsCfg := dockerCli .ConfigFile ().Plugins
43
53
if pluginsCfg == nil {
44
54
return nil
45
55
}
46
56
47
57
nextSteps := make ([]string , 0 , len (pluginsCfg ))
48
58
for pluginName , cfg := range pluginsCfg {
49
- if ! registersHook (cfg , hookCmdName ) {
59
+ match , ok := pluginMatch (cfg , subCmdStr )
60
+ if ! ok {
50
61
continue
51
62
}
52
63
@@ -55,7 +66,7 @@ func invokeAndCollectHooks(dockerCli command.Cli, rootCmd, subCmd *cobra.Command
55
66
continue
56
67
}
57
68
58
- hookReturn , err := p .RunHook (hookCmdName , flags )
69
+ hookReturn , err := p .RunHook (match , flags )
59
70
if err != nil {
60
71
// skip misbehaving plugins, but don't halt execution
61
72
continue
@@ -81,18 +92,41 @@ func invokeAndCollectHooks(dockerCli command.Cli, rootCmd, subCmd *cobra.Command
81
92
return nextSteps
82
93
}
83
94
84
- func registersHook (pluginCfg map [string ]string , subCmdName string ) bool {
85
- hookCmdStr , ok := pluginCfg ["hooks" ]
86
- if ! ok {
87
- return false
95
+ // pluginMatch takes a plugin configuration and a string representing the
96
+ // command being executed (such as 'image ls' – the root 'docker' is omitted)
97
+ // and, if the configuration includes a hook for the invoked command, returns
98
+ // the configured hook string.
99
+ func pluginMatch (pluginCfg map [string ]string , subCmd string ) (string , bool ) {
100
+ configuredPluginHooks , ok := pluginCfg ["hooks" ]
101
+ if ! ok || configuredPluginHooks == "" {
102
+ return "" , false
88
103
}
89
- commands := strings .Split (hookCmdStr , "," )
104
+
105
+ commands := strings .Split (configuredPluginHooks , "," )
90
106
for _ , hookCmd := range commands {
91
- if hookCmd == subCmdName {
92
- return true
107
+ if hookMatch ( hookCmd , subCmd ) {
108
+ return hookCmd , true
93
109
}
94
110
}
95
- return false
111
+
112
+ return "" , false
113
+ }
114
+
115
+ func hookMatch (hookCmd , subCmd string ) bool {
116
+ hookCmdTokens := strings .Split (hookCmd , " " )
117
+ subCmdTokens := strings .Split (subCmd , " " )
118
+
119
+ if len (hookCmdTokens ) > len (subCmdTokens ) {
120
+ return false
121
+ }
122
+
123
+ for i , v := range hookCmdTokens {
124
+ if v != subCmdTokens [i ] {
125
+ return false
126
+ }
127
+ }
128
+
129
+ return true
96
130
}
97
131
98
132
func getCommandFlags (cmd * cobra.Command ) map [string ]string {
0 commit comments