rebar3 icon indicating copy to clipboard operation
rebar3 copied to clipboard

the clean shell hooks will run twice?

Open decoda opened this issue 1 year ago • 2 comments

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.

decoda avatar Dec 29 '22 06:12 decoda

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.

ferd avatar Dec 29 '22 16:12 ferd

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.

decoda avatar Dec 30 '22 03:12 decoda