Skip to content

Instantly share code, notes, and snippets.

@AlexanderWingard
Last active December 17, 2015 21:29
Show Gist options
  • Save AlexanderWingard/5675134 to your computer and use it in GitHub Desktop.
Save AlexanderWingard/5675134 to your computer and use it in GitHub Desktop.
Prototype for stateful directory traverser
-module(tmp).
-compile(export_all).
test() ->
filelib:ensure_dir("level1/level2/level3/"),
file:write_file("level1/l11", "hello"),
file:write_file("level1/l12", "hello"),
file:write_file("level1/l13", "hello"),
file:write_file("level1/level2/l21", "hello"),
file:write_file("level1/level2/level3/l31", "hello"),
State0 = [{dir, "."}],
State1 = navigate(filename:split("./level1"), State0, "."),
State2 = navigate(filename:split("./level1/level2"), State1, "."),
State3 = navigate(filename:split("./level1"), State2, "."),
State4 = navigate(filename:split("./level1"), State3, "."),
State5 = navigate(filename:split("./level1"), State4, ".").
loop(Start, In) ->
case navigate(Start, In, ".") of
[] ->
ok;
Tree ->
loop(Start, Tree)
end.
navigate([H|T], Files, Prefix) ->
case lists:keytake(H, 2, Files) of
{value, {dir, H, []}, Rest} ->
Rest;
{value, {dir, H, Sub}, Rest} ->
lists:reverse([{dir, H, navigate(T, Sub, filename:join(Prefix, H))} | Rest]);
{value, {dir, H}, Rest} ->
lists:reverse([{dir, H, navigate(T, expand(H, Prefix), filename:join(Prefix, H))} | Rest]);
false ->
[]
end;
navigate([], Files, Prefix) ->
iterate(Files, Prefix).
iterate([{dir, Path} | T], Prefix) ->
iterate([{dir, Path, expand(Path, Prefix)} | T], Prefix);
iterate([{dir, Path, []} | T], Prefix) ->
iterate(T, Prefix);
iterate([{dir, Path, Files} | T], Prefix) ->
[{dir, Path, iterate(Files, filename:join([Prefix,Path]))} | T];
iterate([H | T], Prefix) ->
io:format("~s~n", [filename:join(Prefix, H)]),
T;
iterate([], Prefix) ->
[].
expand(Path, Prefix) ->
Dirname = filename:join([Prefix, Path]),
{ok, Files0} = file:list_dir(Dirname),
Files = lists:map(fun(File) ->
Filename = filename:join([Dirname, File]),
case filelib:is_dir(Filename) of
true ->
{dir, File};
false ->
File
end
end,
Files0),
lists:reverse(lists:sort(Files)).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment