Skip to content

Commit c216538

Browse files
Added release contributors script. Resolves DP #647. (#1109)
1 parent 6c095f0 commit c216538

File tree

1 file changed

+132
-0
lines changed

1 file changed

+132
-0
lines changed

script/release-contributors.js

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
/**
2+
* Script that prints the contributors of every project in the March 2020 release.
3+
*/
4+
5+
// Core dependencies
6+
const https = require("https");
7+
8+
// App dependencies
9+
const release2020March = require("../spa/src/app/files/releases/2020-march/2020-03-release.json");
10+
11+
// Constants
12+
const PROJECT_API = "https://service.explore.data.humancellatlas.org/repository/projects/";
13+
14+
/**
15+
* List contributors for all projects in the release.
16+
*/
17+
function readReleaseContributors() {
18+
19+
if ( !release2020March ) {
20+
return;
21+
}
22+
23+
(release2020March.projects || []).forEach((project) => {
24+
listProjectContributors(project);
25+
});
26+
}
27+
28+
/**
29+
* List the contributors in the specified project.
30+
*
31+
* @param {ReleaseProject} releaseProject
32+
*/
33+
function listProjectContributors(releaseProject) {
34+
35+
https.get(`${PROJECT_API}${releaseProject.entryId}`, (res) => {
36+
37+
const { statusCode } = res;
38+
if ( statusCode !== 200 ) {
39+
console.error(`Unable to retrieve contributors for project with ID "${releaseProject.entryId} (${statusCode})."`)
40+
}
41+
42+
let data = "";
43+
res.on("data", (chunk) => {
44+
data += chunk;
45+
});
46+
47+
res.on("end", () => {
48+
const project = JSON.parse(data).projects[0] || {};
49+
console.log(`### ${project.projectTitle}`);
50+
51+
const contributors = (project).contributors;
52+
sortContributors(contributors);
53+
(contributors || []).forEach((contributor, i) => {
54+
const contributorName = formatContributorName(contributor.contactName);
55+
let text = `${contributorName}, ${contributor.institution}`;
56+
if ( contributor.projectRole ) {
57+
const projectRole = toTitleCase(contributor.projectRole);
58+
text += ` (${projectRole})`;
59+
}
60+
if ( i < contributors.length - 1 ) {
61+
text += "\\";
62+
}
63+
console.log(text);
64+
});
65+
console.log("\n");
66+
});
67+
})
68+
.on("error", (error) => {
69+
console.error(error.message);
70+
});
71+
}
72+
73+
/**
74+
* Returns formatted name from "firstName,middleName,lastName" to "firstName middleName lastName".
75+
*
76+
* @param {string} commaDelimitedName
77+
* @returns {string}
78+
*/
79+
function formatContributorName(commaDelimitedName) {
80+
81+
return commaDelimitedName.split(/[ ,]+/).join(" ");
82+
}
83+
84+
/**
85+
* Sort contributors by last name.
86+
*
87+
* @param {Contributor[]} contributors
88+
*/
89+
function sortContributors(contributors) {
90+
91+
contributors.sort((c0, c1) => {
92+
93+
const sortValue0 = findContributorLastName(c0.contactName);
94+
const sortValue1 = findContributorLastName(c1.contactName);
95+
if ( sortValue0 > sortValue1 ) {
96+
return 1;
97+
}
98+
if ( sortValue0 < sortValue1 ) {
99+
return -1;
100+
}
101+
return 0;
102+
});
103+
}
104+
105+
/**
106+
* Returns the last name of the specified contributor.
107+
*
108+
* @param {string} contactName
109+
* @returns {string}
110+
*/
111+
function findContributorLastName(contactName) {
112+
113+
return /[^,]*$/.exec(contactName)[0];
114+
}
115+
116+
/**
117+
* Convert specified string to title case.
118+
*
119+
* @param {string} str
120+
* @returns {string}
121+
*/
122+
function toTitleCase(str) {
123+
124+
return str.replace(
125+
/\w\S*/g,
126+
function(text) {
127+
return text.charAt(0).toUpperCase() + text.substr(1).toLowerCase();
128+
}
129+
);
130+
}
131+
132+
readReleaseContributors();

0 commit comments

Comments
 (0)