Hello everyone,
I’m here to introduce quite a big change in Hammer’s help output I’m curently working on[1]. The task is splitted into 3 smaller parts, so this post is about the first one - squeezing options. The main purpose of this post is to introduce the change so more people are aware of it AND to get some feedback/comments/etc.
Problem:
As you may have noticed, Hammer’s help output contains quite a lot of duplicates regarding options that have the same meaning, but different names. For example:
$ hammer os create --help
Usage:
hammer os create [OPTIONS]
Options:
--architecture-ids ARCHITECTURE_IDS IDs of associated architectures
Comma separated list of values. Values containing comma should be quoted or escaped with backslash.
JSON is acceptable and preferred way for complex parameters
--architectures ARCHITECTURE_NAMES Comma separated list of values. Values containing comma should be quoted or escaped with backslash.
JSON is acceptable and preferred way for complex parameters
--description DESCRIPTION
--family FAMILY
--location LOCATION_NAME Location Name, Set the current location context for the request
--location-id LOCATION_ID Set the current location context for the request
--location-title LOCATION_TITLE Location title, Set the current location context for the request
--major MAJOR
--media MEDIUM_NAMES Comma separated list of values. Values containing comma should be quoted or escaped with backslash.
JSON is acceptable and preferred way for complex parameters
--medium-ids MEDIUM_IDS IDs of associated media
Comma separated list of values. Values containing comma should be quoted or escaped with backslash.
JSON is acceptable and preferred way for complex parameters
--minor MINOR
--name NAME
--organization ORGANIZATION_NAME Set the current organization context for the request
--organization-id ORGANIZATION_ID Set the current organization context for the request
--organization-title ORGANIZATION_TITLE Set the current organization context for the request
--os-parameters-attributes OS_PARAMETERS_ATTRIBUTES Array of parameters
Comma separated list of values defined by a schema. See Option details section below.
JSON is acceptable and preferred way for complex parameters
--partition-table-ids PARTITION_TABLE_IDS IDs of associated partition tables
Comma separated list of values. Values containing comma should be quoted or escaped with backslash.
JSON is acceptable and preferred way for complex parameters
--partition-tables PARTITION_TABLE_NAMES Comma separated list of values. Values containing comma should be quoted or escaped with backslash.
JSON is acceptable and preferred way for complex parameters
--password-hash PASSWORD_HASH Root password hash function to use
Possible value(s): 'SHA256', 'SHA512', 'Base64', 'Base64-Windows', 'MD5'
--provisioning-template-ids PROVISIONING_TEMPLATE_IDS IDs of associated provisioning templates
Comma separated list of values. Values containing comma should be quoted or escaped with backslash.
JSON is acceptable and preferred way for complex parameters
--provisioning-templates PROVISIONING_TEMPLATE_NAMES Comma separated list of values. Values containing comma should be quoted or escaped with backslash.
JSON is acceptable and preferred way for complex parameters
--release-name RELEASE_NAME
-h, --help Print help
Option details:
...
As you may see location
options serves for setting the current location context for the request, but the user can use either location name, title or id. The same option (from the user’s perspective), but thrice. The same for organization
, media
, architectures
, partition-tables
and provisioning-templates
. This is common issue for all hammer’s commands.
Solution:
We squeeze options that have the same meaning. For example:
Usage:
hammer os create [OPTIONS]
Options:
--architecture[s|-ids] IDs of associated architectures
Comma separated list of values. Values containing comma should be quoted or escaped with backslash.
JSON is acceptable and preferred way for complex parameters
--description DESCRIPTION
--family FAMILY
--location[-id|-title] Set the current location context for the request
--major MAJOR
--medi[a|um-ids] IDs of associated media
Comma separated list of values. Values containing comma should be quoted or escaped with backslash.
JSON is acceptable and preferred way for complex parameters
--minor MINOR
--name NAME
--organization[-id|-title] Set the current organization context for the request
--os-parameters-attributes OS_PARAMETERS_ATTRIBUTES Array of parameters
Comma separated list of values defined by a schema. See Option details section below.
JSON is acceptable and preferred way for complex parameters
--partition-table[s|-ids] IDs of associated partition tables
Comma separated list of values. Values containing comma should be quoted or escaped with backslash.
JSON is acceptable and preferred way for complex parameters
--password-hash PASSWORD_HASH Root password hash function to use
Possible value(s): 'SHA256', 'SHA512', 'Base64', 'Base64-Windows', 'MD5'
--provisioning-template[s|-ids] IDs of associated provisioning templates
Comma separated list of values. Values containing comma should be quoted or escaped with backslash.
JSON is acceptable and preferred way for complex parameters
--release-name RELEASE_NAME
-h, --help Print help
Option details:
...
This will reduce the number of lines in help output by ~3k lines with all major plugins installed. The solution is in progress while I’m getting the feedback. I’d be happy if anyone could try to use the changes locally and give some feedback afterwards. The changes are available on GitHub[2] for hammer core and on GitHub[3] for hammer Foreman plugin[4].
Know issues:
- Some squeezed options might lose their descriptions in regular help output. Since most of the descriptions repeat the option name (e.g.
architecrure-ids
option’s description isIDs of associated architectures
). I’m not sure if we want such description at all, so here I’m asking your opinions. By default the descriptions (coming from API documentation) are kept with possibility to change them (see For developers section). - The options might be misleading. If I see
--location[-id|-title]
option I’d assume that I can pass anything inlocation
option (e.g.--location 4
), which is not currently supported. The user must use particular option for passing name, id or title. - The
hammer full-help
command is not affected by this change, so we keep somewhat of backward compatibility. The options are expanded inhammer full-help
. - Some of options are not squeezed. By default Hammer generates options based on API documentation, but hammer’s plugins can extend/change/add options. They are not affected by automation, so it’s up to developers to change their code to be consistent with core.
For developers:
Hammer core introduces so-called option family
which is mainly used for option grouping in help output. Some usage examples can be found in changes for the main Hammer plugin[3]. Documentation can be found here[4].
Here is the usage within a command extension (create a command extension to use option_family
is not required, it can be used directly within the command definition) as an example:
module CommandExtensions
class PuppetEnvironment < HammerCLI::CommandExtensions
option_family(
# Here you can pass options that are related to all the options in this family
# as well as the family related options only .
aliased_resource: 'environment',
description: _('Puppet environment'),
deprecation: _("Use %s instead") % '--puppet-environment[-id]',
deprecated: { '--environment' => _("Use %s instead") % '--puppet-environment[-id]',
'--environment-id' => _("Use %s instead") % '--puppet-environment[-id]'}
) do
parent '--environment-id', 'ENVIRONMENT_ID', _(''),
format: HammerCLI::Options::Normalizers::Number.new,
attribute_name: :option_environment_id
child '--environment', 'ENVIRONMENT_NAME', _('Environment name'),
attribute_name: :option_environment_name
end
end
end
Also here is an example how to use option_family
for existing command to squeeze the help output:
option_family(
format: HammerCLI::Options::Normalizers::List.new,
aliased_resource: 'puppet-class'
) do
parent '--puppet-class-ids', 'PUPPET_CLASS_IDS', '',
attribute_name: :option_puppetclass_ids
child '--puppet-classes', 'PUPPET_CLASS_NAMES', '',
attribute_name: :option_puppetclass_names
end
P.S.
If something doesn’t work or something is missing, please feel free to reply here or on GitHub directly.
[1] - https://projects.theforeman.org/issues/27706.
[2] - https://github.com/theforeman/hammer-cli/pull/323
[3] - https://github.com/theforeman/hammer-cli-foreman/pull/489
[4] - https://github.com/theforeman/hammer-cli/blob/a7548e5e6cde4aaa1bab13beff552ed535d12acd/doc/creating_commands.md#option-family