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(-)
(limited to 'lib')
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