ocamldep: add -strict (error if input doesnt exist)#11593
ocamldep: add -strict (error if input doesnt exist)#11593emillon wants to merge 1 commit intoocaml:trunkfrom
Conversation
|
(as for the PR itself, I tried to add some tests to cover this but let me know if there's a better way to do this or if this should be expanded to cover more cases - in our use case, |
|
cc @snowleopard |
nojb
left a comment
There was a problem hiding this comment.
LGTM generally; the manual needs to be updated though.
|
@nojb thanks. I amended |
|
Grmbl, it seems my comment didn't make it to the PR.
Etienne Millon (2022/10/03 06:20 -0700):
@nojb thanks. I amended `ocamldep.1` and `ocamldep.etex` (and also
reworded to "exit with nonzero ~exit~ code")
How about "fail"?
|
|
I was also suggesting in the lost comment to keep the options in
almost-alphabetic order and to define `-strict` just after `-sort`
|
|
Finally, regarding the testsuite: how about gathering all the tests in
one file? It seems to me it would make the tests easier to follow with
an overall picture of what is being tested and ther coudl be some
factorization.
|
| @@ -0,0 +1,8 @@ | |||
| (* TEST | |||
| modules = "dep.ml a.ml" | |||
There was a problem hiding this comment.
I think it is not necessary to test both with, and without -modules, since the behaviour being changed is orthogonal to this flag. I would leave only the one without -modules and remove the one with -modules.
There was a problem hiding this comment.
I removed the ones with -modules. I'd like to implement @shindere 's suggestion to group things in a single test, but I'm not sure to do it. This is my first time with ocamltest. How can I specify that the same test should be run with different options and different expected outcomes?
| * setup-ocamlc.byte-build-env | ||
| ** ocamlc.byte | ||
| commandline = "-depend a.ml doesnotexist.ml" | ||
| *** check-ocamlc.byte-output |
There was a problem hiding this comment.
I'm not sure we want to test the output of ocamldep in this test; the feature being added seems unrelated. Perhaps let's simplify the patch by removing this test step and the "reference" file?
There was a problem hiding this comment.
I agree. There's one gotcha in the current implementation though: if we pass as input A B and C, and B does not exist, the output will still contain dependency information for A and C (but with a nonzero exit code). That test kind of characterizes that behaviour so that's why I included it. But yes it can be argued that the output of a failing command is not to be relied upon, so I'm fine with removing the check on the output.
|
I fully agree with @nojb's comments
Nicolás Ojeda Bär (2022/10/03 08:21 -0700):
```suggestion
" If an input file does not exist, exit with a nonzero code"
```
I tried to suggest " Fail ff an input file does not exist".
To me, it feels that in the context of a Unix program, "fail" should be
clear enough to mean return non-zero...
|
cf185c2 to
a0b1c62
Compare
|
Etienne Millon (2022/10/07 02:24 -0700):
@emillon commented on this pull request.
> @@ -0,0 +1,7 @@
+(* TEST
+modules = "dep.ml a.ml"
+* setup-ocamlc.byte-build-env
+** ocamlc.byte
+commandline = "-depend a.ml doesnotexist.ml"
+*** check-ocamlc.byte-output
I agree. There's one gotcha in the current implementation though: if
we pass as input A B and C, and B does not exist, the output will
still contain dependency information for A and C (but with a nonzero
exit code). That test kind of characterizes that behaviour so that's
why I included it. But yes it can be argued that the output of a
failing command is not to be relied upon, so I'm fine with removing
the check on the output.
Do you think it would be a lot of work to test for all the file's
existence before even starting to output the dependencies?
That way you could guarantee that nothing is printed if in strict mode
and at least one file does not exist. You could even print the list of
non-existent files on stderr in that case, if you like the idea.
|
|
Etienne Millon (2022/10/07 02:18 -0700):
@emillon commented on this pull request.
> @@ -0,0 +1,8 @@
+(* TEST
+modules = "dep.ml a.ml"
I removed the ones with -modules. I'd like to implement @shindere 's
suggestion to group things in a single test, but I'm not sure to do
it. This is my first time with ocamltest. How can I specify that the
same test should be run with different options and different expected
outcomes?
See e.g. `testsuite/tests/asmcomp/func_sections.ml` for an example.
If you implement the other suggestion you could add meaningful tests
even in the case where `-strict` is specified and one or more files are
missing.
|
|
Nicolás Ojeda Bär (2022/10/03 05:11 -0700):
Is it a good idea to specify the exact exit code? As far as I can see, `we exit with 2 whenever *any* error occurs, so it may be better to use a more general wording:
```suggestion
" if an input file does not exist, exit with a nonzero exit code"
```
How about
```
" fail if an input file does not exist"
```
?
Also, nitpick but, the options are roughly sorted in alphabetical order,
so how about moving the definition of `-strict` just under the one of
`-sort`?
Regarding the testsuite: wouldn't it make things more readable to gather
the tests in the same file? I think they all share the same root test
and the same definition of the `modules` variable, so it feels to me it
would make it easier to get an overall view of what is being tested.
What do you think?
|
|
@emillon I wonder if you might consider a slightly different fix, as per this PR: oxcaml/oxcaml#892 This removes the file-exists test entirely in strict mode, relying on the existing exception handler around the "open" call (which might be in a ppx subprocess). This should avoid a race where the file is deleted between the file-exists test and the open. |
|
Friendly ping. @mshinwell made a suggestion about a different implementation which sounds slightly superior (as it avoids a race condition). @emillon: do you think you could give it a shot? |
|
Friendly ping. @emillon: are you still interested in working on this issue? |
|
I'd like to add that at Jane Street we've been happily using @mshinwell's patch in our build system for a while. |
|
Sorry for the long silence. I wasn't sure what was the situation at JS. I'll update this with @mshinwell's patch. |
Thanks! |
|
Friendly ping. Any news? |
a0b1c62 to
e5e3709
Compare
|
I updated the PR and the test suite output. Let me know what you think. Sorry for leaving that aside. |
Closes ocaml#8625 See oxcaml/oxcaml#892 When a nonexistent input file is passed to ocamldep, it is ignored and the error is not reported. This PR adds a `-strict` flag that prevents this behavior. Consider the following situation: - on one side, ocamldep is being invoked as `ocamldep -modules a.ml` - on the other side, `a.ml` is unlinked and created again. (this corresponds to what happens when `dune` is running and `hg` or `git` is updating its tree in the meantime - updates are not always atomic if hardlinks are involved for example) We want to make sure that when ocamldep exits with 0, its output corresponds to either the old or the new version of the file. This is enabled by `-strict`.
e5e3709 to
05c0e0d
Compare
nojb
left a comment
There was a problem hiding this comment.
Looks generally good. I'm only wondering about the exact semantics of the new flag. Given the placement of the test in a try catch clause, it looks like "strict" mode will apply to any error during the processing of the file (eg syntax error), not just in case the file does not exist.
This seems fine to me; but if that's the case, I would like the documentation appearing in the help text of the tool and the manual/man page to be adapted accordingly.
| with x -> begin | ||
| print_exception x; | ||
| if not !allow_approximation then begin | ||
| if !strict || not !allow_approximation then begin |
There was a problem hiding this comment.
Do I understand correctly that in -strict mode the tool will exit with a non-zero code also if the file contains a syntax error or some other is raised when processing it (not just if the file does not exist)? If yes, the documentation should be adapted accordingly.
|
PR open for two years without any activity. As assignee, I am moving to close it; to be reopened as needed. |
Closes #8625
See oxcaml/oxcaml#892
When a nonexistent input file is passed to ocamldep, it is ignored and the error is not reported. This PR adds a
-strictflag that prevents this behavior.Consider the following situation:
ocamldep -modules a.mla.mlis unlinked and created again.(this corresponds to what happens when
duneis running andhgorgitis updating its tree in the meantime - updates are not always atomic if hardlinks are involved for example)We want to make sure that when ocamldep exits with 0, its output corresponds to either the old or the new version of the file. This is enabled by
-strict.