adamtornhill / code-maat

A command line tool to mine and analyze data from version-control systems
http://www.adamtornhill.com/code/codemaat.htm
2.38k stars 222 forks source link

Option for more verbose output in change coupling analysis? #87

Closed famkedriessen closed 1 year ago

famkedriessen commented 1 year ago

Hi! I am currently doing research in whether change coupling can help in the decision-making on the granularity of microservices. In the csv outputted by the tool after a change coupling analysis, an entry currently consists of the names of the coupled pair, the coupling degree and the average number of revisions. Would it be possible to get a more verbose output here which also shows the absolute number of revisions for each entity and the absolute number of times the entities were in the same logical change set? I tried to implement this myself (with zero Clojure knowledge), but the implementation below doesn't do the trick (or something is going wrong in the building process). The error I get when using my jar (and running the change coupling analysis) is:

java -jar C:....\code-maat-1.0.5-SNAPSHOT-standalone.jar -l test.log -c git2 -a coupling -t 2 -n 1 -m 1 -i 1 -s 100 Invalid argument: Internal error - please report it. Details = class clojure.lang.PersistentVector cannot be cast to class java.lang.Number (clojure.lang.PersistentVector is in unnamed module of loader 'app'; java.lang.Number is in module java.base of loader 'bootstrap')

(defn- as-logical-coupling-measure
  [ds options within-threshold-fn?]
  (let [co-changing (c/co-changing-by-revision ds options)
        module-revs (c/module-by-revs co-changing)
        coupling-percentage (c/coupling-frequencies co-changing)]
    (for [[[first-entity second-entity] shared-revs] coupling-percentage
          :let [entity1-revs (module-revs first-entity)
                entity2-revs (module-revs second-entity)
                shared-revs-count shared-revs
                average-revs (m/average entity1-revs entity2-revs)]
          :when (within-threshold-fn? average-revs shared-revs coupling-percentage)]
      [first-entity second-entity
       (int coupling-percentage) (math/ceil average-revs) (count entity1-revs) (count entity2-revs) shared-revs-count])))

(defn by-degree
  ([ds options]
   (by-degree ds options :desc))
  ([ds options order-fn]
   (->>
    (partial c/within-threshold? options)
    (as-logical-coupling-measure ds options)
    (ds/-dataset [:entity :coupled :degree :average-revs :entity1-revs :entity2-revs :shared-revs])
    (incanter/$order [:degree :average-revs] `order-fn))))
adamtornhill commented 1 year ago

Hi @famkedriessen

I took a look at this, and implemented the requested option. Please find the PR here: https://github.com/adamtornhill/code-maat/pull/88

Let me know if this matches your expectations, and I will merge the PR and make it part of the formal release.

famkedriessen commented 1 year ago

Hi Adam, Thanks a lot, this is exactly what I needed. As far as I can see it works fine, thanks to the more verbose outpute I was able to notice a small peculiarity though, which has to do with how temporal periods are implemented i think. I will open a new issue for it so you can give it a look.

adamtornhill commented 1 year ago

Thanks for the feedback. I'll close this issue now since the PR is merged. Let's continue the discussion in https://github.com/adamtornhill/code-maat/issues/89