--- a/metric-providers/org.ossmeter.metricprovider.trans.rascal.activecommitters/src/ActiveCommitters.rsc
+++ b/metric-providers/org.ossmeter.metricprovider.trans.rascal.activecommitters/src/ActiveCommitters.rsc
@@ -10,7 +10,8 @@
import DateTime;
import String;
import util::Math;
-
+import analysis::statistics::SimpleRegression;
+
@metric{committersToday}
@doc{activeCommitters}
@friendlyName{activeCommitters}
@@ -30,6 +31,17 @@
return {<d,t> | <d,t> <- prev, d > twoweeks} + {<today, committersToday>};
}
+@metric{longerTermActiveCommitters}
+@doc{Committers who have been active the last 6 months}
+@friendlyName{committersLastTwoWeeks}
+@uses{("org.ossmeter.metricprovider.trans.rascal.activecommitters.committersToday":"committersToday")}
+@appliesTo{generic()}
+rel[datetime, set[str]] longerTermActiveCommitters(ProjectDelta delta = \empty(), rel[datetime,set[str]] prev = {}, set[str] committersToday = {}) {
+ today = delta.date;
+ twoweeks = decrementMonths(today, 6);
+ return {<d,t> | <d,t> <- prev, d > twoweeks} + {<today, committersToday>};
+}
+
@metric{numberOfActiveCommitters}
@doc{Number of active committers over time}
@@ -38,6 +50,14 @@
@appliesTo{generic()}
@historic{}
int numberOfActiveCommitters(rel[datetime, set[str]] activeCommitters = {})
+ = size({c | /str c := activeCommitters});
+
+@metric{numberOfActiveCommittersLongTerm}
+@doc{Number of active committers over time}
+@friendlyName{numberOfActiveCommittersLongTerm}
+@uses{("org.ossmeter.metricprovider.trans.rascal.activecommitters.longerTermActiveCommitters" :"activeCommitters")}
+@appliesTo{generic()}
+int numberOfActiveCommittersLongTerm(rel[datetime, set[str]] activeCommitters = {})
= size({c | /str c := activeCommitters});
@metric{maximumActiveCommittersEver}
@@ -49,11 +69,46 @@
return max(history<n>);
}
-@metric{programmerCommunity}
+@metric{developmentTeamStability}
@doc{based on committer activity, what is the health of the community?}
-@friendlyName{community of programmers}
+@friendlyName{Development team stability}
+@uses{("org.ossmeter.metricprovider.trans.rascal.activecommitters.numberOfActiveCommitters.historic" :"history"
+ ,"org.ossmeter.metricprovider.trans.rascal.activecommitters.maximumActiveCommittersEver":"maxDevs"
+ ,"org.ossmeter.metricprovider.trans.rascal.activecommitters.numberOfActiveCommitters":"activeDevs"
+ ,"org.ossmeter.metricprovider.trans.rascal.activecommitters.numberOfActiveCommittersLongTerm":"longTermActive")}
@appliesTo{generic()}
-Factoid programmerCommunity() {
- return factoid("This is a test", four());
+Factoid developmentTeamStability(rel[datetime day, int active] history = {}, int maxDevs = 0, int activeDevs = 0, int longTermActive = 0) {
+ sorted = sort(history, bool(tuple[datetime,int] a, tuple[datetime,int] b) { return a[0] < b[0]; });
+
+ halfYearAgo = decrementMonths(sorted[-1].day, 6);
+ lastYear = [<d,m> | <d,m> <- sorted, d > halfYearAgo];
+ sl = slope([<i,lastYear[i][1]> | i <- index(lastYear)]);
+
+ stability = \one();
+ team = "";
+
+ if (-0.1 < sl && sl < 0.1 && longTermActive > 0) {
+ stability = \three();
+ team = "In the last half year the development team was stable and active.";
+ }
+ else if (-0.1 < sl && sl < 0.1 && longTermActive == 0) {
+ stability = \one(); // project is dead
+ team = "The project has seen hardly anybody developing in the last half year.";
+ }
+ else if (sl < 0 && longTermActive > 0) {
+ stability = \two();
+ team = "People have been leaving the development team in the last half year.";
+ }
+ else if (sl > 0) {
+ stability = \four(); // people are coming
+ team = "In the last half year the development team has been growing.";
+ }
+
+ txt = "<team>
+ 'The maximum number of active developers for this project during its lifetime is <maxDevs>,
+ 'and in the last two weeks there were <activeDevs> people actively developing, as compared to
+ '<longTermActive> in the last six months.";
+
+ return factoid(txt, stability);
}