2
0
Эх сурвалжийг харах

refactor: 移除交互式命令行 (#61)

LoGin 5 сар өмнө
parent
commit
70352fd6b1

+ 1 - 1
Cargo.toml

@@ -1,7 +1,7 @@
 [workspace]
 resolver = "2"
 members = [
-    "crates/test_base", "dadk", "dadk-user",
+    "crates/test_base", "dadk", "dadk-config", "dadk-user",
 ]
 
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

+ 11 - 0
dadk-config/Cargo.toml

@@ -0,0 +1,11 @@
+[package]
+name = "dadk-config"
+version = "0.1.0"
+edition = "2021"
+authors = [
+    "longjin <longjin@DragonOS.org>",
+    "chikejian <chikejian@DragonOS.org>",
+    "xuzihao <xuzihao@DragonOS.org>"
+]
+
+[dependencies]

+ 1 - 0
dadk-config/src/lib.rs

@@ -0,0 +1 @@
+pub mod user;

+ 1 - 0
dadk-config/src/user/mod.rs

@@ -0,0 +1 @@
+

+ 0 - 11
dadk-user/src/console/README.md

@@ -1,11 +0,0 @@
-# 命令行交互模块
-
-## 介绍
-
-命令行交互模块,使得用户能交互式的进行以下操作:
-
-- 创建dadk task配置文件
-- 查看当前所有的task配置文件
-- 删除task配置文件
-- 查询dadk更新
-

+ 0 - 401
dadk-user/src/console/elements.rs

@@ -1,401 +0,0 @@
-use std::{
-    cell::RefCell,
-    fmt::Debug,
-    io::{self, Write},
-    rc::Rc,
-};
-
-use log::error;
-
-use super::{interactive::InputFunc, ConsoleError};
-
-#[derive(Debug, Clone)]
-pub struct Input {
-    /// 在输入箭头前面的提示 (e.g. "Please input your name: >> ")
-    pre_tips: Option<String>,
-    /// 在输入箭头后面的提示 (e.g. ">> (y/n)")
-    post_tips: Option<String>,
-}
-
-impl Input {
-    pub fn new(pre_tips: Option<String>, post_tips: Option<String>) -> Self {
-        Self {
-            pre_tips,
-            post_tips,
-        }
-    }
-
-    /// # 输出提示语,并从标准输入读取一行
-    pub fn input(&self) -> Result<String, ConsoleError> {
-        let mut input = String::new();
-
-        if let Some(pre_tips) = &self.pre_tips {
-            print!("{}", pre_tips);
-        }
-
-        print!(" >> ");
-
-        if let Some(post_tips) = &self.post_tips {
-            print!("{} ", post_tips);
-        }
-
-        io::stdout().flush().map_err(|e| ConsoleError::IOError(e))?;
-
-        io::stdin()
-            .read_line(&mut input)
-            .map_err(|e| ConsoleError::IOError(e))?;
-
-        return Ok(input.trim().to_string());
-    }
-}
-
-#[derive(Debug, Clone)]
-pub struct OptionalChoice {
-    /// 选项的提示语
-    first_line_tips: Option<String>,
-    /// 选项列表
-    items: Vec<OptionalChoiceItem>,
-}
-
-#[derive(Debug, Clone)]
-pub struct OptionalChoiceItem {
-    id: String,
-    description: String,
-}
-
-/// # 列表选择器
-///
-/// 展示一个列表,用户可以通过输入选项序号的方式,选择其中的一个选项
-///
-/// ## 效果
-///
-/// ```text
-/// Please choose an item:
-///
-///     1. Item 1
-///     2. Item 2
-///
-/// Please input: >> (1-2)
-/// ```
-impl OptionalChoice {
-    pub fn new(first_line_tips: Option<String>) -> Self {
-        Self {
-            first_line_tips,
-            items: Vec::new(),
-        }
-    }
-
-    /// # 增加一个选项
-    ///
-    /// ## 参数
-    ///
-    /// * `id` - 选项的 ID (当用户选择了该选项时,会返回该 ID)
-    /// * `description` - 选项的描述(会在选项里面显示)
-    pub fn add_choice(&mut self, id: String, description: String) {
-        self.items.push(OptionalChoiceItem { id, description });
-    }
-
-    /// # 读取用户的选择
-    ///
-    /// ## 返回值
-    ///
-    /// * `Ok(String)` - 用户选择的选项的 ID
-    /// * `Err(ConsoleError)` - 用户输入的不是一个数字,或者数字不在选项列表的范围内
-    pub fn choose(&self) -> Result<String, ConsoleError> {
-        println!("");
-        if let Some(first_line_tips) = &self.first_line_tips {
-            println!("{}", first_line_tips);
-        }
-
-        for item in self.items.iter().enumerate() {
-            println!("\t{}. {}", item.0 + 1, item.1.description);
-        }
-
-        println!("");
-        let input_tips = format!("Please input your choice:");
-        let post_tips = format!("(1-{})", self.items.len());
-        let input: String = Input::new(Some(input_tips), Some(post_tips)).input()?;
-        return self.parse_input(input);
-    }
-
-    /// 读取用户的选择,直到用户输入的是一个有效的选项.
-    /// 如果用户输入的是无效的选项,则会重新输入.
-    ///
-    /// ## 返回值
-    ///
-    /// * `Ok(String)` - 用户选择的选项的 ID
-    /// * `Err(ConsoleError)` - 产生了除InvalidInput之外的错误
-    pub fn choose_until_valid(&self) -> Result<String, ConsoleError> {
-        loop {
-            let choice = self.choose();
-            if choice.is_err() {
-                // 如果用户输入的是无效的选项,则重新输入
-                if let Err(ConsoleError::InvalidInput(e)) = choice {
-                    error!("Invalid choice: {}", e);
-                    continue;
-                } else {
-                    return Err(choice.unwrap_err());
-                }
-            }
-            return choice;
-        }
-    }
-
-    /// 读取用户的选择,直到用户输入的是一个有效的选项.
-    /// 如果用户输入的是无效的选项,则会重新输入.
-    /// 如果用户输入的是无效的选项超过了指定的次数,则会返回错误.
-    ///
-    /// ## 参数
-    ///
-    /// * `retry` - 允许用户输入无效选项的次数
-    ///
-    /// ## 返回值
-    ///
-    /// * `Ok(String)` - 用户选择的选项的 ID
-    /// * `Err(ConsoleError::RetryLimitExceeded)` - 用户输入的无效选项超过了指定的次数
-    /// * `Err(ConsoleError)` - 产生了除InvalidInput之外的错误
-    #[allow(dead_code)]
-    pub fn choose_with_retry(&self, retry: u32) -> Result<String, ConsoleError> {
-        for _ in 0..retry {
-            let choice = self.choose();
-            if choice.is_err() {
-                // 如果用户输入的是无效的选项,则重新输入
-                if let Err(ConsoleError::InvalidInput(e)) = choice {
-                    error!("Invalid choice: {}", e);
-                    continue;
-                } else {
-                    return Err(choice.unwrap_err());
-                }
-            }
-            return choice;
-        }
-        return Err(ConsoleError::RetryLimitExceeded(format!(
-            "Invalid choice: please input a number between 1 and {}",
-            self.items.len()
-        )));
-    }
-
-    /// # 解析用户的输入
-    ///
-    /// 用户的输入必须是一个数字,且在选项列表的范围内.
-    ///
-    /// ## 参数
-    ///
-    /// * `input` - 用户的输入
-    ///
-    /// ## 返回值
-    ///
-    /// * `Ok(String)` - 用户选择的选项的 ID
-    /// * `Err(ConsoleError::InvalidInput(e))` - 用户的输入不合法
-    fn parse_input(&self, input: String) -> Result<String, ConsoleError> {
-        let input = input.trim().to_string();
-        let input = input.parse::<usize>().map_err(|e| {
-            ConsoleError::InvalidInput(format!("Invalid choice: {}", e.to_string()))
-        })?;
-
-        if input < 1 || input > self.items.len() {
-            return Err(ConsoleError::InvalidInput(format!(
-                "Invalid input: {}, please input a number between 1 and {}",
-                input,
-                self.items.len()
-            )));
-        }
-        Ok(self.items[input - 1].id.clone())
-    }
-}
-
-/// # 选择是或者否
-#[derive(Debug)]
-pub struct ChooseYesOrNo {
-    tips: String,
-}
-
-impl ChooseYesOrNo {
-    pub fn new(tips: String) -> Self {
-        Self { tips }
-    }
-
-    /// # 读取用户的选择
-    /// 读取用户的选择,如果用户输入的是 yes,则返回 true,否则返回 false.
-    ///
-    /// ## 返回值
-    ///
-    /// * `Ok(bool)` - 用户的选择
-    /// * `Err(ConsoleError::InvalidInput)` - 用户输入的不是 yes 或者 no
-    /// * `Err(ConsoleError)` - 产生了除InvalidInput之外的错误
-    pub fn choose(&self) -> Result<bool, ConsoleError> {
-        let choice = Input::new(Some(self.tips.clone()), Some("(yes/no)".to_string()))
-            .input()?
-            .to_ascii_lowercase();
-
-        if choice == "yes" || choice == "y" {
-            return Ok(true);
-        } else if choice == "no" || choice == "n" {
-            return Ok(false);
-        } else {
-            return Err(ConsoleError::InvalidInput(format!(
-                "Invalid choice: {}",
-                choice
-            )));
-        }
-    }
-
-    /// 读取用户的选择,直到用户输入的是一个有效的选项.
-    ///
-    /// 如果用户输入的是无效的选项,则会重新输入.
-    ///
-    /// ## 返回值
-    ///
-    /// * `Ok(bool)` - 用户的选择
-    /// * `Err(ConsoleError)` - 产生了除InvalidInput之外的错误
-    pub fn choose_until_valid(&self) -> Result<bool, ConsoleError> {
-        loop {
-            let choice = self.choose();
-            if choice.is_err() {
-                // 如果用户输入的是无效的选项,则重新输入
-                if let Err(ConsoleError::InvalidInput(e)) = choice {
-                    error!("{}", e);
-                    continue;
-                } else {
-                    return Err(choice.unwrap_err());
-                }
-            }
-            return choice;
-        }
-    }
-
-    /// 读取用户的选择,直到用户输入的是一个有效的选项或者超过了指定的次数.
-    ///
-    /// 如果用户输入的是无效的选项,则会重新输入.
-    /// 如果用户输入的是无效的选项超过了指定的次数,则会返回错误.
-    ///
-    /// ## 参数
-    ///
-    /// * `retry` - 允许用户输入无效选项的次数
-    ///
-    /// ## 返回值
-    ///
-    /// * `Ok(bool)` - 用户的选择
-    ///
-    /// * `Err(ConsoleError::RetryLimitExceeded)` - 用户输入的无效选项超过了指定的次数
-    /// * `Err(ConsoleError)` - 产生了除InvalidInput之外的错误
-    #[allow(dead_code)]
-    pub fn choose_with_retry(&self, retry: u32) -> Result<bool, ConsoleError> {
-        for _ in 0..retry {
-            let choice = self.choose();
-            if choice.is_err() {
-                // 如果用户输入的是无效的选项,则重新输入
-                if let Err(ConsoleError::InvalidInput(e)) = choice {
-                    error!("Invalid choice: {}", e);
-                    continue;
-                } else {
-                    return Err(choice.unwrap_err());
-                }
-            }
-            return choice;
-        }
-        return Err(ConsoleError::RetryLimitExceeded(format!(
-            "Retry limit exceeded."
-        )));
-    }
-}
-
-/// # 读入多个元素到一个列表
-pub struct VecInput<T: Debug> {
-    /// 每次读入元素的提示信息
-    tips: Option<String>,
-    /// 读入的元素列表
-    results: Vec<T>,
-    /// 元素读取器
-    element_input_func: Rc<RefCell<dyn InputFunc<T>>>,
-}
-
-impl<T: Debug> Debug for VecInput<T> {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        f.debug_struct("VecInput")
-            .field("tips", &self.tips)
-            .field("results", &self.results)
-            .finish()
-    }
-}
-
-impl<T: Debug> VecInput<T> {
-    /// # 创建一个新的 VecInput
-    ///
-    /// ## 参数
-    ///
-    /// * `tips` - 每次读入元素的提示信息
-    /// * `element_input_func` - 元素读取器
-    pub fn new(tips: Option<String>, element_input_func: Rc<RefCell<dyn InputFunc<T>>>) -> Self {
-        Self {
-            tips,
-            results: Vec::new(),
-            element_input_func,
-        }
-    }
-
-    /// # 读入一组元素
-    pub fn input(&mut self) -> Result<(), ConsoleError> {
-        println!("\nPlease one or more items.");
-        while !self.should_exit()? {
-            self.input_one()?;
-        }
-        return Ok(());
-    }
-
-    /// # 读入指定数量的元素
-    #[allow(dead_code)]
-    pub fn input_n(&mut self, count: usize) -> Result<(), ConsoleError> {
-        println!("\nPlease input {} items.", count);
-        for _ in 0..count {
-            self.input_one()?;
-        }
-        return Ok(());
-    }
-
-    pub fn input_one(&mut self) -> Result<(), ConsoleError> {
-        println!();
-        if let Some(tips) = self.tips.as_ref() {
-            println!("{}", tips);
-        }
-        let elem = self.element_input_func.borrow_mut().input_until_valid()?;
-        self.results.push(elem);
-        return Ok(());
-    }
-
-    fn should_exit(&self) -> Result<bool, ConsoleError> {
-        let input_more = ChooseYesOrNo::new("Input more?".to_string()).choose_until_valid()?;
-        Ok(!input_more)
-    }
-
-    /// # 获取读入的元素列表的引用
-    pub fn results(&self) -> Result<&Vec<T>, ConsoleError> {
-        return Ok(&self.results);
-    }
-}
-
-#[derive(Debug)]
-pub struct BoolInput {
-    input: Input,
-}
-impl BoolInput {
-    pub fn new(mut pre_tips: String, post_tips: Option<String>) -> Self {
-        pre_tips.push_str(" (y/n)");
-        Self {
-            input: Input::new(Some(pre_tips), post_tips),
-        }
-    }
-}
-
-impl InputFunc<bool> for BoolInput {
-    fn input(&mut self) -> Result<bool, ConsoleError> {
-        let x = self.input.input()?;
-
-        let x = x.trim().to_lowercase();
-        if x.starts_with("y") {
-            return Ok(true);
-        } else {
-            return Ok(false);
-        }
-    }
-}

+ 0 - 94
dadk-user/src/console/interactive.rs

@@ -1,94 +0,0 @@
-use std::{fmt::Debug, path::PathBuf};
-
-use log::error;
-
-use crate::console::new_config::NewConfigCommand;
-
-use super::{Action, ConsoleError};
-
-#[derive(Debug)]
-#[allow(dead_code)]
-pub struct InteractiveConsole {
-    /// DragonOS sysroot在主机上的路径
-    dragonos_dir: Option<PathBuf>,
-    /// DADK任务配置文件所在目录
-    config_dir: Option<PathBuf>,
-    /// 要执行的操作
-    action: Action,
-}
-
-pub trait InteractiveCommand {
-    fn run(&mut self) -> Result<(), ConsoleError>;
-}
-
-impl InteractiveConsole {
-    pub fn new(dragonos_dir: Option<PathBuf>, config_dir: Option<PathBuf>, action: Action) -> Self {
-        Self {
-            dragonos_dir,
-            config_dir,
-            action,
-        }
-    }
-
-    pub fn run(&self) -> Result<(), ConsoleError> {
-        println!("\nWelcome to DADK interactive console!\n");
-        match self.action {
-            Action::New => {
-                let mut cmd = NewConfigCommand::new(self.config_dir.clone());
-                cmd.run()
-            }
-            _ => {
-                let msg = format!(
-                    "Action '{:?}' not supported in interactive console",
-                    self.action
-                );
-                error!("{msg}");
-                return Err(ConsoleError::CommandError(msg));
-            }
-        }
-    }
-}
-
-pub trait InputFunc<T: Debug + Sized> {
-    /// # 读取用户输入
-    fn input(&mut self) -> Result<T, ConsoleError>;
-    /// # 读取用户输入,直到返回值合法
-    fn input_until_valid(&mut self) -> Result<T, ConsoleError> {
-        loop {
-            let task_type = self.input();
-            if task_type.is_ok() {
-                return task_type;
-            } else {
-                if let Err(ConsoleError::InvalidInput(e)) = task_type {
-                    error!("{}", e);
-                    continue;
-                } else {
-                    return task_type;
-                }
-            }
-        }
-    }
-
-    /// # 读取用户输入,最多重试指定次数
-    ///
-    /// 如果重试次数超过指定次数,则返回错误Err(ConsoleError::RetryLimitExceeded)
-    #[allow(dead_code)]
-    fn input_with_retry(&mut self, retry: usize) -> Result<T, ConsoleError> {
-        for _ in 0..retry {
-            let task_type = self.input();
-            if task_type.is_ok() {
-                return task_type;
-            } else {
-                if let Err(ConsoleError::InvalidInput(e)) = task_type {
-                    error!("{}", e);
-                    continue;
-                } else {
-                    return task_type;
-                }
-            }
-        }
-        return Err(ConsoleError::RetryLimitExceeded(format!(
-            "Retry limit exceeded."
-        )));
-    }
-}

