needs: syntax error under v5.36 (indirect)
Describe the bug
Calling needs command with the indirect syntax described by its documentation fails with syntax error:
/usr/bin/perlbrew exec -q --with perl-5.36.0 /home/regular/perl5/perlbrew/perls/perl-5.36.0/bin/perl /home/regular/perl5/perlbrew/perls/latest/bin/rex one
[2022-08-24 12:37:14] ERROR - Compile time errors:
[2022-08-24 12:37:14] ERROR - syntax error at __Rexfile__.pm line 9, near "main 'one'"
[2022-08-24 12:37:14] ERROR - Compilation failed in require at /home/regular/perl5/perlbrew/perls/perl-5.36.0/lib/site_perl/5.36.0/Rex/CLI.pm line 759.
[2022-08-24 12:37:14] INFO - Exiting Rex...
[2022-08-24 12:37:14] INFO - Cleaning up...
Expected behavior
[2022-08-24 13:43:10] INFO - Running task one on
Process finished with exit code 0
Success (as achievable with use feature 'indirect';)
How to reproduce it
Call needs with indirect syntax.
See the code example.
Code example
use v5.36;
use Rex -feature => [ '1.4' ];
task 'one', sub {
say 'hello from one';
};
task 'two', sub {
needs main 'one';
say 'hello from two';
};
Additional context
https://github.com/RexOps/Rex/issues/1542
https://github.com/RexOps/Rex/discussions/1538
Rex version
1.13.4
Perl version
5.36.0
Operating system running rex
Debian
Operating system managed by rex
FreeBSD
How rex was installed?
cpan client
Thanks for the report, it's a good find :+1:
Since the currently established syntax of needs relies on perl's indirect feature, I don't think there is a quick fix for this, though :thinking:
Workarounds
Keep using the indirect feature
The general workaround is to add use feature 'indirect'; after use v5.36;.
Simplify Rexfile (and add example to docs)
Alternatively, in this specific example, it's possible to avoid the indirect syntax altogether, because main is only required
To call tasks defined in the Rexfile from within a module
Since task two depends on another task in the same namespace, main is not strictly needed
task 'two', sub {
- needs main 'one';
+ needs 'one';
say 'hello from two';
};
We may want to add one more example to the docs about calling a single task like the above.
Proposed fix outline
The only proper fix I currently see is to introduce a new syntax for needs that doesn't depend on perl's indirect feature (which sounds like a good idea anyway).
Unfortunately that would break all pre-existing Rex-based code which already uses the indirect form of needs, so we would need to introduce new feature flag to control which syntax is expected. This feature flag may also attempt to control calling something like BEGIN { use feature 'indirect'; } on behalf of the user. The new syntax may also become default later, e.g. in a new versioned feature bundle.
For the new syntax itself, I would propose using the already well-established "fully qualified task names" (Rex:: prefix chopped off, and single colons as namespace separators), perhaps combined with the also well-established shortcuts. Some ideas for example:
use Rex -feature => ['no_indirect_needs'];
needs 'another_task'; # call task named `another_task`
needs 'Module:something_else'; # call task named `something_else` from `Module`
needs 'Module:'; # call all tasks from `Module`
Related, but different bug
As an aside, there is a second bug in the provided example. Adding use feature 'indirect'; would fix running rex one on the CLI, but rex two would still fail with an error like:
Can't locate object method "needs" via package "main" at /loader/0x55c93d31c3b8/__Rexfile__.pm line 16, <> line 1
I will open another bug about that.