Skip to content

Commit

Permalink
Improve performance of get_files
Browse files Browse the repository at this point in the history
  • Loading branch information
giacomocavalieri committed May 14, 2024
1 parent 1deee71 commit 3e2fc10
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 34 deletions.
42 changes: 38 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,112 +2,146 @@

## Unreleased

- improve performance of `get_files`

## v1.7.0 - 5 April 2024

- add `create_symlink` function to create a symbolic link
- add `verify_is_symlink` function to check if a file is a symbolic link
- add `describe_error` function to get human-readable descriptions out of errors

## v1.6.1 - 28 March 2024

- fix bug I introduced to `clear_directory_all` which accidentally made absolute directories
relative.

## v1.6.0 - 26 March 2024
- add the `clear_directory` function to make it easy to delete the

- add the `clear_directory` function to make it easy to delete the
contents of a directory while leaving the top level directory in place.
- add the `filepath` dependency to clean up some code.

## v1.5.1 - 22 March 2024

- use unicode module to convert filenames to utf8 on erlang

## v1.5.0 - 29 February 2024

- add `file_info` function.

## v1.4.2 - 18 February 2024

- Update msg in deprecated tag for `is_directory` to correctly point to `verify_is_directory`

## v1.4.1 - 1 February 2024

- Update gleam_stdlib dependency to "~> 0.34 or ~> 1.0" in preparation for 1.0.

## v1.3.1 - 27 January 2024

- Update msg in deprecated tag for `is_file` to correctly point to `verify_is_file`.

## v1.3.0 - 26 January 2024

- Deprecate `is_file` and `is_directory` in favor of `verify_is_file` and `verify_is_directory`,
which error on lack of permissions rather than silently returning false.

## v1.2.0 - 11 January 2024

- Add the `current_directory` function

## v1.1.2 - 9 January 2024

- Update stdlib dep to 0.33

## v1.1.1 - 5 January 2024

- Fix bug with double "/" from `get_files`

## v1.1.0 - 25 December 2023

- Added `set_permissions` and `set_permissions_octal` functions for setting
permissions on a file

## v1.0.0 - 16 November 2023

- No changes, just going v1 so somver starts working

## v0.4.0 - 15 November 2023

- Renamed `list_contents` to `read_directory`
- Added `get_files`

## v0.3.0 - 12 November 2023

- Switched order of parameters for `write`, `append`, `write_bits`, and `append_bits` functions.
They now take the filename first.

## v0.2.1 - 11 November 2023

- Updated ffi js to use `BitArray`

## v0.2.0 - 6 November 2023

- Updated for Gleam v0.32.

## v0.1.14 - 18 September 2023

- added `delete_all` which takes a list of paths to call delete on

## v0.1.13 - 17 September 2023

- copy and rename directory functions perform a create_directory_all

## v0.1.12 - 17 September 2023

- Add `copy_directory` and `rename_directory` functions

## v0.1.11 - 11 September 2023

- Add `copy_file` and `rename_file` functions

## v0.1.10 - 9 August 2023

- Change `creat_dir_all` to `create_directory_all`

## v0.1.9 - 8 August 2023

- Add functions `create_dir_all`, `create_file`, and `is_file`.
- Remove function `delete_directory`. The `delete` function now deletes files
and recursively deletes directories.
- `make_directory` is now called `create_directory` to be consistent with `create_file`.

## v0.1.8 - 31 July 2023

- Small refactor to remove js functions `writeFile` and `appendFile`

## v0.1.7 - 31 July 2023
- Fix bug where `read` was incorrectly returning non utf8 content for string on
javascript target. Now returns correct `NonUtf8` error

- Fix bug where `read` was incorrectly returning non utf8 content for string on
javascript target. Now returns correct `NonUtf8` error

## v0.1.6 - 19 July 2023

- Add `make_directory` and `delete_directory` functions for working with directories.

## v0.1.5 - 12 July 2023

- Update to use new ffi syntax

## v0.1.4 - 21 June 2023

- Add `is_directory` and `list_contents` functions for working with directories.

## v0.1.3 - 21 June 2023

- Add ffi to remove gleam_erlang dependency

## v0.1.2 - 21 June 2023

- Remove unnecessary dependency on `gleam_javascript`. Whoops.

## v0.1.1 - 31 May 2023

