From a9c981e60b6e2cf4fe20c50c445cf0ce9da32c68 Mon Sep 17 00:00:00 2001 From: John Leach Date: Thu, 4 Jul 2013 13:28:45 +0100 Subject: [PATCH 1/2] Allow multiple definitions of a command with a block This allows "reopening" of a command so you can add more subcommands. Fixes #144, in a roundabout way. --- lib/gli/dsl.rb | 3 ++- test/tc_subcommands.rb | 47 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/lib/gli/dsl.rb b/lib/gli/dsl.rb index 73dc7384..07fc6844 100644 --- a/lib/gli/dsl.rb +++ b/lib/gli/dsl.rb @@ -164,7 +164,8 @@ def command(*names) command.parent = self commands[command.name] = command else - command = Command.new(command_options.merge(:names => [names].flatten)) + new_command = Command.new(command_options.merge(:names => [names].flatten)) + command = commands[new_command.name] || new_command command.parent = self commands[command.name] = command yield command diff --git a/test/tc_subcommands.rb b/test/tc_subcommands.rb index 43b91dcd..eb43c50f 100644 --- a/test/tc_subcommands.rb +++ b/test/tc_subcommands.rb @@ -45,6 +45,53 @@ def teardown :args => ['bar']) end + test_that "we can reopen commands to add new subcommands" do + Given { + @app.command :remote do |p| + p.command :add do |c| + c.action do |global_options,command_options,args| + @ran_command = :add + end + end + end + @app.command :remote do |p| + p.command :new do |c| + c.action do |global_options,command_options,args| + @ran_command = :new + end + end + end + } + When run_app('remote','new') + Then { assert_equal(@ran_command, :new) } + When run_app('remote', 'add') + Then { assert_equal(@ran_command, :add) } + end + + test_that "we can reopening commands doesn't cause conflicts" do + Given { + @app.command :remote do |p| + p.command :add do |c| + c.action do |global_options,command_options,args| + @ran_command = :remote_add + end + end + end + @app.command :local do |p| + p.command :add do |c| + c.action do |global_options,command_options,args| + @ran_command = :local_add + end + end + end + } + When run_app('remote','add') + Then { assert_equal(@ran_command, :remote_add) } + When run_app('local', 'add') + Then { assert_equal(@ran_command, :local_add) } + end + + test_that "we can nest subcommands very deep" do Given { @run_results = { :add => nil, :rename => nil, :base => nil } From 097929a462063dbedca6b840f20656303bfb9202 Mon Sep 17 00:00:00 2001 From: John Leach Date: Thu, 4 Jul 2013 19:31:32 +0100 Subject: [PATCH 2/2] Don't display multiply-defined commands multiple times When adding the feature to support reopening commands to add subcommands, I didn't notice that the parent command was getting added to the help output multiple times. Added a test case and fixed it. --- lib/gli/dsl.rb | 14 +++++++++----- test/tc_subcommands.rb | 16 +++++++++++++++- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/lib/gli/dsl.rb b/lib/gli/dsl.rb index 07fc6844..42bd4726 100644 --- a/lib/gli/dsl.rb +++ b/lib/gli/dsl.rb @@ -157,21 +157,25 @@ def command(*names) :skips_post => @skips_post, :skips_around => @skips_around, } + @commands_declaration_order ||= [] if names.first.kind_of? Hash command = GLI::Commands::CompoundCommand.new(self, names.first, command_options) command.parent = self commands[command.name] = command + @commands_declaration_order << command else new_command = Command.new(command_options.merge(:names => [names].flatten)) - command = commands[new_command.name] || new_command - command.parent = self - commands[command.name] = command + command = commands[new_command.name] + if command.nil? + command = new_command + command.parent = self + commands[command.name] = command + @commands_declaration_order << command + end yield command end - @commands_declaration_order ||= [] - @commands_declaration_order << command clear_nexts end alias :c :command diff --git a/test/tc_subcommands.rb b/test/tc_subcommands.rb index eb43c50f..d1838434 100644 --- a/test/tc_subcommands.rb +++ b/test/tc_subcommands.rb @@ -68,7 +68,21 @@ def teardown Then { assert_equal(@ran_command, :add) } end - test_that "we can reopening commands doesn't cause conflicts" do + test_that "reopening commands doesn't re-add them to the output" do + Given { + @app.command :remote do |p| + p.command(:add) { } + end + @app.command :remote do |p| + p.command(:new) { } + end + } + command_names = @app.instance_variable_get("@commands_declaration_order").collect { |c| c.name } + assert_equal 1, command_names.grep(:remote).size + end + + + test_that "we can reopen commands doesn't cause conflicts" do Given { @app.command :remote do |p| p.command :add do |c|