Hello community, here is the log from the commit of package rubygem-gli for openSUSE:Factory checked in at 2015-05-18 22:28:08 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/rubygem-gli (Old) and /work/SRC/openSUSE:Factory/.rubygem-gli.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "rubygem-gli" Changes: -------- --- /work/SRC/openSUSE:Factory/rubygem-gli/rubygem-gli.changes 2015-01-22 01:06:45.000000000 +0100 +++ /work/SRC/openSUSE:Factory/.rubygem-gli.new/rubygem-gli.changes 2015-05-18 22:28:09.000000000 +0200 @@ -1,0 +2,26 @@ +Wed May 13 04:29:16 UTC 2015 - co...@suse.com + +- updated to version 2.13.1 + no changelog found + +------------------------------------------------------------------- +Wed Mar 4 05:30:52 UTC 2015 - co...@suse.com + +- updated to version 2.13.0 + +------------------------------------------------------------------- +Mon Feb 23 05:29:04 UTC 2015 - co...@suse.com + +- updated to version 2.12.3 + +------------------------------------------------------------------- +Tue Feb 10 17:49:03 UTC 2015 - co...@suse.com + +- updated to version 2.12.2 + +------------------------------------------------------------------- +Mon Oct 13 12:11:58 UTC 2014 - co...@suse.com + +- adapt to new rubygem packaging + +------------------------------------------------------------------- Old: ---- gli-2.11.0.gem New: ---- gem2rpm.yml gli-2.13.1.gem ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ rubygem-gli.spec ++++++ --- /var/tmp/diff_new_pack.rsHqVv/_old 2015-05-18 22:28:10.000000000 +0200 +++ /var/tmp/diff_new_pack.rsHqVv/_new 2015-05-18 22:28:10.000000000 +0200 @@ -1,7 +1,7 @@ # # spec file for package rubygem-gli # -# Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -16,24 +16,27 @@ # +# +# This file was generated with a gem2rpm.yml and not just plain gem2rpm. +# All sections marked as MANUAL, license headers, summaries and descriptions +# can be maintained in that file. Please consult this file before editing any +# of those fields +# + Name: rubygem-gli -Version: 2.11.0 +Version: 2.13.1 Release: 0 %define mod_name gli %define mod_full_name %{mod_name}-%{version} -%define mod_branch -%{version} -%define mod_weight 21100 - BuildRoot: %{_tmppath}/%{name}-%{version}-build -%if 0%{?suse_version} <= 1310 -BuildRequires: ruby-macros >= 1 -%else -BuildRequires: ruby-macros >= 3 -%endif -BuildRequires: rubygem(rdoc) > 3.10 +BuildRequires: %{rubygem gem2rpm} +BuildRequires: %{rubygem rdoc > 3.10} +BuildRequires: %{ruby} +BuildRequires: ruby-macros >= 5 BuildRequires: update-alternatives Url: http://davetron5000.github.com/gli Source: http://rubygems.org/gems/%{mod_full_name}.gem +Source1: gem2rpm.yml Summary: Build command-suite CLI apps that are awesome License: Apache-2.0 Group: Development/Languages/Ruby @@ -42,89 +45,18 @@ %description Build command-suite CLI apps that are awesome. Bootstrap your app, add commands, options and documentation while maintaining a well-tested idiomatic -command-line app - -%package doc -Summary: RDoc documentation for %{mod_name} -Group: Development/Languages/Ruby -Requires: %{name} = %{version} - -%description doc -Documentation generated at gem installation time. -Usually in RDoc and RI formats. - -%package testsuite -Summary: Test suite for %{mod_name} -Group: Development/Languages/Ruby -Requires: %{name} = %{version} - -%description testsuite -Test::Unit or RSpec files, useful for developers. +command-line app. %prep -#gem_unpack -#if you need patches, apply them here and replace the # with a % sign in the surrounding lines -#gem_build %build %install -%gem_install -f -mkdir -p %{buildroot}%{_sysconfdir}/alternatives -mv %{buildroot}%{_bindir}/gli{,%{mod_branch}} -touch %{buildroot}%{_sysconfdir}/alternatives/gli -ln -s %{_sysconfdir}/alternatives/gli %{buildroot}%{_bindir}/gli - -mkdir -p %{buildroot}%{_docdir}/%{name} -%if 0%{?suse_version} <= 1310 -ln -s %{_libdir}/ruby/gems/%{rb_ver}/gems/%{mod_full_name}/LICENSE.txt %buildroot/%{_docdir}/%{name}/LICENSE.txt -ln -s %{_libdir}/ruby/gems/%{rb_ver}/gems/%{mod_full_name}/README.rdoc %buildroot/%{_docdir}/%{name}/README.rdoc -%else -ln -s %{gem_base}/gems/%{mod_full_name}/LICENSE.txt %buildroot/%{_docdir}/%{name}/LICENSE.txt -ln -s %{gem_base}/gems/%{mod_full_name}/README.rdoc %buildroot/%{_docdir}/%{name}/README.rdoc -%endif - -%post -/usr/sbin/update-alternatives --install \ - %{_bindir}/gli gli %{_bindir}/gli%{mod_branch} %{mod_weight} - -%preun -if [ "$1" = 0 ] ; then - /usr/sbin/update-alternatives --remove gli %{_bindir}/gli%{mod_branch} -fi - -%files -%defattr(-,root,root,-) -%{_docdir}/%{name} -%{_bindir}/gli%{mod_branch} -%{_bindir}/gli -%ghost %{_sysconfdir}/alternatives/gli -%if 0%{?suse_version} <= 1310 -%{_libdir}/ruby/gems/%{rb_ver}/cache/%{mod_full_name}.gem -%{_libdir}/ruby/gems/%{rb_ver}/gems/%{mod_full_name}/ -%exclude %{_libdir}/ruby/gems/%{rb_ver}/gems/%{mod_full_name}/test -%{_libdir}/ruby/gems/%{rb_ver}/specifications/%{mod_full_name}.gemspec -%else -%{gem_base}/cache/%{mod_full_name}.gem -%{gem_base}/gems/%{mod_full_name}/ -%exclude %{gem_base}/gems/%{mod_full_name}/test -%{gem_base}/specifications/%{mod_full_name}.gemspec -%endif - -%files doc -%defattr(-,root,root,-) -%if 0%{?suse_version} <= 1310 -%doc %{_libdir}/ruby/gems/%{rb_ver}/doc/%{mod_full_name}/ -%else -%doc %{gem_base}/doc -%endif - -%files testsuite -%defattr(-,root,root,-) -%if 0%{?suse_version} <= 1310 -%{_libdir}/ruby/gems/%{rb_ver}/gems/%{mod_full_name}/test -%else -%{gem_base}/gems/%{mod_full_name}/test -%endif +%gem_install \ + --symlink-binaries \ + --doc-files="LICENSE.txt README.rdoc" \ + -f + +%gem_packages %changelog ++++++ gem2rpm.yml ++++++ # --- # ## used by gem2rpm # :summary: this is a custom summary # ## used by gem2rpm # :description: |- # this is a custom description # # it can be multiline # ## used by gem2rpm # :license: MIT or Ruby # ## used by gem2rpm and gem_packages # :version_suffix: -x_y # ## used by gem2rpm and gem_packages # :disable_docs: true # ## used by gem2rpm # :disable_automatic_rdoc_dep: true # ## used by gem2rpm # :preamble: |- # BuildRequires: foobar # Requires: foobar # ## used by gem2rpm # :patches: # foo.patch: -p1 # bar.patch: # ## used by gem2rpm :sources: # - foo.desktop # - bar.desktop # :gem_install_args: '....' # ## used by gem2rpm # :pre_install: |- # %if 0%{?use_system_libev} # export USE_VENDORED_LIBEV="no" # %endif # ## used by gem2rpm # :post_install: |- # # delete custom files here or do other fancy stuff # install -D -m 0644 %{S:1} %{buildroot}%{_bindir}/gem2rpm-opensuse # ## used by gem2rpm # :testsuite_command: |- # (pushd %{buildroot}%{gem_base}/gems/%{mod_full_name} && rake test) # ## used by gem2rpm # :filelist: |- # /usr/bin/gem2rpm-opensuse # ## used by gem2rpm # :scripts: # :post: |- # /bin/echo foo # ## used by gem_packages # :main: # :preamble: |- # Requires: util-linux # Recommends: pwgen # :filelist: |- # /usr/bin/gem2rpm-opensuse # ## used by gem_packages # :custom: # apache: # :preamble: |- # Requires: ..... # :filelist: |- # /etc/apache2/conf.d/passenger.conf # :summary: Custom summary is optional # :description: |- # Custom description is optional # # bar # :post: |- # /bin/echo foo # ++++++ gli-2.11.0.gem -> gli-2.13.1.gem ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/.ruby-version new/.ruby-version --- old/.ruby-version 1970-01-01 01:00:00.000000000 +0100 +++ new/.ruby-version 2015-05-12 15:24:13.000000000 +0200 @@ -1 +1 @@ -2.0.0 +ruby-2.1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/.travis.yml new/.travis.yml --- old/.travis.yml 1970-01-01 01:00:00.000000000 +0100 +++ new/.travis.yml 2015-05-12 15:24:13.000000000 +0200 @@ -4,9 +4,8 @@ script: 'bundle exec rake test features' rvm: - 1.9.3 - - 1.8.7 - 2.0.0 - - 2.1.0 + - 2.1 branches: only: - 'gli-2' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/bin/gli new/bin/gli --- old/bin/gli 1970-01-01 01:00:00.000000000 +0100 +++ new/bin/gli 2015-05-12 15:24:13.000000000 +0200 @@ -9,6 +9,10 @@ version GLI::VERSION +# Can't use these without changing the current behavior of gli +# arguments :strict +# subcommand_option_handling :normal + switch :v, :desc => 'Be verbose' switch :n, :desc => 'Dry run; don''t change the disk' @@ -29,7 +33,9 @@ an executable ready to go, as well as a lib and test directory, all inside the directory named for your project EOS -arg_name 'project_name [command[ command]*]' +arg :project_name +arg :command_name, [:optional, :multiple] +arg_name "project_name [command_name][, [command_name]]*" command [:init,:scaffold] do |c| c.switch :e,:ext, :desc => 'Create an ext dir' Files old/checksums.yaml.gz and new/checksums.yaml.gz differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/features/gli_executable.feature new/features/gli_executable.feature --- old/features/gli_executable.feature 1970-01-01 01:00:00.000000000 +0100 +++ new/features/gli_executable.feature 2015-05-12 15:24:13.000000000 +0200 @@ -49,7 +49,7 @@ init - Create a new GLI-based project SYNOPSIS - gli [global options] init [command options] project_name [command[ command]*] + gli [global options] init [command options] project_name [command_name][, [command_name]]* DESCRIPTION This will create a scaffold command line project that uses GLI for command diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/features/gli_init.feature new/features/gli_init.feature --- old/features/gli_init.feature 1970-01-01 01:00:00.000000000 +0100 +++ new/features/gli_init.feature 2015-05-12 15:24:13.000000000 +0200 @@ -139,6 +139,7 @@ 2 steps (2 passed) """ + @wip Scenario Outline: Scaffold generates and respects flags to create ext dir and avoid test dir When I run `<command>` Then the exit status should be 0 @@ -229,4 +230,4 @@ Then the output should contain "complete command ran" When I run `bin/todo-app foobar` Then the stderr should contain "error: Unknown command 'foobar'" - And the exit status should not be 0 \ No newline at end of file + And the exit status should not be 0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/features/step_definitions/todo_steps.rb new/features/step_definitions/todo_steps.rb --- old/features/step_definitions/todo_steps.rb 1970-01-01 01:00:00.000000000 +0100 +++ new/features/step_definitions/todo_steps.rb 2015-05-12 15:24:13.000000000 +0200 @@ -30,28 +30,28 @@ config = File.open(File.join(ENV['HOME'],'gli_test_todo.rc')) do |file| YAML::load(file) end - config.keys.should include(:flag) - config[:flag].should == 'foo' + expect(config.keys).to include(:flag) + expect(config[:flag]).to eq('foo') config[:flag].tap do |flag| if flag.respond_to?(:encoding) - flag.encoding.name.should == 'UTF-8' + expect(flag.encoding.name).to eq('UTF-8') end end - config.keys.should include(:switch) - config[:switch].should == true - config.keys.should include(:otherswitch) - config[:otherswitch].should == false - config.keys.should include('commands') + expect(config.keys).to include(:switch) + expect(config[:switch]).to eq(true) + expect(config.keys).to include(:otherswitch) + expect(config[:otherswitch]).to eq(false) + expect(config.keys).to include('commands') %w(chained chained2 create first list ls second).map(&:to_sym).each do |command_name| - config['commands'].keys.should include(command_name) + expect(config['commands'].keys).to include(command_name) end - config['commands'][:create].keys.should include('commands') - config['commands'][:create]['commands'].should include(:tasks) - config['commands'][:create]['commands'].should include(:contexts) + expect(config['commands'][:create].keys).to include('commands') + expect(config['commands'][:create]['commands']).to include(:tasks) + expect(config['commands'][:create]['commands']).to include(:contexts) - config['commands'][:list].keys.should include('commands') - config['commands'][:list]['commands'].should include(:tasks) - config['commands'][:list]['commands'].should include(:contexts) + expect(config['commands'][:list].keys).to include('commands') + expect(config['commands'][:list]['commands']).to include(:tasks) + expect(config['commands'][:list]['commands']).to include(:contexts) end Given /^a config file that specifies defaults for some commands with subcommands$/ do @@ -77,10 +77,10 @@ Then /^I should see the defaults for '(.*)' from the config file in the help$/ do |command_path| if command_path == 'list tasks' step %{the output should match /--flag.*default: foobar/} - unescape(all_output).should_not =~ /#{unescape("--otherflag.*default: crud")}/m + expect(unescape(all_output)).not_to match(/#{unescape("--otherflag.*default: crud")}/m) elsif command_path == 'list contexts' step %{the output should match /--otherflag.*default: crud/} - unescape(all_output).should_not =~ /#{unescape("--flag.*default: foobar")}/m + expect(unescape(all_output)).not_to match(/#{unescape("--flag.*default: foobar")}/m) else raise "Don't know how to test for command path #{command_path}" end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/features/support/env.rb new/features/support/env.rb --- old/features/support/env.rb 1970-01-01 01:00:00.000000000 +0100 +++ new/features/support/env.rb 2015-05-12 15:24:13.000000000 +0200 @@ -15,7 +15,6 @@ TMP_PATH = 'tmp/aruba' Before do - unset_bundler_env_vars # Not sure how else to get this dynamically @dirs = [TMP_PATH] @aruba_timeout_seconds = 5 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/features/todo.feature new/features/todo.feature --- old/features/todo.feature 1970-01-01 01:00:00.000000000 +0100 +++ new/features/todo.feature 2015-05-12 15:24:13.000000000 +0200 @@ -15,8 +15,8 @@ error: Unknown command 'unknown'. Use 'todo help' for a list of commands. """ - Scenario Outline: Getting Help for todo in general - When I successfully run `todo <help>` + Scenario: Getting Help for todo in general + When I successfully run `todo help` Then the exit status should be 0 Then the output should contain: """ @@ -52,9 +52,6 @@ second - third - """ - Examples: - | help | - | help | Scenario: Version display When I successfully run `todo --version` @@ -178,6 +175,8 @@ """ Scenario Outline: Getting Help for a top level command of todo + # No idea why I have to do this again. + Given todo's bin directory is in my path When I successfully run `todo <help_invocation>` Then the output should contain: """ @@ -185,7 +184,7 @@ list - List things, such as tasks or contexts SYNOPSIS - todo [global options] list [command options] [tasks] [--flag arg] [-x arg] + todo [global options] list [command options] [tasks] [--flag arg] [-x arg] [task][, [task]]* todo [global options] list [command options] contexts [--otherflag arg] [-b] [-f|--foobar] DESCRIPTION @@ -233,7 +232,7 @@ list - List things, such as tasks or contexts SYNOPSIS - todo [global options] list [command options] [tasks] [--flag arg] [-x arg] + todo [global options] list [command options] [tasks] [--flag arg] [-x arg] [task][, [task]]* todo [global options] list [command options] contexts [--otherflag arg] [-b] [-f|--foobar] DESCRIPTION @@ -258,7 +257,7 @@ list - List things, such as tasks or contexts SYNOPSIS - todo [global options] list [command options] [tasks] [--flag arg] [-x arg] + todo [global options] list [command options] [tasks] [--flag arg] [-x arg] [task][, [task]]* todo [global options] list [command options] contexts [--otherflag arg] [-b] [-f|--foobar] DESCRIPTION @@ -291,7 +290,7 @@ list - List things, such as tasks or contexts SYNOPSIS - todo [global options] list [command options] [tasks] [--flag arg] [-x arg] + todo [global options] list [command options] [tasks] [--flag arg] [-x arg] [task][, [task]]* todo [global options] list [command options] contexts [--otherflag arg] [-b] [-f|--foobar] DESCRIPTION @@ -315,7 +314,7 @@ tasks - List tasks SYNOPSIS - todo [global options] list tasks [command options] + todo [global options] list tasks [command options] [task][, [task]]* todo [global options] list tasks [command options] open DESCRIPTION @@ -502,7 +501,7 @@ list - List things, such as tasks or contexts SYNOPSIS - todo [global options] list [command options] [tasks] [subcommand options] + todo [global options] list [command options] [tasks] [subcommand options] [task][, [task]]* todo [global options] list [command options] contexts [subcommand options] DESCRIPTION @@ -544,3 +543,8 @@ todo [global options] second [argument] """ + Scenario: Generate app documentation + When I run `todo _doc` + Then the exit status should be 0 + And a file named "todo.rdoc" should exist + And the file "todo.rdoc" should contain "Lists all of your contexts, which are places you might be" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/features/todo_legacy.feature new/features/todo_legacy.feature --- old/features/todo_legacy.feature 1970-01-01 01:00:00.000000000 +0100 +++ new/features/todo_legacy.feature 2015-05-12 15:24:13.000000000 +0200 @@ -24,6 +24,8 @@ """ Scenario Outline: Getting Help for a top level command of todo + # No idea why I have to do this again. + Given todo_legacy's bin directory is in my path When I successfully run `todo <help_invocation>` Then the output should contain: """ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gli.gemspec new/gli.gemspec --- old/gli.gemspec 1970-01-01 01:00:00.000000000 +0100 +++ new/gli.gemspec 2015-05-12 15:24:13.000000000 +0200 @@ -25,9 +25,9 @@ s.add_development_dependency('rdoc', '~> 3.11') s.add_development_dependency('rainbow', '~> 1.1.1') s.add_development_dependency('clean_test') - s.add_development_dependency('cucumber', '1.2.3') - s.add_development_dependency('gherkin', '<= 2.11.6') - s.add_development_dependency('aruba', '0.5.1') # 0.5.3 randomly breaks with "LaunchError: no such file or directory" and only sometimes. + s.add_development_dependency('cucumber') + s.add_development_dependency('gherkin') + s.add_development_dependency('aruba') s.add_development_dependency('sdoc') s.add_development_dependency('faker','1.0.0') end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gli.rdoc new/gli.rdoc --- old/gli.rdoc 1970-01-01 01:00:00.000000000 +0100 +++ new/gli.rdoc 2015-05-12 15:24:13.000000000 +0200 @@ -1,6 +1,6 @@ == gli - create scaffolding for a GLI-powered application -v2.2.1 +v2.12.1 === Global Options === -r|--root arg @@ -28,46 +28,8 @@ === --version - +Display the program version === Commands -==== Command: <tt>help command</tt> -Shows a list of commands or help for one command - -Gets help for the application or its commands. Can also list the commands in a way helpful to creating a bash-style completion function -===== Options -===== -c -List commands one per line, to assist with shell completion - - - -==== Command: <tt>init|scaffold project_name [command[ command]*]</tt> -Create a new GLI-based project - -This will create a scaffold command line project that uses GLI -for command line processing. Specifically, this will create -an executable ready to go, as well as a lib and test directory, all -inside the directory named for your project -===== Options -===== -e|--[no-]ext -Create an ext dir - - - -===== --[no-]force -Overwrite/ignore existing files and directories - - - -===== --notest -Do not create a test or features dir - - - -===== --[no-]rvmrc -Create an .rvmrc based on your current RVM setup - - - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/gli/app.rb new/lib/gli/app.rb --- old/lib/gli/app.rb 1970-01-01 01:00:00.000000000 +0100 +++ new/lib/gli/app.rb 2015-05-12 15:24:13.000000000 +0200 @@ -291,6 +291,29 @@ @subcommand_option_handling_strategy = handling_strategy end + # How to handle argument validation. + # + # handling_strategy:: One of: + # +:loose+:: no argument validation. Use of `arg` or `arg_name` is for documentation purposes only. (Default) + # +:strict+:: arguments are validated according to their specification. +action+ blocks may assume + # the value of `arguments` matches the specification provided in `arg`. Note that to use + # this strategy, you must also be sure that +subcommand_option_handling+ is set. + def arguments(handling_strategy) + @argument_handling_strategy = handling_strategy + end + + + # Enables/Disables command autocomplete, where partially spelled commands are automatically expanded to their full form + # + # Example: + # When enabled, executing 'shake' would execute 'shake_hand' (if no 'shake' command is defined). + # When disabled, executing 'shake' would throw an UnknownCommand error + # + # +boolean+:: Boolean value to enable or disable autocomplete, respectively. True by default. + def autocomplete_commands(boolean) + @autocomplete = boolean + end + private def load_commands(path) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/gli/app_support.rb new/lib/gli/app_support.rb --- old/lib/gli/app_support.rb 1970-01-01 01:00:00.000000000 +0100 +++ new/lib/gli/app_support.rb 2015-05-12 15:24:13.000000000 +0200 @@ -26,8 +26,10 @@ @pre_block = false @post_block = false @default_command = :help + @autocomplete = false @around_block = nil @subcommand_option_handling_strategy = :legacy + @argument_handling_strategy = :loose clear_nexts end @@ -67,8 +69,10 @@ flags, switches, accepts, - @default_command, - self.subcommand_option_handling_strategy) + :default_command => @default_command, + :autocomplete => autocomplete, + :subcommand_option_handling_strategy => subcommand_option_handling_strategy, + :argument_handling_strategy => argument_handling_strategy) parsing_result = gli_option_parser.parse_options(args) parsing_result.convert_to_openstruct! if @use_openstruct @@ -201,10 +205,18 @@ end end + def argument_handling_strategy + @argument_handling_strategy || :loose + end + def subcommand_option_handling_strategy @subcommand_option_handling_strategy || :legacy end + def autocomplete + @autocomplete.nil? ? true : @autocomplete + end + private def handle_exception(ex,command) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/gli/command_finder.rb new/lib/gli/command_finder.rb --- old/lib/gli/command_finder.rb 1970-01-01 01:00:00.000000000 +0100 +++ new/lib/gli/command_finder.rb 2015-05-12 15:24:13.000000000 +0200 @@ -1,40 +1,57 @@ module GLI class CommandFinder - # Initialize a finder on the given list of commands, using default_command as the default if none found - def initialize(commands,default_command) - @default_command = default_command - @names_to_commands = {} - commands.each do |command_name,command| - @names_to_commands[command_name.to_s] = command - Array(command.aliases).each do |command_alias| - @names_to_commands[command_alias.to_s] = command - end - end + attr_accessor :options + + DEFAULT_OPTIONS = { + :default_command => nil, + :autocomplete => true + } + + def initialize(commands, options = {}) + self.options = DEFAULT_OPTIONS.merge(options) + self.commands_with_aliases = expand_with_aliases(commands) end - # Finds the command with the given name, allowing for partial matches. Returns the command named by - # the default command if no command with +name+ matched def find_command(name) - name ||= @default_command - - raise UnknownCommand.new("No command name given nor default available") if String(name).strip == '' + name = String(name || options[:default_command]).strip + raise UnknownCommand.new("No command name given nor default available") if name == '' - command_found = @names_to_commands.fetch(name.to_s) do |command_to_match| - find_command_by_partial_name(@names_to_commands, command_to_match) - end - if Array(command_found).empty? - raise UnknownCommand.new("Unknown command '#{name}'") - elsif command_found.kind_of? Array - raise AmbiguousCommand.new("Ambiguous command '#{name}'. It matches #{command_found.sort.join(',')}") + command_found = commands_with_aliases.fetch(name) do |command_to_match| + if options[:autocomplete] + found_match = find_command_by_partial_name(commands_with_aliases, command_to_match) + if found_match.kind_of? GLI::Command + if ENV["GLI_DEBUG"] == 'true' + $stderr.puts "Using '#{name}' as it's is short for #{found_match.name}." + $stderr.puts "Set autocomplete false for any command you don't want matched like this" + end + elsif found_match.kind_of?(Array) && !found_match.empty? + raise AmbiguousCommand.new("Ambiguous command '#{name}'. It matches #{found_match.sort.join(',')}") + end + found_match + end end + + raise UnknownCommand.new("Unknown command '#{name}'") if Array(command_found).empty? command_found end private + attr_accessor :commands_with_aliases + + def expand_with_aliases(commands) + expanded = {} + commands.each do |command_name, command| + expanded[command_name.to_s] = command + Array(command.aliases).each do |command_alias| + expanded[command_alias.to_s] = command + end + end + expanded + end - def find_command_by_partial_name(names_to_commands, command_to_match) - partial_matches = names_to_commands.keys.select { |command_name| command_name =~ /^#{command_to_match}/ } - return names_to_commands[partial_matches[0]] if partial_matches.size == 1 + def find_command_by_partial_name(commands_with_aliases, command_to_match) + partial_matches = commands_with_aliases.keys.select { |command_name| command_name =~ /^#{command_to_match}/ } + return commands_with_aliases[partial_matches[0]] if partial_matches.size == 1 partial_matches end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/gli/commands/help.rb new/lib/gli/commands/help.rb --- old/lib/gli/commands/help.rb 1970-01-01 01:00:00.000000000 +0100 +++ new/lib/gli/commands/help.rb 2015-05-12 15:24:13.000000000 +0200 @@ -59,7 +59,8 @@ super(:names => :help, :description => 'Shows a list of commands or help for one command', :arguments_name => 'command', - :long_desc => 'Gets help for the application or its commands. Can also list the commands in a way helpful to creating a bash-style completion function') + :long_desc => 'Gets help for the application or its commands. Can also list the commands in a way helpful to creating a bash-style completion function', + :arguments => [Argument.new(:command_name, [:multiple, :optional])]) @app = app @parent = app @sorter = SORTERS[@app.help_sort_type] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/gli/commands/help_modules/full_synopsis_formatter.rb new/lib/gli/commands/help_modules/full_synopsis_formatter.rb --- old/lib/gli/commands/help_modules/full_synopsis_formatter.rb 1970-01-01 01:00:00.000000000 +0100 +++ new/lib/gli/commands/help_modules/full_synopsis_formatter.rb 2015-05-12 15:24:13.000000000 +0200 @@ -27,10 +27,11 @@ def sub_options_doc(sub_options) sub_options_doc = sub_options.map { |_,option| - option.names_and_aliases.map { |name| + doc = option.names_and_aliases.map { |name| CommandLineOption.name_as_string(name,false) + (option.kind_of?(Flag) ? " #{option.argument_name }" : '') }.join('|') - }.map { |invocations| "[#{invocations}]" }.sort.join(' ').strip + option.required?? doc : "[#{doc}]" + }.sort.join(' ').strip end private diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/gli/commands/rdoc_document_listener.rb new/lib/gli/commands/rdoc_document_listener.rb --- old/lib/gli/commands/rdoc_document_listener.rb 1970-01-01 01:00:00.000000000 +0100 +++ new/lib/gli/commands/rdoc_document_listener.rb 2015-05-12 15:24:13.000000000 +0200 @@ -81,7 +81,7 @@ # Gives you a command in the current context and creates a new context of this command def command(name,aliases,desc,long_desc,arg_name,arg_options) - @io.puts "#{@nest}=== Command: <tt>#{([name] + aliases).join('|')} #{@arg_name_formatter.format(arg_name,arg_options)}</tt>" + @io.puts "#{@nest}=== Command: <tt>#{([name] + aliases).join('|')} #{@arg_name_formatter.format(arg_name,arg_options,[])}</tt>" @io.puts String(desc).strip @io.puts @io.puts String(long_desc).strip diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/gli/commands/scaffold.rb new/lib/gli/commands/scaffold.rb --- old/lib/gli/commands/scaffold.rb 1970-01-01 01:00:00.000000000 +0100 +++ new/lib/gli/commands/scaffold.rb 2015-05-12 15:24:13.000000000 +0200 @@ -284,6 +284,9 @@ version #{project_name_as_module_name(project_name)}::VERSION +subcommand_option_handling :normal +arguments :strict + desc 'Describe some switch here' switch [:s,:switch] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/gli/gli_option_parser.rb new/lib/gli/gli_option_parser.rb --- old/lib/gli/gli_option_parser.rb 1970-01-01 01:00:00.000000000 +0100 +++ new/lib/gli/gli_option_parser.rb 2015-05-12 15:24:13.000000000 +0200 @@ -1,20 +1,35 @@ module GLI # Parses the command-line options using an actual +OptionParser+ class GLIOptionParser - def initialize(commands,flags,switches,accepts,default_command = nil,subcommand_option_handling_strategy=:legacy) - command_finder = CommandFinder.new(commands,default_command || "help") + attr_accessor :options + + DEFAULT_OPTIONS = { + :default_command => nil, + :autocomplete => true, + :subcommand_option_handling_strategy => :legacy, + :argument_handling_strategy => :loose + } + + def initialize(commands,flags,switches,accepts, options={}) + self.options = DEFAULT_OPTIONS.merge(options) + + command_finder = CommandFinder.new(commands, + :default_command => (options[:default_command] || :help), + :autocomplete => options[:autocomplete]) @global_option_parser = GlobalOptionParser.new(OptionParserFactory.new(flags,switches,accepts),command_finder,flags) @accepts = accepts - @subcommand_option_handling_strategy = subcommand_option_handling_strategy + if options[:argument_handling_strategy] == :strict && options[:subcommand_option_handling_strategy] != :normal + raise ArgumentError, "To use strict argument handling, you must enable normal subcommand_option_handling, e.g. subcommand_option_handling :normal" + end end # Given the command-line argument array, returns an OptionParsingResult def parse_options(args) # :nodoc: - option_parser_class = self.class.const_get("#{@subcommand_option_handling_strategy.to_s.capitalize}CommandOptionParser") + option_parser_class = self.class.const_get("#{options[:subcommand_option_handling_strategy].to_s.capitalize}CommandOptionParser") OptionParsingResult.new.tap { |parsing_result| parsing_result.arguments = args parsing_result = @global_option_parser.parse!(parsing_result) - option_parser_class.new(@accepts).parse!(parsing_result) + option_parser_class.new(@accepts).parse!(parsing_result, options[:argument_handling_strategy]) } end @@ -43,6 +58,38 @@ end protected + def verify_arguments!(arguments, command) + # Lets assume that if the user sets a 'arg_name' for the command it is for a complex scenario + # and we should not validate the arguments + return unless command.arguments_description.empty? + + # Go through all declared arguments for the command, counting the min and max number + # of arguments + min_number_of_arguments = 0 + max_number_of_arguments = 0 + command.arguments.each do |arg| + if arg.optional? + max_number_of_arguments = max_number_of_arguments + 1 + else + min_number_of_arguments = min_number_of_arguments + 1 + max_number_of_arguments = max_number_of_arguments + 1 + end + + # Special case, as soon as we have a 'multiple' arguments, all bets are off for the + # maximum number of arguments ! + if arg.multiple? + max_number_of_arguments = 99999 + end + end + + # Now validate the number of arguments + if arguments.size < min_number_of_arguments + raise MissingRequiredArgumentsException.new("Not enough arguments for command", command) + end + if arguments.size > max_number_of_arguments + raise MissingRequiredArgumentsException.new("Too many arguments for command", command) + end + end def verify_required_options!(flags, command, options) missing_required_options = flags.values. @@ -65,12 +112,12 @@ end def error_handler - lambda { |message,extra_error_context| + lambda { |message,extra_error_context| raise UnknownCommandArgument.new(message,extra_error_context) } end - def parse!(parsing_result) + def parse!(parsing_result,argument_handling_strategy) parsed_command_options = {} command = parsing_result.command arguments = nil @@ -84,7 +131,7 @@ arguments = option_block_parser.parse!(arguments) parsed_command_options[command] = option_parser_factory.options_hash_with_defaults_set! - command_finder = CommandFinder.new(command.commands,command.get_default_command) + command_finder = CommandFinder.new(command.commands, :default_command => command.get_default_command) next_command_name = arguments.shift verify_required_options!(command.flags, command, parsed_command_options[command]) @@ -121,13 +168,17 @@ parsing_result.command_options = command_options parsing_result.command = command parsing_result.arguments = Array(arguments.compact) + + # Lets validate the arguments now that we know for sure the command that is invoked + verify_arguments!(parsing_result.arguments, parsing_result.command) if argument_handling_strategy == :strict + parsing_result end end class LegacyCommandOptionParser < NormalCommandOptionParser - def parse!(parsing_result) + def parse!(parsing_result,argument_handling_strategy) command = parsing_result.command option_parser_factory = OptionParserFactory.for_command(command,@accepts) option_block_parser = LegacyCommandOptionBlockParser.new(option_parser_factory, self.error_handler) @@ -153,7 +204,7 @@ end default_command = command.get_default_command - finder = CommandFinder.new(command.commands,default_command.to_s) + finder = CommandFinder.new(command.commands, :default_command => default_command.to_s) begin results = [finder.find_command(command_name),arguments[1..-1]] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/gli/switch.rb new/lib/gli/switch.rb --- old/lib/gli/switch.rb 1970-01-01 01:00:00.000000000 +0100 +++ new/lib/gli/switch.rb 2015-05-12 15:24:13.000000000 +0200 @@ -31,5 +31,9 @@ def negatable? @negatable end + + def required? + false + end end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/gli/version.rb new/lib/gli/version.rb --- old/lib/gli/version.rb 1970-01-01 01:00:00.000000000 +0100 +++ new/lib/gli/version.rb 2015-05-12 15:24:13.000000000 +0200 @@ -1,5 +1,5 @@ module GLI unless const_defined? :VERSION - VERSION = '2.11.0' + VERSION = '2.13.1' end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/metadata new/metadata --- old/metadata 1970-01-01 01:00:00.000000000 +0100 +++ new/metadata 2015-05-12 15:24:13.000000000 +0200 @@ -1,125 +1,125 @@ --- !ruby/object:Gem::Specification name: gli version: !ruby/object:Gem::Version - version: 2.11.0 + version: 2.13.1 platform: ruby authors: - David Copeland autorequire: bindir: bin cert_chain: [] -date: 2014-06-09 00:00:00.000000000 Z +date: 2015-05-12 00:00:00.000000000 Z dependencies: - !ruby/object:Gem::Dependency name: rake requirement: !ruby/object:Gem::Requirement requirements: - - - ~> + - - "~>" - !ruby/object:Gem::Version version: 0.9.2.2 type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - - ~> + - - "~>" - !ruby/object:Gem::Version version: 0.9.2.2 - !ruby/object:Gem::Dependency name: rdoc requirement: !ruby/object:Gem::Requirement requirements: - - - ~> + - - "~>" - !ruby/object:Gem::Version version: '3.11' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - - ~> + - - "~>" - !ruby/object:Gem::Version version: '3.11' - !ruby/object:Gem::Dependency name: rainbow requirement: !ruby/object:Gem::Requirement requirements: - - - ~> + - - "~>" - !ruby/object:Gem::Version version: 1.1.1 type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - - ~> + - - "~>" - !ruby/object:Gem::Version version: 1.1.1 - !ruby/object:Gem::Dependency name: clean_test requirement: !ruby/object:Gem::Requirement requirements: - - - '>=' + - - ">=" - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - - '>=' + - - ">=" - !ruby/object:Gem::Version version: '0' - !ruby/object:Gem::Dependency name: cucumber requirement: !ruby/object:Gem::Requirement requirements: - - - '=' + - - ">=" - !ruby/object:Gem::Version - version: 1.2.3 + version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - - '=' + - - ">=" - !ruby/object:Gem::Version - version: 1.2.3 + version: '0' - !ruby/object:Gem::Dependency name: gherkin requirement: !ruby/object:Gem::Requirement requirements: - - - <= + - - ">=" - !ruby/object:Gem::Version - version: 2.11.6 + version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - - <= + - - ">=" - !ruby/object:Gem::Version - version: 2.11.6 + version: '0' - !ruby/object:Gem::Dependency name: aruba requirement: !ruby/object:Gem::Requirement requirements: - - - '=' + - - ">=" - !ruby/object:Gem::Version - version: 0.5.1 + version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - - '=' + - - ">=" - !ruby/object:Gem::Version - version: 0.5.1 + version: '0' - !ruby/object:Gem::Dependency name: sdoc requirement: !ruby/object:Gem::Requirement requirements: - - - '>=' + - - ">=" - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - - '>=' + - - ">=" - !ruby/object:Gem::Version version: '0' - !ruby/object:Gem::Dependency @@ -147,10 +147,10 @@ - README.rdoc - gli.rdoc files: -- .gitignore -- .ruby-gemset -- .ruby-version -- .travis.yml +- ".gitignore" +- ".ruby-gemset" +- ".ruby-version" +- ".travis.yml" - CONTRIBUTING.md - Gemfile - LICENSE.txt @@ -241,6 +241,7 @@ - test/init_simplecov.rb - test/option_test_helper.rb - test/tc_command.rb +- test/tc_command_finder.rb - test/tc_compound_command.rb - test/tc_doc.rb - test/tc_flag.rb @@ -258,25 +259,25 @@ metadata: {} post_install_message: rdoc_options: -- --title +- "--title" - Git Like Interface -- --main +- "--main" - README.rdoc require_paths: - lib required_ruby_version: !ruby/object:Gem::Requirement requirements: - - - '>=' + - - ">=" - !ruby/object:Gem::Version version: '0' required_rubygems_version: !ruby/object:Gem::Requirement requirements: - - - '>=' + - - ">=" - !ruby/object:Gem::Version version: '0' requirements: [] rubyforge_project: gli -rubygems_version: 2.0.14 +rubygems_version: 2.4.4 signing_key: specification_version: 4 summary: Build command-suite CLI apps that are awesome. @@ -319,6 +320,7 @@ - test/init_simplecov.rb - test/option_test_helper.rb - test/tc_command.rb +- test/tc_command_finder.rb - test/tc_compound_command.rb - test/tc_doc.rb - test/tc_flag.rb diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/test/apps/todo/bin/todo new/test/apps/todo/bin/todo --- old/test/apps/todo/bin/todo 1970-01-01 01:00:00.000000000 +0100 +++ new/test/apps/todo/bin/todo 2015-05-12 15:24:13.000000000 +0200 @@ -20,6 +20,7 @@ hide_commands_without_desc ENV['HIDE_COMMANDS_WITHOUT_DESC'] === 'true' subcommand_option_handling :normal +arguments :strict program_desc 'Manages tasks' program_long_desc "A test program that has a sophisticated UI that can be used to exercise a lot of GLI's power" @@ -41,7 +42,12 @@ arg :argument, :optional command :second do |c| c.action { |g,o,a| puts "second: #{a.join(',')}" } end +arg :first +arg :second command :chained => [ :first, :second ] + +arg :first +arg :second command [:chained2,:ch2] => [ :second, :first ] pre do |global,command,options,args| diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/test/apps/todo/lib/todo/commands/list.rb new/test/apps/todo/lib/todo/commands/list.rb --- old/test/apps/todo/lib/todo/commands/list.rb 1970-01-01 01:00:00.000000000 +0100 +++ new/test/apps/todo/lib/todo/commands/list.rb 2015-05-12 15:24:13.000000000 +0200 @@ -8,6 +8,7 @@ stored in your todo databases. ) + command [:list] do |c| c.default_command :tasks @@ -22,6 +23,8 @@ Lists all of your tasks that you have, in varying orders, and all that stuff. Yes, this is long, but I need a long description. ) + + c.arg :task, [:optional, :multiple] c.command :tasks do |tasks| tasks.desc "blah blah crud x whatever" tasks.flag [:x], :must_match => Array diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/test/apps/todo/lib/todo/commands/make.rb new/test/apps/todo/lib/todo/commands/make.rb --- old/test/apps/todo/lib/todo/commands/make.rb 1970-01-01 01:00:00.000000000 +0100 +++ new/test/apps/todo/lib/todo/commands/make.rb 2015-05-12 15:24:13.000000000 +0200 @@ -13,7 +13,8 @@ puts o[:long] end - desc 'make a bug' + task.desc 'make a bug' + task.arg :argument, [:multiple, :optional] task.command :bug do |bug| bug.desc 'make this bug in the legacy system' bug.flag [:l,:legacy] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/test/tc_command_finder.rb new/test/tc_command_finder.rb --- old/test/tc_command_finder.rb 1970-01-01 01:00:00.000000000 +0100 +++ new/test/tc_command_finder.rb 2015-05-12 15:24:13.000000000 +0200 @@ -0,0 +1,54 @@ +require 'test_helper' + +class TC_testCommandFinder < Clean::Test::TestCase + include TestHelper + + def setup + @app = CLIApp.new + [:status, :deployable, :some_command, :some_similar_command].each do |command| + @app.commands[command] = GLI::Command.new(:names => command) + end + end + + def teardown + end + + def test_unknown_command_name + assert_raise(GLI::UnknownCommand) do + GLI::CommandFinder.new(@app.commands, :default_command => :status).find_command(:unfindable_command) + end + end + + def test_no_command_name_without_default + assert_raise(GLI::UnknownCommand) do + GLI::CommandFinder.new(@app.commands).find_command(nil) + end + end + + def test_no_command_name_with_default + actual = GLI::CommandFinder.new(@app.commands, :default_command => :status).find_command(nil) + expected = @app.commands[:status] + + assert_equal(actual, expected) + end + + def test_ambigous_command + assert_raise(GLI::AmbiguousCommand) do + GLI::CommandFinder.new(@app.commands, :default_command => :status).find_command(:some) + end + end + + def test_partial_name_with_autocorrect_enabled + actual = GLI::CommandFinder.new(@app.commands, :default_command => :status).find_command(:deploy) + expected = @app.commands[:deployable] + + assert_equal(actual, expected) + end + + def test_partial_name_with_autocorrect_disabled + assert_raise(GLI::UnknownCommand) do + GLI::CommandFinder.new(@app.commands, :default_command => :status, :autocomplete => false) + .find_command(:deploy) + end + end +end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/test/tc_subcommand_parsing.rb new/test/tc_subcommand_parsing.rb --- old/test/tc_subcommand_parsing.rb 1970-01-01 01:00:00.000000000 +0100 +++ new/test/tc_subcommand_parsing.rb 2015-05-12 15:24:13.000000000 +0200 @@ -4,6 +4,30 @@ class TC_testSubCommandParsing < Clean::Test::TestCase include TestHelper + def setup + @fake_stdout = FakeStdOut.new + @fake_stderr = FakeStdOut.new + + @original_stdout = $stdout + $stdout = @fake_stdout + @original_stderr = $stderr + $stderr = @fake_stderr + + @app = CLIApp.new + @app.reset + @app.subcommand_option_handling :legacy + @app.error_device=@fake_stderr + ENV.delete('GLI_DEBUG') + + @results = {} + @exit_code = 0 + end + + def teardown + $stdout = @original_stdout + $stderr = @original_stderr + end + test_that "commands options may clash with globals and it gets sorted out" do Given :app_with_subcommands_storing_results When { @@ -24,7 +48,7 @@ @app.run(%w(-f global command1 -f command -s subcommand10 -f sub)) } Then { - with_clue(@results) { + with_clue { assert_equal 'subcommand10',@results[:command_name] assert_equal 'global', @results[:global_options][:f],'global' assert !@results[:global_options][:s] @@ -42,7 +66,7 @@ @app.run(%w(-f global command1 -f command -s subcommand10 -f sub)) } Then { - with_clue(@results) { + with_clue { assert_equal 'subcommand10',@results[:command_name] assert_equal 'global', @results[:global_options][:f],'global' assert !@results[:global_options][:s] @@ -54,18 +78,89 @@ } end + test_that "in loose mode, argument validation is ignored" do + Given :app_with_arguments, 1, 1, false, :loose + When :run_app_with_X_arguments, 0 + Then { + with_clue { + assert_equal 0, @results[:number_of_args_give_to_action] + assert_equal 0, @exit_code + } + } + end + + test_that "in strict mode, subcommand_option_handling must be normal" do + Given :app_with_arguments, 1, 1, false, :strict, :legacy + When :run_app_with_X_arguments, 1 + Then { + with_clue { + assert_nil @results[:number_of_args_give_to_action] + assert_equal 1, @exit_code + assert @fake_stderr.contained?(/you must enable normal subcommand_option_handling/) + } + } + end + + ix = -1 + [ + [1 , 1 , false , 0 , :not_enough] , + [1 , 1 , false , 1 , :success] , + [1 , 1 , false , 2 , :success] , + [1 , 1 , false , 3 , :too_many] , + [1 , 1 , true , 0 , :not_enough] , + [1 , 1 , true , 1 , :success] , + [1 , 1 , true , 2 , :success] , + [1 , 1 , true , 3 , :success] , + [1 , 1 , true , 30 , :success] , + [0 , 0 , false , 0 , :success] , + [0 , 0 , false , 1 , :too_many] , + [0 , 1 , false , 1 , :success] , + [0 , 1 , false , 0 , :success] , + [1 , 0 , false , 1 , :success] , + [1 , 0 , false , 0 , :not_enough] , + [0 , 0 , true , 0 , :success] , + [0 , 0 , true , 10 , :success] + + ].each do |number_required, number_optional, has_multiple, number_generated, status| + ix = ix + 1 + test_that "in strict mode, with #{number_required} required, #{number_optional} optional, #{ has_multiple ? 'multiple' : 'not multiple' } and #{number_generated} generated, it should be #{status}" do + Given :app_with_arguments, number_required, number_optional, has_multiple, :strict + When :run_app_with_X_arguments, number_generated + Then { + with_clue { + if status == :success then + assert_equal number_generated, @results[:number_of_args_give_to_action] + assert_equal 0, @exit_code + assert !@fake_stderr.contained?(/Not enough arguments for command/) + assert !@fake_stderr.contained?(/Too many arguments for command/) + elsif status == :not_enough then + assert_equal nil, @results[:number_of_args_give_to_action] + assert_equal 64, @exit_code + assert @fake_stderr.contained?(/Not enough arguments for command/) + elsif status == :too_many then + assert_equal nil, @results[:number_of_args_give_to_action] + assert_equal 64, @exit_code + assert @fake_stderr.contained?(/Too many arguments for command/) + else + assert false + end + } + } + end + end private - def with_clue(message,&block) + def with_clue(&block) block.call rescue Exception - PP.pp message,dump="" - puts dump + dump = "" + PP.pp "\nRESULTS---#{@results}", dump unless @results.empty? + PP.pp "\nSTDERR---\n#{@fake_stderr.to_s}", dump + PP.pp "\nSTDOUT---\n#{@fake_stdout.to_s}", dump + @original_stdout.puts dump raise end def app_with_subcommands_storing_results(subcommand_option_handling_strategy = :legacy) - @results = {} - @app = CLIApp.new @app.subcommand_option_handling subcommand_option_handling_strategy @app.flag ['f','flag'] @app.switch ['s','switch'] @@ -101,4 +196,25 @@ end end end + + def app_with_arguments(number_required_arguments, number_optional_arguments, has_argument_multiple, arguments_handling_strategy = :loose, subcommand_option_handling_strategy = :normal) + @app.arguments arguments_handling_strategy + @app.subcommand_option_handling subcommand_option_handling_strategy + + number_required_arguments.times { |i| @app.arg("needed#{i}") } + number_optional_arguments.times { |i| @app.arg("optional#{i}", :optional) } + @app.arg :multiple, [:multiple, :optional] if has_argument_multiple + + @app.command :cmd do |c| + c.action do |g,o,a| + @results = { + :number_of_args_give_to_action => a.size + } + end + end + end + + def run_app_with_X_arguments(number_arguments) + @exit_code = @app.run [].tap{|args| args << "cmd"; number_arguments.times {|i| args << "arg#{i}"}} + end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/test/test_helper.rb new/test/test_helper.rb --- old/test/test_helper.rb 1970-01-01 01:00:00.000000000 +0100 +++ new/test/test_helper.rb 2015-05-12 15:24:13.000000000 +0200 @@ -18,3 +18,4 @@ end Faker::Config.locale = :en +I18n.enforce_available_locales = false