So I've encountered what appears to be a bug in the basic-cli
platform. I have an if block, in which I follow two nearly identical code paths depending on weather a file exists. I call Cmd.exec! "nano" ["filename.txt"]
, and then continue with my program when the editor exits.
This works fine, if I do not check for the file's existence ahead of time. However if I place the Cmd.exec
call inside an if block, I get a CmdError ExecutableFileBusy
error after the exec task completes.
Code is below (note that the bugged version is uncommented, however the commented out code works):
main =
isFile = Path.isFile (Path.fromStr "config.rvn")
|> Task.attempt! \res ->
when res is
Ok bool -> Task.ok bool
_ -> Task.ok Bool.false
if isFile then
Stdout.line! "config file found"
Cmd.exec! "nano" ["config.rvn"]
contents = File.readUtf8! "config.rvn"
Stdout.line! "file contents: $(contents)"
else
Stdout.line! "config file not found"
File.writeUtf8! "config.rvn" configTemplate
Cmd.exec! "nano" ["config.rvn"]
contents = File.readUtf8! "config.rvn"
Stdout.line! "file contents: $(contents)"
# main =
# File.writeUtf8! "config.rvn" configTemplate
# Cmd.exec! "nano" ["config.rvn"]
# contents = File.readUtf8! "config.rvn"
# Stdout.line! "file contents: $(contents)"
The bug happens for both basic-cli v0.10.0
and v0.11.0
.
I'm guessing Path.isFile isn't finished with the file handle before the Cmd.exec runs. What happens if you add a small sleep in there?
Good question... I'll check. I should also note that the following works:
main =
createFileIfNone!
File.writeUtf8! "config.rvn" configTemplate
Cmd.exec! "nano" ["config.rvn"]
contents = File.readUtf8! "config.rvn"
Stdout.line! "file contents: $(contents)"
createFileIfNone =
isFile = Path.isFile (Path.fromStr "config.rvn")
|> Task.attempt! \res ->
when res is
Ok bool -> Task.ok bool
_ -> Task.ok Bool.false
if isFile then
File.writeUtf8 "config.rvn" configTemplate
else
Task.ok {}
Here'd the specific implementation of that Path.isFile effect
I’m computer right now so can’t test sleep immediately, but I should also mention, even in the bugged code, File.write successfully creates the file, and nano is able to open the newly created file.
Interesting. Seems a bit strange. Maybe we could provide more context back in the error. Worth looking into as well. Or adding some dbg statements in the platform.
Ok, yes, adding a 1ms sleep does resolve the issue. Interesting, because I put the sleep immediately before Cmd.exec
, and after File.writeUtf8
.
So file.write does not conflict with the exec command, and regardless of how I write this code, nano always successfully opens the file:
However, if I call exec inside of the if block, after nano exits, I see that the roc program crashed. But no crash occurs if
Last updated: Jul 06 2025 at 12:14 UTC