SavaDev.Lab.Processes 0.1.0

dotnet add package SavaDev.Lab.Processes --version 0.1.0
                    
NuGet\Install-Package SavaDev.Lab.Processes -Version 0.1.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="SavaDev.Lab.Processes" Version="0.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="SavaDev.Lab.Processes" Version="0.1.0" />
                    
Directory.Packages.props
<PackageReference Include="SavaDev.Lab.Processes" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add SavaDev.Lab.Processes --version 0.1.0
                    
#r "nuget: SavaDev.Lab.Processes, 0.1.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package SavaDev.Lab.Processes@0.1.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=SavaDev.Lab.Processes&version=0.1.0
                    
Install as a Cake Addin
#tool nuget:?package=SavaDev.Lab.Processes&version=0.1.0
                    
Install as a Cake Tool

SavaDev.Lab.Processes

SavaDev.Lab.Processes is a small, focused .NET library for launching external processes in a structured, observable, and cancellation-aware way for infrastructure and tooling scenarios.

The library provides a clean abstraction over System.Diagnostics.Process while keeping execution semantics explicit and transparent. It is designed for tooling, infrastructure code, CLI utilities, and scenarios where process execution is part of a larger workflow.


โœจ Key features

  • Asynchronous process execution
  • Cooperative cancellation support
  • Line-by-line streaming of standard output and standard error
  • Pluggable output observers (logging, buffering, metrics, etc.)
  • Clear separation between execution logic and output handling
  • Test-friendly design with deterministic behavior
  • No hidden magic, no global state, no static hooks

๐ŸŽฏ Design goals

This library intentionally focuses on execution mechanics, not orchestration or business logic.

What it does:

  • Starts processes
  • Observes output
  • Handles cancellation
  • Returns execution results

What it does not do:

  • Parse or interpret output
  • Retry, schedule, or orchestrate processes
  • Apply domain-specific semantics
  • Hide execution details behind heuristics

The goal is to provide a solid, predictable foundation that higher-level tooling can safely build upon.


๐Ÿงฉ Core concepts

ProcessRequest

Describes what to run:

  • executable name
  • arguments
  • working directory
  • environment variables
  • unique request identifier

IProcessLauncher

Defines how a process is executed.

The default implementation:

  • redirects standard output and error
  • streams output line-by-line
  • supports cancellation via CancellationToken
  • returns a ProcessResult after completion

ProcessOutputHandling

Defines how output is handled:

  • whether output is captured in memory
  • which observers receive output events

ProcessResult

Represents the execution outcome:

  • exit code
  • captured standard output and error (if enabled)

Success evaluation is provided via the ProcessResultExtensions.IsSuccess() extension method in the SavaDev.Lab.Processes.Extensions namespace and follows the ExitCode == 0 convention.

Output observers

Observers receive output in real time and can:

  • write to console
  • buffer output
  • implement custom side effects

Observers are resolved via an explicit resolver, allowing:

  • mixed observer types
  • contextual (request-aware) observers
  • deterministic invocation order

๐Ÿ”ง Specialized launchers

In addition to the generic process launcher, the library provides convenience launchers for common execution scenarios. These launchers do not introduce new execution semantics โ€” they simply fix certain parameters and delegate all work to the underlying IProcessLauncher.


IDotNetProcessLauncher

IDotNetProcessLauncher is a thin wrapper around the generic process launcher, specialized for executing the dotnet CLI.

It fixes the executable name to dotnet and exposes a simplified API focused on passing command-line arguments.

Typical use cases include:

  • dotnet build
  • dotnet test
  • dotnet publish
  • dotnet --info

The launcher:

  • does not interpret command output or exit codes
  • does not apply any domain-specific semantics
  • delegates all execution, output handling, and cancellation logic to the underlying process launcher

This makes it suitable for tooling, build automation, and infrastructure code where invoking the dotnet CLI is a frequent operation.


IShellProcessLauncher

IShellProcessLauncher provides a simple abstraction for executing commands via the default operating system shell.

Instead of specifying an executable and arguments separately, the shell launcher accepts a single shell command string and runs it using:

  • cmd on Windows
  • /bin/sh on Unix-like systems

Typical use cases include:

  • quick glue commands
  • simple scripts
  • environment inspection
  • demo and diagnostic scenarios

Like the dotnet launcher, the shell launcher:

  • delegates execution to the generic process launcher
  • supports output observers and cancellation
  • does not parse or interpret command output

The shell launcher is intended for simple and explicit scenarios and does not attempt to validate or normalize shell-specific syntax. The shell launcher does not attempt to escape, sanitize, or validate commands and should be used with care.


Design note

Both IDotNetProcessLauncher and IShellProcessLauncher are intentionally minimal.

They exist to:

  • reduce boilerplate
  • improve readability
  • make common execution scenarios explicit

They are not meant to replace the generic IProcessLauncher, but to complement it where a fixed executable or execution style is appropriate.

๐Ÿงช Tests

The test suite covers:

  • successful execution
  • cancellation behavior
  • output capturing and streaming
  • observer invocation order
  • thread-safety and concurrency scenarios
  • resolver behavior with mixed observer sets

Special attention is paid to:

  • concurrency correctness
  • absence of race conditions
  • predictable observer semantics

โ–ถ๏ธ Demo projects

SavaDev.Lab.Processes.Demo

An interactive console demo showcasing:

  • basic process execution
  • cancellation
  • streaming-only output
  • shared observers
  • contextual observers
  • error handling

The demos are intentionally verbose and explicit to serve as live documentation.

SavaDev.Lab.Processes.Demo.LongProcess

A small standalone executable that:

  • runs indefinitely
  • periodically produces output
  • responds to cancellation

It is used by demo scenarios to illustrate cancellation and streaming behavior.


๐Ÿšง Scope and stability

This library is intentionally small and opinionated, focusing on low-level process execution, output handling, and cancellation semantics.

The current releases use a 0.x versioning scheme, which means the API should be considered evolving. Breaking changes may occur as the design is refined based on real-world usage and feedback.

The library is designed to be extensible rather than monolithic. New behavior is expected to be added primarily through:

  • custom process observers
  • dependency injection and pluggable resolvers
  • integrations with logging, metrics, and monitoring systems
  • additional launcher implementations built on top of the core abstractions

Once the core abstractions stabilize, the API will move toward a stable 1.0 release with stronger compatibility guarantees.


๐Ÿค– Development approach

The development of this library is AI-assisted.

AI tools are used as collaborative instruments during design, implementation, testing, documentation, and refactoring. All architectural decisions, API boundaries, and final code choices remain intentional and human-reviewed.

In addition, parts of this codebase are cat-assisted.

Occasional contributions include:

  • unsolicited keyboard input
  • spontaneous design reviews
  • presence during long refactoring sessions
  • morale support and quality assurance through observation

These contributions are provided by Marta the cat and are non-deterministic by nature, but historically beneficial.

No cats were harmed during the development of this library.

๐Ÿ“„ License

This project is licensed under the Business Source License (BSL).

The source code is publicly available, but usage is subject to the terms and limitations defined by the BSL. In particular, certain forms of production or commercial use may be restricted until the license changes.

At a predefined change date, the license will automatically transition to the MIT License, after which the software will become fully open source under the MIT terms.

The exact licensing conditions, including the change date and permitted use, are specified in the LICENSE file included in this repository.


๐Ÿง  Philosophy

Prefer explicit behavior over clever abstractions. Prefer composition over hidden policies. Prefer observability over post-mortem debugging.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net8.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.1.0 201 2/10/2026