Phoenix project statictis (LOC, file types, test, etc)

Hi there,

I searched the forums but I couldn’t find any answer. Is there an equivalent of ‘rails stats’ for elixir/phoenix project?

A tool that outputs a project’s statistics like, number of files, LOC, tests, routes, etc?

Thanks in advance.

1 Like

here’s a tool I use for the LoC :wink:

find . -name '*.heex' | xargs wc -l
2 Likes

thanks. I have used that too to get a broad number, but I was thinking something more refined that could differentiate modules, functions, test similar to how rails do.

It seems there is not such tool.

Thanks anyway

1 Like

Why don’t you make one, like a script or a mix task(s)? With the assistance of an LLMs (Claude, Gemini, .. but Grok can do that too), you could have it done and running within an hour or two.

Have a look at tokei, somehow a generalized rails stats: GitHub / https://terminaltrove.com/tokei/

2 Likes

I added a little statistics package to Archdo ( https://github.com/BadBeta/archdo. It will tell you files, code lines, contexts, modules, public functions, private functions, macros, documentation, genserver, Ecto schemas, structs, sehaviours defined and use, tests also with various statistics and total. Also some ratios and metrics.

If the project is compiled there are more Contex statistics available where boundary leaks might be the most interesting one.

The statistics is likely the least useful and interesting of this package, but it had everything there from before anyway so easy to add to a stat report. :slight_smile:

If used with Claude just download somewhere and point Claude to Archdo and ask to check some Elixir project, or in this case just ask for project stats. (Helps to use with Claude and the Elixir skill if reviewing or fixing).

Alternatively add to project deps:

{:archdo, git: “https://github.REPLACE_WITH_COM/BadBeta/archdo.git”, only: [:dev], runtime: false}

mix deps.get and use mix archdo --stats

4 Likes

thanks for the recommendation. I didn’t know about this tool.

thanks. I’ll try it in a separate branch.

It is my own for internal use, but I’ve found it rather useful over several projects. And adding statistics was quick as it was already there just not presented.

There are functions for making Mermaid and SVG charts, but those are still very much work in progress. (The idea is that eventually it will show the overall architecture with contexts/ domains and how and what they connect at one level, inside of contexts will show how modules connect internally and to the boundary, while inside modules will show functions and how they call each other. Anything skipping boundaries should be very visible. Labview/ Grasshopper/ VEX inspired).

For reviewing I use it with the Elixir/ Rust-NIF/ Phoenix/ etc skills as that will help sort out greyzone actual issues from intentionally made code.

Hope it works out for you. (The architecture-rules.md lists pretty well what it checks for).

I started carefully experimenting with GitHub - jahala/tilth: Smart(er) code reading for humans and AI agents. Reduces cost per correct answer by ~40% on average. Install: cargo install tilth -or- npx tilth · GitHub after I have contributed Eilxir support to it lately. 90% of it is mostly useful to LLMs and not much to humans but Claude told me it helps it orient itself in a codebase compared to having to formulate 10+ grep incantations.

2 Likes

Interesting. I will have to spend some quality time checking out that one.

The TL;DR is that it can give you an outline of any code file i.e. all functions and generally all symbols, callers, callees, project overview and the like. LLMs can spend a while probing a codebase until they orient themselves. I don’t much care whether that’ll take them 20k tokens or 12k tokens, but I got annoyed enough by Claude spending 3 minutes to find something I know exactly where it is that I just installed tilth’s MCP and gave it a firm instruction to always try with it first.

Works much better and faster but it’s not bulletproof; I’d say 75% success rate. The biggest problem is to make Claude actually use it. :003:

Observing how Claude can sometimes wander around looking, I can see how that could save both time and tokens.

Yes, I’ve been arguing a lot with Claude over skill use and TDD. (Apart from the obvious TDD is also usually somewhat smaller than the implementation, so less chance of lazy Claude. And once the test is in place the implementation is more forced. And I think the repeat due to making both test and implementation might be for the better).

Anyway, I have seen the light in using the hooks for pretty much forcing skill and TDD use. Much improved skill use, and test get automatically written first almost without exception. Might be a solution for that one too.

1 Like

Could you elaborate on the hooks?

I admit I am very slow in the LLM usage innovation. I am using Claude to crushing successes lately but like many others I also see the rough edges and want to gradually polish them.

I have started getting results by explicitly instructing it to write a red test first, then implement a feature and make the test green. It’s not a guaranteed good result but it did improve things somewhat, and I am taking the win and I am not complaining.

I don’t know how other LLMs do it, but Claude has hook events like UserPrombtSubmit, PreToolUse, PostToolUse, SessionStart and some others. They can block, allow or inject content into the prompts. The key is that they run deterministically outside of the model itself for better control of what Claude must do and can do.

So for skills I now have a keyword [use-skills] that forces use of relevant skills based on the content of the prompt without having to explicitly invoke them. If Claude tries to start planning or implementing without invoking relevant skills first then it is blocked from doing so. Same with TDD for the first test, the test has to be written first, and once it is started it tends to just keep going. (There is a level of nagging on the way too make sure) And some other stuff to make sure the skills are not only loaded but also actively used throughout the process, and that there are setup automated milestones to make sure each task is ok sized.

1 Like

thanks everyone for their suggestions. I see there is a late tendency to rely on Claude et al for this kind of thing and that is not ideal as I would prefer to not burn tokens for something that can be done statically with some tree-sitter or similar but still very interesting answers.

Thanks for your time and answers!

Archdo is utterly static in its analysis, and for just statistics there is indeed no point of an LLM.

The core analyzer is pure Elixir AST + compiled-beam analysis: it parses files, walks ASTs, builds module/function graphs, applies 203 rule modules deterministically, and emits findings. And the mix archdo --stat spits out stats.

To maximize the value of all that information I do find Claude helpful and well worth the tokens. But each to their own :slight_smile:

1 Like

Mods - you rewrite headlines like lightning, but can’t fix a typo?

(My OCD is killing me.)

it works very well, indeed. and super fast.

╔══════════════════════════════════════════════════════════╗
║              Archdo — Project Statistics                 ║
╚══════════════════════════════════════════════════════════╝

┌─ Source (lib/) ─────────────────────────────────────────────
│
│  Files                              86
│  Lines (total)                      9565
│    Code                             7661
│    Comments                         280
│    Blank                            1624
│
│  Modules                            86
│    Avg lines/module                 89
│    Largest file                     form.ex (362 lines)
│
│  Functions (total)                  623
│    Public (def)                     383
│    Private (defp)                   240
│    Macros                           1
│
│  @spec coverage                     0.0%
│  @moduledoc coverage                19.0%
│
│  Supervisors                        1
│  Ecto schemas                       18
│  Structs                            1
└──────────────────────────────────────────────────────────

┌─ Tests (test/) ─────────────────────────────────────────────
│
│  Files                              44
│  Lines (total)                      11472
│    Code                             8874
│    Comments                         125
│    Blank                            2473
│
│  Modules                            43
│    Avg lines/module                 206
│    Largest file                     movie_test.exs (1385 lines)
│
│  Functions (total)                  59
│    Public (def)                     36
│    Private (defp)                   23
│    Macros                           0
│
│  @spec coverage                     0.0%
│  @moduledoc coverage                21.0%
│
│  Tests                              662
│    Describe blocks                  126
└──────────────────────────────────────────────────────────

┌─ Totals ──────────────────────────────────────────────
│
│  Files                              130
│  Code lines                         16535
│  Modules                            129
│  Functions                          682
│  Tests                              662
└──────────────────────────────────────────────────────────

┌─ Elixir Breakdown ────────────────────────────────────
│
│  Public/Total fn ratio              61.0%
│  Code/Comment ratio                 27.4:1
│  Source/Test ratio                  0.9:1
└──────────────────────────────────────────────────────────


Thanks for the package. i’ll be using it regularly.

1 Like

Good to hear it works for you. That code analyzer knows most anything about your code (certain macro constructs are the exceptions) so it you want something more or have it formatted differently then your local friendly Claude should be able to adapt it easily enough.

1 Like