@@ -183,6 +183,9 @@ pub struct PackageMetadata {
183183
184184 #[ serde( skip_serializing_if = "is_empty_vec" ) ]
185185 pub replaces : Option < Vec < String > > ,
186+
187+ #[ serde( skip_serializing_if = "is_empty_vec" ) ]
188+ pub repology : Option < Vec < String > > ,
186189}
187190
188191impl PackageMetadata {
@@ -236,63 +239,87 @@ impl PackageMetadata {
236239 } else {
237240 Some ( recipe. provides . clone ( ) )
238241 } ,
242+ repology : if recipe. repology . is_empty ( ) {
243+ None
244+ } else {
245+ Some ( recipe. repology . clone ( ) )
246+ } ,
239247 disabled : if recipe. disabled { Some ( true ) } else { None } ,
240248 ..Default :: default ( )
241249 }
242250 }
243251
244252 /// Enrich metadata with OCI manifest data
245- pub fn enrich_from_manifest ( & mut self , manifest : & OciManifest , tag : & str ) {
253+ ///
254+ /// `ghcr_path` is the repository path (e.g., "pkgforge/bincache/hello/static")
255+ pub fn enrich_from_manifest ( & mut self , manifest : & OciManifest , ghcr_path : & str , tag : & str ) {
246256 // Get embedded JSON if available
247257 if let Ok ( Some ( pkg_json) ) = manifest. get_package_json ( ) {
248258 self . merge_from_json ( & pkg_json) ;
249259 }
250260
251- // GHCR info
252- self . ghcr_pkg = manifest. ghcr_pkg ( ) . map ( |s| s. to_string ( ) ) ;
261+ // GHCR info - construct from path and tag
262+ let ghcr_pkg = format ! ( "ghcr.io/{}:{}" , ghcr_path, tag) ;
263+ self . ghcr_pkg = Some ( ghcr_pkg. clone ( ) ) ;
264+ self . ghcr_url = Some ( format ! ( "https://ghcr.io/{}" , ghcr_path) ) ;
265+
253266 let size = manifest. total_size ( ) ;
254267 self . ghcr_size_raw = Some ( size) ;
255268 self . ghcr_size = Some ( format_size ( size) ) ;
256269 self . ghcr_files = Some ( manifest. filenames ( ) . into_iter ( ) . map ( |s| s. to_string ( ) ) . collect ( ) ) ;
257270
271+ // Version from annotations
272+ if let Some ( version) = manifest. get_annotation ( "dev.pkgforge.soar.version" ) {
273+ self . version = version. to_string ( ) ;
274+ } else if let Some ( version) = manifest. get_annotation ( "org.opencontainers.image.version" ) {
275+ self . version = version. to_string ( ) ;
276+ }
277+
278+ // Build date from annotations
279+ if let Some ( date) = manifest. get_annotation ( "dev.pkgforge.soar.push_date" ) {
280+ self . build_date = Some ( date. to_string ( ) ) ;
281+ } else if let Some ( date) = manifest. get_annotation ( "org.opencontainers.image.created" ) {
282+ self . build_date = Some ( date. to_string ( ) ) ;
283+ }
284+
258285 // Build info from annotations
259286 if self . build_id . is_none ( ) {
260287 let build_id = manifest. build_id ( ) . map ( |s| s. to_string ( ) ) ;
261288 self . build_id = build_id. clone ( ) ;
262289
263290 // Generate GitHub Actions URL if we have a build ID
264291 if let Some ( ref id) = build_id {
265- // Try to determine the repo from ghcr_pkg
266- if let Some ( ref ghcr_pkg) = self . ghcr_pkg {
267- let cache_type = if ghcr_pkg. contains ( "pkgcache" ) { "pkgcache" } else { "bincache" } ;
268- self . build_gha = Some ( format ! (
269- "https://github.com/pkgforge/{}/actions/runs/{}" ,
270- cache_type, id
271- ) ) ;
272- }
292+ let cache_type = if ghcr_path. contains ( "pkgcache" ) { "pkgcache" } else { "bincache" } ;
293+ self . build_gha = Some ( format ! (
294+ "https://github.com/pkgforge/{}/actions/runs/{}" ,
295+ cache_type, id
296+ ) ) ;
297+ }
298+ }
299+
300+ // Build script from annotations
301+ if self . build_script . is_none ( ) {
302+ if let Some ( script) = manifest. get_annotation ( "dev.pkgforge.soar.build_script" ) {
303+ self . build_script = Some ( script. to_string ( ) ) ;
273304 }
274305 }
275306
276- // Generate blob reference for main binary
307+ // Generate blob reference and download URLs
277308 if let Some ( filename) = manifest. filenames ( ) . first ( ) {
278309 self . ghcr_blob = manifest. get_blob_ref ( filename) ;
279310
280311 // Generate download URL and manifest URL
281- if let Some ( ref ghcr_pkg) = self . ghcr_pkg {
282- let base = ghcr_pkg. split ( ':' ) . next ( ) . unwrap_or ( ghcr_pkg) ;
283- let repo = base. replace ( "ghcr.io/" , "" ) ;
284- self . download_url = format ! (
285- "https://api.ghcr.pkgforge.dev/{}?tag={}&download={}" ,
286- repo, tag, filename
287- ) ;
288- self . manifest_url = Some ( format ! (
289- "https://api.ghcr.pkgforge.dev/{}?tag={}&manifest" ,
290- repo, tag
291- ) ) ;
292- // Size is usually same as ghcr_size for single binary packages
293- self . size_raw = self . ghcr_size_raw ;
294- self . size = self . ghcr_size . clone ( ) ;
295- }
312+ self . download_url = format ! (
313+ "https://api.ghcr.pkgforge.dev/{}?tag={}&download={}" ,
314+ ghcr_path, tag, filename
315+ ) ;
316+ self . manifest_url = Some ( format ! (
317+ "https://api.ghcr.pkgforge.dev/{}?tag={}&manifest" ,
318+ ghcr_path, tag
319+ ) ) ;
320+ // Size is usually same as ghcr_size for single binary packages
321+ self . size_raw = self . ghcr_size_raw ;
322+ self . size = self . ghcr_size . clone ( ) ;
296323 }
297324 }
298325
@@ -403,8 +430,8 @@ impl MetadataBuilder {
403430 }
404431 }
405432
406- pub fn with_manifest ( mut self , manifest : & OciManifest , tag : & str ) -> Self {
407- self . metadata . enrich_from_manifest ( manifest, tag) ;
433+ pub fn with_manifest ( mut self , manifest : & OciManifest , ghcr_path : & str , tag : & str ) -> Self {
434+ self . metadata . enrich_from_manifest ( manifest, ghcr_path , tag) ;
408435 self
409436 }
410437
0 commit comments