diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-05-10 00:32:08 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-05-10 00:32:08 +0900 |
| commit | 8cc1ba8a02c0318b65658f1634de378c780392b9 (patch) | |
| tree | fdd5cb61e488018891a486b25991b87c84220bb8 /crates/mozart-vcs/src/driver/mod.rs | |
| parent | 72b2e877c01e67ba7edd37e34ac2eadb7a1c62c4 (diff) | |
| download | php-mozart-8cc1ba8a02c0318b65658f1634de378c780392b9.tar.gz php-mozart-8cc1ba8a02c0318b65658f1634de378c780392b9.tar.zst php-mozart-8cc1ba8a02c0318b65658f1634de378c780392b9.zip | |
refactor(workspace): consolidate crates into mozart-core
Merged mozart-archiver, mozart-autoload, mozart-registry,
mozart-sat-resolver, and mozart-vcs into mozart-core to align
the source layout with Composer's structure.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'crates/mozart-vcs/src/driver/mod.rs')
| -rw-r--r-- | crates/mozart-vcs/src/driver/mod.rs | 309 |
1 files changed, 0 insertions, 309 deletions
diff --git a/crates/mozart-vcs/src/driver/mod.rs b/crates/mozart-vcs/src/driver/mod.rs deleted file mode 100644 index cfaf11e..0000000 --- a/crates/mozart-vcs/src/driver/mod.rs +++ /dev/null @@ -1,309 +0,0 @@ -pub mod bitbucket; -pub mod forgejo; -pub mod git; -pub mod github; -pub mod gitlab; -pub mod hg; -pub mod svn; - -use std::collections::BTreeMap; -use std::path::PathBuf; - -use anyhow::Result; -use serde::{Deserialize, Serialize}; - -/// Reference to a source distribution. -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct SourceReference { - #[serde(rename = "type")] - pub source_type: String, - pub url: String, - pub reference: String, -} - -/// Reference to a dist (archive) distribution. -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct DistReference { - #[serde(rename = "type")] - pub dist_type: String, - pub url: String, - pub reference: String, - pub shasum: Option<String>, -} - -/// Configuration passed to VCS drivers. -#[derive(Debug, Clone)] -pub struct DriverConfig { - /// Composer's `cache-vcs-dir`: root for VCS mirrors, one - /// subdirectory per sanitized repository URL. - pub cache_vcs_dir: PathBuf, - /// GitHub OAuth token (from `GITHUB_TOKEN` or config). - pub github_token: Option<String>, - /// GitLab OAuth token. - pub gitlab_token: Option<String>, - /// Bitbucket OAuth consumer key/secret. - pub bitbucket_oauth: Option<(String, String)>, - /// Forgejo token. - pub forgejo_token: Option<String>, - /// Custom GitLab domains (for self-hosted). - pub gitlab_domains: Vec<String>, - /// Custom Forgejo domains (for self-hosted). - pub forgejo_domains: Vec<String>, -} - -impl Default for DriverConfig { - fn default() -> Self { - Self { - cache_vcs_dir: default_cache_vcs_dir(), - github_token: None, - gitlab_token: None, - bitbucket_oauth: None, - forgejo_token: None, - gitlab_domains: vec!["gitlab.com".to_string()], - forgejo_domains: vec!["codeberg.org".to_string()], - } - } -} - -/// Resolve the default `cache-vcs-dir`, honoring Composer's env vars. -/// -/// Priority: `COMPOSER_CACHE_VCS_DIR` → `COMPOSER_CACHE_DIR/vcs` → -/// `XDG_CACHE_HOME/mozart/vcs` → `$HOME/.cache/mozart/vcs`. -fn default_cache_vcs_dir() -> PathBuf { - if let Ok(p) = std::env::var("COMPOSER_CACHE_VCS_DIR") { - return PathBuf::from(p); - } - let base = if let Ok(p) = std::env::var("COMPOSER_CACHE_DIR") { - PathBuf::from(p) - } else if let Ok(xdg) = std::env::var("XDG_CACHE_HOME") { - PathBuf::from(xdg).join("mozart") - } else if let Ok(home) = std::env::var("HOME") { - PathBuf::from(home).join(".cache").join("mozart") - } else { - PathBuf::from("/tmp").join("mozart") - }; - base.join("vcs") -} - -/// Type of VCS driver. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum DriverType { - GitHub, - GitLab, - Bitbucket, - Forgejo, - Git, - Svn, - Hg, -} - -/// The VCS driver interface. -/// -/// Corresponds to Composer's `VcsDriverInterface`. -trait VcsDriver { - /// Initialize the driver (e.g., clone mirror, fetch API metadata). - async fn initialize(&mut self) -> Result<()>; - - /// The root identifier (default branch/trunk). - fn root_identifier(&self) -> &str; - - /// All branches as `name -> commit_hash`. - async fn branches(&mut self) -> Result<&BTreeMap<String, String>>; - - /// All tags as `name -> commit_hash`. - async fn tags(&mut self) -> Result<&BTreeMap<String, String>>; - - /// Get composer.json content parsed as JSON for a given identifier. - async fn composer_information(&mut self, identifier: &str) - -> Result<Option<serde_json::Value>>; - - /// Get raw file content at a given path and identifier. - async fn file_content(&self, file: &str, identifier: &str) -> Result<Option<String>>; - - /// Get the change date for a given identifier (ISO 8601). - async fn change_date(&self, identifier: &str) -> Result<Option<String>>; - - /// Get the dist reference for a given identifier. - async fn dist(&self, identifier: &str) -> Result<Option<DistReference>>; - - /// Get the source reference for a given identifier. - fn source(&self, identifier: &str) -> SourceReference; - - /// The canonical URL of this repository. - fn url(&self) -> &str; - - /// Clean up resources (temp dirs, etc.). - async fn cleanup(&mut self) -> Result<()>; -} - -/// Enum-dispatched VCS driver. -/// -/// Wraps all concrete driver types to allow static dispatch with async trait methods. -pub enum AnyVcsDriver { - GitHub(github::GitHubDriver), - GitLab(gitlab::GitLabDriver), - Bitbucket(bitbucket::BitbucketDriver), - Forgejo(forgejo::ForgejoDriver), - Git(git::GitDriver), - Svn(svn::SvnDriver), - Hg(hg::HgDriver), -} - -macro_rules! dispatch { - ($self:expr, $method:ident $(, $arg:expr)*) => { - match $self { - AnyVcsDriver::GitHub(d) => d.$method($($arg),*), - AnyVcsDriver::GitLab(d) => d.$method($($arg),*), - AnyVcsDriver::Bitbucket(d) => d.$method($($arg),*), - AnyVcsDriver::Forgejo(d) => d.$method($($arg),*), - AnyVcsDriver::Git(d) => d.$method($($arg),*), - AnyVcsDriver::Svn(d) => d.$method($($arg),*), - AnyVcsDriver::Hg(d) => d.$method($($arg),*), - } - }; -} - -macro_rules! dispatch_async { - ($self:expr, $method:ident $(, $arg:expr)*) => { - match $self { - AnyVcsDriver::GitHub(d) => d.$method($($arg),*).await, - AnyVcsDriver::GitLab(d) => d.$method($($arg),*).await, - AnyVcsDriver::Bitbucket(d) => d.$method($($arg),*).await, - AnyVcsDriver::Forgejo(d) => d.$method($($arg),*).await, - AnyVcsDriver::Git(d) => d.$method($($arg),*).await, - AnyVcsDriver::Svn(d) => d.$method($($arg),*).await, - AnyVcsDriver::Hg(d) => d.$method($($arg),*).await, - } - }; -} - -impl AnyVcsDriver { - pub async fn initialize(&mut self) -> Result<()> { - dispatch_async!(self, initialize) - } - - pub fn root_identifier(&self) -> &str { - dispatch!(self, root_identifier) - } - - pub async fn branches(&mut self) -> Result<&BTreeMap<String, String>> { - dispatch_async!(self, branches) - } - - pub async fn tags(&mut self) -> Result<&BTreeMap<String, String>> { - dispatch_async!(self, tags) - } - - pub async fn composer_information( - &mut self, - identifier: &str, - ) -> Result<Option<serde_json::Value>> { - dispatch_async!(self, composer_information, identifier) - } - - pub async fn file_content(&self, file: &str, identifier: &str) -> Result<Option<String>> { - dispatch_async!(self, file_content, file, identifier) - } - - pub async fn change_date(&self, identifier: &str) -> Result<Option<String>> { - dispatch_async!(self, change_date, identifier) - } - - pub async fn dist(&self, identifier: &str) -> Result<Option<DistReference>> { - dispatch_async!(self, dist, identifier) - } - - pub fn source(&self, identifier: &str) -> SourceReference { - dispatch!(self, source, identifier) - } - - pub fn url(&self) -> &str { - dispatch!(self, url) - } - - pub async fn cleanup(&mut self) -> Result<()> { - dispatch_async!(self, cleanup) - } -} - -/// Detect which driver type should handle a given URL. -/// -/// Priority order matches Composer: -/// 1. GitHub → 2. GitLab → 3. Bitbucket → 4. Forgejo → 5. Git → 6. Hg → 7. SVN -pub fn detect_driver( - url: &str, - forced_type: Option<&str>, - config: &DriverConfig, -) -> Option<DriverType> { - if let Some(t) = forced_type { - return match t { - "github" => Some(DriverType::GitHub), - "gitlab" => Some(DriverType::GitLab), - "bitbucket" => Some(DriverType::Bitbucket), - "forgejo" => Some(DriverType::Forgejo), - "git" => Some(DriverType::Git), - "svn" => Some(DriverType::Svn), - "hg" | "mercurial" => Some(DriverType::Hg), - _ => None, - }; - } - - let url_lower = url.to_lowercase(); - - // GitHub - if github::GitHubDriver::supports(url) { - return Some(DriverType::GitHub); - } - - // GitLab - if gitlab::GitLabDriver::supports(url, &config.gitlab_domains) { - return Some(DriverType::GitLab); - } - - // Bitbucket - if bitbucket::BitbucketDriver::supports(url) { - return Some(DriverType::Bitbucket); - } - - // Forgejo - if forgejo::ForgejoDriver::supports(url, &config.forgejo_domains) { - return Some(DriverType::Forgejo); - } - - // Git - if git::GitDriver::supports(url) { - return Some(DriverType::Git); - } - - // Hg - if hg::HgDriver::supports(url) { - return Some(DriverType::Hg); - } - - // SVN - if url_lower.contains("svn") || svn::SvnDriver::supports(url) { - return Some(DriverType::Svn); - } - - // Default to git for generic URLs - if url.starts_with("http://") || url.starts_with("https://") { - return Some(DriverType::Git); - } - - None -} - -/// Create a driver instance for the given URL and type. -pub fn create_driver(url: &str, driver_type: DriverType, config: DriverConfig) -> AnyVcsDriver { - match driver_type { - DriverType::GitHub => AnyVcsDriver::GitHub(github::GitHubDriver::new(url, config)), - DriverType::GitLab => AnyVcsDriver::GitLab(gitlab::GitLabDriver::new(url, config)), - DriverType::Bitbucket => { - AnyVcsDriver::Bitbucket(bitbucket::BitbucketDriver::new(url, config)) - } - DriverType::Forgejo => AnyVcsDriver::Forgejo(forgejo::ForgejoDriver::new(url, config)), - DriverType::Git => AnyVcsDriver::Git(git::GitDriver::new(url, config)), - DriverType::Svn => AnyVcsDriver::Svn(svn::SvnDriver::new(url, config)), - DriverType::Hg => AnyVcsDriver::Hg(hg::HgDriver::new(url, config)), - } -} |
