Skip to main content

dejavu/exec/
mod.rs

1//! Execution core: shim generation, PATH handling, anti-recursion real-binary
2//! resolution, process spawning, and classification/passthrough policy.
3
4pub mod classify;
5pub mod command_key;
6pub mod interactive;
7pub mod path;
8pub mod resolve;
9pub mod shim;
10pub mod spawn;
11
12use std::time::Duration;
13
14/// Command families that Dejavu can optimize (spec §10.1).
15#[derive(Debug, Clone, Copy, PartialEq, Eq)]
16pub enum Family {
17    Validation,
18    Search,
19    Tree,
20    GitReadonly,
21    Logs,
22}
23
24impl Family {
25    pub fn as_str(&self) -> &'static str {
26        match self {
27            Family::Validation => "validation",
28            Family::Search => "search",
29            Family::Tree => "tree",
30            Family::GitReadonly => "git_readonly",
31            Family::Logs => "logs",
32        }
33    }
34}
35
36/// The decision the classifier hands to the runtime.
37#[derive(Debug, Clone)]
38pub enum ExecMode {
39    /// Capture output for reduction.
40    Optimize { family: Family, command_key: String },
41    /// Run with inherited stdio; no capture, no reduction.
42    Passthrough(PassthroughReason),
43}
44
45#[derive(Debug, Clone, Copy, PartialEq, Eq)]
46pub enum PassthroughReason {
47    Disabled,
48    RepoDisabled,
49    ConfigExcluded,
50    UnknownShim,
51    UnsupportedSubcommand,
52    ArgsNotWhitelisted,
53    Interactive,
54    MutatingGit,
55    DangerousDocker,
56    SideEffecting,
57    /// A machine-readable git form (`--porcelain`, `-z`, `@{upstream}`, …) that a
58    /// program parses — reducing it would corrupt shell prompts / IDE SCM.
59    MachineReadable,
60}
61
62impl PassthroughReason {
63    pub fn as_str(&self) -> &'static str {
64        match self {
65            PassthroughReason::Disabled => "disabled",
66            PassthroughReason::RepoDisabled => "repo_disabled",
67            PassthroughReason::ConfigExcluded => "config_excluded",
68            PassthroughReason::UnknownShim => "unknown_shim",
69            PassthroughReason::UnsupportedSubcommand => "unsupported_subcommand",
70            PassthroughReason::ArgsNotWhitelisted => "args_not_whitelisted",
71            PassthroughReason::Interactive => "interactive",
72            PassthroughReason::MutatingGit => "mutating_git",
73            PassthroughReason::DangerousDocker => "dangerous_docker",
74            PassthroughReason::SideEffecting => "side_effecting",
75            PassthroughReason::MachineReadable => "machine_readable",
76        }
77    }
78}
79
80/// The result of running the real command.
81#[derive(Debug, Clone)]
82pub struct ExecOutcome {
83    pub stdout: Vec<u8>,
84    pub stderr: Vec<u8>,
85    /// Already normalized: `code()` if exited, else `128 + signal`.
86    pub exit_code: i32,
87    pub duration: Duration,
88    /// Whether we captured (Optimize) or passed stdio through (Passthrough).
89    pub captured: bool,
90    /// Whether the raw output was truncated to the storage cap (spec §21.4).
91    pub truncated_raw: bool,
92}