From 075702a0c4beeab42d60b2a527392008d1d8cc8c Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Fri, 8 Mar 2024 10:58:54 +0530 Subject: [PATCH] feat: support for automatic update KCL dependencies on kcl.mod file save Signed-off-by: Abhishek Kumar --- kclvm/Cargo.lock | 22 +++++++++++++- kclvm/driver/Cargo.toml | 1 + kclvm/driver/src/kpm.rs | 64 ++++++++++++++++++++++++++++++++++++++--- 3 files changed, 82 insertions(+), 5 deletions(-) diff --git a/kclvm/Cargo.lock b/kclvm/Cargo.lock index 82655fa99..c384bc1fa 100644 --- a/kclvm/Cargo.lock +++ b/kclvm/Cargo.lock @@ -1661,6 +1661,7 @@ dependencies = [ "kclvm-parser", "kclvm-runtime", "kclvm-utils", + "notify 6.1.1", "serde", "serde_json", "walkdir", @@ -2194,6 +2195,25 @@ dependencies = [ "windows-sys 0.42.0", ] +[[package]] +name = "notify" +version = "6.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6205bd8bb1e454ad2e27422015fb5e4f2bcc7e08fa8f27058670d208324a4d2d" +dependencies = [ + "bitflags 2.3.3", + "crossbeam-channel", + "filetime", + "fsevent-sys", + "inotify", + "kqueue", + "libc", + "log", + "mio", + "walkdir", + "windows-sys 0.48.0", +] + [[package]] name = "num-bigint" version = "0.4.3" @@ -2733,7 +2753,7 @@ checksum = "a680f2dbd796844ebeaa2a4d01ae209f412ddc2981f6512ab8bc9b471156e6cd" dependencies = [ "crossbeam-channel", "jod-thread", - "notify", + "notify 5.1.0", "ra_ap_paths", "ra_ap_vfs", "tracing", diff --git a/kclvm/driver/Cargo.toml b/kclvm/driver/Cargo.toml index 9d60f138f..dcd1943e6 100644 --- a/kclvm/driver/Cargo.toml +++ b/kclvm/driver/Cargo.toml @@ -7,6 +7,7 @@ edition = "2021" [dependencies] serde_json = "1.0.86" +notify = "6.1.1" kclvm-config ={ path = "../config"} kclvm-runtime ={ path = "../runtime"} diff --git a/kclvm/driver/src/kpm.rs b/kclvm/driver/src/kpm.rs index 1d0ec7a29..64a4f5a3a 100644 --- a/kclvm/driver/src/kpm.rs +++ b/kclvm/driver/src/kpm.rs @@ -1,10 +1,11 @@ -use crate::kcl; -use crate::lookup_the_nearest_file_dir; use anyhow::{bail, Result}; +use notify::{RecursiveMode, Watcher}; +use serde::{Deserialize, Serialize}; +use std::{collections::HashMap, path::PathBuf, process::Command, sync::mpsc::channel}; + +use crate::{kcl, lookup_the_nearest_file_dir}; use kclvm_config::modfile::KCL_MOD_FILE; use kclvm_parser::LoadProgramOptions; -use serde::{Deserialize, Serialize}; -use std::{collections::HashMap, path::PathBuf, process::Command}; /// [`fill_pkg_maps_for_k_file`] will call `kpm metadata` to obtain the metadata /// of all dependent packages of the kcl package where the current file is located, @@ -107,3 +108,58 @@ pub fn update_dependencies(work_dir: PathBuf) -> Result<()> { ), } } + +/// Monitor changes to the kcl.mod file and automatically update dependencies. +pub fn watch_kcl_mod(directory: PathBuf) -> Result<()> { + let (sender, receiver) = channel(); + let mut watcher = notify::recommended_watcher(move |res| { + if let Err(err) = sender.send(res) { + eprintln!("Error sending event to channel: {:?}", err); + } + })?; + + watcher.watch(&directory, RecursiveMode::NonRecursive)?; + + loop { + match receiver.recv() { + Ok(event) => match event { + Ok(event) => match event.kind { + notify::event::EventKind::Modify(modify_kind) => { + if let notify::event::ModifyKind::Data(data_change) = modify_kind { + if data_change == notify::event::DataChange::Content { + println!("kcl.mod file content modified. Updating dependencies..."); + update_dependencies(directory.clone())?; // Pass directory to update_dependencies + } + } + } + _ => {} + }, + Err(err) => { + println!("Watcher error: {:?}", err); + } + }, + Err(e) => { + println!("Receiver error: {:?}", e); + } + } + } +} + +/// Tracking function for the kcl_mod_file change. +pub fn kcl_mod_file_track(work_dir: PathBuf) -> Result<()> { + let directory = match lookup_the_nearest_file_dir(work_dir.clone(), KCL_MOD_FILE) { + Some(mod_dir) => mod_dir, + None => { + eprintln!( + "Manifest file '{}' not found in directory hierarchy", + KCL_MOD_FILE + ); + return Ok(()); + } + }; + + if let Err(err) = watch_kcl_mod(directory) { + eprintln!("Error watching kcl.mod file: {:?}", err); + } + Ok(()) +}