@@ -165,16 +165,86 @@ export async function selectPackageV2(): Promise<WidgetPkg | ModulePkg> {
165165}
166166
167167const PADDING = 60 ;
168+ // eslint-disable-next-line no-control-regex
169+ const ANSI_RE = / \x1B \[ [ 0 - 9 ; ] * m / g;
170+ const visibleLen = ( s : string ) : number => s . replace ( ANSI_RE , "" ) . length ;
171+
172+ function wrapLine ( line : string , maxLen : number ) : string [ ] {
173+ if ( maxLen <= 0 ) return [ line ] ;
174+ const result : string [ ] = [ ] ;
175+ let remaining = line ;
176+ while ( remaining . length > maxLen ) {
177+ result . push ( remaining . slice ( 0 , maxLen ) ) ;
178+ remaining = remaining . slice ( maxLen ) ;
179+ }
180+ result . push ( remaining ) ;
181+ return result ;
182+ }
183+
184+ function printSectionBox ( type : string , logs : string [ ] , treePrefix : string , boxWidth : number ) : void {
185+ const headerInner = `─ ${ type } ` ;
186+ const topDashes = "─" . repeat ( Math . max ( 0 , boxWidth - 2 - headerInner . length ) ) ;
187+ console . log ( `${ treePrefix } ${ chalk . dim ( `┌${ headerInner } ${ topDashes } ┐` ) } ` ) ;
188+ const contentWidth = boxWidth - 4 ; // subtract "│ " left and " │" right
189+ for ( const log of logs ) {
190+ for ( const wrappedLine of wrapLine ( log , contentWidth ) ) {
191+ console . log ( `${ treePrefix } ${ chalk . dim ( "│" ) } ${ wrappedLine . padEnd ( contentWidth ) } ${ chalk . dim ( "│" ) } ` ) ;
192+ }
193+ }
194+ console . log ( `${ treePrefix } ${ chalk . dim ( `└${ "─" . repeat ( Math . max ( 0 , boxWidth - 2 ) ) } ┘` ) } ` ) ;
195+ }
196+
197+ function printUnreleasedChangelog (
198+ changelog : WidgetChangelogFileWrapper | ModuleChangelogFileWrapper ,
199+ treePrefix : string
200+ ) : void {
201+ const unreleased = changelog . changelog . content [ 0 ] ;
202+ const subcomponents = "subcomponents" in unreleased ? unreleased . subcomponents : [ ] ;
203+
204+ const termWidth = process . stdout . columns || 100 ;
205+ const boxWidth = Math . max ( 20 , termWidth - visibleLen ( treePrefix ) ) ;
206+
207+ for ( const section of unreleased . sections ) {
208+ if ( section . logs . length === 0 ) continue ;
209+ printSectionBox (
210+ section . type ,
211+ section . logs . map ( l => `- ${ l } ` ) ,
212+ treePrefix ,
213+ boxWidth
214+ ) ;
215+ }
216+
217+ for ( const sub of subcomponents ) {
218+ const label = "version" in sub ? `${ sub . name } [${ sub . version . format ( ) } ]` : sub . name ;
219+ console . log ( `${ treePrefix } ${ chalk . yellow ( label ) } ` ) ;
220+ for ( const section of sub . sections ) {
221+ if ( section . logs . length === 0 ) continue ;
222+ printSectionBox (
223+ section . type ,
224+ section . logs . map ( l => `- ${ l } ` ) ,
225+ `${ treePrefix } ` ,
226+ Math . max ( 20 , boxWidth - 2 )
227+ ) ;
228+ }
229+ }
230+ }
231+
168232export function printPkgInformation ( pkg : WidgetPkg | ModulePkg ) : void {
169233 console . log (
170234 `${ shortName ( pkg . info . name ) . padEnd ( PADDING + 3 , " " ) } ${ chalk . bold ( pkg . info . version . format ( ) ) } ${ pkg . changelog . hasUnreleasedLogs ( ) ? "🆕" : " " } `
171235 ) ;
236+ if ( pkg . changelog . hasUnreleasedLogs ( ) ) {
237+ printUnreleasedChangelog ( pkg . changelog , " " ) ;
238+ }
172239 if ( pkg . widgets . length ) {
173240 pkg . widgets . forEach ( ( widget , i ) => {
174241 const isLast = i === pkg . widgets . length - 1 ;
175242 console . log (
176243 `${ isLast ? "└" : "├" } ─ ${ shortName ( widget . info . name ) . padEnd ( PADDING , " " ) } ${ chalk . dim ( widget . info . version . format ( ) ) } ${ widget . changelog . hasUnreleasedLogs ( ) ? "🆕" : "" } `
177244 ) ;
245+ if ( widget . changelog . hasUnreleasedLogs ( ) ) {
246+ printUnreleasedChangelog ( widget . changelog , isLast ? " " : "│ " ) ;
247+ }
178248 } ) ;
179249 }
180250}
0 commit comments