From de0771a4b3d882161f10c1d2d03c8027327f9323 Mon Sep 17 00:00:00 2001 From: Hans Bolinder Date: Thu, 4 Jan 2018 16:54:22 +0100 Subject: stdlib: Let filelib:find_source() search subdirs The Design Principles states that an application can have Erlang source files one level below the "src" directory, and now filelib:find_source() by default searches one level below "src". The same applies to "esrc". That directory is only mentioned in filename(3). --- lib/kernel/doc/src/kernel_app.xml | 20 +++++++++++++++++--- lib/stdlib/doc/src/filelib.xml | 4 ++-- lib/stdlib/doc/src/filename.xml | 19 +++++++++++-------- lib/stdlib/src/filelib.erl | 21 ++++++++++++++------- lib/stdlib/test/filelib_SUITE.erl | 27 ++++++++++++++++++++++++--- 5 files changed, 68 insertions(+), 23 deletions(-) diff --git a/lib/kernel/doc/src/kernel_app.xml b/lib/kernel/doc/src/kernel_app.xml index e5ac031539..0762cebc94 100644 --- a/lib/kernel/doc/src/kernel_app.xml +++ b/lib/kernel/doc/src/kernel_app.xml @@ -4,7 +4,7 @@
- 19962017 + 19962018 Ericsson AB. All Rights Reserved. @@ -469,8 +469,12 @@ MaxT = TickTime + TickTime / 4 ObjSuffix = string() SrcSuffix = string() -

Specifies a list of rules for use by filelib:find_file/2 and - filelib:find_source/2. If this is set to some other value +

