Process Commands
Process commands allow you to easily wrap external CLI tools and forward all arguments to them. This is perfect for creating shortcuts, wrappers, or composite tools.
Basic Usage
Extend ProcessCommand and specify the executable path:
using Promty;
using Promty.Attributes;
[Description("git", "Execute git commands")]
public class GitCommand : ProcessCommand
{
protected override string ExecutablePath => "git";
}Usage:
dotnet run -- git status
dotnet run -- git commit -m "Initial commit"
dotnet run -- git push origin mainAll arguments after git are forwarded directly to the git executable.
Examples
Docker Wrapper
[Description("docker", "Execute docker commands")]
public class DockerCommand : ProcessCommand
{
protected override string ExecutablePath => "docker";
}Usage:
dotnet run -- docker ps
dotnet run -- docker build -t myapp .
dotnet run -- docker run -p 8080:80 myapp.NET CLI Wrapper
[Description("dotnet", "Execute dotnet CLI commands")]
public class DotNetCommand : ProcessCommand
{
protected override string ExecutablePath => "dotnet";
}Usage:
dotnet run -- dotnet build
dotnet run -- dotnet test
dotnet run -- dotnet packNPM Wrapper
[Description("npm", "Execute npm commands")]
public class NpmCommand : ProcessCommand
{
protected override string ExecutablePath => "npm";
}Usage:
dotnet run -- npm install
dotnet run -- npm run build
dotnet run -- npm testWith Full Paths
If the executable is not in the system PATH, specify the full path:
[Description("custom", "Execute custom tool")]
public class CustomCommand : ProcessCommand
{
protected override string ExecutablePath =>
"/usr/local/bin/custom-tool"; // Unix
// or
// @"C:\Tools\custom-tool.exe"; // Windows
}Cross-Platform Paths
For cross-platform support:
[Description("python", "Execute Python scripts")]
public class PythonCommand : ProcessCommand
{
protected override string ExecutablePath =>
Environment.OSVersion.Platform == PlatformID.Win32NT
? "python.exe"
: "python3";
}Use Cases
1. Create Shortcuts
Simplify complex commands:
[Description("build-all", "Build all projects")]
public class BuildAllCommand : ProcessCommand
{
protected override string ExecutablePath => "dotnet";
// Override to add default arguments
protected override string[] GetArguments(string[] args)
{
return new[] { "build", "-c", "Release" }
.Concat(args)
.ToArray();
}
}2. Wrap External Tools
Make external tools part of your CLI:
[Description("format", "Format code with Prettier")]
public class FormatCommand : ProcessCommand
{
protected override string ExecutablePath => "npx";
protected override string[] GetArguments(string[] args)
{
return new[] { "prettier", "--write", "." }
.Concat(args)
.ToArray();
}
}3. Create Composite Commands
Chain multiple operations:
[Description("deploy", "Build and deploy the application")]
public class DeployCommand : Command<DeployCommand.Args>
{
public class Args { }
public override async Task<int> ExecuteAsync(Args args)
{
// Build
Console.WriteLine("Building...");
var buildResult = await RunProcessAsync("dotnet", "build -c Release");
if (buildResult != 0) return buildResult;
// Test
Console.WriteLine("Testing...");
var testResult = await RunProcessAsync("dotnet", "test");
if (testResult != 0) return testResult;
// Deploy
Console.WriteLine("Deploying...");
var deployResult = await RunProcessAsync("./deploy.sh");
return deployResult;
}
private async Task<int> RunProcessAsync(string executable, string args = "")
{
var process = new System.Diagnostics.Process
{
StartInfo = new System.Diagnostics.ProcessStartInfo
{
FileName = executable,
Arguments = args,
UseShellExecute = false
}
};
process.Start();
await process.WaitForExitAsync();
return process.ExitCode;
}
}Exit Codes
Process commands automatically return the exit code from the external process:
0- Process succeeded- Non-zero - Process failed (specific meaning depends on the tool)
Standard Output/Error
By default, process commands:
- Forward stdout to your console
- Forward stderr to your console
- Wait for the process to complete
- Return the exit code
Advantages
✅ No Argument Parsing - All arguments forwarded as-is ✅ Simple Setup - Just specify the executable path ✅ Exit Code Propagation - Exit codes automatically forwarded ✅ Console Integration - Output appears directly in your console ✅ Quick Wrappers - Perfect for creating shortcuts and aliases
When to Use
Use Process Commands when:
- Wrapping existing CLI tools
- Creating shortcuts for complex commands
- Building composite workflows
- Forwarding all arguments to external tools
Use Standard Commands when:
- You need typed argument binding
- You want validation and help text
- Building custom business logic
- Processing arguments in code
