Add first draft of new osproc.readLines (#15429)

* Add first draft of new osproc.readLines

* Add test for new osproc.readLines

* Rename test to start w/t to run; Also add newline to output

* Suppress hint messages.

* Output should match this time.

* Shoulda picked a program with simpler syntax than ..lol

* Address https://github.com/nim-lang/Nim/pull/15429#issuecomment-701890898
and https://github.com/nim-lang/Nim/pull/15429#issuecomment-701985976 by
factoring `readLines` into `iterator lines` and a wrapper `proc`.

* Address https://github.com/nim-lang/Nim/pull/15429#issuecomment-702127289
and also add a `ReadIOEffect` tag to the iterator (called by the wrapper..
so it should need no separate tag, if I understand correctly).
This commit is contained in:
c-blake 2020-10-01 12:06:38 -04:00 • committed by GitHub
commit 26d656e73e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 73 additions and 0 deletions

View file

@ -444,6 +444,57 @@ proc execProcesses*(cmds: openArray[string],
if afterRunEvent != nil: afterRunEvent(i, p)
close(p)
iterator lines*(p: Process): string {.since: (1, 3), tags: [ReadIOEffect].} =
## Convenience iterator for working with `startProcess` to read data from a
## background process.
##
## See also:
## * `readLines proc <#readLines,Process>`_
##
## Example:
##
## .. code-block:: Nim
## const opts = {poUsePath, poDaemon, poStdErrToStdOut}
## var ps: seq[Process]
## for prog in ["a", "b"]: # run 2 progs in parallel
## ps.add startProcess("nim", "", ["r", prog], nil, opts)
## for p in ps:
## var i = 0
## for line in p.lines:
## echo line
## i.inc
## if i > 100: break
## p.close
var outp = p.outputStream
var line = newStringOfCap(120)
while true:
if outp.readLine(line):
yield line
else:
if p.peekExitCode != -1: break
proc readLines*(p: Process): (seq[string], int) {.since: (1, 3).} =
## Convenience function for working with `startProcess` to read data from a
## background process.
##
## See also:
## * `lines iterator <#lines.i,Process>`_
##
## Example:
##
## .. code-block:: Nim
## const opts = {poUsePath, poDaemon, poStdErrToStdOut}
## var ps: seq[Process]
## for prog in ["a", "b"]: # run 2 progs in parallel
## ps.add startProcess("nim", "", ["r", prog], nil, opts)
## for p in ps:
## let (lines, exCode) = p.readLines
## if exCode != 0:
## for line in lines: echo line
## p.close
for line in p.lines: result[0].add(line)
result[1] = p.peekExitCode
when not defined(useNimRtl):
proc execProcess(command: string, workingDir: string = "",
args: openArray[string] = [], env: StringTableRef = nil,