hammer_cli 0.19.1 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/bin/hammer-complete +28 -0
 - data/config/cli_config.template.yml +2 -0
 - data/config/hammer.completion +5 -0
 - data/doc/commands_extension.md +12 -0
 - data/doc/creating_commands.md +100 -0
 - data/doc/installation.md +47 -4
 - data/doc/installation_rpm.md +2 -2
 - data/doc/release_notes.md +31 -6
 - data/lib/hammer_cli.rb +1 -0
 - data/lib/hammer_cli/abstract.rb +61 -4
 - data/lib/hammer_cli/apipie/api_connection.rb +5 -1
 - data/lib/hammer_cli/apipie/command.rb +3 -2
 - data/lib/hammer_cli/apipie/option_builder.rb +15 -13
 - data/lib/hammer_cli/apipie/option_definition.rb +9 -7
 - data/lib/hammer_cli/bash.rb +2 -0
 - data/lib/hammer_cli/bash/completion.rb +159 -0
 - data/lib/hammer_cli/bash/prebuild_command.rb +21 -0
 - data/lib/hammer_cli/command_extensions.rb +21 -1
 - data/lib/hammer_cli/connection.rb +4 -0
 - data/lib/hammer_cli/exception_handler.rb +11 -2
 - data/lib/hammer_cli/full_help.rb +8 -1
 - data/lib/hammer_cli/help/builder.rb +29 -3
 - data/lib/hammer_cli/logger_watch.rb +1 -1
 - data/lib/hammer_cli/main.rb +5 -3
 - data/lib/hammer_cli/options/normalizers.rb +7 -3
 - data/lib/hammer_cli/options/option_definition.rb +26 -6
 - data/lib/hammer_cli/options/option_family.rb +114 -0
 - data/lib/hammer_cli/options/predefined.rb +1 -1
 - data/lib/hammer_cli/output/adapter/abstract.rb +1 -5
 - data/lib/hammer_cli/output/adapter/base.rb +1 -1
 - data/lib/hammer_cli/output/adapter/csv.rb +3 -2
 - data/lib/hammer_cli/output/adapter/json.rb +14 -3
 - data/lib/hammer_cli/output/adapter/silent.rb +1 -1
 - data/lib/hammer_cli/output/adapter/table.rb +27 -8
 - data/lib/hammer_cli/output/adapter/yaml.rb +6 -3
 - data/lib/hammer_cli/output/output.rb +2 -4
 - data/lib/hammer_cli/settings.rb +2 -1
 - data/lib/hammer_cli/subcommand.rb +25 -1
 - data/lib/hammer_cli/testing/command_assertions.rb +2 -2
 - data/lib/hammer_cli/utils.rb +22 -0
 - data/lib/hammer_cli/version.rb +1 -1
 - data/locale/ca/LC_MESSAGES/hammer-cli.mo +0 -0
 - data/locale/de/LC_MESSAGES/hammer-cli.mo +0 -0
 - data/locale/en/LC_MESSAGES/hammer-cli.mo +0 -0
 - data/locale/en_GB/LC_MESSAGES/hammer-cli.mo +0 -0
 - data/locale/es/LC_MESSAGES/hammer-cli.mo +0 -0
 - data/locale/fr/LC_MESSAGES/hammer-cli.mo +0 -0
 - data/locale/it/LC_MESSAGES/hammer-cli.mo +0 -0
 - data/locale/ja/LC_MESSAGES/hammer-cli.mo +0 -0
 - data/locale/ko/LC_MESSAGES/hammer-cli.mo +0 -0
 - data/locale/pt_BR/LC_MESSAGES/hammer-cli.mo +0 -0
 - data/locale/ru/LC_MESSAGES/hammer-cli.mo +0 -0
 - data/locale/zh_CN/LC_MESSAGES/hammer-cli.mo +0 -0
 - data/locale/zh_TW/LC_MESSAGES/hammer-cli.mo +0 -0
 - data/test/unit/abstract_test.rb +23 -2
 - data/test/unit/apipie/api_connection_test.rb +1 -0
 - data/test/unit/apipie/option_builder_test.rb +8 -0
 - data/test/unit/bash_test.rb +138 -0
 - data/test/unit/command_extensions_test.rb +67 -49
 - data/test/unit/exception_handler_test.rb +44 -0
 - data/test/unit/help/builder_test.rb +22 -0
 - data/test/unit/options/option_family_test.rb +48 -0
 - data/test/unit/output/adapter/base_test.rb +58 -0
 - data/test/unit/output/adapter/csv_test.rb +63 -1
 - data/test/unit/output/adapter/json_test.rb +61 -0
 - data/test/unit/output/adapter/table_test.rb +70 -1
 - data/test/unit/output/adapter/yaml_test.rb +59 -0
 - data/test/unit/output/output_test.rb +3 -3
 - metadata +17 -6
 - data/hammer_cli_complete +0 -13
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: d903c3dbbe33a2411dfd2e23b781609a40b39b4ed29066cabe35af22335042d5
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 25acdf29e7a071a945a4c7c2c4745083e0e11e7d12ce098c662054a7d87caeb1
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 8a117c635359bc261f70cb67bf33fc2080f15b909981a98f87d7c64235a2ecf686bf1530b5293e60565e5e52cab2ed9bbf17f604816099ada8e11b11a5b7f064
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 3e296e36f46d6374fc1878a51447cd2fe820104fa5ba191c6bde91a62aff2fd7b76e12743d152ca0eb9457b541e38dd39351da138020501d286c3af071e33b39
         
     | 
    
        data/bin/hammer-complete
    ADDED
    
    | 
         @@ -0,0 +1,28 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/usr/bin/env ruby
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'English'
         
     | 
| 
      
 4 
     | 
    
         
            +
            @project_root = File.expand_path('../..', __FILE__)
         
     | 
