aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe
diff options
context:
space:
mode:
Diffstat (limited to 'crates/shirabe')
-rw-r--r--crates/shirabe/src/downloader/fossil_downloader.rs62
-rw-r--r--crates/shirabe/src/downloader/git_downloader.rs108
-rw-r--r--crates/shirabe/src/downloader/hg_downloader.rs70
-rw-r--r--crates/shirabe/src/downloader/perforce_downloader.rs44
-rw-r--r--crates/shirabe/src/downloader/svn_downloader.rs70
-rw-r--r--crates/shirabe/src/downloader/vcs_downloader.rs18
6 files changed, 248 insertions, 124 deletions
diff --git a/crates/shirabe/src/downloader/fossil_downloader.rs b/crates/shirabe/src/downloader/fossil_downloader.rs
index 7e80c4c..9a38578 100644
--- a/crates/shirabe/src/downloader/fossil_downloader.rs
+++ b/crates/shirabe/src/downloader/fossil_downloader.rs
@@ -1,7 +1,9 @@
//! ref: composer/src/Composer/Downloader/FossilDownloader.php
use crate::config::Config;
+use crate::downloader::ChangeReportInterface;
use crate::downloader::DownloaderInterface;
+use crate::downloader::VcsCapableDownloaderInterface;
use crate::downloader::VcsDownloaderBase;
use crate::io::IOInterface;
use crate::io::IOInterfaceImmutable;
@@ -151,27 +153,6 @@ impl FossilDownloader {
Ok(None)
}
- pub fn get_local_changes(
- &self,
- _package: PackageInterfaceHandle,
- path: String,
- ) -> Option<String> {
- if !self.has_metadata_repository(&path) {
- return None;
- }
-
- let mut output = String::new();
- self.inner.process.borrow_mut().execute_args(
- &["fossil".to_string(), "changes".to_string()],
- &mut output,
- shirabe_php_shim::realpath(&path),
- );
-
- let output = output.trim().to_string();
-
- if output.len() > 0 { Some(output) } else { None }
- }
-
pub(crate) fn get_commit_logs(
&self,
_from_reference: String,
@@ -248,11 +229,50 @@ impl FossilDownloader {
}
}
+impl ChangeReportInterface for FossilDownloader {
+ fn get_local_changes(
+ &self,
+ _package: PackageInterfaceHandle,
+ path: &str,
+ ) -> Result<Option<String>> {
+ if !self.has_metadata_repository(path) {
+ return Ok(None);
+ }
+
+ let mut output = String::new();
+ self.inner.process.borrow_mut().execute_args(
+ &["fossil".to_string(), "changes".to_string()],
+ &mut output,
+ shirabe_php_shim::realpath(path),
+ );
+
+ let output = output.trim().to_string();
+
+ Ok(if output.len() > 0 { Some(output) } else { None })
+ }
+}
+
+impl VcsCapableDownloaderInterface for FossilDownloader {
+ fn get_vcs_reference(&self, package: PackageInterfaceHandle, path: String) -> Option<String> {
+ self.inner.get_vcs_reference(package, &path)
+ }
+}
+
// TODO(phase-b): wire up VcsDownloader trait properly. FossilDownloader extends VcsDownloader
// which implements DownloaderInterface in PHP. Delegating each trait method to todo!() until the
// inner VcsDownloaderBase exposes the matching impl surface.
#[async_trait::async_trait(?Send)]
impl DownloaderInterface for FossilDownloader {
+ fn as_change_report_interface(&self) -> Option<&dyn crate::downloader::ChangeReportInterface> {
+ Some(self)
+ }
+
+ fn as_vcs_capable_downloader_interface(
+ &self,
+ ) -> Option<&dyn crate::downloader::VcsCapableDownloaderInterface> {
+ Some(self)
+ }
+
fn get_installation_source(&self) -> String {
todo!()
}
diff --git a/crates/shirabe/src/downloader/git_downloader.rs b/crates/shirabe/src/downloader/git_downloader.rs
index 6d545ce..acf935b 100644
--- a/crates/shirabe/src/downloader/git_downloader.rs
+++ b/crates/shirabe/src/downloader/git_downloader.rs
@@ -11,7 +11,9 @@ use shirabe_php_shim::{
use crate::cache::Cache;
use crate::config::Config;
+use crate::downloader::ChangeReportInterface;
use crate::downloader::DvcsDownloaderInterface;
+use crate::downloader::VcsCapableDownloaderInterface;
use crate::downloader::VcsDownloaderBase;
use crate::io::IOInterface;
use crate::io::IOInterfaceImmutable;
@@ -455,49 +457,6 @@ impl GitDownloader {
Ok(None)
}
- pub fn get_local_changes(
- &self,
- _package: PackageInterfaceHandle,
- path: &str,
- ) -> Option<String> {
- GitUtil::clean_env(&self.inner.process);
- if !self.has_metadata_repository(path) {
- return None;
- }
-
- let command = vec![
- "git".to_string(),
- "status".to_string(),
- "--porcelain".to_string(),
- "--untracked-files=no".to_string(),
- ];
- let mut output = String::new();
- if self.inner.process.borrow_mut().execute_args(
- &command,
- &mut output,
- Some(path.to_string()),
- ) != 0
- {
- // TODO(phase-b): cannot throw from &self / non-Result fn; bubble error via Result later
- panic!(
- "{}",
- format!(
- "Failed to execute {}\n\n{}",
- implode(" ", &command),
- self.inner.process.borrow().get_error_output(),
- )
- );
- }
-
- let output = trim(&output, None);
-
- if strlen(&output) > 0 {
- Some(output)
- } else {
- None
- }
- }
-
pub fn get_unpushed_changes(
&self,
_package: PackageInterfaceHandle,
@@ -723,7 +682,7 @@ impl GitDownloader {
}
}
- let changes = match self.get_local_changes(package.clone(), &path) {
+ let changes = match self.get_local_changes(package.clone(), &path)? {
Some(c) => c,
None => return Ok(None),
};
@@ -1371,6 +1330,57 @@ impl DvcsDownloaderInterface for GitDownloader {
}
}
+impl ChangeReportInterface for GitDownloader {
+ fn get_local_changes(
+ &self,
+ _package: PackageInterfaceHandle,
+ path: &str,
+ ) -> Result<Option<String>> {
+ GitUtil::clean_env(&self.inner.process);
+ if !self.has_metadata_repository(path) {
+ return Ok(None);
+ }
+
+ let command = vec![
+ "git".to_string(),
+ "status".to_string(),
+ "--porcelain".to_string(),
+ "--untracked-files=no".to_string(),
+ ];
+ let mut output = String::new();
+ if self.inner.process.borrow_mut().execute_args(
+ &command,
+ &mut output,
+ Some(path.to_string()),
+ ) != 0
+ {
+ return Err(RuntimeException {
+ message: format!(
+ "Failed to execute {}\n\n{}",
+ implode(" ", &command),
+ self.inner.process.borrow().get_error_output(),
+ ),
+ code: 0,
+ }
+ .into());
+ }
+
+ let output = trim(&output, None);
+
+ Ok(if strlen(&output) > 0 {
+ Some(output)
+ } else {
+ None
+ })
+ }
+}
+
+impl VcsCapableDownloaderInterface for GitDownloader {
+ fn get_vcs_reference(&self, package: PackageInterfaceHandle, path: String) -> Option<String> {
+ self.inner.get_vcs_reference(package, &path)
+ }
+}
+
// TODO(phase-b): GitDownloader extends VcsDownloader which implements DownloaderInterface.
// Delegating each trait method to todo!() until the inner VcsDownloaderBase exposes the
// matching impl surface.
@@ -1386,6 +1396,16 @@ impl crate::downloader::DownloaderInterface for GitDownloader {
Some(self)
}
+ fn as_change_report_interface(&self) -> Option<&dyn crate::downloader::ChangeReportInterface> {
+ Some(self)
+ }
+
+ fn as_vcs_capable_downloader_interface(
+ &self,
+ ) -> Option<&dyn crate::downloader::VcsCapableDownloaderInterface> {
+ Some(self)
+ }
+
async fn download(
&self,
_package: PackageInterfaceHandle,
diff --git a/crates/shirabe/src/downloader/hg_downloader.rs b/crates/shirabe/src/downloader/hg_downloader.rs
index 7a48054..c5a65a0 100644
--- a/crates/shirabe/src/downloader/hg_downloader.rs
+++ b/crates/shirabe/src/downloader/hg_downloader.rs
@@ -1,7 +1,9 @@
//! ref: composer/src/Composer/Downloader/HgDownloader.php
use crate::config::Config;
+use crate::downloader::ChangeReportInterface;
use crate::downloader::DownloaderInterface;
+use crate::downloader::VcsCapableDownloaderInterface;
use crate::downloader::VcsDownloaderBase;
use crate::io::IOInterface;
use crate::io::IOInterfaceImmutable;
@@ -152,31 +154,6 @@ impl HgDownloader {
Ok(None)
}
- pub fn get_local_changes(
- &self,
- package: PackageInterfaceHandle,
- path: String,
- ) -> Option<String> {
- if !std::path::Path::new(&format!("{}/.hg", path)).is_dir() {
- return None;
- }
-
- let mut output = String::new();
- self.inner.process.borrow_mut().execute_args(
- &["hg".to_string(), "st".to_string()],
- &mut output,
- shirabe_php_shim::realpath(&path),
- );
-
- let output = output.trim().to_string();
-
- if !output.is_empty() {
- Some(output)
- } else {
- None
- }
- }
-
pub(crate) fn get_commit_logs(
&self,
from_reference: String,
@@ -218,11 +195,54 @@ impl HgDownloader {
}
}
+impl ChangeReportInterface for HgDownloader {
+ fn get_local_changes(
+ &self,
+ _package: PackageInterfaceHandle,
+ path: &str,
+ ) -> Result<Option<String>> {
+ if !std::path::Path::new(&format!("{}/.hg", path)).is_dir() {
+ return Ok(None);
+ }
+
+ let mut output = String::new();
+ self.inner.process.borrow_mut().execute_args(
+ &["hg".to_string(), "st".to_string()],
+ &mut output,
+ shirabe_php_shim::realpath(path),
+ );
+
+ let output = output.trim().to_string();
+
+ Ok(if !output.is_empty() {
+ Some(output)
+ } else {
+ None
+ })
+ }
+}
+
+impl VcsCapableDownloaderInterface for HgDownloader {
+ fn get_vcs_reference(&self, package: PackageInterfaceHandle, path: String) -> Option<String> {
+ self.inner.get_vcs_reference(package, &path)
+ }
+}
+
// TODO(phase-b): wire up VcsDownloader trait properly. HgDownloader extends VcsDownloader which
// implements DownloaderInterface in PHP. Delegating each trait method to todo!() until the inner
// VcsDownloaderBase exposes the matching impl surface.
#[async_trait::async_trait(?Send)]
impl DownloaderInterface for HgDownloader {
+ fn as_change_report_interface(&self) -> Option<&dyn crate::downloader::ChangeReportInterface> {
+ Some(self)
+ }
+
+ fn as_vcs_capable_downloader_interface(
+ &self,
+ ) -> Option<&dyn crate::downloader::VcsCapableDownloaderInterface> {
+ Some(self)
+ }
+
fn get_installation_source(&self) -> String {
todo!()
}
diff --git a/crates/shirabe/src/downloader/perforce_downloader.rs b/crates/shirabe/src/downloader/perforce_downloader.rs
index fcea57c..e33b159 100644
--- a/crates/shirabe/src/downloader/perforce_downloader.rs
+++ b/crates/shirabe/src/downloader/perforce_downloader.rs
@@ -1,7 +1,9 @@
//! ref: composer/src/Composer/Downloader/PerforceDownloader.php
use crate::config::Config;
+use crate::downloader::ChangeReportInterface;
use crate::downloader::DownloaderInterface;
+use crate::downloader::VcsCapableDownloaderInterface;
use crate::downloader::VcsDownloaderBase;
use crate::io::IOInterface;
use crate::io::IOInterfaceImmutable;
@@ -124,18 +126,6 @@ impl PerforceDownloader {
self.do_install(target, path, url).await
}
- pub fn get_local_changes(
- &self,
- _package: PackageInterfaceHandle,
- _path: String,
- ) -> Option<String> {
- self.inner
- .io
- .write_error("Perforce driver does not check for local changes before overriding");
-
- None
- }
-
pub(crate) fn get_commit_logs(
&mut self,
from_reference: String,
@@ -159,11 +149,41 @@ impl PerforceDownloader {
}
}
+impl ChangeReportInterface for PerforceDownloader {
+ fn get_local_changes(
+ &self,
+ _package: PackageInterfaceHandle,
+ _path: &str,
+ ) -> Result<Option<String>> {
+ self.inner
+ .io
+ .write_error("Perforce driver does not check for local changes before overriding");
+
+ Ok(None)
+ }
+}
+
+impl VcsCapableDownloaderInterface for PerforceDownloader {
+ fn get_vcs_reference(&self, package: PackageInterfaceHandle, path: String) -> Option<String> {
+ self.inner.get_vcs_reference(package, &path)
+ }
+}
+
// TODO(phase-b): wire up VcsDownloader trait properly. PerforceDownloader extends VcsDownloader
// which implements DownloaderInterface in PHP. Delegating each trait method to todo!() until the
// inner VcsDownloaderBase exposes the matching impl surface.
#[async_trait::async_trait(?Send)]
impl DownloaderInterface for PerforceDownloader {
+ fn as_change_report_interface(&self) -> Option<&dyn crate::downloader::ChangeReportInterface> {
+ Some(self)
+ }
+
+ fn as_vcs_capable_downloader_interface(
+ &self,
+ ) -> Option<&dyn crate::downloader::VcsCapableDownloaderInterface> {
+ Some(self)
+ }
+
fn get_installation_source(&self) -> String {
todo!()
}
diff --git a/crates/shirabe/src/downloader/svn_downloader.rs b/crates/shirabe/src/downloader/svn_downloader.rs
index 98456a4..8ac3e99 100644
--- a/crates/shirabe/src/downloader/svn_downloader.rs
+++ b/crates/shirabe/src/downloader/svn_downloader.rs
@@ -6,7 +6,9 @@ use shirabe_external_packages::composer::pcre::{CaptureKey, Preg};
use shirabe_php_shim::{PhpMixed, RuntimeException, is_dir, version_compare};
use crate::config::Config;
+use crate::downloader::ChangeReportInterface;
use crate::downloader::DownloaderInterface;
+use crate::downloader::VcsCapableDownloaderInterface;
use crate::downloader::VcsDownloaderBase;
use crate::io::IOInterface;
use crate::io::IOInterfaceImmutable;
@@ -158,27 +160,6 @@ impl SvnDownloader {
Ok(None)
}
- pub fn get_local_changes(&self, package: PackageInterfaceHandle, path: &str) -> Option<String> {
- if !self.has_metadata_repository(path) {
- return None;
- }
-
- let mut output = String::new();
- self.inner.process.borrow_mut().execute_args(
- &["svn", "status", "--ignore-externals"]
- .map(|s| s.to_string())
- .to_vec(),
- &mut output,
- Some(path.to_string()),
- );
-
- if Preg::is_match("{^ *[^X ] +}m", &output).unwrap_or(false) {
- Some(output)
- } else {
- None
- }
- }
-
pub(crate) fn execute(
&self,
package: PackageInterfaceHandle,
@@ -211,7 +192,7 @@ impl SvnDownloader {
path: &str,
update: bool,
) -> anyhow::Result<Option<PhpMixed>> {
- let changes = self.get_local_changes(package.clone(), path);
+ let changes = self.get_local_changes(package.clone(), path)?;
if changes.is_none() {
return Ok(None);
}
@@ -432,6 +413,41 @@ impl SvnDownloader {
}
}
+impl ChangeReportInterface for SvnDownloader {
+ fn get_local_changes(
+ &self,
+ _package: PackageInterfaceHandle,
+ path: &str,
+ ) -> anyhow::Result<Option<String>> {
+ if !self.has_metadata_repository(path) {
+ return Ok(None);
+ }
+
+ let mut output = String::new();
+ self.inner.process.borrow_mut().execute_args(
+ &["svn", "status", "--ignore-externals"]
+ .map(|s| s.to_string())
+ .to_vec(),
+ &mut output,
+ Some(path.to_string()),
+ );
+
+ Ok(
+ if Preg::is_match("{^ *[^X ] +}m", &output).unwrap_or(false) {
+ Some(output)
+ } else {
+ None
+ },
+ )
+ }
+}
+
+impl VcsCapableDownloaderInterface for SvnDownloader {
+ fn get_vcs_reference(&self, package: PackageInterfaceHandle, path: String) -> Option<String> {
+ self.inner.get_vcs_reference(package, &path)
+ }
+}
+
// TODO(phase-b): wire up VcsDownloader trait properly. SvnDownloader extends VcsDownloader which
// implements DownloaderInterface in PHP. Delegating each trait method to todo!() until the inner
// VcsDownloaderBase exposes the matching impl surface.
@@ -441,6 +457,16 @@ impl DownloaderInterface for SvnDownloader {
todo!()
}
+ fn as_change_report_interface(&self) -> Option<&dyn crate::downloader::ChangeReportInterface> {
+ Some(self)
+ }
+
+ fn as_vcs_capable_downloader_interface(
+ &self,
+ ) -> Option<&dyn crate::downloader::VcsCapableDownloaderInterface> {
+ Some(self)
+ }
+
async fn download(
&self,
_package: PackageInterfaceHandle,
diff --git a/crates/shirabe/src/downloader/vcs_downloader.rs b/crates/shirabe/src/downloader/vcs_downloader.rs
index fadfa98..493440c 100644
--- a/crates/shirabe/src/downloader/vcs_downloader.rs
+++ b/crates/shirabe/src/downloader/vcs_downloader.rs
@@ -69,6 +69,24 @@ impl VcsDownloaderBase {
// Callers in subclasses must do that check themselves (they already have).
Ok(None)
}
+
+ pub fn get_vcs_reference(&self, package: PackageInterfaceHandle, path: &str) -> Option<String> {
+ let parser = VersionParser::new();
+ let mut guesser = VersionGuesser::new(
+ self.config.clone(),
+ self.process.clone(),
+ parser.clone(),
+ Some(self.io.clone()),
+ );
+ let dumper = ArrayDumper::new();
+
+ let package_config = dumper.dump(package.clone());
+ if let Ok(Some(package_version)) = guesser.guess_version(&package_config, path) {
+ return package_version.commit.clone();
+ }
+
+ None
+ }
}
pub trait VcsDownloader: