Am 17/10/2014 15:14, schrieb Matthias Dittrich: > This commit integrates the feature analysis added by the last commits by > providing a --collaboration parameter. > This parameter defaults to "function" which is exactly the old bahaviour. > You can also set it to "feature_file" which is a per-file feature analysis or > "feature" for a project wide feature analysis. > > Signed-off-by: Matthias Dittrich <matthi.d@xxxxxxxxx> > --- > codeface/VCS.py | 20 +++++++++++++------- > codeface/cli.py | 7 ++++++- > codeface/cluster/cluster.py | 26 ++++++++++++++++---------- > codeface/project.py | 4 ++-- > 4 files changed, 37 insertions(+), 20 deletions(-) > > diff --git a/codeface/VCS.py b/codeface/VCS.py > index 8bf7022..98a779e 100644 > --- a/codeface/VCS.py > +++ b/codeface/VCS.py > @@ -811,7 +811,7 @@ class gitVCS (VCS): > for logstring in reversed(clist)] > > > - def extractCommitData(self, subsys="__main__", link_type=None): > + def extractCommitData(self, subsys="__main__", link_type=None, > collab_type="function"): > if not(self._subsysIsValid(subsys)): > log.critical("Subsys specification invalid: > {0}\n".format(subsys)) > raise Error("Invalid subsystem specification.") > @@ -827,7 +827,7 @@ class gitVCS (VCS): > > if link_type in ("proximity", "file"): > self.addFiles4Analysis() > - self._prepareFileCommitList(self._fileNames, link_type=link_type) > + self._prepareFileCommitList(self._fileNames, > link_type=link_type, collab_type=collab_type) > > # _commit_list_dict as computed by _prepareCommitLists() already > # provides a decomposition of the commit list into subsystems: > @@ -908,7 +908,7 @@ class gitVCS (VCS): > > > def _prepareFileCommitList(self, fnameList, link_type, singleBlame=True, > - ignoreOldCmts=True): > + ignoreOldCmts=True, collab_type="function"): > ''' > uses git blame to determine the file layout of a revision > ''' > @@ -977,13 +977,13 @@ class gitVCS (VCS): > # retrieve blame data > if singleBlame: #only one set of blame data per file > self._addBlameRev(self.rev_end, file_commit, > - blameMsgCmtIds, link_type) > + blameMsgCmtIds, link_type, > collab_type=collab_type) > else: # get one set of blame data for every commit made > # this option is computationally intensive thus the > alternative > # singleBlame option is possible when speed is a higher > # priority than precision > [self._addBlameRev(cmt.id, file_commit, > - blameMsgCmtIds, link_type) for cmt in > cmtList] > + blameMsgCmtIds, link_type, > collab_type=collab_type) for cmt in cmtList] > > #store fileCommit object to dictionary > self._fileCommit_dict[fname] = file_commit > @@ -1029,7 +1029,7 @@ class gitVCS (VCS): > > pbar.finish() > > - def _addBlameRev(self, rev, file_commit, blame_cmt_ids, link_type): > + def _addBlameRev(self, rev, file_commit, blame_cmt_ids, link_type, > collab_type="function"): > ''' > saves the git blame output of a revision for a particular file > ''' > @@ -1056,7 +1056,13 @@ class gitVCS (VCS): > > # locate all function lines in the file > if link_type=="proximity": # separate the file commits into code > structures > - self._getFunctionLines(src_lines, file_commit) > + if collab_type == "function": > + self._getFunctionLines(src_lines, file_commit) > + elif collab_type == "feature_file" or collab_type == "feature": > + self._getFeatureLines(src_lines, file_commit) > + else: > + raise Exception("unknown collaboration type!") > + > # else: do not separate file commits into code structures, > # this will result in all commits to a single file seen as > # related thus the more course grained analysis > diff --git a/codeface/cli.py b/codeface/cli.py > index 708b6b5..b9f99c0 100644 > --- a/codeface/cli.py > +++ b/codeface/cli.py > @@ -56,6 +56,11 @@ def get_parser(): > run_parser.set_defaults(func=cmd_run) > run_parser.add_argument('-c', '--config', help="Prosoda configuration > file", > default='codeface.conf') > + run_parser.add_argument( > + '--collaboration', > + help="Type of commit collaboration analysis (function, feature_file > and feature). " > + "feature is currently unsupported, default is function", > + default='function') > run_parser.add_argument('-p', '--project', help="Project configuration > file", > required=True) > run_parser.add_argument('resdir', > @@ -103,7 +108,7 @@ def cmd_run(args): > logfile = os.path.abspath(logfile) > project_analyse(resdir, gitdir, codeface_conf, project_conf, > args.no_report, args.loglevel, logfile, args.recreate, > - args.profile_r, args.jobs) > + args.profile_r, args.jobs, args.collaboration) > return 0 > > def cmd_ml(args): > diff --git a/codeface/cluster/cluster.py b/codeface/cluster/cluster.py > index 45cfb59..b09db46 100755 > --- a/codeface/cluster/cluster.py > +++ b/codeface/cluster/cluster.py > @@ -53,7 +53,7 @@ class LinkType: > > > def createDB(filename, git_repo, revrange, subsys_descr, link_type, > - range_by_date, rcranges=None): > + range_by_date, rcranges=None, collab_type="function"): > #------------------ > #configuration > #------------------ > @@ -69,7 +69,7 @@ def createDB(filename, git_repo, revrange, subsys_descr, > link_type, > #------------------------ > #data extraction > #------------------------ > - git.extractCommitData(link_type=link_type) > + git.extractCommitData(link_type=link_type, collab_type=collab_type) > > #------------------------ > #save data > @@ -1612,14 +1612,14 @@ def computeSimilarity(cmtlist): > ########################################################################### > def performAnalysis(conf, dbm, dbfilename, git_repo, revrange, subsys_descr, > create_db, outdir, limit_history, > - range_by_date, rcranges=None): > + range_by_date, rcranges=None, collab_type="function"): > link_type = conf["tagging"] > > if create_db == True: > log.devinfo("Creating data base for {0}..{1}".format(revrange[0], > revrange[1])) > createDB(dbfilename, git_repo, revrange, subsys_descr, \ > - link_type, range_by_date, rcranges) > + link_type, range_by_date, rcranges, collab_type) > > projectID = dbm.getProjectID(conf["project"], conf["tagging"]) > revisionIDs = (dbm.getRevisionID(projectID, revrange[0]), > @@ -1656,10 +1656,16 @@ def performAnalysis(conf, dbm, dbfilename, git_repo, > revrange, subsys_descr, > startDate = None > > fileCommitDict = git.getFileCommitDict() > - computeProximityLinks(fileCommitDict, cmtdict, id_mgr, link_type, > - startDate) > - logical_depends = computeLogicalDepends(fileCommitDict, cmtdict, > - startDate) > + logical_depends = None > + if collab_type == "function": > + computeProximityLinks(fileCommitDict, cmtdict, id_mgr, > link_type, startDate) > + logical_depends = computeLogicalDepends(fileCommitDict, cmtdict, > startDate) > + elif collab_type == "feature_file": > + compute_feature_proximity_links_perfile(fileCommitDict, cmtdict, > id_mgr, link_type, startDate) > + elif collab_type == "feature": > + compute_feature_proximity_links(fileCommitDict, cmtdict, id_mgr, > link_type, startDate) > + else: > + raise Exception("Unsupported collaboration type!") > #--------------------------------- > #compute statistical information > #--------------------------------- > @@ -1675,7 +1681,7 @@ def performAnalysis(conf, dbm, dbfilename, git_repo, > revrange, subsys_descr, > > ################################################################## > def doProjectAnalysis(conf, from_rev, to_rev, rc_start, outdir, > - git_repo, create_db, limit_history, range_by_date): > + git_repo, create_db, limit_history, range_by_date, > collab_type="function"): > #-------------- > #folder setup > #-------------- > @@ -1699,7 +1705,7 @@ def doProjectAnalysis(conf, from_rev, to_rev, rc_start, > outdir, > dbm = DBManager(conf) > performAnalysis(conf, dbm, filename, git_repo, [from_rev, to_rev], > None, create_db, outdir, limit_history, range_by_date, > - rc_range) > + rc_range, collab_type) > > ################################## > # TESTING CODE > diff --git a/codeface/project.py b/codeface/project.py > index a311fb7..f105f4e 100644 > --- a/codeface/project.py > +++ b/codeface/project.py > @@ -51,7 +51,7 @@ def project_setup(conf, recreate): > return project_id, dbm, all_range_ids > > def project_analyse(resdir, gitdir, codeface_conf, project_conf, > - no_report, loglevel, logfile, recreate, profile_r, > n_jobs): > + no_report, loglevel, logfile, recreate, profile_r, > n_jobs, collab_type): > pool = BatchJobPool(int(n_jobs)) > conf = Configuration.load(codeface_conf, project_conf) > project, tagging = conf["project"], conf["tagging"] > @@ -88,7 +88,7 @@ def project_analyse(resdir, gitdir, codeface_conf, > project_conf, > s1 = pool.add( > doProjectAnalysis, > (conf, start_rev, end_rev, rc_rev, range_resdir, repo, > - True, True, range_by_date), > + True, True, range_by_date, collab_type), > startmsg=prefix + "Analysing commits...", > endmsg=prefix + "Commit analysis done." > ) > Looks good to me, thanks! Best regards, Wolfgang