Support and honor the "primary" option for Command plugins
This commit is contained in:
parent
5170d83c21
commit
7c56c74bb6
@ -2,6 +2,7 @@ package configvagrant
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/go-hclog"
|
||||
sdk "github.com/hashicorp/vagrant-plugin-sdk"
|
||||
"github.com/hashicorp/vagrant-plugin-sdk/component"
|
||||
@ -12,8 +13,8 @@ import (
|
||||
var CommandOptions = []sdk.Option{
|
||||
sdk.WithComponents(
|
||||
&Config{},
|
||||
&Command{},
|
||||
),
|
||||
sdk.WithComponent(&Command{}, &component.CommandOptions{Primary: false}),
|
||||
sdk.WithName("configvagrant"),
|
||||
}
|
||||
|
||||
|
||||
@ -19,11 +19,14 @@ import (
|
||||
var CommandOptions = []sdk.Option{
|
||||
sdk.WithComponents(
|
||||
// &Provider{},
|
||||
&command.Command{},
|
||||
&host.AlwaysTrueHost{},
|
||||
&communicator.DummyCommunicator{},
|
||||
&push.Encouragement{},
|
||||
),
|
||||
sdk.WithComponent(&command.Command{}, &component.CommandOptions{
|
||||
// Should keep the plugin out of the default help output
|
||||
Primary: false,
|
||||
}),
|
||||
sdk.WithComponent(&provider.Happy{}, &component.ProviderOptions{
|
||||
Priority: 100,
|
||||
}),
|
||||
|
||||
@ -2,13 +2,17 @@ package otherplugin
|
||||
|
||||
import (
|
||||
sdk "github.com/hashicorp/vagrant-plugin-sdk"
|
||||
"github.com/hashicorp/vagrant-plugin-sdk/component"
|
||||
"github.com/hashicorp/vagrant/builtin/otherplugin/guest"
|
||||
)
|
||||
|
||||
var CommandOptions = []sdk.Option{
|
||||
sdk.WithComponents(
|
||||
&Command{},
|
||||
&guest.AlwaysTrueGuest{},
|
||||
),
|
||||
sdk.WithComponent(&Command{}, &component.CommandOptions{
|
||||
// Hide command from default help output
|
||||
Primary: false,
|
||||
}),
|
||||
sdk.WithName("otherplugin"),
|
||||
}
|
||||
|
||||
@ -22,6 +22,7 @@ type DynamicCommand struct {
|
||||
help string
|
||||
parent *DynamicCommand
|
||||
flags []*component.CommandFlag
|
||||
primary bool
|
||||
}
|
||||
|
||||
func (c *DynamicCommand) Run(args []string) int {
|
||||
@ -154,6 +155,10 @@ func (c *DynamicCommand) Flags() component.CommandFlags {
|
||||
})
|
||||
}
|
||||
|
||||
func (c *DynamicCommand) Primary() bool {
|
||||
return c.primary
|
||||
}
|
||||
|
||||
func (c *DynamicCommand) fullName() string {
|
||||
var v string
|
||||
if c.parent != nil {
|
||||
|
||||
@ -224,6 +224,7 @@ func registerCommand(
|
||||
synopsis: c.Synopsis,
|
||||
help: c.Help,
|
||||
flags: flgs,
|
||||
primary: c.Primary,
|
||||
}
|
||||
if parent != nil {
|
||||
d.parent = parent
|
||||
@ -399,10 +400,13 @@ func GroupedHelpFunc(f cli.HelpFunc) cli.HelpFunc {
|
||||
).Row())
|
||||
d.Append(glint.Text(""))
|
||||
|
||||
// Add common commands
|
||||
// First add hand-picked common commands
|
||||
helpCommandsSection(d, "Common commands", commonCommands, commands)
|
||||
|
||||
// Make our other commands
|
||||
// Make our list of other commands by
|
||||
// - skipping common commands we just printed
|
||||
// - skipping hand-picked hidden commands
|
||||
// - skipping commands that set CommandOptions.Primary to false
|
||||
ignoreMap := map[string]struct{}{}
|
||||
for k := range hiddenCommands {
|
||||
ignoreMap[k] = struct{}{}
|
||||
@ -411,6 +415,16 @@ func GroupedHelpFunc(f cli.HelpFunc) cli.HelpFunc {
|
||||
ignoreMap[k] = struct{}{}
|
||||
}
|
||||
|
||||
for k, cmdFn := range commands {
|
||||
cmd, err := cmdFn()
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("failed to load %q command: %s", k, err))
|
||||
}
|
||||
if pc, ok := cmd.(Primaryable); ok && pc.Primary() == false {
|
||||
ignoreMap[k] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
var otherCommands []string
|
||||
for k := range commands {
|
||||
if _, ok := ignoreMap[k]; ok {
|
||||
@ -464,4 +478,8 @@ func helpCommandsSection(
|
||||
).PaddingLeft(2))
|
||||
}
|
||||
|
||||
type Primaryable interface {
|
||||
Primary() bool
|
||||
}
|
||||
|
||||
var helpText = map[string][2]string{}
|
||||
|
||||
@ -1,14 +1,18 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
sdk "github.com/hashicorp/vagrant-plugin-sdk"
|
||||
"github.com/hashicorp/vagrant/internal/plugin"
|
||||
"github.com/hashicorp/vagrant-plugin-sdk"
|
||||
)
|
||||
|
||||
type PluginCommand struct {
|
||||
*baseCommand
|
||||
}
|
||||
|
||||
func (c *PluginCommand) Primary() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (c *PluginCommand) Run(args []string) int {
|
||||
plugin, ok := plugin.Builtins[args[0]]
|
||||
if !ok {
|
||||
|
||||
@ -99,6 +99,10 @@ func (c *UICommand) Flags() component.CommandFlags {
|
||||
})
|
||||
}
|
||||
|
||||
func (c *UICommand) Primary() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// func (c *UICommand) AutocompleteArgs() complete.Predictor {
|
||||
// return complete.PredictNothing
|
||||
// }
|
||||
|
||||
@ -34,6 +34,10 @@ func (c *VersionCommand) Flags() component.CommandFlags {
|
||||
return c.flagSet(0, nil)
|
||||
}
|
||||
|
||||
func (c *VersionCommand) Primary() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// func (c *VersionCommand) AutocompleteArgs() complete.Predictor {
|
||||
// return complete.PredictNothing
|
||||
// }
|
||||
|
||||
@ -589,17 +589,21 @@ func (b *Basis) RunInit() (result *vagrant_server.Job_InitResult, err error) {
|
||||
|
||||
for _, c := range cmds {
|
||||
fn := c.Value.(component.Command).CommandInfoFunc()
|
||||
// See core.JobCommandProto
|
||||
raw, err := b.callDynamicFunc(ctx, b.logger, fn,
|
||||
(*[]*vagrant_plugin_sdk.Command_CommandInfo)(nil),
|
||||
argmapper.Typed(b.ctx),
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result.Commands = append(result.Commands,
|
||||
raw.([]*vagrant_plugin_sdk.Command_CommandInfo)...)
|
||||
// Primary comes from plugin options so add that to CommandInfo here
|
||||
cinfos := raw.([]*vagrant_plugin_sdk.Command_CommandInfo)
|
||||
copts := c.Options.(*component.CommandOptions)
|
||||
cinfos[0].Primary = copts.Primary
|
||||
|
||||
result.Commands = append(result.Commands, cinfos...)
|
||||
}
|
||||
|
||||
return
|
||||
@ -750,6 +754,7 @@ func (b *Basis) component(
|
||||
Name: name,
|
||||
ServerAddr: b.Client().ServerTarget(),
|
||||
},
|
||||
Options: c.Options,
|
||||
hooks: hooks,
|
||||
mappers: append(b.mappers, c.Mappers...),
|
||||
plugin: c,
|
||||
|
||||
@ -12,6 +12,9 @@ type Component struct {
|
||||
Value interface{}
|
||||
Info *vagrant_server.Component
|
||||
|
||||
// Options for component type, see PluginInfo.ComponentOptions
|
||||
Options interface{}
|
||||
|
||||
// These fields can be accessed internally
|
||||
hooks map[string][]*config.Hook
|
||||
labels map[string]string
|
||||
|
||||
@ -12,6 +12,7 @@ var Mappers = []interface{}{
|
||||
JobCommandProto,
|
||||
}
|
||||
|
||||
// JobCommandProto converts a CommandInfo into its proto equivalent
|
||||
func JobCommandProto(c *component.CommandInfo) []*vagrant_plugin_sdk.Command_CommandInfo {
|
||||
return jobCommandProto(c, []string{})
|
||||
}
|
||||
|
||||
@ -179,8 +179,7 @@ module Vagrant
|
||||
sf_class.plugin_name = plg[:name]
|
||||
sf_class.type = plg[:type]
|
||||
result.register(plg[:name].to_sym) do
|
||||
# TODO(phinze): wire through CommandOptions and return them here
|
||||
[proc{sf_class}, {}]
|
||||
[proc{sf_class}, plg[:options]]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -436,6 +436,9 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
|
||||
add_message "hashicorp.vagrant.sdk.PluginInfo.ComponentOptionsMap" do
|
||||
map :options, :uint32, :message, 1, "google.protobuf.Any"
|
||||
end
|
||||
add_message "hashicorp.vagrant.sdk.PluginInfo.CommandOptions" do
|
||||
optional :primary, :bool, 1
|
||||
end
|
||||
add_message "hashicorp.vagrant.sdk.PluginInfo.ProviderOptions" do
|
||||
optional :priority, :int32, 1
|
||||
optional :parallel, :bool, 2
|
||||
@ -499,6 +502,7 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
|
||||
optional :synopsis, :string, 3
|
||||
repeated :flags, :message, 4, "hashicorp.vagrant.sdk.Command.Flag"
|
||||
repeated :subcommands, :message, 5, "hashicorp.vagrant.sdk.Command.CommandInfo"
|
||||
optional :primary, :bool, 6
|
||||
end
|
||||
add_message "hashicorp.vagrant.sdk.Command.CommandInfoResp" do
|
||||
optional :command_info, :message, 1, "hashicorp.vagrant.sdk.Command.CommandInfo"
|
||||
@ -1120,6 +1124,7 @@ module Hashicorp
|
||||
PluginInfo::ComponentList = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("hashicorp.vagrant.sdk.PluginInfo.ComponentList").msgclass
|
||||
PluginInfo::Name = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("hashicorp.vagrant.sdk.PluginInfo.Name").msgclass
|
||||
PluginInfo::ComponentOptionsMap = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("hashicorp.vagrant.sdk.PluginInfo.ComponentOptionsMap").msgclass
|
||||
PluginInfo::CommandOptions = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("hashicorp.vagrant.sdk.PluginInfo.CommandOptions").msgclass
|
||||
PluginInfo::ProviderOptions = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("hashicorp.vagrant.sdk.PluginInfo.ProviderOptions").msgclass
|
||||
PluginInfo::SyncedFolderOptions = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("hashicorp.vagrant.sdk.PluginInfo.SyncedFolderOptions").msgclass
|
||||
PluginManager = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("hashicorp.vagrant.sdk.PluginManager").msgclass
|
||||
|
||||
@ -40,6 +40,8 @@ module VagrantPlugins
|
||||
return {} if plg_opts.nil?
|
||||
opts = mapper.unany(plg_opts)
|
||||
case opts
|
||||
when Hashicorp::Vagrant::Sdk::PluginInfo::CommandOptions
|
||||
opts.to_h
|
||||
when Hashicorp::Vagrant::Sdk::PluginInfo::ProviderOptions
|
||||
opts.to_h
|
||||
when Hashicorp::Vagrant::Sdk::PluginInfo::SyncedFolderOptions
|
||||
|
||||
@ -102,6 +102,7 @@ module VagrantPlugins
|
||||
synopsis: info.synopsis,
|
||||
flags: flags,
|
||||
subcommands: subcommands,
|
||||
primary: info.primary,
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
@ -149,12 +149,15 @@ module VagrantPlugins
|
||||
end
|
||||
subcommands = get_subcommands(plugin_name, subcommand_names)
|
||||
|
||||
opts = Vagrant.plugin("2").local_manager.commands[plugin_name.to_sym].last
|
||||
|
||||
SDK::Command::CommandInfo.new(
|
||||
name: command_name,
|
||||
help: hlp_msg,
|
||||
flags: flags,
|
||||
synopsis: synopsis,
|
||||
subcommands: subcommands
|
||||
subcommands: subcommands,
|
||||
primary: opts[:primary],
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
@ -124,8 +124,11 @@ module VagrantPlugins
|
||||
def _convert_options_to_proto(type, class_or_tuple_with_class_and_options)
|
||||
case type
|
||||
when :COMMAND
|
||||
# _, command_options = class_or_tuple_with_class_and_options
|
||||
return Google::Protobuf::Empty.new
|
||||
_, opts = class_or_tuple_with_class_and_options
|
||||
return SDK::PluginInfo::CommandOptions.new(
|
||||
# Primary is always set in V2::Plugin.command
|
||||
primary: opts[:primary],
|
||||
)
|
||||
when :COMMUNICATOR
|
||||
# No options for communicators
|
||||
return Google::Protobuf::Empty.new
|
||||
|
||||
@ -25,14 +25,16 @@ module VagrantPlugins
|
||||
:help,
|
||||
:synopsis,
|
||||
:flags,
|
||||
:subcommands
|
||||
:subcommands,
|
||||
:primary
|
||||
|
||||
def initialize(name:, help:, synopsis: nil, subcommands: [])
|
||||
def initialize(name:, help:, synopsis: nil, subcommands: [], primary:)
|
||||
@name = name.to_s
|
||||
@help = help.to_s
|
||||
@synopsis = synopsis.to_s
|
||||
@subcommands = Array(subcommands)
|
||||
@flags = []
|
||||
@primary = primary
|
||||
end
|
||||
|
||||
def add_flag(**kwargs)
|
||||
|
||||
@ -200,6 +200,7 @@ class VagrantPlugins::CommandServe::Type::CommandInfo
|
||||
synopsis: info.synopsis,
|
||||
flags: flags,
|
||||
subcommands: subcommands,
|
||||
primary: info.primary,
|
||||
)
|
||||
end
|
||||
end
|
||||
@ -641,6 +642,7 @@ class Hashicorp::Vagrant::Sdk::Command::CommandInfo
|
||||
name: name,
|
||||
help: help,
|
||||
synopsis: synopsis,
|
||||
primary: primary,
|
||||
).tap do |c|
|
||||
flags.each do |f|
|
||||
c.add_flag(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user