rebar3
rebar3 copied to clipboard
the clean shell hooks will run twice?
Environment
Rebar3 report
version 3.20.0
generated at 2022-12-29T03:49:57+00:00
=================
Please submit this along with your issue at https://github.com/erlang/rebar3/issues (and feel free to edit out private information, if any)
-----------------
Task:
Entered as:
-----------------
Operating System: aarch64-unknown-linux-gnu
ERTS: Erlang/OTP 25 [erts-13.1.2] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [jit]
Root Directory: /data/kerl/25.1.2
Library directory: /data/kerl/25.1.2/lib
-----------------
Loaded Applications:
bbmustache: 1.12.2
certifi: 2.9.0
cf: 0.3.1
common_test: 1.23.1
compiler: 8.2.1
crypto: 5.1.2
cth_readable: 1.5.1
dialyzer: 5.0.3
edoc: 1.2
erlware_commons: 1.5.0
eunit: 2.8.1
eunit_formatters: 0.5.0
getopt: 1.0.1
inets: 8.1
kernel: 8.5.1
providers: 1.9.0
public_key: 1.13.1
relx: 4.7.0
sasl: 4.2
snmp: 5.13.1
ssl_verify_fun: 1.1.6
stdlib: 4.1.1
syntax_tools: 3.0
tools: 3.5.3
-----------------
Escript path: undefined
Providers:
app_discovery as clean compile compile cover ct deps dialyzer do edoc escriptize eunit get-deps help install install_deps list lock new path pkgs release relup report repos shell state tar tree unlock update upgrade upgrade upgrade vendor version xref
Current behaviour
I am learning to build a nif project follow the tutorial(http://rebar3.org/docs/tutorials/building_c_cpp/). It adds the shell hooks in rebar.config.
{pre_hooks,
[{"(linux|darwin|solaris)", compile, "make -C c_src"},
{"(freebsd)", compile, "gmake -C c_src"}]}.
{post_hooks,
[{"(linux|darwin|solaris)", clean, "make -C c_src clean"},
{"(freebsd)", clean, "gmake -C c_src clean"}]}.
When i run rebar clean, the hook shell command runs twice.
$ DEBUG=1 rebar3 clean
===> Expanded command sequence to be run: [app_discovery,install_deps,clean]
===> Running provider: app_discovery
===> Found top-level apps: [test_nif]
using config: [{src_dirs,["src"]},{lib_dirs,["apps/*","lib/*","."]}]
===> Running provider: install_deps
===> Verifying dependencies...
===> Running provider: clean
===> Running hooks for clean with configuration:
===> {pre_hooks, []}.
===> Cleaning out test_nif...
===> Running hooks for clean in app test_nif (/data/project/test_nif) with configuration:
===> {pre_hooks, []}.
===> Running hooks for clean in app test_nif (/data/project/test_nif) with configuration:
===> {post_hooks, [{"(linux|darwin|solaris)",clean,
"make -C c_src clean"},
{"(freebsd)",clean,"gmake -C c_src clean"}]}.
make: Entering directory '/data/project/test_nif/c_src'
make: Leaving directory '/data/project/test_nif/c_src'
===> Running hooks for clean with configuration:
===> {post_hooks, [{"(linux|darwin|solaris)",clean,
"make -C c_src clean"},
{"(freebsd)",clean,"gmake -C c_src clean"}]}.
make: Entering directory '/data/project/test_nif/c_src'
make: Leaving directory '/data/project/test_nif/c_src'
But when i run the command with option -a
, it only runs once.
$ DEBUG=1 rebar3 clean -a
===> Expanded command sequence to be run: [app_discovery,install_deps,clean]
===> Running provider: app_discovery
===> Found top-level apps: [test_nif]
using config: [{src_dirs,["src"]},{lib_dirs,["apps/*","lib/*","."]}]
===> Running provider: install_deps
===> Verifying dependencies...
===> Running provider: clean
===> Running hooks for clean with configuration:
===> {pre_hooks, []}.
===> Cleaning out test_nif...
===> Running hooks for clean in app test_nif (/data/project/test_nif/_build/default/lib/test_nif) with configuration:
===> {pre_hooks, []}.
===> Running hooks for clean in app test_nif (/data/project/test_nif/_build/default/lib/test_nif) with configuration:
===> {post_hooks, []}.
===> Running hooks for clean with configuration:
===> {post_hooks, [{"(linux|darwin|solaris)",clean,
"make -C c_src clean"},
{"(freebsd)",clean,"gmake -C c_src clean"}]}.
make: Entering directory '/data/project/test_nif/c_src'
make: Leaving directory '/data/project/test_nif/c_src'
I think both of these commands run clean on all apps, with or without options. Why would their behavior be inconsistent?
I tried to check the code and found that the parameters passed in these two places are different.
https://github.com/erlang/rebar3/blob/69a5898969adac08b30564801ea1d4cd407ffa5b/apps/rebar/src/rebar_prv_clean.erl#L53-L56
the parameters AllApps
and ProjectApps
have different app_info_t
content.
And i found only the clean hook is being run twice, the compile hook runs once.
I would expect the clean shell post hook to only be once with default option.
Look forward to your help, thanks in advance.
Generally the hooks can be run more than once to account for app-specific hooks and project-wide hooks. See https://rebar3.org/docs/configuration/configuration/#hookable-points-in-providers for details.
Looking at the logs, there are two message variations:
Running hooks for clean in app test_nif ...
Running hooks for clean with configuration ...
I believe what you are seeing is the hook running first for the app itself, and then for the project as a whole.
I'm not sure why the All
flag being set suddenly skips running it against the app though. It appears that -a
makes it run only on deps rather than on apps+deps.
Yes, the clean command with option -a
or --apps
, it's shell hooks on apps are not working correctly. it seems to be an issue.