From c365d6f485c708fe121aa6c63d9af66e7ce3164f Mon Sep 17 00:00:00 2001 From: Benjamin Peinhardt Date: Sat, 7 Mar 2026 14:56:58 -0500 Subject: [PATCH 1/4] add raw mode options as default --- src/simplifile.gleam | 7 +++++++ src/simplifile_erl.erl | 6 +++--- src/simplifile_js.mjs | 12 ++++++++++++ 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/simplifile.gleam b/src/simplifile.gleam index b38c40c..5ab3810 100644 --- a/src/simplifile.gleam +++ b/src/simplifile.gleam @@ -334,6 +334,13 @@ pub fn write( @external(javascript, "./simplifile_js.mjs", "delete_") pub fn delete(file_or_dir_at path: String) -> Result(Nil, FileError) +/// Delete a file. +/// On Erlang, if you're specifically deleting a single file, this function +/// should be more efficient than `delete` because it can pass the raw option. +@external(erlang, "simplifile_erl", "delete_file") +@external(javascript, "./simplifile_js.mjs", "deleteFile") +pub fn delete_file(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 diff --git a/src/simplifile_erl.erl b/src/simplifile_erl.erl index a1d138f..f997758 100644 --- a/src/simplifile_erl.erl +++ b/src/simplifile_erl.erl @@ -103,20 +103,20 @@ read_bits(Filename) -> %% Write bytes to a file write_bits(Filename, Contents) -> case bit_size(Contents) rem 8 of - 0 -> posix_result(file:write_file(Filename, Contents)); + 0 -> posix_result(file:write_file(Filename, Contents, [raw])); _ -> {error, einval} end. %% Append bytes to a file append_bits(Filename, Contents) -> case bit_size(Contents) rem 8 of - 0 -> posix_result(file:write_file(Filename, Contents, [append])); + 0 -> posix_result(file:write_file(Filename, Contents, [append, raw])); _ -> {error, einval} end. %% Delete the file at the given path delete_file(Filename) -> - posix_result(file:delete(Filename)). + posix_result(file:delete(Filename, [raw])). %% Create a directory at the given path. Missing parent directories are not created. create_directory(Dir) -> diff --git a/src/simplifile_js.mjs b/src/simplifile_js.mjs index 1c003df..6b82923 100644 --- a/src/simplifile_js.mjs +++ b/src/simplifile_js.mjs @@ -182,6 +182,18 @@ export function delete_(fileOrDirPath) { }); } +/** + * Specifically delete a single file. + * + * @param {string} filePath + * @returns {Ok | GError} + */ +export function deleteFile(filePath) { + return gleamResult(() => { + fs.unlinkSync(path.normalize(filePath)); + }) +} + /** * List the contents of a directory. * From fd113695760c2e8e4e0269602ec88e2faa96da77 Mon Sep 17 00:00:00 2001 From: Benjamin Peinhardt Date: Sat, 7 Mar 2026 14:59:51 -0500 Subject: [PATCH 2/4] update changelog and gleam.toml --- CHANGELOG.md | 4 ++++ gleam.toml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fc448e9..8b3daf5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +## v2.4.0 - 7 March 2026 +- Use `raw` option for `write` and `append` on Erlang +- Add `delete_file` function for specifically deleting a file (uses `raw` on erlang as well) + ## v2.3.2 - 26 December 2025 - Fix bug where unknown errors were not properly converted to the Unknown variant in Erlang ffi. diff --git a/gleam.toml b/gleam.toml index b974558..92e39e5 100644 --- a/gleam.toml +++ b/gleam.toml @@ -1,5 +1,5 @@ name = "simplifile" -version = "2.3.2" +version = "2.4.0" description = "Basic file operations that work on all targets" licences = ["Apache-2.0"] From ad6352be9ca1d943cf2ef5e8abe18a96e9ec5c9c Mon Sep 17 00:00:00 2001 From: Benjamin Peinhardt Date: Sat, 7 Mar 2026 15:05:04 -0500 Subject: [PATCH 3/4] new test for new delete_file function --- test/simplifile_test.gleam | 35 ++++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/test/simplifile_test.gleam b/test/simplifile_test.gleam index 0cbe3c2..6eaa930 100644 --- a/test/simplifile_test.gleam +++ b/test/simplifile_test.gleam @@ -13,11 +13,11 @@ import simplifile.{ Esrch, Estale, Etxtbsy, Exdev, Execute, File, FilePermissions, NotUtf8, Read, Unknown, Write, append, append_bits, copy, copy_directory, copy_file, create_directory, create_directory_all, create_file, create_link, - create_symlink, delete, delete_all, file_info, file_info_permissions, - file_info_permissions_octal, file_info_type, file_permissions_to_octal, - get_files, is_directory, is_file, is_symlink, link_info, read, read_bits, - read_directory, rename, set_permissions, set_permissions_octal, write, - write_bits, + create_symlink, delete, delete_all, delete_file, file_info, + file_info_permissions, file_info_permissions_octal, file_info_type, + file_permissions_to_octal, get_files, is_directory, is_file, is_symlink, + link_info, read, read_bits, read_directory, rename, set_permissions, + set_permissions_octal, write, write_bits, } pub fn main() { @@ -357,6 +357,31 @@ pub fn delete_test() { let assert Ok(False) = is_file("./tmp/" <> the_target) } +pub fn delete_file_test() { + // Basic delete + let assert Ok(_) = write("Hello", to: "./tmp/existing_file_2.txt") + let assert Ok(_) = delete_file("./tmp/existing_file_2.txt") + let assert Error(Enoent) = read("./tmp/existing_file_2.txt") + + // Deleting a file that doesn't exist throws an error + let assert Error(Enoent) = delete_file("./idontexist") + + // Delete a symlink doesn't delete the target + let the_target = "target_of_created_symlink_2" + let the_symlink = "./tmp/created_symlink_2" + let assert Ok(_) = + "" + |> write(to: "./tmp/" <> the_target) + let assert Ok(_) = create_symlink(the_target, the_symlink) + let assert Ok(True) = is_file("./tmp/" <> the_target) + let assert Ok(True) = is_symlink(the_symlink) + let assert Ok(_) = delete_file(the_symlink) + let assert Ok(False) = is_symlink(the_symlink) + let assert Ok(True) = is_file("./tmp/" <> the_target) + let assert Ok(_) = delete_file(at: "./tmp/" <> the_target) + let assert Ok(False) = is_file("./tmp/" <> the_target) +} + pub fn delete_all_test() { let files = list.map([1, 2, 3, 4, 5], fn(item) { From 798b394788369250bd7cd06a56d7f6669b452654 Mon Sep 17 00:00:00 2001 From: Benjamin Peinhardt Date: Sat, 7 Mar 2026 15:10:48 -0500 Subject: [PATCH 4/4] changelog tweak --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b3daf5..ff7abbe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,8 +3,8 @@ ## Unreleased ## v2.4.0 - 7 March 2026 -- Use `raw` option for `write` and `append` on Erlang -- Add `delete_file` function for specifically deleting a file (uses `raw` on erlang as well) +- Use `raw` option for write and append operations on Erlang +- Add `delete_file` function for specifically deleting a file (uses `raw` on Erlang as well) ## v2.3.2 - 26 December 2025 - Fix bug where unknown errors were not properly converted to the Unknown variant in Erlang ffi.