WIP: add css from stasis
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
## Introduction
|
||||
|
||||
We wish to print a list of all the files in a directory, ignoring files beginning with certain characters, sorted alphabetically, with the directories last.
|
||||
|
||||
## Finding the files
|
||||
|
||||
### Code
|
||||
|
||||
Finds all files in the `path` directory recursively, ignoring any files or directories that start with any of the characters in the `@starts_with` module attribute.
|
||||
|
||||
```
|
||||
defmodule Files do
|
||||
@starts_with [".", "_"]
|
||||
|
||||
def find(path \\ "."), do: find(path, list_contents(path))
|
||||
|
||||
defp find(dir, files) do
|
||||
Enum.reduce(files, {dir, []}, fn file, {path, contents} ->
|
||||
{path, path |> Path.join(file) |> update_contents(file, contents)}
|
||||
end)
|
||||
end
|
||||
|
||||
defp list_contents(path), do: path |> File.ls!() |> ignore()
|
||||
|
||||
defp update_contents(path, file, contents) do
|
||||
cond do
|
||||
File.regular?(path) -> [file | contents]
|
||||
File.dir?(path) -> [find(path) | contents]
|
||||
end
|
||||
end
|
||||
|
||||
defp ignore(filenames) do
|
||||
Enum.reject(filenames, &(String.first(&1) in @starts_with))
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
### Output
|
||||
|
||||
The data structure holding the results of the file search.
|
||||
|
||||
```
|
||||
iex(1)> directory_tree = Files.find("hello")
|
||||
{"hello",
|
||||
[
|
||||
"README.md",
|
||||
{"hello/test",
|
||||
[
|
||||
{"hello/test/support", ["conn_case.ex"]},
|
||||
"test_helper.exs",
|
||||
{"hello/test/hello_web",
|
||||
[{"hello/test/hello_web/controllers", ["error_json_test.exs"]}]}
|
||||
]},
|
||||
{"hello/lib",
|
||||
[
|
||||
"hello.ex",
|
||||
{"hello/lib/hello", ["application.ex"]},
|
||||
"hello_web.ex",
|
||||
{"hello/lib/hello_web",
|
||||
[
|
||||
{"hello/lib/hello_web/controllers", ["error_json.ex"]},
|
||||
"telemetry.ex",
|
||||
"router.ex",
|
||||
"endpoint.ex"
|
||||
]}
|
||||
]},
|
||||
{"hello/priv", [{"hello/priv/static", ["robots.txt", "favicon.ico"]}]},
|
||||
{"hello/config",
|
||||
["config.exs", "dev.exs", "test.exs", "prod.exs", "runtime.exs"]},
|
||||
"mix.exs"
|
||||
]}
|
||||
```
|
||||
|
||||
## Sorting and printing
|
||||
|
||||
### Code
|
||||
|
||||
Sort alphabetically, with directories last. Downcase before comparing strings.
|
||||
|
||||
```
|
||||
defmodule Paths do
|
||||
def puts(dir_tree), do: dir_tree |> print() |> Enum.join("\n") |> IO.puts()
|
||||
|
||||
defp print({path, contents}), do: path |> list(contents) |> List.flatten()
|
||||
|
||||
defp list(path, contents) do
|
||||
contents |> Enum.sort(&alpha_asc_dir_last/2) |> Enum.map(&make_path(&1, path))
|
||||
end
|
||||
|
||||
defp alpha_asc_dir_last({a, _}, {b, _}), do: fmt(a) < fmt(b)
|
||||
defp alpha_asc_dir_last({_, _}, _), do: false
|
||||
defp alpha_asc_dir_last(_, {_, _}), do: true
|
||||
defp alpha_asc_dir_last(a, b), do: fmt(a) < fmt(b)
|
||||
|
||||
defp make_path(filename, path) when is_binary(filename), do: Path.join(path, filename)
|
||||
defp make_path({path, contents}, _), do: list(path, contents)
|
||||
|
||||
defp fmt(f), do: String.downcase(f)
|
||||
end
|
||||
```
|
||||
|
||||
### Output
|
||||
|
||||
Print all the files sorted.
|
||||
|
||||
```
|
||||
iex(2)> Paths.puts(directory_tree)
|
||||
hello/mix.exs
|
||||
hello/README.md
|
||||
hello/config/config.exs
|
||||
hello/config/dev.exs
|
||||
hello/config/prod.exs
|
||||
hello/config/runtime.exs
|
||||
hello/config/test.exs
|
||||
hello/lib/hello.ex
|
||||
hello/lib/hello_web.ex
|
||||
hello/lib/hello/application.ex
|
||||
hello/lib/hello_web/endpoint.ex
|
||||
hello/lib/hello_web/router.ex
|
||||
hello/lib/hello_web/telemetry.ex
|
||||
hello/lib/hello_web/controllers/error_json.ex
|
||||
hello/priv/static/favicon.ico
|
||||
hello/priv/static/robots.txt
|
||||
hello/test/test_helper.exs
|
||||
hello/test/hello_web/controllers/error_json_test.exs
|
||||
hello/test/support/conn_case.ex
|
||||
:ok
|
||||
```
|
||||
|
||||
## Conclusion
|
||||
|
||||
Trying to do this without recursion made it difficult to sort directories first.
|
||||
@@ -1 +0,0 @@
|
||||
# post 1
|
||||
@@ -1 +0,0 @@
|
||||
# post 2
|
||||
Reference in New Issue
Block a user