Conversation
a71da34 to
9908d2c
Compare
bin/main.ml
Outdated
| let target_file = Path.project target_file in | ||
| let flags = [ Open_wronly; Open_creat; Open_trunc; Open_binary ] in | ||
| Out_channel.(with_open_gen flags 0o600 target_file (fun oc -> output_string oc contents)) | ||
| Util.save_as ~path:target_file ~mode:0o600 (fun oc -> output_string oc contents) |
There was a problem hiding this comment.
Restored the original usage of Devkit.Files.save_as here. But the question remains as to whether all other writes of passage should be made atomic in the same manner (they weren't before I removed devkit).
There was a problem hiding this comment.
IIUC, this is what Storage.Secrets.encrypt_using_tmpfile is doing, so we're good there.
There are two cases of writing recipients to disk in commands.ml where we are using Out_channel.with_open_text.
I would say that we could use the same function everywhere, even if only for a matter of consistency. AFAIU, there are no downsides to having atomic writes here, right?
| Fun.protect ~finally:(fun () -> try Sys.remove tmpfile with _ -> ()) (fun () -> f (tmpfile, tmpfile_oc)) | ||
| Fun.protect | ||
| ~finally:(fun () -> | ||
| Stdlib.close_out_noerr tmpfile_oc; |
There was a problem hiding this comment.
IIUC, this should ensure that this function will not leak file descriptors in case f fails.
There was a problem hiding this comment.
lgtmttbomk
(looks good to me, to the best of my knowledge)
acf204c to
84ce2f1
Compare
84ce2f1 to
7994a7d
Compare
thatportugueseguy
left a comment
There was a problem hiding this comment.
lgtm, we could probably have the atomic writes everywhere for consistency
bin/main.ml
Outdated
| let target_file = Path.project target_file in | ||
| let flags = [ Open_wronly; Open_creat; Open_trunc; Open_binary ] in | ||
| Out_channel.(with_open_gen flags 0o600 target_file (fun oc -> output_string oc contents)) | ||
| Util.save_as ~path:target_file ~mode:0o600 (fun oc -> output_string oc contents) |
There was a problem hiding this comment.
IIUC, this is what Storage.Secrets.encrypt_using_tmpfile is doing, so we're good there.
There are two cases of writing recipients to disk in commands.ml where we are using Out_channel.with_open_text.
I would say that we could use the same function everywhere, even if only for a matter of consistency. AFAIU, there are no downsides to having atomic writes here, right?
| Fun.protect ~finally:(fun () -> try Sys.remove tmpfile with _ -> ()) (fun () -> f (tmpfile, tmpfile_oc)) | ||
| Fun.protect | ||
| ~finally:(fun () -> | ||
| Stdlib.close_out_noerr tmpfile_oc; |
There was a problem hiding this comment.
lgtmttbomk
(looks good to me, to the best of my knowledge)
There was a problem hiding this comment.
i don't like the module name, but i don't have a better one.
There was a problem hiding this comment.
we could have just type.ml if you prefer? it's modelled on Devkit.Prelude.Fresh, where you'd have Fresh (String), now you have Abstract_type.Make (String). I don't think Fresh is particularly clear, but if you know you know. We could have a name that is reminiscent to Fresh, might make it more clear?
There was a problem hiding this comment.
now you have Abstract_type.Make (String)
Actually you have Abstract_type.Fresh (String), that's why it probably makes me a bit icky. Also i feel like Abstract_type should be under some Utils module, or maybe under a Types one?
What do you feel about Types.Fresh (String)? I know that the Fresh is unclear at first, but after you have a name for the thing, can you use another one? 😅 In any case, this still doesn't make me happy, but i guess it's that old thing about naming in programming..
There was a problem hiding this comment.
Types.Fresh is OK for me, renamed in latest version.
There was a problem hiding this comment.
I would say that we could use the same function everywhere, even if only for a matter of consistency. AFAIU, there are no downsides to having atomic writes here, right?
Latest version I use save_as for the other case of writing recipient files. Except for that, couldn't find any file writes in the project.
There was a problem hiding this comment.
Btw, we also have encrypt_using_tmpfile. It seems like it could be use Util.save_as.
There was a problem hiding this comment.
In the latest version I use save_as in encrypt_using_tmpfile.
I also move Util.save_as to Storage.save_as. I do this so that I can use it in Storage.Secrets.encrypt_using_tmpfile, and since Util depends on Storage this would induce a dependency cycle. I think I would've preferred to keep it in some separate module though, with some base functionality. Util is kind of that, but not really since it depends on Storage.
lib/util.mli
Outdated
| will be renamed to [path] after [f] has succesfully terminated. Therefore this guarantee that either [filename] will | ||
| not be modified or will contain whatever [f] was writing to it as a side-effect. |
There was a problem hiding this comment.
| will be renamed to [path] after [f] has succesfully terminated. Therefore this guarantee that either [filename] will | |
| not be modified or will contain whatever [f] was writing to it as a side-effect. | |
| will be renamed to [path] after [f] has successfully terminated. Therefore, this guarantees that either [filename] will | |
| not be modified or will contain whatever [f] was writing to it as a side-effect. |
is it a side-effect? It's the intended result
There was a problem hiding this comment.
see latest version. I think the original authors meant side-effect as in, "this function is not pure, it has a side-effect". but I think that is redundant, and confusing as you point out, so I removed it.
What
Respond to @rr0gi's remarks on #11