|
@@ -79,6 +79,9 @@ class Reader(object):
|
|
|
def get_header(self):
|
|
|
raise NotImplementedError
|
|
|
|
|
|
+ def get_burndown_parameters(self):
|
|
|
+ raise NotImplementedError
|
|
|
+
|
|
|
def get_project_burndown(self):
|
|
|
raise NotImplementedError
|
|
|
|
|
@@ -122,35 +125,43 @@ class YamlReader(Reader):
|
|
|
self.data = data
|
|
|
|
|
|
def get_name(self):
|
|
|
- return next(iter(self.data["project"]))
|
|
|
+ return next(iter(self.data["Burndown"]["project"]))
|
|
|
|
|
|
def get_header(self):
|
|
|
- header = self.data["burndown"]
|
|
|
- return header["begin"], header["end"], header["sampling"], header["granularity"]
|
|
|
+ header = self.data["hercules"]
|
|
|
+ return header["begin_unix_time"], header["end_unix_time"]
|
|
|
+
|
|
|
+ def get_burndown_parameters(self):
|
|
|
+ header = self.data["Burndown"]
|
|
|
+ return header["sampling"], header["granularity"]
|
|
|
|
|
|
def get_project_burndown(self):
|
|
|
- name, matrix = next(iter(self.data["project"].items()))
|
|
|
- return name, self._parse_burndown_matrix(matrix).T
|
|
|
+ return self.data["hercules"]["repository"], \
|
|
|
+ self._parse_burndown_matrix(self.data["Burndown"]["project"]).T
|
|
|
|
|
|
def get_files_burndown(self):
|
|
|
- return [(p[0], self._parse_burndown_matrix(p[1]).T) for p in self.data["files"].items()]
|
|
|
+ return [(p[0], self._parse_burndown_matrix(p[1]).T)
|
|
|
+ for p in self.data["Burndown"]["files"].items()]
|
|
|
|
|
|
def get_people_burndown(self):
|
|
|
- return [(p[0], self._parse_burndown_matrix(p[1]).T) for p in self.data["people"].items()]
|
|
|
+ return [(p[0], self._parse_burndown_matrix(p[1]).T)
|
|
|
+ for p in self.data["Burndown"]["people"].items()]
|
|
|
|
|
|
def get_ownership_burndown(self):
|
|
|
- return self.data["people_sequence"], {p[0]: self._parse_burndown_matrix(p[1])
|
|
|
- for p in self.data["people"].items()}
|
|
|
+ return self.data["Burndown"]["people_sequence"],\
|
|
|
+ {p[0]: self._parse_burndown_matrix(p[1])
|
|
|
+ for p in self.data["Burndown"]["people"].items()}
|
|
|
|
|
|
def get_people_interaction(self):
|
|
|
- return self.data["people_sequence"], self._parse_burndown_matrix(self.data["people_interaction"])
|
|
|
+ return self.data["Burndown"]["people_sequence"], \
|
|
|
+ self._parse_burndown_matrix(self.data["Burndown"]["people_interaction"])
|
|
|
|
|
|
def get_files_coocc(self):
|
|
|
- coocc = self.data["files_coocc"]
|
|
|
+ coocc = self.data["Couples"]["files_coocc"]
|
|
|
return coocc["index"], self._parse_coocc_matrix(coocc["matrix"])
|
|
|
|
|
|
def get_people_coocc(self):
|
|
|
- coocc = self.data["people_coocc"]
|
|
|
+ coocc = self.data["Couples"]["people_coocc"]
|
|
|
return coocc["index"], self._parse_coocc_matrix(coocc["matrix"])
|
|
|
|
|
|
def _parse_burndown_matrix(self, matrix):
|
|
@@ -195,32 +206,36 @@ class ProtobufReader(Reader):
|
|
|
|
|
|
def get_header(self):
|
|
|
header = self.data.header
|
|
|
- return header.begin_unix_time, header.end_unix_time, \
|
|
|
- self.contents["Burndown"].sampling, self.contents["Burndown"].granularity
|
|
|
+ return header.begin_unix_time, header.end_unix_time
|
|
|
+
|
|
|
+ def get_burndown_parameters(self):
|
|
|
+ burndown = self.contents["Burndown"]
|
|
|
+ return burndown.sampling, burndown.granularity
|
|
|
|
|
|
def get_project_burndown(self):
|
|
|
- return self._parse_burndown_matrix(self.data.burndown_project)
|
|
|
+ return self._parse_burndown_matrix(self.contents["Burndown"].project)
|
|
|
|
|
|
def get_files_burndown(self):
|
|
|
- return [self._parse_burndown_matrix(i) for i in self.data.burndown_files]
|
|
|
+ return [self._parse_burndown_matrix(i) for i in self.contents["Burndown"].files]
|
|
|
|
|
|
def get_people_burndown(self):
|
|
|
- return [self._parse_burndown_matrix(i) for i in self.data.burndown_developers]
|
|
|
+ return [self._parse_burndown_matrix(i) for i in self.contents["Burndown"].people]
|
|
|
|
|
|
def get_ownership_burndown(self):
|
|
|
people = self.get_people_burndown()
|
|
|
return [p[0] for p in people], {p[0]: p[1].T for p in people}
|
|
|
|
|
|
def get_people_interaction(self):
|
|
|
- return [i.name for i in self.data.burndown_developers], \
|
|
|
- self._parse_sparse_matrix(self.contents["Couples"].developers_interaction).toarray()
|
|
|
+ burndown = self.contents["Burndown"]
|
|
|
+ return [i.name for i in burndown.people], \
|
|
|
+ self._parse_sparse_matrix(burndown.people_interaction).toarray()
|
|
|
|
|
|
def get_files_coocc(self):
|
|
|
- node = self.data.file_couples
|
|
|
+ node = self.contents["Couples"].file_couples
|
|
|
return list(node.index), self._parse_sparse_matrix(node.matrix)
|
|
|
|
|
|
def get_people_coocc(self):
|
|
|
- node = self.data.developer_couples
|
|
|
+ node = self.contents["Couples"].developer_couples
|
|
|
return list(node.index), self._parse_sparse_matrix(node.matrix)
|
|
|
|
|
|
def _parse_burndown_matrix(self, matrix):
|
|
@@ -833,40 +848,65 @@ def main():
|
|
|
header = reader.get_header()
|
|
|
name = reader.get_name()
|
|
|
|
|
|
- files_warning = "Files stats were not collected. Re-run hercules with -files."
|
|
|
- people_warning = "People stats were not collected. Re-run hercules with -people."
|
|
|
+ burndown_warning = "Burndown stats were not collected. Re-run hercules with -burndown."
|
|
|
+ burndown_files_warning = \
|
|
|
+ "Burndown stats for people were not collected. Re-run hercules with " \
|
|
|
+ "-burndown -burndown-files."
|
|
|
+ burndown_people_warning = \
|
|
|
+ "Burndown stats for people were not collected. Re-run hercules with " \
|
|
|
+ "-burndown -burndown-people."
|
|
|
couples_warning = "Coupling stats were not collected. Re-run hercules with -couples."
|
|
|
|
|
|
def project_burndown():
|
|
|
+ try:
|
|
|
+ full_header = header + reader.get_burndown_parameters()
|
|
|
+ except KeyError:
|
|
|
+ print(burndown_warning)
|
|
|
+ return
|
|
|
plot_burndown(args, "project",
|
|
|
- *load_burndown(header, *reader.get_project_burndown(),
|
|
|
+ *load_burndown(full_header, *reader.get_project_burndown(),
|
|
|
resample=args.resample))
|
|
|
|
|
|
def files_burndown():
|
|
|
try:
|
|
|
- plot_many_burndown(args, "file", header, reader.get_files_burndown())
|
|
|
+ full_header = header + reader.get_burndown_parameters()
|
|
|
except KeyError:
|
|
|
- print(files_warning)
|
|
|
+ print(burndown_warning)
|
|
|
+ return
|
|
|
+ try:
|
|
|
+ plot_many_burndown(args, "file", full_header, reader.get_files_burndown())
|
|
|
+ except KeyError:
|
|
|
+ print(burndown_files_warning)
|
|
|
|
|
|
def people_burndown():
|
|
|
try:
|
|
|
- plot_many_burndown(args, "person", header, reader.get_people_burndown())
|
|
|
+ full_header = header + reader.get_burndown_parameters()
|
|
|
+ except KeyError:
|
|
|
+ print(burndown_warning)
|
|
|
+ return
|
|
|
+ try:
|
|
|
+ plot_many_burndown(args, "person", full_header, reader.get_people_burndown())
|
|
|
except KeyError:
|
|
|
- print(people_warning)
|
|
|
+ print(burndown_people_warning)
|
|
|
|
|
|
def churn_matrix():
|
|
|
try:
|
|
|
plot_churn_matrix(args, name, *load_churn_matrix(
|
|
|
*reader.get_people_interaction(), max_people=args.max_people))
|
|
|
except KeyError:
|
|
|
- print(people_warning)
|
|
|
+ print(burndown_people_warning)
|
|
|
|
|
|
def ownership_burndown():
|
|
|
try:
|
|
|
+ full_header = header + reader.get_burndown_parameters()
|
|
|
+ except KeyError:
|
|
|
+ print(burndown_warning)
|
|
|
+ return
|
|
|
+ try:
|
|
|
plot_ownership(args, name, *load_ownership(
|
|
|
- header, *reader.get_ownership_burndown(), max_people=args.max_people))
|
|
|
+ full_header, *reader.get_ownership_burndown(), max_people=args.max_people))
|
|
|
except KeyError:
|
|
|
- print(people_warning)
|
|
|
+ print(burndown_people_warning)
|
|
|
|
|
|
def couples():
|
|
|
try:
|