Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test, tweak and document std/misc/process #1022

Merged
merged 1 commit into from
Oct 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 50 additions & 4 deletions doc/reference/std/misc/process.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@
## run-process
``` scheme
(run-process cmd
[coprocess: read-all-as-string]
[coprocess: ...]
[check-status: #t]
[environment: #f]
[directory: #f]
[stdin-redirection: #t]
[stdout-redirection: #t]
[stderr-redirection: #f]
[pseudo-terminal: #f]
[show-console: #f]) -> any | error
[show-console: ...]) -> any | error

cmd := list of strings, [path . arguments]
coprocess := procedure interacting with process
Expand All @@ -38,7 +38,8 @@ The following keyword settings are available:
- *coprocess*: A procedure that specifies how to interact with the process,
which it receives as an argument, and what should be returned from
`run-process`. Defaults to reading the whole output as a string via
`std/misc/ports#read-all-as-string`.
`std/misc/ports#read-all-as-string` if either `stdout-redirection` or
`stderr-redirection` is true, otherwise to `void`.
- *check-status*: Declares how to handle the exit status of the process upon
termination. If a procedure is provided, then it will be called with the
process' exit status and a list of process creation arguments. If
Expand Down Expand Up @@ -75,7 +76,7 @@ The following keyword settings are available:
behave differently when they are used interactively, for example shells.
- *show-console*: Applies to *Microsoft Windows*. It controls whether the
process’ console window will be hidden or visible. The default value of this
setting is `#f` (i.e. hide the console window).
setting is true if any of the port redirection option is false.

