From c028a9d5c737de5d2b259638a0a76b999364a262 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Sat, 6 Jun 2026 22:40:30 +0900 Subject: feat(vcs): implement VcsDriverInterface for all VCS drivers Reconcile the VcsDriverInterface trait with the concrete drivers so every driver implements it as in PHP, where each driver extends VcsDriver. - Make cache-mutating getters take &mut self in the trait, matching the inherent methods' lazy-cache semantics; update vcs_repository consumers. - Change supports() to take Rc> and return Result, completing GitDriver::supports deep ls-remote and its config wiring. - Add base get_composer_information to Git/Hg/Fossil/Perforce and an impl VcsDriverInterface block to every driver, delegating to inherent methods and absorbing type differences in the impl. Co-Authored-By: Claude Opus 4.8 (1M context) --- crates/shirabe/src/repository/vcs/git_driver.rs | 107 ++++++++++++++---------- 1 file changed, 65 insertions(+), 42 deletions(-) (limited to 'crates/shirabe/src/repository/vcs/git_driver.rs') diff --git a/crates/shirabe/src/repository/vcs/git_driver.rs b/crates/shirabe/src/repository/vcs/git_driver.rs index 01aa759..4878ffe 100644 --- a/crates/shirabe/src/repository/vcs/git_driver.rs +++ b/crates/shirabe/src/repository/vcs/git_driver.rs @@ -12,6 +12,7 @@ use shirabe_php_shim::{ use crate::cache::Cache; use crate::config::Config; +use crate::downloader::TransportException; use crate::io::IOInterface; use crate::io::IOInterfaceImmutable; use crate::repository::vcs::VcsDriverBase; @@ -19,6 +20,7 @@ use crate::util::Filesystem; use crate::util::Git as GitUtil; use crate::util::ProcessExecutor; use crate::util::Url; +use shirabe_php_shim::PhpMixed; #[derive(Debug)] pub struct GitDriver { @@ -401,7 +403,7 @@ impl GitDriver { pub fn supports( io: std::rc::Rc>, - _config: &Config, + config: std::rc::Rc>, url: &str, deep: bool, ) -> anyhow::Result { @@ -446,22 +448,15 @@ impl GitDriver { let process = std::rc::Rc::new(std::cell::RefCell::new(ProcessExecutor::new(Some( io.clone(), )))); - // TODO(phase-b): supports() takes &Config; GitUtil now needs Rc>. - // Skipping clean Rc construction since we cannot reconstruct one from a borrowed &Config. - let _ = _config; - return Err(anyhow::anyhow!( - "GitDriver::supports requires Rc>: not yet ported" - )); - #[allow(unreachable_code)] let mut git_util = GitUtil::new( io.clone(), - todo!(), + config.clone(), process.clone(), std::rc::Rc::new(std::cell::RefCell::new(Filesystem::new(None))), ); GitUtil::clean_env(&process); - let result = git_util.run_commands( + match git_util.run_commands( vec![vec![ "git".to_string(), "ls-remote".to_string(), @@ -473,63 +468,91 @@ impl GitDriver { Some(&sys_get_temp_dir()), false, None, - ); - match result { + ) { Ok(_) => Ok(true), - Err(_) => Ok(false), + Err(e) => { + if e.downcast_ref::().is_some() { + Ok(false) + } else { + Err(e) + } + } } } + + pub fn get_composer_information( + &mut self, + identifier: &str, + ) -> anyhow::Result>> { + if let Some(cached) = self.inner.read_cached_composer(identifier)? { + return Ok(cached); + } + + let file_content = self.get_file_content("composer.json", identifier)?; + let composer = + VcsDriverBase::finish_base_composer_information(identifier, file_content, || { + self.get_change_date(identifier) + })?; + + self.inner.write_cached_composer(identifier, composer) + } } -// TODO(phase-b): implement VcsDriverInterface for GitDriver — signatures here -// differ from the trait (some &mut self vs &self, different return shapes), so -// each method delegates via todo!() until reconciled. impl crate::repository::vcs::VcsDriverInterface for GitDriver { fn initialize(&mut self) -> anyhow::Result<()> { GitDriver::initialize(self) } fn get_composer_information( - &self, - _identifier: &str, - ) -> anyhow::Result>> { - todo!() + &mut self, + identifier: &str, + ) -> anyhow::Result>> { + GitDriver::get_composer_information(self, identifier) } - fn get_file_content(&self, _file: &str, _identifier: &str) -> anyhow::Result> { - todo!() + fn get_file_content(&mut self, file: &str, identifier: &str) -> anyhow::Result> { + GitDriver::get_file_content(self, file, identifier) } - fn get_change_date(&self, _identifier: &str) -> anyhow::Result>> { - todo!() + fn get_change_date(&mut self, identifier: &str) -> anyhow::Result>> { + GitDriver::get_change_date(self, identifier) } - fn get_root_identifier(&self) -> anyhow::Result { - todo!() + fn get_root_identifier(&mut self) -> anyhow::Result { + GitDriver::get_root_identifier(self) } - fn get_branches(&self) -> anyhow::Result> { - todo!() + fn get_branches(&mut self) -> anyhow::Result> { + GitDriver::get_branches(self) } - fn get_tags(&self) -> anyhow::Result> { - todo!() + fn get_tags(&mut self) -> anyhow::Result> { + GitDriver::get_tags(self) } - fn get_dist(&self, _identifier: &str) -> anyhow::Result>> { - todo!() + fn get_dist(&self, identifier: &str) -> anyhow::Result>> { + Ok(GitDriver::get_dist(self, identifier)) } - fn get_source(&self, _identifier: &str) -> anyhow::Result> { - todo!() + fn get_source(&self, identifier: &str) -> anyhow::Result> { + Ok(GitDriver::get_source(self, identifier)) } fn get_url(&self) -> String { GitDriver::get_url(self) } - fn has_composer_file(&self, _identifier: &str) -> anyhow::Result { - todo!() + fn has_composer_file(&mut self, identifier: &str) -> anyhow::Result { + match self.get_composer_information(identifier) { + Ok(info) => Ok(info.is_some()), + Err(e) => { + if e.downcast_ref::().is_some() { + Ok(false) + } else { + Err(e) + } + } + } } fn cleanup(&mut self) -> anyhow::Result<()> { @@ -537,11 +560,11 @@ impl crate::repository::vcs::VcsDriverInterface for GitDriver { } fn supports( - _io: std::rc::Rc>, - _config: &Config, - _url: &str, - _deep: bool, - ) -> bool { - todo!() + io: std::rc::Rc>, + config: std::rc::Rc>, + url: &str, + deep: bool, + ) -> anyhow::Result { + GitDriver::supports(io, config, url, deep) } } -- cgit v1.3.1