Fix PackageInfoShort to handle LocaleString on releaseNotes (#3112)

* Fix PackageInfoShort to handle LocaleString on releaseNotes

* fix: filter by target_version in get_matching_models and pass otherVersions from install

* chore: add exver documentation for ai agents
This commit is contained in:
Aiden McClelland
2026-02-09 20:42:03 +01:00
committed by GitHub
parent ba740a9ee2
commit b6262c8e13
3 changed files with 368 additions and 24 deletions

View File

@@ -137,6 +137,7 @@ pub async fn install(
json!({
"id": id,
"targetVersion": VersionRange::exactly(version.deref().clone()),
"otherVersions": "none",
}),
RegistryUrlParams {
registry: registry.clone(),
@@ -484,7 +485,7 @@ pub async fn cli_install(
let mut packages: GetPackageResponse = from_value(
ctx.call_remote::<RegistryContext>(
"package.get",
json!({ "id": &id, "targetVersion": version, "sourceVersion": source_version }),
json!({ "id": &id, "targetVersion": version, "sourceVersion": source_version, "otherVersions": "none" }),
)
.await?,
)?;

View File

@@ -15,6 +15,7 @@ use crate::progress::{FullProgressTracker, ProgressUnits};
use crate::registry::context::RegistryContext;
use crate::registry::device_info::DeviceInfo;
use crate::registry::package::index::{PackageIndex, PackageVersionInfo};
use crate::s9pk::manifest::LocaleString;
use crate::s9pk::merkle_archive::source::ArchiveSource;
use crate::s9pk::v2::SIG_CONTEXT;
use crate::util::VersionString;
@@ -38,11 +39,11 @@ impl Default for PackageDetailLevel {
}
}
#[derive(Debug, Deserialize, Serialize, TS)]
#[derive(Clone, Debug, Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct PackageInfoShort {
pub release_notes: String,
pub release_notes: LocaleString,
}
#[derive(Debug, Deserialize, Serialize, TS, Parser, HasModel)]
@@ -89,17 +90,20 @@ impl GetPackageResponse {
let lesser_versions: BTreeMap<_, _> = self
.other_versions
.as_ref()
.clone()
.into_iter()
.flatten()
.filter(|(v, _)| ***v < *version)
.filter(|(v, _)| **v < *version)
.collect();
if !lesser_versions.is_empty() {
table.add_row(row![bc => "OLDER VERSIONS"]);
table.add_row(row![bc => "VERSION", "RELEASE NOTES"]);
for (version, info) in lesser_versions {
table.add_row(row![AsRef::<str>::as_ref(version), &info.release_notes]);
table.add_row(row![
AsRef::<str>::as_ref(&version),
&info.release_notes.localized()
]);
}
}
@@ -147,6 +151,7 @@ fn get_matching_models(
id,
source_version,
device_info,
target_version,
..
}: &GetPackageParams,
) -> Result<Vec<(PackageId, ExtendedVersion, Model<PackageVersionInfo>)>, Error> {
@@ -165,26 +170,29 @@ fn get_matching_models(
.as_entries()?
.into_iter()
.map(|(v, info)| {
let ev = ExtendedVersion::from(v);
Ok::<_, Error>(
if source_version.as_ref().map_or(Ok(true), |source_version| {
Ok::<_, Error>(
source_version.satisfies(
&info
.as_source_version()
.de()?
.unwrap_or(VersionRange::any()),
),
)
})? {
if target_version.as_ref().map_or(true, |tv| ev.satisfies(tv))
&& source_version.as_ref().map_or(Ok(true), |source_version| {
Ok::<_, Error>(
source_version.satisfies(
&info
.as_source_version()
.de()?
.unwrap_or(VersionRange::any()),
),
)
})?
{
let mut info = info.clone();
if let Some(device_info) = &device_info {
if info.for_device(device_info)? {
Some((k.clone(), ExtendedVersion::from(v), info))
Some((k.clone(), ev, info))
} else {
None
}
} else {
Some((k.clone(), ExtendedVersion::from(v), info))
Some((k.clone(), ev, info))
}
} else {
None
@@ -207,12 +215,7 @@ pub async fn get_package(ctx: RegistryContext, params: GetPackageParams) -> Resu
for (id, version, info) in get_matching_models(&peek.as_index().as_package(), &params)? {
let package_best = best.entry(id.clone()).or_default();
let package_other = other.entry(id.clone()).or_default();
if params
.target_version
.as_ref()
.map_or(true, |v| version.satisfies(v))
&& package_best.keys().all(|k| !(**k > version))
{
if package_best.keys().all(|k| !(**k > version)) {
for worse_version in package_best
.keys()
.filter(|k| ***k < version)
@@ -569,3 +572,42 @@ pub async fn cli_download(
Ok(())
}
#[test]
fn check_matching_info_short() {
use crate::registry::package::index::PackageMetadata;
use crate::s9pk::manifest::{Alerts, Description};
use crate::util::DataUrl;
let lang_map = |s: &str| {
LocaleString::LanguageMap([("en".into(), s.into())].into_iter().collect())
};
let info = PackageVersionInfo {
metadata: PackageMetadata {
title: "Test Package".into(),
icon: DataUrl::from_vec("image/png", vec![]),
description: Description {
short: lang_map("A short description"),
long: lang_map("A longer description of the test package"),
},
release_notes: lang_map("Initial release"),
git_hash: None,
license: "MIT".into(),
wrapper_repo: "https://github.com/example/wrapper".parse().unwrap(),
upstream_repo: "https://github.com/example/upstream".parse().unwrap(),
support_site: "https://example.com/support".parse().unwrap(),
marketing_site: "https://example.com".parse().unwrap(),
donation_url: None,
docs_url: None,
alerts: Alerts::default(),
dependency_metadata: BTreeMap::new(),
os_version: exver::Version::new([0, 3, 6], []),
sdk_version: None,
hardware_acceleration: false,
},
source_version: None,
s9pks: Vec::new(),
};
from_value::<PackageInfoShort>(to_value(&info).unwrap()).unwrap();
}