1
1
'use strict'
2
2
3
- var npm = require ( './npm.js' )
4
- var output = require ( './utils/output.js' )
5
- var readPackageTree = require ( 'read-package-tree' )
6
- var runParallelLimit = require ( 'run-parallel-limit' )
7
- var simpleGet = require ( 'simple-get' )
8
- var semver = require ( 'semver' )
9
- var hasANSI = require ( 'has-ansi' )
3
+ const npm = require ( './npm.js' )
4
+ const output = require ( './utils/output.js' )
5
+ const path = require ( 'path' )
6
+ const readPackageTree = require ( 'read-package-tree' )
7
+ const semver = require ( 'semver' )
8
+ const validSupportURL = require ( './utils/valid-support-url' )
10
9
11
10
module . exports = support
12
11
@@ -18,7 +17,6 @@ support.usage = usage(
18
17
19
18
support . completion = function ( opts , cb ) {
20
19
const argv = opts . conf . argv . remain
21
-
22
20
switch ( argv [ 2 ] ) {
23
21
case 'support' :
24
22
return cb ( null , [ ] )
@@ -27,206 +25,64 @@ support.completion = function (opts, cb) {
27
25
}
28
26
}
29
27
28
+ // Compare lib/ls.js.
30
29
function support ( args , silent , cb ) {
31
- readPackageTree ( npm . dir , function ( error , tree ) {
32
- if ( error ) return cb ( error )
33
- var supportablePackages = Array . from ( findSupportablePackages ( tree ) )
34
- downloadSupportData ( supportablePackages , function ( error , data ) {
35
- if ( error ) return cb ( error )
36
-
37
- if ( typeof cb !== 'function' ) {
38
- cb = silent
39
- silent = false
40
- }
41
- if ( silent ) return cb ( null , data )
42
-
43
- var out
44
- var json = npm . config . get ( 'json' )
45
- if ( json ) {
46
- out = JSON . stringify ( data , null , 2 )
47
- } else {
48
- out = data
49
- . sort ( function ( a , b ) {
50
- var comparison = a . name . localeCompare ( b . name )
51
- return comparison === 0
52
- ? semver . compare ( a . version , b . version )
53
- : comparison
54
- } )
55
- . map ( displaySupportData )
56
- . join ( '\n\n' )
57
- }
58
- output ( out )
59
- if ( error ) process . exitCode = 1
60
- cb ( error , data )
61
- } )
30
+ if ( typeof cb !== 'function' ) {
31
+ cb = silent
32
+ silent = false
33
+ }
34
+ const dir = path . resolve ( npm . dir , '..' )
35
+ readPackageTree ( dir , function ( err , tree ) {
36
+ if ( err ) {
37
+ process . exitCode = 1
38
+ return cb ( err )
39
+ }
40
+ const data = findPackages ( tree )
41
+ if ( silent ) return cb ( null , data )
42
+ var out
43
+ if ( npm . config . get ( 'json' ) ) {
44
+ out = JSON . stringify ( data , null , 2 )
45
+ } else {
46
+ out = data . map ( displayPackage ) . join ( '\n\n' )
47
+ }
48
+ output ( out )
49
+ cb ( err , data )
62
50
} )
63
51
}
64
52
65
- function findSupportablePackages ( root ) {
66
- var set = new Set ( )
53
+ function findPackages ( root ) {
54
+ const set = new Set ( )
67
55
iterate ( root )
68
- return set
56
+ return Array . from ( set ) . sort ( function ( a , b ) {
57
+ const comparison = a . name
58
+ . toLowerCase ( )
59
+ . localeCompare ( b . name . toLowerCase ( ) )
60
+ return comparison === 0
61
+ ? semver . compare ( a . version , b . version )
62
+ : comparison
63
+ } )
69
64
70
65
function iterate ( node ) {
71
66
node . children . forEach ( recurse )
72
67
}
73
68
74
69
function recurse ( node ) {
75
- var metadata = node . package
76
- if ( metadata . support ) {
70
+ const metadata = node . package
71
+ const support = metadata . support
72
+ if ( support && validSupportURL ( support ) ) {
77
73
set . add ( {
78
74
name : metadata . name ,
79
75
version : metadata . version ,
76
+ path : node . path ,
80
77
homepage : metadata . homepage ,
81
78
repository : metadata . repository ,
82
- support : metadata . support ,
83
- parent : node . parent ,
84
- path : node . path
79
+ support : metadata . support
85
80
} )
86
81
}
87
82
if ( node . children ) iterate ( node )
88
83
}
89
84
}
90
85
91
- function downloadSupportData ( supportablePackages , cb ) {
92
- var cache = new Map ( )
93
- var headers = { 'user-agent' : npm . config . get ( 'user-agent' ) }
94
- runParallelLimit ( supportablePackages . map ( function ( entry ) {
95
- return function task ( done ) {
96
- var url = entry . support
97
- get ( url , function ( error , response , projectData ) {
98
- if ( error ) {
99
- return done ( null , {
100
- url : url ,
101
- error : 'could not download data'
102
- } )
103
- }
104
- if ( typeof projectData !== 'object' || Array . isArray ( projectData ) ) {
105
- return done ( null , {
106
- url : url ,
107
- error : 'not an object'
108
- } )
109
- }
110
- var contributors = projectData . contributors
111
- if ( ! Array . isArray ( contributors ) ) {
112
- return done ( null , projectData )
113
- }
114
- runParallelLimit ( contributors . map ( function ( contributor ) {
115
- return function ( done ) {
116
- if (
117
- typeof contributor !== 'object' ||
118
- typeof contributor . url !== 'string'
119
- ) {
120
- return setImmediate ( function ( ) {
121
- done ( null , contributor )
122
- } )
123
- }
124
- get ( contributor . url , function ( error , response , contributorData ) {
125
- if ( error ) {
126
- return done ( null , {
127
- url : contributor . url ,
128
- error : error
129
- } )
130
- }
131
- contributorData . url = contributor . url
132
- var result = {
133
- name : contributorData . name ,
134
- type : contributorData . type ,
135
- url : contributor . url
136
- }
137
- if ( looksLikeURL ( contributorData . homepage ) ) {
138
- result . homepage = contributorData . homepage
139
- }
140
- if (
141
- Array . isArray ( contributorData . links ) &&
142
- contributorData . links . every ( function ( element ) {
143
- return looksLikeURL ( element )
144
- } )
145
- ) {
146
- result . links = contributorData . links
147
- }
148
- done ( null , result )
149
- } )
150
- }
151
- } ) , 5 , function ( error , resolvedContributors ) {
152
- if ( error ) return done ( error )
153
- done ( null , {
154
- name : entry . name ,
155
- version : entry . version ,
156
- url : entry . support ,
157
- homepage : entry . homepage ,
158
- contributors : resolvedContributors
159
- } )
160
- } )
161
- } )
162
- }
163
- } ) , 5 , cb )
164
-
165
- function get ( url , cb ) {
166
- var cached = cache . get ( url )
167
- if ( cached ) {
168
- return setImmediate ( function ( ) {
169
- cb ( null , { cached : true } , cached )
170
- } )
171
- }
172
- simpleGet . concat ( {
173
- url : url ,
174
- json : true ,
175
- headers : headers
176
- } , function ( err , response , data ) {
177
- if ( err ) return cb ( err )
178
- cache . set ( url , data )
179
- cb ( null , response , data )
180
- } )
181
- }
182
- }
183
-
184
- function displaySupportData ( entry ) {
185
- var returned = [ entry . name + '@' + entry . version ]
186
- if ( looksLikeURL ( entry . homepage ) ) {
187
- returned [ 0 ] += ' (' + entry . homepage + ')'
188
- }
189
- if ( Array . isArray ( entry . contributors ) ) {
190
- entry . contributors . forEach ( function ( contributor ) {
191
- var name = contributor . name
192
- if ( looksLikeSafeString ( name ) ) {
193
- var item = [ '- ' + name ]
194
- var email = contributor . email
195
- if ( looksLikeSafeString ( email ) ) {
196
- item [ 0 ] += ' <' + email + '>'
197
- }
198
- var homepage = contributor . homepage
199
- if ( looksLikeURL ( homepage ) ) {
200
- item [ 0 ] += ' (' + homepage + ')'
201
- }
202
- var links = contributor . links
203
- if ( Array . isArray ( links ) ) {
204
- links . forEach ( function ( link ) {
205
- if ( looksLikeURL ( link ) ) item . push ( ' ' + link )
206
- } )
207
- }
208
- returned . push ( item . join ( '\n' ) )
209
- }
210
- } )
211
- }
212
- return returned . join ( '\n' )
213
- }
214
-
215
- function looksLikeSafeString ( argument ) {
216
- return (
217
- typeof argument === 'string' &&
218
- argument . length > 0 &&
219
- argument . length < 80 &&
220
- ! hasANSI ( argument )
221
- )
222
- }
223
-
224
- function looksLikeURL ( argument ) {
225
- return (
226
- looksLikeSafeString ( argument ) &&
227
- (
228
- argument . indexOf ( 'https://' ) === 0 ||
229
- argument . indexOf ( 'http://' ) === 0
230
- )
231
- )
86
+ function displayPackage ( entry ) {
87
+ return entry . name + '@' + entry . version + ': ' + entry . support
232
88
}
0 commit comments