@@ -26,7 +26,12 @@ impl SupportedOs {
2626 match os {
2727 "linux" => {
2828 let os_id = System :: distribution_id ( ) ;
29- Ok ( Self :: Linux ( LinuxDistribution :: from_id ( & os_id, & os_version) ) )
29+ let os_id_like = System :: distribution_id_like ( ) ;
30+ Ok ( Self :: Linux ( LinuxDistribution :: from_id_like (
31+ & os_id,
32+ & os_id_like,
33+ & os_version,
34+ ) ) )
3035 }
3136 "macos" => Ok ( Self :: Macos {
3237 version : os_version,
@@ -99,6 +104,21 @@ impl LinuxDistribution {
99104 }
100105 }
101106
107+ /// Build a [`LinuxDistribution`] from the `sysinfo`-reported `os_id` and `os_id_like` fields.
108+ /// This is needed to handle cases like PopOS (`os_id` = "pop" and `os_id_like` = ["ubuntu"]).
109+ fn from_id_like ( os_id : & str , os_id_like : & [ String ] , version : & str ) -> Self {
110+ let by_id = Self :: from_id ( os_id, version) ;
111+ if matches ! ( by_id, Self :: Other { .. } ) {
112+ for like_id in os_id_like {
113+ let by_like_id = Self :: from_id ( like_id, version) ;
114+ if !matches ! ( by_like_id, Self :: Other { .. } ) {
115+ return by_like_id;
116+ }
117+ }
118+ }
119+ by_id
120+ }
121+
102122 /// The distro id as it appears on the wire (matches `sysinfo::System::distribution_id()`).
103123 pub fn id ( & self ) -> & str {
104124 match self {
@@ -137,4 +157,42 @@ mod tests {
137157 let err = SupportedOs :: from_os ( "windows" ) . unwrap_err ( ) ;
138158 assert_eq ! ( err. to_string( ) , "Unsupported operating system: windows" ) ;
139159 }
160+
161+ #[ test]
162+ fn pop_os_resolves_to_ubuntu_via_id_like ( ) {
163+ // Pop!_OS: ID=pop, ID_LIKE="ubuntu debian"
164+ let distro = LinuxDistribution :: from_id_like (
165+ "pop" ,
166+ & [ String :: from ( "ubuntu" ) , String :: from ( "debian" ) ] ,
167+ "24.04" ,
168+ ) ;
169+ assert ! (
170+ matches!( distro, LinuxDistribution :: Ubuntu { .. } ) ,
171+ "got {distro}"
172+ ) ;
173+ }
174+
175+ #[ test]
176+ fn ubuntu_resolves_directly_without_id_like ( ) {
177+ // Ubuntu laptop: ID=ubuntu, ID_LIKE="debian" — primary id wins, no fallback needed
178+ let distro = LinuxDistribution :: from_id_like ( "ubuntu" , & [ String :: from ( "debian" ) ] , "24.04" ) ;
179+ assert ! (
180+ matches!( distro, LinuxDistribution :: Ubuntu { .. } ) ,
181+ "got {distro}"
182+ ) ;
183+ }
184+
185+ #[ test]
186+ fn centos_with_unrecognized_parents_is_other ( ) {
187+ // CentOS server: ID=centos, ID_LIKE="rhel fedora" — neither parent is known
188+ let distro = LinuxDistribution :: from_id_like (
189+ "centos" ,
190+ & [ String :: from ( "rhel" ) , String :: from ( "fedora" ) ] ,
191+ "9" ,
192+ ) ;
193+ assert ! (
194+ matches!( & distro, LinuxDistribution :: Other { name, .. } if name == "centos" ) ,
195+ "got {distro}"
196+ ) ;
197+ }
140198}
0 commit comments