Specifies a list of rules for use by + + filelib:find_file/2 + + filelib:find_source/2 + If this is set to some other value than the empty list, it replaces the default rules. Rules can be simple pairs of directory suffixes, such as {"ebin", "src"}, which are used by filelib:find_file/2, or @@ -478,6 +482,16 @@ MaxT = TickTime + TickTime / 4 file name extensions, for example [{".beam", ".erl", [{"ebin", "src"}]}, which are used by filelib:find_source/2. Both kinds of rules can be mixed in the list.

+

The interpretation of ObjDirSuffix and SrcDirSuffix + is as follows: if the end of the directory name where an + object is located matches ObjDirSuffix, then the + name created by replacing ObjDirSuffix with + SrcDirSuffix is expanded by calling + + filelib:wildcard/1, and the first regular + file found among the matches is the source file. +

+ diff --git a/lib/stdlib/doc/src/filelib.xml b/lib/stdlib/doc/src/filelib.xml index 80c4acffdb..11762a3c5a 100644 --- a/lib/stdlib/doc/src/filelib.xml +++ b/lib/stdlib/doc/src/filelib.xml @@ -4,7 +4,7 @@
- 20032017 + 20032018 Ericsson AB. All Rights Reserved. @@ -267,7 +267,7 @@ filelib:wildcard("lib/**/*.{erl,hrl}") for a file with the extension .beam, the default rule is to look for a file with a corresponding extension .erl by replacing the suffix "ebin" of the object directory path with - "src". + "src" or "src/*". The file search is done through find_file/3. The directory of the object file is always tried before any other directory specified diff --git a/lib/stdlib/doc/src/filename.xml b/lib/stdlib/doc/src/filename.xml index 14fd5ef787..1135a6dd80 100644 --- a/lib/stdlib/doc/src/filename.xml +++ b/lib/stdlib/doc/src/filename.xml @@ -4,7 +4,7 @@
- 19972017 + 19972018 Ericsson AB. All Rights Reserved. @@ -372,15 +372,18 @@ true tuples {BinSuffix, SourceSuffix} and is interpreted as follows: if the end of the directory name where the object is located matches BinSuffix, then the - source code directory has the same name, but with - BinSuffix replaced by - SourceSuffix. Rules defaults + name created by replacing BinSuffix with + SourceSuffix is expanded by calling + + filelib:wildcard/1. + If a regular file is found among the matches, the function + returns that location together with Options. + Otherwise the next rule is tried, and so on.

+

Rules defaults to:

-[{"", ""}, {"ebin", "src"}, {"ebin", "esrc"}] -

If the source file is found in the resulting directory, the function - returns that location together with Options. - Otherwise the next rule is tried, and so on.

+[{"", ""}, {"ebin", "src"}, {"ebin", "esrc"}, + {"ebin", "src/*"}, {"ebin", "esrc/*"}]

The function returns {SourceFile, Options} if it succeeds. SourceFile is the absolute path to the source diff --git a/lib/stdlib/src/filelib.erl b/lib/stdlib/src/filelib.erl index d7c313f214..a9c055f72d 100644 --- a/lib/stdlib/src/filelib.erl +++ b/lib/stdlib/src/filelib.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2017. All Rights Reserved. +%% Copyright Ericsson AB 1997-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -544,17 +544,16 @@ default_search_rules() -> {"", ".c", c_source_search_rules()}, {"", ".in", basic_source_search_rules()}, %% plain old directory rules, backwards compatible - {"", ""}, - {"ebin","src"}, - {"ebin","esrc"} - ]. + {"", ""}] ++ erl_source_search_rules(). basic_source_search_rules() -> (erl_source_search_rules() ++ c_source_search_rules()). erl_source_search_rules() -> - [{"ebin","src"}, {"ebin","esrc"}]. + [{"ebin","src"}, {"ebin","esrc"}, + {"ebin",filename:join("src", "*")}, + {"ebin",filename:join("esrc", "*")}]. c_source_search_rules() -> [{"priv","c_src"}, {"priv","src"}, {"bin","c_src"}, {"bin","src"}, {"", "src"}]. @@ -634,8 +633,16 @@ try_dir_rule(Dir, Filename, From, To) -> Src = filename:join(NewDir, Filename), case is_regular(Src) of true -> {ok, Src}; - false -> error + false -> find_regular_file(wildcard(Src)) end; false -> error end. + +find_regular_file([]) -> + error; +find_regular_file([File|Files]) -> + case is_regular(File) of + true -> {ok, File}; + false -> find_regular_file(Files) + end. diff --git a/lib/stdlib/test/filelib_SUITE.erl b/lib/stdlib/test/filelib_SUITE.erl index c94821bc75..261acb70ad 100644 --- a/lib/stdlib/test/filelib_SUITE.erl +++ b/lib/stdlib/test/filelib_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2005-2017. All Rights Reserved. +%% Copyright Ericsson AB 2005-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -26,7 +26,7 @@ wildcard_one/1,wildcard_two/1,wildcard_errors/1, fold_files/1,otp_5960/1,ensure_dir_eexist/1,ensure_dir_symlink/1, wildcard_symlink/1, is_file_symlink/1, file_props_symlink/1, - find_source/1]). + find_source/1, find_source_subdir/1]). -import(lists, [foreach/2]). @@ -47,7 +47,7 @@ all() -> [wildcard_one, wildcard_two, wildcard_errors, fold_files, otp_5960, ensure_dir_eexist, ensure_dir_symlink, wildcard_symlink, is_file_symlink, file_props_symlink, - find_source]. + find_source, find_source_subdir]. groups() -> []. @@ -559,3 +559,24 @@ find_source(Config) when is_list(Config) -> {ok, ParserYrl} = filelib:find_file(ParserYrlName, ParserYrlDir), {ok, ParserYrl} = filelib:find_file(ParserYrlName, ParserYrlDir, []), ok. + +find_source_subdir(Config) when is_list(Config) -> + BeamFile = code:which(inets), % Located in lib/inets/src/inets_app/ + BeamName = filename:basename(BeamFile), + BeamDir = filename:dirname(BeamFile), + SrcName = filename:basename(BeamFile, ".beam") ++ ".erl", + + {ok, SrcFile} = filelib:find_source(BeamName, BeamDir), + SrcName = filename:basename(SrcFile), + + {error, not_found} = + filelib:find_source(BeamName, BeamDir, + [{".beam",".erl",[{"ebin","src"}]}]), + {ok, SrcFile} = + filelib:find_source(BeamName, BeamDir, + [{".beam",".erl", + [{"ebin",filename:join("src", "*")}]}]), + + {ok, SrcFile} = filelib:find_file(SrcName, BeamDir), + + ok. -- cgit v1.2.3 From 36b19c153fba7c41ab1da9c9e8bc6e685da1fd95 Mon Sep 17 00:00:00 2001 From: Hans Bolinder Date: Fri, 5 Jan 2018 12:54:34 +0100 Subject: stdlib: Correct a filelib test case --- lib/stdlib/test/filelib_SUITE.erl | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/stdlib/test/filelib_SUITE.erl b/lib/stdlib/test/filelib_SUITE.erl index 261acb70ad..afaf2404fa 100644 --- a/lib/stdlib/test/filelib_SUITE.erl +++ b/lib/stdlib/test/filelib_SUITE.erl @@ -536,16 +536,18 @@ find_source(Config) when is_list(Config) -> [{".erl",".yrl",[{"",""}]}]), {ok, ParserErl} = filelib:find_source(code:which(core_parse)), + ParserErlName = filename:basename(ParserErl), + ParserErlDir = filename:dirname(ParserErl), {ok, ParserYrl} = filelib:find_source(ParserErl), "lry." ++ _ = lists:reverse(ParserYrl), - {ok, ParserYrl} = filelib:find_source(ParserErl, + {ok, ParserYrl} = filelib:find_source(ParserErlName, ParserErlDir, [{".beam",".erl",[{"ebin","src"}]}, {".erl",".yrl",[{"",""}]}]), %% find_source automatically checks the local directory regardless of rules {ok, ParserYrl} = filelib:find_source(ParserErl), - {ok, ParserYrl} = filelib:find_source(ParserErl, - [{".beam",".erl",[{"ebin","src"}]}]), + {ok, ParserYrl} = filelib:find_source(ParserErlName, ParserErlDir, + [{".erl",".yrl",[{"ebin","src"}]}]), %% find_file does not check the local directory unless in the rules ParserYrlName = filename:basename(ParserYrl), -- cgit v1.2.3