metrumresearchgroup / bbi

Next generation modeling platform
11 stars 2 forks source link

Windows fixes #296

Closed kyleam closed 1 year ago

kyleam commented 1 year ago

We're still working on getting a Windows machine with NONMEM installed, so both of these haven't been tested directly. However, I've did the following indirect tests on a Windows machine without NONMEM.

first issue

I confirmed that ./bbi.exe init --dir nm/foo writes out a "nonmem" section with an fake directory that looks like this:

$ find nm
nm
nm/foo
nm/foo/bar
nm/foo/bar/license
nm/foo/bar/license/nonmem.lic
nm/foo/bar/run
nm/foo/bar/run/nmfe99.bat
nm/foo/bar/source
nm/foo/bar/util
nm/foo/baz
nm/foo/baz/license
nm/foo/baz/license/nonmem.lic
nm/foo/baz/run
nm/foo/baz/run/nmfe32.bat
nm/foo/baz/run/nmfe33.bat
nm/foo/baz/source
nm/foo/baz/util

bbi.yaml excerpt:

nonmem:
  bar:
    executable: nmfe99.bat
    home: nm\foo\bar
  baz:
    executable: nmfe32.bat
    home: nm\foo\baz

second issue

Dummy go program:

package main

import (
    "fmt"
    "os"
    "os/exec"
)

func main() {
    bash, err := exec.LookPath("bash")
    if err != nil {
        panic(err)
    }
    fmt.Printf("bash is at %q\n", bash)

    // /usr/bin/bash is where Git for Windows' bash is on the Windows
    // machine.
    if err = os.WriteFile("1.sh", []byte("#!/usr/bin/bash\necho foo"), 0666); err != nil {
        panic(err)
    }

    c := exec.Command(bash, "1.sh")
    out, err := c.CombinedOutput()
    if err != nil {
        panic(err)
    }
    fmt.Printf("%s", out)
}

From Git Bash (what RStudio will use by default if available), all is good:

Administrator@EC2AMAZ-V9JAO7M MINGW64 ~/scratch
$ ./therealbbi.exe
bash is at "C:\\Program Files\\Git\\usr\\bin\\bash.exe"
foo

Administrator@EC2AMAZ-V9JAO7M MINGW64 ~/scratch
$ ./1.sh
foo

From Rtools bash, all is good:

Administrator@EC2AMAZ-V9JAO7M MSYS ~/scratch
$ ./therealbbi.exe
bash is at "C:\\rtools40\\usr\\bin\\bash.exe"
foo

Administrator@EC2AMAZ-V9JAO7M MSYS ~/scratch
$ ./1.sh
foo

From RStudio (with Rtools on path):

> Sys.getenv("PATH")
[1] "C:\\rtools40\\usr\\bin;C:\\Program Files\\R\\R-4.1.3\\bin\\x64;C:\\Windows\\system32;C:\\Windows;C:\\Windows\\System32\\Wbem;C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\;C:\\Windows\\System32\\OpenSSH\\;C:\\Program Files\\Amazon\\cfn-bootstrap\\;C:\\Program Files\\Git\\cmd;C:\\Program Files\\Amazon\\AWSCLIV2\\;C:\\Users\\Administrator\\AppData\\Local\\Microsoft\\WindowsApps;"

> processx::run("therealbbi")
$status
[1] 0

$stdout
[1] "bash is at \"C:\\\\rtools40\\\\usr\\\\bin\\\\bash.exe\"\nfoo\n"

$stderr
[1] ""

$timeout
[1] FALSE

> processx::run("1.sh")
Error in `process_initialize(self, private, command, args, stdin, stdout, ...`:
! Native call to `processx_exec` failed
Caused by error in `chain_call(c_processx_exec, command, c(command, args), pty, pty_options, ...`:
! create process '1.sh' (system error 193, %1 is not a valid Win32 application.
) @win/processx.c:1040 (processx_exec)
Type .Last.error to see the more details.

The first process run is supposed to mimic the how bbr would call bbi, and (with this series) bbi would then call bash x.sh. So, all good.

When Git for Windows bin is on path instead, the same processx call looks good:

> Sys.getenv("PATH")
[1] "C:\\Program Files\\Git\\bin;C:\\Program Files\\R\\R-4.1.3\\bin\\x64;C:\\Windows\\system32;C:\\Windows;C:\\Windows\\System32\\Wbem;C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\;C:\\Windows\\System32\\OpenSSH\\;C:\\Program Files\\Amazon\\cfn-bootstrap\\;C:\\Program Files\\Git\\cmd;C:\\Program Files\\Amazon\\AWSCLIV2\\;C:\\Users\\Administrator\\AppData\\Local\\Microsoft\\WindowsApps;"

> processx::run("therealbbi")
$status
[1] 0

$stdout
[1] "bash is at \"C:\\\\Program Files\\\\Git\\\\bin\\\\bash.exe\"\nfoo\n"

$stderr
[1] ""

$timeout
[1] FALSE

> processx::run("1.sh")
Error in `process_initialize(self, private, command, args, stdin, stdout, ...`:
! Native call to `processx_exec` failed
Caused by error in `chain_call(c_processx_exec, command, c(command, args), pty, pty_options, ...`:
! create process '1.sh' (system error 193, %1 is not a valid Win32 application.
) @win/processx.c:1040 (processx_exec)
Type .Last.error to see the more details.

And, if I have neither Rtools or Git for Windows on path, things fail as expected:

> processx::run("therealbbi.exe")
Error in `processx::run("therealbbi.exe")`:
! System command 'therealbbi.exe' failed
---
Exit status: 2
Stderr:
panic: exec: "bash": executable file not found in %PATH%

goroutine 1 [running]:
main.main()
    /Users/KyleM/scratch/go-scratchpad/therealbbi.go:12 +0x1bd
---
Type .Last.error to see the more details.
> processx::run("1.sh")
Error in `process_initialize(self, private, command, args, stdin, stdout, ...`:
! Native call to `processx_exec` failed
Caused by error in `chain_call(c_processx_exec, command, c(command, args), pty, pty_options, ...`:
! create process '1.sh' (system error 193, %1 is not a valid Win32 application.
) @win/processx.c:1040 (processx_exec)
Type .Last.error to see the more details.
> Sys.getenv("PATH")
[1] "C:\\Program Files\\R\\R-4.1.3\\bin\\x64;C:\\Windows\\system32;C:\\Windows;C:\\Windows\\System32\\Wbem;C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\;C:\\Windows\\System32\\OpenSSH\\;C:\\Program Files\\Amazon\\cfn-bootstrap\\;C:\\Program Files\\Git\\cmd;C:\\Program Files\\Amazon\\AWSCLIV2\\;C:\\Users\\Administrator\\AppData\\Local\\Microsoft\\WindowsApps;"