/
arch_linux
/
rcm
Обзор
Документация
Войти
/
arch_linux
/
rcm
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/interactive.rs
293 строки
9 KB
БАЛИЦКИЙ АЛЕКСАНДР НИКОЛАЕВИЧ
upload files
26 ноя 2025, 10:22
26 ноя 2025, 10:22
35fe12c
Код
Авторство
О чём код?
use dialoguer::{theme::ColorfulTheme, Select, Input}; use std::env; use std::path::PathBuf; pub fn run_interactive_mode() { // Сначала выбираем/подтверждаем рабочую директорию if let Some(project_dir) = select_project_directory() { if let Err(e) = env::set_current_dir(&project_dir) { eprintln!("❌ Не удалось перейти в директорию: {}", e); return; } println!("📁 Рабочая директория: {}", project_dir.display()); } else { return; } loop { let choices = vec![ "📦 Команды сборки", "🔧 Управление зависимостями", "🧪 Тестирование", "📚 Документация", "🚀 Публикация", "⚙️ Инструменты", "📁 Сменить проект", "❌ Выход" ]; let selection = Select::with_theme(&ColorfulTheme::default()) .with_prompt("Cargo UI Manager - Выберите категорию") .items(&choices) .interact() .unwrap(); match selection { 0 => build_menu(), 1 => dependencies_menu(), 2 => testing_menu(), 3 => documentation_menu(), 4 => publish_menu(), 5 => tools_menu(), 6 => { if let Some(new_dir) = select_project_directory() { if let Err(e) = env::set_current_dir(&new_dir) { eprintln!("❌ Не удалось перейти в директорию: {}", e); } else { println!("📁 Новая рабочая директория: {}", new_dir.display()); } } }, 7 => { println!("👋 До свидания!"); break; }, _ => {} } } } fn select_project_directory() -> Option<PathBuf> { let current_dir = env::current_dir().ok()?; // Проверяем, есть ли Cargo.toml в текущей директории if current_dir.join("Cargo.toml").exists() { let use_current = dialoguer::Confirm::new() .with_prompt(format!( "Найден проект в {}. Использовать эту директорию?", current_dir.display() )) .default(true) .interact() .ok()?; if use_current { return Some(current_dir); } } // Запрашиваем путь к проекту let path: String = Input::new() .with_prompt("Введите путь к проекту (где находится Cargo.toml)") .default(current_dir.to_string_lossy().to_string()) .interact_text() .ok()?; let path = PathBuf::from(path); if path.join("Cargo.toml").exists() { Some(path) } else { eprintln!("❌ В указанной директории не найден Cargo.toml"); None } } fn build_menu() { let commands = vec![ "build - Сборка проекта", "build --release - Сборка в release режиме", "run - Запуск проекта", "check - Проверка кода", "clean - Очистка сборки", "← Назад" ]; let selection = Select::with_theme(&ColorfulTheme::default()) .with_prompt("Выберите команду сборки") .items(&commands) .interact() .unwrap(); match selection { 0 => execute_command("cargo build"), 1 => execute_command("cargo build --release"), 2 => execute_command("cargo run"), 3 => execute_command("cargo check"), 4 => execute_command("cargo clean"), _ => {} // Назад } } fn dependencies_menu() { let commands = vec![ "add - Добавить зависимость", "remove - Удалить зависимость", "update - Обновить зависимости", "tree - Показать дерево зависимостей", "← Назад" ]; let selection = Select::with_theme(&ColorfulTheme::default()) .with_prompt("Управление зависимостями") .items(&commands) .interact() .unwrap(); match selection { 0 => { // Явно указываем тип String для Input let crate_name: String = Input::new() .with_prompt("Введите имя крейта") .interact_text() .unwrap_or_default(); if !crate_name.is_empty() { execute_command(&format!("cargo add {}", crate_name)); } } 1 => { // Явно указываем тип String для Input let crate_name: String = Input::new() .with_prompt("Введите имя крейта для удаления") .interact_text() .unwrap_or_default(); if !crate_name.is_empty() { execute_command(&format!("cargo remove {}", crate_name)); } } 2 => execute_command("cargo update"), 3 => execute_command("cargo tree"), _ => {} // Назад } } fn testing_menu() { let commands = vec![ "test - Запуск тестов", "test --release - Тесты в release режиме", "bench - Запуск бенчмарков", "← Назад" ]; let selection = Select::with_theme(&ColorfulTheme::default()) .with_prompt("Тестирование") .items(&commands) .interact() .unwrap(); match selection { 0 => execute_command("cargo test"), 1 => execute_command("cargo test --release"), 2 => execute_command("cargo bench"), _ => {} // Назад } } fn documentation_menu() { let commands = vec![ "doc - Генерация документации", "doc --open - Документация в браузере", "← Назад" ]; let selection = Select::with_theme(&ColorfulTheme::default()) .with_prompt("Документация") .items(&commands) .interact() .unwrap(); match selection { 0 => execute_command("cargo doc"), 1 => execute_command("cargo doc --open"), _ => {} // Назад } } fn publish_menu() { let commands = vec![ "publish --dry-run - Тест публикации", "login - Авторизация", "package - Создание пакета", "← Назад" ]; let selection = Select::with_theme(&ColorfulTheme::default()) .with_prompt("Публикация") .items(&commands) .interact() .unwrap(); match selection { 0 => execute_command("cargo publish --dry-run"), 1 => execute_command("cargo login --help"), 2 => execute_command("cargo package"), _ => {} // Назад } } fn tools_menu() { let commands = vec![ "fmt - Форматирование кода", "clippy - Статический анализ", "audit - Проверка уязвимостей", "outdated - Устаревшие зависимости", "← Назад" ]; let selection = Select::with_theme(&ColorfulTheme::default()) .with_prompt("Инструменты") .items(&commands) .interact() .unwrap(); match selection { 0 => execute_command("cargo fmt"), 1 => execute_command("cargo clippy"), 2 => execute_command("cargo audit"), 3 => execute_command("cargo outdated"), _ => {} // Назад } } fn execute_command(cmd: &str) { println!("\n🚀 Выполняется: {}", cmd); // Используем прямой вызов cargo вместо sh для лучшей совместимости let args: Vec<&str> = cmd.split_whitespace().collect(); if args.is_empty() { eprintln!("❌ Пустая команда"); return; } let program = args[0]; let cargs = &args[1..]; let output = std::process::Command::new(program) .args(cargs) .output(); match output { Ok(output) => { if output.status.success() { println!("✅ Команда выполнена успешно"); if !output.stdout.is_empty() { println!("📋 Вывод:\n{}", String::from_utf8_lossy(&output.stdout)); } } else { println!("❌ Команда завершилась с ошибкой"); if !output.stderr.is_empty() { eprintln!("💥 Ошибка:\n{}", String::from_utf8_lossy(&output.stderr)); } } }, Err(e) => { eprintln!("❌ Ошибка выполнения команды: {}", e); } } // Пауза для просмотра результата println!("\n⏎ Нажмите Enter для продолжения..."); let mut input = String::new(); let _ = std::io::stdin().read_line(&mut input); }