1
1
//Setup
2
- export default async function ( { login, q, imports, graphql, data, account, queries} , { enabled = false } = { } ) {
2
+ export default async function ( { login, q, imports, rest , graphql, data, account, queries} , { enabled = false , extras = false } = { } ) {
3
3
//Plugin execution
4
4
try {
5
5
//Check if plugin is enabled and requirements are met
6
6
if ( ( ! enabled ) || ( ! q . notable ) )
7
7
return null
8
8
9
9
//Load inputs
10
- let { filter, repositories, from} = imports . metadata . plugins . notable . inputs ( { data, account, q} )
10
+ let { filter, repositories, from, indepth } = imports . metadata . plugins . notable . inputs ( { data, account, q} )
11
11
12
12
//Iterate through contributed repositories
13
- const notable = new Map ( )
13
+ const commits = [ ]
14
14
{
15
15
let cursor = null
16
16
let pushed = 0
@@ -21,15 +21,89 @@ export default async function({login, q, imports, graphql, data, account, querie
21
21
edges
22
22
. filter ( ( { node} ) => ( { all :true , organization :node . isInOrganization , user :! node . isInOrganization } [ from ] ) )
23
23
. filter ( ( { node} ) => imports . ghfilter ( filter , { name :node . nameWithOwner , user :node . owner . login , stars :node . stargazers . totalCount , watchers :node . watchers . totalCount , forks :node . forks . totalCount } ) )
24
- . map ( ( { node} ) => notable . set ( ( repositories || ! node . isInOrganization ) ? node . nameWithOwner : node . owner . login , { organization :node . isInOrganization , avatarUrl :node . owner . avatarUrl } ) )
24
+ . map ( ( { node} ) => commits . push ( { handle : node . nameWithOwner , stars : node . stargazers . totalCount , organization :node . isInOrganization , avatarUrl :node . owner . avatarUrl } ) )
25
25
pushed = edges . length
26
26
} while ( ( pushed ) && ( cursor ) )
27
27
}
28
28
29
29
//Set contributions
30
- const contributions = ( await Promise . all ( [ ... notable . entries ( ) ] . map ( async ( [ name , { avatarUrl, organization} ] ) => ( { name, avatar :await imports . imgb64 ( avatarUrl ) , organization} ) ) ) ) . sort ( ( a , b ) => a . name . localeCompare ( b . name ) )
30
+ let contributions = ( await Promise . all ( commits . map ( async ( { handle , stars , avatarUrl, organization} ) => ( { name : handle . split ( "/" ) . shift ( ) , handle , stars , avatar :await imports . imgb64 ( avatarUrl ) , organization} ) ) ) ) . sort ( ( a , b ) => a . name . localeCompare ( b . name ) )
31
31
console . debug ( `metrics/compute/${ login } /plugins > notable > found ${ contributions . length } notable contributions` )
32
32
33
+ //Extras features
34
+ if ( extras ) {
35
+ //Indepth
36
+ if ( indepth ) {
37
+ console . debug ( `metrics/compute/${ login } /plugins > notable > indepth` )
38
+ for ( const contribution of contributions ) {
39
+ //Prepare data
40
+ const { handle, stars} = contribution
41
+ const [ owner , repo ] = handle . split ( "/" )
42
+ try {
43
+ //Count total commits on repository
44
+ const { repository :{ defaultBranchRef :{ target :{ history} } } } = await graphql ( queries . notable . commits ( { owner, repo} ) )
45
+ contribution . history = history . totalCount
46
+
47
+ //Load maintainers (errors probably means that token is not allowed to list contributors hence not a maintainer of said repo)
48
+ const { data :collaborators } = await rest . repos . listCollaborators ( { owner, repo} ) . catch ( ( ) => ( { data :[ ] } ) )
49
+ const maintainers = collaborators . filter ( ( { role_name :role } ) => [ "admin" , "maintain" , "write" ] . includes ( role ) ) . map ( ( { login} ) => login )
50
+
51
+ //Count total commits of user
52
+ const { data :contributions = [ ] } = await rest . repos . getContributorsStats ( { owner, repo} )
53
+ const commits = contributions . filter ( ( { author} ) => author . login . toLocaleLowerCase ( ) === login . toLocaleLowerCase ( ) ) . reduce ( ( a , { total :b } ) => a + b , 0 )
54
+
55
+ //Save user data
56
+ contribution . user = {
57
+ commits,
58
+ percentage :commits / contribution . history ,
59
+ maintainer :maintainers . includes ( login ) ,
60
+ get stars ( ) {
61
+ return this . maintainer ? stars : this . percentage * stars
62
+ }
63
+ }
64
+ console . debug ( `metrics/compute/${ login } /plugins > notable > indepth > successfully processed ${ owner } /${ repo } ` )
65
+ }
66
+ catch ( error ) {
67
+ console . debug ( error )
68
+ console . debug ( `metrics/compute/${ login } /plugins > notable > indepth > failed to compute for ${ owner } /${ repo } ` )
69
+ }
70
+ }
71
+ }
72
+ }
73
+
74
+ //Aggregate contributions
75
+ if ( from !== "all" ) {
76
+ console . debug ( `metrics/compute/${ login } /plugins > notable > aggregating results` )
77
+ contributions = contributions . filter ( ( { organization} ) => ( from === "organization" ) && ( organization ) )
78
+ const aggregated = new Map ( )
79
+ for ( const { name, handle, avatar, organization, stars, ..._extras } of contributions ) {
80
+ const key = repositories ? handle : name
81
+ if ( aggregated . has ( key ) ) {
82
+ const aggregate = aggregated . get ( key )
83
+ aggregate . aggregated ++
84
+ if ( extras ) {
85
+ const { history = 0 , user :{ commits = 0 , percentage = 0 , maintainer = false } = { } } = _extras
86
+ aggregate . history = aggregate . history ?? 0
87
+ aggregate . history += history
88
+ aggregate . user = aggregate . user ?? { }
89
+ aggregate . user . commits += commits
90
+ aggregate . user . percentage += percentage
91
+ aggregate . user . maintainer = aggregate . user . maintainer || maintainer
92
+ }
93
+ }
94
+ else
95
+ aggregated . set ( key , { name :key , handle, avatar, organization, stars, aggregated :1 , ..._extras } )
96
+ }
97
+ contributions = [ ...aggregated . values ( ) ]
98
+ if ( extras ) {
99
+ //Normalize contribution percentage
100
+ contributions . map ( aggregate => aggregate . user ? aggregate . user . percentage /= aggregate . aggregated : null )
101
+ //Sort contribution by maintainer first and then by contribution percentage
102
+ contributions = contributions . sort ( ( a , b ) => ( ( b . user ?. percentage + b . user ?. maintainer ) || 0 ) - ( ( a . user ?. percentage + a . user ?. maintainer ) || 0 ) )
103
+ }
104
+ }
105
+
106
+
33
107
//Results
34
108
return { contributions}
35
109
}
0 commit comments