| 
      
 5 
     | 
    
         
            +
            $LOAD_PATH.unshift(File.join(@project_root, 'lib'))
         
     | 
| 
      
 6 
     | 
    
         
            +
            HAMMER = ENV['HAMMER'] || File.join(@project_root, 'bin/hammer')
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            require 'yaml'
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            completion_cache_file = ENV['HAMMER_COMPLETION_CACHE'] || '~/.cache/hammer_completion.yml'
         
     | 
| 
      
 11 
     | 
    
         
            +
            completion_cache_file = File.expand_path(completion_cache_file)
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            # build the cache if it does not exist
         
     | 
| 
      
 14 
     | 
    
         
            +
            unless File.exist?(completion_cache_file)
         
     | 
| 
      
 15 
     | 
    
         
            +
              require 'hammer_cli'
         
     | 
| 
      
 16 
     | 
    
         
            +
              `#{HAMMER} prebuild-bash-completion`
         
     | 
| 
      
 17 
     | 
    
         
            +
            end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            require 'hammer_cli/bash/completion'
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            dict = HammerCLI::Bash::Completion.load_description(completion_cache_file)
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            comp_line = ENV['COMP_LINE'] || ''
         
     | 
| 
      
 24 
     | 
    
         
            +
            comp_args = comp_line.split(' ', 2).last || ''
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
            result = HammerCLI::Bash::Completion.new(dict).complete(comp_args)
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
            puts result.join("\n")
         
     | 
    
        data/doc/commands_extension.md
    CHANGED
    
    | 
         @@ -10,6 +10,11 @@ Each command can be easily extended with one ore more `HammerCLI::CommandExtensi 
     | 
|
| 
       10 
10 
     | 
    
         
             
                inheritable true
         
     | 
| 
       11 
11 
     | 
    
         
             
                # Simply add a new option to a command is being extended
         
     | 
| 
       12 
12 
     | 
    
         
             
                option(option_params)
         
     | 
| 
      
 13 
     | 
    
         
            +
                # Add option family to a command
         
     | 
| 
      
 14 
     | 
    
         
            +
                option_family(common_options = {}) do
         
     | 
| 
      
 15 
     | 
    
         
            +
                  parent option_params
         
     | 
| 
      
 16 
     | 
    
         
            +
                  child option_params
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
       13 
18 
     | 
    
         
             
                # Extend hash with data returned from server before it is printed
         
     | 
| 
       14 
19 
     | 
    
         
             
                before_print do |data|
         
     | 
| 
       15 
20 
     | 
    
         
             
                  # data modifications
         
     | 
| 
         @@ -65,6 +70,13 @@ class MyCommandExtensions < HammerCLI::CommandExtensions 
     | 
|
| 
       65 
70 
     | 
    
         | 
| 
       66 
71 
     | 
    
         
             
              option ['--new-option'], 'TYPE', _('Option description')
         
     | 
| 
       67 
72 
     | 
    
         | 
| 
      
 73 
     | 
    
         
            +
              option_family(
         
     | 
| 
      
 74 
     | 
    
         
            +
                description: _('Common description')
         
     | 
| 
      
 75 
     | 
    
         
            +
              ) do
         
     | 
| 
      
 76 
     | 
    
         
            +
                parent ['--new-option'], 'TYPE', _('Option description')
         
     | 
| 
      
 77 
     | 
    
         
            +
                child ['--new-option-ver2'], 'TYPE', _('Option description')
         
     | 
| 
      
 78 
     | 
    
         
            +
              end
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
       68 
80 
     | 
    
         
             
              before_print do |data|
         
     | 
| 
       69 
81 
     | 
    
         
             
                data['results'].each do |result|
         
     | 
| 
       70 
82 
     | 
    
         
             
                  result['status'] = process_errors(result['errors'])
         
     | 
    
        data/doc/creating_commands.md
    CHANGED
    
    | 
         @@ -173,6 +173,54 @@ Here is the list of predefined options: 
     | 
|
| 
       173 
173 
     | 
    
         
             
              * `:fields` Expects a list with fields to show in output, see [example](creating_commands.md#printing-hash-records).
         
     | 
| 
       174 
174 
     | 
    
         | 
| 
       175 
175 
     | 
    
         | 
| 
      
 176 
     | 
    
         
            +
            ### Option family
         
     | 
| 
      
 177 
     | 
    
         
            +
            Option family is the way to unify options which have the same meaning or purpose,
         
     | 
| 
      
 178 
     | 
    
         
            +
            but contain some differences in their definitions (e.g. the name/switch of an option).
         
     | 
| 
      
 179 
     | 
    
         
            +
            Mainly serves as a container for options, which purpose is to show less repetitive
         
     | 
| 
      
 180 
     | 
    
         
            +
            output in commands' help. Option builders use it by default.
         
     | 
| 
      
 181 
     | 
    
         
            +
             
     | 
| 
      
 182 
     | 
    
         
            +
            To define an option family, use the following DSL:
         
     | 
| 
      
 183 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 184 
     | 
    
         
            +
              # options is a Hash with options for family/each defined option within it
         
     | 
| 
      
 185 
     | 
    
         
            +
              option_family(options = {}) do
         
     | 
| 
      
 186 
     | 
    
         
            +
                # parent is the main option. Must be single, option family can have only one parent.
         
     | 
| 
      
 187 
     | 
    
         
            +
                parent switches, type, description, options
         
     | 
| 
      
 188 
     | 
    
         
            +
                # child  is an additional option. Could be none or more than one. Aren't shown in the help output.
         
     | 
| 
      
 189 
     | 
    
         
            +
                child  switches, type, description, options
         
     | 
| 
      
 190 
     | 
    
         
            +
              end
         
     | 
| 
      
 191 
     | 
    
         
            +
            ```
         
     | 
| 
      
 192 
     | 
    
         
            +
             
     | 
| 
      
 193 
     | 
    
         
            +
            ##### Example
         
     | 