+ 0 - 5
dadk-user/src/console/mod.rs

@@ -12,9 +12,6 @@
 //!
 
 pub mod clean;
-pub mod elements;
-pub mod interactive;
-pub mod new_config;
 
 use std::path::PathBuf;
 
@@ -82,8 +79,6 @@ pub enum Action {
     Install,
     /// 尚不支持
     Uninstall,
-    /// 使用交互式命令行创建dadk任务配置文件
-    New,
 }
 
 #[allow(dead_code)]

+ 0 - 805
dadk-user/src/console/new_config.rs

@@ -1,805 +0,0 @@
-use std::{cell::RefCell, fmt::Debug, path::PathBuf, rc::Rc};
-
-use log::{debug, error, info};
-
-use crate::{
-    console::elements::{BoolInput, OptionalChoice, VecInput},
-    executor::{
-        cache::CacheDir,
-        source::{ArchiveSource, GitSource, LocalSource},
-    },
-    parser::task::{
-        BuildConfig, CleanConfig, CodeSource, DADKTask, Dependency, InstallConfig, PrebuiltSource,
-        TargetArch, TaskEnv, TaskType,
-    },
-};
-
-use super::{
-    elements::{ChooseYesOrNo, Input},
-    interactive::{InputFunc, InteractiveCommand},
-    ConsoleError,
-};
-
-#[derive(Debug)]
-pub struct NewConfigCommand {
-    /// DADK任务配置文件所在目录
-    config_dir: Option<PathBuf>,
-}
-
-impl InteractiveCommand for NewConfigCommand {
-    fn run(&mut self) -> Result<(), ConsoleError> {
-        // 如果没有指定配置文件输出的目录,则使用当前目录
-        if self.config_dir.is_none() {
-            self.config_dir = Some(PathBuf::from("./"));
-        }
-
-        println!("To create a new DADK task config, please follow the guidance below... \n");
-
-        let mut dadk_task = self.build_dadk_task()?;
-        debug!("dadk_task: {:?}", dadk_task);
-
-        // 校验
-        let check: Result<(), ConsoleError> = dadk_task.validate().map_err(|e| {
-            let msg = format!("Failed to validate DADKTask: {:?}", e);
-            ConsoleError::InvalidInput(msg)
-        });
-
-        if check.is_err() {
-            error!("{:?}", check.unwrap_err());
-        }
-        // 不管校验是否通过,都写入文件
-        let config_file_path = self.write_dadk_config_file(&dadk_task)?;
-
-        info!(
-            "DADK task config file created successfully! File:{}",
-            config_file_path.display()
-        );
-        return Ok(());
-    }
-}
-
-impl NewConfigCommand {
-    pub fn new(config_dir: Option<PathBuf>) -> Self {
-        Self { config_dir }
-    }
-
-    fn write_dadk_config_file(&self, dadk_task: &DADKTask) -> Result<PathBuf, ConsoleError> {
-        let json = serde_json::to_string_pretty(&dadk_task).map_err(|e| {
-            let msg = format!("Failed to serialize DADKTask to json: {:?}", e);
-            error!("{}", msg);
-            ConsoleError::InvalidInput(msg)
-        })?;
-        info!("Complete DADK task config file:\n {}", json);
-
-        // 创建路径
-        let config_dir = self.config_dir.as_ref().unwrap();
-        let filename = format!("{}.dadk", dadk_task.name_version());
-        let config_path = config_dir.join(filename);
-
-        // 写入文件
-        std::fs::write(&config_path, json).map_err(|e| {
-            let msg = format!(
-                "Failed to write config file to {}, error: {:?}",
-                config_path.display(),
-                e
-            );
-            error!("{}", msg);
-            ConsoleError::InvalidInput(msg)
-        })?;
-
-        return Ok(config_path);
-    }
-
-    fn build_dadk_task(&self) -> Result<DADKTask, ConsoleError> {
-        let name = self.input_name()?;
-        let version = self.input_version()?;
-        let description = self.input_description()?;
-        debug!(
-            "name: {}, version: {}, description: {}",
-            name, version, description
-        );
-        let rust_target = self.input_rust_target()?;
-        let task_type: TaskType = TaskTypeInput::new().input()?;
-        debug!("task_type: {:?}", task_type);
-
-        let dep: Vec<Dependency> = DependencyInput::new().input()?;
-        debug!("dep: {:?}", dep);
-        let build_config: BuildConfig = match &task_type {
-            TaskType::InstallFromPrebuilt(_) => BuildConfig::new(Option::Some("".to_string())),
-            TaskType::BuildFromSource(_) => BuildConfigInput::new().input()?,
-        };
-        debug!("build_config: {:?}", build_config);
-        let install_config: InstallConfig = InstallConfigInput::new().input()?;
-        debug!("install_config: {:?}", install_config);
-        let clean_config: CleanConfig = CleanConfigInput::new().input()?;
-        debug!("clean_config: {:?}", clean_config);
-
-        let task_env: Option<Vec<TaskEnv>> = TaskEnvInput::new().input()?;
-        debug!("task_env: {:?}", task_env);
-
-        let build_once = BoolInput::new("Run this task once?".to_string(), None).input()?;
-        debug!("build_once: {:?}", build_once);
-        let install_once = BoolInput::new("Install this task once?".to_string(), None).input()?;
-        debug!("install_once: {:?}", install_once);
-
-        let target_arch = TargetArchInput::new().input()?;
-        debug!("target_arch: {:?}", target_arch);
-
-        let mut dadk: DADKTask = DADKTask::new(
-            name,
-            version,
-            description,
-            rust_target,
-            task_type,
-            dep,
-            build_config,
-            install_config,
-            clean_config,
-            task_env,
-            build_once,
-            install_once,
-            target_arch,
-        );
-
-        dadk.trim();
-
-        return Ok(dadk);
-    }
-
-    // 输入任务名称
-    fn input_name(&self) -> Result<String, ConsoleError> {
-        let name = Input::new(
-            Some("Please input the [name] of the task:".to_string()),
-            None,
-        )
-        .input()?;
-        Ok(name)
-    }
-
-    // 输入任务版本
-    fn input_version(&self) -> Result<String, ConsoleError> {
-        let version = Input::new(
-            Some("Please input the [version] of the task:".to_string()),
-            None,
-        )
-        .input()?;
-
-        return Ok(version);
-    }
-
-    // 输入任务描述
-    fn input_description(&self) -> Result<String, ConsoleError> {
-        let description = Input::new(
-            Some("Please input the [description] of the task:".to_string()),
-            None,
-        )
-        .input()?;
-
-        return Ok(description);
-    }
-
-    // 输入编译target
-    fn input_rust_target(&self) -> Result<Option<String>, ConsoleError> {
-        let choice = ChooseYesOrNo::new("Input rust_target?".to_string()).choose_until_valid()?;
-
-        if choice {
-            let rust_target = Input::new(
-                Some("Please input the [rust_target] of the task:".to_string()),
-                None,
-            )
-            .input()?;
-            return Ok(Some(rust_target));
-        }
-
-        return Ok(None);
-    }
-}
-
-#[derive(Debug)]
-struct TaskTypeInput;
-
-impl TaskTypeInput {
-    pub fn new() -> Self {
-        Self {}
-    }
-}
-
-impl InputFunc<TaskType> for TaskTypeInput {
-    /// # 输入任务类型
-    fn input(&mut self) -> Result<TaskType, ConsoleError> {
-        const TASK_TYPE_BUILD_FROM_SOURCE: &str = "src";
-        const TASK_TYPE_INSTALL_FROM_PREBUILT: &str = "prebuilt";
-
-        let mut task_type_choose =
-            OptionalChoice::new(Some("Please choose the [type] of the task:".to_string()));
-        task_type_choose.add_choice(
-            TASK_TYPE_BUILD_FROM_SOURCE.to_string(),
-            "Build from source".to_string(),
-        );
-        task_type_choose.add_choice(
-            TASK_TYPE_INSTALL_FROM_PREBUILT.to_string(),
-            "Install from prebuilt".to_string(),
-        );
-
-        // 读取用户输入
-        let task_type = task_type_choose.choose_until_valid()?;
-
-        // debug!("task type: {}", task_type);
-
-        let mut task_type = match task_type.as_str() {
-            TASK_TYPE_BUILD_FROM_SOURCE => {
-                TaskType::BuildFromSource(CodeSourceInput::new().input()?)
-            }
-            TASK_TYPE_INSTALL_FROM_PREBUILT => {
-                TaskType::InstallFromPrebuilt(PrebuiltSourceInput::new().input()?)
-            }
-            _ => {
-                let msg = format!("Invalid task type: {}", task_type);
-                return Err(ConsoleError::InvalidInput(msg));
-            }
-        };
-
-        // 验证输入
-        task_type.validate().map_err(|e| {
-            ConsoleError::InvalidInput(format!("Invalid task type: {}", e.to_string()))
-        })?;
-
-        return Ok(task_type);
-    }
-}
-/// # 代码源输入
-#[derive(Debug)]
-struct CodeSourceInput;
-
-impl CodeSourceInput {
-    pub fn new() -> Self {
-        Self {}
-    }
-
-    pub fn input(&self) -> Result<CodeSource, ConsoleError> {
-        const CODE_SOURCE_GIT: &str = "git";
-        const CODE_SOURCE_LOCAL: &str = "local";
-        const CODE_SOURCE_ARCHIVE: &str = "archive";
-
-        let mut code_source_choose = OptionalChoice::new(Some(
-            "Please choose the [code source] of the task:".to_string(),
-        ));
-        code_source_choose.add_choice(
-            CODE_SOURCE_GIT.to_string(),
-            "Build from git repository".to_string(),
-        );
-        code_source_choose.add_choice(
-            CODE_SOURCE_LOCAL.to_string(),
-            "Build from local directory".to_string(),
-        );
-        code_source_choose.add_choice(
-            CODE_SOURCE_ARCHIVE.to_string(),
-            "Build from archive file".to_string(),
-        );
-
-        // 读取用户输入
-        let code_source: String = code_source_choose.choose_until_valid()?;
-        // debug!("code source: {}", code_source);
-
-        let mut code_source: CodeSource = match code_source.as_str() {
-            CODE_SOURCE_GIT => CodeSource::Git(GitSourceInput::new().input_until_valid()?),
-            CODE_SOURCE_LOCAL => CodeSource::Local(LocalSourceInput::new().input_until_valid()?),
-            CODE_SOURCE_ARCHIVE => {
-                CodeSource::Archive(ArchiveSourceInput::new().input_until_valid()?)
-            }
-            _ => {
-                let msg = format!("Invalid code source: {}", code_source);
-                return Err(ConsoleError::InvalidInput(msg));
-            }
-        };
-        code_source.trim();
-        code_source.validate().map_err(|e| {
-            ConsoleError::InvalidInput(format!("Invalid code source: {}", e.to_string()))
-        })?;
-
-        return Ok(code_source);
-    }
-}
-
-#[derive(Debug)]
-struct PrebuiltSourceInput;
-
-impl PrebuiltSourceInput {
-    pub fn new() -> Self {
-        Self {}
-    }
-}
-
-impl InputFunc<PrebuiltSource> for PrebuiltSourceInput {
-    fn input(&mut self) -> Result<PrebuiltSource, ConsoleError> {
-        const PREBUILT_SOURCE_LOCAL: &str = "local";
-        const PREBUILT_SOURCE_ARCHIVE: &str = "archive";
-
-        let mut prebuilt_source_choose = OptionalChoice::new(Some(
-            "Please choose the [prebuilt source] of the task:".to_string(),
-        ));
-
-        prebuilt_source_choose.add_choice(
-            PREBUILT_SOURCE_LOCAL.to_string(),
-            "Install from local directory".to_string(),
-        );
-        prebuilt_source_choose.add_choice(
-            PREBUILT_SOURCE_ARCHIVE.to_string(),
-            "Install from archive file".to_string(),
-        );
-
-        // 读取用户输入
-        let prebuilt_source: String = prebuilt_source_choose.choose_until_valid()?;
-        // debug!("prebuilt source: {}", prebuilt_source);
-
-        let mut prebuilt_source: PrebuiltSource = match prebuilt_source.as_str() {
-            PREBUILT_SOURCE_LOCAL => {
-                PrebuiltSource::Local(LocalSourceInput::new().input_until_valid()?)
-            }
-            PREBUILT_SOURCE_ARCHIVE => {
-                PrebuiltSource::Archive(ArchiveSourceInput::new().input_until_valid()?)
-            }
-            _ => {
-                let msg = format!("Invalid prebuilt source: {}", prebuilt_source);
-                return Err(ConsoleError::InvalidInput(msg));
-            }
-        };
-        prebuilt_source.trim();
-        prebuilt_source.validate().map_err(|e| {
-            ConsoleError::InvalidInput(format!("Invalid prebuilt source: {}", e.to_string()))
-        })?;
-
-        return Ok(prebuilt_source);
-    }
-}
-
-#[derive(Debug)]
-struct GitSourceInput;
-
-impl InputFunc<GitSource> for GitSourceInput {
-    fn input(&mut self) -> Result<GitSource, ConsoleError> {
-        let url = self.input_url()?;
-
-        // 选择分支还是指定的commit
-        const GIT_SOURCE_BRANCH: &str = "branch";
-        const GIT_SOURCE_REVISION: &str = "revision";
-
-        let mut git_source_choose = OptionalChoice::new(Some(
-            "Please choose the [git source] of the task:".to_string(),
-        ));
-        git_source_choose.add_choice(GIT_SOURCE_BRANCH.to_string(), "branch name".to_string());
-        git_source_choose.add_choice(GIT_SOURCE_REVISION.to_string(), "revision hash".to_string());
-
-        // 读取用户输入
-        let git_source = git_source_choose.choose_until_valid()?;
-        // debug!("git source: {}", git_source);
-
-        let mut git_source: GitSource = match git_source.as_str() {
-            GIT_SOURCE_BRANCH => {
-                let branch = self.input_branch()?;
-                GitSource::new(url, Some(branch), None)
-            }
-            GIT_SOURCE_REVISION => {
-                let revision = self.input_revision()?;
-                GitSource::new(url, None, Some(revision))
-            }
-            _ => {
-                let msg = format!("Invalid git source: {}", git_source);
-                return Err(ConsoleError::InvalidInput(msg));
-            }
-        };
-        git_source.trim();
-        // 验证输入
-        git_source.validate().map_err(|e| {
-            ConsoleError::InvalidInput(format!("Invalid git source: {}", e.to_string()))
-        })?;
-
-        return Ok(git_source);
-    }
-}
-
-impl GitSourceInput {
-    pub fn new() -> Self {
-        Self {}
-    }
-
-    fn input_url(&self) -> Result<String, ConsoleError> {
-        let url = Input::new(
-            Some("Please input the [url] of the git repository:".to_string()),
-            None,
-        )
-        .input()?;
-        return Ok(url);
-    }
-
-    fn input_branch(&self) -> Result<String, ConsoleError> {
-        let branch = Input::new(
-            Some("Please input the [branch name] of the git repository:".to_string()),
-            None,
-        )
-        .input()?;
-        return Ok(branch);
-    }
-
-    fn input_revision(&self) -> Result<String, ConsoleError> {
-        let revision = Input::new(
-            Some("Please input the [revision hash] of the git repository:".to_string()),
-            None,
-        )
-        .input()?;
-        return Ok(revision);
-    }
-}
-
-#[derive(Debug)]
-struct LocalSourceInput;
-
-impl LocalSourceInput {
-    pub fn new() -> Self {
-        Self {}
-    }
-
-    fn input_path(&self) -> Result<String, ConsoleError> {
-        let path = Input::new(
-            Some("Please input the [path] of the local directory:".to_string()),
-            None,
-        )
-        .input()?;
-        return Ok(path);
-    }
-}
-impl InputFunc<LocalSource> for LocalSourceInput {
-    fn input(&mut self) -> Result<LocalSource, ConsoleError> {
-        let path = self.input_path()?;
-        let path = PathBuf::from(path);
-        let mut local_source = LocalSource::new(path);
-
-        local_source.trim();
-        // 验证输入
-        local_source.validate(None).map_err(|e| {
-            ConsoleError::InvalidInput(format!("Invalid local source: {}", e.to_string()))
-        })?;
-
-        return Ok(local_source);
-    }
-}
-
-#[derive(Debug)]
-struct ArchiveSourceInput;
-
-impl ArchiveSourceInput {
-    pub fn new() -> Self {
-        Self {}
-    }
-
-    fn input_url(&self) -> Result<String, ConsoleError> {
-        let url = Input::new(
-            Some("Please input the [url] of the archive file:".to_string()),
-            None,
-        )
-        .input()?;
-        return Ok(url);
-    }
-}
-
-impl InputFunc<ArchiveSource> for ArchiveSourceInput {
-    fn input(&mut self) -> Result<ArchiveSource, ConsoleError> {
-        let url = self.input_url()?;
-        let mut archive_source = ArchiveSource::new(url);
-
-        archive_source.trim();
-        // 验证输入
-        archive_source.validate().map_err(|e| {
-            ConsoleError::InvalidInput(format!("Invalid archive source: {}", e.to_string()))
-        })?;
-
-        return Ok(archive_source);
-    }
-}
-
-#[derive(Debug)]
-struct DependencyInput;
-
-impl DependencyInput {
-    pub fn new() -> Self {
-        Self {}
-    }
-}
-
-impl InputFunc<Vec<Dependency>> for DependencyInput {
-    fn input(&mut self) -> Result<Vec<Dependency>, ConsoleError> {
-        const TIPS: &str = "Please input the [dependencies] of the task:";
-        println!();
-        println!("Please input the [dependencies] of the task:");
-        let dependency_reader: Rc<RefCell<DependencyInputOne>> =
-            Rc::new(RefCell::new(DependencyInputOne::new()));
-        let mut vecinput = VecInput::new(Some(TIPS.to_string()), dependency_reader);
-        vecinput.input()?;
-        return Ok(vecinput.results()?.clone());
-    }
-}
-
-/// 读取一个dependency的读取器
-#[derive(Debug)]
-struct DependencyInputOne;
-
-impl InputFunc<Dependency> for DependencyInputOne {
-    fn input(&mut self) -> Result<Dependency, ConsoleError> {
-        return self.input_one();
-    }
-}
-
-impl DependencyInputOne {
-    pub fn new() -> Self {
-        Self {}
-    }
-
-    fn input_name(&self) -> Result<String, ConsoleError> {
-        let name = Input::new(
-            Some("Please input the [name] of the dependency:".to_string()),
-            None,
-        )
-        .input()?;
-        return Ok(name);
-    }
-
-    fn input_version(&self) -> Result<String, ConsoleError> {
-        let version = Input::new(
-            Some("Please input the [version] of the dependency:".to_string()),
-            None,
-        )
-        .input()?;
-        return Ok(version);
-    }
-
-    fn input_one(&self) -> Result<Dependency, ConsoleError> {
-        let name = self.input_name()?;
-        let version = self.input_version()?;
-        let mut dependency = Dependency::new(name, version);
-
-        dependency.trim();
-        // 验证输入
-        dependency.validate().map_err(|e| {
-            ConsoleError::InvalidInput(format!("Invalid dependency: {}", e.to_string()))
-        })?;
-
-        return Ok(dependency);
-    }
-}
-
-#[derive(Debug)]
-pub struct BuildConfigInput;
-
-impl BuildConfigInput {
-    pub fn new() -> Self {
-        Self {}
-    }
-
-    fn input_command(&self) -> Result<String, ConsoleError> {
-        println!("Please input the [build command] of the task:");
-        let tips = format!("\nNote:
-\t1. The command will be executed in the root directory of the source code.
-\t2. After the command is executed, all files need to install to DragonOS should be placed in: [{}_TASKNAME_VERSION]\n",
- CacheDir::DADK_BUILD_CACHE_DIR_ENV_KEY_PREFIX);
-        println!("{}", tips);
-        let mut command = Input::new(Some("Build Command:".to_string()), None).input()?;
-        command = command.trim().to_string();
-
-        return Ok(command);
-    }
-}
-
-impl InputFunc<BuildConfig> for BuildConfigInput {
-    fn input(&mut self) -> Result<BuildConfig, ConsoleError> {
-        println!("\nPlease input the [build_config] of the task:");
-
-        // 读取build_config
-        let command = self.input_command()?;
-        let command = if command.is_empty() {
-            None
-        } else {
-            Some(command)
-        };
-        let build_config = BuildConfig::new(command);
-        return Ok(build_config);
-    }
-}
-
-#[derive(Debug)]
-struct InstallConfigInput;
-
-impl InstallConfigInput {
-    pub fn new() -> Self {
-        Self {}
-    }
-
-    fn input_install_dir(&self) -> Result<Option<PathBuf>, ConsoleError> {
-        let install_dir = Input::new(
-            Some("Please input the [dir to install in DragonOS] of the task:".to_string()),
-            None,
-        )
-        .input()?;
-        let install_dir = install_dir.trim().to_string();
-        let install_dir = if install_dir.is_empty() {
-            None
-        } else {
-            Some(PathBuf::from(install_dir))
-        };
-        return Ok(install_dir);
-    }
-}
-
-impl InputFunc<InstallConfig> for InstallConfigInput {
-    fn input(&mut self) -> Result<InstallConfig, ConsoleError> {
-        println!("\nPlease input the [install_config] of the task:");
-
-        // 读取install dir
-        let install_dir = self.input_install_dir()?;
-        let mut install_config = InstallConfig::new(install_dir);
-        install_config.trim();
-        return Ok(install_config);
-    }
-}
-
-#[derive(Debug)]
-struct CleanConfigInput;
-
-impl CleanConfigInput {
-    pub fn new() -> Self {
-        Self {}
-    }
-
-    fn input_clean_command(&self) -> Result<Option<String>, ConsoleError> {
-        let clean_command = Input::new(
-            Some("Please input the [clean command] of the task:".to_string()),
-            None,
-        )
-        .input()?;
-        let clean_command = clean_command.trim().to_string();
-        let clean_command = if clean_command.is_empty() {
-            None
-        } else {
-            Some(clean_command)
-        };
-        return Ok(clean_command);
-    }
-}
-
-impl InputFunc<CleanConfig> for CleanConfigInput {
-    fn input(&mut self) -> Result<CleanConfig, ConsoleError> {
-        println!("\nPlease configure the [clean_config] of the task:");
-
-        // 读取clean command
-        let clean_command = self.input_clean_command()?;
-        let mut clean_config = CleanConfig::new(clean_command);
-        clean_config.trim();
-        return Ok(clean_config);
-    }
-}
-
-#[derive(Debug)]
-struct TaskEnvInput;
-
-impl TaskEnvInput {
-    pub fn new() -> Self {
-        Self {}
-    }
-}
-
-impl InputFunc<Option<Vec<TaskEnv>>> for TaskEnvInput {
-    fn input(&mut self) -> Result<Option<Vec<TaskEnv>>, ConsoleError> {
-        const TIPS: &str = "Please configure the [ environment variables ] of the task:";
-        println!();
-        println!("{TIPS}");
-        let env_reader: Rc<RefCell<TaskEnvInputOne>> =
-            Rc::new(RefCell::new(TaskEnvInputOne::new()));
-        let mut vecinput: VecInput<TaskEnv> = VecInput::new(Some(TIPS.to_string()), env_reader);
-        vecinput.input()?;
-        let result = vecinput.results()?.clone();
-        // 不管是否有输入,都返回Some
-        return Ok(Some(result));
-    }
-}
-
-#[derive(Debug)]
-struct TaskEnvInputOne;
-
-impl TaskEnvInputOne {
-    pub fn new() -> Self {
-        Self {}
-    }
-
-    fn input_name(&self) -> Result<String, ConsoleError> {
-        let name = Input::new(
-            Some("Please input the [name] of the env:".to_string()),
-            None,
-        )
-        .input()?;
-        return Ok(name);
-    }
-
-    fn input_value(&self) -> Result<String, ConsoleError> {
-        let value = Input::new(
-            Some("Please input the [value] of the env:".to_string()),
-            None,
-        )
-        .input()?;
-        return Ok(value);
-    }
-
-    fn input_one(&self) -> Result<TaskEnv, ConsoleError> {
-        let name = self.input_name()?;
-        let value = self.input_value()?;
-        let mut env = TaskEnv::new(name, value);
-
-        env.trim();
-        // 验证输入
-        env.validate()
-            .map_err(|e| ConsoleError::InvalidInput(format!("Invalid env: {}", e.to_string())))?;
-
-        return Ok(env);
-    }
-}
-
-impl InputFunc<TaskEnv> for TaskEnvInputOne {
-    fn input(&mut self) -> Result<TaskEnv, ConsoleError> {
-        let env = self.input_one()?;
-        return Ok(env);
-    }
-}
-
-/// # 输入目标架构
-///
-/// 可选值参考:[TargetArch](crate::parser::task::TargetArch::EXPECTED)
-#[derive(Debug)]
-struct TargetArchInput;
-
-impl TargetArchInput {
-    pub fn new() -> Self {
-        Self {}
-    }
-}
-
-impl InputFunc<Option<Vec<TargetArch>>> for TargetArchInput {
-    fn input(&mut self) -> Result<Option<Vec<TargetArch>>, ConsoleError> {
-        const TIPS: &str = "Please configure the [ available target arch ] of the task:";
-        println!();
-        println!("{TIPS}");
-        let env_reader: Rc<RefCell<TargetArchInputOne>> =
-            Rc::new(RefCell::new(TargetArchInputOne::new()));
-        let mut vecinput: VecInput<TargetArch> = VecInput::new(Some(TIPS.to_string()), env_reader);
-        vecinput.input()?;
-        let result = vecinput.results()?.clone();
-
-        if result.is_empty() {
-            return Ok(None);
-        }
-
-        return Ok(Some(result));
-    }
-}
-
-#[derive(Debug)]
-struct TargetArchInputOne;
-
-impl TargetArchInputOne {
-    pub fn new() -> Self {
-        Self
-    }
-
-    fn input_one(&self) -> Result<TargetArch, ConsoleError> {
-        let s = Input::new(Some("Please input one target arch:".to_string()), None).input()?;
-
-        let target_arch = TargetArch::try_from(s.as_str()).map_err(|e| {
-            ConsoleError::InvalidInput(format!("Invalid target arch: {}", e.to_string()))
-        })?;
-        return Ok(target_arch);
-    }
-}
-
-impl InputFunc<TargetArch> for TargetArchInputOne {
-    fn input(&mut self) -> Result<TargetArch, ConsoleError> {
-        let env = self.input_one()?;
-        return Ok(env);
-    }
-}

