App-Cmd
App-Cmd copied to clipboard
subdispatch commands are promoted to top level commands
I'm playing (and not succeeding terribly well) at getting subcommands to work. My expectation is that subcommands live in a namespace which is private to their parent commands. However, that doesn't appear to be so. Here's some test code:
#!/usr/bin/env perl
MyApp->run;
package MyApp;
use App::Cmd::Setup -app;
package MyApp::Command::first;
use base 'App::Cmd::Subdispatch';
sub execute { print __PACKAGE__, "\n" }
package MyApp::Command::first::init;
use base 'App::Cmd::Command';
sub execute { print __PACKAGE__, "\n" }
package MyApp::Command::second;
use base 'App::Cmd::Subdispatch';
sub execute { print __PACKAGE__, "\n" }
package MyApp::Command::second::init;
use base 'App::Cmd::Command';
sub execute { print __PACKAGE__, "\n" };
Executing that code leads to the following error message:
two plugins for command init: MyApp::Command::second::init and MyApp::Command::first::init
If I remove the definition of second::init
, I get the following
Available commands:
commands: list the application's commands
help: display a command's help screen
first: (unknown)
init: (unknown)
second: (unknown)
And I can execute first::init
as if it were a top-level command:
$ ./tpan init
MyApp::Command::first::init
Which isn't what I'd expect. Am I going about this the wrong way?
Thanks.
I have also seen subdispatch commands being treated as top-level commands. I also did not expect that behavior.
Hello, I encounter the same problem.
I have the following setup:
.
./NestedCmd
./NestedCmd/Command
./NestedCmd/Command/first.pm
./NestedCmd/Command/first
./NestedCmd/Command/first/Command
./NestedCmd/Command/first/Command/second.pm
./nestedcmd.pl
./NestedCmd.pm
- nestedcmd.pl
#!/usr/bin/env perl
use NestedCmd;
NestedCmd->run;
- NestedCmd.pm
package NestedCmd 0.1;
use App::Cmd::Setup -app;
1;
- NestedCmd/Command/first.pm
package NestedCmd::Command::first 0.1;
use parent 'App::Cmd::Subdispatch';
1;
- NestedCmd/Command/first/Command/second.pm
package NestedCmd::Command::first::Command::second;
use NestedCmd::Command::first -command;
sub execute {
print __PACKAGE__ . "\n";
}
1;
I got the following error when i start this:
Can't locate NestedCmd/Command/first/Command.pm in @INC (you may need to install the NestedCmd::Command::first::Command module) (@INC contains: /usr/local/lib/cperl/site_cperl/5.22.2/x86_64-linux /usr/local/lib/cperl/site_cperl/5.22.2 /usr/local/lib/cperl/5.22.2/x86_64-linux /usr/local/lib/cperl/5.22.2 .) at NestedCmd/Command/first/Command/second.pm line 3.
BEGIN failed--compilation aborted at NestedCmd/Command/first/Command/second.pm line 3.
Compilation failed in require at /usr/local/lib/cperl/site_cperl/5.22.2/App/Cmd.pm line 194.
App::Cmd::_command("NestedCmd", undef) called at /usr/local/lib/cperl/site_cperl/5.22.2/App/Cmd.pm line 171
App::Cmd::new("NestedCmd") called at /usr/local/lib/cperl/site_cperl/5.22.2/App/Cmd.pm line 314
App::Cmd::run("NestedCmd") called at ./nestedcmd.pl line 5
I'ts seems to work when i replace use NestedCmd::Command::first -command;
with use App::Cmd::Setup -command;
... but the second
command is in the top-level too ...
nestedcmd.pl <command> [-?h] [long options...]
-? -h --help show help
Available commands:
commands: list the application's commands
help: display a command's help screen
first: (unknown)
second: (unknown)
nestedcmd.pl first
Available commands:
commands: list the application's commands
help: display a command's help screen
second: (unknown)
So I override should_ignore()
in NestedCmd
(and it works):
sub should_ignore {
my ($self, $command_class) = @_;
$command_class =~ /^NestedCmd::Command::.*::/;
}
Could you confirm that:
- this is the right way to do it.
- this will work with future versions of your module.
?
Thanks.
In case someone still has trouble with this - in the App module, you can set the max depth to limit the listing of subcommands:
sub _module_pluggable_options {
return (max_depth => 3);
}