Skip to content

Commit

Permalink
Use filename:absname/2 to resolve absolute paths
Browse files Browse the repository at this point in the history
This handles Windows' `volumerelative` path types by properly resolving
them based on the "per-drive" working directory.

Also, resolve the input file absolute paths. This is new functionality;
if you were previously to use a file path like `a/../b`, that would have
been directly matched against the excludes. As a result, an exclude of
`b` would not have applied. This change makes sure relative path
resolution is consistent between `files`/`exclude_files`.

To avoid displaying different paths from what was requesting by config
or CLI options (e.g. when using the verbose flag), use a map of absolute
paths -> original paths and return the original paths from
`erlfmt_cli:set_difference/2` after applying excludes.
  • Loading branch information
danielfinke authored and michalmuskala committed Sep 2, 2024
1 parent f3be5db commit c2286a8
Showing 1 changed file with 16 additions and 15 deletions.
31 changes: 16 additions & 15 deletions src/erlfmt_cli.erl
Original file line number Diff line number Diff line change
Expand Up @@ -109,23 +109,24 @@ with_parsed(Name, Config) ->

-spec set_difference([file:name_all()], [file:name_all()]) -> [file:name_all()].
set_difference(Files, Excludes) ->
{ok, Dir} = file:get_cwd(),
AbsoluteExcludes = [resolve_path(Dir, E) || E <- Excludes],
AllExcludes = sets:from_list(Excludes ++ AbsoluteExcludes),
sets:to_list(sets:subtract(sets:from_list(Files), AllExcludes)).
{ok, Cwd} = file:get_cwd(),
AbsoluteFiles = maps:from_list([{resolve_path(Cwd, F), F} || F <- Files]),
AbsoluteExcludes = [resolve_path(Cwd, E) || E <- Excludes],
maps:values(maps:without(AbsoluteExcludes, AbsoluteFiles)).

resolve_path(Dir, Filename) ->
case filename:pathtype(Filename) of
absolute -> Filename;
relative -> resolve_path2(lists:reverse(filename:split(Dir)), filename:split(Filename))
end.

resolve_path2([_H | T1], [".." | T2]) ->
resolve_path2(T1, T2);
resolve_path2([_H | T1], [<<"..">> | T2]) ->
resolve_path2(T1, T2);
resolve_path2(Dir, Filename) ->
filename:join(lists:reverse(Dir) ++ Filename).
resolve_path2(filename:absname(Filename, Dir)).

resolve_path2(AbsPath) ->
[Volume | Components] = filename:split(AbsPath),
filename:join(resolve_path2(Components, [Volume])).

resolve_path2([".." | T1], [Volume]) -> resolve_path2(T1, [Volume]);
resolve_path2([<<"..">> | T1], [Volume]) -> resolve_path2(T1, [Volume]);
resolve_path2([".." | T1], [_H2 | T2]) -> resolve_path2(T1, T2);
resolve_path2([<<"..">> | T1], [_H2 | T2]) -> resolve_path2(T1, T2);
resolve_path2([H1 | T1], Components) -> resolve_path2(T1, [H1 | Components]);
resolve_path2([], Components) -> lists:reverse(Components).

%% needed because of getopt
-dialyzer({nowarn_function, [unprotected_with_config/2]}).
Expand Down

0 comments on commit c2286a8

Please sign in to comment.