Parcourir la source

feat: 添加target_arch字段,实现根据不同的架构来自动编译对应的包。 (#42)

* feat: 添加target_arch字段,实现根据不同的架构来自动编译对应的包。

在dadk配置文件内添加target_arch字段,实现根据不同的架构来自动编译对应的包。

## DADK 在运行时如何获得“当前编译的目标架构?”

按照以下顺序获取(一旦获取成功就不会继续尝试其他方法来获取)
1. 根据命令行传入的`--target-arch`字段获取
2. 根据`ARCH`环境变量获取
3. 如果都获取不到,则默认设置为x86_64

## 哪些任务将会被执行?

如果dadk配置文件没有指定target_arch,那么该字段的默认值的获取顺序为:
1. 根据`ARCH`环境变量获取
2. 如果获取不到,则默认设置为x86_64

当任务的`target_arch`字段包含了当前编译的目标架构时,任务将会被执行。
LoGin il y a 3 semaines
Parent
commit
9efba7eea2

+ 14 - 0
src/console/mod.rs

@@ -20,6 +20,8 @@ use std::path::PathBuf;
 
 use clap::{Parser, Subcommand};
 
+use crate::parser::task::TargetArch;
+
 use self::clean::CleanArg;
 
 #[derive(Debug, Parser, Clone)]
@@ -43,6 +45,10 @@ pub struct CommandLineArgs {
     /// DADK任务并行线程数量
     #[arg(short, long)]
     pub thread: Option<usize>,
+
+    /// 目标架构,可选: ["aarch64", "x86_64", "riscv64", "riscv32"]
+    #[arg(long, value_parser = parse_target_arch)]
+    pub target_arch: Option<TargetArch>,
 }
 
 /// @brief 检查目录是否存在
@@ -58,6 +64,14 @@ fn parse_check_dir_exists(path: &str) -> Result<PathBuf, String> {
     return Ok(path);
 }
 
+fn parse_target_arch(s: &str) -> Result<TargetArch, String> {
+    let x = TargetArch::try_from(s);
+    if x.is_err() {
+        return Err(format!("Invalid target arch: {}", s));
+    }
+    return Ok(x.unwrap());
+}
+
 /// @brief 要执行的操作
 #[derive(Debug, Subcommand, Clone, Copy, PartialEq, Eq)]
 pub enum Action {

+ 61 - 1
src/console/new_config.rs

@@ -10,7 +10,7 @@ use crate::{
     },
     parser::task::{
         BuildConfig, CleanConfig, CodeSource, DADKTask, Dependency, InstallConfig, PrebuiltSource,
-        TaskEnv, TaskType,
+        TargetArch, TaskEnv, TaskType,
     },
 };
 
@@ -122,6 +122,9 @@ impl NewConfigCommand {
         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,
@@ -135,6 +138,7 @@ impl NewConfigCommand {
             task_env,
             build_once,
             install_once,
+            target_arch,
         );
 
         dadk.trim();
@@ -743,3 +747,59 @@ impl InputFunc<TaskEnv> for TaskEnvInputOne {
         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);
+    }
+}

+ 87 - 28
src/context.rs

@@ -1,11 +1,18 @@
-use std::{path::PathBuf, process::exit};
+use std::{
+    path::PathBuf,
+    process::exit,
+    sync::{Arc, Mutex, Weak},
+};
 
 use derive_builder::Builder;
 use log::error;
 #[cfg(test)]
 use test_base::{test_context::TestContext, BaseTestContext};
 
-use crate::{console::Action, executor::cache::cache_root_init, scheduler::task_deque::TASK_DEQUE};
+use crate::{
+    console::Action, executor::cache::cache_root_init, parser::task::TargetArch,
+    scheduler::task_deque::TASK_DEQUE,
+};
 
 #[derive(Debug, Builder)]
 #[builder(setter(into))]
@@ -21,12 +28,21 @@ pub struct DadkExecuteContext {
     /// dadk缓存根目录
     cache_dir: Option<PathBuf>,
 
+    /// 目标架构
+    #[builder(default = "crate::DADKTask::default_target_arch()")]
+    target_arch: TargetArch,
+
     #[cfg(test)]
     base_test_context: Option<BaseTestContext>,
+
+    #[builder(setter(skip), default = "Mutex::new(Weak::new())")]
+    self_ref: Mutex<Weak<Self>>,
 }
 
 impl DadkExecuteContext {
-    pub fn init(&self) {
+    pub fn init(&self, self_arc: Arc<Self>) {
+        self.set_self_ref(Arc::downgrade(&self_arc));
+
         // 初始化缓存目录
         let r: Result<(), crate::executor::ExecutorError> =
             cache_root_init(self.cache_dir().cloned());
@@ -56,6 +72,20 @@ impl DadkExecuteContext {
             exit(1);
         }
     }
+
+    #[allow(dead_code)]
+    pub fn self_ref(&self) -> Option<Arc<Self>> {
+        self.self_ref.lock().unwrap().upgrade()
+    }
+
+    fn set_self_ref(&self, self_ref: Weak<Self>) {
+        *self.self_ref.lock().unwrap() = self_ref;
+    }
+
+    pub fn target_arch(&self) -> &TargetArch {
+        &self.target_arch
+    }
+
     pub fn sysroot_dir(&self) -> Option<&PathBuf> {
         self.sysroot_dir.as_ref()
     }
@@ -84,41 +114,65 @@ pub trait TestContextExt: TestContext {
     fn execute_context(&self) -> &DadkExecuteContext;
 }
 
+impl DadkExecuteContextBuilder {
+    /// 用于测试的默认构建器
+    #[cfg(test)]
+    fn default_test_execute_context_builder(
+        base_context: &BaseTestContext,
+    ) -> DadkExecuteContextBuilder {
+        DadkExecuteContextBuilder::default()
+            .sysroot_dir(Some(base_context.fake_dragonos_sysroot()))
+            .action(Action::Build)
+            .thread_num(None)
+            .cache_dir(Some(base_context.fake_dadk_cache_root()))
+            .base_test_context(Some(base_context.clone()))
+            .clone()
+    }
+}
+
 #[cfg(test)]
-pub struct DadkExecuteContextTestBuildV1 {
-    context: DadkExecuteContext,
+pub struct DadkExecuteContextTestBuildX86_64V1 {
+    context: Arc<DadkExecuteContext>,
 }
 
 #[cfg(test)]
-impl TestContext for DadkExecuteContextTestBuildV1 {
+impl TestContext for DadkExecuteContextTestBuildX86_64V1 {
     fn setup() -> Self {
         let base_context = BaseTestContext::setup();
-        let context = DadkExecuteContextBuilder::default()
-            .sysroot_dir(Some(base_context.fake_dragonos_sysroot()))
-            .config_dir(Some(base_context.config_v1_dir()))
-            .action(Action::Build)
-            .thread_num(None)
-            .cache_dir(Some(base_context.fake_dadk_cache_root()))
-            .base_test_context(Some(base_context))
-            .build()
-            .expect("Failed to build DadkExecuteContextTestBuildV1");
-        context.init();
-        DadkExecuteContextTestBuildV1 { context }
+        let context =
+            DadkExecuteContextBuilder::default_test_execute_context_builder(&base_context)
+                .target_arch(TargetArch::X86_64)
+                .config_dir(Some(base_context.config_v1_dir()))
+                .build()
+                .expect("Failed to build DadkExecuteContextTestBuildX86_64V1");
+        let context = Arc::new(context);
+        context.init(context.clone());
+        DadkExecuteContextTestBuildX86_64V1 { context }
     }
 }
 
 #[cfg(test)]
-impl TestContextExt for DadkExecuteContextTestBuildV1 {
-    fn base_context(&self) -> &BaseTestContext {
-        self.base_test_context.as_ref().unwrap()
-    }
+pub struct DadkExecuteContextTestBuildRiscV64V1 {
+    context: Arc<DadkExecuteContext>,
+}
 
-    fn execute_context(&self) -> &DadkExecuteContext {
-        &self.context
+#[cfg(test)]
+impl TestContext for DadkExecuteContextTestBuildRiscV64V1 {
+    fn setup() -> Self {
+        let base_context = BaseTestContext::setup();
+        let context =
+            DadkExecuteContextBuilder::default_test_execute_context_builder(&base_context)
+                .target_arch(TargetArch::RiscV64)
+                .config_dir(Some(base_context.config_v1_dir()))
+                .build()
+                .expect("Failed to build DadkExecuteContextTestBuildRiscV64V1");
+        let context = Arc::new(context);
+        context.init(context.clone());
+        DadkExecuteContextTestBuildRiscV64V1 { context }
     }
 }
 
-macro_rules! impl_deref_for_test_context {
+macro_rules! impl_for_test_context {
     ($context:ty) => {
         #[cfg(test)]
         impl std::ops::Deref for $context {
@@ -130,12 +184,17 @@ macro_rules! impl_deref_for_test_context {
         }
 
         #[cfg(test)]
-        impl std::ops::DerefMut for $context {
-            fn deref_mut(&mut self) -> &mut Self::Target {
-                &mut self.context
+        impl TestContextExt for $context {
+            fn base_context(&self) -> &BaseTestContext {
+                self.base_test_context.as_ref().unwrap()
+            }
+
+            fn execute_context(&self) -> &DadkExecuteContext {
+                &self.context
             }
         }
     };
 }
 
-impl_deref_for_test_context!(DadkExecuteContextTestBuildV1);
+impl_for_test_context!(DadkExecuteContextTestBuildX86_64V1);
+impl_for_test_context!(DadkExecuteContextTestBuildRiscV64V1);

+ 24 - 97
src/executor/mod.rs

@@ -10,6 +10,7 @@ use log::{debug, error, info, warn};
 
 use crate::{
     console::{clean::CleanLevel, Action},
+    context::DadkExecuteContext,
     executor::cache::CacheDir,
     parser::{
         task::{CodeSource, PrebuiltSource, TaskEnv, TaskType},
@@ -24,6 +25,8 @@ use self::cache::{CacheDirType, TaskDataDir};
 pub mod cache;
 pub mod source;
 pub mod target;
+#[cfg(test)]
+mod tests;
 
 lazy_static! {
     // 全局环境变量的列表
@@ -611,10 +614,24 @@ pub enum ExecutorError {
 }
 
 /// # 准备全局环境变量
-pub fn prepare_env(sched_entities: &SchedEntities) -> Result<(), ExecutorError> {
+pub fn prepare_env(
+    sched_entities: &SchedEntities,
+    execute_ctx: &Arc<DadkExecuteContext>,
+) -> Result<(), ExecutorError> {
     info!("Preparing environment variables...");
-    // 获取当前全局环境变量列表
-    let mut env_list = ENV_LIST.write().unwrap();
+    let env_list = create_global_env_list(sched_entities, execute_ctx)?;
+    // 写入全局环境变量列表
+    let mut global_env_list = ENV_LIST.write().unwrap();
+    *global_env_list = env_list;
+    return Ok(());
+}
+
+/// # 创建全局环境变量列表
+fn create_global_env_list(
+    sched_entities: &SchedEntities,
+    execute_ctx: &Arc<DadkExecuteContext>,
+) -> Result<EnvMap, ExecutorError> {
+    let mut env_list = EnvMap::new();
     let envs: Vars = std::env::vars();
     env_list.add_vars(envs);
 
@@ -640,99 +657,9 @@ pub fn prepare_env(sched_entities: &SchedEntities) -> Result<(), ExecutorError>
         }
     }
 
-    // 查看环境变量列表
-    // debug!("Environment variables:");
-
-    // for (key, value) in env_list.envs.iter() {
-    //     debug!("{}: {}", key, value.value);
-    // }
-
-    return Ok(());
-}
-
-#[cfg(test)]
-mod tests {
-    use std::path::PathBuf;
-
-    use test_base::test_context::{self as test_context, test_context};
-
-    use crate::{
-        context::{DadkExecuteContextTestBuildV1, TestContextExt},
-        executor::Executor,
-        parser::Parser,
-        scheduler::Scheduler,
-    };
-
-    fn setup_executor<T: TestContextExt>(config_file: PathBuf, ctx: &T) -> Executor {
-        let task = Parser::new(ctx.base_context().config_v1_dir()).parse_config_file(&config_file);
-        assert!(task.is_ok(), "parse error: {:?}", task);
-        let scheduler = Scheduler::new(
-            ctx.base_context().fake_dragonos_sysroot(),
-            *ctx.execute_context().action(),
-            vec![],
-        );
-
-        assert!(scheduler.is_ok(), "Create scheduler error: {:?}", scheduler);
-
-        let mut scheduler = scheduler.unwrap();
-
-        let entity = scheduler.add_task(config_file, task.unwrap());
-
-        assert!(entity.is_ok(), "Add task error: {:?}", entity);
-        let entity = entity.unwrap();
-        let executor = Executor::new(
-            entity.clone(),
-            *ctx.execute_context().action(),
-            ctx.base_context().fake_dragonos_sysroot(),
-        );
-
-        assert!(executor.is_ok(), "Create executor error: {:?}", executor);
-
-        let executor = executor.unwrap();
-        return executor;
-    }
-
-    /// 测试能否正确设置本地环境变量
-    #[test_context(DadkExecuteContextTestBuildV1)]
-    #[test]
-    fn set_local_env(ctx: &DadkExecuteContextTestBuildV1) {
-        let config_file_path = ctx
-            .base_context()
-            .config_v1_dir()
-            .join("app_normal_with_env_0_1_0.dadk");
-        let mut executor = setup_executor(config_file_path, ctx);
-
-        let r = executor.prepare_local_env();
-        assert!(r.is_ok(), "Prepare local env error: {:?}", r);
-        assert_ne!(executor.local_envs.envs.len(), 0);
-
-        assert!(executor.local_envs.get("DADK_CURRENT_BUILD_DIR").is_some());
-        assert!(executor.local_envs.get("CC").is_some());
-        assert_eq!(executor.local_envs.get("CC").unwrap().value, "abc-gcc");
-
-        let x = executor.execute();
-        assert!(x.is_ok(), "Execute error: {:?}", x);
-    }
+    // 创建ARCH环境变量
+    let target_arch = execute_ctx.target_arch();
+    env_list.add(EnvVar::new("ARCH".to_string(), (*target_arch).into()));
 
-    /// 测试执行错误时,能否感知到错误
-    #[test_context(DadkExecuteContextTestBuildV1)]
-    #[test]
-    fn execute_should_capture_error(ctx: &DadkExecuteContextTestBuildV1) {
-        let config_file_path = ctx
-            .base_context()
-            .config_v1_dir()
-            .join("app_normal_with_env_fail_0_1_0.dadk");
-        let mut executor = setup_executor(config_file_path, ctx);
-
-        let r = executor.prepare_local_env();
-        assert!(r.is_ok(), "Prepare local env error: {:?}", r);
-        assert_ne!(executor.local_envs.envs.len(), 0);
-
-        assert!(executor.local_envs.get("DADK_CURRENT_BUILD_DIR").is_some());
-        assert!(executor.local_envs.get("CC").is_some());
-        assert_eq!(executor.local_envs.get("CC").unwrap().value, "abc-gcc1");
-
-        let x = executor.execute();
-        assert!(x.is_err(), "Executor cannot catch error when build error");
-    }
+    return Ok(env_list);
 }

+ 119 - 0
src/executor/tests.rs

@@ -0,0 +1,119 @@
+use std::path::PathBuf;
+use test_base::test_context::{self as test_context, test_context};
+
+use crate::{
+    context::{
+        DadkExecuteContextTestBuildRiscV64V1, DadkExecuteContextTestBuildX86_64V1, TestContextExt,
+    },
+    executor::Executor,
+    parser::Parser,
+    scheduler::{SchedEntities, Scheduler},
+};
+
+use super::create_global_env_list;
+
+fn setup_executor<T: TestContextExt>(config_file: PathBuf, ctx: &T) -> Executor {
+    let task = Parser::new(ctx.base_context().config_v1_dir()).parse_config_file(&config_file);
+    assert!(task.is_ok(), "parse error: {:?}", task);
+    let scheduler = Scheduler::new(
+        ctx.execute_context().self_ref().unwrap(),
+        ctx.base_context().fake_dragonos_sysroot(),
+        *ctx.execute_context().action(),
+        vec![],
+    );
+
+    assert!(scheduler.is_ok(), "Create scheduler error: {:?}", scheduler);
+
+    let mut scheduler = scheduler.unwrap();
+
+    let entity = scheduler.add_task(config_file, task.unwrap());
+
+    assert!(entity.is_ok(), "Add task error: {:?}", entity);
+    let entity = entity.unwrap();
+    let executor = Executor::new(
+        entity.clone(),
+        *ctx.execute_context().action(),
+        ctx.base_context().fake_dragonos_sysroot(),
+    );
+
+    assert!(executor.is_ok(), "Create executor error: {:?}", executor);
+
+    let executor = executor.unwrap();
+    return executor;
+}
+
+/// 测试能否正确设置本地环境变量
+#[test_context(DadkExecuteContextTestBuildX86_64V1)]
+#[test]
+fn set_local_env(ctx: &DadkExecuteContextTestBuildX86_64V1) {
+    let config_file_path = ctx
+        .base_context()
+        .config_v1_dir()
+        .join("app_normal_with_env_0_1_0.dadk");
+    let mut executor = setup_executor(config_file_path, ctx);
+
+    let r = executor.prepare_local_env();
+    assert!(r.is_ok(), "Prepare local env error: {:?}", r);
+    assert_ne!(executor.local_envs.envs.len(), 0);
+
+    assert!(executor.local_envs.get("DADK_CURRENT_BUILD_DIR").is_some());
+    assert!(executor.local_envs.get("CC").is_some());
+    assert_eq!(executor.local_envs.get("CC").unwrap().value, "abc-gcc");
+
+    let x = executor.execute();
+    assert!(x.is_ok(), "Execute error: {:?}", x);
+}
+
+/// 测试执行错误时,能否感知到错误
+#[test_context(DadkExecuteContextTestBuildX86_64V1)]
+#[test]
+fn execute_should_capture_error(ctx: &DadkExecuteContextTestBuildX86_64V1) {
+    let config_file_path = ctx
+        .base_context()
+        .config_v1_dir()
+        .join("app_normal_with_env_fail_0_1_0.dadk");
+    let mut executor = setup_executor(config_file_path, ctx);
+
+    let r = executor.prepare_local_env();
+    assert!(r.is_ok(), "Prepare local env error: {:?}", r);
+    assert_ne!(executor.local_envs.envs.len(), 0);
+
+    assert!(executor.local_envs.get("DADK_CURRENT_BUILD_DIR").is_some());
+    assert!(executor.local_envs.get("CC").is_some());
+    assert_eq!(executor.local_envs.get("CC").unwrap().value, "abc-gcc1");
+
+    let x = executor.execute();
+    assert!(x.is_err(), "Executor cannot catch error when build error");
+}
+
+/// 测试能否正确设置ARCH全局环境变量为x86_64
+#[test_context(DadkExecuteContextTestBuildX86_64V1)]
+#[test]
+fn check_arch_env_x86_64(ctx: &DadkExecuteContextTestBuildX86_64V1) {
+    let entities = SchedEntities::new();
+    let env_list = create_global_env_list(&entities, &ctx.execute_context().self_ref().unwrap());
+    assert!(
+        env_list.is_ok(),
+        "Create global env list error: {:?}",
+        env_list
+    );
+    let env_list = env_list.unwrap();
+    assert!(env_list.get("ARCH").is_some());
+    assert_eq!(env_list.get("ARCH").unwrap().value, "x86_64");
+}
+
+/// 测试能否正确设置ARCH全局环境变量为riscv64
+#[test_context(DadkExecuteContextTestBuildRiscV64V1)]
+#[test]
+fn check_arch_env_riscv64(ctx: &DadkExecuteContextTestBuildRiscV64V1) {
+    let entities = SchedEntities::new();
+    let env_list = create_global_env_list(&entities, &ctx.execute_context().self_ref().unwrap());
+    assert!(
+        env_list.is_ok(),
+        "Create global env list error: {:?}",
+        env_list
+    );
+    let env_list = env_list.unwrap();
+    assert!(env_list.get("ARCH").is_some());
+    assert_eq!(env_list.get("ARCH").unwrap().value, "riscv64");
+}

+ 7 - 3
src/lib.rs

@@ -93,7 +93,10 @@ extern crate serde;
 extern crate serde_json;
 extern crate simple_logger;
 
-use std::{path::PathBuf, process::exit};
+#[cfg(test)]
+extern crate test_base;
+
+use std::{path::PathBuf, process::exit, sync::Arc};
 
 use clap::Parser;
 
@@ -131,8 +134,8 @@ pub fn dadk_main() {
         .cache_dir(args.cache_dir)
         .build()
         .expect("Failed to build execute context");
-
-    context.init();
+    let context = Arc::new(context);
+    context.init(context.clone());
     // DragonOS sysroot在主机上的路径
 
     info!(
@@ -179,6 +182,7 @@ pub fn dadk_main() {
     // info!("Parsed tasks: {:?}", tasks);
 
     let scheduler = Scheduler::new(
+        context.clone(),
         context.sysroot_dir().cloned().unwrap(),
         *context.action(),
         tasks,

+ 2 - 54
src/parser/mod.rs

@@ -34,6 +34,8 @@ use log::{debug, error, info};
 use self::task::DADKTask;
 pub mod task;
 pub mod task_log;
+#[cfg(test)]
+mod tests;
 
 /// # 配置解析器
 ///
@@ -226,57 +228,3 @@ impl Parser {
         return Ok(task);
     }
 }
-
-#[cfg(test)]
-mod tests {
-    use test_base::{
-        test_context::{self as test_context, test_context},
-        BaseTestContext,
-    };
-    use tests::task::{BuildConfig, TaskType};
-
-    use crate::executor::source::LocalSource;
-
-    use super::*;
-
-    #[test_context(BaseTestContext)]
-    #[test]
-    fn parse_normal_v1(ctx: &mut BaseTestContext) {
-        let parser = Parser::new(ctx.config_v1_dir());
-        let config_file = ctx.config_v1_dir().join("app_normal_0_1_0.dadk");
-        let result = parser.parse_config_file(&config_file);
-
-        assert!(result.is_ok(), "Error: {:?}", result);
-
-        let result = result.unwrap();
-
-        assert_eq!(result.name, "app_normal");
-        assert_eq!(result.version, "0.1.0");
-        assert_eq!(result.description, "A normal app");
-
-        let expected_task_type = TaskType::BuildFromSource(task::CodeSource::Local(
-            LocalSource::new(PathBuf::from("tests/data/apps/app_normal")),
-        ));
-
-        assert_eq!(result.task_type, expected_task_type,);
-
-        assert_eq!(result.depends.len(), 0);
-
-        let expected_build_config: BuildConfig =
-            BuildConfig::new(Some("bash build.sh".to_string()));
-        assert_eq!(result.build, expected_build_config);
-
-        let expected_install_config = task::InstallConfig::new(Some(PathBuf::from("/")));
-
-        assert_eq!(result.install, expected_install_config);
-        let expected_clean_config = task::CleanConfig::new(None);
-
-        assert_eq!(result.clean, expected_clean_config);
-
-        assert!(result.envs.is_some());
-        assert_eq!(result.envs.as_ref().unwrap().len(), 0);
-
-        assert_eq!(result.build_once, false);
-        assert_eq!(result.install_once, false);
-    }
-}

+ 106 - 1
src/parser/task.rs

@@ -1,6 +1,6 @@
 use std::path::PathBuf;
 
-use serde::{Deserialize, Serialize};
+use serde::{Deserialize, Deserializer, Serialize};
 
 use crate::executor::source::{ArchiveSource, GitSource, LocalSource};
 
@@ -44,6 +44,9 @@ pub struct DADKTask {
     /// (可选) 是否只安装一次,如果为true,DADK会在安装成功后,不再重复安装。
     #[serde(default)]
     pub install_once: bool,
+
+    #[serde(default = "DADKTask::default_target_arch_vec")]
+    pub target_arch: Vec<TargetArch>,
 }
 
 impl DADKTask {
@@ -61,6 +64,7 @@ impl DADKTask {
         envs: Option<Vec<TaskEnv>>,
         build_once: bool,
         install_once: bool,
+        target_arch: Option<Vec<TargetArch>>,
     ) -> Self {
         Self {
             name,
@@ -75,9 +79,22 @@ impl DADKTask {
             envs,
             build_once,
             install_once,
+            target_arch: target_arch.unwrap_or_else(Self::default_target_arch_vec),
         }
     }
 
+    /// 默认的目标处理器架构
+    ///
+    /// 从环境变量`ARCH`中获取,如果没有设置,则默认为`x86_64`
+    pub fn default_target_arch() -> TargetArch {
+        let s = std::env::var("ARCH").unwrap_or("x86_64".to_string());
+        return TargetArch::try_from(s.as_str()).unwrap();
+    }
+
+    fn default_target_arch_vec() -> Vec<TargetArch> {
+        vec![Self::default_target_arch()]
+    }
+
     pub fn validate(&mut self) -> Result<(), String> {
         if self.name.is_empty() {
             return Err("name is empty".to_string());
@@ -92,6 +109,7 @@ impl DADKTask {
         self.clean.validate()?;
         self.validate_depends()?;
         self.validate_envs()?;
+        self.validate_target_arch()?;
 
         return Ok(());
     }
@@ -133,6 +151,13 @@ impl DADKTask {
         return Ok(());
     }
 
+    fn validate_target_arch(&self) -> Result<(), String> {
+        if self.target_arch.is_empty() {
+            return Err("target_arch is empty".to_string());
+        }
+        return Ok(());
+    }
+
     fn trim_envs(&mut self) {
         if let Some(envs) = &mut self.envs {
             for env in envs {
@@ -424,3 +449,83 @@ impl TaskEnv {
         return Ok(());
     }
 }
+
+/// 目标处理器架构
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub enum TargetArch {
+    Aarch64,
+    X86_64,
+    RiscV64,
+    RiscV32,
+}
+
+impl TargetArch {
+    /// 期望的目标处理器架构(如果修改了枚举,那一定要修改这里)
+    pub const EXPECTED: [&'static str; 4] = ["aarch64", "x86_64", "riscv64", "riscv32"];
+}
+
+impl Default for TargetArch {
+    fn default() -> Self {
+        TargetArch::X86_64
+    }
+}
+
+impl TryFrom<&str> for TargetArch {
+    type Error = String;
+
+    fn try_from(value: &str) -> Result<Self, Self::Error> {
+        match value.trim().to_ascii_lowercase().as_str() {
+            "aarch64" => Ok(TargetArch::Aarch64),
+            "x86_64" => Ok(TargetArch::X86_64),
+            "riscv64" => Ok(TargetArch::RiscV64),
+            "riscv32" => Ok(TargetArch::RiscV32),
+            _ => Err(format!("Unknown target arch: {}", value)),
+        }
+    }
+}
+
+impl Into<&str> for TargetArch {
+    fn into(self) -> &'static str {
+        match self {
+            TargetArch::Aarch64 => "aarch64",
+            TargetArch::X86_64 => "x86_64",
+            TargetArch::RiscV64 => "riscv64",
+            TargetArch::RiscV32 => "riscv32",
+        }
+    }
+}
+
+impl Into<String> for TargetArch {
+    fn into(self) -> String {
+        let x: &str = self.into();
+        x.to_string()
+    }
+}
+
+impl<'de> Deserialize<'de> for TargetArch {
+    fn deserialize<D>(deserializer: D) -> Result<TargetArch, D::Error>
+    where
+        D: Deserializer<'de>,
+    {
+        let s = String::deserialize(deserializer)?;
+
+        let r = TargetArch::try_from(s.as_str());
+        match r {
+            Ok(v) => Ok(v),
+            Err(_) => Err(serde::de::Error::invalid_value(
+                serde::de::Unexpected::Str(s.as_str()),
+                &format!("Expected one of {:?}", TargetArch::EXPECTED).as_str(),
+            )),
+        }
+    }
+}
+
+impl Serialize for TargetArch {
+    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+    where
+        S: serde::Serializer,
+    {
+        let string: String = Into::into(*self);
+        serializer.serialize_str(string.as_str())
+    }
+}

+ 104 - 0
src/parser/tests.rs

@@ -0,0 +1,104 @@
+use test_base::{
+    test_context::{self as test_context, test_context},
+    BaseTestContext,
+};
+use tests::task::{BuildConfig, TargetArch, TaskType};
+
+use crate::executor::source::LocalSource;
+
+use super::*;
+
+#[test_context(BaseTestContext)]
+#[test]
+fn parse_normal_v1(ctx: &mut BaseTestContext) {
+    let parser = Parser::new(ctx.config_v1_dir());
+    let config_file = ctx.config_v1_dir().join("app_normal_0_1_0.dadk");
+    let result = parser.parse_config_file(&config_file);
+
+    assert!(result.is_ok(), "Error: {:?}", result);
+
+    let result = result.unwrap();
+
+    assert_eq!(result.name, "app_normal");
+    assert_eq!(result.version, "0.1.0");
+    assert_eq!(result.description, "A normal app");
+
+    let expected_task_type = TaskType::BuildFromSource(task::CodeSource::Local(LocalSource::new(
+        PathBuf::from("tests/data/apps/app_normal"),
+    )));
+
+    assert_eq!(result.task_type, expected_task_type,);
+
+    assert_eq!(result.depends.len(), 0);
+
+    let expected_build_config: BuildConfig = BuildConfig::new(Some("bash build.sh".to_string()));
+    assert_eq!(result.build, expected_build_config);
+
+    let expected_install_config = task::InstallConfig::new(Some(PathBuf::from("/")));
+
+    assert_eq!(result.install, expected_install_config);
+    let expected_clean_config = task::CleanConfig::new(None);
+
+    assert_eq!(result.clean, expected_clean_config);
+
+    assert!(result.envs.is_some());
+    assert_eq!(result.envs.as_ref().unwrap().len(), 0);
+
+    assert_eq!(result.build_once, false);
+    assert_eq!(result.install_once, false);
+}
+
+#[test_context(BaseTestContext)]
+#[test]
+fn target_arch_field_has_one_v1(ctx: &mut BaseTestContext) {
+    let parser = Parser::new(ctx.config_v1_dir());
+    let config_file = ctx
+        .config_v1_dir()
+        .join("app_target_arch_x86_64_0_1_0.dadk");
+    let result = parser.parse_config_file(&config_file);
+
+    assert!(result.is_ok(), "Error: {:?}", result);
+
+    let result = result.unwrap();
+
+    assert_eq!(result.name, "app_target_arch_x86_64");
+    assert_eq!(result.version, "0.1.0");
+
+    assert_eq!(result.target_arch.len(), 1);
+    assert_eq!(result.target_arch[0], TargetArch::X86_64);
+}
+
+#[test_context(BaseTestContext)]
+#[test]
+fn target_arch_field_has_one_uppercase_v1(ctx: &mut BaseTestContext) {
+    let parser = Parser::new(ctx.config_v1_dir());
+    let config_file = ctx
+        .config_v1_dir()
+        .join("app_target_arch_x86_64_uppercase_0_1_0.dadk");
+    let result = parser.parse_config_file(&config_file);
+
+    assert!(result.is_ok(), "Error: {:?}", result);
+
+    let result = result.unwrap();
+
+    assert_eq!(result.name, "app_target_arch_x86_64_uppercase");
+    assert_eq!(result.version, "0.1.0");
+
+    assert_eq!(result.target_arch.len(), 1);
+    assert_eq!(result.target_arch[0], TargetArch::X86_64);
+}
+
+#[test_context(BaseTestContext)]
+#[test]
+fn target_arch_field_empty_should_failed_v1(ctx: &mut BaseTestContext) {
+    let parser = Parser::new(ctx.config_v1_dir());
+    let config_file = ctx
+        .config_v1_dir()
+        .join("app_target_arch_empty_should_fail_0_1_0.dadk");
+    let result = parser.parse_config_file(&config_file);
+
+    assert!(
+        result.is_err(),
+        "parse_config_file should return error when target_arch field in config file is empty"
+    );
+}

+ 33 - 2
src/scheduler/mod.rs

@@ -14,6 +14,7 @@ use log::{error, info};
 
 use crate::{
     console::Action,
+    context::DadkExecuteContext,
     executor::{target::Target, Executor},
     parser::task::DADKTask,
 };
@@ -21,6 +22,8 @@ use crate::{
 use self::task_deque::TASK_DEQUE;
 
 pub mod task_deque;
+#[cfg(test)]
+mod tests;
 
 lazy_static! {
     // 线程id与任务实体id映射表
@@ -262,10 +265,14 @@ pub struct Scheduler {
     action: Action,
     /// 调度实体列表
     target: SchedEntities,
+    /// dadk执行的上下文
+    context: Arc<DadkExecuteContext>,
 }
 
 pub enum SchedulerError {
     TaskError(String),
+    /// 不是当前正在编译的目标架构
+    InvalidTargetArch(String),
     DependencyNotFound(Arc<SchedEntity>, String),
     RunError(String),
 }
@@ -288,12 +295,16 @@ impl Debug for SchedulerError {
             SchedulerError::RunError(msg) => {
                 write!(f, "RunError: {}", msg)
             }
+            SchedulerError::InvalidTargetArch(msg) => {
+                write!(f, "InvalidTargetArch: {}", msg)
+            }
         }
     }
 }
 
 impl Scheduler {
     pub fn new(
+        context: Arc<DadkExecuteContext>,
         dragonos_dir: PathBuf,
         action: Action,
         tasks: Vec<(PathBuf, DADKTask)>,
@@ -304,6 +315,7 @@ impl Scheduler {
             dragonos_dir,
             action,
             target: entities,
+            context,
         };
 
         let r = scheduler.add_tasks(tasks);
@@ -320,12 +332,23 @@ impl Scheduler {
     /// 添加任务到调度器中,如果任务已经存在,则返回错误
     pub fn add_tasks(&mut self, tasks: Vec<(PathBuf, DADKTask)>) -> Result<(), SchedulerError> {
         for task in tasks {
-            self.add_task(task.0, task.1)?;
+            let e = self.add_task(task.0, task.1);
+            if e.is_err() {
+                if let Err(SchedulerError::InvalidTargetArch(_)) = &e {
+                    continue;
+                }
+                e?;
+            }
         }
 
         return Ok(());
     }
 
+    /// # 任务是否匹配当前目标架构
+    pub fn task_arch_matched(&self, task: &DADKTask) -> bool {
+        task.target_arch.contains(self.context.target_arch())
+    }
+
     /// # 添加一个任务
     ///
     /// 添加任务到调度器中,如果任务已经存在,则返回错误
@@ -334,6 +357,14 @@ impl Scheduler {
         path: PathBuf,
         task: DADKTask,
     ) -> Result<Arc<SchedEntity>, SchedulerError> {
+        if !self.task_arch_matched(&task) {
+            return Err(SchedulerError::InvalidTargetArch(format!(
+                "Task {} is not for target arch: {:?}",
+                task.name_version(),
+                self.context.target_arch()
+            )));
+        }
+
         let id: i32 = self.generate_task_id();
         let indegree: usize = 0;
         let children = Vec::new();
@@ -411,7 +442,7 @@ impl Scheduler {
     /// # 执行调度器中的所有任务
     pub fn run(&self) -> Result<(), SchedulerError> {
         // 准备全局环境变量
-        crate::executor::prepare_env(&self.target)
+        crate::executor::prepare_env(&self.target, &self.context)
             .map_err(|e| SchedulerError::RunError(format!("{:?}", e)))?;
 
         match self.action {

+ 181 - 0
src/scheduler/tests.rs

@@ -0,0 +1,181 @@
+use test_base::{
+    test_context::{self as test_context, test_context},
+    BaseTestContext,
+};
+
+use crate::{
+    context::{
+        DadkExecuteContextTestBuildRiscV64V1, DadkExecuteContextTestBuildX86_64V1, TestContextExt,
+    },
+    parser::{task::TargetArch, Parser},
+};
+
+use super::*;
+
+/// 不应在x86_64上运行仅限riscv64的任务
+#[test_context(DadkExecuteContextTestBuildX86_64V1)]
+#[test]
+fn should_not_run_task_only_riscv64_on_x86_64(ctx: &DadkExecuteContextTestBuildX86_64V1) {
+    let config_file = ctx
+        .base_context()
+        .config_v1_dir()
+        .join("app_target_arch_riscv64_only_0_1_0.dadk");
+    let task = Parser::new(ctx.base_context().config_v1_dir()).parse_config_file(&config_file);
+    assert!(task.is_ok(), "parse error: {:?}", task);
+    let task = task.unwrap();
+    assert!(
+        task.target_arch.len() == 1,
+        "target_arch length error: {:?}",
+        task
+    );
+    assert!(
+        task.target_arch[0] == TargetArch::RiscV64,
+        "target_arch should be riscv64: {:?}",
+        task
+    );
+
+    let scheduler = Scheduler::new(
+        ctx.execute_context().self_ref().unwrap(),
+        ctx.base_context().fake_dragonos_sysroot(),
+        *ctx.execute_context().action(),
+        vec![],
+    );
+
+    assert!(scheduler.is_ok(), "Create scheduler error: {:?}", scheduler);
+
+    let mut scheduler = scheduler.unwrap();
+
+    let entity = scheduler.add_task(config_file, task);
+    assert!(
+        entity.is_err(),
+        "Add task should return error: {:?}",
+        entity
+    );
+}
+
+/// 不应在riscv64上运行仅限x86_64的任务
+#[test_context(DadkExecuteContextTestBuildRiscV64V1)]
+#[test]
+fn should_not_run_task_only_x86_64_on_riscv64(ctx: &DadkExecuteContextTestBuildRiscV64V1) {
+    let config_file = ctx
+        .base_context()
+        .config_v1_dir()
+        .join("app_target_arch_x86_64_only_0_1_0.dadk");
+    let task = Parser::new(ctx.base_context().config_v1_dir()).parse_config_file(&config_file);
+    assert!(task.is_ok(), "parse error: {:?}", task);
+    let task = task.unwrap();
+    assert!(
+        task.target_arch.len() == 1,
+        "target_arch length error: {:?}",
+        task
+    );
+    assert!(
+        task.target_arch[0] == TargetArch::X86_64,
+        "target_arch should be x86_64: {:?}",
+        task
+    );
+
+    let scheduler = Scheduler::new(
+        ctx.execute_context().self_ref().unwrap(),
+        ctx.base_context().fake_dragonos_sysroot(),
+        *ctx.execute_context().action(),
+        vec![],
+    );
+
+    assert!(scheduler.is_ok(), "Create scheduler error: {:?}", scheduler);
+
+    let mut scheduler = scheduler.unwrap();
+
+    let entity = scheduler.add_task(config_file, task);
+    assert!(
+        entity.is_err(),
+        "Add task should return error: {:?}",
+        entity
+    );
+}
+
+/// 应在x86_64上运行包含x86_64的任务
+#[test_context(DadkExecuteContextTestBuildX86_64V1)]
+#[test]
+fn should_run_task_include_x86_64_on_x86_64(ctx: &DadkExecuteContextTestBuildX86_64V1) {
+    let config_file = ctx
+        .base_context()
+        .config_v1_dir()
+        .join("app_all_target_arch_0_1_0.dadk");
+    let task = Parser::new(ctx.base_context().config_v1_dir()).parse_config_file(&config_file);
+    assert!(task.is_ok(), "parse error: {:?}", task);
+    let task = task.unwrap();
+
+    assert!(
+        task.target_arch.contains(&TargetArch::X86_64),
+        "Cannot find target_arch x86_64: {:?}",
+        task
+    );
+
+    let scheduler = Scheduler::new(
+        ctx.execute_context().self_ref().unwrap(),
+        ctx.base_context().fake_dragonos_sysroot(),
+        *ctx.execute_context().action(),
+        vec![],
+    );
+
+    assert!(scheduler.is_ok(), "Create scheduler error: {:?}", scheduler);
+
+    let mut scheduler = scheduler.unwrap();
+
+    let entity = scheduler.add_task(config_file, task);
+    assert!(entity.is_ok(), "Add task should return ok: {:?}", entity);
+}
+
+/// 应在riscv64上运行包含riscv64的任务
+#[test_context(DadkExecuteContextTestBuildRiscV64V1)]
+#[test]
+fn should_run_task_include_riscv64_on_riscv64(ctx: &DadkExecuteContextTestBuildRiscV64V1) {
+    let config_file = ctx
+        .base_context()
+        .config_v1_dir()
+        .join("app_all_target_arch_0_1_0.dadk");
+    let task = Parser::new(ctx.base_context().config_v1_dir()).parse_config_file(&config_file);
+    assert!(task.is_ok(), "parse error: {:?}", task);
+    let task = task.unwrap();
+
+    assert!(
+        task.target_arch.contains(&TargetArch::RiscV64),
+        "Cannot find target_arch riscv64: {:?}",
+        task
+    );
+
+    let scheduler = Scheduler::new(
+        ctx.execute_context().self_ref().unwrap(),
+        ctx.base_context().fake_dragonos_sysroot(),
+        *ctx.execute_context().action(),
+        vec![],
+    );
+
+    assert!(scheduler.is_ok(), "Create scheduler error: {:?}", scheduler);
+
+    let mut scheduler = scheduler.unwrap();
+
+    let entity = scheduler.add_task(config_file, task);
+    assert!(entity.is_ok(), "Add task should return ok: {:?}", entity);
+}
+
+/// 确保文件 app_all_target_arch_0_1_0.dadk 包含了所有的目标架构
+#[test_context(BaseTestContext)]
+#[test]
+fn ensure_all_target_arch_testcase_v1(ctx: &BaseTestContext) {
+    let config_file = ctx.config_v1_dir().join("app_all_target_arch_0_1_0.dadk");
+    let task = Parser::new(ctx.config_v1_dir()).parse_config_file(&config_file);
+    assert!(task.is_ok(), "parse error: {:?}", task);
+    let task = task.unwrap();
+
+    for a in TargetArch::EXPECTED.iter() {
+        let target_arch = TargetArch::try_from(*a).unwrap();
+        assert!(
+            task.target_arch.contains(&target_arch),
+            "Cannot find target_arch '{:?}' in task: {:?}",
+            a,
+            task
+        );
+    }
+}

+ 34 - 0
tests/data/dadk_config_v1/app_all_target_arch_0_1_0.dadk

@@ -0,0 +1,34 @@
+{
+  "name": "app_all_target_arch_0_1_0",
+  "version": "0.1.0",
+  "description": "An app targets to all arch",
+  "rust_target": null,
+  "task_type": {
+    "BuildFromSource": {
+      "Git": {
+        "url": "1",
+        "branch": "1",
+        "revision": null
+      }
+    }
+  },
+  "depends": [],
+  "build": {
+    "build_command": "1"
+  },
+  "install": {
+    "in_dragonos_path": "/"
+  },
+  "clean": {
+    "clean_command": "1"
+  },
+  "envs": [],
+  "build_once": false,
+  "install_once": false,
+  "target_arch": [
+    "riscv64",
+    "riscv32",
+    "x86_64",
+    "aarch64"
+  ]
+}

+ 29 - 0
tests/data/dadk_config_v1/app_target_arch_empty_should_fail_0_1_0.dadk

@@ -0,0 +1,29 @@
+{
+  "name": "app_target_arch_empty_should_fail",
+  "version": "0.1.0",
+  "description": "An app targets empty, which should failed when parsing",
+  "rust_target": null,
+  "task_type": {
+    "BuildFromSource": {
+      "Git": {
+        "url": "1",
+        "branch": "1",
+        "revision": null
+      }
+    }
+  },
+  "depends": [],
+  "build": {
+    "build_command": "1"
+  },
+  "install": {
+    "in_dragonos_path": "/"
+  },
+  "clean": {
+    "clean_command": "1"
+  },
+  "envs": [],
+  "build_once": false,
+  "install_once": false,
+  "target_arch": []
+}

+ 31 - 0
tests/data/dadk_config_v1/app_target_arch_riscv64_only_0_1_0.dadk

@@ -0,0 +1,31 @@
+{
+  "name": "app_target_arch_riscv64_only",
+  "version": "0.1.0",
+  "description": "An app only target to riscv64",
+  "rust_target": null,
+  "task_type": {
+    "BuildFromSource": {
+      "Git": {
+        "url": "1",
+        "branch": "1",
+        "revision": null
+      }
+    }
+  },
+  "depends": [],
+  "build": {
+    "build_command": "1"
+  },
+  "install": {
+    "in_dragonos_path": "/"
+  },
+  "clean": {
+    "clean_command": "1"
+  },
+  "envs": [],
+  "build_once": false,
+  "install_once": false,
+  "target_arch": [
+    "riscv64"
+  ]
+}

+ 31 - 0
tests/data/dadk_config_v1/app_target_arch_x86_64_0_1_0.dadk

@@ -0,0 +1,31 @@
+{
+  "name": "app_target_arch_x86_64",
+  "version": "0.1.0",
+  "description": "An app targets x86_64",
+  "rust_target": null,
+  "task_type": {
+    "BuildFromSource": {
+      "Git": {
+        "url": "1",
+        "branch": "1",
+        "revision": null
+      }
+    }
+  },
+  "depends": [],
+  "build": {
+    "build_command": "1"
+  },
+  "install": {
+    "in_dragonos_path": "/"
+  },
+  "clean": {
+    "clean_command": "1"
+  },
+  "envs": [],
+  "build_once": false,
+  "install_once": false,
+  "target_arch": [
+    "x86_64"
+  ]
+}

+ 31 - 0
tests/data/dadk_config_v1/app_target_arch_x86_64_only_0_1_0.dadk

@@ -0,0 +1,31 @@
+{
+  "name": "app_target_arch_x86_64_only",
+  "version": "0.1.0",
+  "description": "An app only target to x86_64",
+  "rust_target": null,
+  "task_type": {
+    "BuildFromSource": {
+      "Git": {
+        "url": "1",
+        "branch": "1",
+        "revision": null
+      }
+    }
+  },
+  "depends": [],
+  "build": {
+    "build_command": "1"
+  },
+  "install": {
+    "in_dragonos_path": "/"
+  },
+  "clean": {
+    "clean_command": "1"
+  },
+  "envs": [],
+  "build_once": false,
+  "install_once": false,
+  "target_arch": [
+    "x86_64"
+  ]
+}

+ 31 - 0
tests/data/dadk_config_v1/app_target_arch_x86_64_uppercase_0_1_0.dadk

@@ -0,0 +1,31 @@
+{
+  "name": "app_target_arch_x86_64_uppercase",
+  "version": "0.1.0",
+  "description": "An app targets x86_64(upper case and empty space)",
+  "rust_target": null,
+  "task_type": {
+    "BuildFromSource": {
+      "Git": {
+        "url": "1",
+        "branch": "1",
+        "revision": null
+      }
+    }
+  },
+  "depends": [],
+  "build": {
+    "build_command": "1"
+  },
+  "install": {
+    "in_dragonos_path": "/"
+  },
+  "clean": {
+    "clean_command": "1"
+  },
+  "envs": [],
+  "build_once": false,
+  "install_once": false,
+  "target_arch": [
+    "X86_64 "
+  ]
+}

+ 1 - 21
tests/parser.rs

@@ -1,21 +1 @@
-use log::error;
-use test_base::{
-    test_context::{self as test_context, test_context},
-    BaseTestContext,
-};
-
-const CONFIG_V1_DIR: &str = "tests/data/dadk_config_v1";
-
-#[test_context(BaseTestContext)]
-#[test]
-fn test_parser(ctx: &mut BaseTestContext) {
-    let mut parser = dadk::parser::Parser::new(ctx.abs_path(CONFIG_V1_DIR));
-    let result = parser.parse();
-    let cwd = std::env::current_dir().unwrap();
-
-    log::debug!("Current working directory: {:?}", cwd);
-    if let Err(e) = result {
-        error!("Error: {:?}", e);
-        assert!(false);
-    }
-}
+// todo: 添加集成测试