@@ -3,66 +3,82 @@ var fs = require('fs');
3
3
var request = require ( 'request' ) ;
4
4
var log = require ( 'npmlog' ) ;
5
5
6
- var requestOpts = require ( './util' ) . requestOpts ;
7
- /**
8
- * Upload a tarball packaged by node-pre-gyp as an asset to a github release
9
- *
10
- * @param {Object } opts - A options object as return by node-pre-gyp's versioning.evaluate()
11
- * @param {Object } config - A config object as built by node-pre-gyp using the rc configuration module
12
- * @param {Function } callback - No particular return, just err or no err
13
- */
14
- exports . publish = function ( opts , config , callback ) {
6
+ // initialize options for a HTTP request
7
+ var requestOpts = function ( opts , config ) {
8
+ var requestOpts = {
9
+ headers : {
10
+ 'User-Agent' : 'node-pre-gyp-github-hosting'
11
+ }
12
+ } ;
13
+ if ( config . githubToken ) requestOpts . headers . Authorization = 'token ' + config . githubToken ;
14
+ var proxyUrl = opts . proxy || process . env . http_proxy || process . env . HTTP_PROXY || process . env . npm_config_proxy ;
15
+ if ( proxyUrl ) requestOpts . proxy = proxyUrl ;
15
16
16
- // first fetch the list of releases
17
+ return requestOpts ;
18
+ } ;
19
+
20
+ var getReleaseFromVersion = function ( opts , config , callback ) {
17
21
var listOpts = requestOpts ( opts , config ) ;
22
+ listOpts . headers . Accept = 'application/vnd.github.manifold-preview' ;
18
23
listOpts . url = 'https://api.github.com/repos/' + opts . repo + '/releases' ;
19
24
20
25
request ( listOpts , function ( err , response , body ) {
21
26
if ( err ) return callback ( err ) ;
27
+ log . http ( response . statusCode , listOpts . url ) ;
22
28
if ( response . statusCode !== 200 ) return callback ( new Error ( 'Cannot list assets from ' + listOpts . url + ': ' + response . statusCode ) ) ;
23
-
24
29
var releases = JSON . parse ( body ) ;
25
- var currentRelease ;
30
+ var release ;
26
31
for ( var i in releases ) {
27
- // remember the release that matches the required version
28
32
if ( releases [ i ] . tag_name === opts . version || releases [ i ] . tag_name === 'v' + opts . version ) {
29
- currentRelease = releases [ i ] ;
30
- }
31
- // fail if an asset matching current upload already exists
32
- for ( var j in releases [ i ] . assets ) {
33
- if ( releases [ i ] . assets [ i ] . name === opts . package_name ) {
34
- log . error ( 'publish' , 'Cannot publish over existing version' ) ;
35
- log . error ( 'publish' , "Update the 'version' field in package.json and try again" ) ;
36
- log . error ( 'publish' , 'If the previous version was published in error see:' ) ;
37
- log . error ( 'publish' , '\t node-pre-gyp unpublish' ) ;
38
- return callback ( new Error ( 'Failed publishing to github' ) ) ;
39
- }
33
+ release = releases [ i ] ;
40
34
}
41
35
}
36
+ callback ( null , release ) ;
37
+ } ) ;
38
+ } ;
42
39
43
- if ( ! currentRelease ) return callback ( new Error ( 'Cannot publish over non-existing github release' ) ) ;
40
+ /**
41
+ * Upload a tarball packaged by node-pre-gyp as an asset to a github release
42
+ *
43
+ * @param {Object } opts - A options object as return by node-pre-gyp's versioning.evaluate()
44
+ * @param {Object } config - A config object as built by node-pre-gyp using the rc configuration module
45
+ * @param {Function } callback - No particular return, just err or no err
46
+ */
47
+ exports . publish = function ( opts , config , callback ) {
48
+
49
+ if ( ! config . githubToken ) return callback ( new Error ( 'Authentication token required to publish an asset to github' ) ) ;
50
+
51
+ getReleaseFromVersion ( opts , config , function ( err , release ) {
52
+ if ( ! release ) return callback ( new Error ( 'Cannot publish over non-existing github release' ) ) ;
53
+
54
+ for ( var i in release . assets ) {
55
+ if ( release . assets [ i ] . name === opts . package_name ) {
56
+ log . error ( 'publish' , 'Cannot publish over existing version' ) ;
57
+ log . error ( 'publish' , "Update the 'version' field in package.json and try again" ) ;
58
+ log . error ( 'publish' , 'If the previous version was published in error see:' ) ;
59
+ log . error ( 'publish' , '\t node-pre-gyp unpublish' ) ;
60
+ return callback ( new Error ( 'Failed publishing to github' ) ) ;
61
+ }
62
+ }
44
63
45
- // then actually upload the asset on the release
46
64
var postOpts = requestOpts ( opts , config ) ;
47
- postOpts . url = currentRelease . upload_url . replace ( '{?name}' , '' ) ;
65
+ postOpts . url = release . upload_url . replace ( '{?name}' , '' ) ;
48
66
postOpts . qs = {
49
67
name : opts . package_name
50
68
} ;
51
69
postOpts . method = 'POST' ;
52
- delete postOpts . headers . Accept ;
53
70
postOpts . headers [ 'Content-Type' ] = 'application/tar' ;
54
71
fs . readFile ( opts . staged_tarball , function ( err , data ) {
55
72
if ( err ) return callback ( err ) ;
56
73
postOpts . body = data ;
57
74
request ( postOpts , function ( err , response ) {
58
75
if ( err ) return callback ( err ) ;
59
- if ( response . statusCode !== 201 ) return callback ( new Error ( 'Cannot upload to github: ' + response . statusCode ) ) ;
76
+ log . http ( response . statusCode , postOpts . url ) ;
77
+ if ( response . statusCode !== 201 ) return callback ( new Error ( 'Cannot upload to ' + postOpts . url + ': ' + response . statusCode ) ) ;
60
78
console . log ( '[' + opts . name + '] Success: published to ' + postOpts . url ) ;
61
79
callback ( ) ;
62
80
} ) ;
63
81
} ) ;
64
-
65
-
66
82
} ) ;
67
83
} ;
68
84
@@ -72,9 +88,35 @@ exports.publish = function(opts, config, callback) {
72
88
* @param {Object } opts - An options object as return by node-pre-gyp's versioning.evaluate()
73
89
* @param {Function } callback - No particular return, just err or no err
74
90
*/
75
- exports . unpublish = function ( opts , callback ) {
76
- // TODO
77
- callback ( ) ;
91
+ exports . unpublish = function ( opts , config , callback ) {
92
+ if ( ! config . githubToken ) return callback ( new Error ( 'Authentication token required to unpublish an asset to github' ) ) ;
93
+
94
+ getReleaseFromVersion ( opts , config , function ( err , release ) {
95
+ if ( ! release ) return callback ( new Error ( 'Cannot unpublish over non-existing github release' ) ) ;
96
+
97
+ var asset ;
98
+ for ( var i in release . assets ) {
99
+ if ( release . assets [ i ] . name === opts . package_name ) {
100
+ asset = release . assets [ i ] ;
101
+ }
102
+ }
103
+
104
+ if ( ! asset ) {
105
+ console . log ( '[' + opts . name + '] Not found: ' + opts . package_name ) ;
106
+ return callback ( ) ;
107
+ }
108
+
109
+ var delOpts = requestOpts ( opts , config ) ;
110
+ delOpts . url = asset . url ;
111
+ delOpts . method = 'DELETE' ;
112
+ request ( delOpts , function ( err , response ) {
113
+ if ( err ) return callback ( err ) ;
114
+ log . http ( response . statusCode , delOpts . url ) ;
115
+ if ( response . statusCode !== 204 ) return callback ( new Error ( 'Cannot delete ' + delOpts . url + ': ' + response . statusCode ) ) ;
116
+ console . log ( '[' + opts . name + '] Success: unpublished ' + delOpts . url ) ;
117
+ callback ( ) ;
118
+ } ) ;
119
+ } ) ;
78
120
} ;
79
121
80
122
/**
@@ -83,7 +125,23 @@ exports.unpublish = function(opts, callback) {
83
125
* @param {Object } opts - An options object as return by node-pre-gyp's versioning.evaluate()
84
126
* @param {Function } callback - called with a request object (https://github.com/mikeal/request) that will be used as a stream by node-pre-gyp
85
127
*/
86
- exports . download = function ( opts , callback ) {
87
- // TODO
88
- callback ( ) ;
128
+ exports . download = function ( opts , config , callback ) {
129
+ getReleaseFromVersion ( opts , config , function ( err , release ) {
130
+ if ( ! release ) return callback ( new Error ( 'Cannot unpublish over non-existing github release' ) ) ;
131
+
132
+ var asset ;
133
+ for ( var i in release . assets ) {
134
+ if ( release . assets [ i ] . name === opts . package_name ) {
135
+ asset = release . assets [ i ] ;
136
+ }
137
+ }
138
+
139
+ if ( ! asset ) return callback ( new Error ( 'Pre-built binary not available for your system' ) ) ;
140
+
141
+ var getOpts = requestOpts ( opts , config ) ;
142
+ getOpts . url = asset . url ;
143
+ getOpts . headers . Accept = 'application/octet-stream' ;
144
+ delete getOpts . headers . Authorization ;
145
+ callback ( null , request ( getOpts ) ) ;
146
+ } ) ;
89
147
} ;
0 commit comments