HigherOrderCO / HVM

A massively parallel, optimal functional runtime in Rust
https://higherorderco.com
Apache License 2.0
10.43k stars 395 forks source link

Add IO functions for removing files and directories #418

Open kings177 opened 3 weeks ago

kings177 commented 3 weeks ago

Implement a file deletion functionality to give Bend the ability to delete files from the filesystem. This should include both single file deletion and recursive directory deletion.

1. delete_file(path)

@spec delete_file(str) -> Result[None, Error]

Deletes a single file or an empty directory at the specified path.

Returns Ok(None) if successful, or Err(reason) if an error occurs.

This function attempts to remove both files and empty directories without first checking the type of the path. It tries to remove the path as a file first, and if that fails, it attempts to remove it as a directory.

Possible (but not limited to) errors:

Examples

# Delete an existing file
result = delete_file("example.txt")
# Ok(None)
# Delete an empty directory
result = delete_file("empty_dir")
# Ok(None)
# Try to delete a non-existent file or directory
result = delete_file("nonexistent.txt")
# Err(FileNotFound)
# Try to delete a non-empty directory
result = delete_file("my_directory")
# Err(NotEmpty)

2. delete_directory(path, recursive=False)

@spec delete_directory(str, bool) -> Result[None, Error]

Deletes a directory at the specified path. If recursive is True, it will delete the directory and all its contents.

Returns Ok(None) if successful, or Err(reason) if an error occurs.

Note: For non-recursive deletion of an empty directory, this function behaves the same as delete_file(path).

Possible (but not limited to) errors:

Examples

# Delete an empty directory
result = delete_directory("empty_dir")
# Ok(None)
# Try to delete a non-empty directory
result = delete_directory("non_empty_dir")
# Err(NotEmpty)
# Delete a directory and its contents
result = delete_directory("non_empty_dir", recursive=True)
# Ok(None)
# Try to delete a file using delete_directory
result = delete_directory("file.txt")
# Err(NotADirectory)

Considerations

Test cases to implement

  1. Delete a regular file
  2. Attempt to delete a non-existent file
  3. Delete an empty directory
  4. Attempt to delete a non-empty directory
  5. Attempt to delete a file without proper permissions
  6. Delete a non-empty directory (recursive)
  7. Delete a read-only file
  8. Attempt to delete a file that is currently in use by another process
developedby commented 2 weeks ago

@kings177 I don't think this is a good interface.

I think a better interface would be one of these two:

Personally I'm favorable to the first one, but either would be fine.

The second one can still be implemented with only two functions and the recursive flag, choosing between recursive or not can be an additional layer in bend.

As always, names can still be bikeshed (remove vs remove_file, remove_dir vs rmdir, etc)

kings177 commented 2 weeks ago

those are some pretty good points, and i agree.

remove for removing non-directory files and empty directories and remove_all for removing any files recursively, including trees of directories.

i do prefer this over the one originally written in the issue. so changes to this would be:

  1. instead of delete_file(path) we would have remove(path)
  2. instead of delete_directory(path) we would have remove_all(path)