Getting started with prox

First add one of the prox interfaces as a dependency:

libraryDependencies += "io.github.vigoo" %% "prox-zstream" % "0.7.3"

and import the ZIO specific API from:

import io.github.vigoo.prox._
import io.github.vigoo.prox.zstream._

There is also an experimental version for ZIO 2, based on it’s snapshot releases:

libraryDependencies += "io.github.vigoo" %% "prox-zstream-2" % "0.7.3"

The code snippets in the documentation are based on the ZIO 1 version.

Defining a process to run

In prox a process to be executed is defined by a pure value which implements the Process[O, E] trait. The type parameters have the following meaning:

  • O is the type of the output value after the system process has finished running
  • E is the type of the error output value after the system process has finished running

To create a simple process to be executed use the Process constructor:

val proc1 = Process("ls", List("-hal"))
// proc1: Process.ProcessImpl = ProcessImpl(
//   command = "ls",
//   arguments = List("-hal"),
//   workingDirectory = None,
//   environmentVariables = Map(),
//   removedEnvironmentVariables = Set(),
//   outputRedirection = StdOut(),
//   runOutputStream = io.github.vigoo.prox.ProcessModule$Process$$$Lambda$10720/0x00000008026f7040@7e0a87d1,
//   errorRedirection = StdOut(),
//   runErrorStream = io.github.vigoo.prox.ProcessModule$Process$$$Lambda$10721/0x0000000802701040@7ae455b3,
//   inputRedirection = StdIn()
// )

or we can use the string interpolator:

val proc2 = proc"ls -hal"
// proc2: Process.ProcessImpl = ProcessImpl(
//   command = "ls",
//   arguments = List("-hal"),
//   workingDirectory = None,
//   environmentVariables = Map(),
//   removedEnvironmentVariables = Set(),
//   outputRedirection = StdOut(),
//   runOutputStream = io.github.vigoo.prox.ProcessModule$Process$$$Lambda$10720/0x00000008026f7040@553fef4a,
//   errorRedirection = StdOut(),
//   runErrorStream = io.github.vigoo.prox.ProcessModule$Process$$$Lambda$10721/0x0000000802701040@3db98ccc,
//   inputRedirection = StdIn()
// )

Then we can

still staying on purely specification level.

Running the process

Once we have our process specification ready, we can start the process with one of the IO functions on process.

But for this we first have to have a ProcessRunner implementation in scope. The default one is called JVMProcessRunner and it can be created in the following way:

implicit val runner: ProcessRunner[JVMProcessInfo] = new JVMProcessRunner 

Read the custom process runners page for an example of using a customized runner.

With the runner in place we can use several methods to start the process. The simplest one is called run and it blocks the active thread until the process finishes running:

proc1.run()
// res0: ProxIO[ProcessResult[Unit, Unit]] = OnSuccess(
//   trace = "io.github.vigoo.prox.ProxZStream.useResource(ProxZStream.scala:117)",
//   first = OnSuccess(
//     trace = "io.github.vigoo.prox.ProxZStream.useResource(ProxZStream.scala:117)",
//     first = Sync(
//       trace = "io.github.vigoo.prox.ProxZStream.useResource(ProxZStream.scala:117)",
//       eval = zio.Scope$ReleaseMap$$$Lambda$10957/0x000000080319fc40@1727b0a5
//     ),
//     successK = zio.ZIO$$Lambda$10959/0x000000080319e040@4fb6263f
//   ),
//   successK = zio.ZIO$ScopedPartiallyApplied$$$Lambda$10960/0x000000080319d040@6559d53c
// )

The result of this IO action is a ProcessResult[O, E], with the ability to observe the exit code and the redirected output and error values. In our first example both O and E were Unit because the default is to redirect output and error to the standard output and standard error streams.