Skip to content

Commit

Permalink
Fixes #21634 - Allows modification of output fields
Browse files Browse the repository at this point in the history
  • Loading branch information
ofedoren committed Oct 18, 2018
1 parent b559403 commit c4f3594
Show file tree
Hide file tree
Showing 5 changed files with 352 additions and 7 deletions.
74 changes: 74 additions & 0 deletions doc/commands_modification.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
Modify an existing command
-------------------------

### Modification of output fields

Each command (as well as each field) might have its own
output definition. You can modify the output definition of existing
command or a specific field of that command by following output
definition interface:

```ruby
# Appends fields to the end.
# Where:
# fields is one or more existing fields
# block is block of code with new fields
append(fields) do
label
field
collection
end
# Inserts one or more fields.
# Where:
# :mode is one of [:before, :after, :replace]
# :id is field's id or key. Field's label can be used if field does not
# have id
# fields is one or more existing fields
# block is block of code with new fields
insert(:mode, :id, fields) do
label
field
collection
end
# Returns output definition of the command or field specified with path.
# Where:
# path = Array of :key or/and :id or/and 'label']
at(path)
# Returns field from current output definition.
find_field(:id)
# Deletes all fields from current output definition.
clear
```
#### Examples
```ruby
# Append some fields to the end
HammerCLIForeman::Host::InfoCommand.output_definition
.at('Collection Field Label')
.append do
field :value3, _('Value 3')
end
# Change field's label
HammerCLIForeman::Host::InfoCommand.output_definition
.at(:path)
.find_field(:id).label = _('New label')
# Expand a field with new definition
HammerCLIForeman::Host::InfoCommand.output_definition
.at(['some', :path])
.insert(:replace, :not_container_field_id) do
field nil, _('Label with new fields'), Fields::Label, id: :now_container_field_id do
field :new_field1, _('New field 1')
field :new_field2, _('New field 2')
end
end
# Insert a new field after specific field
HammerCLIForeman::Host::InfoCommand.output_definition
.at(['some', :path])
.insert(:after, :other_field_id, [Fields::Field.new(label: _('My field'), id: :my_field_id)])
# Insert a new field before specific field
HammerCLIForeman::Host::InfoCommand.output_definition
.insert(:before, :other_field_id,
Fields::Field.new(label: _('My field'), id: :my_field_id))
# Remove field
HammerCLIForeman::Host::InfoCommand.output_definition
.insert(:replace, :field_id) do; end
```
1 change: 1 addition & 0 deletions doc/developer_docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ before creating hammer specific plugins.
Contents:
- [Writing a plugin](writing_a_plugin.md#writing-your-own-hammer-plugin)
- [Creating commands](creating_commands.md#create-your-first-command)
- [Commands modification](commands_modification.md#modify-an-existing-command)
- [Option builders](option_builders.md#option-builders)
- [Creating ApiPie commands](creating_apipie_commands.md#creating-commands-for-restful-api-with-apipie)
- [Development tips](development_tips.md#development-tips)
Expand Down
55 changes: 51 additions & 4 deletions lib/hammer_cli/output/definition.rb
Original file line number Diff line number Diff line change
@@ -1,21 +1,68 @@
module HammerCLI::Output

class Definition

attr_accessor :fields

def initialize
@fields = []
end

def append(fields)
def append(fields = nil, &block)
fields = [fields].compact unless fields.is_a?(Array)
@fields += fields
return @fields unless block_given?
dsl = Dsl.new
dsl.build(&block)
@fields += dsl.fields
end

def find_field(field_id)
@fields[field_index(field_id)]
end

def insert(mode, field_id, fields = nil, &block)
index = field_index(field_id)
index += 1 if mode == :after
definition = self.class.new
definition.append(fields, &block)
insert_fields(index, definition.fields, with_remove: mode == :replace)
end

def at(path = [])
path = [path] unless path.is_a? Array
return self if path.empty?

field = find_field(path[0])

unless field.respond_to?(:output_definition)
raise ArgumentError, "Field #{path[0]} doesn't have nested output definition"
end

field.output_definition.at(path[1..-1])
end

def clear
@fields = []
end

def empty?
@fields.empty?
end

end
private

def field_index(field_id)
index = @fields.find_index do |f|
f.id == field_id
end
raise ArgumentError, "Field #{field_id} not found" if index.nil?
index
end

def insert_fields(index, fields, with_remove: false)
@fields.delete_at(index) if with_remove
fields.each_with_index do |f, i|
@fields.insert(index + i, f)
end
end
end
end
7 changes: 5 additions & 2 deletions lib/hammer_cli/output/fields.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@
module Fields

class Field

attr_reader :label
attr_reader :path
attr_accessor :label

def initialize(options={})
@hide_blank = options[:hide_blank].nil? ? false : options[:hide_blank]
Expand All @@ -15,6 +14,10 @@ def initialize(options={})
@options = options
end

def id
@options[:id] || @options[:key] || @label
end

def hide_blank?
@hide_blank
end
Expand Down
Loading

0 comments on commit c4f3594

Please sign in to comment.