mod.rs 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. use std::{cell::OnceCell, path::PathBuf};
  2. use anyhow::Result;
  3. use clap::Parser;
  4. use dadk_config::{
  5. common::target_arch::TargetArch, manifest::DadkManifestFile, rootfs::RootFSConfigFile,
  6. };
  7. use derive_builder::Builder;
  8. use manifest::parse_manifest;
  9. use crate::{
  10. console::CommandLineArgs,
  11. utils::{abs_path, check_dir_exists},
  12. };
  13. mod manifest;
  14. /// DADK的执行上下文
  15. #[derive(Debug, Clone, Builder)]
  16. pub struct DADKExecContext {
  17. pub command: CommandLineArgs,
  18. /// DADK manifest file
  19. manifest: Option<DadkManifestFile>,
  20. /// RootFS config file
  21. rootfs: OnceCell<RootFSConfigFile>,
  22. }
  23. pub fn build_exec_context() -> Result<DADKExecContext> {
  24. let mut builder = DADKExecContextBuilder::create_empty();
  25. builder.command(CommandLineArgs::parse());
  26. builder.rootfs(OnceCell::new());
  27. if builder.command.as_ref().unwrap().action.needs_manifest() {
  28. parse_manifest(&mut builder).expect("Failed to parse manifest");
  29. } else {
  30. builder.manifest(None);
  31. }
  32. let ctx: DADKExecContext = builder.build()?;
  33. ctx.setup_workdir().expect("Failed to setup workdir");
  34. Ok(ctx)
  35. }
  36. impl DADKExecContext {
  37. /// 获取工作目录的绝对路径
  38. pub fn workdir(&self) -> PathBuf {
  39. abs_path(&PathBuf::from(&self.command.workdir))
  40. }
  41. /// 设置进程的工作目录
  42. fn setup_workdir(&self) -> Result<()> {
  43. std::env::set_current_dir(&self.workdir()).expect("Failed to set current directory");
  44. Ok(())
  45. }
  46. /// Get rootfs configuration
  47. pub fn rootfs(&self) -> &RootFSConfigFile {
  48. self.rootfs.get_or_init(|| {
  49. RootFSConfigFile::load(&self.manifest().metadata.rootfs_config)
  50. .expect("Failed to load rootfs config")
  51. })
  52. }
  53. pub fn manifest(&self) -> &DadkManifestFile {
  54. self.manifest.as_ref().unwrap()
  55. }
  56. /// Get sysroot directory
  57. ///
  58. /// If the directory does not exist, or the path is not a folder, an error is returned
  59. pub fn sysroot_dir(&self) -> Result<PathBuf> {
  60. check_dir_exists(&self.manifest().metadata.sysroot_dir)
  61. .map(|p| p.clone())
  62. .map_err(|e| anyhow::anyhow!("Failed to get sysroot dir: {}", e))
  63. }
  64. /// Get cache root directory
  65. ///
  66. /// If the directory does not exist, or the path is not a folder, an error is returned
  67. pub fn cache_root_dir(&self) -> Result<PathBuf> {
  68. check_dir_exists(&self.manifest().metadata.cache_root_dir)
  69. .map(|p| p.clone())
  70. .map_err(|e| anyhow::anyhow!("Failed to get cache root dir: {}", e))
  71. }
  72. #[deprecated]
  73. pub fn user_config_dir(&self) -> Result<PathBuf> {
  74. check_dir_exists(&self.manifest().metadata.user_config_dir)
  75. .map(|p| p.clone())
  76. .map_err(|e| anyhow::anyhow!("Failed to get user config dir: {}", e))
  77. }
  78. pub fn target_arch(&self) -> TargetArch {
  79. self.manifest().metadata.arch
  80. }
  81. /// 获取磁盘镜像的路径,路径由工作目录、架构和固定文件名组成
  82. pub fn disk_image_path(&self) -> PathBuf {
  83. self.workdir()
  84. .join(format!("bin/{}.img", self.disk_image_basename()))
  85. }
  86. /// 获取磁盘挂载路径
  87. pub fn disk_mount_path(&self) -> PathBuf {
  88. self.workdir()
  89. .join(format!("bin/mnt/{}", self.disk_image_basename()))
  90. }
  91. fn disk_image_basename(&self) -> String {
  92. let arch: String = self.target_arch().into();
  93. format!("disk-image-{}", arch)
  94. }
  95. /// 获取磁盘镜像大小
  96. pub fn disk_image_size(&self) -> usize {
  97. self.rootfs().metadata.size
  98. }
  99. }