@@ -303,65 +303,157 @@ func appendComponentSection(sb *strings.Builder, issue testapi.Issue, findingTyp
303303
304304// appendDependencyPathsSection adds dependency path information to the markdown
305305func appendDependencyPathsSection (sb * strings.Builder , issue testapi.Issue , componentName string ) {
306- var dependencyPaths [][]string
307- if val , ok := issue .GetData (testapi .DataKeyDependencyPaths ); ok {
308- // Handle new format: [][]Package (structured data)
309- if paths , ok := val .([][]testapi.Package ); ok {
310- for _ , path := range paths {
311- formattedPath := make ([]string , len (path ))
312- for i , pkg := range path {
313- formattedPath [i ] = fmt .Sprintf ("%s@%s" , pkg .Name , pkg .Version )
314- }
315- dependencyPaths = append (dependencyPaths , formattedPath )
316- }
317- } else if paths , ok := val .([][]string ); ok {
318- // Backward compatibility: [][]string format
319- dependencyPaths = paths
320- } else if strs , ok := val .([]string ); ok {
321- // Backward compatibility: convert old format (pre-joined strings) to new format
322- for _ , pathStr := range strs {
323- parts := strings .Split (pathStr , " › " )
324- dependencyPaths = append (dependencyPaths , parts )
325- }
306+ val , ok := issue .GetData (testapi .DataKeyDependencyPaths )
307+ if ! ok {
308+ if componentName != "" {
309+ appendFallbackIntroduction (sb , issue , componentName )
310+ }
311+ return
312+ }
313+
314+ // Handle new format: [][]Package (structured data)
315+ if paths , ok := val .([][]testapi.Package ); ok {
316+ if len (paths ) > 0 {
317+ appendDependencyPathsSummaryFromPackages (sb , paths )
318+ appendDetailedPathsFromPackages (sb , paths )
319+ }
320+ return
321+ }
322+
323+ // Backward compatibility: [][]string format
324+ if paths , ok := val .([][]string ); ok {
325+ if len (paths ) > 0 {
326+ appendDependencyPathsSummary (sb , paths )
327+ appendDetailedPaths (sb , paths )
328+ }
329+ return
330+ }
331+
332+ // Backward compatibility: []string format (old pre-joined strings)
333+ if strs , ok := val .([]string ); ok {
334+ if len (strs ) > 0 {
335+ appendDependencyPathsFromStrings (sb , strs )
326336 }
337+ return
327338 }
328339
329- if len (dependencyPaths ) > 0 {
330- appendDependencyPathsSummary (sb , dependencyPaths )
331- appendDetailedPaths (sb , dependencyPaths )
332- } else if componentName != "" {
340+ // No valid paths found
341+ if componentName != "" {
333342 appendFallbackIntroduction (sb , issue , componentName )
334343 }
335344}
336345
337- // appendDependencyPathsSummary adds a summary of dependency paths
338- func appendDependencyPathsSummary (sb * strings.Builder , dependencyPaths [][]string ) {
339- if len (dependencyPaths ) == 0 {
346+ // appendDependencyPathsSummaryFromPackages writes summary directly without intermediate allocations
347+ func appendDependencyPathsSummaryFromPackages (sb * strings.Builder , paths [][]testapi. Package ) {
348+ if len (paths ) == 0 || len ( paths [ 0 ] ) == 0 {
340349 return
341350 }
342351
343- firstPath := dependencyPaths [0 ]
344- introduction := "* Introduced through: %s\n "
352+ firstPath := paths [0 ]
353+ sb .WriteString ("* Introduced through: " )
354+
355+ // Format first package
356+ sb .WriteString (firstPath [0 ].Name )
357+ sb .WriteByte ('@' )
358+ sb .WriteString (firstPath [0 ].Version )
359+
360+ if len (firstPath ) > 2 {
361+ sb .WriteString (", " )
362+ sb .WriteString (firstPath [1 ].Name )
363+ sb .WriteByte ('@' )
364+ sb .WriteString (firstPath [1 ].Version )
365+ sb .WriteString (" and others" )
366+ } else if len (firstPath ) == 2 {
367+ sb .WriteString (" and " )
368+ sb .WriteString (firstPath [1 ].Name )
369+ sb .WriteByte ('@' )
370+ sb .WriteString (firstPath [1 ].Version )
371+ }
345372
346- if len (firstPath ) == 0 {
373+ sb .WriteByte ('\n' )
374+ }
375+
376+ // appendDetailedPathsFromPackages writes paths directly without intermediate strings
377+ func appendDetailedPathsFromPackages (sb * strings.Builder , paths [][]testapi.Package ) {
378+ sb .WriteString ("### Detailed paths\n " )
379+ for _ , path := range paths {
380+ sb .WriteString ("* _Introduced through_: " )
381+ for i , pkg := range path {
382+ if i > 0 {
383+ sb .WriteString (" › " )
384+ }
385+ sb .WriteString (pkg .Name )
386+ sb .WriteByte ('@' )
387+ sb .WriteString (pkg .Version )
388+ }
389+ sb .WriteByte ('\n' )
390+ }
391+ }
392+
393+ // appendDependencyPathsSummary adds a summary of dependency paths ([][]string format)
394+ func appendDependencyPathsSummary (sb * strings.Builder , dependencyPaths [][]string ) {
395+ if len (dependencyPaths ) == 0 || len (dependencyPaths [0 ]) == 0 {
347396 return
348397 }
349398
350- dependencyPath := firstPath [0 ]
399+ firstPath := dependencyPaths [0 ]
400+ sb .WriteString ("* Introduced through: " )
401+ sb .WriteString (firstPath [0 ])
402+
351403 if len (firstPath ) > 2 {
352- dependencyPath = fmt .Sprintf ("%s, %s and others" , firstPath [0 ], firstPath [1 ])
404+ sb .WriteString (", " )
405+ sb .WriteString (firstPath [1 ])
406+ sb .WriteString (" and others" )
353407 } else if len (firstPath ) == 2 {
354- dependencyPath = fmt .Sprintf ("%s and %s" , firstPath [0 ], firstPath [1 ])
408+ sb .WriteString (" and " )
409+ sb .WriteString (firstPath [1 ])
355410 }
356- fmt .Fprintf (sb , introduction , dependencyPath )
411+
412+ sb .WriteByte ('\n' )
357413}
358414
359- // appendDetailedPaths adds detailed dependency path information
415+ // appendDetailedPaths adds detailed dependency path information ([][]string format)
360416func appendDetailedPaths (sb * strings.Builder , dependencyPaths [][]string ) {
361417 sb .WriteString ("### Detailed paths\n " )
362418 for _ , pathParts := range dependencyPaths {
363- formattedPath := strings .Join (pathParts , " › " )
364- sb .WriteString (fmt .Sprintf ("* _Introduced through_: %s\n " , formattedPath ))
419+ sb .WriteString ("* _Introduced through_: " )
420+ for i , part := range pathParts {
421+ if i > 0 {
422+ sb .WriteString (" › " )
423+ }
424+ sb .WriteString (part )
425+ }
426+ sb .WriteByte ('\n' )
427+ }
428+ }
429+
430+ // appendDependencyPathsFromStrings handles old format (pre-joined strings)
431+ func appendDependencyPathsFromStrings (sb * strings.Builder , paths []string ) {
432+ if len (paths ) == 0 {
433+ return
434+ }
435+
436+ // Summary from first path
437+ firstPath := paths [0 ]
438+ parts := strings .SplitN (firstPath , " › " , 3 ) // Only split what we need
439+ sb .WriteString ("* Introduced through: " )
440+ sb .WriteString (parts [0 ])
441+ if len (parts ) > 2 {
442+ sb .WriteString (", " )
443+ sb .WriteString (parts [1 ])
444+ sb .WriteString (" and others" )
445+ } else if len (parts ) == 2 {
446+ sb .WriteString (" and " )
447+ sb .WriteString (parts [1 ])
448+ }
449+ sb .WriteByte ('\n' )
450+
451+ // Detailed paths
452+ sb .WriteString ("### Detailed paths\n " )
453+ for _ , pathStr := range paths {
454+ sb .WriteString ("* _Introduced through_: " )
455+ sb .WriteString (pathStr )
456+ sb .WriteByte ('\n' )
365457 }
366458}
367459
0 commit comments