From f60cc4eb0593781f9412d78e3277baddfff311bb Mon Sep 17 00:00:00 2001 From: LoGin Date: Sat, 16 Nov 2024 18:01:00 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=B0=86`last=5Fmodified=5Ftime`?= =?UTF-8?q?=E6=94=B9=E4=B8=BABFS=20&=20=E4=BF=AE=E6=AD=A3=E6=9C=AA?= =?UTF-8?q?=E5=88=A4=E6=96=AD=E6=96=87=E4=BB=B6=E5=A4=B9=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E6=97=B6=E9=97=B4=E7=9A=84bug=20(#84)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dadk-user/src/executor/mod.rs | 106 +++++++++++++++++++------------ dadk-user/src/parser/mod.rs | 4 +- dadk-user/src/parser/task_log.rs | 12 +++- dadk-user/src/utils/file.rs | 1 + 4 files changed, 79 insertions(+), 44 deletions(-) diff --git a/dadk-user/src/executor/mod.rs b/dadk-user/src/executor/mod.rs index f25e8ec..1e1ca36 100644 --- a/dadk-user/src/executor/mod.rs +++ b/dadk-user/src/executor/mod.rs @@ -1,5 +1,5 @@ use std::{ - collections::BTreeMap, + collections::{BTreeMap, VecDeque}, env::Vars, path::PathBuf, process::{Command, Stdio}, @@ -130,6 +130,7 @@ impl Executor { } else { task_log.set_install_status(InstallStatus::Failed); } + task_log.set_install_time_now(); } Action::Clean(_) => { @@ -175,7 +176,12 @@ impl Executor { fn build(&mut self) -> Result<(), ExecutorError> { if let Some(status) = self.task_log().build_status() { if let Some(build_time) = self.task_log().build_time() { - let last_modified = last_modified_time(&self.entity.file_path(), build_time)?; + let mut last_modified = last_modified_time(&self.entity.file_path(), build_time)?; + last_modified = core::cmp::max( + last_modified, + last_modified_time(&self.src_work_dir(), build_time)?, + ); + if *status == BuildStatus::Success && (self.entity.task().build_once || last_modified < *build_time) { @@ -212,21 +218,27 @@ impl Executor { } fn install(&self) -> Result<(), ExecutorError> { + log::trace!("dadk-user: install {}", self.entity.task().name_version()); if let Some(status) = self.task_log().install_status() { - if let Some(build_time) = self.task_log().build_time() { - let last_modified = last_modified_time(&self.entity.file_path(), build_time)?; + if let Some(install_time) = self.task_log().install_time() { + let last_modified = last_modified_time(&self.build_dir.path, install_time)?; + let last_modified = core::cmp::max( + last_modified, + last_modified_time(&self.entity.file_path(), install_time)?, + ); + if *status == InstallStatus::Success - && (self.entity.task().install_once || last_modified < *build_time) + && (self.entity.task().install_once || last_modified < *install_time) { info!( - "Task {} has been installed successfully, skip install.", + "install: Task {} not changed.", self.entity.task().name_version() ); return Ok(()); } } } - + log::trace!("dadk-user: to do install {}", self.entity.task().name_version()); return self.do_install(); } @@ -658,44 +670,58 @@ fn last_modified_time( path: &PathBuf, build_time: &DateTime, ) -> Result, ExecutorError> { - let metadata = path - .metadata() - .map_err(|e| ExecutorError::InstallError(e.to_string()))?; - - let last_modified = if metadata.is_dir() { - let mut last_modified = DateTime::::from(SystemTime::UNIX_EPOCH); - for r in std::fs::read_dir(path).unwrap() { - if let Ok(entry) = r { - // 忽略编译产物目录 - if entry.file_name() == "target" { - continue; - } + let mut queue = VecDeque::new(); + queue.push_back(path.clone()); + + let mut last_modified = DateTime::::from(SystemTime::UNIX_EPOCH); + + while let Some(current_path) = queue.pop_front() { + let metadata = current_path + .metadata() + .map_err(|e| ExecutorError::InstallError(e.to_string()))?; + + if metadata.is_dir() { + for r in std::fs::read_dir(¤t_path).unwrap() { + if let Ok(entry) = r { + // 忽略编译产物目录 + if entry.file_name() == "target" { + continue; + } - let metadata = entry.metadata().unwrap(); - if metadata.is_dir() { - // 如果是子目录,则递归找改子目录下的文件最后的更新时间 - last_modified = std::cmp::max( - last_modified, - last_modified_time(&entry.path(), build_time)?, - ); - } else { + let entry_path = entry.path(); + let entry_metadata = entry.metadata().unwrap(); // 比较文件的修改时间和last_modified,取最大值 - last_modified = std::cmp::max( - last_modified, - DateTime::::from(metadata.modified().unwrap()), - ); - } + let file_modified = DateTime::::from(entry_metadata.modified().unwrap()); + last_modified = std::cmp::max(last_modified, file_modified); - // 如果其中某一个文件的修改时间在build_time之后,则直接返回,不用继续递归 - if last_modified > *build_time { - return Ok(last_modified); + // 如果其中某一个文件的修改时间在build_time之后,则直接返回,不用继续搜索 + if last_modified > *build_time { + return Ok(last_modified); + } + + if entry_metadata.is_dir() { + // 如果是子目录,则将其加入队列 + queue.push_back(entry_path); + } } } + } else { + // 如果是文件,直接比较修改时间 + let file_modified = DateTime::::from(metadata.modified().unwrap()); + last_modified = std::cmp::max(last_modified, file_modified); + + // 如果其中某一个文件的修改时间在build_time之后,则直接返回,不用继续递归 + if last_modified > *build_time { + return Ok(last_modified); + } } - last_modified - } else { - DateTime::::from(metadata.modified().unwrap()) - }; + } - return Ok(last_modified); + if last_modified == DateTime::::from(SystemTime::UNIX_EPOCH) { + return Err(ExecutorError::InstallError(format!( + "Failed to get last modified time for path: {}", + path.display() + ))); + } + Ok(last_modified) } diff --git a/dadk-user/src/parser/mod.rs b/dadk-user/src/parser/mod.rs index e3de4fc..6997f97 100644 --- a/dadk-user/src/parser/mod.rs +++ b/dadk-user/src/parser/mod.rs @@ -175,7 +175,7 @@ impl Parser { continue; } let extension: &std::ffi::OsStr = extension.unwrap(); - if extension.to_ascii_lowercase() != "dadk" { + if extension.to_ascii_lowercase() != "toml" { continue; } // 找到一个配置文件, 加入列表 @@ -217,10 +217,10 @@ impl Parser { /// * `Ok(DADKTask)` - 生成好的任务 /// * `Err(ParserError)` - 解析错误 pub(super) fn parse_config_file(&self, config_file: &PathBuf) -> Result { + log::trace!("Parsing config file {}", config_file.display()); // 从toml文件中解析出DADKTask let mut task: DADKTask = Self::parse_toml_file(config_file)?; - debug!("Parsed config file {}: {:?}", config_file.display(), task); // 去除字符串中的空白字符 task.trim(); diff --git a/dadk-user/src/parser/task_log.rs b/dadk-user/src/parser/task_log.rs index 6d5ad0b..b09db2b 100644 --- a/dadk-user/src/parser/task_log.rs +++ b/dadk-user/src/parser/task_log.rs @@ -15,6 +15,7 @@ pub struct TaskLog { skip_serializing_if = "Option::is_none" )] build_timestamp: Option>, + install_timestamp: Option>, /// 任务构建状态 build_status: Option, /// 任务安装状态 @@ -36,6 +37,7 @@ impl TaskLog { Self { build_timestamp: None, build_status: None, + install_timestamp: None, install_status: None, } } @@ -45,16 +47,22 @@ impl TaskLog { self.build_timestamp = Some(time); } - #[allow(dead_code)] pub fn build_time(&self) -> Option<&DateTime> { self.build_timestamp.as_ref() } - #[allow(dead_code)] pub fn set_build_time_now(&mut self) { self.build_timestamp = Some(Utc::now()); } + pub fn install_time(&self) -> Option<&DateTime> { + self.install_timestamp.as_ref() + } + + pub fn set_install_time_now(&mut self) { + self.install_timestamp = Some(Utc::now()); + } + pub fn set_build_status(&mut self, status: BuildStatus) { self.build_status = Some(status); } diff --git a/dadk-user/src/utils/file.rs b/dadk-user/src/utils/file.rs index a67a143..af6d2dd 100644 --- a/dadk-user/src/utils/file.rs +++ b/dadk-user/src/utils/file.rs @@ -46,6 +46,7 @@ impl FileUtils { /// 递归地复制给定目录下所有文件到另一个文件夹中 pub fn copy_dir_all(src: &Path, dst: &Path) -> Result<(), String> { + log::trace!("FileUtils::copy_dir_all: src: {:?}, dst: {:?}", src, dst); let mut cmd = Command::new("cp"); cmd.arg("-r").arg("-f").arg("./").arg(dst);