1+ use crate :: args:: InspectForTags ;
2+ use std:: process:: Command ;
3+
4+ #[ derive( Clone ) ]
5+ struct TagInfo {
6+ date : String ,
7+ name : String ,
8+ subject : String ,
9+ }
10+
11+ pub fn show_tags ( options : & InspectForTags ) -> Result < ( ) , String > {
12+ let output = Command :: new ( "git" )
13+ . args ( [
14+ "for-each-ref" ,
15+ "--sort=creatordate" , // Sort by date ascending
16+ "--format=%(creatordate:short)\t %(refname:short)\t %(subject)" ,
17+ "refs/tags" ,
18+ ] )
19+ . output ( )
20+ . map_err ( |e| e. to_string ( ) ) ?;
21+
22+ if !output. status . success ( ) {
23+ return Err ( String :: from_utf8_lossy ( & output. stderr ) . to_string ( ) ) ;
24+ }
25+
26+ let output_str = String :: from_utf8_lossy ( & output. stdout ) ;
27+ if output_str. is_empty ( ) {
28+ println ! ( "No tags found." ) ;
29+ return Ok ( ( ) ) ;
30+ }
31+
32+ let all_tags: Vec < TagInfo > = output_str
33+ . lines ( )
34+ . filter_map ( |line| {
35+ let parts: Vec < & str > = line. splitn ( 3 , '\t' ) . collect ( ) ;
36+ if parts. len ( ) == 3 {
37+ Some ( TagInfo {
38+ date : parts[ 0 ] . to_string ( ) ,
39+ name : parts[ 1 ] . to_string ( ) ,
40+ subject : parts[ 2 ] . to_string ( ) ,
41+ } )
42+ } else {
43+ None
44+ }
45+ } )
46+ . collect ( ) ;
47+
48+ let total_tags = all_tags. len ( ) ;
49+ let tags_to_display = if options. all {
50+ all_tags. clone ( )
51+ } else {
52+ let tags: Vec < TagInfo > = all_tags. iter ( ) . rev ( ) . take ( 10 ) . cloned ( ) . collect ( ) ;
53+ tags. into_iter ( ) . rev ( ) . collect ( )
54+ } ;
55+
56+ if tags_to_display. is_empty ( ) {
57+ println ! ( "No tags to display." ) ;
58+ return Ok ( ( ) ) ;
59+ }
60+
61+ if !options. all && total_tags > tags_to_display. len ( ) {
62+ if let ( Some ( first_tag) , Some ( last_tag) ) = ( all_tags. first ( ) , all_tags. last ( ) ) {
63+ println ! (
64+ "Showing the last {} of {} tags (from {} to {}). Use --all to see all." ,
65+ tags_to_display. len( ) ,
66+ total_tags,
67+ first_tag. date,
68+ last_tag. date
69+ ) ;
70+ println ! ( ) ; // Add a blank line for separation
71+ }
72+ }
73+
74+
75+ let mut max_tag_width = 0 ;
76+ for tag in & tags_to_display {
77+ if tag. name . len ( ) > max_tag_width {
78+ max_tag_width = tag. name . len ( ) ;
79+ }
80+ }
81+
82+ for tag in tags_to_display {
83+ println ! (
84+ "{} {:<width$} {}" ,
85+ tag. date,
86+ tag. name,
87+ tag. subject,
88+ width = max_tag_width
89+ ) ;
90+ }
91+
92+ Ok ( ( ) )
93+ }
0 commit comments