aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/mozart-vcs
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-05-09 19:59:58 +0900
committernsfisis <nsfisis@gmail.com>2026-05-09 19:59:58 +0900
commit72b2e877c01e67ba7edd37e34ac2eadb7a1c62c4 (patch)
treeddccef3355d76f759b3cf43af0fcc3c8b79eaa6d /crates/mozart-vcs
parentf9671f2dcde92d5c037595d0d3f01396a8190970 (diff)
downloadphp-mozart-72b2e877c01e67ba7edd37e34ac2eadb7a1c62c4.tar.gz
php-mozart-72b2e877c01e67ba7edd37e34ac2eadb7a1c62c4.tar.zst
php-mozart-72b2e877c01e67ba7edd37e34ac2eadb7a1c62c4.zip
refactor(vcs): mirror Composer interfaces; rename get_local_changes
- Rename `local_changes` → `get_local_changes` to match Composer's `getLocalChanges` - Add `is_change_report`, `is_vcs_capable_downloader`, `is_dvcs_downloader` trait methods to replace PHP `instanceof` checks - Add `VersionParser` stub to keep `VersionGuesser::new` signature compatible with Composer's constructor - Add `ArrayDumper` in status.rs mirroring `Composer\Package\Dumper\ArrayDumper`; expand `build_package_config` to include all fields that `VersionGuesser` inspects
Diffstat (limited to 'crates/mozart-vcs')
-rw-r--r--crates/mozart-vcs/src/downloader/git.rs14
-rw-r--r--crates/mozart-vcs/src/downloader/hg.rs14
-rw-r--r--crates/mozart-vcs/src/downloader/mod.rs11
-rw-r--r--crates/mozart-vcs/src/downloader/svn.rs14
-rw-r--r--crates/mozart-vcs/src/version_guesser.rs26
-rw-r--r--crates/mozart-vcs/tests/git_driver_test.rs6
6 files changed, 76 insertions, 9 deletions
diff --git a/crates/mozart-vcs/src/downloader/git.rs b/crates/mozart-vcs/src/downloader/git.rs
index 0c78f89..814d67e 100644
--- a/crates/mozart-vcs/src/downloader/git.rs
+++ b/crates/mozart-vcs/src/downloader/git.rs
@@ -96,7 +96,7 @@ impl VcsDownloader for GitDownloader {
Ok(())
}
- fn local_changes(&self, target: &Path) -> Result<Option<String>> {
+ fn get_local_changes(&self, target: &Path) -> Result<Option<String>> {
if !target.join(".git").exists() {
return Ok(None);
}
@@ -223,6 +223,18 @@ impl VcsDownloader for GitDownloader {
)?;
Ok(output.stdout)
}
+
+ fn is_change_report(&self) -> bool {
+ true
+ }
+
+ fn is_vcs_capable_downloader(&self) -> bool {
+ true
+ }
+
+ fn is_dvcs_downloader(&self) -> bool {
+ true
+ }
}
fn collect_show_ref(process: &ProcessExecutor, target: &Path) -> Result<Option<String>> {
diff --git a/crates/mozart-vcs/src/downloader/hg.rs b/crates/mozart-vcs/src/downloader/hg.rs
index 926cfa8..3230404 100644
--- a/crates/mozart-vcs/src/downloader/hg.rs
+++ b/crates/mozart-vcs/src/downloader/hg.rs
@@ -45,7 +45,7 @@ impl VcsDownloader for HgDownloader {
Ok(())
}
- fn local_changes(&self, target: &Path) -> Result<Option<String>> {
+ fn get_local_changes(&self, target: &Path) -> Result<Option<String>> {
if !target.join(".hg").is_dir() {
return Ok(None);
}
@@ -72,4 +72,16 @@ impl VcsDownloader for HgDownloader {
)?;
Ok(output.stdout)
}
+
+ fn is_change_report(&self) -> bool {
+ true
+ }
+
+ fn is_vcs_capable_downloader(&self) -> bool {
+ true
+ }
+
+ fn is_dvcs_downloader(&self) -> bool {
+ false
+ }
}
diff --git a/crates/mozart-vcs/src/downloader/mod.rs b/crates/mozart-vcs/src/downloader/mod.rs
index 8948921..352f330 100644
--- a/crates/mozart-vcs/src/downloader/mod.rs
+++ b/crates/mozart-vcs/src/downloader/mod.rs
@@ -25,7 +25,7 @@ pub trait VcsDownloader {
/// Detect local changes in the working copy.
/// Returns `None` if clean, `Some(diff)` if modified.
/// Mirrors `Composer\Downloader\ChangeReportInterface::getLocalChanges`.
- fn local_changes(&self, target: &Path) -> Result<Option<String>>;
+ fn get_local_changes(&self, target: &Path) -> Result<Option<String>>;
/// Detect commits present locally but not on the tracking remote.
/// Returns `None` if there are no unpushed commits or the concept does
@@ -44,4 +44,13 @@ pub trait VcsDownloader {
/// Get commit log between two references.
fn commit_logs(&self, from: &str, to: &str, target: &Path) -> Result<String>;
+
+ /// instanceof ChangeReportInterface
+ fn is_change_report(&self) -> bool;
+
+ /// instanceof VcsCapableDownloaderInterface
+ fn is_vcs_capable_downloader(&self) -> bool;
+
+ /// instanceof DvcsDownloaderInterface
+ fn is_dvcs_downloader(&self) -> bool;
}
diff --git a/crates/mozart-vcs/src/downloader/svn.rs b/crates/mozart-vcs/src/downloader/svn.rs
index 533e15a..87b59da 100644
--- a/crates/mozart-vcs/src/downloader/svn.rs
+++ b/crates/mozart-vcs/src/downloader/svn.rs
@@ -51,7 +51,7 @@ impl VcsDownloader for SvnDownloader {
Ok(())
}
- fn local_changes(&self, target: &Path) -> Result<Option<String>> {
+ fn get_local_changes(&self, target: &Path) -> Result<Option<String>> {
if !target.join(".svn").is_dir() {
return Ok(None);
}
@@ -72,4 +72,16 @@ impl VcsDownloader for SvnDownloader {
.execute(&["log", "-r", &range], Some(target))?;
Ok(output.stdout)
}
+
+ fn is_change_report(&self) -> bool {
+ true
+ }
+
+ fn is_vcs_capable_downloader(&self) -> bool {
+ true
+ }
+
+ fn is_dvcs_downloader(&self) -> bool {
+ false
+ }
}
diff --git a/crates/mozart-vcs/src/version_guesser.rs b/crates/mozart-vcs/src/version_guesser.rs
index e70eb4e..038e332 100644
--- a/crates/mozart-vcs/src/version_guesser.rs
+++ b/crates/mozart-vcs/src/version_guesser.rs
@@ -20,6 +20,25 @@ use crate::process::ProcessExecutor;
const DEFAULT_BRANCH_ALIAS: &str = "9999999-dev";
+/// Mirrors `Composer\Package\Version\VersionParser` (itself a thin wrapper
+/// around `Composer\Semver\VersionParser`). In Rust, semver parsing is
+/// handled by `mozart_semver` directly, so this type carries no state;
+/// it exists to keep `VersionGuesser::new` signature compatible with the
+/// PHP constructor.
+pub struct VersionParser;
+
+impl Default for VersionParser {
+ fn default() -> Self {
+ Self::new()
+ }
+}
+
+impl VersionParser {
+ pub fn new() -> Self {
+ Self
+ }
+}
+
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct GuessedVersion {
pub version: String,
@@ -35,12 +54,15 @@ pub struct VersionGuesser {
impl Default for VersionGuesser {
fn default() -> Self {
- Self::new()
+ Self::new(VersionParser::new())
}
}
impl VersionGuesser {
- pub fn new() -> Self {
+ /// Mirrors `Composer\Package\Version\VersionGuesser::__construct`.
+ /// `_version_parser` is accepted for API parity but unused — Rust relies
+ /// on `mozart_semver` directly.
+ pub fn new(_version_parser: VersionParser) -> Self {
Self {
process: ProcessExecutor::new(),
}
diff --git a/crates/mozart-vcs/tests/git_driver_test.rs b/crates/mozart-vcs/tests/git_driver_test.rs
index 2654665..dd72ad6 100644
--- a/crates/mozart-vcs/tests/git_driver_test.rs
+++ b/crates/mozart-vcs/tests/git_driver_test.rs
@@ -165,13 +165,13 @@ fn test_git_downloader() {
assert!(target.join("composer.json").exists());
// Check no local changes
- let changes = downloader.local_changes(&target).unwrap();
+ let changes = downloader.get_local_changes(&target).unwrap();
assert!(changes.is_none(), "Expected no changes, got: {:?}", changes);
// Untracked files alone must NOT count as local changes (matches
// Composer's `git status --porcelain --untracked-files=no`).
std::fs::write(target.join("untracked.txt"), "untracked").unwrap();
- let changes = downloader.local_changes(&target).unwrap();
+ let changes = downloader.get_local_changes(&target).unwrap();
assert!(
changes.is_none(),
"Untracked files should be ignored, got: {:?}",
@@ -180,7 +180,7 @@ fn test_git_downloader() {
// Modifying a tracked file is a local change.
std::fs::write(target.join("composer.json"), "{\"name\":\"changed\"}\n").unwrap();
- let changes = downloader.local_changes(&target).unwrap();
+ let changes = downloader.get_local_changes(&target).unwrap();
assert!(changes.is_some());
assert!(changes.unwrap().contains("composer.json"));