Archeometer
Archeometer is a laboratory and a set of tools for understanding Elixir code bases from the point of view of design, architecture and code quality. You can use Archeometer to conduct invesstigations about the real architecture and quality of a given project, or simply to have a better understanding of the project you've just arrived.
Among other things, you can
- Get a queryable inventory of applications, modules, functions and macros.
- Investigate code properties: size, cyclomatic complexity, coverage.
- Visualize dependencies between applications and modules.
- Detect cyclic dependencies.
The goal is to provide you the tools to obtain insights into how a project is organized and how it could be improved.
Installation
Simply add archeometer as a dependency to your project. If you already use Credo, be sure to use at least the 1.6.6 version.
def deps do
[
{:archeometer, "~> 0.1.0"},
# and if you already use Credo, be sure to use at least the 1.6.6 version and add something like this
{:credo, "~> 1.6.6", only: [:dev, :test], runtime: false}
]
end
Or alternatively, you can clone this repository and add the dependency as a path: "path/to/the/repo" instead.
Usage
Collecting Data
Data collection is divided in several phases, but you can do it in a single run with
mix arch.exploreA SQLite database will be created in your local directory with all the collected data.
You can also run each phase individually. They are:
mix arch.explore.static: to run the static analysis section and create the database; it needs Credo,mix arch.explore.xrefs: collect cross reference data; it needs to force compile the project,mix arch.explore.apps: collect OTP application data; it needs the project to be previously compiled.mix arch.explore.coverage: collects test coverage information; it requires to run all the tests.
Mix tasks
There are some predefined tasks that can help you to have an overview of the project under the lens.
mix arch.report.html: Creates a comprehensive report for the project under review. The report contains lots of examples about how you can use Archeometer.
Documentation for arch.report.html
mix arch.dsm: will create a Design Structure Matrix, and will use it to find the cyclic dependencies in the project. In the following example, colored squares represents groups of modules whose dependencies form cycles.
Documentation for arch.dsm.
The cycles can be confirmed with yet another task: mix arch.xref --format png --out out.png Mod1 Mod2... ModN will create the dependency graph of the given module names.
Documentation for arch.xref.
Finally, mix arch.apps.xref --format png --out apps.png will create a dependency graph between the applications in your umbrella project.
Documentation for arch.apps.xref.
Code Query Language
Besides mix tasks, we created a Code Query Language (CQL) that you can use to make your own investigations. For example, to get the list of the biggest modules in a specific application, you can use
iex(10)> Repo.all(
...(10)> from m in Module,
...(10)> select: [
...(10)> name: m.name,
...(10)> num_lines: m.num_lines
...(10)> ],
...(10)> order_by: [desc: num_lines],
...(10)> where: m.application.name == "jissai",
...(10)> limit: 10
...(10)> ) |> IO.puts()
|name |num_lines |
|---------------------------- |--------- |
|Jissai.AtamaData |504 |
|Jissai.AnalyticsMock |496 |
|Jissai.AtamaDataMock |458 |
|Jissai.ProcessAlgorithmsTest |428 |
|Jissai.AtamaDataTest |420 |
|Jissai.Reports |361 |
|Jissai.DataAnalysisMock |359 |
|Jissai.ReportProvider |355 |
|Jissai.ClassDynamicsProcess |349 |
|Jissai.ReportsTest |345 |
:okThe CQL and available schemas (Modules, Applications, Functions, XRefs) are documented here.
Directly poke at the database
For everything else, you can always run SQL queries directly into the generated database. For example, the SQL equivalent of the last example would be
select m.name, m.num_lines
from modules m
inner join apps a on m.app_id = a.id
where a.name = 'jissai'
order by m.num_lines desc
limit 10;There are plenty of more examples in the Wiki!
Setup for development
To use the correct Erlang and Elixir version we use asdf-vm. You need to run
asdf installon the root of the repository.
To add the git hooks you must change the default hooks path to githooks using the following command
git config core.hooksPath .githookswith this, before each commit the hook will find issues related with compilation errors and warnings, failures in tests, issues or warnings in Credo and a correct code formatting.
Third party dependencies
Some non Elixir dependencies are necessary: