Giter VIP home page Giter VIP logo

code-maat's Introduction

Build Status

Code Maat

Code Maat is a command line tool used to mine and analyze data from version-control systems (VCS).

Code Maat was developed to accompany the discussions in my books Your Code as a Crime Scene and Software Design X-Rays.

Note that the analyses have evolved into CodeScene, which automates all the analyses found in Code Maat and several new ones.

Code Maat Maintainability

CodeScene Code Health

CodeScene System Mastery

The ideas behind Code Maat

To understand large-scale software systems we need to look at their evolution. The history of our system provides us with data we cannot derive from a single snapshot of the source code. Instead VCS data blends technical, social and organizational information along a temporal axis that let us map out our interaction patterns in the code. Analyzing these patterns gives us early warnings on potential design issues and development bottlenecks, as well as suggesting new modularities based on actual interactions with the code. Addressing these issues saves costs, simplifies maintenance and let us evolve our systems in the direction of how we actually work with the code.

About the name

Maat was a goddess in ancient Egyptian myth. She was the one who gave us order out of the initial chaos in the universe. Code Maat hopes to continue the work of Maat, albeit on a smaller basis, by highlighting code with chaotic development practices and suggest the directions of future refactorings to bring order to it. Further, maat was used in ancient Egypt as a concept of truth. And metrics never lie (except when they do).

License

Copyright © 2013 Adam Tornhill

Distributed under the GNU General Public License v3.0.

Usage

Code Maat is written in Clojure. To build it from source, use leiningen:

   lein uberjar

The command above will create a standalone jar containing all the dependencies.

We also publish a pre-built executable JAR file as part of the latest release that you can download and run directly.

You can also build code-maat as a Docker image:

  docker build -t code-maat-app .

Finally, if you want to use Code Maat as a library, then add the following line to your leiningen dependencies:

   [code-maat "1.0.1"]

Generating input data

Code Maat operates on log files from version-control systems. The supported version-control systems are git, Mercurial (hg), svn, Perforce (p4), and Team Foundation Server (tfs). The log files are generated by using the version-control systems themselves as described in the following sections.

Preparations

To analyze our VCS data we need to define a temporal period of interest. Over time, many design issues do get fixed and we don't want old data to interfere with our current analysis of the code. To limit the data Code Maat will consider, use one of the following flags depending on your version-control system:

  • git: Use the --after=<date> to specify the last date of interest. The <date> is given as YYYY-MM-DD.
  • hg: Use the --date switch to specify the last date of interest. The value is given as ">YYYY-MM-DD".
  • svn: Use the -r option to specify a range of interest, for example -r {20130820}:HEAD.
  • p4: Use the -m option to specify the last specified number of changelists, for example -m 1000.
  • tfs: Use the /stopafter option to specify the number of changesets, for example /stopafter:1000

Generate a Subversion log file using the following command:

      svn log -v --xml > logfile.log -r {YYYYmmDD}:HEAD

Generate a git log file using the following command:

The first options is the legacy format used in Your Code As A Crime Scene. Use the -c git parse option when Running Code Maat.

      git log --pretty=format:'[%h] %aN %ad %s' --date=short --numstat --after=YYYY-MM-DD > logfile.log

There's a second supported Git format as well. It's more tolerant and faster to parse, so please prefer it over the plain git format described above. Use the -c git2 parse option when Running Code Maat.

      git log --all --numstat --date=short --pretty=format:'--%h--%ad--%aN' --no-renames --after=YYYY-MM-DD > logfile.log

Many codebases include third-party content or non-code artefacts, which might generate noise in the analyses. You can exclude such content via git's pathspecs that limit paths on the command line. For example, let's say you want to exclude everything in a vendor/ folder. You would then append the following pattern to the git log commands above:

       -- . ":(exclude)vendor/*"

To exclude multiple folders, you just append more pathspecs:

       -- . ":(exclude)vendor/" ":(exclude)test/"

Generate a Mercurial log file using the following command:

      hg log --template "rev: {rev} author: {author} date: {date|shortdate} files:\n{files %'{file}\n'}\n" --date ">YYYY-MM-DD"

Generate a Perforce log file using the following command:

      p4 changes -s submitted -m 5000 //depot/project/... | cut -d ' ' -f 2 | xargs -I commitid -n1 sh -c 'p4 describe -s commitid | grep -v "^\s*$" && echo ""'

Generate a TFS log file using the following command from a Developer command-prompt:

Note: The TFS CLI tool does not support custom date formatting. The parser currently only supports the en-us default: Friday, January 1, 2016 1:12:35 PM - you may need to adjust your system locale settings before using the following command.
      tf hist /path/to/workspace /noprompt /format:detailed /recursive

Running Code Maat

You can run Code Maat directly from leiningen:

	  lein run -l logfile.log -c <vcs>

If you've downloaded or built the standalone jar, then run it via java. Please note that you need at least Java 8 installed:

 	  java -jar code-maat-1.0.4-standalone.jar -l logfile.log -c <vcs>

If you've built a docker container, then you can run it as

    docker run -v /home/xx/src/code-maat:/data -it code-maat-app -l /data/logfile.log -c <vcs>

where the /home/xx/src/code-maat is the host's directory containing the file logfile.log.

When invoked with -h, Code Maat prints its usage:

         adam$ java -jar code-maat-1.0.4-standalone.jar
         This is Code Maat, a program used to collect statistics from a VCS.
         Version: 1.0-SNAPSHOT

         Usage: program-name -l log-file [options]

         Options:
           -l, --log LOG                                         Log file with input data
           -c, --version-control VCS                             Input vcs module type: supports svn, git, git2, hg, p4, or tfs
           -a, --analysis ANALYSIS                      authors  The analysis to run (abs-churn, age, author-churn, authors, communication, coupling, entity-churn, entity-effort, entity-ownership, fragmentation, identity, main-dev, main-dev-by-revs, messages, refactoring-main-dev, revisions, soc, summary)
          --input-encoding INPUT-ENCODING                        Specify an encoding other than UTF-8 for the log file
           -r, --rows ROWS                                       Max rows in output
           -g, --group GROUP                                     A file with a pre-defined set of layers. The data will be aggregated according to the group of layers.
           -n, --min-revs MIN-REVS                      5        Minimum number of revisions to include an entity in the analysis
           -m, --min-shared-revs MIN-SHARED-REVS        5        Minimum number of shared revisions to include an entity in the analysis
           -i, --min-coupling MIN-COUPLING              30       Minimum degree of coupling (in percentage) to consider
           -x, --max-coupling MAX-COUPLING              100      Maximum degree of coupling (in percentage) to consider
           -s, --max-changeset-size MAX-CHANGESET-SIZE  30       Maximum number of modules in a change set if it shall be included in a coupling analysis
           -e, --expression-to-match MATCH-EXPRESSION            A regex to match against commit messages. Used with -messages analyses
           -t, --temporal-period TEMPORAL-PERIOD                 Instructs Code Maat to consider all commits during the same day as a single, logical commit
           -d, --age-time-now AGE-TIME_NOW                       Specify a date as YYYY-MM-dd that counts as time zero when doing a code age analysis
           -h, --help

Optional: specify an encoding

By default, Code Maat expects your log files to be UTF-8. If you use another encoding, override the default with --input-encoding, for example --input-encoding UTF-16BE.

Generating a summary

When starting out, I find it useful to get an overview of the mined data. With the summary analysis, Code Maat produces such an overview:

   java -jar code-maat-1.0.4-standalone.jar -l logfile.log -c git -a summary

The resulting output is on csv format:

          statistic,                 value
          number-of-commits,           919
          number-of-entities,          730
          number-of-entities-changed, 3397
          number-of-authors,            79

If you use the second Git format, just specify git2 instead:

   java -jar code-maat-1.0.4-standalone.jar -l logfile2.log -c git2 -a summary

Mining organizational metrics

By default, Code Maat runs an analysis on the number of authors per module. The authors analysis is based on the idea that the more developers working on a module, the larger the communication challenges. The analysis is invoked with the following command:

   java -jar code-maat-1.0.4-standalone.jar -l logfile.log -c git

The resulting output is on CSV format:

          entity,         n-authors, n-revs
          InfoUtils.java, 12,        60
          BarChart.java,   7,        30
          Page.java,       4,        27
          ...

In example above, the first column gives us the name of module, the second the total number of distinct authors that have made commits on that module, and the third column gives us the total number of revisions of the module. Taken together, these metrics serve as predictors of defects and quality issues.

Mining logical coupling

Logical coupling refers to modules that tend to change together. Modules that are logically coupled have a hidden, implicit dependency between them such that a change to one of them leads to a predictable change in the coupled module. To analyze the logical coupling in a system, invoke Code Maat with the following arguments:

          java -jar code-maat-1.0.4-standalone.jar -l logfile.log -c git -a coupling

The resulting output is on CSV format:

          entity,          coupled,        degree,  average-revs
          InfoUtils.java,  Page.java,      78,      44
          InfoUtils.java,  BarChart.java,  62,      45
          ...

In the example above, the first column (entity) gives us the name of the module, the second (coupled) gives us the name of a logically coupled module, the third column (degree) gives us the coupling as a percentage (0-100), and finally average-revs gives us the average number of revisions of the two modules.

To interpret the data, consider the InfoUtils.java module in the example output above. The coupling tells us that each time it's modified, it's a 78% risk/chance that we'll have to change our Page.java module too. Since there's probably no reason they should change together, the analysis points to a part of the code worth investigating as a potential target for a future refactoring.

Advanced: the coupling analysis also supports --verbose-results. In verbose mode, the coupling analysis also includes the number of revisions for each coupled entity together with the number of shared revisions. The main use cases for this option are a) build custom filters to reduce noise, or b) research studies.

Calculate code age

The change frequency of code is a factor that should (but rarely do) drive the evolution of a software architecture. In general, you want to stabilize as much code as possible. A failure to stabilize means that you need to maintain a working knowledge of those parts of the code for the life-time of the system.

One way to measure the stability of a software architecture is by a code age analysis:

          java -jar code-maat-1.0.4-standalone.jar -l logfile.log -c git -a age

The age analysis grades each module based on the date of last change. The measurement unit is age in months. Here's how the result may look:

          entity,age-months
          src/code_maat/app/app.clj,2
          project.clj,4
          src/code_maat/parsers/perforce.clj,5
          ...

By default, Code Maat uses the current date as starting point for a code age analysis. You specify a different start time with the command line argument --age-time-now.

By using the techniques from Your Code as a Crime Scene we visualize the system with each module marked-up by its age (the more red, the more recent changes to the code):

code age visualized.

Visualise your Results

Code Maat doesn't include any visualizations itself. However, you do have a bunch of options.

One option is CodeScene which is free for open source and delivers all these analyses as a service. CodeScene is also available in an on-premise version. CodeScene is a complete application with automated repository mining, visualizations, and is built around the ideas prototyped in Code Maat.

I also present a whole suite of different visualization techniques and options in Your Code as a Crime Scene, so do check out the book if you want to dive deeper. You can also look at some of the basic tools I've open sourced such as Metrics Tree Map:

coupling visualized.

Yet another alternative is to save the generated CSV to a file and import it into a spreadsheet program such as OpenOffice or Excel. That allows us to generate charts such as the ones below:

coupling visualized.

Code churn measures

Code churn is related to post-release defects. Modules with higher churn tend to have more defects. There are several different aspects of code churn. I intend to support several of them in Code Maat.

Absolute churn

The absolute code churn numbers are calculated with the -a abs-churn option. Note that the option is only available for git. The analysis will output a CSV table with the churn accumulated per date:

         date,       added, deleted
         2013-08-09,   259,      20
         2013-08-19,   146,      77
         2013-08-21,     5,       6
         2013-08-20,   773,     121
         2013-08-30,   349,     185
         ...

Visualizing the result allows us to spot general trends over time:

abs churn visualized.

Churn by author

The idea behind this analysis is to get an idea of the overall contributions by each individual. The analysis is invoked with the -a author-churn option. The result will be given as CSV:

         author,        added, deleted
         Adam Tornhill, 13826,    1670
         Some One Else,   123,      80
         Mr Petersen,       3,       3
         ...

And, of course, you wouldn't use this data for any performance evaluation; it wouldn't serve well (in case anything should be rewarded it would be a net deletion of code - there's too much of it in the world).

Churn by entity

The pre-release churn of a module is a good predictor of its number of post-release defects. Such an analysis is supported in Code Maat by the -a entity-churn option.

Note: Some research suggests that relative churn measures are better, while others don't find any significant differences. The metrics calculated by Code Maat are absolute for now because it's easier to calculate. I'm likely to include support for relative churn too.

Ownership patterns

Once we have mined the organizational metrics described above, we may find we have multiple developers working on the same modules. How is their effort distributed? Does a particular module have a major developer or is everyone contributing a small piece? Let's find out by running the -a entity-ownership analysis. This analysis gives us the following output:

         entity,               author,  added, deleted
         analysis/authors.clj,    apt,    164,      98
         analysis/authors.clj,    qew,     81,      10
         analysis/authors.clj,     jt,     42,      32
         analysis/entities.clj,   apt,     72,      24
         ...

Another ownership view is to consider the effort spent by individual authors on the different entities in the system. This analysis is run by the -a entity-effort option. The analysis gives us the following table:

         entity,                author, author-revs, total-revs
         analysis/authors.clj,     apt,           5,         10
         analysis/authors.clj,     qew,           3,         10
         analysis/authors.clj,      jt,           1,         10
         analysis/authors.clj,     apt,           1,         10
         ...

This information may be a useful guide to find the right author to discuss functionality and potential refactorings with. Just note that the ownership metrics are sensitive to the same biases as the churn metrics; they're both heuristics and no absolute truths.

Temporal periods

Sometimes we'd like to find patterns that manifests themselves over multiple commits. Code Maat provides the --temporal-period switch that let you consider all commits within a day as a logical change. Just provide the switch and add a digit - in the future that digit may even mean something; Right now the aggregation is limited to commits within a single day.

Architectural level analyses

Using the -g flag lets you specify a mapping from individual files to logical components. This feature makes it possible to scale the analyses to an architectural level and get hotspots, knowledge metrics, etc. on the level of sub-systems.

There are some sample mapping files in the end_to_end test folder, for example this one

The format is regex_pattern => logical_group_name:

src/Features/Core      => Core
^src\/.*\/.*Tests\.cs$ => CS Tests

Code Maat takes everything that matches a regex and analyses it as a holistic whole by aggregating all file contributions for the matches.

Intermediate results

Code Maat supports an identity analysis. By using this switch, Code Maat will output the intermediate parse result of the raw VCS file. This can be useful either as a debug aid or as input to other tools.

JVM options

Code Maat uses the Incanter library. By default, Incanter will create an awt frame. You can suppress the frame by providing the following option to your java command: -Djava.awt.headless=true. Code Maat is quite memory hungry, particularly when working with larger change sets. Thus, I recommend specifying a larger heap size than the JVM defaults: -Xmx4g. Note that when running Code Maat through leiningen, those options are already configured in the project.clj file.

Limitations

The current version of Code Maat processes all its content in memory. Thus, it may not scale to large input files (however, it depends a lot on the combination of parser and analysis). The recommendation is to limit the input by specifying a sensible start date (as discussed initially, you want to do that anyway to avoid confounds in the analysis).

Future directions

In future versions of Code Maat I plan to add more analysis methods such as code churn and developer patterns. I also plan on direct visualization support and a database backed analysis to allow processing of larger log files. Further, I plan to add a worked example. That example will be a case study of some well-known open source code. Until then, I hope you find Code Maat useful in its initial shape.

code-maat's People

Contributors

adamtornhill avatar andreacrotti avatar dotemacs avatar figaw avatar hilbrand avatar janisz avatar jstepien avatar katrinleinweber avatar knorrium avatar laenas avatar logicalchaos avatar matthiasn avatar meraioth avatar o7g8 avatar oflisback avatar seriema avatar smontanari avatar tjchambers avatar wonderbird avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

code-maat's Issues

Error running tests

Hi guys, I'm trying to run the tests for this project and I'm getting a very cryptic error.

I'm using these Java 1.8 and these other libraries, any idea about what is it?

; CIDER 0.10.0snapshot (package: 20150629.637) (Java 1.8.0_45, Clojure 1.6.0, nREPL 0.2.7)

$ lein test
java.lang.RuntimeException: EOF while reading
 at clojure.lang.Util.runtimeException (Util.java:221)
    clojure.lang.LispReader.readDelimitedList (LispReader.java:1127)
    clojure.lang.LispReader$ListReader.invoke (LispReader.java:972)
    clojure.lang.LispReader.read (LispReader.java:183)
    clojure.core$read.invoke (core.clj:3477)
    clojure.core$read.invoke (core.clj:3475)
    bultitude.core$read_ns_form$fn__525.invoke (core.clj:28)
    bultitude.core$read_ns_form.invoke (core.clj:28)
    bultitude.core$ns_form_for_file.invoke (core.clj:42)
    bultitude.core$namespace_forms_in_dir$iter__531__535$fn__536.invoke (core.clj:56)
    clojure.lang.LazySeq.sval (LazySeq.java:40)
    clojure.lang.LazySeq.seq (LazySeq.java:49)
    clojure.lang.RT.seq (RT.java:484)
    clojure.core$seq.invoke (core.clj:133)
    clojure.core$map$fn__4245.invoke (core.clj:2551)
    clojure.lang.LazySeq.sval (LazySeq.java:40)
    clojure.lang.LazySeq.seq (LazySeq.java:49)
    clojure.lang.Cons.next (Cons.java:39)
    clojure.lang.RT.length (RT.java:1646)
    clojure.lang.RT.seqToArray (RT.java:1587)
    clojure.lang.LazySeq.toArray (LazySeq.java:126)
    clojure.lang.RT.toArray (RT.java:1565)
    clojure.core$to_array.invoke (core.clj:333)
    clojure.core$sort.invoke (core.clj:2828)
    clojure.core$sort.invoke (core.clj:2825)
    leiningen.test$read_args.invoke (test.clj:146)
    leiningen.test$test.doInvoke (test.clj:192)
    clojure.lang.RestFn.invoke (RestFn.java:410)
    clojure.lang.Var.invoke (Var.java:379)
    clojure.lang.AFn.applyToHelper (AFn.java:154)
    clojure.lang.Var.applyTo (Var.java:700)
    clojure.core$apply.invoke (core.clj:626)
    leiningen.core.main$partial_task$fn__6094.doInvoke (main.clj:263)
    clojure.lang.RestFn.invoke (RestFn.java:410)
    clojure.lang.AFn.applyToHelper (AFn.java:154)
    clojure.lang.RestFn.applyTo (RestFn.java:132)
    clojure.lang.AFunction$1.doInvoke (AFunction.java:29)
    clojure.lang.RestFn.applyTo (RestFn.java:137)
    clojure.core$apply.invoke (core.clj:626)
    leiningen.core.main$apply_task.invoke (main.clj:313)
    leiningen.core.main$resolve_and_apply.invoke (main.clj:319)
    clojure.lang.AFn.applyToHelper (AFn.java:156)
    clojure.lang.AFn.applyTo (AFn.java:144)
    clojure.core$apply.invoke (core.clj:624)
    leiningen.githooks$auto_install.doInvoke (githooks.clj:144)
    clojure.lang.RestFn.invoke (RestFn.java:439)
    clojure.lang.Var.invoke (Var.java:388)
    clojure.lang.AFn.applyToHelper (AFn.java:160)
    clojure.lang.Var.applyTo (Var.java:700)
    clojure.core$apply.invoke (core.clj:626)
    robert.hooke$compose_hooks$fn__11735.doInvoke (hooke.clj:40)
    clojure.lang.RestFn.applyTo (RestFn.java:137)
    clojure.core$apply.invoke (core.clj:624)
    robert.hooke$run_hooks.invoke (hooke.clj:46)
    robert.hooke$prepare_for_hooks$fn__11740$fn__11741.doInvoke (hooke.clj:54)
    clojure.lang.RestFn.applyTo (RestFn.java:137)
    clojure.lang.AFunction$1.doInvoke (AFunction.java:29)
    clojure.lang.RestFn.invoke (RestFn.java:421)
    leiningen.core.main$_main$fn__6160.invoke (main.clj:392)
    leiningen.core.main$_main.doInvoke (main.clj:385)
    clojure.lang.RestFn.invoke (RestFn.java:408)
    clojure.lang.Var.invoke (Var.java:379)
    clojure.lang.AFn.applyToHelper (AFn.java:154)
    clojure.lang.Var.applyTo (Var.java:700)
    clojure.core$apply.invoke (core.clj:624)
    clojure.main$main_opt.invoke (main.clj:315)
    clojure.main$main.doInvoke (main.clj:420)
    clojure.lang.RestFn.invoke (RestFn.java:436)
    clojure.lang.Var.invoke (Var.java:388)
    clojure.lang.AFn.applyToHelper (AFn.java:160)
    clojure.lang.Var.applyTo (Var.java:700)
    clojure.main.main (main.java:37)

Can't locate code_maat/cmd_line__init.class - where to place the folder?

Hello,

I'm completly new to maat, and I'm having problems with the setup process.

I've made the lein script to a shell file and put it in my bin folder as I usually do. I've also put the project.clj in the same folder.
When I run the code I get the following error:
Madss-MacBook-Pro:bin madsgadehenrichsen$ ./lein run -l desktop/betaflight/log2.log -c Compiling code-maat.cmd-line Could not locate code_maat/cmd_line__init.class or code_maat/cmd_line.clj on classpath. Please check that namespaces with dashes use underscores in the Clojure file name. Exception in thread "main" java.io.FileNotFoundException: Could not locate code_maat/cmd_line__init.class or code_maat/cmd_line.clj on classpath. Please check that namespaces with dashes use underscores in the Clojure file name., compiling:(/private/var/folders/_g/67_46n712vxchn3rc17cch2m0000gn/T/form-init5180465450996050829.clj:1:125) at clojure.lang.Compiler.load(Compiler.java:7391) at clojure.lang.Compiler.loadFile(Compiler.java:7317) at clojure.main$load_script.invokeStatic(main.clj:275) at clojure.main$init_opt.invokeStatic(main.clj:277) at clojure.main$init_opt.invoke(main.clj:277) at clojure.main$initialize.invokeStatic(main.clj:308) at clojure.main$null_opt.invokeStatic(main.clj:342) at clojure.main$null_opt.invoke(main.clj:339) at clojure.main$main.invokeStatic(main.clj:421) at clojure.main$main.doInvoke(main.clj:384) at clojure.lang.RestFn.invoke(RestFn.java:421) at clojure.lang.Var.invoke(Var.java:383) at clojure.lang.AFn.applyToHelper(AFn.java:156) at clojure.lang.Var.applyTo(Var.java:700) at clojure.main.main(main.java:37) Caused by: java.io.FileNotFoundException: Could not locate code_maat/cmd_line__init.class or code_maat/cmd_line.clj on classpath. Please check that namespaces with dashes use underscores in the Clojure file name. at clojure.lang.RT.load(RT.java:456) at clojure.lang.RT.load(RT.java:419) at clojure.core$load$fn__5677.invoke(core.clj:5893) at clojure.core$load.invokeStatic(core.clj:5892) at clojure.core$load.doInvoke(core.clj:5876) at clojure.lang.RestFn.invoke(RestFn.java:408) at clojure.core$load_one.invokeStatic(core.clj:5697) at clojure.core$compile$fn__5682.invoke(core.clj:5903) at clojure.core$compile.invokeStatic(core.clj:5903) at clojure.core$compile.invoke(core.clj:5895) at user$eval20$fn__29.invoke(form-init5180465450996050829.clj:1) at user$eval20.invokeStatic(form-init5180465450996050829.clj:1) at user$eval20.invoke(form-init5180465450996050829.clj:1) at clojure.lang.Compiler.eval(Compiler.java:6927) at clojure.lang.Compiler.eval(Compiler.java:6917) at clojure.lang.Compiler.eval(Compiler.java:6917) at clojure.lang.Compiler.load(Compiler.java:7379) ... 14 more Compilation failed: Subprocess failed
Looks to me like it can't find the code_maat folder. I've tried placing it multiple places without luck. Where am I supposed to put it so the script can find it?

Thanks

Issues while running code maat

Hey adam ,
I not able to generate log file with this command
git log --all --numstat --date=short --pretty=format:'--%h--%ad--%aN' --no-renames --after=2016-10-01
I am running it in a cloned project for which numstat is getting displayed but log isn't getting generated
can you just guide me how to run code-maat for a git project
I have lein install already using package manager on ubuntu 18.04
Do i need to create a a clj file for my git project or shall i include it in a lein app.

git tags

This is just a suggestion, but might be nice to tag the git revision whenever, which makes github understand your project history a bit better and is also easier to understand what is the last release.
It can still be done even now for previous versions potentially if you're interested in doing that, thanks

How can we use code-maat with CI tools ?

How can we use code-maat with CI tools like Jenkins and codeship because code-maat is a part of code analysis. Now, the time, we need to maintain code analysis at CI time. Is possible to use with codeship of Jenkins?

Invalid argument/parse error with dates in Git commit messages

The following git log file leads to an error when invoking Code Maat (winmaat0.8.5) using maat -l evo.Sample.log -c git -a summary:

[611a2fe] User2 2016-03-11 (JIRA-789) Some text (see mails of 2016-03-11).
12  3   Project.UnitTests/Spec.cs
3   3   OtherProject.UnitTests/OtherSpec.cs

The error message is:

Invalid argument:  input: [611a2fe] User2 2016-03-11 (JIRA-789) Some text (see mails of 2016-03-11).
12      3       Project.UnitTests/Spec.cs
3       3       OtherProject.UnitTests/OtherSpec.cs
, reason: Parse error at line 1, column 73:
[611a2fe] User2 2016-03-11 (JIRA-789) Some text (see mails of 2016-03-11).
                                                                        ^
Expected:
#"\s"

This is Code Maat, a program used to collect statistics from a VCS.
[...]

Code Maat seems to interpret the date within the message as something to be parsed rather than treating it as an opaque part of the commit message.

OOM when processing really large git logs

Hi!

I tried to process a pretty large git log from a private git repo. I increased to max heap to 4GB but it still did not help. Much more heap would not go as my laptop's memory is limited.

Best Regards,
Robin

csv_as_enclosure_json.py is not calculating weight

I am running the python script csv_as_enclosure_json.py and the json is always generated with 0 in the weight attribute.

In debug mode the function normalized_weight_for is not executing "if module_name in normalized_weights:"

These are my files

countlines-domina04012018.txt
revisions-domina04012018.txt

And this is the way i execute the script

python csv_as_enclosure_json.py
--structure "countlines-domina04012018.csv" --weights "revisions-domina04012018.csv" - weightcolumn 2 > jsond3Domina.json

Unable to justify results

Hi,

First of all, thanks for creating this tool and putting in the effort and research to help bring some insight into analysing technical debts.

I'm trying to use code-maat to understand our codebases and i'm seeing very weird results which making me question whether I should use the results of this tool at all.

I ran this tool on a large codebase within my company and the results seem conflicting:

git log --all --numstat --date=short --pretty=format:'--%h--%ad--%aN' --no-renames --after=2019-03-01 -- . ":(exclude).staging/" ":(exclude).tmp_staging/" ":(exclude)tests/" ":(exclude)k8s/" ":(exclude)node_modules/" > logfile.log

Main Dev

Command:

docker run -v ~/Work/code-analysis/:/data -it code-maat-app -l /data/logfile.log -c git2 -a main-dev > main-dev.csv

Tagged over 2000 files to a single dev - with added=0, total-added=0 and ownsership=0. This means that no changes were made to these files? This dev has made no changes to the files at all. Verified this by looking at Github history.

Main Dev By Rev

Command:

docker run -v ~/Work/code-analysis/:/data -it code-maat-app -l /data/logfile.log -c git2 -a main-dev-by-revs > main-dev-by-revs.csv

Tagged over 2000 files to a single dev - This dev has made no changes to the files at all. Verified this by looking at Github history

Age

Command:

docker run -v ~/Work/code-analysis/:/data -it code-maat-app -l /data/logfile.log -c git2 -a age > age.csv

Result - Off the 5k files analysed, 4.7k files have been modified in the last 2 month. This is conflicting with the results under Main Dev. Also, I checked file history, some files tagged with age as 2 months has not been modified since 2018.

Is this because it looks at entire git history of all branches vs only master? How do I make it run against only master?

File formats under Windows

I am running the Docker Container version of Code Maat and can see it is trying to work but it seems unable to cope with the Git log I have generated using the command you suggest in the documentation. I have tried saving it in various different encodings to see if that fixed the issue but it doesn't. Any other ideas on what might be going wrong?

I am running Docker for Windows for clarity.

codemaat2.log

Is it a valid logfile?

Hi Adam

This is right at the edge of my technical envelope! =) Anyway, have a log file and am also pretty sure it's UTF-8 encoded. At least that's what it says when I open it in Notepad++ and Atom.

