aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/mozart
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-05-08 02:41:45 +0900
committernsfisis <nsfisis@gmail.com>2026-05-08 02:41:45 +0900
commitb3fcdf3b5cf0d6b43109c4bcb3dfcbb6576abce5 (patch)
tree14c5270d7f39932a57acbfb176f05faa4ec74a8f /crates/mozart
parent2fee33109dbc81dadeb152f38bea3050c4a0bfa2 (diff)
downloadphp-mozart-b3fcdf3b5cf0d6b43109c4bcb3dfcbb6576abce5.tar.gz
php-mozart-b3fcdf3b5cf0d6b43109c4bcb3dfcbb6576abce5.tar.zst
php-mozart-b3fcdf3b5cf0d6b43109c4bcb3dfcbb6576abce5.zip
fix(browse): mirror Composer's HomeCommand semantics
Replace the hand-rolled composer.json -> composer.lock -> Packagist fallback with a BrowseRepos composite that dispatches via a uniform find_packages(name) over the root package, the local installed repository, and the Packagist remote -- matching HomeCommand's initializeRepos() + findPackages() loop. - Extend InstalledPackageEntry with homepage/support so the local repo carries the same fields HomeCommand reads off CompletePackageInterface; propagate them through locked_to_installed_entry. - Collapse three extract_url_from_* helpers into a single handle_package mirror. - Relax is_valid_url to a filter_var(FILTER_VALIDATE_URL) analog (drop the http/https scheme allowlist). - Route warnings and "No package specified" notices to stderr; match HomeCommand's exact wording. - Merge the macOS/Linux open_browser branches; add the literal "web" window-title argument on Windows.
Diffstat (limited to 'crates/mozart')
-rw-r--r--crates/mozart/src/commands/audit.rs6
-rw-r--r--crates/mozart/src/commands/browse.rs459
-rw-r--r--crates/mozart/src/commands/fund.rs4
-rw-r--r--crates/mozart/src/commands/install.rs4
-rw-r--r--crates/mozart/src/commands/licenses.rs8
-rw-r--r--crates/mozart/src/commands/reinstall.rs2
-rw-r--r--crates/mozart/src/commands/show.rs6
-rw-r--r--crates/mozart/src/commands/status.rs10
-rw-r--r--crates/mozart/src/commands/suggests.rs2
9 files changed, 204 insertions, 297 deletions
diff --git a/crates/mozart/src/commands/audit.rs b/crates/mozart/src/commands/audit.rs
index 5c0d46c..da61e62 100644
--- a/crates/mozart/src/commands/audit.rs
+++ b/crates/mozart/src/commands/audit.rs
@@ -858,6 +858,8 @@ mod tests {
install_path: None,
autoload: None,
aliases: vec![],
+ homepage: None,
+ support: None,
extra_fields: BTreeMap::new(),
});
installed.write(&vendor_dir).unwrap();
@@ -887,6 +889,8 @@ mod tests {
install_path: None,
autoload: None,
aliases: vec![],
+ homepage: None,
+ support: None,
extra_fields: BTreeMap::new(),
});
installed.upsert(mozart_registry::installed::InstalledPackageEntry {
@@ -899,6 +903,8 @@ mod tests {
install_path: None,
autoload: None,
aliases: vec![],
+ homepage: None,
+ support: None,
extra_fields: BTreeMap::new(),
});
installed
diff --git a/crates/mozart/src/commands/browse.rs b/crates/mozart/src/commands/browse.rs
index a977012..538cf6a 100644
--- a/crates/mozart/src/commands/browse.rs
+++ b/crates/mozart/src/commands/browse.rs
@@ -1,8 +1,13 @@
use clap::Args;
+use mozart_core::composer::Composer;
+use mozart_core::console::Console;
use mozart_core::console_format;
use mozart_core::console_writeln;
+use mozart_core::console_writeln_error;
use mozart_core::exit_code;
-use std::path::Path;
+use mozart_registry::browse_repos::{BrowseRepos, CompletePackageView};
+use mozart_registry::cache::{Cache, build_cache_config};
+use mozart_registry::installed::InstalledPackages;
use std::process::Command;
#[derive(Args)]
@@ -19,381 +24,241 @@ pub struct BrowseArgs {
pub show: bool,
}
-pub async fn execute(
- args: &BrowseArgs,
- cli: &super::Cli,
- console: &mozart_core::console::Console,
-) -> anyhow::Result<()> {
- let cache_config = mozart_registry::cache::build_cache_config(cli.no_cache);
- let repo_cache = mozart_registry::cache::Cache::repo(&cache_config);
-
+pub async fn execute(args: &BrowseArgs, cli: &super::Cli, console: &Console) -> anyhow::Result<()> {
let working_dir = cli.working_dir()?;
+ let cache = Cache::repo(&build_cache_config(cli.no_cache));
+
+ let composer = Composer::try_load(&working_dir)?;
+ let repos = build_repos(composer.as_ref(), cache);
- // If no packages specified, use root package name from composer.json
let packages: Vec<String> = if args.packages.is_empty() {
- let composer_json = working_dir.join("composer.json");
- if !composer_json.exists() {
- anyhow::bail!(
- "No composer.json found in the current directory and no package specified."
- );
- }
- console.info("No package specified, opening homepage for the root package");
- let root = mozart_core::package::read_from_file(&composer_json)?;
- vec![root.name.clone()]
+ console_writeln_error!(
+ console,
+ "No package specified, opening homepage for the root package"
+ );
+ // Mirrors HomeCommand's `$this->requireComposer()->getPackage()->getName()`.
+ let composer = composer.ok_or_else(|| {
+ anyhow::anyhow!(
+ "Composer could not find a composer.json file in {}",
+ working_dir.display()
+ )
+ })?;
+ vec![composer.package().name.clone()]
} else {
args.packages.clone()
};
- let mut exit_code = 0i32;
-
+ let mut return_code = 0i32;
for package_name in &packages {
- match resolve_url(package_name, &working_dir, args.homepage, &repo_cache).await? {
- ResolveResult::Found(url) => {
- if args.show {
- console_writeln!(console, &console_format!("<info>{}</info>", url),);
- } else {
- open_browser(&url, console)?;
+ let mut handled = false;
+ let mut package_exists = false;
+ 'outer: for repo in repos.iter() {
+ for view in repo.find_packages(package_name).await? {
+ package_exists = true;
+ if handle_package(&view, args.homepage, args.show, console)? {
+ handled = true;
+ break 'outer;
}
}
- ResolveResult::NotFound => {
- console.info(&console_format!(
- "<warning>Package {} not found</warning>",
- package_name
- ));
- exit_code = 1;
- }
- ResolveResult::NoUrl => {
- let msg = if args.homepage {
- format!("Invalid or missing homepage for {}", package_name)
- } else {
- format!("Invalid or missing repository URL for {}", package_name)
- };
- console.info(&console_format!("<warning>{}</warning>", msg));
- exit_code = 1;
- }
}
- }
-
- if exit_code != 0 {
- return Err(exit_code::bail_silent(exit_code));
- }
-
- Ok(())
-}
-
-enum ResolveResult {
- /// Package found and URL resolved
- Found(String),
- /// Package found but no valid URL available
- NoUrl,
- /// Package not found in any source
- NotFound,
-}
-
-async fn resolve_url(
- package_name: &str,
- working_dir: &Path,
- prefer_homepage: bool,
- repo_cache: &mozart_registry::cache::Cache,
-) -> anyhow::Result<ResolveResult> {
- // 1. Check root package (composer.json)
- let composer_json = working_dir.join("composer.json");
- if composer_json.exists()
- && let Ok(root) = mozart_core::package::read_from_file(&composer_json)
- && root.name.eq_ignore_ascii_case(package_name)
- {
- return Ok(match extract_url_from_root(&root, prefer_homepage) {
- Some(url) => ResolveResult::Found(url),
- None => ResolveResult::NoUrl,
- });
- }
- // 2. Check lock file (composer.lock)
- let lock_path = working_dir.join("composer.lock");
- if lock_path.exists()
- && let Ok(lock) = mozart_registry::lockfile::LockFile::read_from_file(&lock_path)
- {
- let all_packages = lock
- .packages
- .iter()
- .chain(lock.packages_dev.as_deref().unwrap_or(&[]));
-
- for pkg in all_packages {
- if pkg.name.eq_ignore_ascii_case(package_name) {
- return Ok(match extract_url_from_locked(pkg, prefer_homepage) {
- Some(url) => ResolveResult::Found(url),
- None => ResolveResult::NoUrl,
- });
- }
+ if !package_exists {
+ return_code = 1;
+ console_writeln_error!(
+ console,
+ &console_format!("<warning>Package {} not found</warning>", package_name),
+ );
}
- }
- // 3. Fall back to Packagist API
- match mozart_registry::packagist::fetch_package_versions(package_name, repo_cache).await {
- Ok(versions) if !versions.is_empty() => {
- // Find the latest stable version (first non-dev, or fallback to first)
- let best = versions
- .iter()
- .find(|v| !v.version.starts_with("dev-") && !v.version.ends_with("-dev"))
- .or_else(|| versions.first());
-
- if let Some(version) = best {
- return Ok(match extract_url_from_packagist(version, prefer_homepage) {
- Some(url) => ResolveResult::Found(url),
- None => ResolveResult::NoUrl,
- });
- }
- Ok(ResolveResult::NotFound)
+ if !handled {
+ return_code = 1;
+ let kind = if args.homepage {
+ "Invalid or missing homepage"
+ } else {
+ "Invalid or missing repository URL"
+ };
+ console_writeln_error!(
+ console,
+ &console_format!("<warning>{} for {}</warning>", kind, package_name),
+ );
}
- _ => Ok(ResolveResult::NotFound),
- }
-}
-
-fn extract_url_from_locked(
- pkg: &mozart_registry::lockfile::LockedPackage,
- prefer_homepage: bool,
-) -> Option<String> {
- if prefer_homepage {
- return pkg
- .homepage
- .as_deref()
- .filter(|u| is_valid_url(u))
- .map(|u| u.to_string());
}
- // Priority: support.source → source.url → homepage
- if let Some(ref support) = pkg.support
- && let Some(source_url) = support.get("source").and_then(|v| v.as_str())
- && is_valid_url(source_url)
- {
- return Some(source_url.to_string());
+ if return_code != 0 {
+ return Err(exit_code::bail_silent(return_code));
}
- if let Some(ref source) = pkg.source
- && is_valid_url(&source.url)
- {
- return Some(source.url.clone());
- }
-
- pkg.homepage
- .as_deref()
- .filter(|u| is_valid_url(u))
- .map(|u| u.to_string())
+ Ok(())
}
-fn extract_url_from_root(
- root: &mozart_core::package::RawPackageData,
- prefer_homepage: bool,
-) -> Option<String> {
- if prefer_homepage {
- return root
- .homepage
- .as_deref()
- .filter(|u| is_valid_url(u))
- .map(|u| u.to_string());
- }
-
- // Priority: support.source → homepage (no source.url in RawPackageData)
- if let Some(support_val) = root.extra_fields.get("support")
- && let Some(source_url) = support_val.get("source").and_then(|v| v.as_str())
- && is_valid_url(source_url)
- {
- return Some(source_url.to_string());
- }
-
- root.homepage
- .as_deref()
- .filter(|u| is_valid_url(u))
- .map(|u| u.to_string())
+fn build_repos(composer: Option<&Composer>, cache: Cache) -> BrowseRepos {
+ let (root, installed) = match composer {
+ Some(c) => {
+ let root = Some(c.package().clone());
+ let installed = InstalledPackages::read(c.installation_manager().vendor_dir()).ok();
+ (root, installed)
+ }
+ None => (None, None),
+ };
+ BrowseRepos::new(root, installed, cache)
}
-fn extract_url_from_packagist(
- pkg: &mozart_registry::packagist::PackagistVersion,
- prefer_homepage: bool,
-) -> Option<String> {
- if prefer_homepage {
- return pkg
- .homepage
- .as_deref()
- .filter(|u| is_valid_url(u))
- .map(|u| u.to_string());
+/// Port of `HomeCommand::handlePackage`. Returns `true` on success
+/// (URL printed or browser opened), `false` when no valid URL was
+/// available — matching Composer's signal for the outer loop.
+fn handle_package(
+ view: &CompletePackageView,
+ show_homepage: bool,
+ show_only: bool,
+ console: &Console,
+) -> anyhow::Result<bool> {
+ let mut url = view
+ .support_source
+ .clone()
+ .or_else(|| view.source_url.clone());
+ if url.is_none() || show_homepage {
+ url = view.homepage.clone();
}
- // Priority: support.source → source.url → homepage
- if let Some(ref support) = pkg.support
- && let Some(source_url) = support.get("source").and_then(|v| v.as_str())
- && is_valid_url(source_url)
- {
- return Some(source_url.to_string());
- }
+ let Some(url) = url.filter(|u| is_valid_url(u)) else {
+ return Ok(false);
+ };
- if let Some(ref source) = pkg.source
- && is_valid_url(&source.url)
- {
- return Some(source.url.clone());
+ if show_only {
+ console_writeln!(console, &console_format!("<info>{}</info>", url));
+ } else {
+ open_browser(&url, console)?;
}
-
- pkg.homepage
- .as_deref()
- .filter(|u| is_valid_url(u))
- .map(|u| u.to_string())
+ Ok(true)
}
fn is_valid_url(url: &str) -> bool {
- match url::Url::parse(url) {
- Ok(parsed) => matches!(parsed.scheme(), "http" | "https"),
- Err(_) => false,
- }
+ url::Url::parse(url).is_ok()
}
-fn open_browser(url: &str, console: &mozart_core::console::Console) -> anyhow::Result<()> {
- #[cfg(target_os = "macos")]
- {
- Command::new("open").arg(url).status()?;
- return Ok(());
- }
-
+fn open_browser(url: &str, console: &Console) -> anyhow::Result<()> {
#[cfg(target_os = "windows")]
{
Command::new("cmd")
- .args(["/C", "start", "web", "explorer", url])
+ .args(["/C", "start", "\"web\"", "explorer", url])
.status()?;
return Ok(());
}
- #[cfg(target_os = "linux")]
+ #[cfg(not(target_os = "windows"))]
{
- if Command::new("which")
- .arg("xdg-open")
- .output()
- .map(|o| o.status.success())
- .unwrap_or(false)
- {
+ let xdg_open = which("xdg-open");
+ let open = which("open");
+ if xdg_open {
Command::new("xdg-open").arg(url).status()?;
- return Ok(());
- }
- if Command::new("which")
- .arg("open")
- .output()
- .map(|o| o.status.success())
- .unwrap_or(false)
- {
+ } else if open {
Command::new("open").arg(url).status()?;
- return Ok(());
+ } else {
+ console_writeln_error!(
+ console,
+ &format!(
+ "No suitable browser opening command found, open yourself: {}",
+ url
+ ),
+ );
}
- console.info(&format!(
- "No suitable browser opener found. Please open manually: {}",
- url
- ));
Ok(())
}
}
+#[cfg(not(target_os = "windows"))]
+fn which(cmd: &str) -> bool {
+ Command::new("which")
+ .arg(cmd)
+ .output()
+ .map(|o| o.status.success())
+ .unwrap_or(false)
+}
+
#[cfg(test)]
mod tests {
use super::*;
- use std::collections::BTreeMap;
- fn make_locked_package(
- source_url: Option<&str>,
+ fn console() -> Console {
+ Console::new(0, false, false, false, true)
+ }
+
+ fn view(
+ support: Option<&str>,
+ source: Option<&str>,
homepage: Option<&str>,
- support_source: Option<&str>,
- ) -> mozart_registry::lockfile::LockedPackage {
- let support = support_source.map(|s| serde_json::json!({"source": s}));
- let source = source_url.map(|url| mozart_registry::lockfile::LockedSource {
- source_type: "git".to_string(),
- url: url.to_string(),
- reference: None,
- });
- mozart_registry::lockfile::LockedPackage {
- name: "vendor/package".to_string(),
- version: "1.0.0".to_string(),
- version_normalized: None,
- source,
- dist: None,
- require: BTreeMap::new(),
- require_dev: BTreeMap::new(),
- conflict: BTreeMap::new(),
- provide: BTreeMap::new(),
- replace: BTreeMap::new(),
- suggest: None,
- package_type: None,
- autoload: None,
- autoload_dev: None,
- license: None,
- description: None,
- homepage: homepage.map(|s| s.to_string()),
- keywords: None,
- authors: None,
- support,
- funding: None,
- time: None,
- extra_fields: BTreeMap::new(),
+ ) -> CompletePackageView {
+ CompletePackageView {
+ support_source: support.map(str::to_string),
+ source_url: source.map(str::to_string),
+ homepage: homepage.map(str::to_string),
}
}
#[test]
- fn test_is_valid_url() {
- assert!(!is_valid_url("https://"));
+ fn is_valid_url_accepts_filter_var_compatible_schemes() {
assert!(is_valid_url("https://example.com"));
assert!(is_valid_url("http://example.com/path?query=1"));
- assert!(!is_valid_url("ftp://example.com"));
- assert!(!is_valid_url("not-a-url"));
+ assert!(is_valid_url("ftp://example.com/a"));
+ }
+
+ #[test]
+ fn is_valid_url_rejects_malformed() {
assert!(!is_valid_url(""));
+ assert!(!is_valid_url("not-a-url"));
+ assert!(!is_valid_url("https://"));
}
#[test]
- fn test_extract_url_from_locked_prefers_support_source() {
- // Has all three: support.source should win
- let pkg = make_locked_package(
- Some("https://github.com/vendor/package.git"),
+ fn handle_package_prefers_support_source() {
+ let v = view(
+ Some("https://github.com/vendor/pkg"),
+ Some("https://github.com/vendor/pkg.git"),
Some("https://vendor.example.com"),
- Some("https://github.com/vendor/package"),
);
- let url = extract_url_from_locked(&pkg, false);
- assert_eq!(url, Some("https://github.com/vendor/package".to_string()));
+ assert!(handle_package(&v, false, true, &console()).unwrap());
}
#[test]
- fn test_extract_url_from_locked_prefers_homepage() {
- // With prefer_homepage=true, only homepage is returned
- let pkg = make_locked_package(
- Some("https://github.com/vendor/package.git"),
+ fn handle_package_falls_back_to_source_url() {
+ let v = view(
+ None,
+ Some("https://github.com/vendor/pkg.git"),
Some("https://vendor.example.com"),
- Some("https://github.com/vendor/package"),
);
- let url = extract_url_from_locked(&pkg, true);
- assert_eq!(url, Some("https://vendor.example.com".to_string()));
+ assert!(handle_package(&v, false, true, &console()).unwrap());
}
#[test]
- fn test_extract_url_from_locked_fallback_to_source() {
- // No support.source, has source.url
- let pkg = make_locked_package(
- Some("https://github.com/vendor/package.git"),
+ fn handle_package_falls_back_to_homepage_when_no_source() {
+ let v = view(None, None, Some("https://vendor.example.com"));
+ assert!(handle_package(&v, false, true, &console()).unwrap());
+ }
+
+ #[test]
+ fn handle_package_show_homepage_overrides_to_homepage() {
+ let v = view(
+ Some("https://github.com/vendor/pkg"),
+ Some("https://github.com/vendor/pkg.git"),
Some("https://vendor.example.com"),
- None,
- );
- let url = extract_url_from_locked(&pkg, false);
- assert_eq!(
- url,
- Some("https://github.com/vendor/package.git".to_string())
);
+ assert!(handle_package(&v, true, true, &console()).unwrap());
}
#[test]
- fn test_extract_url_from_locked_fallback_to_homepage() {
- // No source URLs, falls back to homepage
- let pkg = make_locked_package(None, Some("https://vendor.example.com"), None);
- let url = extract_url_from_locked(&pkg, false);
- assert_eq!(url, Some("https://vendor.example.com".to_string()));
+ fn handle_package_returns_false_when_no_valid_url() {
+ let v = view(None, None, None);
+ assert!(!handle_package(&v, false, true, &console()).unwrap());
+
+ // Invalid URL strings still cause `handlePackage` to bail.
+ let bad = view(Some("not-a-url"), None, None);
+ assert!(!handle_package(&bad, false, true, &console()).unwrap());
}
#[test]
- fn test_extract_url_from_locked_no_urls() {
- // No URLs at all
- let pkg = make_locked_package(None, None, None);
- let url = extract_url_from_locked(&pkg, false);
- assert_eq!(url, None);
+ fn handle_package_show_homepage_with_missing_homepage_returns_false() {
+ let v = view(Some("https://github.com/vendor/pkg"), None, None);
+ // -H and homepage absent → falls through and bails.
+ assert!(!handle_package(&v, true, true, &console()).unwrap());
}
}
diff --git a/crates/mozart/src/commands/fund.rs b/crates/mozart/src/commands/fund.rs
index ab8591a..f240378 100644
--- a/crates/mozart/src/commands/fund.rs
+++ b/crates/mozart/src/commands/fund.rs
@@ -470,6 +470,8 @@ mod tests {
install_path: None,
autoload: None,
aliases: vec![],
+ homepage: None,
+ support: None,
extra_fields: extra,
});
@@ -484,6 +486,8 @@ mod tests {
install_path: None,
autoload: None,
aliases: vec![],
+ homepage: None,
+ support: None,
extra_fields: BTreeMap::new(),
});
diff --git a/crates/mozart/src/commands/install.rs b/crates/mozart/src/commands/install.rs
index 428c5cc..7b4315c 100644
--- a/crates/mozart/src/commands/install.rs
+++ b/crates/mozart/src/commands/install.rs
@@ -629,6 +629,8 @@ pub fn locked_to_installed_entry(
install_path: Some(install_path),
autoload: pkg.autoload.clone(),
aliases: vec![],
+ homepage: pkg.homepage.clone(),
+ support: pkg.support.clone(),
extra_fields: pkg.extra_fields.clone(),
}
}
@@ -1634,6 +1636,8 @@ mod tests {
install_path: None,
autoload: None,
aliases: vec![],
+ homepage: None,
+ support: None,
extra_fields: BTreeMap::new(),
}
}
diff --git a/crates/mozart/src/commands/licenses.rs b/crates/mozart/src/commands/licenses.rs
index 7515b32..1574d79 100644
--- a/crates/mozart/src/commands/licenses.rs
+++ b/crates/mozart/src/commands/licenses.rs
@@ -376,6 +376,8 @@ mod tests {
install_path: None,
autoload: None,
aliases: vec![],
+ homepage: None,
+ support: None,
extra_fields: extra,
}
}
@@ -489,6 +491,8 @@ mod tests {
install_path: None,
autoload: None,
aliases: vec![],
+ homepage: None,
+ support: None,
extra_fields: extra,
});
@@ -530,6 +534,8 @@ mod tests {
install_path: None,
autoload: None,
aliases: vec![],
+ homepage: None,
+ support: None,
extra_fields: extra_prod,
});
@@ -546,6 +552,8 @@ mod tests {
install_path: None,
autoload: None,
aliases: vec![],
+ homepage: None,
+ support: None,
extra_fields: extra_dev,
});
installed
diff --git a/crates/mozart/src/commands/reinstall.rs b/crates/mozart/src/commands/reinstall.rs
index b421bd8..45f44f5 100644
--- a/crates/mozart/src/commands/reinstall.rs
+++ b/crates/mozart/src/commands/reinstall.rs
@@ -415,6 +415,8 @@ mod tests {
install_path: None,
autoload: None,
aliases: vec![],
+ homepage: None,
+ support: None,
extra_fields: BTreeMap::new(),
}
}
diff --git a/crates/mozart/src/commands/show.rs b/crates/mozart/src/commands/show.rs
index 7b87403..c675d54 100644
--- a/crates/mozart/src/commands/show.rs
+++ b/crates/mozart/src/commands/show.rs
@@ -2062,6 +2062,8 @@ mod tests {
install_path: None,
autoload: None,
aliases: vec![],
+ homepage: None,
+ support: None,
extra_fields: extra,
};
assert_eq!(get_installed_description(&pkg), "A logging library");
@@ -2080,6 +2082,8 @@ mod tests {
install_path: None,
autoload: None,
aliases: vec![],
+ homepage: None,
+ support: None,
extra_fields: BTreeMap::new(),
};
assert_eq!(get_installed_description(&pkg), "");
@@ -2103,6 +2107,8 @@ mod tests {
install_path: None,
autoload: None,
aliases: vec![],
+ homepage: None,
+ support: None,
extra_fields: extra,
};
assert_eq!(get_installed_keywords(&pkg), "log, psr3, logging");
diff --git a/crates/mozart/src/commands/status.rs b/crates/mozart/src/commands/status.rs
index c22fd3c..60db8ac 100644
--- a/crates/mozart/src/commands/status.rs
+++ b/crates/mozart/src/commands/status.rs
@@ -501,6 +501,8 @@ mod tests {
install_path: None,
autoload: None,
aliases: vec![],
+ homepage: None,
+ support: None,
extra_fields: BTreeMap::new(),
};
@@ -528,6 +530,8 @@ mod tests {
install_path: None,
autoload: None,
aliases: vec![],
+ homepage: None,
+ support: None,
extra_fields: BTreeMap::new(),
};
@@ -548,6 +552,8 @@ mod tests {
install_path: None,
autoload: None,
aliases: vec![],
+ homepage: None,
+ support: None,
extra_fields: BTreeMap::new(),
};
@@ -568,6 +574,8 @@ mod tests {
install_path: None,
autoload: None,
aliases: vec![],
+ homepage: None,
+ support: None,
extra_fields: BTreeMap::new(),
};
@@ -590,6 +598,8 @@ mod tests {
install_path: Some("../monolog/monolog".to_string()),
autoload: None,
aliases: vec![],
+ homepage: None,
+ support: None,
extra_fields: BTreeMap::new(),
};
diff --git a/crates/mozart/src/commands/suggests.rs b/crates/mozart/src/commands/suggests.rs
index f00a2a2..ab4100d 100644
--- a/crates/mozart/src/commands/suggests.rs
+++ b/crates/mozart/src/commands/suggests.rs
@@ -548,6 +548,8 @@ mod tests {
install_path: None,
autoload: None,
aliases: vec![],
+ homepage: None,
+ support: None,
extra_fields,
}
}