mirror of
https://github.com/alexpasmantier/television.git
synced 2025-07-29 06:11:37 +00:00
feat: add foundation for future external process features
This commit is contained in:
parent
fd6a4ef489
commit
c514494f6d
@ -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)]
|
||||
|
@ -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!(
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user