aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/mozart-core
diff options
context:
space:
mode:
Diffstat (limited to 'crates/mozart-core')
-rw-r--r--crates/mozart-core/src/composer.rs100
-rw-r--r--crates/mozart-core/src/factory.rs57
2 files changed, 152 insertions, 5 deletions
diff --git a/crates/mozart-core/src/composer.rs b/crates/mozart-core/src/composer.rs
index 6fe022a..66bae92 100644
--- a/crates/mozart-core/src/composer.rs
+++ b/crates/mozart-core/src/composer.rs
@@ -92,20 +92,72 @@ pub struct Composer {
locker: Locker,
}
-/// Subset of `Composer\Package\PackageInterface` needed by the
-/// installation manager. Today only the fields referenced by
-/// `LibraryInstaller::getInstallPath` (`prettyName`, `targetDir`).
+/// Which source the package was installed from. Mirrors
+/// `PackageInterface::getInstallationSource` ("source" | "dist").
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub enum InstallationSource {
+ Source,
+ Dist,
+}
+
+impl InstallationSource {
+ /// Parse the `installation-source` field from `installed.json`.
+ pub fn parse(s: &str) -> Option<Self> {
+ match s {
+ "source" => Some(InstallationSource::Source),
+ "dist" => Some(InstallationSource::Dist),
+ _ => None,
+ }
+ }
+}
+
+/// Source/dist descriptor — mirrors the nested `source`/`dist` objects in
+/// `installed.json`.
+#[derive(Debug, Clone)]
+pub struct PackageReference {
+ pub kind: String,
+ pub url: String,
+ pub reference: Option<String>,
+ pub shasum: Option<String>,
+}
+
+/// Subset of `Composer\Package\PackageInterface` carried through Mozart's
+/// `LocalRepository`. Holds the fields needed by both the installation
+/// manager (`prettyName`, `targetDir`) and the status command
+/// (installation source, source/dist refs, version, extra).
#[derive(Debug, Clone)]
pub struct LocalPackage {
pretty_name: String,
+ pretty_version: String,
target_dir: Option<String>,
+ package_type: Option<String>,
+ installation_source: Option<InstallationSource>,
+ source: Option<PackageReference>,
+ dist: Option<PackageReference>,
+ extra: serde_json::Value,
}
impl LocalPackage {
- pub fn new(pretty_name: String, target_dir: Option<String>) -> Self {
+ #[allow(clippy::too_many_arguments)]
+ pub fn new(
+ pretty_name: String,
+ pretty_version: String,
+ target_dir: Option<String>,
+ package_type: Option<String>,
+ installation_source: Option<InstallationSource>,
+ source: Option<PackageReference>,
+ dist: Option<PackageReference>,
+ extra: serde_json::Value,
+ ) -> Self {
Self {
pretty_name,
+ pretty_version,
target_dir,
+ package_type,
+ installation_source,
+ source,
+ dist,
+ extra,
}
}
@@ -115,11 +167,51 @@ impl LocalPackage {
&self.pretty_name
}
+ /// Original-case version string (e.g. `v1.0.0`). Mirrors
+ /// `PackageInterface::getPrettyVersion`.
+ pub fn pretty_version(&self) -> &str {
+ &self.pretty_version
+ }
+
/// Optional sub-directory inside the install path that holds the
/// package code. Mirrors `PackageInterface::getTargetDir`.
pub fn target_dir(&self) -> Option<&str> {
self.target_dir.as_deref()
}
+
+ /// Mirrors `PackageInterface::getType`.
+ pub fn package_type(&self) -> Option<&str> {
+ self.package_type.as_deref()
+ }
+
+ /// Mirrors `PackageInterface::getInstallationSource`.
+ pub fn installation_source(&self) -> Option<InstallationSource> {
+ self.installation_source
+ }
+
+ pub fn source(&self) -> Option<&PackageReference> {
+ self.source.as_ref()
+ }
+
+ pub fn dist(&self) -> Option<&PackageReference> {
+ self.dist.as_ref()
+ }
+
+ /// Mirrors `PackageInterface::getSourceReference`.
+ pub fn source_reference(&self) -> Option<&str> {
+ self.source.as_ref().and_then(|r| r.reference.as_deref())
+ }
+
+ /// Mirrors `PackageInterface::getDistReference`.
+ pub fn dist_reference(&self) -> Option<&str> {
+ self.dist.as_ref().and_then(|r| r.reference.as_deref())
+ }
+
+ /// Raw `extra` field — used by VersionGuesser to read
+ /// `branch-alias`, `non-feature-branches`, etc.
+ pub fn extra(&self) -> &serde_json::Value {
+ &self.extra
+ }
}
/// In-memory mirror of `Composer\Repository\InstalledFilesystemRepository`
diff --git a/crates/mozart-core/src/factory.rs b/crates/mozart-core/src/factory.rs
index 92aa70e..c9d346b 100644
--- a/crates/mozart-core/src/factory.rs
+++ b/crates/mozart-core/src/factory.rs
@@ -276,15 +276,70 @@ fn read_local_packages(vendor_dir: &Path) -> anyhow::Result<Vec<LocalPackage>> {
.and_then(|v| v.as_str())
.unwrap_or("")
.to_string();
+ let pretty_version = entry
+ .get("version")
+ .and_then(|v| v.as_str())
+ .unwrap_or("")
+ .to_string();
let target_dir = entry
.get("target-dir")
.and_then(|v| v.as_str())
.map(|s| s.to_string());
- out.push(LocalPackage::new(pretty_name, target_dir));
+ let package_type = entry
+ .get("type")
+ .and_then(|v| v.as_str())
+ .map(|s| s.to_string());
+ let installation_source = entry
+ .get("installation-source")
+ .and_then(|v| v.as_str())
+ .and_then(crate::composer::InstallationSource::parse);
+ let source = read_package_reference(entry.get("source"));
+ let dist = read_package_reference(entry.get("dist"));
+ let extra = entry
+ .get("extra")
+ .cloned()
+ .unwrap_or(serde_json::Value::Null);
+ out.push(LocalPackage::new(
+ pretty_name,
+ pretty_version,
+ target_dir,
+ package_type,
+ installation_source,
+ source,
+ dist,
+ extra,
+ ));
}
Ok(out)
}
+fn read_package_reference(
+ value: Option<&serde_json::Value>,
+) -> Option<crate::composer::PackageReference> {
+ let v = value?;
+ let kind = v.get("type").and_then(|x| x.as_str())?.to_string();
+ let url = v
+ .get("url")
+ .and_then(|x| x.as_str())
+ .unwrap_or("")
+ .to_string();
+ let reference = v
+ .get("reference")
+ .and_then(|x| x.as_str())
+ .map(|s| s.to_string());
+ let shasum = v
+ .get("shasum")
+ .and_then(|x| x.as_str())
+ .filter(|s| !s.is_empty())
+ .map(|s| s.to_string());
+ Some(crate::composer::PackageReference {
+ kind,
+ url,
+ reference,
+ shasum,
+ })
+}
+
#[cfg(test)]
mod tests {
use super::*;