| 
      
 194 
     | 
    
         
            +
             
     | 
| 
      
 195 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 196 
     | 
    
         
            +
              option_family(
         
     | 
| 
      
 197 
     | 
    
         
            +
                aliased_resource: 'environment',
         
     | 
| 
      
 198 
     | 
    
         
            +
                description: _('Puppet environment'),
         
     | 
| 
      
 199 
     | 
    
         
            +
                deprecation: _("Use %s instead") % '--puppet-environment[-id]'
         
     | 
| 
      
 200 
     | 
    
         
            +
                deprecated: { '--environment' => _("Use %s instead") % '--puppet-environment[-id]',
         
     | 
| 
      
 201 
     | 
    
         
            +
                              '--environment-id' => _("Use %s instead") % '--puppet-environment[-id]'}
         
     | 
| 
      
 202 
     | 
    
         
            +
              ) do
         
     | 
| 
      
 203 
     | 
    
         
            +
                parent '--environment-id', 'ENVIRONMENT_ID', _(''),
         
     | 
| 
      
 204 
     | 
    
         
            +
                       format: HammerCLI::Options::Normalizers::Number.new,
         
     | 
| 
      
 205 
     | 
    
         
            +
                       attribute_name: :option_environment_id
         
     | 
| 
      
 206 
     | 
    
         
            +
                child '--environment', 'ENVIRONMENT_NAME', _('Environment name'),
         
     | 
| 
      
 207 
     | 
    
         
            +
                      attribute_name: :option_environment_name
         
     | 
| 
      
 208 
     | 
    
         
            +
              end
         
     | 
| 
      
 209 
     | 
    
         
            +
             
     | 
| 
      
 210 
     | 
    
         
            +
              # $ hammer command --help:
         
     | 
| 
      
 211 
     | 
    
         
            +
              # ...
         
     | 
| 
      
 212 
     | 
    
         
            +
              #  Options:
         
     | 
| 
      
 213 
     | 
    
         
            +
              #    --environment[-id]               Puppet environment (Deprecated: Use --puppet-environment[-id] instead)
         
     | 
| 
      
 214 
     | 
    
         
            +
              # ...
         
     | 
| 
      
 215 
     | 
    
         
            +
             
     | 
| 
      
 216 
     | 
    
         
            +
              # $ hammer full-help:
         
     | 
| 
      
 217 
     | 
    
         
            +
              # ...
         
     | 
| 
      
 218 
     | 
    
         
            +
              #  Options:
         
     | 
| 
      
 219 
     | 
    
         
            +
              #    --environment   ENVIRONMENT_NAME    Environment name (--environment is deprecated: Use --puppet-environment[-id] instead)
         
     | 
| 
      
 220 
     | 
    
         
            +
              #    --environment-id   ENVIRONMENT_ID    (--environment-id is deprecated: Use --puppet-environment[-id] instead)
         
     | 
| 
      
 221 
     | 
    
         
            +
              # ...
         
     | 
| 
      
 222 
     | 
    
         
            +
            ```
         
     | 
| 
      
 223 
     | 
    
         
            +
             
     | 
| 
       176 
224 
     | 
    
         
             
            ### Option builders
         
     | 
| 
       177 
225 
     | 
    
         
             
            Hammer commands offer option builders that can be used for automatic option generation.
         
     | 
| 
       178 
226 
     | 
    
         
             
            See [documentation page](option_builders.md#option-builders) dedicated to this topic for more details.
         
     | 
| 
         @@ -406,6 +454,31 @@ Options: 
     | 
|
| 
       406 
454 
     | 
    
         
             
                -h, --help                    print help
         
     | 
| 
       407 
455 
     | 
    
         
             
            ```
         
     | 
| 
       408 
456 
     | 
    
         | 
| 
      
 457 
     | 
    
         
            +
            #### Aliasing subcommands
         
     | 
| 
      
 458 
     | 
    
         
            +
             
     | 
| 
      
 459 
     | 
    
         
            +
            Commands can have two or more names, e.g. aliases. To support such functionality
         
     | 
| 
      
 460 
     | 
    
         
            +
            simple name addition could be used via `command_name` or `command_names` method:
         
     | 
| 
      
 461 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 462 
     | 
    
         
            +
            module HammerCLIHello
         
     | 
| 
      
 463 
     | 
    
         
            +
             
     | 
| 
      
 464 
     | 
    
         
            +
              class SayCommand < HammerCLI::AbstractCommand
         
     | 
| 
      
 465 
     | 
    
         
            +
             
     | 
| 
      
 466 
     | 
    
         
            +
                class GreetingsCommand < HammerCLI::AbstractCommand
         
     | 
| 
      
 467 
     | 
    
         
            +
                  command_name 'hello'
         
     | 
| 
      
 468 
     | 
    
         
            +
                  command_name 'hi'
         
     | 
| 
      
 469 
     | 
    
         
            +
                  # or use can use other method:
         
     | 
| 
      
 470 
     | 
    
         
            +
                  command_names 'hello', 'hi'
         
     | 
| 
      
 471 
     | 
    
         
            +
             
     | 
| 
      
 472 
     | 
    
         
            +
                  desc 'Say Hello World!'
         
     | 
| 
      
 473 
     | 
    
         
            +
                  # ...
         
     | 
| 
      
 474 
     | 
    
         
            +
                end
         
     | 
| 
      
 475 
     | 
    
         
            +
             
     | 
| 
      
 476 
     | 
    
         
            +
                autoload_subcommands
         
     | 
| 
      
 477 
     | 
    
         
            +
              end
         
     | 
| 
      
 478 
     | 
    
         
            +
             
     | 
| 
      
 479 
     | 
    
         
            +
              HammerCLI::MainCommand.subcommand 'say', "Say something", HammerCLIHello::SayCommand
         
     | 
| 
      
 480 
     | 
    
         
            +
            end
         
     | 
| 
      
 481 
     | 
    
         
            +
            ```
         
     | 
| 
       409 
482 
     | 
    
         | 
| 
       410 
483 
     | 
    
         
             
            ### Conflicting subcommands
         
     | 
| 
       411 
484 
     | 
    
         
             
            It can happen that two different plugins define subcommands with the same name by accident.
         
     | 
| 
         @@ -494,6 +567,33 @@ You first create an _output definition_ that you apply to your data. The result 
     | 
|
| 
       494 
567 
     | 
    
         
             
            is a collection of fields, each having its type. The collection is then passed to an
         
     | 
| 
       495 
568 
     | 
    
         
             
            _output adapter_ which handles the actual formatting and printing.
         
     | 
| 
       496 
569 
     | 
    
         | 
| 
      
 570 
     | 
    
         
            +
            Adapters support printing by chunks, e.g. if you want to print a large set of
         
     | 
| 
      
 571 
     | 
    
         
            +
            data (1000+ records), but you make several calls to the server instead of one,
         
     | 
| 
      
 572 
     | 
    
         
            +
            you may want to print received data right away instead of waiting for the rest.
         
     | 
| 
      
 573 
     | 
    
         
            +
            This can be achieved via `:current_chunk` option for
         
     | 
| 
      
 574 
     | 
    
         
            +
            `print_collection` and `print_data` methods. Allowed values for `:current_chunk`
         
     | 
| 
      
 575 
     | 
    
         
            +
            are `:first`, `:another`, `:last`. By default adapters use `:single` value that
         
     | 
| 
      
 576 
     | 
    
         
            +
            means only one record will be printed.
         
     | 
| 
      
 577 
     | 
    
         
            +
             
     | 
| 
      
 578 
     | 
    
         
            +
            ##### Printing by chunks
         
     | 
| 
      
 579 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 580 
     | 
    
         
            +
            # ...
         
     | 
| 
      
 581 
     | 
    
         
            +
              def execute
         
     | 
| 
      
 582 
     | 
    
         
            +
                loop do
         
     | 
| 
      
 583 
     | 
    
         
            +
                  # ...
         
     | 
| 
      
 584 
     | 
    
         
            +
                  data = send_request
         
     | 
| 
      
 585 
     | 
    
         
            +
                  print_data(data, current_chunk: :first)
         
     | 
| 
      
 586 
     | 
    
         
            +
                  # ...
         
     | 
| 
      
 587 
     | 
    
         
            +
                  data = send_request
         
     | 
| 
      
 588 
     | 
    
         
            +
                  print_data(data, current_chunk: :another)
         
     | 
| 
      
 589 
     | 
    
         
            +
                  # ...
         
     | 
| 
      
 590 
     | 
    
         
            +
                  data = send_request
         
     | 
| 
      
 591 
     | 
    
         
            +
                  print_data(data, current_chunk: :last)
         
     | 
| 
      
 592 
     | 
    
         
            +
                end
         
     | 
| 
      
 593 
     | 
    
         
            +
              end
         
     | 
| 
      
 594 
     | 
    
         
            +
            # ...
         
     | 
| 
      
 595 
     | 
    
         
            +
            ```
         
     | 
| 
      
 596 
     | 
    
         
            +
             
     | 
| 
       497 
597 
     | 
    
         
             
            Hammer provides a DSL for defining the output. Next rather complex example will
         
     | 
| 
       498 
598 
     | 
    
         
             
            explain how to use it in action.
         
     | 
| 
       499 
599 
     | 
    
         | 
    
        data/doc/installation.md
    CHANGED
    
    | 
         @@ -132,8 +132,51 @@ And you are done. Your hammer client is configured and ready to use. 
     | 
|
| 
       132 
132 
     | 
    
         
             
            Autocompletion
         
     | 
| 
       133 
133 
     | 
    
         
             
            --------------
         
     | 
| 
       134 
134 
     | 
    
         | 
| 
       135 
     | 
    
         
            -
             
     | 
| 
       136 
     | 
    
         
            -
             
     | 
| 
       137 
     | 
    
         
            -
             
     | 
| 
      
 135 
     | 
    
         
            +
            The completion offers suggestion of possible command-line subcommands and their
         
     | 
| 
      
 136 
     | 
    
         
            +
            options as usual. It can also suggest values for options and params where file
         
     | 
| 
      
 137 
     | 
    
         
            +
            or directory path is expected.
         
     | 
| 
      
 138 
     | 
    
         
            +
             
     | 
| 
      
 139 
     | 
    
         
            +
            Bash completion is automatically installed by RPM. To use it for development
         
     | 
| 
      
 140 
     | 
    
         
            +
            setup `cp ./config/hammer.completion /etc/bash_completion.d/hammer` and load it
         
     | 
| 
      
 141 
     | 
    
         
            +
            to the current shell `source /etc/bash_completion.d/hammer`. Make sure
         
     | 
| 
      
 142 
     | 
    
         
            +
            the `$PWD/bin` is in `PATH` or there is full path to `hammer-complete`
         
     | 
| 
      
 143 
     | 
    
         
            +
            executable specified in `/etc/bash_completion.d/hammer`.
         
     | 
| 
      
 144 
     | 
    
         
            +
             
     | 
| 
      
 145 
     | 
    
         
            +
            Bash completion for hammer needs pre-built cache that holds description of
         
     | 
| 
      
 146 
     | 
    
         
            +
            all subcommands and its parameters. The cache is located by default in
         
     | 
| 
      
 147 
     | 
    
         
            +
            `~/.cache/hammer_completion.yml`. The location can be changed in hammer's
         
     | 
| 
      
 148 
     | 
    
         
            +
            config file. The cache can be built manually with
         
     | 
| 
      
 149 
     | 
    
         
            +
            `hammer prebuild-bash-completion` or is built automatically when completion is
         
     | 
| 
      
 150 
     | 
    
         
            +
            used and the cache is missing (this may cause slight delay). The cache expires
         
     | 
| 
      
 151 
     | 
    
         
            +
            if your API cache was changed (it indicates that the features on the instance
         
     | 
| 
      
 152 
     | 
    
         
            +
            may have changed which has impact on hammer CLI options and subcommands).
         
     | 
| 
      
 153 
     | 
    
         
            +
             
     | 
| 
      
 154 
     | 
    
         
            +
            ####  Available value types
         
     | 
| 
      
 155 
     | 
    
         
            +
             
     | 
| 
      
 156 
     | 
    
         
            +
            Completion of values is dependent on CLI option and prameter settings, e.g.:
         
     | 
| 
      
 157 
     | 
    
         
            +
             
     | 
| 
      
 158 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 159 
     | 
    
         
            +
              option '--value', 'VALUE', 'One of a, b, c', completion: { type: :enum, values: %w[a b c] }
         
     | 
| 
      
 160 
     | 
    
         
            +
            ```
         
     | 
| 
       138 
161 
     | 
    
         | 
| 
       139 
     | 
    
         
            -
             
     | 
| 
      
 162 
     | 
    
         
            +
            Possible options for the `:completion` attribute are:
         
     | 
| 
      
 163 
     | 
    
         
            +
             - `{ type: :flag }` option has no value, default for flags.
         
     | 
| 
      
 164 
     | 
    
         
            +
             - `{ type: :value }` option has value of unknown type, no suggestions for the
         
     | 
| 
      
 165 
     | 
    
         
            +
            value, default.
         
     | 
| 
      
 166 
     | 
    
         
            +
            - `{ type: :list }` option has value of list type, no suggestions for the
         
     | 
| 
      
 167 
     | 
    
         
            +
            value.
         
     | 
| 
      
 168 
     | 
    
         
            +
            - `{ type: :key_value_list }` option has value of key=value list type, no
         
     | 
| 
      
 169 
     | 
    
         
            +
            suggestions for the value.
         
     | 
| 
      
 170 
     | 
    
         
            +
             - `{ type: :directory }` value is directory, suggestions follow directory
         
     | 
| 
      
 171 
     | 
    
         
            +
            structure.
         
     | 
| 
      
 172 
     | 
    
         
            +
             - `{ type: :file, filter: '\.txt$' }` value is file, suggestions follow
         
     | 
| 
      
 173 
     | 
    
         
            +
            directory structure, optional `:filter` is regexp to filter the results.
         
     | 
| 
      
 174 
     | 
    
         
            +
             - `{ type: :enum, values: ['first', 'second']}` option can have one of the
         
     | 
| 
      
 175 
     | 
    
         
            +
            listed values, suggestions follow specified `values`.
         
     | 
| 
      
 176 
     | 
    
         
            +
             - `{ type: :multienum, values: ['first', 'second']}` option can have one or
         
     | 
| 
      
 177 
     | 
    
         
            +
            more of the listed values, suggestions follow specified `values`.
         
     | 
| 
      
 178 
     | 
    
         
            +
             - `{ type: :schema, schema: 'a=int\,b=string' }` option should have value
         
     | 
| 
      
 179 
     | 
    
         
            +
            according to specified schema, suggestion is the specified schema.
         
     | 
| 
      
 180 
     | 
    
         
            +
             
     | 
| 
      
 181 
     | 
    
         
            +
            All those completion attributes are generated automatically, specify you own to
         
     | 
| 
      
 182 
     | 
    
         
            +
            override.
         
     | 
    
        data/doc/installation_rpm.md
    CHANGED
    
    | 
         @@ -1,8 +1,8 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ### Installation from RPMs
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
     | 
    
         
            -
            #### Step 1:  
     | 
| 
      
 3 
     | 
    
         
            +
            #### Step 1: set up yum repositories
         
     | 
| 
       4 
4 
     | 
    
         | 
| 
       5 
     | 
    
         
            -
            For Foreman 1.3 stable the hammer packages are part of your installation repo and you can skip this step.
         
     | 
| 
      
 5 
     | 
    
         
            +
            For Foreman 1.3 stable, the hammer packages are part of your installation repo and you can skip this step.
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
       7 
7 
     | 
    
         
             
            You can choose from stable or nightly repo. Nightly has more recent version of hammer packages, but it was subject to less testing so there is a higher risk of issues.
         
     | 
| 
       8 
8 
     | 
    
         
             
            Add the Foreman yum repository to your yum repo files. For Fedora installations replace 'el6' with 'f18' or 'f19' as appropriate.
         
     | 
    
        data/doc/release_notes.md
    CHANGED
    
    | 
         @@ -1,15 +1,40 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            Release notes
         
     | 
| 
       2 
2 
     | 
    
         
             
            =============
         
     | 
| 
       3 
     | 
    
         
            -
            ###  
     | 
| 
      
 3 
     | 
    
         
            +
            ### 2.2.0 (2020-08-11)
         
     | 
| 
      
 4 
     | 
    
         
            +
            * Update installation_rpm.md ([PR #333](https://github.com/theforeman/hammer-cli/pull/333))
         
     | 
| 
      
 5 
     | 
    
         
            +
            * Clean gem_release.ipynb up
         
     | 
| 
      
 6 
     | 
    
         
            +
            * Replace awesome_print with amazing_print ([PR #330](https://github.com/theforeman/hammer-cli/pull/330)), [#29846](http://projects.theforeman.org/issues/29846)
         
     | 
| 
      
 7 
     | 
    
         
            +
            * Fix typo: s/filed/feild/ ([PR #331](https://github.com/theforeman/hammer-cli/pull/331))
         
     | 
| 
      
 8 
     | 
    
         
            +
            * Bump to 2.2.0-develop
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            ### 2.1.0 (2020-05-14)
         
     | 
| 
      
 11 
     | 
    
         
            +
            * Hammer full-help returns correct output, [#29697](http://projects.theforeman.org/issues/29697)
         
     | 
| 
      
 12 
     | 
    
         
            +
            * Add fuzzy subcommand matching, [#29413](http://projects.theforeman.org/issues/29413)
         
     | 
| 
      
 13 
     | 
    
         
            +
            * Help contains squeezed options, [#28440](http://projects.theforeman.org/issues/28440)
         
     | 
| 
      
 14 
     | 
    
         
            +
            * Keep referenced resource in option options, [#29015](http://projects.theforeman.org/issues/29015)
         
     | 
| 
      
 15 
     | 
    
         
            +
            * Bump to 2.1.0-develop
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            ### 2.0.0 (2020-02-12)
         
     | 
| 
      
 18 
     | 
    
         
            +
            * Bump version to 2.0.0
         
     | 
| 
      
 19 
     | 
    
         
            +
            * Bump version to 2.0 ([PR #324](https://github.com/theforeman/hammer-cli/pull/324))
         
     | 
| 
      
 20 
     | 
    
         
            +
            * Better promts for missing arguments, [#28793](http://projects.theforeman.org/issues/28793)
         
     | 
| 
       4 
21 
     | 
    
         
             
            * Allow column max width more than 80, [#28503](http://projects.theforeman.org/issues/28503)
         
     | 
| 
      
 22 
     | 
    
         
            +
            * Remove computing sha, [#27728](http://projects.theforeman.org/issues/27728)
         
     | 
| 
      
 23 
     | 
    
         
            +
            * Fixed userdata false display in image list, [#28134](http://projects.theforeman.org/issues/28134)
         
     | 
| 
      
 24 
     | 
    
         
            +
            * Add new bash completion, [#27728](http://projects.theforeman.org/issues/27728)
         
     | 
| 
      
 25 
     | 
    
         
            +
            * Allow adapters print page by page, [#17819](http://projects.theforeman.org/issues/17819)
         
     | 
| 
      
 26 
     | 
    
         
            +
            * Add release documentation ([PR #317](https://github.com/theforeman/hammer-cli/pull/317)), [#28149](http://projects.theforeman.org/issues/28149)
         
     | 
| 
      
 27 
     | 
    
         
            +
            * Fix pr links in release notes ([PR #318](https://github.com/theforeman/hammer-cli/pull/318)), [#28202](http://projects.theforeman.org/issues/28202)
         
     | 
| 
       5 
28 
     | 
    
         
             
            * Extract table generator into reusable component ([PR #314](https://github.com/theforeman/hammer-cli/pull/314)), [#27318](http://projects.theforeman.org/issues/27318)
         
     | 
| 
      
 29 
     | 
    
         
            +
            * Better prompts for missing arguments ([PR #313](https://github.com/theforeman/hammer-cli/pull/313)), [#27595](http://projects.theforeman.org/issues/27595)
         
     | 
| 
      
 30 
     | 
    
         
            +
            * Bump to 0.20-develop
         
     | 
| 
       6 
31 
     | 
    
         | 
| 
       7 
32 
     | 
    
         
             
            ### 0.19.0 (2019-10-26)
         
     | 
| 
       8 
     | 
    
         
            -
            * Allow schema building for custom options ([PR #316](https://github.com/ 
     | 
| 
       9 
     | 
    
         
            -
            * New lines in text attr dont break output ([PR #300](https://github.com/ 
     | 
| 
       10 
     | 
    
         
            -
            * Added error to wrong --output ([PR #315](https://github.com/ 
     | 
| 
       11 
     | 
    
         
            -
            * Pr review checklist ([PR #305](https://github.com/ 
     | 
| 
       12 
     | 
    
         
            -
            * List items in help with customization ([PR #309](https://github.com/ 
     | 
| 
      
 33 
     | 
    
         
            +
            * Allow schema building for custom options ([PR #316](https://github.com/theforeman/hammer-cli/pull/316)), [#27899](http://projects.theforeman.org/issues/27899)
         
     | 
| 
      
 34 
     | 
    
         
            +
            * New lines in text attr dont break output ([PR #300](https://github.com/theforeman/hammer-cli/pull/300)), [#25878](http://projects.theforeman.org/issues/25878)
         
     | 
| 
      
 35 
     | 
    
         
            +
            * Added error to wrong --output ([PR #315](https://github.com/theforeman/hammer-cli/pull/315)), [#21590](http://projects.theforeman.org/issues/21590)
         
     | 
| 
      
 36 
     | 
    
         
            +
            * Pr review checklist ([PR #305](https://github.com/theforeman/hammer-cli/pull/305)), [#26950](http://projects.theforeman.org/issues/26950)
         
     | 
| 
      
 37 
     | 
    
         
            +
            * List items in help with customization ([PR #309](https://github.com/theforeman/hammer-cli/pull/309)), [#27237](http://projects.theforeman.org/issues/27237)
         
     | 
| 
       13 
38 
     | 
    
         | 
| 
       14 
39 
     | 
    
         
             
            ### 0.18.0 (2019-08-01)
         
     | 
| 
       15 
40 
     | 
    
         
             
            * Unsure minimal label length ([PR #310](https://github.com/theforeman/hammer-cli/pull/310)) ([#26960](http://projects.theforeman.org/issues/26960))
         
     | 
    
        data/lib/hammer_cli.rb
    CHANGED
    
    
    
        data/lib/hammer_cli/abstract.rb
    CHANGED
    
    | 
         @@ -13,6 +13,7 @@ require 'hammer_cli/options/predefined' 
     | 
|
| 
       13 
13 
     | 
    
         
             
            require 'hammer_cli/help/builder'
         
     | 
| 
       14 
14 
     | 
    
         
             
            require 'hammer_cli/help/text_builder'
         
     | 
| 
       15 
15 
     | 
    
         
             
            require 'hammer_cli/command_extensions'
         
     | 
| 
      
 16 
     | 
    
         
            +
            require 'hammer_cli/options/option_family'
         
     | 
| 
       16 
17 
     | 
    
         
             
            require 'logging'
         
     | 
| 
       17 
18 
     | 
    
         | 
| 
       18 
19 
     | 
    
         
             
            module HammerCLI
         
     | 
| 
         @@ -74,6 +75,7 @@ module HammerCLI 
     | 
|
| 
       74 
75 
     | 
    
         
             
                  begin
         
     | 
| 
       75 
76 
     | 
    
         
             
                    begin
         
     | 
| 
       76 
77 
     | 
    
         
             
                      exit_code = super
         
     | 
| 
      
 78 
     | 
    
         
            +
                      context.delete(:fields)
         
     | 
| 
       77 
79 
     | 
    
         
             
                      raise "exit code must be integer" unless exit_code.is_a? Integer
         
     | 
| 
       78 
80 
     | 
    
         
             
                    rescue => e
         
     | 
| 
       79 
81 
     | 
    
         
             
                      exit_code = handle_exception(e)
         
     | 
| 
         @@ -190,10 +192,21 @@ module HammerCLI 
     | 
|
| 
       190 
192 
     | 
    
         
             
                    # skip switches that are already defined
         
     | 
| 
       191 
193 
     | 
    
         
             
                    next if option.nil? or option.switches.any? {|s| find_option(s) }
         
     | 
| 
       192 
194 
     | 
    
         | 
| 
      
 195 
     | 
    
         
            +
                    if option.respond_to?(:referenced_resource)
         
     | 
| 
      
 196 
     | 
    
         
            +
                      # Collect options that don't have family, but related to this parent.
         
     | 
| 
      
 197 
     | 
    
         
            +
                      children = find_options(
         
     | 
| 
      
 198 
     | 
    
         
            +
                        referenced_resource: option.referenced_resource.to_s,
         
     | 
| 
      
 199 
     | 
    
         
            +
                        aliased_resource: option.aliased_resource.to_s
         
     | 
| 
      
 200 
     | 
    
         
            +
                      ).select { |o| o.family.nil? || o.family.head.nil? }
         
     | 
| 
      
 201 
     | 
    
         
            +
                      children.each do |child|
         
     | 
| 
      
 202 
     | 
    
         
            +
                        option.family.adopt(child) if option.family
         
     | 
| 
      
 203 
     | 
    
         
            +
                      end
         
     | 
| 
      
 204 
     | 
    
         
            +
                    end
         
     | 
| 
       193 
205 
     | 
    
         
             
                    declared_options << option
         
     | 
| 
       194 
206 
     | 
    
         
             
                    block ||= option.default_conversion_block
         
     | 
| 
       195 
207 
     | 
    
         
             
                    define_accessors_for(option, &block)
         
     | 
| 
       196 
208 
     | 
    
         
             
                    extend_options_help(option) if option.value_formatter.is_a?(HammerCLI::Options::Normalizers::ListNested)
         
     | 
| 
      
 209 
     | 
    
         
            +
                    completion_type_for(option)
         
     | 
| 
       197 
210 
     | 
    
         
             
                  end
         
     | 
| 
       198 
211 
     | 
    
         
             
                end
         
     | 
| 
       199 
212 
     | 
    
         | 
| 
         @@ -205,6 +218,7 @@ module HammerCLI 
     | 
|
| 
       205 
218 
     | 
    
         
             
                    extension.delegatee(self)
         
     | 
| 
       206 
219 
     | 
    
         
             
                    extension.extend_predefined_options(self)
         
     | 
| 
       207 
220 
     | 
    
         
             
                    extension.extend_options(self)
         
     | 
| 
      
 221 
     | 
    
         
            +
                    extension.extend_option_family(self)
         
     | 
| 
       208 
222 
     | 
    
         
             
                    extension.extend_output(self)
         
     | 
| 
       209 
223 
     | 
    
         
             
                    extension.extend_help(self)
         
     | 
| 
       210 
224 
     | 
    
         
             
                    logger('Extensions').info "Applied #{extension.details} on #{self}."
         
     | 
| 
         @@ -220,6 +234,12 @@ module HammerCLI 
     | 
|
| 
       220 
234 
     | 
    
         | 
| 
       221 
235 
     | 
    
         
             
                protected
         
     | 
| 
       222 
236 
     | 
    
         | 
| 
      
 237 
     | 
    
         
            +
                def self.option_family(options = {}, &block)
         
     | 
| 
      
 238 
     | 
    
         
            +
                  options[:creator] ||= self
         
     | 
| 
      
 239 
     | 
    
         
            +
                  family = HammerCLI::Options::OptionFamily.new(options)
         
     | 
| 
      
 240 
     | 
    
         
            +
                  family.instance_eval(&block)
         
     | 
| 
      
 241 
     | 
    
         
            +
                end
         
     | 
| 
      
 242 
     | 
    
         
            +
             
     | 
| 
       223 
243 
     | 
    
         
             
                def self.find_options(switch_filter, other_filters={})
         
     | 
| 
       224 
244 
     | 
    
         
             
                  filters = other_filters
         
     | 
| 
       225 
245 
     | 
    
         
             
                  if switch_filter.is_a? Hash
         
     | 
| 
         @@ -242,8 +262,8 @@ module HammerCLI 
     | 
|
| 
       242 
262 
     | 
    
         
             
                  output.print_record(definition, record)
         
     | 
| 
       243 
263 
     | 
    
         
             
                end
         
     | 
| 
       244 
264 
     | 
    
         | 
| 
       245 
     | 
    
         
            -
                def print_collection(definition, collection)
         
     | 
| 
       246 
     | 
    
         
            -
                  output.print_collection(definition, collection)
         
     | 
| 
      
 265 
     | 
    
         
            +
                def print_collection(definition, collection, options = {})
         
     | 
| 
      
 266 
     | 
    
         
            +
                  output.print_collection(definition, collection, options)
         
     | 
| 
       247 
267 
     | 
    
         
             
                end
         
     | 
| 
       248 
268 
     | 
    
         | 
| 
       249 
269 
     | 
    
         
             
                def print_message(msg, msg_params = {}, options = {})
         
     | 
| 
         @@ -283,8 +303,17 @@ module HammerCLI 
     | 
|
| 
       283 
303 
     | 
    
         
             
                end
         
     | 
| 
       284 
304 
     | 
    
         | 
| 
       285 
305 
     | 
    
         
             
                def self.command_name(name=nil)
         
     | 
| 
       286 
     | 
    
         
            -
                  @ 
     | 
| 
       287 
     | 
    
         
            -
             
     | 
| 
      
 306 
     | 
    
         
            +
                  if @names && name
         
     | 
| 
      
 307 
     | 
    
         
            +
                    @names << name if !@names.include?(name)
         
     | 
| 
      
 308 
     | 
    
         
            +
                  else
         
     | 
| 
      
 309 
     | 
    
         
            +
                    @names = [name] if name
         
     | 
| 
      
 310 
     | 
    
         
            +
                  end
         
     | 
| 
      
 311 
     | 
    
         
            +
                  @names || (superclass.respond_to?(:command_names) ? superclass.command_names : nil)
         
     | 
| 
      
 312 
     | 
    
         
            +
                end
         
     | 
| 
      
 313 
     | 
    
         
            +
             
     | 
| 
      
 314 
     | 
    
         
            +
                def self.command_names(*names)
         
     | 
| 
      
 315 
     | 
    
         
            +
                  @names = names unless names.empty?
         
     | 
| 
      
 316 
     | 
    
         
            +
                  @names || (superclass.respond_to?(:command_names) ? superclass.command_names : nil)
         
     | 
| 
       288 
317 
     | 
    
         
             
                end
         
     | 
| 
       289 
318 
     | 
    
         | 
| 
       290 
319 
     | 
    
         
             
                def self.warning(message = nil)
         
     | 
| 
         @@ -314,6 +343,7 @@ module HammerCLI 
     | 
|
| 
       314 
343 
     | 
    
         
             
                    declared_options << option
         
     | 
| 
       315 
344 
     | 
    
         
             
                    block ||= option.default_conversion_block
         
     | 
| 
       316 
345 
     | 
    
         
             
                    define_accessors_for(option, &block)
         
     | 
| 
      
 346 
     | 
    
         
            +
                    completion_type_for(option, opts)
         
     | 
| 
       317 
347 
     | 
    
         
             
                  end
         
     | 
| 
       318 
348 
     | 
    
         
             
                  extend_options_help(option) if option.value_formatter.is_a?(HammerCLI::Options::Normalizers::ListNested)
         
     | 
| 
       319 
349 
     | 
    
         
             
                  option
         
     | 
| 
         @@ -352,6 +382,33 @@ module HammerCLI 
     | 
|
| 
       352 
382 
     | 
    
         
             
                  sources
         
     | 
| 
       353 
383 
     | 
    
         
             
                end
         
     | 
| 
       354 
384 
     | 
    
         | 
| 
      
 385 
     | 
    
         
            +
                def self.completion_map
         
     | 
| 
      
 386 
     | 
    
         
            +
                  completion = {}
         
     | 
| 
      
 387 
     | 
    
         
            +
                  # collect options
         
     | 
| 
      
 388 
     | 
    
         
            +
                  recognised_options.each do |opt|
         
     | 
| 
      
 389 
     | 
    
         
            +
                    opt.switches.each do |switch|
         
     | 
| 
      
 390 
     | 
    
         
            +
                      completion[switch] = completion_types.fetch(switch, {})
         
     | 
| 
      
 391 
     | 
    
         
            +
                    end
         
     | 
| 
      
 392 
     | 
    
         
            +
                  end
         
     | 
| 
      
 393 
     | 
    
         
            +
                  # collect subcommands recursively
         
     | 
| 
      
 394 
     | 
    
         
            +
                  recognised_subcommands.each do |cmd|
         
     | 
| 
      
 395 
     | 
    
         
            +
                    completion[cmd.names.first] = cmd.subcommand_class.completion_map
         
     | 
| 
      
 396 
     | 
    
         
            +
                  end
         
     | 
| 
      
 397 
     | 
    
         
            +
                  # collect params
         
     | 
| 
      
 398 
     | 
    
         
            +
                  completion[:params] = completion_types[:params] unless completion_types[:params].empty?
         
     | 
| 
      
 399 
     | 
    
         
            +
                  completion
         
     | 
| 
      
 400 
     | 
    
         
            +
                end
         
     | 
| 
      
 401 
     | 
    
         
            +
             
     | 
| 
      
 402 
     | 
    
         
            +
                def self.completion_types
         
     | 
| 
      
 403 
     | 
    
         
            +
                  @completion_types ||= { :params => [] }
         
     | 
| 
      
 404 
     | 
    
         
            +
                end
         
     | 
| 
      
 405 
     | 
    
         
            +
             
     | 
| 
      
 406 
     | 
    
         
            +
                def self.completion_type_for(option, opts = {})
         
     | 
| 
      
 407 
     | 
    
         
            +
                  completion_type = opts.delete(:completion)
         
     | 
| 
      
 408 
     | 
    
         
            +
                  completion_type ||= option.completion_type(opts[:format])
         
     | 
| 
      
 409 
     | 
    
         
            +
                  [option.switches].flatten(1).each { |s| completion_types[s] = completion_type }
         
     | 
| 
      
 410 
     | 
    
         
            +
                end
         
     | 
| 
      
 411 
     | 
    
         
            +
             
     | 
| 
       355 
412 
     | 
    
         
             
                private
         
     | 
| 
       356 
413 
     | 
    
         | 
| 
       357 
414 
     | 
    
         
             
                def self.inherited_output_definition
         
     |