Register subcommands with subcommands passed as part of command info

This commit is contained in:
sophia 2021-04-14 17:24:49 -05:00 committed by Paul Hinze
parent 0414be7cf7
commit 3c491fafdd
No known key found for this signature in database
GPG Key ID: B69DEDF2D55501C0
5 changed files with 83 additions and 69 deletions

View File

@ -71,7 +71,7 @@ func (c *Command) CommandInfoFunc() interface{} {
func (c *Command) CommandInfo() *plugincore.CommandInfo {
return &plugincore.CommandInfo{
Name: []string{"myplugin"},
Name: "myplugin",
Help: c.Help(),
Synopsis: c.Synopsis(),
Flags: c.Flags(),

View File

@ -102,7 +102,8 @@ func (b *Basis) Init() (result *vagrant_server.Job_InitResult, err error) {
if err != nil {
b.logger.Error("failed to get command info for command "+name, "error", err)
}
err = RegisterSubcommands(cmd, result)
names := []string{cmdInfo.Name}
err = RegisterSubcommands(cmdInfo, names, result)
if err != nil {
b.logger.Error("subcommand error", err)
}
@ -120,24 +121,21 @@ func (b *Basis) Init() (result *vagrant_server.Job_InitResult, err error) {
return
}
func RegisterSubcommands(cmd sdkcore.Command, result *vagrant_server.Job_InitResult) (err error) {
subcmds, err := cmd.Subcommands()
func RegisterSubcommands(cmd *sdkcore.CommandInfo, names []string, result *vagrant_server.Job_InitResult) (err error) {
subcmds := cmd.Subcommands
if len(subcmds) > 0 {
for _, scmd := range subcmds {
scmdInfo, err := scmd.CommandInfo()
if err != nil {
return err
}
name := append(names, scmd.Name)
result.Commands = append(
result.Commands,
&vagrant_server.Job_Command{
Name: strings.Join(scmdInfo.Name, " "),
Synopsis: scmdInfo.Synopsis,
Help: scmdInfo.Help,
Flags: FlagsToProtoMapper(scmdInfo.Flags),
Name: strings.Join(name, " "),
Synopsis: scmd.Synopsis,
Help: scmd.Help,
Flags: FlagsToProtoMapper(scmd.Flags),
},
)
err = RegisterSubcommands(scmd, result)
err = RegisterSubcommands(scmd, name, result)
}
}
return

View File

@ -326,17 +326,19 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
value :STRING, 0
value :BOOL, 2
end
add_message "hashicorp.vagrant.sdk.Command.CommandInfo" do
optional :name, :string, 1
optional :help, :string, 2
optional :synopsis, :string, 3
repeated :flags, :message, 4, "hashicorp.vagrant.sdk.Command.Flag"
repeated :subcommands, :message, 5, "hashicorp.vagrant.sdk.Command.CommandInfo"
end
add_message "hashicorp.vagrant.sdk.Command.CommandInfoResp" do
optional :help, :string, 1
optional :synopsis, :string, 2
repeated :flags, :message, 3, "hashicorp.vagrant.sdk.Command.Flag"
optional :command_info, :message, 1, "hashicorp.vagrant.sdk.Command.CommandInfo"
end
add_message "hashicorp.vagrant.sdk.Command.ExecuteResp" do
optional :exit_code, :int64, 1
end
add_message "hashicorp.vagrant.sdk.Command.SubcommandResp" do
repeated :commands, :string, 1
end
add_message "hashicorp.vagrant.sdk.Command.Arguments" do
repeated :flags, :message, 1, "hashicorp.vagrant.sdk.Command.Arguments.Flag"
repeated :args, :string, 2
@ -606,9 +608,9 @@ module Hashicorp
Command = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("hashicorp.vagrant.sdk.Command").msgclass
Command::Flag = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("hashicorp.vagrant.sdk.Command.Flag").msgclass
Command::Flag::Type = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("hashicorp.vagrant.sdk.Command.Flag.Type").enummodule
Command::CommandInfo = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("hashicorp.vagrant.sdk.Command.CommandInfo").msgclass
Command::CommandInfoResp = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("hashicorp.vagrant.sdk.Command.CommandInfoResp").msgclass
Command::ExecuteResp = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("hashicorp.vagrant.sdk.Command.ExecuteResp").msgclass
Command::SubcommandResp = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("hashicorp.vagrant.sdk.Command.SubcommandResp").msgclass
Command::Arguments = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("hashicorp.vagrant.sdk.Command.Arguments").msgclass
Command::Arguments::Flag = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("hashicorp.vagrant.sdk.Command.Arguments.Flag").msgclass
Command::Arguments::Flag::Type = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("hashicorp.vagrant.sdk.Command.Arguments.Flag.Type").enummodule

View File

@ -143,8 +143,6 @@ module Hashicorp
rpc :Documentation, ::Google::Protobuf::Empty, ::Hashicorp::Vagrant::Sdk::Config::Documentation
rpc :ExecuteSpec, ::Google::Protobuf::Empty, ::Hashicorp::Vagrant::Sdk::FuncSpec
rpc :Execute, ::Hashicorp::Vagrant::Sdk::FuncSpec::Args, ::Hashicorp::Vagrant::Sdk::Command::ExecuteResp
rpc :SubcommandSpec, ::Google::Protobuf::Empty, ::Hashicorp::Vagrant::Sdk::FuncSpec
rpc :Subcommands, ::Hashicorp::Vagrant::Sdk::FuncSpec::Args, ::Hashicorp::Vagrant::Sdk::Command::SubcommandResp
rpc :CommandInfoSpec, ::Google::Protobuf::Empty, ::Hashicorp::Vagrant::Sdk::FuncSpec
rpc :CommandInfo, ::Hashicorp::Vagrant::Sdk::FuncSpec::Args, ::Hashicorp::Vagrant::Sdk::Command::CommandInfoResp
end

View File

@ -6,7 +6,9 @@ module VagrantPlugins
class CommandService < SDK::CommandService::Service
prepend VagrantPlugins::CommandServe::Service::ExceptionLogger
[:execute, :subcommands, :command_info].each do |method|
LOGGER = Log4r::Logger.new("vagrant::plugins::command::service:command_service")
[:execute, :command_info].each do |method|
VagrantPlugins::CommandServe::Service::ExceptionLogger.log_exception method
end
@ -16,60 +18,74 @@ module VagrantPlugins
def command_info(req, ctx)
ServiceInfo.with_info(ctx) do |info|
plugin_name = info.plugin_name
options = command_options_for(plugin_name, info.command)
if options.nil?
hlp_msg = ""
flags = []
else
hlp_msg = options.help
# Now we can build our list of flags
flags = options.top.list.find_all { |o|
o.is_a?(OptionParser::Switch)
}.map { |o|
SDK::Command::Flag.new(
description: o.desc.join(" "),
long_name: o.switch_name,
short_name: o.short.first,
type: o.is_a?(OptionParser::Switch::NoArgument) ?
SDK::Command::Flag::Type::BOOL :
SDK::Command::Flag::Type::STRING
)
}
end
if info.command.empty?
plugin = Vagrant::Plugin::V2::Plugin.manager.commands[plugin_name.to_sym].to_a.first
if !plugin
raise "Failed to locate command plugin for: #{plugin_name}"
end
klass = plugin.call
synopsis = klass.synopsis
else
synopsis = ""
end
command_info = collect_command_info(info.plugin_name, info.command)
LOGGER.info("command info, #{command_info}")
SDK::Command::CommandInfoResp.new(
help: hlp_msg,
flags: flags,
synopsis: synopsis,
command_info: command_info,
)
end
end
def subcommand_spec(*args)
return SDK::FuncSpec.new
def collect_command_info(plugin_name, subcommand_names)
LOGGER.info("collecting command information for #{plugin_name} #{subcommand_names}")
options = command_options_for(plugin_name, subcommand_names)
if options.nil?
hlp_msg = ""
flags = []
else
hlp_msg = options.help
# Now we can build our list of flags
flags = options.top.list.find_all { |o|
o.is_a?(OptionParser::Switch)
}.map { |o|
SDK::Command::Flag.new(
description: o.desc.join(" "),
long_name: o.switch_name,
short_name: o.short.first,
type: o.is_a?(OptionParser::Switch::NoArgument) ?
SDK::Command::Flag::Type::BOOL :
SDK::Command::Flag::Type::STRING
)
}
end
if subcommand_names.empty?
plugin = Vagrant::Plugin::V2::Plugin.manager.commands[plugin_name.to_sym].to_a.first
if !plugin
raise "Failed to locate command plugin for: #{plugin_name}"
end
klass = plugin.call
synopsis = klass.synopsis
command_name = plugin_name
else
synopsis = ""
command_name = subcommand_names.last
end
subcommands = get_subcommands(plugin_name, subcommand_names)
SDK::Command::CommandInfo.new(
name: command_name,
help: hlp_msg,
flags: flags,
synopsis: synopsis,
subcommands: subcommands
)
end
def subcommands(req, ctx)
ServiceInfo.with_info(ctx) do |info|
cmds = subcommands_for(info.plugin_name, info.command)
SDK::Command::SubcommandResp.new(
commands: cmds.nil? ? [] : cmds.keys,
)
def get_subcommands(plugin_name, subcommand_names)
LOGGER.info("collecting subcommands for #{plugin_name} #{subcommand_names}")
subcommands = []
cmds = subcommands_for(plugin_name, subcommand_names)
if !cmds.nil?
LOGGER.info("found subcommands #{cmds.keys}")
cmds.keys.each do |subcmd|
subnms = subcommand_names.dup
subcommands << collect_command_info(plugin_name, subnms.append(subcmd.to_s))
end
else
LOGGER.info("no subcommands found")
end
return subcommands
end
def augment_cmd_class(cmd_cls)