msys2 / setup-msys2

GitHub Action to setup MSYS2
https://github.com/marketplace/actions/setup-msys2
MIT License
285 stars 38 forks source link

msys2 command line argument syntax #271

Closed oscarbenjamin closed 1 year ago

oscarbenjamin commented 1 year ago

I've been using msys2 to build Python wheels in python-flint and it works excellently so many thanks!

I did have one issue though that was awkward (at the time) to diagnose and fix and i wonder if there is a better way to solve this in general. The problem is that I wanted to call msys2 and ask it to run a shell script with command line arguments that are Windows paths e.g. like:

> msys2 -c bin/myscript.sh C:\Path\To\File

The msys2 command expects a single command line argument though so it needed to be more like:

> msys2 -c "bin/myscript.sh C:\Path\To\File"

Now the problem is (I think) that msys2 parses this as bash syntax so my script ends up being called like:

$ bin/myscript.sh C:PathToFile

I could work around this with an extra batch file that turns the arguments into environment variables: https://github.com/fredrik-johansson/python-flint/blob/e08d3dfc236f6b38fcc11bcde5c621993761a806/bin/cibw_repair_wheel_command_windows.bat#L2-L5

Could there be a way to invoke the msys2 command and have it just take separate string arguments and treat them faithfully as the strings that they are? Perhaps something like:

> msys2 -cc bin/myscript.sh C:\Path\To\File

Note that I can't just escape the slashes etc because the paths are generated indirectly: https://github.com/fredrik-johansson/python-flint/blob/e08d3dfc236f6b38fcc11bcde5c621993761a806/.github/workflows/buildwheel.yml#L52-L53

lazka commented 1 year ago

You can quote the string:

$ bash -cx "echo 'C:\Path\To\File'"
+ echo 'C:\Path\To\File'
C:\Path\To\File

or you can also convert it to a cygwin path so that unix tools understand it:

$ bash -cx 'echo `cygpath "C:\Path\To\File"`'
++ cygpath 'C:\Path\To\File'
+ echo /c/Path/To/File
/c/Path/To/File

or if you want to pass it as an argument:

$ bash -cx 'echo `cygpath "$0"`' 'C:\Path\To\File'
++ cygpath 'C:\Path\To\File'
+ echo /c/Path/To/File
/c/Path/To/File
oscarbenjamin commented 1 year ago

You can quote the string:

I'm pretty sure I tried that but I'll try again. Part of the problem I think is that I'm writing the command line as a template string that gets preprocessed by cibuildwheel which "helpfully" translates unixy syntax into Windowsy syntax.

oscarbenjamin commented 1 year ago

Is there a way to install the msys2 command that is used in the action locally?

lazka commented 1 year ago

It should be equivalent to https://gist.github.com/lazka/6d89a3cd85b0a64112f18c4cb7ef5f91

oscarbenjamin commented 1 year ago

Thanks. I can see where that's generated in the code now and that's a lot easier now that I can test this locally. It should be possible to pass quotes if I can get cibuildwheel not to mess them up but that's not an issue for this action so I'll close this.

I'll test this once I've figured out my other problem which is how to get the msys2 command to add the ucrt paths for gcc etc...

lazka commented 1 year ago

If you just use it in a separate step and make msys2 the shell there you'd lose one level of escaping:

  - shell: msys2 {0}
    run: |
      ls
      echo "Hello"

It's basically like writing it to a file and running that instead of passing the code via the CLI. Not sure if that helps in your case though.

oscarbenjamin commented 1 year ago

The problem is that I'm passing command lines into another tool: https://github.com/fredrik-johansson/python-flint/blob/e08d3dfc236f6b38fcc11bcde5c621993761a806/.github/workflows/buildwheel.yml#L52-L53 I don't think that setting the shell for GA to msys will change the way that cibuildwheel runs the commands.