From 063c5e91333d15b72f3c9470ed130a8189050be8 Mon Sep 17 00:00:00 2001 From: Jiri Stransky Date: Fri, 18 Jan 2013 18:15:19 +0100 Subject: [PATCH] Output: select fields you want for listings Closes #24. There is one gotcha. When user writes the option mistakenly like `--fields`, Thor automatically parses it the same way as if user had written `--fields=fields`, even though the `fields` option is configured to type `string`, so it should not be treated like a switch imho. Seems to me more like a bug than a feature, but I don't know how to write a *clean* wrokaround, so I'd rather keep it this way for now. --- features/usage.feature | 2 ++ lib/aeolus_cli/common_cli.rb | 20 ++++++++++++++++++++ lib/aeolus_cli/provider.rb | 3 ++- lib/aeolus_cli/provider_account.rb | 3 ++- spec/aeolus_cli/common_cli_spec.rb | 24 ++++++++++++++++++++++++ spec/aeolus_cli/formatting_spec.rb | 23 +++++++++++++++++++++++ 6 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 spec/aeolus_cli/common_cli_spec.rb create mode 100644 spec/aeolus_cli/formatting_spec.rb diff --git a/features/usage.feature b/features/usage.feature index 7b6e2ad..55fc86d 100644 --- a/features/usage.feature +++ b/features/usage.feature @@ -50,6 +50,7 @@ Feature: Usage aeolus provider list Options: + [--fields=FIELDS] # Fields (attributes) to print in the listing [--conductor-url=CONDUCTOR_URL] [--username=USERNAME] [--password=PASSWORD] @@ -85,6 +86,7 @@ Feature: Usage aeolus provider_account list Options: + [--fields=FIELDS] # Fields (attributes) to print in the listing [--conductor-url=CONDUCTOR_URL] [--username=USERNAME] [--password=PASSWORD] diff --git a/lib/aeolus_cli/common_cli.rb b/lib/aeolus_cli/common_cli.rb index 71a03c6..4c87409 100644 --- a/lib/aeolus_cli/common_cli.rb +++ b/lib/aeolus_cli/common_cli.rb @@ -45,6 +45,17 @@ def banner(task, namespace = nil, subcommand = false) # aeolus list #"#{basename} #{task.formatted_usage(self, $thor_runner, subcommand)}" end + + def method_options_for_resource_list + method_option_fields + # TODO: method_option_sort_by + end + + def method_option_fields + method_option :fields, + :type => :string, + :desc => 'Fields (attributes) to print in the listing' + end end def load_aeolus_config(options) @@ -125,6 +136,15 @@ def set_output_format(options) @output_format = AeolusCli::Formatting.create_format(shell, options) end + # Transforms e.g. 'name,status' into [:name, :status] + def resource_fields(fields_option) + return nil unless fields_option + if fields_option == '' + raise Thor::MalformattedArgumentError.new("Option 'fields' cannot be empty.") + end + fields_option.split(',').map { |option| option.to_sym } + end + def provider_type(type_s) # we need to hit the API to get the map of provider_type.name => # provider_type.id, so make sure we only do this once. diff --git a/lib/aeolus_cli/provider.rb b/lib/aeolus_cli/provider.rb index 33c254d..7fcb603 100644 --- a/lib/aeolus_cli/provider.rb +++ b/lib/aeolus_cli/provider.rb @@ -4,9 +4,10 @@ class AeolusCli::Provider < AeolusCli::CommonCli desc "list", "List all providers" + method_options_for_resource_list def list providers = AeolusCli::Model::Provider.all - output_format.list(providers) + output_format.list(providers, resource_fields(options[:fields])) end desc "add PROVIDER_NAME", "Add a provider" diff --git a/lib/aeolus_cli/provider_account.rb b/lib/aeolus_cli/provider_account.rb index d2b32f4..77fffc7 100644 --- a/lib/aeolus_cli/provider_account.rb +++ b/lib/aeolus_cli/provider_account.rb @@ -4,10 +4,11 @@ class AeolusCli::ProviderAccount < AeolusCli::CommonCli desc "list", "list provider accounts" + method_options_for_resource_list # TODO maybe an optional variable for provider_type def list accounts = AeolusCli::Model::ProviderAccount.all_full_detail - output_format.list(accounts) + output_format.list(accounts, resource_fields(options[:fields])) end desc "add PROVIDER_ACCOUNT_LABEL", "Add a provider account" diff --git a/spec/aeolus_cli/common_cli_spec.rb b/spec/aeolus_cli/common_cli_spec.rb new file mode 100644 index 0000000..b67153f --- /dev/null +++ b/spec/aeolus_cli/common_cli_spec.rb @@ -0,0 +1,24 @@ +require 'aeolus_cli/common_cli' + +describe AeolusCli::CommonCli do + let(:common_cli) { AeolusCli::CommonCli.new() } + + context "#resource_fields" do + context "non-empty fields" do + subject { common_cli.send(:resource_fields, "name,status,is_cool") } + it { should == [:name, :status, :is_cool] } + end + + context "empty fields" do + subject { common_cli.send(:resource_fields, "") } + it do + expect { subject }.to raise_error Thor::MalformattedArgumentError + end + end + + context "nil fields" do + subject { common_cli.send(:resource_fields, nil) } + it { should == nil } + end + end +end diff --git a/spec/aeolus_cli/formatting_spec.rb b/spec/aeolus_cli/formatting_spec.rb new file mode 100644 index 0000000..3ca97cc --- /dev/null +++ b/spec/aeolus_cli/formatting_spec.rb @@ -0,0 +1,23 @@ +require 'aeolus_cli/formatting' + +describe AeolusCli::Formatting do + let(:formatting) { AeolusCli::Formatting } + let(:shell) { double('shell') } + + context ".create_format" do + subject { formatting.create_format(shell, { :format => 'human' }) } + let(:human_format) { double('human format') } + let(:human_format_class) do + double('human format class').tap do |clazz| + clazz.stub(:new).with(shell).and_return(human_format) + end + end + + before do + formatting.should_receive(:require).with("aeolus_cli/formatting/human_format").and_return(true) + formatting.should_receive(:const_get).with("HumanFormat").and_return(human_format_class) + end + + it { should == human_format } + end +end