- Refactored to match gleam idiom of ffi "do" functions and single signature.
- Added documentation about the utf8 issue with the read function.
- Added documentation about the utf8 issue with the read function.
65 changes: 35 additions & 30 deletions src/simplifile.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -182,10 +182,10 @@ pub type FileInfo {
FileInfo(
/// File size in bytes.
size: Int,
/// File mode that indicates the file type and its permissions.
/// For example, in Unix and Linux, a mode value of 33188 indicates
/// a regular file and the permissions associated with it
/// (read and write for the owner, and read-only for others, in
/// File mode that indicates the file type and its permissions.
/// For example, in Unix and Linux, a mode value of 33188 indicates
/// a regular file and the permissions associated with it
/// (read and write for the owner, and read-only for others, in
/// this case).
mode: Int,
/// Number of hard links that exist for the file.
Expand Down Expand Up @@ -265,9 +265,9 @@ pub fn delete(file_or_dir_at path: String) -> Result(Nil, FileError) {

/// Delete all files/directories specified in a list of paths.
/// Recursively deletes provided directories.
/// Does not return an error if one or more of the provided paths
/// do not exist.
///
/// Does not return an error if one or more of the provided paths
/// do not exist.
///
pub fn delete_all(paths paths: List(String)) -> Result(Nil, FileError) {
case paths {
[] -> Ok(Nil)
Expand Down Expand Up @@ -338,15 +338,15 @@ pub fn append_bits(
/// ```gleam
/// let assert True = is_directory("./test")
/// ```
///
///
@deprecated("Use `verify_is_directory` instead")
pub fn is_directory(filepath: String) -> Bool {
do_is_directory(filepath)
}

/// Checks if the provided filepath exists and is a directory.
/// Returns an error if it lacks permissions to read the directory.
///
///
/// ## Example
/// ```gleam
/// let assert Ok(True) = verify_is_directory("./test")
Expand Down Expand Up @@ -392,27 +392,27 @@ pub fn create_symlink(

/// Lists the contents of a directory.
/// The list contains directory and file names, and is not recursive.
///
///
/// ## Example
/// ```gleam
/// let assert Ok(files_and_folders) = read_directory(at: "./Folder1")
/// ```
///
///
pub fn read_directory(at path: String) -> Result(List(String), FileError) {
do_read_directory(path)
|> cast_error
}

/// Returns `True` if there is a file at the given path, false otherwise.
///
///
@deprecated("Use `verify_is_file` instead")
pub fn is_file(filepath: String) -> Bool {
do_is_file(filepath)
}

/// Checks if the file at the provided filepath exists and is a file.
/// Returns an Error if it lacks permissions to read the file.
///
///
/// ## Example
/// ```gleam
/// let assert Ok(True) = verify_is_file("./test.txt")
Expand Down Expand Up @@ -454,7 +454,7 @@ fn do_verify_is_symlink(filepath: String) -> Result(Bool, FileError)

/// Creates an empty file at the given filepath. Returns an `Error(Eexist)`
/// if the file already exists.
///
///
pub fn create_file(at filepath: String) -> Result(Nil, FileError) {
case
filepath
Expand Down Expand Up @@ -502,8 +502,8 @@ pub fn rename_file(at src: String, to dest: String) -> Result(Nil, FileError) {

/// Copy a directory recursively
pub fn copy_directory(at src: String, to dest: String) -> Result(Nil, FileError) {
// Erlang does not provide a built in `copy_dir` function,
// and Deno doesn't support Node's `fs.cpSync`, so we'll just roll
// Erlang does not provide a built in `copy_dir` function,
// and Deno doesn't support Node's `fs.cpSync`, so we'll just roll
// our own for now.
use _ <- result.try(create_directory_all(dest))
do_copy_directory(src, dest)
Expand Down Expand Up @@ -561,19 +561,24 @@ pub fn clear_directory(at path: String) -> Result(Nil, FileError) {

/// Returns a list of filepaths for every file in the directory, including nested
/// files.
///
///
pub fn get_files(in directory: String) -> Result(List(String), FileError) {
use contents <- result.try(read_directory(directory))
let paths =
contents
|> list.map(filepath.join(directory, _))
let files = list.filter(paths, fn(path) { verify_is_file(path) == Ok(True) })
case list.filter(paths, fn(path) { verify_is_directory(path) == Ok(True) }) {
[] -> Ok(files)
directories -> {
use nested_files <- result.try(list.try_map(directories, get_files))
Ok(list.append(files, list.flatten(nested_files)))
}
use acc, content <- list.try_fold(over: contents, from: [])
let path = filepath.join(directory, content)

case verify_is_file(path) {
Error(e) -> Error(e)
Ok(True) -> Ok([path, ..acc])
Ok(False) ->
case verify_is_directory(path) {
Error(e) -> Error(e)
Ok(False) -> Ok(acc)
Ok(True) -> {
use nested_files <- result.try(get_files(path))
Ok(list.append(acc, nested_files))
}
}
}
}

Expand Down Expand Up @@ -617,7 +622,7 @@ pub fn file_permissions_to_octal(permissions: FilePermissions) -> Int {
}

/// Sets the permissions for a given file
///
///
/// # Example
/// ```gleam
/// let all = set.from_list([Read, Write, Execute])
Expand All @@ -632,7 +637,7 @@ pub fn set_permissions(
}

/// Sets the permissions for a given file using an octal representation
///
///
/// # Example
/// ```gleam
/// set_permissions_octal("./script.sh", 0o777)
Expand All @@ -646,7 +651,7 @@ pub fn set_permissions_octal(
}

/// Returns the current working directory
///
///
pub fn current_directory() -> Result(String, FileError) {
do_current_directory()
|> cast_error
Expand Down

0 comments on commit 3e2fc10

Please sign in to comment.