What other issues could be causing this error text?

Invalid argument: git2: Failed to parse the given file - is it a valid logfile?

Actually took the test simple_git2.txt file and tried to run it through this and it failed with the same error so I'm guessing this could be a case of user (has no clue) error 👍

Also - since I know NOTHING about clojure - is this warning relevant at all??
WARNING: update already refers to: #'clojure.core/update in namespace: incanter.core, being replaced by: #'incanter.core/update

Thanks!!

Parsing error

I am analyzing wikimedia/mediawiki with code-maat.

I seem to be getting parsing errors for the commit messages:

java -Xmx512M -Xms64M -jar \winmaat0.8.5\code-maat-0.8.5-standalone.jar -l ../mediawiki/maat_evo.log -c git -a summary
Invalid argument: input: [ebbf38d2ab] Antoine Musso 2010-10-29 Follow up r75682 : fix private function naming. Fix cruise control build 2010-10-29T22:18:27
3 3 maintenance/tests/phpunit/includes/UserIsValidEmailAddrTest.php
, reason: Parse error at line 1, column 122:
[ebbf38d2ab] Antoine Musso 2010-10-29 Follow up r75682 : fix private function naming. Fix cruise control build 2010-10-29T22:18:27

When I manually fix this comment, I run into the next parsing error:

java -Xmx512M -Xms64M -jar \winmaat0.8.5\code-maat-0.8.5-standalone.jar -l ../mediawiki/maat_evo.log -c git -a summary
Invalid argument: input: [c7723263fc] Niklas Laxstr▒m 2010-08-08 Removed $wgUseZhdaemon, $wgZhdaemonHost and $wgZhdaemonPort. Apparently unused since r6878 at 2004-12-29.

It would be nice if code-maat would be more robust in parsing comments.

Remove layer_mapper.clj?

I noticed that the two files are essentially the same, grouper.clj and layer_mapper.clj. So we should delete layer_mapper.clj (since the ns is grouper)

>diff code_maat/app/grouper.clj code_maat/app/layer_mapper.clj 
24c24
<     path      = #'^[\\w/\\\\\\.\\-]+'

---
>     path      = #'^[\\w/\\\\]+'

Thanks,
Rui

Please publish docker image

Hi,

On Docker Hub there is a code-maat image: https://hub.docker.com/r/stevenalexander/code-maat-python/

However that also contains Python and cloc. I could add my own bare image, but maybe it would be handier to do so under an adamtornhill account?

I'd suggest publishing every image version under three tags: a version tag, a major version tag, and 'latest', e.g.

adamtornhill/code-maat:1.0.2
adamtornhill/code-maat:1
adamtornhill/code-maat:latest

That way, people can choose to depend on a specific version, a major version, or to use the latest tag.

Website down

http://www.adamtornhill.com/code/codemaat.htm seems to be down currently

Accept regexp in group layer definitions

When using code-maat on recent javascript (React) code bases unfortunately it's not possible to distinguish production code from test code, as the convention for React seems to be putting test files next to production files in the same folder. If I wanted to separate the production code from the test code in my code-maat analysis using the --group options I would liked to be able to write a file using regexp expressions to split the layer assignment, e.g.

app/frontend/.*/[^--]+\.js => Code
app/frontend/.*--test\.js => Unit tests

Extension and Support

Hi @adamtornhill ,

I loved this tool and learning to understand more to use code-maat in my work environment. I want to know still what new features are you going to add up and how support will be delivered if i looking it to deploy it in my working place.

P4 log parser error

I created a Perforce log file using the command given in the documentation.
It looks like the code-maat parser can't handle some lines I have, starting with 'Jobs fixed'.
The error from the parser says that it expected 'Affected' at that position.
Below is the log file content.

Change 401723 by ejbo@ejbo-home-fimbul on 2015/03/19 12:40:33
FIM-29 ##scription here>
Jobs fixed ...
FIM-29 on 2015/03/19 by ejbo closed
Fimbul unit test suite
Affected files ...
... //depot/fiks/fimbul/unittest/gmock-1.6.0/gtest/samples/test_fimbul_klip.cc#31 edit

Change 401722 by ejbo@ejbo-home-fimbul on 2015/03/19 10:21:54
FIM-175 proxy ##on here>
Jobs fixed ...
FIM-40 on 2015/03/19 by ejbo closed
Fjern hardkodet dato 01.01.2020 i army.cxx
Affected files ...
... //depot/fiks/fimbul/klip_syg.cxx#93 edit
... //depot/fiks/fimbul/klip_syg.hxx#16 edit

Can I get the record of code change by code-maat?

Hi,
Here is an engineer from Huawei Technologies Co.,Ltd.. We are working on a topic How to get the record of code change by VCS?
We want to know which lines of code were changed by who and at when through analyzing the log of VCS by some tools. Code-maat seems to be what we are looking for.

Getting "NoClassDefFound" error

Using: Java 8, Leiningen 2.9.2

When I try to run the following command

java -jar C:\code-maat\target\code-maat-1.1-SNAPSHOT.jar -l logfile.log -c git

I get the following error message:

Exception in thread "main" java.lang.NoClassDefFoundError: clojure/lang/Var
at code_maat.cmd_line.(Unknown Source)
Caused by: java.lang.ClassNotFoundException: clojure.lang.Var
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 1 more

I still get the error message above after running the following command:

java -jar C:\code-maat\target\code-maat-1.1-SNAPSHOT.jar -cp .;C:\Users\Owner\Documents\WindowsPowerShell\Modules\ClojureTools\clojure-tools-1.10.1.561.jar -l logfile.log -c git

Simpler invocation

I think it would be great to avoid the need to manually generate the logs and then feed it into code-maat after..

After all the command that needs to be run is known and to find out what kind of repository is we just need to check for .git/.hg/.svn in the directory right?

I can probably give it a try and add something like "--auto $path" or "--repository-path $path" option that does the detection and parsing, what do you think?

java.lang.OutOfMemoryError: Java heap space

I'm following along and tried to run the analysis tool on some logs generated from a ~3 year old project. there are about 81K lines in the file i'm trying to analyze -- here's the command and output:

$ ~/opt/ixmaat0.8.2/maat -l ignore_me/commit_log.txt -c git -a summary
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at clojure.lang.PersistentHashMap$ArrayNode.assoc(PersistentHashMap.java:368)
    at clojure.lang.PersistentHashMap$ArrayNode.assoc(PersistentHashMap.java:365)
    at clojure.lang.PersistentHashMap.assoc(PersistentHashMap.java:142)
    at clojure.lang.PersistentHashMap.assoc(PersistentHashMap.java:28)
    at clojure.lang.RT.assoc(RT.java:702)
    at clojure.core$assoc.invoke(core.clj:187)
    at clojure.lang.Atom.swap(Atom.java:65)
    at clojure.core$swap_BANG_.invoke(core.clj:2234)
    at instaparse.gll$node_get.invoke(gll.clj:221)
    at instaparse.gll$push_listener.invoke(gll.clj:267)
    at instaparse.gll$CatListener$fn__672.invoke(gll.clj:397)
    at instaparse.gll$push_message$f__602.invoke(gll.clj:173)
    at instaparse.gll$step.invoke(gll.clj:328)
    at instaparse.gll$run.invoke(gll.clj:344)
    at instaparse.gll$run.invoke(gll.clj:332)
    at instaparse.gll$parse.invoke(gll.clj:758)
    at instaparse.core$parse.doInvoke(core.clj:83)
    at clojure.lang.RestFn.invoke(RestFn.java:425)
    at code_maat.parsers.hiccup_based_parser$as_grammar_map.invoke(hiccup_based_parser.clj:23)
    at code_maat.parsers.hiccup_based_parser$parse_log.invoke(hiccup_based_parser.clj:90)
    at code_maat.parsers.git$parse_log.invoke(git.clj:62)
    at code_maat.app.app$git__GT_modifications$fn__8177.invoke(app.clj:111)
    at code_maat.app.app$run_parser_in_error_handling_context.invoke(app.clj:80)
    at code_maat.app.app$git__GT_modifications.invoke(app.clj:109)
    at code_maat.app.app$parse_commits_to_dataset.invoke(app.clj:168)
    at code_maat.app.app$run.invoke(app.clj:181)
    at code_maat.cmd_line$_main.doInvoke(cmd_line.clj:63)
    at clojure.lang.RestFn.applyTo(RestFn.java:137)
    at code_maat.cmd_line.main(Unknown Source)

Invalid argument: git2: Failed to parse the given file - is it a valid logfile? error when running with docker

Im getting the following error when running this with the docker container:

Invalid argument: git2: Failed to parse the given file - is it a valid logfile?

I built the container with the command below from the latest code on 9th august:

docker build -t code-maat-app .

I then ran

git log --all --numstat --date=short --pretty=format:'--%h--%ad--%aN' --no-renames --after=2018-10-31 > logfile.log

and after that:

docker run -v /PATH-TO-CODEBASE:/data -it code-maat-app -l logfile.log -c git2

my logfile looks just like the ones in your tests folder :/

NumberFormatException when trying to run Maat

Hi,

Thanks a lot for creating this awesome project. I'm trying it for our projects:

git log --all -M -C --numstat --date=short --pretty=format:'--%h--%ad--%an' --no-renames > log.log

java -jar target/code-maat-0.9.2-SNAPSHOT-standalone.jar -l log.log -c git -s summary

WARNING: update already refers to: #'clojure.core/update in namespace: incanter.core, being replaced by: #'incanter.core/update
The following errors occurred while parsing your command:
Error while parsing option "-s summary": java.lang.NumberFormatException: For input string: "summary"

Am I doing something wrong?

Btw, your presentation in EuroClojure was the best!

Thanks a lot.

Code maat is not parsing date in TFS log

I am trying to execute code maat in TFS but i get the following error:

Invalid argument: Unsupported TFS Date Format: Thursday, December 21, 2017 9:26:46 AM
This is Code Maat, a program used to collect statistics from a VCS.
Version: 1.0-SNAPSHOT

This is the command i am using

java -jar code-maat.jar -l "C:\TFS\Loc\Dev\Satrack.Loc.Core\Domain\tfslog.csv" -c tfs -a revisions

And this is the tfs log i am using.

tfslog.txt

I checked and the date is in the locale that you recommend.

Thanks!

Code maat extensions

Hi adamtornhill
Wanted to know whether all scenarios of code-forensics are covered here like sloc,churn etc if not what are to be covered and when are you going to extend it.How many languages it supports currently
and how to extend it for other languages.Wanted to know how to extend in terms of code.

running git log on windows needs double quotes not single ones

git log --all --numstat --date=short --pretty=format:"--%h--%ad--%aN" --no-renames

produces a file
`
-aa208775--2017-10-26--araut
2 0 src/main/java/com/xxx/yyy/repository/z1.java
23 0 src/main/java/com/xxx/yy/rest/z2.java
30 0 src/main/java/com/xxx/yy/service/z3.java
47 0 src/main/resources/swagger.yml
37 0 src/test/java/com/xxx/yy/rest/z4.java

--c1ffc53b--2017-10-26--Prasad xxx
`
while with single quotes
git log --all --numstat --date=short --pretty=format:'--%h--%ad--%aN' --no-renames
produces

'--aa208775--2017-10-26--araut' 2 0 src/main/java/com/xxx/yyy/repository/z1.java 23 0 src/main/java/com/xxx/yy/rest/z2.java 30 0 src/main/java/com/xxx/yy/service/z3.java 47 0 src/main/resources/swagger.yml 37 0 src/test/java/com/xxx/yy/rest/z4.java '--c1ffc53b--2017-10-26--Prasad xxx'

(note the quotes around the author/date bit)..
the parser will not parse the 2nd option sadly.

No definition for fragmentation analysis

I found about it by accident (in an error message). I tried to infer what it does from the code but it would be nicer to have an example and proper documentation.

Churn gives wrong output

What does the "commits" column on the churn output represent? If it is meant to represent the total number of commits for the file, then it's reporting incorrectly.

exclusion patterns

I just started playing with code-maat, and I find I do something like this:
lein.bat run -l logfile.log -c git | grep -v pom.xml | grep -v test | head
It would be really nice to be able to specify these exclusions on the command-line of code-maat instead piping to commands

Logical Coupling - Mining

Hello,

I've been using the code-maat tool to mine features from a git repository, especially the logic coupling. What I'm facing is the scenario that I want to mine the coupling changes over a time. So what I'm wondering is if it's possible to get all couplings by just running on the latest revision? Or do I need to do as I'm doing now and run the tool on each revision and then track the coupling changes myself?

Best regards,

Oscar

code maat Parse error at line 1 on code maat sources

Hi, I did git clone for code maat then:

code-maat$ git log --all --numstat --date=short --pretty=format:'--%h--%ad--%aN' --no-renames > git.log
java -jar target/code-maat-1.0-SNAPSHOT-standalone.jar -l git.log -c git

and result:

