Commit 1c8e7865 authored by Pierre-Yves Gibello's avatar Pierre-Yves Gibello
Browse files

Fixes in issues gathering, to refine unanswered bugs ratio

parent c203ffe7
Pipeline #18747 passed with stages
in 3 minutes and 58 seconds
......@@ -522,7 +522,10 @@ public class MainCollector {
return script.toString();
} else if (url.contains("github.com")) {
StringBuilder script = new StringBuilder();
script.append("{ curl -X GET").append(credentials).append(" -H \"Content-Type: application/json\" '").append(complementUrl(url, "/issues?state=closed&per_page=100")).append("'; ");
// Call https://api.github.com/repos/{owner}/{repo} for global issues count (and repo stats if needed)
script.append("{ curl -X GET").append(credentials).append(" -H \"Content-Type: application/json\" '").append(url).append("'; ");
// Retrieve issues data
script.append("curl -X GET").append(credentials).append(" -H \"Content-Type: application/json\" '").append(complementUrl(url, "/issues?state=closed&per_page=100")).append("'; ");
script.append("curl -X GET").append(credentials).append(" -H \"Content-Type: application/json\" '").append(complementUrl(url, "/issues?state=open&per_page=100")).append("'; } > ").append(getOutputDir(true)).append(project).append("_issues.json");
return script.toString();
} else return null;
......
......@@ -28,6 +28,8 @@ import org.ow2.mrl.data.collect.JsonDataHandler;
*/
public class GithubHandler extends JsonDataHandler {
int objectLevel; // JSON object level (for embedded objects)
LocalDateTime rDate, cDate, uDate; // Dates of resolution, creation, update
String lastKey;
String iid;
......@@ -92,31 +94,43 @@ public class GithubHandler extends JsonDataHandler {
@Override
public void simpleValue(String val) throws Exception {
if("number".equals(this.lastKey)) {
this.iid = val.trim();
this.state = null;
} else if("closed_at".equals(this.lastKey)) {
if(! "null".equals(val)) {
rDate = LocalDateTime.parse(val.substring(0, 19), DateTimeFormatter.ISO_LOCAL_DATE_TIME);
if(this.objectLevel == 1) {
if("number".equals(this.lastKey)) {
this.iid = val.trim();
this.state = null;
} else if("closed_at".equals(this.lastKey)) {
if(! "null".equals(val)) {
rDate = LocalDateTime.parse(val.substring(0, 19), DateTimeFormatter.ISO_LOCAL_DATE_TIME);
}
}
else if("created_at".equals(this.lastKey)) {
cDate = LocalDateTime.parse(val.substring(0, 19), DateTimeFormatter.ISO_LOCAL_DATE_TIME);
} else if("updated_at".equals(this.lastKey)) {
uDate = LocalDateTime.parse(val.substring(0, 19), DateTimeFormatter.ISO_LOCAL_DATE_TIME);
} else if("open_issues_count".equals(this.lastKey)) {
// Global bug count
// In result of: https://api.github.com/repos/{owner}/{repo}
// Example: curl -X GET -H "Content-Type: application/json" 'https://api.github.com/repos/imixs/imixs-workflow'
try {
if(this.totalBugs <= 0) this.totalBugs = Integer.parseInt(val.trim());
} catch(Exception ignore) { }
} else if("state".equals(this.lastKey)) {
this.state = val.trim();
} else if("comments".equals(this.lastKey)) {
if("open".equals(this.state)) {
// Unanswered bug = open, no comment
try {
if(Integer.parseInt(val.trim()) <= 0) this.unansweredBugs ++;
} catch(Exception ignore) { }
}
}
}
else if("created_at".equals(this.lastKey)) {
cDate = LocalDateTime.parse(val.substring(0, 19), DateTimeFormatter.ISO_LOCAL_DATE_TIME);
} else if("updated_at".equals(this.lastKey)) {
uDate = LocalDateTime.parse(val.substring(0, 19), DateTimeFormatter.ISO_LOCAL_DATE_TIME);
} else if("login".equals(this.lastKey) && this.assignee) {
if("login".equals(this.lastKey) && this.assignee) {
this.assignees.add(val.trim());
this.assignee = false;
} else if("assignees".equals(this.lastKey)) {
this.assignee = false; // assignee value is an object, or "null" (if lastKey=assignee, it is null)
} else if("state".equals(this.lastKey)) {
this.state = val.trim();
} else if("comments".equals(this.lastKey) && "open".equals(this.state)) {
this.totalBugs ++;
// Unanswered bug = open, no comment
try {
if(Integer.parseInt(val.trim()) <= 0) this.unansweredBugs ++;
} catch(Exception ignore) { }
} else if("body".equals(this.lastKey)) {
computeAverage(); // body comes after all dates
}
......@@ -180,10 +194,21 @@ public class GithubHandler extends JsonDataHandler {
super.endParsing();
getMetrics().put("ActiveUsers", Double.valueOf(getBugTrackerActiveUsers().size()));
getMetrics().put("UnansweredBugs", Double.valueOf(getUnansweredBugs()));
getMetrics().put("BugsCount", Double.valueOf(getBugsCount()));
getMetrics().put("UnansweredBugsCount", Double.valueOf(getUnansweredBugsCount()));
getMetrics().put("Opentime", Double.valueOf(getBugOpenTime()));
getMetrics().put("AverageResponseTime", Double.valueOf(getBugResponseTime()));
}
@Override
public void startObject() throws Exception {
++ this.objectLevel;
}
@Override
public void endObject() throws Exception {
-- this.objectLevel;
}
// Test main program.
public static void main(String args[]) throws Exception {
String jsonFile = "/tmp/issues.json";
......
......@@ -115,8 +115,14 @@ public class GitlabHandler extends JsonDataHandler {
this.assignee = false; // assignee value is an object, or "null" (if lastKey=assignee, it is null)
} else if("state".equals(this.lastKey)) {
if(this.state == null) this.state = val.trim(); // there are other "state" in embedded objects
} else if("opened".equals(this.lastKey)) {
// Global bug count
// In result of: https://{gitlab-url}/api/v4/projects/{project-number}/issues_statistics
// Example: curl -X GET -H "Content-Type: application/json" 'https://gitlab.ow2.org/api/v4/projects/181/issues_statistics'
try {
if(this.totalBugs <= 0) this.totalBugs = Integer.parseInt(val.trim());
} catch(Exception ignore) { }
} else if("user_notes_count".equals(this.lastKey)) {
this.totalBugs ++;
// Unanswered bug = open, no comment
if("opened".equals(this.state)) {
try {
......@@ -186,6 +192,8 @@ public class GitlabHandler extends JsonDataHandler {
super.endParsing();
getMetrics().put("ActiveUsers", Double.valueOf(getBugTrackerActiveUsers().size()));
getMetrics().put("UnansweredBugs", Double.valueOf(getUnansweredBugs()));
getMetrics().put("BugsCount", Double.valueOf(getBugsCount()));
getMetrics().put("UnansweredBugsCount", Double.valueOf(getUnansweredBugsCount()));
getMetrics().put("Opentime", Double.valueOf(getBugOpenTime()));
getMetrics().put("AverageResponseTime", Double.valueOf(getBugResponseTime()));
}
......
......@@ -20,13 +20,13 @@ import org.ow2.mrl.data.collect.JsonDataHandler;
* To retrieve data, concatenate results from:
* 1) Unanswered bugs (open + not commented bugs)
* curl -X GET -H "Content-Type: application/json"
* 'http://jira.xwiki.org/rest/api/2/search?maxResults=0&jql=Type=Bug%20AND%20Status=Open%20AND%20issueFunction%20not%20in%20commented("")%20AND%20Project=XWIKI'
* 'https://jira.xwiki.org/rest/api/2/search?maxResults=0&jql=Type=Bug%20AND%20Status=Open%20AND%20issueFunction%20not%20in%20commented("")%20AND%20Project=XWIKI'
* 2) Recent closed bugs (currently limited to 100)
* curl -X GET -H "Content-Type: application/json"
* 'http://jira.xwiki.org/rest/api/2/search?maxResults=100&jql=Type=Bug%20AND%20Status=Closed%20AND%20Project=XWIKI'
* 'https://jira.xwiki.org/rest/api/2/search?maxResults=100&jql=Type=Bug%20AND%20Status=Closed%20AND%20Project=XWIKI'
* 3) Recent open bugs (currently limited to 100)
* curl -X GET -H "Content-Type: application/json"
* 'http://jira.xwiki.org/rest/api/2/search?maxResults=100&jql=Type=Bug%20AND%20Status=Open%20AND%20Project=XWIKI'
* 'https://jira.xwiki.org/rest/api/2/search?maxResults=100&jql=Type=Bug%20AND%20Status=Open%20AND%20Project=XWIKI'
* WARNING: Project must be embedded in JQL query.
* Adding project (as below) as a specific parameter instead of part of JQL gives irrelevant results (?):
* (wrong request) https://jira.xwiki.org/rest/api/2/search?project=XWIKI&maxResults=0&jql=Type=Bug%20AND%20Status=Open
......@@ -123,9 +123,9 @@ public class JiraHandler extends JsonDataHandler {
stat = 0;
}
if(this.unansweredBugs < 0) {
this.unansweredBugs = this.totalBugs = stat; // Should be all open bugs (1st query)
this.unansweredBugs = this.totalBugs = stat; // Should be all open bugs (stat from 1st query)
} else {
this.unansweredBugs -= stat; // Substract commented bugs (2nd query)
this.unansweredBugs -= stat; // Substract commented bugs (stat from 2nd query)
}
}
}
......@@ -188,6 +188,8 @@ public class JiraHandler extends JsonDataHandler {
super.endParsing();
getMetrics().put("ActiveUsers", Double.valueOf(getBugTrackerActiveUsers().size()));
getMetrics().put("UnansweredBugs", Double.valueOf(getUnansweredBugs()));
getMetrics().put("BugsCount", Double.valueOf(getBugsCount()));
getMetrics().put("UnansweredBugsCount", Double.valueOf(getUnansweredBugsCount()));
getMetrics().put("Opentime", Double.valueOf(getBugOpenTime()));
getMetrics().put("AverageResponseTime", Double.valueOf(getBugResponseTime()));
}
......
......@@ -22,8 +22,8 @@ class GithubHandlerTest {
assertEquals(37956, handler.getBugResponseTime());
assertEquals(8, handler.getBugTrackerActiveUsers().size());
assertEquals(3, handler.getUnansweredBugsCount());
assertEquals(4, handler.getBugsCount());
assertEquals(75, handler.getUnansweredBugs()); // unanswered bugs ratio
assertEquals(7, handler.getBugsCount());
assertEquals(43, handler.getUnansweredBugs()); // unanswered bugs ratio
} catch(Exception e) {
e.printStackTrace();
}
......
{
"id": 97740785,
"node_id": "MDEwOlJlcG9zaXRvcnk5Nzc0MDc4NQ==",
"name": "telosys-cli",
"full_name": "telosys-tools-bricks/telosys-cli",
"private": false,
"owner": {
"login": "telosys-tools-bricks",
"id": 8697336,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjg2OTczMzY=",
"avatar_url": "https://avatars.githubusercontent.com/u/8697336?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/telosys-tools-bricks",
"html_url": "https://github.com/telosys-tools-bricks",
"followers_url": "https://api.github.com/users/telosys-tools-bricks/followers",
"following_url": "https://api.github.com/users/telosys-tools-bricks/following{/other_user}",
"gists_url": "https://api.github.com/users/telosys-tools-bricks/gists{/gist_id}",
"starred_url": "https://api.github.com/users/telosys-tools-bricks/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/telosys-tools-bricks/subscriptions",
"organizations_url": "https://api.github.com/users/telosys-tools-bricks/orgs",
"repos_url": "https://api.github.com/users/telosys-tools-bricks/repos",
"events_url": "https://api.github.com/users/telosys-tools-bricks/events{/privacy}",
"received_events_url": "https://api.github.com/users/telosys-tools-bricks/received_events",
"type": "Organization",
"site_admin": false
},
"html_url": "https://github.com/telosys-tools-bricks/telosys-cli",
"description": "Telosys v 3 CLI - Command Line Interface",
"fork": false,
"url": "https://api.github.com/repos/telosys-tools-bricks/telosys-cli",
"forks_url": "https://api.github.com/repos/telosys-tools-bricks/telosys-cli/forks",
"keys_url": "https://api.github.com/repos/telosys-tools-bricks/telosys-cli/keys{/key_id}",
"collaborators_url": "https://api.github.com/repos/telosys-tools-bricks/telosys-cli/collaborators{/collaborator}",
"teams_url": "https://api.github.com/repos/telosys-tools-bricks/telosys-cli/teams",
"hooks_url": "https://api.github.com/repos/telosys-tools-bricks/telosys-cli/hooks",
"issue_events_url": "https://api.github.com/repos/telosys-tools-bricks/telosys-cli/issues/events{/number}",
"events_url": "https://api.github.com/repos/telosys-tools-bricks/telosys-cli/events",
"assignees_url": "https://api.github.com/repos/telosys-tools-bricks/telosys-cli/assignees{/user}",
"branches_url": "https://api.github.com/repos/telosys-tools-bricks/telosys-cli/branches{/branch}",
"tags_url": "https://api.github.com/repos/telosys-tools-bricks/telosys-cli/tags",
"blobs_url": "https://api.github.com/repos/telosys-tools-bricks/telosys-cli/git/blobs{/sha}",
"git_tags_url": "https://api.github.com/repos/telosys-tools-bricks/telosys-cli/git/tags{/sha}",
"git_refs_url": "https://api.github.com/repos/telosys-tools-bricks/telosys-cli/git/refs{/sha}",
"trees_url": "https://api.github.com/repos/telosys-tools-bricks/telosys-cli/git/trees{/sha}",
"statuses_url": "https://api.github.com/repos/telosys-tools-bricks/telosys-cli/statuses/{sha}",
"languages_url": "https://api.github.com/repos/telosys-tools-bricks/telosys-cli/languages",
"stargazers_url": "https://api.github.com/repos/telosys-tools-bricks/telosys-cli/stargazers",
"contributors_url": "https://api.github.com/repos/telosys-tools-bricks/telosys-cli/contributors",
"subscribers_url": "https://api.github.com/repos/telosys-tools-bricks/telosys-cli/subscribers",
"subscription_url": "https://api.github.com/repos/telosys-tools-bricks/telosys-cli/subscription",
"commits_url": "https://api.github.com/repos/telosys-tools-bricks/telosys-cli/commits{/sha}",
"git_commits_url": "https://api.github.com/repos/telosys-tools-bricks/telosys-cli/git/commits{/sha}",
"comments_url": "https://api.github.com/repos/telosys-tools-bricks/telosys-cli/comments{/number}",
"issue_comment_url": "https://api.github.com/repos/telosys-tools-bricks/telosys-cli/issues/comments{/number}",
"contents_url": "https://api.github.com/repos/telosys-tools-bricks/telosys-cli/contents/{+path}",
"compare_url": "https://api.github.com/repos/telosys-tools-bricks/telosys-cli/compare/{base}...{head}",
"merges_url": "https://api.github.com/repos/telosys-tools-bricks/telosys-cli/merges",
"archive_url": "https://api.github.com/repos/telosys-tools-bricks/telosys-cli/{archive_format}{/ref}",
"downloads_url": "https://api.github.com/repos/telosys-tools-bricks/telosys-cli/downloads",
"issues_url": "https://api.github.com/repos/telosys-tools-bricks/telosys-cli/issues{/number}",
"pulls_url": "https://api.github.com/repos/telosys-tools-bricks/telosys-cli/pulls{/number}",
"milestones_url": "https://api.github.com/repos/telosys-tools-bricks/telosys-cli/milestones{/number}",
"notifications_url": "https://api.github.com/repos/telosys-tools-bricks/telosys-cli/notifications{?since,all,participating}",
"labels_url": "https://api.github.com/repos/telosys-tools-bricks/telosys-cli/labels{/name}",
"releases_url": "https://api.github.com/repos/telosys-tools-bricks/telosys-cli/releases{/id}",
"deployments_url": "https://api.github.com/repos/telosys-tools-bricks/telosys-cli/deployments",
"created_at": "2017-07-19T16:55:51Z",
"updated_at": "2022-01-06T20:31:06Z",
"pushed_at": "2022-01-06T20:31:02Z",
"git_url": "git://github.com/telosys-tools-bricks/telosys-cli.git",
"ssh_url": "git@github.com:telosys-tools-bricks/telosys-cli.git",
"clone_url": "https://github.com/telosys-tools-bricks/telosys-cli.git",
"svn_url": "https://github.com/telosys-tools-bricks/telosys-cli",
"homepage": "",
"size": 415,
"stargazers_count": 86,
"watchers_count": 86,
"language": "Java",
"has_issues": true,
"has_projects": true,
"has_downloads": true,
"has_wiki": true,
"has_pages": false,
"forks_count": 17,
"mirror_url": null,
"archived": false,
"disabled": false,
"open_issues_count": 7,
"license": {
"key": "lgpl-3.0",
"name": "GNU Lesser General Public License v3.0",
"spdx_id": "LGPL-3.0",
"url": "https://api.github.com/licenses/lgpl-3.0",
"node_id": "MDc6TGljZW5zZTEy"
},
"allow_forking": true,
"is_template": false,
"topics": [
"cli",
"codegenerator",
"generator",
"java",
"telosys"
],
"visibility": "public",
"forks": 17,
"open_issues": 7,
"watchers": 86,
"default_branch": "master",
"temp_clone_token": null,
"organization": {
"login": "telosys-tools-bricks",
"id": 8697336,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjg2OTczMzY=",
"avatar_url": "https://avatars.githubusercontent.com/u/8697336?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/telosys-tools-bricks",
"html_url": "https://github.com/telosys-tools-bricks",
"followers_url": "https://api.github.com/users/telosys-tools-bricks/followers",
"following_url": "https://api.github.com/users/telosys-tools-bricks/following{/other_user}",
"gists_url": "https://api.github.com/users/telosys-tools-bricks/gists{/gist_id}",
"starred_url": "https://api.github.com/users/telosys-tools-bricks/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/telosys-tools-bricks/subscriptions",
"organizations_url": "https://api.github.com/users/telosys-tools-bricks/orgs",
"repos_url": "https://api.github.com/users/telosys-tools-bricks/repos",
"events_url": "https://api.github.com/users/telosys-tools-bricks/events{/privacy}",
"received_events_url": "https://api.github.com/users/telosys-tools-bricks/received_events",
"type": "Organization",
"site_admin": false
},
"network_count": 17,
"subscribers_count": 12
}
[
{
"url": "https://api.github.com/repos/telosys-tools-bricks/telosys-cli/issues/18",
......@@ -355,7 +488,7 @@
"due_on": null,
"closed_at": null
},
"comments": 3,
"comments": 0,
"created_at": "2018-02-28T11:00:54Z",
"updated_at": "2018-03-01T16:14:34Z",
"closed_at": "2018-03-01T16:14:33Z",
......
......@@ -3,7 +3,7 @@
"counts" : {
"all" : 13,
"closed" : 11,
"opened" : 2
"opened" : 13
}
}
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment