The `needs()` function should propogate run-time task arguments (`%params` and `@args`) from the calling task down to the "needed" tasks
评估
调研方向
从 lib/Rex/Commands.pm 中的 needs() 子程序开始,检查运行时参数和参数是如何传递给所需任务的。阅读现有的 needs.t 测试,为两种传播情况添加覆盖,并运行该测试文件。当所需任务按照文档所述接收到调用任务的 params 和 args 时,即表示完成。
由索引模型根据 Issue 内容生成。
描述
The needs() function should propagate run-time task arguments (%params and @args) from the calling task down to the "needed" tasks
Edits:
As it turns out: this bug is really easy to fix, as it appears to stem from a typo, introduced initially by PR #1157 (the fix for #1066 ) with 48c737b78f69be92d5f31c2c79fe992f83a4e75c (ultimately merged into master with 7cf0ca4c7093c3fd9d1f5d4dc9472215bc63861e). Some other sharp edges introduced by PR #1157 seem to have already been handled by #1188, but not this one.
I am preparing a PR with accompanying tests.
Describe the bug
The needs() function has a bug which prevents it from implicitely propagating the calling task's params/args down to the "needed" tasks when it runs them.
How to reproduce it
Steps to reproduce the behavior:
- In a brief
Rexfile, define two simple tasks (task_a&task_b) that dump their run-time arguments (@_) onSTDERR - Make sure that
task_bcallsneeds("task_a") - From the shell, launch
rex task_b(with appropriate host & auth info) and observe the results
The dump fromtask_ais empty, whereastask_bnormally displays itsparams. - Also try
rex task_b --greetings=Hello, and observe that the result is similar to the previous trial.
Shortest code example that demonstrates the bug:
Rexfile
# Rexfile
### ex: set ft=perl :
use Rex -feature => [qw(1.13 exec_autodie)];
use DDP; # alias for `Data::Printer`, used just for pretty display of dumps.
desc "Display host name";
task hostname => sub {
say STDERR "hostname: \@_ : "; DDP::p(@_);
say STDERR ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>";
say ''. run('hostname');
};
desc "Display host info";
task hostinfo => sub {
say STDERR "hostinfo: \@_ : "; DDP::p(@_);
say STDERR ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>";
needs "hostname";
};
1;
Run the example from the shell
Execute rex within the directory where the above Rexfile resides (with appropriate host and authentication switches).
$ rex hostinfo --greetings=Hello
[2021-09-26 18:26:45] INFO - Running task hostinfo on medusa
hostinfo: @_ :
[
[0] {
greetings => "Hello",
hostinfo => 1
},
[1] []
]
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
hostname: @_ :
[]
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
medusa
Expected behavior
The needs() function should implicitly propagate the calling task's params/args down to the "needed" tasks when it runs them, as documented and seemingly intended by the current code base (see notes below).
Circumstances
- Rex version: (R)?ex 1.13.4 (also on latest branch master)
- Perl version: v5.34.0
- OS running rex: ~~~ (irrelevant)
- OS managed by rex: ~~~ (irrelevant)
- How rex was installed: git clone repo
Debug log
Notes
It turns out: this is really easy to fix, as it appears to stem from a typo.
The culprit
Here's the offending portion of code in Rex::Commands.
# lib/Rex/Commands.pm
...
sub needs {
...
if ( @args && grep ( /^\Q$task_name\E$/, @args ) ) {
Rex::Logger::debug( "Calling " . $task_o->name );
$task_o->run( "<func>", params => \@task_args, args => \%task_opts );
}
elsif ( !@args ) {
Rex::Logger::debug( "Calling " . $task_o->name );
$task_o->run( "<func>", params => \@task_args, args => \%task_opts );
}
...
}
Notice how params and args are mixed up (interchanged) when being passed to run!! This certainly looks like a typo.
The current test suite does not catch the issue. The tests in needs.t do not cover propagation of parameters/args.
Quick fix
For a fix with minimal changes, just patch the two occurrences of the $task_o->run call, within the body of the needs() subroutine (in Rex::Commands), as below:
- $task_o->run( "<func>", params => \@task_args, args => \%task_opts );
+ $task_o->run( "<func>", params => \%task_opts, args => \@task_args );
Alternative fix (slightly better, imho)
There does not appear to be any particular reason for having two identical invocations of the ->run method in the above code snippet.
So, the offending code can be replaced by the following -logically equivalent- snippet. I will put that in a separate commit; in case there are other (historical?) reasons to keep the two branches of the if statement around.
In any case, all tests pass either way.
# lib/Rex/Commands.pm
...
sub needs {
...
# edit: further simplified the logic.
if ( !@args || grep ( /^\Q$task_name\E$/, @args ) ) {
Rex::Logger::debug( "Calling " . $task_o->name );
$task_o->run( "<func>", params => \%task_opts, args => \@task_args );
}
...
}
Edit: Digging in repo history, it seems that the if ... elsif ... form existed since the very initial introduction of needs() by commit 95d3e913367828f0927591b0e8bda897e9150016, but even at that time (and probably ever since), those two arms of the if statement always did exactly the same thing... So I can't think of any valid reason to keep them around.
- 主要语言
- Perl
- 星标
- 736
- 派生
- 217
- PR 合并指标
- 30 天内没有已合并 PR
环境准备
- 没有 Dockerfile 或 Docker Compose 文件
- 有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
RexOps/Rex 的其他 Issue
-
is_redhat() misses Rocky/Alma/CentOS Stream/Oracle Linux lsb_release IDs -> pkg dies "OS/Provider not supported"可能已有人在做 @stantheman0128 于 22 天前认领。 未关闭
难度 2/5 1-3 小时 新手友好度 75/100
-
bug
难度 3/5 1-2 天 新手友好度 45/100
-
triage needed
难度 4/5 3-5 天 新手友好度 35/100
-
bug
难度 3/5 1-2 天 新手友好度 35/100
-
triage needed
难度 3/5 1-2 天 新手友好度 42/100
相似的 Issue
-
enhancement
难度 2/5 1-3 小时 新手友好度 67/100
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 76/100
-
radius_audit_logs/search returns 500 when the body has no query (nil SearchOp in Vars2.Sql)可能已有人在做 @fdurand 于 1 天前认领。 未关闭Type: Bug
难度 2/5 1-3 小时 新手友好度 78/100
inverse-inc/packetfence#9564 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 83/100
LMS-Community/slimserver#1692 · 4 条评论 ·
维护者通常 1 天内回复
-
fix(api): API v3 Product Read ignores request language (lc) for sample products and image URLs可能已有人在做 @muntasir-396 于 2 天前认领。 未关闭
难度 2/5 1-3 小时 新手友好度 88/100
openfoodfacts/openfoodfacts-server#15042 · 1 条评论 ·
维护者通常 1 天内回复