Invalid argument:  java.lang.IllegalArgumentException: input: --788a0f3--2016-07-19--Adam Tornhill
1	1	README.md
, reason: Parse error at line 1, column 1:
--788a0f3--2016-07-19--Adam Tornhill
^
Expected:
[

This is Code Maat, a program used to collect statistics from a VCS.
Version: 1.0-SNAPSHOT

can you help please?

Grouping causes incorrect CSV output

Hi,

I am following the code samples from the book and the grouping commands output incorrect text.

For example:

  1. maat -l maat_evo.log -c git -a coupling -g maat_src_test_boundaries.txt
    entity,coupled,degree,average-revs
    ",80,65est
  2. maat -l maat_evo.log -c git -a coupling -g maat_src_detailed_test_boundaries.txt
    entity,coupled,degree,average-revs
    ",42,50to end Tests
    ",42,49is Test
    ",Parsers Test,41,49

I have tried both the latest version and 0.8.5 and I get the same results. I am running on Windows 8.

Thanks!

Cannot work with newlines with latest parsing update

I forked to implement a Perforce parser. I have it completed, but when I went to merge with your latest which splits the parsing into chunks, I'm unable to get it functioning again. I've found if I remove all newlines except those between change sets, I can get it parsing again. But, that involves quite a bit of data massaging to clean up the perforce log. Do you have any suggestions? If you look on my perforce branch, you can see my grammar.

Error when running java

Hi, I am not well versed in java so bear with me. When I run this code from my repo directory, I get an error.

java -jar code-maat-0.5.1.jar -l logfile.log -c <vcs>
zsh: parse error near `\n'

Again, I am running this inside of my repository directory which I have a feeling I am doing wrong. Please let me know what it is that I need to do so that this will work. Thank you.

Cannot compute churn metrics for SVN XML logs

Using the SVN log format mentioned in the README file for code-maat:

svn log -v --xml > logfile.log -r {YYYYmmDD}:HEAD

I have encountered the following error:

$ maat -l ~/workspace/project/logfile.log -c svn -a abs-churn
java.lang.IllegalArgumentException: Internal error - please report it. Details = churn analysis: the given VCS data doesn't contain modification metrics. Check the code-maat docs for supported VCS and correct log format.
    at code_maat.app.app$throw_internal_error.invoke(app.clj:158)
    at code_maat.app.app$run_with_recovery_point.invoke(app.clj:167)
    at code_maat.app.app$run.invoke(app.clj:188)
    at code_maat.cmd_line$_main.doInvoke(cmd_line.clj:63)
    at clojure.lang.RestFn.applyTo(RestFn.java:137)
    at code_maat.cmd_line.main(Unknown Source)
Error:  Internal error - please report it. Details = churn analysis: the given VCS data doesn't contain modification metrics. Check the code-maat docs for supported VCS and correct log format.

This issue arises from the choice of using SVN's XML log format, which does not support reporting the diffs. The text format supports diffs but may be harder to parse.

git2 log command

From the readme:

Generate a git log file using the following command:

git log --pretty=format:'[%h] %aN %ad %s' --date=short --numstat --after=YYYY-MM-DD

Note that there's a second supported Git format as well, imaginatively named git2. This format is more tolerant and faster to parse, so please prefer it over the plain git format described above:

git log --all -M -C --numstat --date=short --pretty=format:'--%h--%ad--%an' --no-renames

The second instruction uses --pretty=format:'--%h--%ad--%an', which results in this error:

$ java -jar code-maat-0.9.2-SNAPSHOT-standalone.jar -l test.log -c git -a entity-effort -o entity-test.csv
WARNING: update already refers to: #'clojure.core/update in namespace: incanter.core, being replaced by: #'incanter.core/update
Invalid argument:  java.lang.IllegalArgumentException: input: --afefec5--2015-11-07--JP Johansson
5       3       filename1.js
60      0       filename2.js
55      81      filename3.js
126     158     filename.css
, reason: Parse error at line 1, column 1:
--afefec5--2015-11-07--JP Johansson
^
Expected:
[

This is Code Maat, a program used to collect statistics from a VCS.
Version: 0.9.2-SNAPSHOT

It happens with all -a flags to code-maat. I changed it to use the --pretty=format:'[%h] %aN %ad %s' from the first instruction and it works, but then the readme text about a "second supported Git format" is a bit confusing.

I also didn't quite understand the other flags in the second instruction, especially the last parameter --no-renames which seems to contradict -M -C? That's how I read it on ExplainShell.

Unable to build code-maat under OSX

When I try to build code-maatwith lein uberjar under OSX 10.11, the compilation fails:

[525]08:51:[email protected]:code-maat$ lein uberjar
Compiling code-maat.cmd-line
java.lang.UnsupportedClassVersionError: incanter/Matrix : Unsupported major.minor version 52.0, compiling:(incanter/core.clj:2277:1)
Exception in thread "main" java.lang.UnsupportedClassVersionError: incanter/Matrix : Unsupported major.minor version 52.0, compiling:(incanter/core.clj:2277:1)
        at clojure.lang.Compiler.analyze(Compiler.java:6688)
        at clojure.lang.Compiler.analyze(Compiler.java:6625)
        at clojure.lang.Compiler$HostExpr$Parser.parse(Compiler.java:1009)
        at clojure.lang.Compiler.analyzeSeq(Compiler.java:6868)
        at clojure.lang.Compiler.analyze(Compiler.java:6669)
        at clojure.lang.Compiler.analyze(Compiler.java:6625)
        at clojure.lang.Compiler.compile1(Compiler.java:7469)
        at clojure.lang.Compiler.compile(Compiler.java:7541)
        at clojure.lang.RT.compile(RT.java:406)
        at clojure.lang.RT.load(RT.java:451)
        at clojure.lang.RT.load(RT.java:419)
        at clojure.core$load$fn__5677.invoke(core.clj:5893)
        at clojure.core$load.invokeStatic(core.clj:5892)
        at clojure.core$load.doInvoke(core.clj:5876)
        at clojure.lang.RestFn.invoke(RestFn.java:408)
        at clojure.core$load_one.invokeStatic(core.clj:5697)
        at clojure.core$load_one.invoke(core.clj:5692)
        at clojure.core$load_lib$fn__5626.invoke(core.clj:5737)
        at clojure.core$load_lib.invokeStatic(core.clj:5736)
        at clojure.core$load_lib.doInvoke(core.clj:5717)
        at clojure.lang.RestFn.applyTo(RestFn.java:142)
        at clojure.core$apply.invokeStatic(core.clj:648)
        at clojure.core$load_libs.invokeStatic(core.clj:5774)
        at clojure.core$load_libs.doInvoke(core.clj:5758)
        at clojure.lang.RestFn.applyTo(RestFn.java:137)
        at clojure.core$apply.invokeStatic(core.clj:648)
        at clojure.core$require.invokeStatic(core.clj:5796)
        at clojure.core$require.doInvoke(core.clj:5796)
        at clojure.lang.RestFn.invoke(RestFn.java:436)
        at code_maat.cmd_line$loading__5569__auto____36.invoke(cmd_line.clj:6)
        at clojure.lang.AFn.applyToHelper(AFn.java:152)
        at clojure.lang.AFn.applyTo(AFn.java:144)
        at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:3652)
        at clojure.lang.Compiler.compile1(Compiler.java:7474)
        at clojure.lang.Compiler.compile1(Compiler.java:7464)
        at clojure.lang.Compiler.compile(Compiler.java:7541)
        at clojure.lang.RT.compile(RT.java:406)
        at clojure.lang.RT.load(RT.java:451)
        at clojure.lang.RT.load(RT.java:419)
        at clojure.core$load$fn__5677.invoke(core.clj:5893)
        at clojure.core$load.invokeStatic(core.clj:5892)
        at clojure.core$load.doInvoke(core.clj:5876)
        at clojure.lang.RestFn.invoke(RestFn.java:408)
        at clojure.core$load_one.invokeStatic(core.clj:5697)
        at clojure.core$compile$fn__5682.invoke(core.clj:5903)
        at clojure.core$compile.invokeStatic(core.clj:5903)
        at clojure.core$compile.invoke(core.clj:5895)
        at user$eval20$fn__29.invoke(form-init3861789591659076358.clj:1)
        at user$eval20.invokeStatic(form-init3861789591659076358.clj:1)
        at user$eval20.invoke(form-init3861789591659076358.clj:1)
        at clojure.lang.Compiler.eval(Compiler.java:6927)
        at clojure.lang.Compiler.eval(Compiler.java:6917)
        at clojure.lang.Compiler.eval(Compiler.java:6917)
        at clojure.lang.Compiler.load(Compiler.java:7379)
        at clojure.lang.Compiler.loadFile(Compiler.java:7317)
        at clojure.main$load_script.invokeStatic(main.clj:275)
        at clojure.main$init_opt.invokeStatic(main.clj:277)
        at clojure.main$init_opt.invoke(main.clj:277)
        at clojure.main$initialize.invokeStatic(main.clj:308)
        at clojure.main$null_opt.invokeStatic(main.clj:342)
        at clojure.main$null_opt.invoke(main.clj:339)
        at clojure.main$main.invokeStatic(main.clj:421)
        at clojure.main$main.doInvoke(main.clj:384)
        at clojure.lang.RestFn.invoke(RestFn.java:421)
        at clojure.lang.Var.invoke(Var.java:383)
        at clojure.lang.AFn.applyToHelper(AFn.java:156)
        at clojure.lang.Var.applyTo(Var.java:700)
        at clojure.main.main(main.java:37)
Caused by: java.lang.UnsupportedClassVersionError: incanter/Matrix : Unsupported major.minor version 52.0
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:792)
        at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
        at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
        at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:411)
        at clojure.lang.DynamicClassLoader.loadClass(DynamicClassLoader.java:77)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:411)
        at clojure.lang.DynamicClassLoader.loadClass(DynamicClassLoader.java:77)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:411)
        at clojure.lang.DynamicClassLoader.loadClass(DynamicClassLoader.java:77)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:411)
        at clojure.lang.DynamicClassLoader.loadClass(DynamicClassLoader.java:77)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:411)
        at clojure.lang.DynamicClassLoader.loadClass(DynamicClassLoader.java:77)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:411)
        at clojure.lang.DynamicClassLoader.loadClass(DynamicClassLoader.java:77)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:411)
        at clojure.lang.DynamicClassLoader.loadClass(DynamicClassLoader.java:77)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:411)
        at clojure.lang.DynamicClassLoader.loadClass(DynamicClassLoader.java:77)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:411)
        at clojure.lang.DynamicClassLoader.loadClass(DynamicClassLoader.java:77)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:270)
        at clojure.lang.RT.classForName(RT.java:2168)
        at clojure.lang.RT.classForName(RT.java:2177)
        at clojure.lang.Compiler.resolveIn(Compiler.java:7145)
        at clojure.lang.Compiler.resolve(Compiler.java:7108)
        at clojure.lang.Compiler.analyzeSymbol(Compiler.java:7069)
        at clojure.lang.Compiler.analyze(Compiler.java:6648)
        ... 95 more
Compilation failed: Subprocess failed

Here is my Java version:

[527]09:01:[email protected]:code-maat$ java -version
java version "1.7.0_25"
Java(TM) SE Runtime Environment (build 1.7.0_25-b15)
Java HotSpot(TM) 64-Bit Server VM (build 23.25-b01, mixed mode)

Error on messages analysis regular expression

I am trying to use the new "messages" analysis but it doesn't seem to like the regular expression I am passing to it.
According to other tools it is a valid regex. Maybe Clojure uses a different syntax?
I tried to find an example under the test directory but couldn't find any.

java -jar C:\Dropbox\bin\code-maat-0.9.0-SNAPSHOT-standalone.jar -l C:\temp\d4vanrx.txt -c git -a messages -e "(S[0-9]{,7})|([)]|([A-Z]{1,}-[0-9]{1,})[:]" -o C:\temp\maat_output\messages.csv
Invalid argument: Internal error - please report it. Details = Illegal repetition near index 6
(S[0-9]{,7})|([)]|([A-Z]{1,}-[0-9]{1,})[:]

lein uberjar fails to download dependencies: Socket closed

Downloaded and unpacked code-maat release 1.0.1

Installed lein with:

$ brew install leiningen

Lein version that got installed:

$ lein --version
Leiningen 2.8.3 on Java 1.8.0_202-ea Java HotSpot(TM) 64-Bit Server VM

Launched

lein uberjar

Result:

$ lein uberjar
[...]
Retrieving com/github/rwl/AMDJ/1.0.1/AMDJ-1.0.1.jar from central
Retrieving org/clojure/data.csv/0.1.2/data.csv-0.1.2.jar from central
Retrieving joda-time/joda-time/2.6/joda-time-2.6.jar from central
Retrieving org/clojure/math.numeric-tower/0.0.4/math.numeric-tower-0.0.4.jar from central
Could not transfer artifact org.clojure:math.combinatorics:jar:0.1.1 from/to central (https://repo1.maven.org/maven2/): Socket closed
Could not transfer artifact org.clojure:math.combinatorics:jar:0.1.1 from/to clojars (https://repo.clojars.org/): Socket closed
Could not transfer artifact org.clojure:clojurescript:jar:1.9.493 from/to central (https://repo1.maven.org/maven2/): Socket closed
Could not find artifact org.clojure:clojurescript:jar:1.9.493 in clojars (https://repo.clojars.org/)
Could not transfer artifact com.google.javascript:closure-compiler-unshaded:jar:v20170218 from/to central (https://repo1.maven.org/maven2/): Socket closed
Could not find artifact com.google.javascript:closure-compiler-unshaded:jar:v20170218 in clojars (https://repo.clojars.org/)
Could not transfer artifact com.google.javascript:closure-compiler-externs:jar:v20170218 from/to central (https://repo1.maven.org/maven2/): Socket closed
Could not find artifact com.google.javascript:closure-compiler-externs:jar:v20170218 in clojars (https://repo.clojars.org/)
Could not transfer artifact args4j:args4j:jar:2.33 from/to central (https://repo1.maven.org/maven2/): Socket closed
Could not find artifact args4j:args4j:jar:2.33 in clojars (https://repo.clojars.org/)
Could not transfer artifact com.google.protobuf:protobuf-java:jar:3.0.2 from/to central (https://repo1.maven.org/maven2/): Socket closed
Could not transfer artifact com.google.protobuf:protobuf-java:jar:3.0.2 from/to clojars (https://repo.clojars.org/): Socket closed
Could not transfer artifact com.google.code.findbugs:jsr305:jar:3.0.1 from/to central (https://repo1.maven.org/maven2/): Socket closed
Could not transfer artifact com.google.code.findbugs:jsr305:jar:3.0.1 from/to clojars (https://repo.clojars.org/): Socket closed
Could not transfer artifact com.google.jsinterop:jsinterop-annotations:jar:1.0.0 from/to central (https://repo1.maven.org/maven2/): Socket closed
Could not transfer artifact com.google.jsinterop:jsinterop-annotations:jar:1.0.0 from/to clojars (https://repo.clojars.org/): Socket closed
Could not transfer artifact org.clojure:google-closure-library:jar:0.0-20160609-f42b4a24 from/to central (https://repo1.maven.org/maven2/): Socket closed
Could not transfer artifact org.clojure:google-closure-library:jar:0.0-20160609-f42b4a24 from/to clojars (https://repo.clojars.org/): Socket closed
Could not transfer artifact org.clojure:google-closure-library-third-party:jar:0.0-20160609-f42b4a24 from/to central (https://repo1.maven.org/maven2/): Socket closed
Could not transfer artifact org.clojure:google-closure-library-third-party:jar:0.0-20160609-f42b4a24 from/to clojars (https://repo.clojars.org/): Socket closed
Could not transfer artifact org.clojure:data.json:jar:0.2.6 from/to central (https://repo1.maven.org/maven2/): Socket closed
Could not transfer artifact org.clojure:data.json:jar:0.2.6 from/to clojars (https://repo.clojars.org/): Socket closed
Could not transfer artifact org.mozilla:rhino:jar:1.7R5 from/to central (https://repo1.maven.org/maven2/): Socket closed
Could not transfer artifact org.mozilla:rhino:jar:1.7R5 from/to clojars (https://repo.clojars.org/): Socket closed
Could not transfer artifact org.clojure:tools.reader:jar:1.0.0-beta3 from/to central (https://repo1.maven.org/maven2/): Socket closed
Could not transfer artifact org.clojure:tools.reader:jar:1.0.0-beta3 from/to clojars (https://repo.clojars.org/): Socket closed
This could be due to a typo in :dependencies, file system permissions, or network issues.
If you are behind a proxy, try setting the 'http_proxy' environment variable.
Uberjar aborting because jar failed: Could not resolve dependencies

OS version:
MacOS Hight Sierra 10.13.6 (17G5019)

Improving IllegalArgumentException error message when passing wrong parameters

I invoked code-maat with a wrong parameter (-a couplin instead of -a coupling) and it threw the following exception:

java.lang.IllegalArgumentException: Internal error - please report it. Details = Wrong number of args (1) passed to: app/make-analysis/fn--8124
    at code_maat.app.app$throw_internal_error.invoke(app.clj:158)
    at code_maat.app.app$run_with_recovery_point.invoke(app.clj:167)
    at code_maat.app.app$run.invoke(app.clj:188)
    at code_maat.cmd_line$_main.doInvoke(cmd_line.clj:63)
    at clojure.lang.RestFn.applyTo(RestFn.java:137)
    at code_maat.cmd_line.main(Unknown Source)
Error:  Internal error - please report it. Details = Wrong number of args (1) passed to: app/make-analysis/fn--8124

It would be good to know that "couplin" is invalid and what the valid options are :)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.