I wanted to use Roc to make a script to automate a series of find and replaces in a file. I wrote a simple script using cli-platform which I think should work, however it crashes. Is there something obvious I am missing? Issue #4607
oh, just that file error handling isn't actually implemented yet :sweat_smile:
if you're interested in wiring that up, I can talk you through how to do it!
Ahk, I should be able to fix that. I'll let you know if I get stuck.
sounds great! :100:
Making slow progress here. The rust<->roc glue was easy to write, but I'm at a bit of a loss the best way to test the functionality properly.
I wrote the helper below which seems to work well, but how would you recommend we test it? I've been wrestling with a few different compiler errors trying to write a test program, and then I tried a writeErrToStr : WriteErr -> Str
helper in examples/cli/cli-platform/File.roc
which is really slowing me down.
fn toRocWriteError(err : std::io::Error) -> RocResult<(), WriteErr> {
match err.kind(){
std::io::ErrorKind::NotFound => RocResult::err(file_glue::WriteErr::NotFound),
std::io::ErrorKind::AlreadyExists => RocResult::err(file_glue::WriteErr::AlreadyExists),
std::io::ErrorKind::Interrupted => RocResult::err(file_glue::WriteErr::Interrupted),
std::io::ErrorKind::OutOfMemory => RocResult::err(file_glue::WriteErr::OutOfMemory),
std::io::ErrorKind::PermissionDenied => RocResult::err(file_glue::WriteErr::PermissionDenied),
std::io::ErrorKind::TimedOut => RocResult::err(file_glue::WriteErr::TimedOut),
// TODO TooManySymlinks not used here, do we need to change Roc platform API??
std::io::ErrorKind::WriteZero => RocResult::err(file_glue::WriteErr::WriteZero),
_ => RocResult::err(file_glue::WriteErr::Unsupported),
// TODO investigate support the following IO errors which are nightly-only experimental API
// std::io::ErrorKind::FileTooLarge <- unstable language feature
// std::io::ErrorKind::ExecutableFileBusy <- unstable language feature
// std::io::ErrorKind::FilesystemQuotaExceeded <- unstable language feature
// std::io::ErrorKind::InvalidFilename <- unstable language feature
// std::io::ErrorKind::ResourceBusy <- unstable language feature
// std::io::ErrorKind::ReadOnlyFilesystem <- unstable language feature
// std::io::ErrorKind::TooManyLinks <- unstable language feature
// std::io::ErrorKind::StaleNetworkFileHandle <- unstable language feature
// std::io::ErrorKind::StorageFull <- unstable language feature
}
}
I would honestly just try testing it with two of the errors - e.g. NotFound and PermissionDenied
those are pretty easy to reproduce, I'd assume - for NotFound just try to read a file that's not there, and for PermissionDenied, you can probably try something like writing to /
and the test can just be a Roc app which tries to do those things, and then prints "It worked!" if it gets the expected errors - and then a Rust test can launch the Roc app and verify that its stdout is "It worked!"
I think as long as you have 2 different errors covered, that's enough for the test
at that point we know that:
so from there, further tests would essentially be confirming that we've correctly translated the Rust ErrorKind
into the Roc glue type, which doesn't seem so error-prone that tests for every single one of them is essential
I think we should instead assume that Rust has correctly implemented ErrorKind
, and that glue is translating the names properly, and therefore all we really need to do is to visually check that the names line up as expected
tests of everything would be ideal, but I don't think they'd be worth the amount of time it would take to recreate all those different types of errors :sweat_smile:
Cool, I've managed to do that here is the test app. It works as you suggested, which is pretty neat.
Should I leave it in the cli-platform folder for now?
192-168-1-108:cli luke$ roc run file-test.roc
🔨 Rebuilding platform...
Pass: expected NotFound
Pass: expected PermissionDenied
Tests complete
oh let's put it in https://github.com/roc-lang/basic-cli - I already have a WIP PR to move everything into there! :big_smile:
we don't have CI set up there yet though
but all in good time!
First PR :tada: #4
very nice! Now we "just" need to get some automation around releases :laughing:
because currently making the URL requires going around and building binaries by hand on 4 different operating systems
(that can be automated via GitHub Actions, but hasn't been yet)
FYSA I went and updated all my AoC 2021 and the project Euler code for the new API and to use the "release" URL for cli-platform.
It was a really pleasant experience! :heart_eyes: Everything just worked, and it was super easy to work with the Tasks. I don't know if it is because I have grokked Tasks as an API now, but the simple apps feel much easier to write and understand.
awesome, glad to hear it! :smiley:
Last updated: Jul 05 2025 at 12:14 UTC