# Software Quality Award, 2016

Source: https://www.yegor256.com/2015/10/17/award-2016.html

{% badge /images/andreea/quality-award.svg 300 %}

This is the second year of the
[Software Quality Award](/award.html). The prize
is still the same---**$4,096**.
The rules were changed a bit. Read on.
BTW, 2015 is [here]({% pst 2015/apr/2015-04-16-award %}).


{% youtube Z70PMGaxGhY %}

Rules:

  * One person can submit **only one** project.

  * Submissions are accepted until the **September 1, 2016**.

  * I will check the commit history to make sure you're the main contributor to the project.

  * I reserve the right to reject any submission without explanation.

  * All submissions will be published on this page (including rejected ones).

  * Results will be announced **October 15, 2016** on this page and by email.

  * The best project will receive **$4,096**.

  * Final decisions will be made by me and are not negotiable
    (although I may invite other people to help me make the right decision).

  * Winners that received any cash prizes in previous years can't submit again.

Each project must be:

  * Open source (in GitHub).

  * At least 10,000 lines of code.

  * At least one year old.

  * Object-oriented (that's the only thing I understand).

The best project is selected using this [criteria]({% pst 2015/jun/2015-06-08-deadly-sins-software-project %}).

What doesn't matter:

  * Popularity. Even if nobody is using your
    product, it is still eligible for this award. I don't care about
    popularity; quality is the key.

  * Programming language. I believe that any language, used correctly,
    can be applied to design a high-quality product.

  * Buzz and trends. Even if your project is yet another parser of command
    line arguments, it's still eligible for the award. I don't care about
    your marketing position; quality is all.

By the way, if you want to sponsor this award and increase the bonus,
[email me](mailto:me@yegor256.com).

<hr/>

60 projects submitted so far (in random order):

  * [`hackiftekhar/IQKeyboardManager`](https://github.com/hackiftekhar/IQKeyboardManager)
  * [`artem-zinnatullin/qualitymatters`](https://github.com/artem-zinnatullin/qualitymatters)
  * [`pholser/junit-quickcheck`](https://github.com/pholser/junit-quickcheck) by [`@albogdano`](https://github.com/albogdano)
  * [`codeborne/selenide`](https://github.com/codeborne/selenide) by [`@asolntsev`](https://github.com/asolntsev)
  * [`raphw/byte-buddy`](https://github.com/raphw/byte-buddy)
  * [`AdamsLair/duality`](https://github.com/AdamsLair/duality)
  * [`thothbot/parallax`](https://github.com/thothbot/parallax)
  * [`vmi/selenese-runner-java`](https://github.com/vmi/selenese-runner-java)
  * [`scd4j/gradle-plugins`](https://github.com/scd4j/gradle-plugins)
  * [`wseemann/FFmpegMediaMetadataRetriever`](https://github.com/wseemann/FFmpegMediaMetadataRetriever)
  * [`bladecoder/bladecoder-adventure-engine`](https://github.com/bladecoder/bladecoder-adventure-engine)
  * [`Flipkart/phantom`](https://github.com/Flipkart/phantom)
  * [`NullVoxPopuli/aeonvera`](https://github.com/NullVoxPopuli/aeonvera)
  * [`mangstadt/ez-vcard`](https://github.com/mangstadt/ez-vcard/)
  * `axet/desktop`
  * [`DakaraOnline/dakara-server`](https://github.com/DakaraOnline/dakara-server)
  * [`ppareit/swiftp`](https://github.com/ppareit/swiftp)
  * [`DSteve595/Put.io`](https://github.com/DSteve595/Put.io)
  * [`jaredsburrows/android-gradle-java-app-template`](https://github.com/jaredsburrows/android-gradle-java-app-template)
  * [`Belphemur/SoundSwitch`](https://github.com/Belphemur/SoundSwitch)
  * [`inklabs/kommerce-core`](https://github.com/inklabs/kommerce-core)
  * [`sniffy/sniffy`](https://github.com/sniffy/sniffy)
  * [`RobinJ1995/DistroHopper`](https://github.com/RobinJ1995/DistroHopper)
  * [`DSH105/EchoPet/tree/3.x`](https://github.com/DSH105/EchoPet/tree/3.x)
  * [`SimonKagstrom/kcov`](https://github.com/SimonKagstrom/kcov/)
  * `pedja1/SMC-Android`
  * [`HeinrichReimer/material-intro`](https://github.com/HeinrichReimer/material-intro)
  * [`skinny-framework/skinny-framework`](https://github.com/skinny-framework/skinny-framework) by [@seratch](https://github.com/seratch)
  * [`hsz/idea-gitignore`](https://github.com/hsz/idea-gitignore)
  * [`doanduyhai/Achilles`](https://github.com/doanduyhai/Achilles)
  * [`Omertron/api-themoviedb`](https://github.com/Omertron/api-themoviedb)
  * [`gerc99/SawimNE`](https://github.com/gerc99/SawimNE)
  * [`orfjackal/jumi`](https://github.com/orfjackal/jumi)
  * [`wbotelhos/raty`](https://github.com/wbotelhos/raty)
  * [`GautamGupta/Simple-Android-OCR`](https://github.com/GautamGupta/Simple-Android-OCR)
  * [`tananaev/traccar`](https://github.com/tananaev/traccar)
  * [`paypal/squbs`](https://github.com/paypal/squbs) by [`@akara`](https://github.com/akara)
  * [`clun/ff4j`](https://github.com/clun/ff4j)
  * [`datavis-tech/reactive-model`](https://github.com/datavis-tech/reactive-model)
  * [`kwhat/jnativehook`](https://github.com/kwhat/jnativehook)
  * [`javaslang/javaslang`](https://github.com/javaslang/javaslang)
  * [`lukeFalsina/Grab-n-Run`](https://github.com/lukeFalsina/Grab-n-Run)
  * [`bxbxbai/ZhuanLan`](https://github.com/bxbxbai/ZhuanLan)
  * [`apache/wicket`](https://github.com/apache/wicket)
  * [`nikolamilosevic86/owasp-seraphimdroid`](https://github.com/nikolamilosevic86/owasp-seraphimdroid)
  * [`uniVocity/univocity-parsers`](https://github.com/uniVocity/univocity-parsers)
  * [`ben-manes/caffeine`](https://github.com/ben-manes/caffeine/)
  * [`chrisvest/stormpot`](https://github.com/chrisvest/stormpot)
  * [`js-cookie/js-cookie`](https://github.com/js-cookie/js-cookie)
  * [`coala/coala`](https://github.com/coala/coala) by [`@sils`](https://github.com/sils)
  * `arzzen/altcoin-bitcoin-explorer`
  * [`allure-framework/allure-core`](https://github.com/allure-framework/allure-core)
  * [`kailash09dabhi/OmRecorder`](https://github.com/kailash09dabhi/OmRecorder)
  * [`Cyan4973/zstd`](https://github.com/Cyan4973/zstd)
  * [`pmwmedia/tinylog`](https://github.com/pmwmedia/tinylog)
  * [`yi-editor/yi`](https://github.com/yi-editor/yi) by [`@ethercrow`](https://github.com/ethercrow)
  * [`reinterpretcat/utymap`](https://github.com/)
  * [`eventstore/eventstore`](https://github.com/) by [`@gregoryyoung`](https://github.com/gregoryyoung)
  * [`srdja/Collections-C`](https://github.com/)
  * [`checkstyle/checkstyle`](https://github.com/checkstyle/checkstyle) by [`@romani`](https://github.com/romani)

15 Oct 2016:
I asked one of our Java developers to do a preliminary analysis
of all projects. This is the report he sent me back today:
[`award-2016.txt`](/txt/2016/award-2016.txt) (you can find your project there).
I added my comments to his pluses and minuses (see them right in that text file).
Based on his opinion and a preliminary analysis I picked these few finalists:

 * `pholser/junit-quickcheck` (Java)
 * `NullVoxPopuli/aeonvera` (Ruby)
 * `SimonKagstrom/kcov` (C++)
 * `skinny-framework/skinny-framework` (Scala)
 * `paypal/squbs` (Scala)
 * `ben-manes/caffeine` (Java)
 * `coala/coala` (Python)

I'm sorry for being late, but I need a few more days to analyze them properly
and decide which one gets the prize. I will announce the winner on 21st of October,
in six days. I will email everybody and publish my decision here.

18 Oct 2016:
This is my analysis of that seven finalists. I tried to pay as much attention
to each project as possible (they all are rather good).

[`pholser/junit-quickcheck`](https://github.com/pholser/junit-quickcheck) (19K LoC, 80K [HoC]({% pst 2014/nov/2014-11-14-hits-of-code %}))

  * changes are not really traceable, for example
    [this commit](https://github.com/pholser/junit-quickcheck/commit/a9f7527a05381c4a9c8e71c03e13d0ffb100626f)
    has no link to any GitHub issue, why was it made?
  * GitHub releases are [there](https://github.com/pholser/junit-quickcheck/releases),
    but I didn't find how exactly they are made, where is the release procedure? Also,
    they are not documented anyhow, there are no relase notes.
  * There are some utility classes, for example
    [`Lists`](https://github.com/pholser/junit-quickcheck/blob/junit-quickcheck-0.6.1/core/src/main/java/com/pholser/junit/quickcheck/internal/Lists.java),
    [`Items`](https://github.com/pholser/junit-quickcheck/blob/junit-quickcheck-0.6.1/core/src/main/java/com/pholser/junit/quickcheck/internal/Items.java),
    and [`Sequences`](https://github.com/pholser/junit-quickcheck/blob/junit-quickcheck-0.6.1/core/src/main/java/com/pholser/junit/quickcheck/internal/Sequences.java).
  * There are some -ER classes, for example
    [`Shrinker`](https://github.com/pholser/junit-quickcheck/blob/junit-quickcheck-0.6.1/core/src/main/java/com/pholser/junit/quickcheck/runner/Shrinker.java)
    and [`SampleSizer`](https://github.com/pholser/junit-quickcheck/blob/junit-quickcheck-0.6.1/core/src/main/java/com/pholser/junit/quickcheck/internal/SampleSizer.java)
    (which has code-rich constructor).
  * The design of "generators" is not really object-oriented, I guess. They
    all are providers of procedures, not really "objects" in terms of OOP.
  * Score: 5

[`NullVoxPopuli/aeonvera`](https://github.com/NullVoxPopuli/aeonvera) (46K LoC, 835K HoC)

  * "Vendor" assets are right in the GitHub repo, it's a bad practice (including jQuery)
  * It's Ruby on Rails, which is MVC, which is not really OOP. And there
    is also an ORM with anemic model (in `models/` dir). Aside from that,
    "serializers", "services", "validators", etc. -- not realy an OOP.
  * I didn't find any GitHub releases
  * There is no official release procedure in the repo. I simply
    can't understand how this product goes to production, the process
    is not automated (or the script is not in the repo). It's a serious problem
    for a web app.
  * Aside from that, the app is definitely cleaner than many other
    similar RoR web apps. Good job.
  * Score: 4

[`SimonKagstrom/kcov`](https://github.com/SimonKagstrom/kcov) (15K LoC, 50K HoC)

  * I didn't find any static analysis, although there are
    [many](https://en.wikipedia.org/wiki/List_of_tools_for_static_code_analysis#C.2C_C.2B.2B)
    open source tools for C/C++.
  * Some pieces of code are too complex methods, for example at
    [`ptrace.cc`](https://github.com/SimonKagstrom/kcov/blob/v31/src/engines/ptrace.cc),
    [`elf-parser.cc`](https://github.com/SimonKagstrom/kcov/blob/v31/src/parsers/elf-parser.cc),
    or [`html-writer.cc`](https://github.com/SimonKagstrom/kcov/blob/v31/src/writers/html-writer.cc).
  * There are some -ER classes, like
    "writers", "verifiers", and "parsers", for example:
    [`AddressVerifier`](https://github.com/SimonKagstrom/kcov/blob/v31/src/parsers/dummy-address-verifier.cc)
    or [`DwarfParser`](https://github.com/SimonKagstrom/kcov/blob/v31/src/parsers/dwarf.cc).
  * Interfaces are prefixed with `I`, which is a bad practice in OOP, see
    [`reporter.hh`](https://github.com/SimonKagstrom/kcov/blob/v31/src/include/reporter.hh).
  * There are some "utils", which I would replace with classes (most of them):
    [`utils.hh`](https://github.com/SimonKagstrom/kcov/blob/v31/src/include/utils.hh).
  * Score: 4

[`skinny-framework/skinny-framework`](https://github.com/skinny-framework/skinny-framework) (44K LoC, 191K HoC)

  * It seems that the owner of the repo is making commits directly
    to the master branch, without any issues/pull requests, for
    [example](https://github.com/skinny-framework/skinny-framework/commit/4282b2fdcb0cf3fdcd79a2b16d6fac46f89887f4).
  * I didn't find any static analysis.
  * I didn't find code coverage control, although there are many unit tests.
  * There are utility classes, for example
    [`StringUtil`](https://github.com/skinny-framework/skinny-framework/blob/2.2.0/common/src/main/scala/skinny/util/StringUtil.scala),
    [`DateTimeUtil`](https://github.com/skinny-framework/skinny-framework/blob/2.2.0/common/src/main/scala/skinny/util/DateTimeUtil.scala).
  * It's MVC, which is an anti-pattern in OOP.
  * There is ORM, which also is an anti-pattern.
  * The complexity of the code sometimes is very high, for
    example this file:
    [`AssociationsFeature.scala`](https://github.com/skinny-framework/skinny-framework/blob/2.2.0/orm/src/main/scala/skinny/orm/feature/AssociationsFeature.scala)
  * Score: 2

[`paypal/squbs`](https://github.com/paypal/squbs) (28K LoC, 163K HoC)

  * Where is static analysis?
  * Exception swallowing seems to be a common practice here, for example:
    [here](https://github.com/paypal/squbs/blob/RELEASE-0.8.X/squbs-zkcluster/src/main/scala/org/squbs/cluster/ZkCluster.scala#L119),
    [here](https://github.com/paypal/squbs/blob/RELEASE-0.8.X/squbs-admin/src/main/scala/org/squbs/admin/MBeanUtil.scala#L101),
    [here](https://github.com/paypal/squbs/blob/RELEASE-0.8.X/squbs-pattern/src/main/scala/org/squbs/pattern/util/ConfigUtil.scala#L83), etc.
  * There are utility classes, for example
    `ConfigUtil`.
  * Overall impression is that the complexity is rather high, for example
    these files are really hard to understand:
    `ServiceRegistry.scala`
    or [`UnicomplexBoot.scala`](https://github.com/paypal/squbs/blob/RELEASE-0.8.X/squbs-unicomplex/src/main/scala/org/squbs/unicomplex/UnicomplexBoot.scala).
  * Score: 3 (mostly due to complexity)

[`ben-manes/caffeine`](https://github.com/ben-manes/caffeine) (47K LoC, 191K HoC)

  * Some files are very long, for example
    [`BoundedLocalCache.java`](https://github.com/ben-manes/caffeine/blob/v2.3.3/caffeine/src/main/java/com/github/benmanes/caffeine/cache/BoundedLocalCache.java)
    (3300 LoC!). Aside from a few super long files, there are many `.java` files
    with 300+ LoC; it's too much and complexity is high because
    of that. The code looks clean, but very complex.
  * There are some -ER classes, for example
    [`Weigher`](https://github.com/ben-manes/caffeine/blob/v2.3.3/caffeine/src/main/java/com/github/benmanes/caffeine/cache/Weigher.java)
    can easily be renamed to `Weight`. Same for "loaders" and "writers."
  * Score: 4

[`coala/coala`](https://github.com/coala/coala) (15K LoC, 274K HoC)

  * This project was a finalist last year.
  * There are some -ER classes, like "parsers", "collectors", "importers."
  * I still don't see a consistent code formatting, it's really strange
    to see so many spaces in front of some lines, placed there without
    any logic (at least I can't see that logic, for
    [example](https://github.com/coala/coala/blob/master/coalib/collecting/Collectors.py#L216-L226)).
  * Some code is pure global, without any classes, like
    in [`Processing.py`](https://github.com/coala/coala/blob/master/coalib/processes/Processing.py)
    and in
    [`Collectors.py`](https://github.com/coala/coala/blob/master/coalib/collecting/Collectors.py)
    (maybe it's inevitable, but still looks strange).
  * Some files are rather long, like `Lynter.py` or `ConsoleInteraction.py`.
  * Score: 5

I can't find a strong single leader... Let me think about it.

23 Oct 2016:
I didn't find a single leader this year and the prize goes to two projects:
`pholser/junit-quickcheck` and `coala/coala` (**$2,048** to each one).

Congratulations to [`@pholser`](https://github.com/pholser) and
[`@sils`](https://github.com/sils), the winners!

Here are your badges:

<img src="//www.yegor256.com/images/award/2016/winner-pholser.png" style="width:203px;height:45px;" alt='winner'/>
&nbsp;
<img src="//www.yegor256.com/images/award/2016/winner-sils.png" style="width:203px;height:45px;" alt='winner'/>

Put this code into GitHub `README` (replace `???` with your GitHub name in the URL):

```text
<a href="https://www.yegor256.com/2015/10/17/award-2016.html">
  <img src="//www.yegor256.com/images/award/2016/winner-???.png"
  style="width:203px;height:45px;" alt='winner'/></a>
```

Thanks to everybody for participation! See you
[next year]({% pst 2016/oct/2016-10-23-award-2017 %}).