+ 0 - 4
dadk-user/src/context.rs

@@ -55,10 +55,6 @@ impl DadkUserExecuteContext {
             TASK_DEQUE.lock().unwrap().set_thread(thread);
         }
 
-        if self.action() == &Action::New {
-            return;
-        }
-
         if self.config_dir().is_none() {
             error!("Config dir is required for action: {:?}", self.action());
             exit(1);

+ 2 - 21
dadk-user/src/lib.rs

@@ -99,13 +99,11 @@ use std::{path::PathBuf, process::exit, sync::Arc};
 
 use clap::Parser;
 
-use log::{error, info};
+use log::info;
 use parser::task::DADKTask;
 
 use crate::{
-    console::{interactive::InteractiveConsole, CommandLineArgs},
-    context::DadkUserExecuteContextBuilder,
-    scheduler::Scheduler,
+    console::CommandLineArgs, context::DadkUserExecuteContextBuilder, scheduler::Scheduler,
 };
 
 mod console;
@@ -151,23 +149,6 @@ pub fn dadk_user_main() {
         context.thread_num().map_or_else(|| 0, |t| t)
     );
 
-    match context.action() {
-        console::Action::New => {
-            let r = InteractiveConsole::new(
-                context.sysroot_dir().cloned(),
-                context.config_dir().cloned(),
-                *context.action(),
-            )
-            .run();
-            if r.is_err() {
-                error!("Failed to run interactive console: {:?}", r.unwrap_err());
-                exit(1);
-            }
-            exit(0);
-        }
-        _ => {}
-    }
-
     let mut parser = parser::Parser::new(context.config_dir().unwrap().clone());
     let r = parser.parse();
     if r.is_err() {

+ 4 - 4
dadk-user/src/scheduler/mod.rs

@@ -260,7 +260,7 @@ impl SchedEntities {
 #[derive(Debug)]
 pub struct Scheduler {
     /// DragonOS sysroot在主机上的路径
-    dragonos_dir: PathBuf,
+    sysroot_dir: PathBuf,
     /// 要执行的操作
     action: Action,
     /// 调度实体列表
@@ -312,7 +312,7 @@ impl Scheduler {
         let entities = SchedEntities::new();
 
         let mut scheduler = Scheduler {
-            dragonos_dir,
+            sysroot_dir: dragonos_dir,
             action,
             target: entities,
             context,
@@ -471,7 +471,7 @@ impl Scheduler {
         let r: Vec<Arc<SchedEntity>> = self.target.topo_sort();
 
         let action = self.action.clone();
-        let dragonos_dir = self.dragonos_dir.clone();
+        let dragonos_dir = self.sysroot_dir.clone();
         let id2entity = self.target.id2entity();
         let count = r.len();
 
@@ -489,7 +489,7 @@ impl Scheduler {
     fn run_without_topo_sort(&self) -> Result<(), SchedulerError> {
         // 启动守护线程
         let action = self.action.clone();
-        let dragonos_dir = self.dragonos_dir.clone();
+        let dragonos_dir = self.sysroot_dir.clone();
         let mut r = self.target.entities();
         let handler = std::thread::spawn(move || {
             Self::clean_daemon(action, dragonos_dir, &mut r);