33import path from 'path' ;
44import GitHubApi from 'github' ;
55import program from 'commander' ;
6+ import minimatch from 'minimatch' ;
67import pkg from '../package.json' ;
78
89program
910 . version ( pkg . version )
11+ . usage ( '<command> [<args>]' )
1012 . option ( '-T, --token <token>' , 'OAuth2 token' )
1113 . option ( '-o, --owner <owner>' , 'owner' )
1214 . option ( '-r, --repo <repo>' , 'repo' )
1315 . option ( '-t, --tag <tag>' , 'tag' )
1416 . option ( '-n, --name <name>' , 'name' )
15- . option ( '-b, --body <body>' , 'body' , false )
16- . parse ( process . argv ) ;
17+ . option ( '-b, --body <body>' , 'body' , false ) ;
18+
19+ program . parse ( process . argv ) ;
20+
21+ const [ command , ...args ] = program . args ;
1722
1823const github = new GitHubApi ( {
1924 version : '3.0.0' ,
@@ -22,7 +27,6 @@ const github = new GitHubApi({
2227 'user-agent' : 'GitHub-Release-App'
2328 }
2429} ) ;
25- const files = program . args ;
2630
2731github . authenticate ( {
2832 type : 'oauth' ,
@@ -77,124 +81,118 @@ const uploadAsset = (options) => {
7781 } ) ;
7882} ;
7983
80- const main = async ( ) => {
81- const { owner, repo, tag, name, body } = program ;
84+ const fn = {
85+ 'upload' : async ( ) => {
86+ const { owner, repo, tag, name, body } = program ;
87+ const files = args ;
88+ let release ;
8289
83- try {
84- console . log ( '> releases#getReleaseByTag' ) ;
85- let release = await getReleaseByTag ( {
86- owner : owner ,
87- repo : repo ,
88- tag : tag
89- } ) ;
90- if ( ! release ) {
91- console . log ( '> releases#createRelease' ) ;
92- release = await createRelease ( {
90+ try {
91+ console . log ( '> releases#getReleaseByTag' ) ;
92+ release = await getReleaseByTag ( {
9393 owner : owner ,
9494 repo : repo ,
95- tag_name : tag ,
96- name : name || tag ,
97- body : body || ''
95+ tag : tag
9896 } ) ;
99- console . log ( 'ok' , release ) ;
100- } else if ( release . body !== body ) {
101- console . log ( '> releases#editRelease' ) ;
102- let releaseOptions = {
103- owner : owner ,
104- repo : repo ,
105- id : release . id ,
106- tag_name : tag ,
107- name : name || tag
108- } ;
109- if ( body ) {
110- releaseOptions . body = body || '' ;
111- }
112- release = await editRelease ( releaseOptions ) ;
113- console . log ( 'ok' , release ) ;
97+ } catch ( err ) {
98+ // Ignore
11499 }
115100
116- console . log ( '> releases#getAssets' ) ;
117- let assets = await getAssets ( {
118- owner : owner ,
119- repo : repo ,
120- id : release . id
121- } ) ;
122- console . log ( 'assets=%d' , assets . length ) ;
123-
124- assets = assets . filter ( asset => {
125- // Example:
126- // 'cnc-1.1.0-latest-08c256a-linux-x64.tar.gz'
127- // ["cnc-1.1.0-latest-08c256a-linux-x64.tar.gz", "cnc", "1.1.0-latest-08c256a", "linux", "x64", "tar.gz"]
128- const pattern = new RegExp ( / ( [ a - z A - Z 0 - 9 ] [ a - z A - Z 0 - 9 \- ] * ) \- ( \d + \. \d + \. \d + (?: \- [ a - z A - Z 0 - 9 ] [ a - z A - Z 0 - 9 \- ] * ) ? ) (?: \- ( m a c | w i n | l i n u x | t i n y w e b ) ) (?: (?: \- ( [ a - z A - Z 0 - 9 _ \- ] + ) ) ? \. ( .* ) ) / ) ;
129-
130- return files . some ( file => {
131- let r1 = asset . name . match ( pattern ) ;
132- let r2 = path . basename ( file ) . match ( pattern ) ;
133-
134- if ( ( r1 === null ) || ( r2 === null ) ) {
135- console . error ( 'Unable to match file: asset="%s", file="%s"' , asset . name , path . basename ( file ) ) ;
136- return false ;
137- }
138-
139- // 0: full
140- // 1: name
141- // 2: version
142- // 3: platform
143- // 4: arch
144- // 5: extname
145-
146- // Skip checking for #0 (full) and #2 (version)
147- r1 [ 0 ] = r1 [ 2 ] = undefined ;
148- r2 [ 0 ] = r2 [ 2 ] = undefined ;
149-
150- // compact
151- r1 = r1 . filter ( r => r !== undefined && r !== null ) ;
152- r2 = r2 . filter ( r => r !== undefined && r !== null ) ;
153-
154- // compare two arrays
155- return ( r1 . length === r2 . length ) && r1 . every ( ( v , i ) => v === r2 [ i ] ) ;
156- } ) ;
157- } ) ;
158-
159- if ( assets . length > 0 ) {
160- console . log ( '> releases#deleteAsset' ) ;
161- for ( let i = 0 ; i < assets . length ; ++ i ) {
162- const asset = assets [ i ] ;
163- console . log ( '#%d' , i + 1 , {
164- id : asset . id ,
165- name : asset . name ,
166- label : asset . label ,
167- state : asset . state ,
168- size : asset . size ,
169- download_count : asset . download_count ,
170- created_at : asset . created_at ,
171- updated_at : asset . updated_at
172- } ) ;
173- await deleteAsset ( {
101+ try {
102+ if ( ! release ) {
103+ console . log ( '> releases#createRelease' ) ;
104+ release = await createRelease ( {
174105 owner : owner ,
175106 repo : repo ,
176- id : asset . id
107+ tag_name : tag ,
108+ name : name || tag ,
109+ body : body || ''
177110 } ) ;
178- }
179- }
180-
181- if ( files . length > 0 ) {
182- console . log ( '> releases#uploadAsset' ) ;
183- for ( let i = 0 ; i < files . length ; ++ i ) {
184- const file = files [ i ] ;
185- console . log ( '#%d name="%s" filePath="%s"' , i + 1 , path . basename ( file ) , file ) ;
186- await uploadAsset ( {
111+ } else if ( body && ( release . body !== body ) ) {
112+ console . log ( '> releases#editRelease' ) ;
113+ let releaseOptions = {
187114 owner : owner ,
188115 repo : repo ,
189116 id : release . id ,
190- filePath : file ,
191- name : path . basename ( file )
192- } ) ;
117+ tag_name : tag ,
118+ name : name || tag ,
119+ body : body || ''
120+ } ;
121+ release = await editRelease ( releaseOptions ) ;
122+ }
123+
124+ if ( files . length > 0 ) {
125+ console . log ( '> releases#uploadAsset' ) ;
126+ for ( let i = 0 ; i < files . length ; ++ i ) {
127+ const file = files [ i ] ;
128+ console . log ( '#%d name="%s" filePath="%s"' , i + 1 , path . basename ( file ) , file ) ;
129+ await uploadAsset ( {
130+ owner : owner ,
131+ repo : repo ,
132+ id : release . id ,
133+ filePath : file ,
134+ name : path . basename ( file )
135+ } ) ;
136+ }
193137 }
138+ } catch ( err ) {
139+ console . error ( err ) ;
140+ }
141+ } ,
142+ 'delete' : async ( ) => {
143+ const { owner, repo, tag, name, body } = program ;
144+ const patterns = args ;
145+ let release ;
146+
147+ try {
148+ console . log ( '> releases#getReleaseByTag' ) ;
149+ release = await getReleaseByTag ( {
150+ owner : owner ,
151+ repo : repo ,
152+ tag : tag
153+ } ) ;
154+ } catch ( err ) {
155+ console . error ( err ) ;
156+ return ;
157+ }
158+
159+ try {
160+ console . log ( '> releases#getAssets' ) ;
161+ const assets = await getAssets ( {
162+ owner : owner ,
163+ repo : repo ,
164+ id : release . id
165+ } ) ;
166+ const deleteAssets = assets . filter ( asset => {
167+ return patterns . some ( pattern => minimatch ( asset . name , pattern ) ) ;
168+ } ) ;
169+ console . log ( 'assets=%d, deleteAssets=%d' , assets . length , deleteAssets . length ) ;
170+
171+ if ( deleteAssets . length > 0 ) {
172+ console . log ( '> releases#deleteAsset' ) ;
173+ for ( let i = 0 ; i < deleteAssets . length ; ++ i ) {
174+ const asset = deleteAssets [ i ] ;
175+ console . log ( '#%d' , i + 1 , {
176+ id : asset . id ,
177+ name : asset . name ,
178+ label : asset . label ,
179+ state : asset . state ,
180+ size : asset . size ,
181+ download_count : asset . download_count ,
182+ created_at : asset . created_at ,
183+ updated_at : asset . updated_at
184+ } ) ;
185+ await deleteAsset ( {
186+ owner : owner ,
187+ repo : repo ,
188+ id : asset . id
189+ } ) ;
190+ }
191+ }
192+ } catch ( err ) {
193+ console . error ( err ) ;
194194 }
195- } catch ( err ) {
196- console . error ( err ) ;
197195 }
198- } ;
196+ } [ command ] ;
199197
200- main ( ) ;
198+ typeof fn === 'function' && fn ( ) ;
0 commit comments