feat: add foundation for future external process features

This commit is contained in:
lalvarezt 2025-07-28 00:52:23 +02:00
parent fd6a4ef489
commit c514494f6d
3 changed files with 86 additions and 13 deletions

View File

@ -159,12 +159,42 @@ impl CommandSpec {
}
}
/// Execution mode for external actions
#[derive(Debug, Clone, Default, serde::Deserialize, serde::Serialize, PartialEq)]
#[serde(rename_all = "lowercase")]
pub enum ExecutionMode {
/// Fork the command as a child process (current behavior, tv stays open)
#[default]
Fork,
/// Replace the current process with the command (tv exits, command takes over)
Become,
}
/// Output handling mode for external actions
#[derive(Debug, Clone, Default, serde::Deserialize, serde::Serialize, PartialEq)]
#[serde(rename_all = "lowercase")]
pub enum OutputMode {
/// Inherit stdin/stdout/stderr (current behavior)
#[default]
Inherit,
/// Capture output for processing
Capture,
/// Discard output silently
Discard,
}
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize, PartialEq)]
pub struct ActionSpec {
#[serde(default)]
pub description: Option<String>,
#[serde(flatten)]
pub command: CommandSpec,
/// How to execute the command (fork vs become)
#[serde(default)]
pub become: bool,
/// How to handle command output
#[serde(default)]
pub output_mode: OutputMode,
}
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]

View File

@ -21,7 +21,7 @@ use television::{
gh::update_local_channels,
television::Mode,
utils::clipboard::CLIPBOARD,
utils::command::shell_command,
utils::command::{execute_action, shell_command},
utils::{
shell::{
Shell, completion_script, render_autocomplete_script_template,
@ -123,18 +123,8 @@ async fn main() -> Result<()> {
debug!("External command: {}", formatted_command);
// Execute the command with inherited stdio
let mut child = shell_command(
&formatted_command,
action_spec.command.interactive,
&action_spec.command.env,
)
.stdin(Stdio::inherit())
.stdout(Stdio::inherit())
.stderr(Stdio::inherit())
.spawn()?;
let status = child.wait()?;
// Execute the command using the new action execution abstraction
let status = execute_action(&action_spec, &formatted_command)?;
if !status.success() {
eprintln!(

View File

@ -4,6 +4,7 @@ use std::{collections::HashMap, process::Command};
use tracing::warn;
use super::shell::Shell;
use crate::channels::prototypes::{ActionSpec, OutputMode};
pub fn shell_command<S>(
command: &str,
@ -32,3 +33,55 @@ pub fn shell_command<S>(
cmd.envs(envs).arg(command);
cmd
}
/// Execute an external action with the appropriate execution mode and output handling
///
/// Currently implements the existing behavior but designed to be extended with:
/// - `become` flag for execve behavior
/// - `output_mode` for different output handling modes
pub fn execute_action(
action_spec: &ActionSpec,
formatted_command: &str,
) -> std::io::Result<std::process::ExitStatus> {
// For now, preserve existing behavior regardless of the new flags
// In the future, this will branch based on action_spec.become and action_spec.output_mode
let mut cmd = shell_command(
formatted_command,
action_spec.command.interactive,
&action_spec.command.env,
);
// Configure stdio based on output mode (future extension point)
match action_spec.output_mode {
OutputMode::Inherit => {
cmd.stdin(std::process::Stdio::inherit())
.stdout(std::process::Stdio::inherit())
.stderr(std::process::Stdio::inherit());
}
OutputMode::Capture => {
// Future: capture output for processing
cmd.stdin(std::process::Stdio::inherit())
.stdout(std::process::Stdio::inherit())
.stderr(std::process::Stdio::inherit());
}
OutputMode::Discard => {
// Future: discard output silently
cmd.stdin(std::process::Stdio::inherit())
.stdout(std::process::Stdio::inherit())
.stderr(std::process::Stdio::inherit());
}
}
// Execute based on become flag (future extension point)
if action_spec.become {
// Future: use execve to replace current process
// For now, use normal execution
let mut child = cmd.spawn()?;
child.wait()
} else {
// Normal fork execution (current behavior)
let mut child = cmd.spawn()?;
child.wait()
}
}