Conversation
| } | ||
| ``` | ||
|
|
||
| The preceding example uses ``run(_:arguments:environment:workingDirectory:platformOptions:input:output:error:)-(_,_,_,_,_,Input,_,_)``: |
There was a problem hiding this comment.
I think this is supposed to end after error:)
There was a problem hiding this comment.
Nope, need the disambiguating extension on that one. The only one that doesn’t need it (or the run) is the one with body: closure
There was a problem hiding this comment.
I realize now this is DocC-specific markup, so it won't appear exactly like this once processed by DocC. Feel free to mark this as resolved.
|
Heads-up: #349 removes the deprecated |
| The function `run` returns only after the body returns and the process exits. | ||
| Because of that, the `execution` value, its streams, and the input writer are valid only inside the body. | ||
|
|
||
| ## Drain every stream, concurrently |
There was a problem hiding this comment.
Thank you!! This section is very useful. I was struggling to find the right place to emphasize the concurrency requirement.
|
thanks @broken-circle - no worries, it's already merged - so I'll rebase and I need to update based on it (and other's) changes anyway based on the feedback. Bits I missed when assembling ;-) |
… more common inputs and patterns
…esolving a lingering possessive use
…tail and clarity based on initial feedback
- Add `- Throws:` clauses to all six `run` overloads: they throw
`SubprocessError` on launch/limit failures (or rethrow the body
closure's error), and a non-zero exit is a normal result to inspect
via `terminationStatus`, not a thrown error.
- Fix imprecise "The subprocess throws an error…" comments on `.string`,
`.bytes`, `.data`, and `maxLineLength` to attribute the throw to
`run`/iteration and name `SubprocessError`.
- Correct the landing-page example: `standardOutput` is non-optional, so
it no longer prints `Optional(...)`.
invalidname
left a comment
There was a problem hiding this comment.
This looks really useful. I've left a few suggestions to consider.
|
|
||
| > Note: A non-zero exit never surfaces as a Swift error, and neither does output on standard error. | ||
| > To run a `catch` block when a command “fails,” check ``TerminationStatus/isSuccess`` yourself and throw from your own code. | ||
|
|
There was a problem hiding this comment.
This was a nice section that clears up some potential misunderstandings.
Co-authored-by: Chris Adamson <invalidname@gmail.com>
Co-authored-by: Chris Adamson <invalidname@gmail.com>
Co-authored-by: Chris Adamson <invalidname@gmail.com>
| } | ||
| ``` | ||
|
|
||
| The same structure can chain two subprocesses, sending the stream of output from one subprocess to the input of another. |
There was a problem hiding this comment.
I think creating the equivalent to a shell pipe is important enough that this should be its own section.
Possibly 'Chaining Subprocesses' or even 'Chaining Subprocesses To Pipe Commands' or 'Pipe Commands By Chaining Subprocesses'.
When I first scanned the article, I was hoping to find code on how to pipe using Subprocess and missed this section completely.
I also think using the term 'pipe' or 'piping' either in a heading title or body text would make this section easier to find in searches.
There was a problem hiding this comment.
I think this would be an excellent additional article to add, referenced from here. I don't think it's a great addition for this article though, since it's trying to be more introductory and common use case, and doing so would expand the scope and narrative of the this article, which is really meant to provide the basics and rules behind handling streaming. The piping and chaining concepts are something I'd describe as more advanced topics. Not invalid, just not something I want to try and cover in this article.
| ``FileDescriptorOutput/fileDescriptor(_:closeAfterSpawningProcess:)``, | ||
| which is efficient for large amounts of data. | ||
| When you use a file descriptor, the bytes never pass through your code. | ||
|
|
There was a problem hiding this comment.
Possibly add a code example showing writing the output of a command that generates a lot of text directly to a file via file descriptor?
There was a problem hiding this comment.
I wanted to keep this article focused on the basics and most common usage. I agree that an example showing how to use the file descriptors effectively - where they shine - would be a great add, but I don't want to expand the scope of this article to include that. I think that would be better as it's own, focused thing - I'm seeing that as "advanced use" of this library.
… in terminationStatus, per feedback
Co-authored-by: Chris Adamson <invalidname@gmail.com>
I wanted to wrap up the great conversations I saw during the development work for this library to provide some of the concrete "how to use it" advice touching on collecting result content, searching for executables vs. providing a path, and the just edging on the stream processing for results from a long running process - or even the input streaming.
I put together these two articles, pulling heavily in influence from the conversations in Swift Forums.
Please look over the example code blocks with a high degree of skepticism, and verify that I'm not suggesting poor code patterns or encouraging use in a way that would be harmful.