More information can be found in section `17.7.2 Process devices` of the Gambit
manual.
Expand Down Expand Up @@ -133,3 +134,48 @@ adding: file2.txt (stored 0%)
adding: file3.txt (stored 0%)
```
:::

## invoke
``` scheme
(invoke program args
[stdout-redirection: #f]
[stderr-redirection: #f]
[stdin-redirection: #f]
[coprocess: ...]
[check-status: #t]
[environment: #f]
[directory: #f]
[show-console: ...]
```

Invoke a `program` with arguments `args`, in a way very similar to `run-process` above,
except that the program is specified separately from the arguments,
and the defaults for standard port redirections are different.

::: tip Examples:
``` scheme
> (invoke "date" ["--utc"] stdout-redirection: #t coprocess: read-line)
```
:::

## filter-process
``` scheme
(filter-with-process command writer reader
[directory: #f]
[environment: #f])
```

Invoke a Unix `command` to filter some data, wherein
the `writer` procedure takes an output port as argument and writes pre-filtered data to the port,
the `command` then filters the data, reading it from its standard input,
processing it and writing the filtered result to its standard output,
and the `reader` procedure takes an input port as argument and reads the filtered data from it.
The optional keyword arguments `directory:` and `environment:` are passed to `run-process`.

::: tip Examples:
``` scheme
> (check (filter-with-process ["sh" "-c" "echo BEGIN ; cat ; echo END"]
(lambda (proc) (display "ab\ncd\nef\n" proc))
read-all-as-lines)
("BEGIN" "ab" "cd" "ef" "END")
```
2 changes: 1 addition & 1 deletion src/std/misc/ports-test.ss
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
(export ports-test)
(export #t)

(import
:std/error
Expand Down
62 changes: 62 additions & 0 deletions src/std/misc/process-test.ss
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
(export process-test)

(import
:gerbil/gambit
:std/error
:std/format
:std/misc/ports
:std/misc/process
:std/os/temporaries
:std/source
:std/sugar
:std/test
"./ports-test.ss")

(def process-test
(test-suite "test :std/misc/process"
(test-case "run-process, run-process/batch, invoke"
(def dir (this-source-directory))
(def (rp/i c . a) (apply invoke (car c) (cdr c) a))
(defrule (checks/redir-coproc run ...)
(begin
(begin
(check (run ["echo" "ok" "1"]
stdin-redirection: #f stdout-redirection: #t stderr-redirection: #t)
=> "ok 1\n")
(check (run ["echo" "ok" "1"]
stdin-redirection: #t stdout-redirection: #t stderr-redirection: #t)
=> "ok 1\n")
(check (run ["sh" "-c" "echo foo bar; echo baz >&2"]
stdout-redirection: #t stderr-redirection: #f)
=> "foo bar\n")
(check (run ["sh" "-c" "echo foo bar; echo baz >&2"]
stdout-redirection: #t stderr-redirection: #t)
=> "foo bar\nbaz\n")
(check (run ["sh" "-c" "echo foo >&2 ; echo bar; echo baz >&2"]
coprocess: read-all-as-lines
stdout-redirection: #t stderr-redirection: #t)
=> ["foo" "bar" "baz"])
(check (run ["sh" "-c" "exit 0"]
coprocess: process-status) => 0)
(check (run ["sh" "-c" "exit 42"]
coprocess: process-status
check-status: true) => (* 42 256))
(check (run ["true"] coprocess: process-status) => 0)
(check (run ["false"] coprocess: process-status check-status: true) => 256)
(check (run ["sh" "-c" "cat < ports-test.data ; echo bar baz >&2 ; exit 42"]
stdout-redirection: #t stderr-redirection: #f
directory: dir
check-status: (lambda (s _) (= s (* 42 256))))
=> test-data))...))
(checks/redir-coproc run-process rp/i)
(defrule (checks/pass-fail run ...)
(begin
(begin
(check (begin (run ["true"]) 69) => 69)
(check-exception (run ["sh" "-c" "exit 42"]) process-error?)
(check-exception (run ["false"]) process-error?))...))
(checks/pass-fail run-process run-process/batch rp/i))
(test-case "filter-with-process"
(check (filter-with-process ["sh" "-c" "echo BEGIN ; cat ; echo END"]
(lambda (proc) (display "ab\ncd\nef\n" proc))
read-all-as-lines) => ["BEGIN" "ab" "cd" "ef" "END"]))))
23 changes: 16 additions & 7 deletions src/std/misc/process.ss
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,16 @@
;; That is also coherent with the above pseudo-terminal: default to #f, BTW.
(def (run-process
command
coprocess: (coprocess read-all-as-string)
check-status: (check-status #t)
environment: (environment #f)
directory: (directory #f)
stdin-redirection: (stdin-redirection #t)
stdout-redirection: (stdout-redirection #t)
stderr-redirection: (stderr-redirection #f)
coprocess: (coprocess (if (or stdout-redirection stderr-redirection) read-all-as-string void))
check-status: (check-status #t)
environment: (environment #f)
directory: (directory #f)
pseudo-terminal: (pseudo-terminal #f)
show-console: (show-console #f)) ;; NB: default differs from Gambit. See above.
;; NB: defaults for show-console differ from Gambit. See above.
show-console: (show-console #f))
(let* ((settings
[path: (car command)
arguments: (cdr command)
Expand Down Expand Up @@ -94,7 +95,7 @@
stdout-redirection: (stdout-r #f)
stderr-redirection: (stderr-r #f)
stdin-redirection: (stdin-r #f)
coprocess: (coprocess (if stdout-r read-all-as-string void))
coprocess: (coprocess (if (or stdout-r stderr-r) read-all-as-string void))
check-status: (check-status #t)
environment: (environment #f)
directory: (directory #f)
Expand All @@ -103,6 +104,7 @@
stdout-redirection: stdout-r
stderr-redirection: stderr-r
stdin-redirection: stdin-r
coprocess: coprocess
check-status: check-status
environment: environment
directory: directory
Expand All @@ -111,9 +113,16 @@
;; write data into a filter process and read some data back.
;; process-options as per open-process, except you should only use
;; path: arguments: directory: environment:
(def (filter-with-process command writer reader)
(def (filter-with-process command writer reader
directory: (directory #f)
environment: (environment #f))
(run-process
command
stdin-redirection: #t
stdout-redirection: #t
stderr-redirection: #f
directory: directory
environment: environment
coprocess:
(lambda (process)
(spawn/name
Expand Down
Loading