Skip to content
This repository has been archived by the owner on May 12, 2018. It is now read-only.

avoid pre-compile time errors in expand_include_lib_path #485

Merged
merged 1 commit into from May 8, 2015
Merged

avoid pre-compile time errors in expand_include_lib_path #485

merged 1 commit into from May 8, 2015

Conversation

ghost
Copy link

@ghost ghost commented Apr 25, 2015

No description provided.

@ghost
Copy link

ghost commented Apr 25, 2015

Thanks. Do you mind extending the commit message with a previously broken include_lib directive?

@ghost
Copy link
Author

ghost commented Apr 25, 2015

No problem. Done.

@ghost
Copy link

ghost commented Apr 25, 2015

This probably warrants a debug log msg.

@ghost
Copy link
Author

ghost commented Apr 25, 2015

ok

@carlosedp
Copy link
Contributor

Tested the changes and the pull request works here. Thanks @Tuncer.

[Lib | Parts] = filename:split(filename:dirname(File)),
SubDir = case Parts of
[] -> % prevent function clause error
[];
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make more sense to print the debug msg here instead?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably yes. I have pushed an updated version.

@ghost
Copy link

ghost commented May 5, 2015

@kejv should we have tests to go with this?

@ghost
Copy link
Author

ghost commented May 5, 2015

Are we able to tell whether compilation failed because of rebar internal error or compile time error (I am thinking of retest_sh:run/2)?

@ghost
Copy link

ghost commented May 5, 2015

On Tue, May 5, 2015 at 8:03 PM, kejv wrote:

Are we able to tell whether compilation failed because of rebar internal error or compile time error (I am thinking of retest_sh:run/2)?

Scanning the error output from run/2 would be the usual way.

@ghost
Copy link
Author

ghost commented May 6, 2015

Compare the rebar errors produced by 1) erlc, 2) rebar itself:

{stopped,{1,
          ["5396","==> erlc_dep_graph_rt (compile)",
           "src/lisp.erl:11: can't find include lib \"include/non/existent.hrl\"",
           "Compiling src/lisp.erl failed:",
           "ERROR: compile failed while processing /home/david/git/rebar/rt.work/20150506_175922/erlc_dep_graph_rt: rebar_abort"]}}
{stopped,{1,
          ["5550","==> erlc_dep_graph_rt (compile)",
           "ERROR: compile failed while processing /home/david/git/rebar/rt.work/20150506_175958/erlc_dep_graph_rt: {'EXIT',",
           "    {function_clause,",
           "        [{filename,join,[[]],[{file,\"filename.erl\"},{line,392}]},",
           "         {rebar_erlc_compiler,expand_include_lib_path,1,",
           "             [{file,\"src/rebar_erlc_compiler.erl\"},{line,696}]},",
           "         {rebar_erlc_compiler,process_attr,3,",
           "             [{file,\"src/rebar_erlc_compiler.erl\"},{line,646}]},",
           "         {rebar_erlc_compiler,parse_attrs,2,",
           "             [{file,\"src/rebar_erlc_compiler.erl\"},{line,614}]},",
           "         {rebar_erlc_compiler,modify_erlcinfo,4,",
           "             [{file,\"src/rebar_erlc_compiler.erl\"},{line,444}]},",
           "         {rebar_erlc_compiler,'-update_erlcinfo_fun/2-fun-0-',4,",
           "             [{file,\"src/rebar_erlc_compiler.erl\"},{line,399}]},",
           "         {lists,foldl,3,[{file,\"lists.erl\"},{line,1248}]},",
           "         {rebar_erlc_compiler,init_erlcinfo,2,",
           "             [{file,\"src/rebar_erlc_compiler.erl\"},{line,389}]}]}}"]}}

I don't think there's any sane way how to test the difference (and I don't consider scanning the strings in the list with regex as sane). retest_sh:run/2 should probably provide some more detailed error codes.

@ghost
Copy link

ghost commented May 6, 2015

Doesn't that mean we should (1) print a more informative error in erlc_compiler, and (2) can't we scan for the ?DEBUG message?

@ghost
Copy link
Author

ghost commented May 6, 2015

(1) No, since we don't print any error message at all in erlc_compiler. Quite the contrary actually, we want to try to avoid any errors.
(2) No, since ?DEBUG message is present only if compiling on debug level and I don't think we should rely on this fact.

Moreover, I really start thinking that printing the debug message is not such a good idea. Because it will print for e.g. -include_lib("erl_compile.hrl"). but not for -include_lib("stdlib/includ/erl_compile.hrl"). (note the typo). I think we should not pretend that we are trying to catch invalid include_lib file at this place. User will get compilation error later anyway. Only thing done here is trying to prevent any rebar internal errors.

@ghost
Copy link

ghost commented May 6, 2015

I agree, but as we're treating the included header as a dependency, shouldn't we at least log a DEBUG msg on ENOFILE?

@ghost
Copy link
Author

ghost commented May 6, 2015

Note that at this stage we don't know yet whether the header is a dependency for rebar logic (erlcinfo). This will be decided only in expand_file_names/2 based on content of Dirs variable. Generally I think there's no reason to duplicate the work of erlc. If the header file doesn't exist erlc will throw an error anyway.

@ghost
Copy link

ghost commented May 6, 2015

But don't we already do the check before updating the digraph?

@ghost
Copy link
Author

ghost commented May 6, 2015

No. We collect all included headers (in process_attr) and then filter out those which are not in the include path (in expand_file_names) and this will typically filter out all include_lib files.

Generally I think there's no reason to duplicate the work of erlc. If the header file doesn't exist erlc will throw an error anyway.

Still this is the strongest reason why rebar should not try to check existence of files, yet even printing some related debug messages.

@ghost
Copy link

ghost commented May 7, 2015

Okay. Let's add the previously crashing scenario as a regression test and merge this.

Previously when user specified broken include_lib, such as
-include_lib("my_app.hrl"), the code throwed too early
exception.  We fix this simply by avoiding any possible
internal errors, possibly letting even nonsensical paths pass.
These will be checked and filtered later in expand_file_names/2.
@ghost
Copy link
Author

ghost commented May 7, 2015

Until retest_sh:run/2 starts producing more detailed error codes I am afraid we will have to live without regression test...

@ghost
Copy link

ghost commented May 7, 2015

Having fixed the rebar-internal error, why can't we (1) expect run/2 failure AND (2) scan for can't find include lib...?

@ghost
Copy link
Author

ghost commented May 7, 2015

You mean something like this?

{stopped,{_,Lines}} = Result,
?assertMatch([ _ | _ ], lists:filter( fun(L) ->
        re:run(L, "can't find include lib \"include/non/existent.hrl\" ) /= nomatch
end, Lines)

This seems quite hacky to me. And moreover it is also fragile. What if someone decides that he really wants that debugging message (which I didn't) and formulates it in exactly the same way as erlc? Then if he breaks the code the test will still pass. Or what if erlc for some reason changes the error message?

Frankly, I would rather have no tests at all than tests with potential of false negatives or positives.

@ghost
Copy link

ghost commented May 7, 2015

Something like that or inttest/logging.

If someone adds that debug msg, the test would have to be adapted. Also, looking for a less specific error msg and having a minimal module that's unable to provoke any other error should make the scan resilient against changes in compile:file.

However, the missing test is not important enough to hold up the patch. So, I'm okay without it.

@ferd
Copy link
Contributor

ferd commented May 8, 2015

Uh yeah, so that +7-3 patch seems good then. Merging.

ferd added a commit that referenced this pull request May 8, 2015
avoid pre-compile time errors in expand_include_lib_path
@ferd ferd merged commit dec5bed into rebar:master May 8, 2015
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
2 participants