pacsea/install/scan/
spawn.rs

1/*!
2What: Scan spawn launcher
3
4Input:
5- Package name and scan configuration flags
6
7Output:
8- Uses integrated process for scans (excluding aur-sleuth)
9- Spawns terminal for aur-sleuth if enabled
10
11Details:
12- Configures environment variables and launches scans via executor
13- aur-sleuth runs in separate terminal simultaneously
14*/
15
16/// What: Build aur-sleuth command for terminal execution.
17///
18/// Input:
19/// - `pkg`: AUR package identifier to analyse.
20///
21/// Output:
22/// - Command string for terminal execution.
23///
24/// Details:
25/// - Sets up working directory, finds aur-sleuth binary, loads proxy settings, and runs aur-sleuth.
26#[cfg(not(target_os = "windows"))]
27#[must_use]
28pub fn build_sleuth_command_for_terminal(pkg: &str) -> String {
29    // This command will be run in a separate terminal
30    // It sets up the working directory, finds aur-sleuth, loads config, and runs the scan
31    format!(
32        r#"pkg='{pkg}'; work=$(mktemp -d -t pacsea_scan_XXXXXXXX); cd "$work" && \
33(if command -v paru >/dev/null 2>&1; then paru -G "$pkg"; elif command -v yay >/dev/null 2>&1; then yay -G "$pkg"; else git clone --depth 1 "https://aur.archlinux.org/${{pkg}}.git" || exit 1; fi) && \
34if [ -f "$pkg/PKGBUILD" ]; then cd "$pkg"; else f=$(find "$pkg" -maxdepth 3 -type f -name PKGBUILD 2>/dev/null | head -n1); if [ -n "$f" ]; then cd "$(dirname "$f")"; elif [ -d "$pkg" ]; then cd "$pkg"; fi; fi && \
35A_SLEUTH="$(command -v aur-sleuth 2>/dev/null || true)"; \
36if [ -z "$A_SLEUTH" ] && [ -x "$HOME/.local/bin/aur-sleuth" ]; then A_SLEUTH="$HOME/.local/bin/aur-sleuth"; fi; \
37if [ -z "$A_SLEUTH" ] && [ -x "/usr/local/bin/aur-sleuth" ]; then A_SLEUTH="/usr/local/bin/aur-sleuth"; fi; \
38if [ -z "$A_SLEUTH" ] && [ -x "/usr/bin/aur-sleuth" ]; then A_SLEUTH="/usr/bin/aur-sleuth"; fi; \
39if [ -n "$A_SLEUTH" ]; then \
40  cfg="${{XDG_CONFIG_HOME:-$HOME/.config}}/pacsea/settings.conf"; \
41  if [ -f "$cfg" ]; then \
42    get_key() {{ awk -F= -v k="$1" 'tolower($0) ~ "^[[:space:]]*"k"[[:space:]]*=" {{ sub(/#.*/,"",$2); gsub(/^[[:space:]]+|[[:space:]]+$/,"",$2); print $2; exit }}' "$cfg"; }}; \
43    HP=$(get_key http_proxy); [ -n "$HP" ] && export http_proxy="$HP"; \
44    XP=$(get_key https_proxy); [ -n "$XP" ] && export https_proxy="$XP"; \
45    AP=$(get_key all_proxy); [ -n "$AP" ] && export ALL_PROXY="$AP"; \
46    NP=$(get_key no_proxy); [ -n "$NP" ] && export NO_PROXY="$NP"; \
47    CAB=$(get_key requests_ca_bundle); [ -n "$CAB" ] && export REQUESTS_CA_BUNDLE="$CAB"; \
48    SCF=$(get_key ssl_cert_file); [ -n "$SCF" ] && export SSL_CERT_FILE="$SCF"; \
49    CCB=$(get_key curl_ca_bundle); [ -n "$CCB" ] && export CURL_CA_BUNDLE="$CCB"; \
50    PIPIDX=$(get_key pip_index_url); [ -n "$PIPIDX" ] && export PIP_INDEX_URL="$PIPIDX"; \
51    PIPEX=$(get_key pip_extra_index_url); [ -n "$PIPEX" ] && export PIP_EXTRA_INDEX_URL="$PIPEX"; \
52    PIPTH=$(get_key pip_trusted_host); [ -n "$PIPTH" ] && export PIP_TRUSTED_HOST="$PIPTH"; \
53    UVCA=$(get_key uv_http_ca_certs); [ -n "$UVCA" ] && export UV_HTTP_CA_CERTS="$UVCA"; \
54  fi; \
55  WORK_DIR=$(pwd); \
56  SLEUTH_OUTPUT_FILE="./.pacsea_sleuth.txt"; \
57  if command -v script >/dev/null 2>&1; then \
58    SLEUTH_CMD="cd $(printf '%q' "$WORK_DIR") && script -f -q $(printf '%q' "$SLEUTH_OUTPUT_FILE") -c \"$(printf '%q' "$A_SLEUTH") --pkgdir .\"; echo ''; echo 'Press Enter to close this window...'; read -r _;"; \
59  else \
60    SLEUTH_CMD="cd $(printf '%q' "$WORK_DIR") && $(printf '%q' "$A_SLEUTH") --pkgdir .; echo ''; echo 'Press Enter to close this window...'; read -r _;"; \
61  fi; \
62  TERM_FOUND=false; \
63  if command -v gnome-terminal >/dev/null 2>&1; then \
64    gnome-terminal -- bash -lc "$SLEUTH_CMD" 2>&1 && TERM_FOUND=true; \
65  elif command -v alacritty >/dev/null 2>&1; then \
66    alacritty -e bash -lc "$SLEUTH_CMD" 2>&1 && TERM_FOUND=true; \
67  elif command -v kitty >/dev/null 2>&1; then \
68    kitty bash -lc "$SLEUTH_CMD" 2>&1 && TERM_FOUND=true; \
69  elif command -v xterm >/dev/null 2>&1; then \
70    xterm -hold -e bash -lc "$SLEUTH_CMD" 2>&1 && TERM_FOUND=true; \
71  elif command -v konsole >/dev/null 2>&1; then \
72    konsole -e bash -lc "$SLEUTH_CMD" 2>&1 && TERM_FOUND=true; \
73  elif command -v tilix >/dev/null 2>&1; then \
74    tilix -e bash -lc "$SLEUTH_CMD" 2>&1 && TERM_FOUND=true; \
75  elif command -v mate-terminal >/dev/null 2>&1; then \
76    mate-terminal -- bash -lc "$SLEUTH_CMD" 2>&1 && TERM_FOUND=true; \
77  elif command -v xfce4-terminal >/dev/null 2>&1; then \
78    SLEUTH_CMD_QUOTED=$(printf '%q' "$SLEUTH_CMD"); \
79    xfce4-terminal --command "bash -lc $SLEUTH_CMD_QUOTED" 2>&1 && TERM_FOUND=true; \
80  fi; \
81  if [ "$TERM_FOUND" = "true" ]; then \
82    echo "aur-sleuth launched in separate terminal window."; \
83    echo "The scan will continue in the background. You can close the terminal when done."; \
84  else \
85    echo "No suitable terminal found. Running aur-sleuth in current terminal..."; \
86    ("$A_SLEUTH" --pkgdir . 2>&1 | tee ./.pacsea_sleuth.txt) || echo 'aur-sleuth failed; see output above'; \
87  fi; \
88else \
89  echo 'aur-sleuth not found (checked PATH, ~/.local/bin, /usr/local/bin, /usr/bin)'; \
90fi"#
91    )
92}
93
94/// What: Launch integrated scan process for AUR package (excluding aur-sleuth).
95///
96/// Input:
97/// - `pkg`: AUR package identifier to analyse.
98/// - `_do_clamav`/`_do_trivy`/`_do_semgrep`/`_do_shellcheck`/`_do_virustotal`/`_do_custom`/`do_sleuth`: Toggles enabling optional scan stages.
99///
100/// Output:
101/// - Uses integrated process for scans (excluding aur-sleuth).
102/// - Spawns terminal for aur-sleuth if enabled (runs simultaneously).
103///
104/// Details:
105/// - Clones `https://aur.archlinux.org/<pkg>.git` and runs `makepkg -o` (download sources only).
106/// - Optionally runs `ClamAV`, `Trivy` filesystem, and `Semgrep` scans via integrated process.
107/// - Performs `VirusTotal` hash lookups for `PKGBUILD`/`src` files when `VT_API_KEY` is provided.
108/// - aur-sleuth runs in separate terminal simultaneously if enabled.
109/// - Note: This function is kept for backward compatibility; actual execution should use `ExecutorRequest::Scan`.
110/// - `_do_clamav`, `_do_trivy`, `_do_semgrep`, `_do_shellcheck`, `_do_virustotal`, and `_do_custom` parameters are kept for API consistency but unused in this function.
111/// - The actual scan configuration is handled via `ExecutorRequest::Scan` which reads from the application state.
112/// - The underscore prefix suppresses Rust/clippy warnings for intentionally unused parameters.
113#[cfg(not(target_os = "windows"))]
114#[allow(
115    clippy::too_many_arguments,
116    clippy::fn_params_excessive_bools,
117    clippy::must_use_candidate
118)]
119pub fn spawn_aur_scan_for_with_config(
120    pkg: &str,
121    _do_clamav: bool,
122    _do_trivy: bool,
123    _do_semgrep: bool,
124    _do_shellcheck: bool,
125    _do_virustotal: bool,
126    _do_custom: bool,
127    do_sleuth: bool,
128) {
129    // Note: _do_clamav, _do_trivy, _do_semgrep, _do_shellcheck, _do_virustotal, and _do_custom
130    // are unused in this function. They are kept for API consistency, but the actual scan
131    // configuration is handled via ExecutorRequest::Scan which reads from application state.
132    // The underscore prefix suppresses Rust/clippy warnings for intentionally unused parameters.
133    // If sleuth is enabled, spawn it in a separate terminal
134    if do_sleuth {
135        let sleuth_cmd = build_sleuth_command_for_terminal(pkg);
136        super::super::shell::spawn_shell_commands_in_terminal(&[sleuth_cmd]);
137    }
138
139    // Note: The integrated scan process is triggered via ExecutorRequest::Scan
140    // This function is kept for backward compatibility but the actual execution
141    // should be done through the executor pattern (see events/modals/scan.rs)
142}