[codeface] Re: [PATCH 9/9] Integrate feature analysis by providing a CLI parameter.

  • From: Wolfgang Mauerer <wm@xxxxxxxxxxxxxxxx>
  • To: codeface@xxxxxxxxxxxxx
  • Date: Mon, 17 Nov 2014 17:59:00 +0100


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

Other related posts: