buffet: Provide results definition in command definition.
That allows us to provide typed results for supported commands.
BUG=chromium:435607
TEST=cros_workon_make --test buffet
Change-Id: I61b5a5b294b4d869366c821adf1ef7f6db31c7ea
Reviewed-on: https://chromium-review.googlesource.com/231322
Reviewed-by: Anton Muhin <antonm@chromium.org>
Commit-Queue: Anton Muhin <antonm@chromium.org>
Tested-by: Anton Muhin <antonm@chromium.org>
diff --git a/buffet/commands/command_dictionary.cc b/buffet/commands/command_dictionary.cc
index 98ffefc..930e044 100644
--- a/buffet/commands/command_dictionary.cc
+++ b/buffet/commands/command_dictionary.cc
@@ -54,8 +54,8 @@
package_name.c_str());
return false;
}
- const base::DictionaryValue* command_value = nullptr;
- if (!command_iter.value().GetAsDictionary(&command_value)) {
+ const base::DictionaryValue* command_def_json = nullptr;
+ if (!command_iter.value().GetAsDictionary(&command_def_json)) {
chromeos::Error::AddToPrintf(error, FROM_HERE,
errors::commands::kDomain,
errors::commands::kTypeMismatch,
@@ -66,32 +66,22 @@
// Construct the compound command name as "pkg_name.cmd_name".
std::string full_command_name = chromeos::string_utils::Join(
'.', package_name, command_name);
- // Get the "parameters" definition of the command and read it into
- // an object schema.
- const base::DictionaryValue* command_schema_def = nullptr;
- if (!command_value->GetDictionaryWithoutPathExpansion(
- commands::attributes::kCommand_Parameters, &command_schema_def)) {
- chromeos::Error::AddToPrintf(
- error, FROM_HERE, errors::commands::kDomain,
- errors::commands::kPropertyMissing,
- "Command definition '%s' is missing property '%s'",
- full_command_name.c_str(),
- commands::attributes::kCommand_Parameters);
- return false;
- }
- const ObjectSchema* base_def = nullptr;
+ const ObjectSchema* base_parameters_def = nullptr;
+ const ObjectSchema* base_results_def = nullptr;
if (base_commands) {
const CommandDefinition* cmd =
base_commands->FindCommand(full_command_name);
- if (cmd)
- base_def = cmd->GetParameters().get();
+ if (cmd) {
+ base_parameters_def = cmd->GetParameters().get();
+ base_results_def = cmd->GetResults().get();
+ }
// If the base command dictionary was provided but the command was not
// found in it, this must be a custom (vendor) command. GCD spec states
// that all custom command names must begin with "_". Let's enforce
// this rule here.
- if (!base_def) {
+ if (!cmd) {
if (command_name.front() != '_') {
chromeos::Error::AddToPrintf(
error, FROM_HERE, errors::commands::kDomain,
@@ -104,17 +94,27 @@
}
}
- auto command_schema = std::make_shared<ObjectSchema>();
- if (!command_schema->FromJson(command_schema_def, base_def, error)) {
- chromeos::Error::AddToPrintf(error, FROM_HERE,
- errors::commands::kDomain,
- errors::commands::kInvalidObjectSchema,
- "Invalid definition for command '%s'",
- full_command_name.c_str());
+ auto parameters_schema = BuildObjectSchema(
+ command_def_json,
+ commands::attributes::kCommand_Parameters,
+ base_parameters_def,
+ full_command_name,
+ error);
+ if (!parameters_schema)
return false;
- }
+
+ auto results_schema = BuildObjectSchema(
+ command_def_json,
+ commands::attributes::kCommand_Results,
+ base_results_def,
+ full_command_name,
+ error);
+ if (!results_schema)
+ return false;
+
auto command_def = std::make_shared<CommandDefinition>(category,
- command_schema);
+ parameters_schema,
+ results_schema);
new_defs.insert(std::make_pair(full_command_name, command_def));
command_iter.Advance();
@@ -150,6 +150,38 @@
return true;
}
+std::shared_ptr<ObjectSchema> CommandDictionary::BuildObjectSchema(
+ const base::DictionaryValue* command_def_json,
+ const char* property_name,
+ const ObjectSchema* base_def,
+ const std::string& command_name,
+ chromeos::ErrorPtr* error) {
+ auto object_schema = std::make_shared<ObjectSchema>();
+
+ const base::DictionaryValue* schema_def = nullptr;
+ if (!command_def_json->GetDictionaryWithoutPathExpansion(property_name,
+ &schema_def)) {
+ chromeos::Error::AddToPrintf(
+ error, FROM_HERE, errors::commands::kDomain,
+ errors::commands::kPropertyMissing,
+ "Command definition '%s' is missing property '%s'",
+ command_name.c_str(),
+ property_name);
+ return {};
+ }
+
+ if (!object_schema->FromJson(schema_def, base_def, error)) {
+ chromeos::Error::AddToPrintf(error, FROM_HERE,
+ errors::commands::kDomain,
+ errors::commands::kInvalidObjectSchema,
+ "Invalid definition for command '%s'",
+ command_name.c_str());
+ return {};
+ }
+
+ return object_schema;
+}
+
std::unique_ptr<base::DictionaryValue> CommandDictionary::GetCommandsAsJson(
bool full_schema, chromeos::ErrorPtr* error) const {
std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue);