diff options
author | Tom Duffield <tom@chef.io> | 2016-10-25 15:34:10 -0500 |
---|---|---|
committer | Tom Duffield <tom@chef.io> | 2016-10-28 14:20:49 -0500 |
commit | 1c7392cb2f002f700cbae31936512e7d73ae4a5d (patch) | |
tree | abbf6814a22dc1049b19a6c0ab32de3b6d42f08f | |
parent | daa20d6b7e6afb066760b7e7c59f1d9f2b4a409b (diff) | |
download | chef-1c7392cb2f002f700cbae31936512e7d73ae4a5d.tar.gz |
Add the `--field-separator` flag to knife show commands
For the commands that allow you to filter which attributes it shows you
using the `--attribute` flag, add the `--field-separator` flag to allow
the user to customize which character(s) they want to use to deliniate the
attribute hierarchy.
```shell
knife node show NODE -S: -a "packages:Chef Client v12.12.15"
```
Signed-off-by: Tom Duffield <tom@chef.io>
-rw-r--r-- | lib/chef/knife/core/generic_presenter.rb | 14 | ||||
-rw-r--r-- | spec/integration/knife/environment_show_spec.rb | 28 | ||||
-rw-r--r-- | spec/support/shared/integration/knife_support.rb | 5 | ||||
-rw-r--r-- | spec/unit/knife/core/ui_spec.rb | 10 |
4 files changed, 51 insertions, 6 deletions
diff --git a/lib/chef/knife/core/generic_presenter.rb b/lib/chef/knife/core/generic_presenter.rb index a963a24f12..861bf1510d 100644 --- a/lib/chef/knife/core/generic_presenter.rb +++ b/lib/chef/knife/core/generic_presenter.rb @@ -28,6 +28,11 @@ class Chef # :nodoc: def self.included(includer) includer.class_eval do + option :field_separator, + :short => "-S SEPARATOR", + :long => "--field-separator SEPARATOR", + :description => "Character separator used to delineate nesting in --attribute filters (default \".\")" + option :attribute, :short => "-a ATTR1 [-a ATTR2]", :long => "--attribute ATTR1 [--attribute ATTR2] ", @@ -175,8 +180,15 @@ class Chef config[:attribute] || config[:run_list] end + # GenericPresenter is used in contexts where MultiAttributeReturnOption + # is not, so we need to set the default value here rather than as part + # of the CLI option. + def attribute_field_separator + config[:field_separator] || "." + end + def extract_nested_value(data, nested_value_spec) - nested_value_spec.split(".").each do |attr| + nested_value_spec.split(attribute_field_separator).each do |attr| data = if data.is_a?(Array) data[attr.to_i] diff --git a/spec/integration/knife/environment_show_spec.rb b/spec/integration/knife/environment_show_spec.rb index e74bf6d05d..56422dc1a5 100644 --- a/spec/integration/knife/environment_show_spec.rb +++ b/spec/integration/knife/environment_show_spec.rb @@ -26,7 +26,7 @@ describe "knife environment show", :workstation do when_the_chef_server "has some environments" do before do environment "b", { - "default_attributes" => { "foo" => "bar" }, + "default_attributes" => { "foo" => "bar", "baz" => { "raz.my" => "mataz" } }, } end @@ -36,6 +36,8 @@ describe "knife environment show", :workstation do chef_type: environment cookbook_versions: default_attributes: + baz: + raz.my: mataz foo: bar description: json_class: Chef::Environment @@ -46,11 +48,29 @@ EOM # rubocop:enable Style/TrailingWhitespace it "shows the requested attribute of an environment" do - pending "KnifeSupport doesn't appear to pass this through correctly" - knife("environment show b -a foo").should_succeed <<EOM + knife("environment show b -a default_attributes").should_succeed <<EOM b: - foo: bar + default_attributes: + baz: + raz.my: mataz + foo: bar EOM end + + it "shows the requested nested attribute of an environment" do + knife("environment show b -a default_attributes.baz").should_succeed <<EON +b: + default_attributes.baz: + raz.my: mataz +EON + end + + it "shows the requested attribute of an environment with custom field separator" do + knife("environment show b -S: -a default_attributes:baz").should_succeed <<EOT +b: + default_attributes:baz: + raz.my: mataz +EOT + end end end diff --git a/spec/support/shared/integration/knife_support.rb b/spec/support/shared/integration/knife_support.rb index 1a374e1b84..4efa30a003 100644 --- a/spec/support/shared/integration/knife_support.rb +++ b/spec/support/shared/integration/knife_support.rb @@ -64,8 +64,11 @@ module KnifeSupport subcommand_class.load_deps instance = subcommand_class.new(args) + # Load configs + instance.merge_configs + # Capture stdout/stderr - instance.ui = Chef::Knife::UI.new(stdout, stderr, stdin, disable_editing: true) + instance.ui = Chef::Knife::UI.new(stdout, stderr, stdin, instance.config.merge(disable_editing: true)) # Don't print stuff Chef::Config[:verbosity] = ( DEBUG ? 2 : 0 ) diff --git a/spec/unit/knife/core/ui_spec.rb b/spec/unit/knife/core/ui_spec.rb index be77fd8501..38c72161e5 100644 --- a/spec/unit/knife/core/ui_spec.rb +++ b/spec/unit/knife/core/ui_spec.rb @@ -28,6 +28,7 @@ describe Chef::Knife::UI do :verbosity => 0, :yes => nil, :format => "summary", + :field_separator => ".", } @ui = Chef::Knife::UI.new(@out, @err, @in, @config) Chef::Config[:treat_deprecation_warnings_as_errors] = false @@ -410,6 +411,15 @@ EOM @ui.config[:attribute] = non_existing_path expect(@ui.format_for_display(input)).to eq({ "sample-data-bag-item" => { non_existing_path => nil } }) end + + describe "when --field-separator is passed" do + it "honors that separator" do + input = { "keys" => { "with spaces" => { "open" => { "doors" => { "with many.dots" => "when asked" } } } } } + @ui.config[:field_separator] = ";" + @ui.config[:attribute] = "keys;with spaces;open;doors;with many.dots" + expect(@ui.format_for_display(input)).to eq({ nil => { "keys;with spaces;open;doors;with many.dots" => "when asked" } }) + end + end end describe "with --run-list passed" do |