@@ -59,26 +59,18 @@ pub struct Asset {
5959 pub size : u64 ,
6060}
6161
62- /// Platform specification for asset matching
62+ /// Platform specification for asset matching (Linux only)
6363#[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
6464pub enum Platform {
6565 LinuxX86_64 ,
6666 LinuxAarch64 ,
67- DarwinX86_64 ,
68- DarwinAarch64 ,
69- WindowsX86_64 ,
70- WindowsAarch64 ,
7167}
7268
7369impl std:: fmt:: Display for Platform {
7470 fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
7571 match self {
7672 Platform :: LinuxX86_64 => write ! ( f, "linux-x86_64" ) ,
7773 Platform :: LinuxAarch64 => write ! ( f, "linux-aarch64" ) ,
78- Platform :: DarwinX86_64 => write ! ( f, "darwin-x86_64" ) ,
79- Platform :: DarwinAarch64 => write ! ( f, "darwin-aarch64" ) ,
80- Platform :: WindowsX86_64 => write ! ( f, "windows-x86_64" ) ,
81- Platform :: WindowsAarch64 => write ! ( f, "windows-aarch64" ) ,
8274 }
8375 }
8476}
@@ -100,51 +92,21 @@ impl Platform {
10092 "aarch64-unknown-linux-gnu" ,
10193 "aarch64-unknown-linux-musl" ,
10294 ] ,
103- Platform :: DarwinX86_64 => & [
104- "darwin-x86_64" ,
105- "darwin-amd64" ,
106- "darwin-x64" ,
107- "macos-x86_64" ,
108- "osx-x86_64" ,
109- "x86_64-apple-darwin" ,
110- ] ,
111- Platform :: DarwinAarch64 => & [
112- "darwin-aarch64" ,
113- "darwin-arm64" ,
114- "macos-aarch64" ,
115- "macos-arm64" ,
116- "osx-arm64" ,
117- "aarch64-apple-darwin" ,
118- ] ,
119- Platform :: WindowsX86_64 => & [
120- "windows-x86_64" ,
121- "windows-amd64" ,
122- "windows-x64" ,
123- "win-x86_64" ,
124- "win-amd64" ,
125- "x86_64-pc-windows-msvc" ,
126- "x86_64-pc-windows-gnu" ,
127- ] ,
128- Platform :: WindowsAarch64 => & [
129- "windows-aarch64" ,
130- "windows-arm64" ,
131- "win-aarch64" ,
132- "win-arm64" ,
133- "aarch64-pc-windows-msvc" ,
134- ] ,
13595 }
13696 }
13797
98+ /// Get supported archive extensions
99+ #[ allow( dead_code) ]
100+ fn extensions ( & self ) -> & [ & ' static str ] {
101+ & [ ".tar.gz" , ".tar.xz" , ".tar.bz2" , ".tgz" , ".zip" ]
102+ }
103+
138104 /// Detect the current platform
139105 pub fn current ( ) -> Result < Self > {
140- match ( std:: env:: consts:: OS , std:: env:: consts:: ARCH ) {
141- ( "linux" , "x86_64" ) => Ok ( Platform :: LinuxX86_64 ) ,
142- ( "linux" , "aarch64" ) => Ok ( Platform :: LinuxAarch64 ) ,
143- ( "macos" , "x86_64" ) => Ok ( Platform :: DarwinX86_64 ) ,
144- ( "macos" , "aarch64" ) | ( "macos" , "arm64" ) => Ok ( Platform :: DarwinAarch64 ) ,
145- ( "windows" , "x86_64" ) => Ok ( Platform :: WindowsX86_64 ) ,
146- ( "windows" , "aarch64" ) | ( "windows" , "arm64" ) => Ok ( Platform :: WindowsAarch64 ) ,
147- ( os, arch) => bail ! ( "Unsupported platform: {}-{}" , os, arch) ,
106+ match std:: env:: consts:: ARCH {
107+ "x86_64" => Ok ( Platform :: LinuxX86_64 ) ,
108+ "aarch64" | "arm64" => Ok ( Platform :: LinuxAarch64 ) ,
109+ arch => bail ! ( "Unsupported architecture: {}" , arch) ,
148110 }
149111 }
150112}
@@ -404,24 +366,38 @@ pub fn find_matching_asset(
404366 let name_lower = asset. name . to_lowercase ( ) ;
405367 let mut score = 0 ;
406368
407- // Check platform aliases
369+ // Check platform aliases (specific arch match = +10)
408370 for alias in aliases {
409371 if name_lower. contains ( alias) {
410372 score += 10 ;
411373 break ;
412374 }
413375 }
414376
377+ // Generic "linux" match (no arch specified) = +5
378+ if score == 0 && name_lower. contains ( "linux" ) {
379+ score += 5 ;
380+ }
381+
415382 // Only consider archives if platform matched
416- if score >= 10 {
417- // Prefer archives over bare binaries (but still allow bare binaries)
383+ if score >= 5 {
384+ // Prefer archives over bare binaries
418385 if name_lower. ends_with ( ".tar.gz" )
419386 || name_lower. ends_with ( ".tgz" )
420387 || name_lower. ends_with ( ".tar.xz" )
388+ || name_lower. ends_with ( ".tar.bz2" )
421389 || name_lower. ends_with ( ".zip" )
390+ || name_lower. ends_with ( ".appimage" )
391+ || name_lower. ends_with ( ".deb" )
392+ || name_lower. ends_with ( ".rpm" )
393+ || name_lower. ends_with ( ".tar" )
422394 {
423395 score += 5 ;
424396 }
397+ // Shell scripts get small bonus
398+ if name_lower. ends_with ( ".sh" ) {
399+ score += 2 ;
400+ }
425401 }
426402
427403 // Avoid checksum-like names
@@ -598,8 +574,8 @@ mod tests {
598574 } ,
599575 Asset {
600576 id: 2 ,
601- name: "app-darwin-arm64 .tar.gz" . to_string( ) ,
602- browser_download_url: "https://example.com/darwin " . to_string( ) ,
577+ name: "app-linux-aarch64 .tar.gz" . to_string( ) ,
578+ browser_download_url: "https://example.com/aarch64 " . to_string( ) ,
603579 size: 1000 ,
604580 } ,
605581 Asset {
@@ -614,8 +590,110 @@ mod tests {
614590 let asset = find_matching_asset ( & release, Platform :: LinuxX86_64 ) . unwrap ( ) ;
615591 assert_eq ! ( asset. name, "app-linux-x86_64.tar.gz" ) ;
616592
617- let asset = find_matching_asset ( & release, Platform :: DarwinAarch64 ) . unwrap ( ) ;
618- assert_eq ! ( asset. name, "app-darwin-arm64.tar.gz" ) ;
593+ let asset = find_matching_asset ( & release, Platform :: LinuxAarch64 ) . unwrap ( ) ;
594+ assert_eq ! ( asset. name, "app-linux-aarch64.tar.gz" ) ;
595+ }
596+
597+ #[ test]
598+ fn test_find_matching_asset_generic_linux ( ) {
599+ // Test generic "linux" assets (no arch specified)
600+ let release = Release {
601+ tag_name : "v1.0.0" . to_string ( ) ,
602+ name : None ,
603+ body : None ,
604+ assets : vec ! [ Asset {
605+ id: 1 ,
606+ name: "app-linux.tar.gz" . to_string( ) ,
607+ browser_download_url: "https://example.com/linux" . to_string( ) ,
608+ size: 1000 ,
609+ } ] ,
610+ } ;
611+
612+ // Generic linux should match both x86_64 and aarch64 (lower priority)
613+ let asset = find_matching_asset ( & release, Platform :: LinuxX86_64 ) . unwrap ( ) ;
614+ assert_eq ! ( asset. name, "app-linux.tar.gz" ) ;
615+
616+ let asset = find_matching_asset ( & release, Platform :: LinuxAarch64 ) . unwrap ( ) ;
617+ assert_eq ! ( asset. name, "app-linux.tar.gz" ) ;
618+ }
619+
620+ #[ test]
621+ fn test_find_matching_asset_deb_rpm ( ) {
622+ // Test .deb and .rpm packages
623+ let release = Release {
624+ tag_name : "v1.0.0" . to_string ( ) ,
625+ name : None ,
626+ body : None ,
627+ assets : vec ! [
628+ Asset {
629+ id: 1 ,
630+ name: "app_1.0.0_linux_amd64.deb" . to_string( ) ,
631+ browser_download_url: "https://example.com/deb" . to_string( ) ,
632+ size: 1000 ,
633+ } ,
634+ Asset {
635+ id: 2 ,
636+ name: "app-1.0.0-linux-x86_64.rpm" . to_string( ) ,
637+ browser_download_url: "https://example.com/rpm" . to_string( ) ,
638+ size: 1000 ,
639+ } ,
640+ ] ,
641+ } ;
642+
643+ let asset = find_matching_asset ( & release, Platform :: LinuxX86_64 ) . unwrap ( ) ;
644+ // Should prefer .deb or .rpm with archive bonus
645+ assert ! ( asset. name. ends_with( ".deb" ) || asset. name. ends_with( ".rpm" ) ) ;
646+ }
647+
648+ #[ test]
649+ fn test_find_matching_asset_shell_script ( ) {
650+ // Test .sh shell scripts get small bonus
651+ let release = Release {
652+ tag_name : "v1.0.0" . to_string ( ) ,
653+ name : None ,
654+ body : None ,
655+ assets : vec ! [ Asset {
656+ id: 1 ,
657+ name: "install-linux-x86_64.sh" . to_string( ) ,
658+ browser_download_url: "https://example.com/sh" . to_string( ) ,
659+ size: 1000 ,
660+ } ] ,
661+ } ;
662+
663+ let asset = find_matching_asset ( & release, Platform :: LinuxX86_64 ) . unwrap ( ) ;
664+ assert_eq ! ( asset. name, "install-linux-x86_64.sh" ) ;
665+ }
666+
667+ #[ test]
668+ fn test_find_matching_asset_prefers_specific_arch ( ) {
669+ // When specific arch is available, prefer it over generic
670+ let release = Release {
671+ tag_name : "v1.0.0" . to_string ( ) ,
672+ name : None ,
673+ body : None ,
674+ assets : vec ! [
675+ Asset {
676+ id: 1 ,
677+ name: "app-linux.tar.gz" . to_string( ) ,
678+ browser_download_url: "https://example.com/generic" . to_string( ) ,
679+ size: 1000 ,
680+ } ,
681+ Asset {
682+ id: 2 ,
683+ name: "app-linux-x86_64.tar.gz" . to_string( ) ,
684+ browser_download_url: "https://example.com/specific" . to_string( ) ,
685+ size: 1000 ,
686+ } ,
687+ ] ,
688+ } ;
689+
690+ // Should prefer the x86_64 specific asset
691+ let asset = find_matching_asset ( & release, Platform :: LinuxX86_64 ) . unwrap ( ) ;
692+ assert_eq ! ( asset. name, "app-linux-x86_64.tar.gz" ) ;
693+
694+ // aarch64 should fall back to generic
695+ let asset = find_matching_asset ( & release, Platform :: LinuxAarch64 ) . unwrap ( ) ;
696+ assert_eq ! ( asset. name, "app-linux.tar.gz" ) ;
619697 }
620698
621699 #[ test]
0 commit comments