@@ -53,26 +53,38 @@ pub(super) fn is_codspeed_valgrind_installation_supported(system_info: &SystemIn
5353 get_codspeed_valgrind_target ( system_info) . is_ok ( )
5454}
5555
56- /// Parse a valgrind version string and extract the semantic version.
57- /// Expected format: "valgrind-3.25.1.codspeed" or "3.25.1.codspeed"
58- /// Returns Some(Version) if parsing succeeds, None otherwise.
59- fn parse_valgrind_codspeed_version ( version_str : & str ) -> Option < Version > {
60- let version_str = version_str. trim ( ) ;
61-
62- // Extract the version numbers before .codspeed
63- let version_part = if let Some ( codspeed_idx) = version_str. find ( ".codspeed" ) {
64- & version_str[ ..codspeed_idx]
65- } else {
66- return None ;
67- } ;
56+ #[ derive( Debug , Clone , PartialEq , Eq ) ]
57+ struct ValgrindVersion {
58+ semver : Version ,
59+ codspeed_iteration : Option < u32 > ,
60+ }
6861
69- // Remove "valgrind-" prefix if present
70- let version_part = version_part
62+ /// Parse a valgrind version string and extract the upstream semver plus the
63+ /// optional CodSpeed iteration number.
64+ ///
65+ /// Accepted formats:
66+ /// - `valgrind-3.25.1.codspeed` (legacy, no iteration)
67+ /// - `valgrind-3.25.1.codspeed2` (with iteration)
68+ /// - same forms without the `valgrind-` prefix
69+ fn parse_valgrind_codspeed_version ( version_str : & str ) -> Option < ValgrindVersion > {
70+ let stripped = version_str
71+ . trim ( )
7172 . strip_prefix ( "valgrind-" )
72- . unwrap_or ( version_part) ;
73+ . unwrap_or ( version_str. trim ( ) ) ;
74+
75+ let ( semver_part, iteration_part) = stripped. split_once ( ".codspeed" ) ?;
76+ let semver = Version :: parse ( semver_part) . ok ( ) ?;
77+
78+ let codspeed_iteration = if iteration_part. is_empty ( ) {
79+ None
80+ } else {
81+ Some ( iteration_part. parse :: < u32 > ( ) . ok ( ) ?)
82+ } ;
7383
74- // Parse using semver
75- Version :: parse ( version_part) . ok ( )
84+ Some ( ValgrindVersion {
85+ semver,
86+ codspeed_iteration,
87+ } )
7688}
7789
7890const TOOL_NAME : & str = "valgrind" ;
@@ -136,7 +148,7 @@ pub fn get_valgrind_status() -> ToolStatus {
136148 } ;
137149 } ;
138150
139- if installed_version < VALGRIND_CODSPEED_VERSION {
151+ if installed_version. semver < VALGRIND_CODSPEED_VERSION {
140152 return ToolStatus {
141153 tool_name,
142154 status : ToolInstallStatus :: IncorrectVersion {
@@ -275,32 +287,49 @@ mod tests {
275287 #[ test]
276288 fn test_parse_valgrind_codspeed_version_with_prefix ( ) {
277289 let version = parse_valgrind_codspeed_version ( "valgrind-3.25.1.codspeed" ) . unwrap ( ) ;
278- assert_eq ! ( version, Version :: new( 3 , 25 , 1 ) ) ;
290+ assert_eq ! ( version. semver, Version :: new( 3 , 25 , 1 ) ) ;
291+ assert_eq ! ( version. codspeed_iteration, None ) ;
279292 }
280293
281294 #[ test]
282295 fn test_parse_valgrind_codspeed_version_without_prefix ( ) {
283296 let version = parse_valgrind_codspeed_version ( "3.25.1.codspeed" ) . unwrap ( ) ;
284- assert_eq ! ( version, Version :: new( 3 , 25 , 1 ) ) ;
297+ assert_eq ! ( version. semver, Version :: new( 3 , 25 , 1 ) ) ;
298+ assert_eq ! ( version. codspeed_iteration, None ) ;
285299 }
286300
287301 #[ test]
288302 fn test_parse_valgrind_codspeed_version_higher_patch ( ) {
289303 let version = parse_valgrind_codspeed_version ( "valgrind-3.25.2.codspeed" ) . unwrap ( ) ;
290- assert_eq ! ( version, Version :: new( 3 , 25 , 2 ) ) ;
304+ assert_eq ! ( version. semver , Version :: new( 3 , 25 , 2 ) ) ;
291305 }
292306
293307 #[ test]
294308 fn test_parse_valgrind_codspeed_version_with_newline ( ) {
295309 let version = parse_valgrind_codspeed_version ( "valgrind-3.25.1.codspeed\n " ) . unwrap ( ) ;
296- assert_eq ! ( version, Version :: new( 3 , 25 , 1 ) ) ;
310+ assert_eq ! ( version. semver , Version :: new( 3 , 25 , 1 ) ) ;
297311 }
298312
299313 #[ test]
300314 fn test_parse_valgrind_codspeed_version_without_codspeed_suffix ( ) {
301315 assert_eq ! ( parse_valgrind_codspeed_version( "valgrind-3.25.1" ) , None ) ;
302316 }
303317
318+ #[ test]
319+ fn test_parse_valgrind_codspeed_version_iterations_are_differentiated ( ) {
320+ let legacy = parse_valgrind_codspeed_version ( "valgrind-3.26.0.codspeed" ) . unwrap ( ) ;
321+ let v1 = parse_valgrind_codspeed_version ( "valgrind-3.26.0.codspeed1" ) . unwrap ( ) ;
322+ let v2 = parse_valgrind_codspeed_version ( "valgrind-3.26.0.codspeed2" ) . unwrap ( ) ;
323+
324+ assert_eq ! ( legacy. semver, v1. semver) ;
325+ assert_eq ! ( legacy. codspeed_iteration, None ) ;
326+ assert_eq ! ( v1. codspeed_iteration, Some ( 1 ) ) ;
327+ assert_eq ! ( v2. codspeed_iteration, Some ( 2 ) ) ;
328+
329+ assert_ne ! ( legacy, v1) ;
330+ assert_ne ! ( v1, v2) ;
331+ }
332+
304333 #[ test]
305334 fn test_parse_valgrind_codspeed_version_invalid_format ( ) {
306335 assert_eq ! (
0 commit comments