Rex icon indicating copy to clipboard operation
Rex copied to clipboard

needs: syntax error under v5.36 (indirect)

Open rwp0 opened this issue 3 years ago • 1 comments

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 hello from one [2022-08-24 13:43:11] INFO - All tasks successful on all hosts

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

rwp0 avatar Aug 24 '22 09:08 rwp0

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.

ferki avatar Sep 04 '22 19:09 ferki