1
+ import { simpleGit } from 'simple-git' ;
2
+
3
+ const REPO_URL = 'https://github.com/HeyPuter/puter' ;
4
+
5
+ const params = {
6
+ from : 'v2.3.0' ,
7
+ // from: 'v2.4.0',
8
+ to : 'v2.5.0' ,
9
+ date : '2024-07-08' ,
10
+ } ;
11
+
12
+ const git = simpleGit ( ) ;
13
+ const log = await git . log ( { from : params . from } ) ;
14
+ const commits = log . all ;
15
+
16
+ const CC_REGEX = / ^ ( [ a - z ] + ) ( \( [ a - z ] + \) ) ? : \s ( .* ) / ;
17
+ const parse_conventional_commit = message => {
18
+ const parts = CC_REGEX . exec ( message ) ;
19
+ if ( ! parts ) return null ;
20
+ let [ match , type , scope , summary ] = parts ;
21
+ if ( ! match ) return null ;
22
+ if ( scope ) scope = scope . slice ( 1 , - 1 ) ;
23
+ return { type, scope, summary } ;
24
+ } ;
25
+
26
+ const types = {
27
+ feat : {
28
+ label : 'Features'
29
+ } ,
30
+ fix : {
31
+ label : 'Bug Fixes'
32
+ }
33
+ } ;
34
+
35
+ const scopes = {
36
+ puter : {
37
+ label : 'Puter'
38
+ } ,
39
+ phoenix : {
40
+ label : 'Phoenix Shell'
41
+ } ,
42
+ git : {
43
+ label : 'Puter Git'
44
+ } ,
45
+ backend : {
46
+ label : 'Backend'
47
+ } ,
48
+ gui : {
49
+ label : 'GUI'
50
+ } ,
51
+ } ;
52
+
53
+ const scope_aliases = {
54
+ main : 'puter' ,
55
+ ui : 'gui' ,
56
+ parsely : 'phoenix' ,
57
+ } ;
58
+
59
+ const data = { } ;
60
+ const ensure_scope = name => {
61
+ if ( data [ name ] ) return ;
62
+ const o = data [ name ] = { } ;
63
+ for ( const k in types ) o [ k ] = [ ] ;
64
+ } ;
65
+
66
+ for ( const commit of commits ) {
67
+ const meta = parse_conventional_commit ( commit . message ) ;
68
+ if ( ! meta ) continue ;
69
+ let scope = meta . scope ?? 'puter' ;
70
+ while ( scope in scope_aliases ) {
71
+ scope = scope_aliases [ scope ] ;
72
+ }
73
+ ensure_scope ( scope ) ;
74
+ if ( ! scopes [ scope ] ) {
75
+ console . log ( commit ) ;
76
+ throw new Error ( `missing scope: ${ scope } ` ) ;
77
+ }
78
+
79
+ if ( types . hasOwnProperty ( meta . type ) ) {
80
+ data [ scope ] [ meta . type ] . push ( { meta, commit } ) ;
81
+ }
82
+ }
83
+
84
+ let s = '' ;
85
+ s += `## ${ params . from } (${ params . date } )\n\n` ;
86
+ for ( const scope_name in data ) {
87
+ const scope = data [ scope_name ] ;
88
+ s += `### ${ scopes [ scope_name ] . label } \n\n` ;
89
+ for ( const type_name in types ) {
90
+ const type = types [ type_name ] ;
91
+ const items = scope [ type_name ] ;
92
+ if ( items . length == 0 ) continue ;
93
+ s += `#### ${ type . label } \n\n` ;
94
+ for ( const { meta, commit } of items ) {
95
+ const shorthash = commit . hash . slice ( 0 , 7 )
96
+ s += `- ${ meta . summary } ([${ shorthash } ](${ REPO_URL } /commit/${ commit . hash } ))\n` ;
97
+ }
98
+ }
99
+ }
100
+
101
+ console . log ( s ) ;
0 commit comments