Adjust program and args when running executables on Windows#13293
Adjust program and args when running executables on Windows#13293Alizter merged 1 commit intoocaml:mainfrom
Conversation
8bcdd4b to
5c9bf01
Compare
|
Could you add a test in This will run on macOS and Linux by default, and additionally on Windows which is what we want to fix. |
c0baf74 to
5f70449
Compare
8a74a42 to
1082424
Compare
40bc68c to
0179940
Compare
Leonidas-from-XIV
left a comment
There was a problem hiding this comment.
Code looks good to me, the implementation makes sense and the tests are fine.
Some minor concerns about wording but otherwise its good to go from my perspective. Thanks for the fix!
38294c9 to
4ad2830
Compare
Makes sense. I've now added a Hashtbl to keep track of the executable paths we discovered. Let me know if that's too simplistic and we should do better. |
|
I am not aware of the context, but this seems of limited usefulness to me: is there any reason to expect Windows builds to have executables such as |
|
Can we do the caching per executable with @nojb This is mostly about |
Thanks for the pointer. Of course, it would be better for users to call the shell explicitly: |
|
@nojb The decision to change the semantics of
This PR is intending to resolve the discussion by allowing the same behaviour (of running scripts) across platforms. This is not a simple change and will require careful consideration about whether or not we would like it and if it makes sense for dune as a whole. MotivationThe motivating use-case for this PR is that when we translate opam build instructions into dune actions and serialise them to a lock file, we cannot know if a given file is an executable or a script without running the action. This means that so far we have only translated such build instructions into This of course leads into trouble when running such actions on Windows since we can only execute executable files (with extension .exe). There are some edge-cases for handling batch and powershell scripts, but they are not relevant here. Ultimately, the analogy we draw in Dune between Windows'
See here for more details: https://www.in-ulm.de/~mascheck/various/shebang/ SolutionThe solution here is (or should be) to understand if a given file is an executable before running it on Windows. If it is, then proceed as usual with The main difficulty comes from the flexibility in the definition of a shebang. I am inclined to think that we should be more restrictive with the kinds of interpreters we allow, for example Prior "art"Other build systems have considered making analogous changes that may be worth reading:
Both cases had a different problem, required the analogous script detection as a possible fix but ultimately ended up with fixing the original problem a different way. That's maybe something we should consider doing here. AlternativesFor solving the issue with lock directories on Windows, we can consider introducing an alternative If an author has written: Is there really a good reason to fail this on Windows? |
| let adjust_prog_and_args ~metadata ~path ?dir prog args = | ||
| let { Process.loc; annots; _ } = metadata in | ||
| let prog_name = Path.basename prog in | ||
| let parse_win32_prog_and_args prog = |
There was a problem hiding this comment.
An alternative:
let parse_win32_prog_and_args prog =
match Io.file_line prog 1 with
| exception _ -> None, []
| line ->
match String.drop_prefix line ~prefix:"#!" with
| None -> None, []
| Some rest -> parse_shebang_line rest
The string.trim is stripping the trailing \r we get on Windows which is a bit confusing. Also unsure about the binary mode.
There was a problem hiding this comment.
Wouldn't Io.file_line prog 1 end up reading a lot of unnecessary data, especially from binary files when a newline character doesn't appear anywhere near the beginning of the file? My implementation tries to read only the first 2 characters before trying to process the first line.
Also, I don't understand what you mean by "stripping the trailing \r" being confusing.
There was a problem hiding this comment.
Io.file_line sets binary to false (so Windows line endings turn from \r\n to \n) and skips lines in a loop. It doesn't read the whole file, thus file_line prog 1 is basically just a single input_line on a non-binary file.
There was a problem hiding this comment.
I did look at the source of Io.file_line and I understand it that on a non-binary file it does read the first line correctly. But on a binary file, we could end-up reading too many chars, if the newline doesn't appear anywhere the beginning. But, I guess I don't need to worry about it since the DOS Stub ends with a newline, and this code only runs on Windows.
There was a problem hiding this comment.
How does opam do it? Perhaps we should just copy them.
There was a problem hiding this comment.
I wrote the initial version after looking at the opam workaround shared by David in #11174 (comment) . I guess, I should've explicitly mentioned that earlier. (I had context from #11174 which others looking at this PR may be missing!)
test/blackbox-tests/test-cases/pkg/build-with-executable-script-on-windows.t
Outdated
Show resolved
Hide resolved
Alizter
left a comment
There was a problem hiding this comment.
I'm happy with the state that this PR is in. If issues arise on Windows with typical build scripts we can of course always revisit this problem.
I have only a few user-facing concerns:
If we see an invalid shebang, what should a user do? We could probably give a little more information in the error message such as the location for the (build) expression and perhaps telling them to report it if they believe its a valid shebang etc.
80fc7a3 to
e22bc8a
Compare
I've added a user-facing message to this effect. Let me know if there's anything else I need to fix in this PR, before we are able to merge this. |
src/dune_rules/run_with_path.ml
Outdated
| | _ -> prog, args)) | ||
| in | ||
| match parse_win32_prog_and_args prog with | ||
| | exception Sys_error _ -> prog, args |
There was a problem hiding this comment.
What is throwing exceptions here?
There was a problem hiding this comment.
Stdune.Io.with_file_in would throw when prog doesn't exist.
There was a problem hiding this comment.
Ah, I see. Maybe worth defining with_file_in_opt that just wraps Stdune.Io.with_file_in to contain the exception?
There was a problem hiding this comment.
I'm happy to do that in a separate PR. I think it's better to keep this one focused on the Windows related change?
There was a problem hiding this comment.
This PR introduces the exceptions into this context (thrown by with_file_in but caught around parse_win32_prog_and_args), so it would make sense to keep the code exception-free from the start instead of merging it and then removing it later.
test/blackbox-tests/test-cases/pkg/build-with-executable-script-on-windows.t
Show resolved
Hide resolved
test/blackbox-tests/test-cases/pkg/build-with-executable-script-on-windows.t
Show resolved
Hide resolved
|
As we've discussed before. There were a few more changes I would like:
|
5bfb134 to
eb8fc1c
Compare
|
Thanks for listing out the changes!
I've added a test case for this and tweaked the code to handle this correctly.
I've added a test case for this, but couldn't find any issues. If you have an example handy, that would be helpful.
Yes, I've removed this. |
Windows doesn't support shebang lines and build rules generated from opam build instructions could have rules like `(build (run <executable-script>))`, which would fail to run on Windows. This commit adds support to parse shebang lines of such executable scripts on Windows and run them with an appropriate executable. Closes ocaml#11174 Signed-off-by: Puneeth Chaganti <punchagan@muse-amuse.in>
rgrinberg
left a comment
There was a problem hiding this comment.
LGTM.
I think it would be better to test this behavior on every OS by making it possible to enable it in a config. Few of us have access to Windows otherwise.
Windows doesn't support shebang lines and build rules generated from opam build instructions could have rules like
(build (run <executable-script>)), which would fail to run on Windows. This commit adds support to parse shebang lines of such executable scripts on Windows and run them with an appropriate executable.Closes #11174