A customizable linter: Flinter

(Sorry I already written this info in other posts)

We tried to make a customizable linter with Flinter, but we lack feedback. If some motivated guy want to try it out, the help (and critics) would be appreciated.

Note : To make this possible we extended Lizard to Fortran , so we have a new free Cyclomatic Complexity evaluation by func/subroutine for fortran too…

4 Likes

I just gave it a quick try. It deserves to be tested! The installation is so easy: $ pip install flinter

I guess I should customize the options because I don’t β€œagree” with all default formatting rules. But I have found some interesting things in the Fortran code I tested, for example:

useless-eol-dotcomma
+---------+--------+------+----------------------------------------------------------------------------+
| line_no | column | span |                                    line                                    |
+---------+--------+------+----------------------------------------------------------------------------+
|   211   |   73   |  1   |                 & "png"//c_null_char, c_null_ptr, c_null_ptr, c_null_ptr); |
|   348   |   59   |  1   |            box1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10_c_int);        |
+---------+--------+------+----------------------------------------------------------------------------+

Calling C GTK functions, it seems I sometimes put a ; at the end of line… :grin:

There are some false positives, especially when there is text in a string the regex get confused:

not-recommended-use-pause
+---------+--------+------+----------------------------------------------------------------------------------+
| line_no | column | span |                                       line                                       |
+---------+--------+------+----------------------------------------------------------------------------------+
|   238   |   20   |  5   |                        & "In pause"//C_NEW_LINE//c_null_char, -1_c_int)          |
|   241   |   43   |  5   |                                              &"In pause..."//c_null_char)        |
|   251   |   38   |  5   |                             & "Not in pause"//C_NEW_LINE//c_null_char, -1_c_int) |
+---------+--------+------+----------------------------------------------------------------------------------+

The flint tree is interesting. Is it possible to make the image bigger? (it’s rather small compared to current resolutions…) And the standard color scale is strange: OK, it follows the rainbow order, but green for high score would be more intuitive I think.

Thanks for that work, I will try to test it further.

Thanks a lot for the feedback

yeah, The string (and docstring) is somehow biasing the results. I hope we will find a clean solution soon.

Do tell me more about the rules you would prefer to see as a default (This probably the hardest part, finding a common linting standard…)

I agree the graphical output should be more customisable. We tried to follow Paul Tol rules to be colorblind friendly. The β€œIncandescent” scale might be a better fit.

We will keep you in touch.

I think flinter would deserve its own thread in the Discourse, rather than discussing in β€œFortran goals for 2022”.

Concerning the default formatting rules, maybe a poll in the Discourse could help defining them.

Concerning colors, I am not familiar with colorblind friendly but β€œincandescent” scale could be more intuitive. For me, green means β€œeverything is OK”!

1 Like

3 posts were split to a new topic: (Intrinsic) equation parsing

I tested it for GitHub - tblite/tblite: Light-weight tight-binding framework and all its dependencies (150 KLOC). With fpm turns out to be quite easy by just using the dependencies subdir as starting point:

❯ git clone https://github.com/tblite/tblite
❯ cd tblite
❯ fpm update
❯ git clone . build/dependencies/tblite
❯ time flint score build/dependencies
Flinter global rating -->|3.90|<--  (150571 statements)
flint score build/dependencies  17.55s user 0.07s system 99% cpu 17.635 total

The tree view is really helpful for spotting files worth linting. The overall result looks quite well, since I’m not actually following the built-in style I’m loosing some score points there, especially for files with many comments, due to one-space-after-comment at the moment (!> Docstring style).

From the 8 projects only JSON Fortran is not really parsed correctly here due to cpp preprocessor usage.

I think I found a bug in the regex when it comes to select type statements, like in TOML Fortran at src/tomlf/type.f90:

❯ time flint struct build/dependencies/toml-f/src/tomlf/type.f90
build/dependencies/toml-f/src/tomlf/type.f90
β”œ type: file
β”œ path: build/dependencies/toml-f/src/tomlf/type.f90
β”œ size: 435
β”œ start_line: 0
β”œ end_line: 435
β”” tomlf_type
  β”œ type: module
  β”œ path: build/dependencies/toml-f/src/tomlf/type.f90/tomlf_type
  β”œ size: 406
  β”œ start_line: 29
  β”œ end_line: 435
  β”” add_table_to_table
    β”œ type: subroutine
    β”œ path: build/dependencies/toml-f/src/tomlf/type.f90/tomlf_type/add_table_to_table
    β”œ size: 361
    β”œ start_line: 74
    β”œ end_line: 435
    β”œ is
    β”‚ β”œ type: program
    β”‚ β”œ path: build/dependencies/toml-f/src/tomlf/type.f90/tomlf_type/add_table_to_table/is
    β”‚ β”œ size: 4
    β”‚ β”œ start_line: 108
    β”‚ β”” end_line: 112
    β”” add_table_to_table.add_array_to_table
      β”œ type: subroutine
      β”œ path: build/dependencies/toml-f/src/tomlf/type.f90/tomlf_type/add_table_to_table/add_table_to_table.add_array_to_table
      β”œ size: 311
      β”œ start_line: 124
      β”œ end_line: 435
      β”œ is
      β”‚ β”œ type: program
      β”‚ β”œ path: build/dependencies/toml-f/src/tomlf/type.f90/tomlf_type/add_table_to_table/add_table_to_table.add_array_to_table/is
      β”‚ β”œ size: 4
      β”‚ β”œ start_line: 158
      β”‚ β”” end_line: 162
      β”” add_table_to_table.add_array_to_table.add_keyval_to_table
        β”œ type: subroutine
        β”œ path: build/dependencies/toml-f/src/tomlf/type.f90/tomlf_type/add_table_to_table/add_table_to_table.add_array_to_table/add_table_to_table.add_array_to_table.add_keyval_to_table
        β”œ size: 261
        β”œ start_line: 174
        β”œ end_line: 435
        β”œ is
        β”‚ β”œ type: program
        β”‚ β”œ path: build/dependencies/toml-f/src/tomlf/type.f90/tomlf_type/add_table_to_table/add_table_to_table.add_array_to_table/add_table_to_table.add_array_to_table.add_keyval_to_table/is
        β”‚ β”œ size: 4
        β”‚ β”œ start_line: 208
        β”‚ β”” end_line: 212
        β”” add_table_to_table.add_array_to_table.add_keyval_to_table.add_table_to_array
          β”œ type: subroutine
          β”œ path: build/dependencies/toml-f/src/tomlf/type.f90/tomlf_type/add_table_to_table/add_table_to_table.add_array_to_table/add_table_to_table.add_array_to_table.add_keyval_to_table/add_table_to_table.add_array_to_table.add_keyval_to_table.add_table_to_array
          β”œ size: 211
          β”œ start_line: 224
          β”œ end_line: 435
          β”œ is
          β”‚ β”œ type: program
          β”‚ β”œ path: build/dependencies/toml-f/src/tomlf/type.f90/tomlf_type/add_table_to_table/add_table_to_table.add_array_to_table/add_table_to_table.add_array_to_table.add_keyval_to_table/add_table_to_table.add_array_to_table.add_keyval_to_table.add_table_to_array/is
          β”‚ β”œ size: 4
          β”‚ β”œ start_line: 254
          β”‚ β”” end_line: 258
          β”” add_table_to_table.add_array_to_table.add_keyval_to_table.add_table_to_array.add_array_to_array
            β”œ type: subroutine
            β”œ path: build/dependencies/toml-f/src/tomlf/type.f90/tomlf_type/add_table_to_table/add_table_to_table.add_array_to_table/add_table_to_table.add_array_to_table.add_keyval_to_table/add_table_to_table.add_array_to_table.add_keyval_to_table.add_table_to_array/add_table_to_table.add_array_to_table.add_keyval_to_table.add_table_to_array.add_array_to_array
            β”œ size: 165
            β”œ start_line: 270
            β”œ end_line: 435
            β”œ is
            β”‚ β”œ type: program
            β”‚ β”œ path: build/dependencies/toml-f/src/tomlf/type.f90/tomlf_type/add_table_to_table/add_table_to_table.add_array_to_table/add_table_to_table.add_array_to_table.add_keyval_to_table/add_table_to_table.add_array_to_table.add_keyval_to_table.add_table_to_array/add_table_to_table.add_array_to_table.add_keyval_to_table.add_table_to_array.add_array_to_array/is
            β”‚ β”œ size: 4
            β”‚ β”œ start_line: 301
            β”‚ β”” end_line: 305
            β”” add_table_to_table.add_array_to_table.add_keyval_to_table.add_table_to_array.add_array_to_array.add_keyval_to_array
              β”œ type: subroutine
              β”œ path: build/dependencies/toml-f/src/tomlf/type.f90/tomlf_type/add_table_to_table/add_table_to_table.add_array_to_table/add_table_to_table.add_array_to_table.add_keyval_to_table/add_table_to_table.add_array_to_table.add_keyval_to_table.add_table_to_array/add_table_to_table.add_array_to_table.add_keyval_to_table.add_table_to_array.add_array_to_array/add_table_to_table.add_array_to_table.add_keyval_to_table.add_table_to_array.add_array_to_array.add_keyval_to_array
              β”œ size: 118
              β”œ start_line: 317
              β”œ end_line: 435
              β”œ is
              β”‚ β”œ type: program
              β”‚ β”œ path: build/dependencies/toml-f/src/tomlf/type.f90/tomlf_type/add_table_to_table/add_table_to_table.add_array_to_table/add_table_to_table.add_array_to_table.add_keyval_to_table/add_table_to_table.add_array_to_table.add_keyval_to_table.add_table_to_array/add_table_to_table.add_array_to_table.add_keyval_to_table.add_table_to_array.add_array_to_array/add_table_to_table.add_array_to_table.add_keyval_to_table.add_table_to_array.add_array_to_array.add_keyval_to_array/is
              β”‚ β”œ size: 4
              β”‚ β”œ start_line: 347
              β”‚ β”” end_line: 351
              β”œ add_table_to_table.add_array_to_table.add_keyval_to_table.add_table_to_array.add_array_to_array.add_keyval_to_array.new_table_
              β”‚ β”œ type: subroutine
              β”‚ β”œ path: build/dependencies/toml-f/src/tomlf/type.f90/tomlf_type/add_table_to_table/add_table_to_table.add_array_to_table/add_table_to_table.add_array_to_table.add_keyval_to_table/add_table_to_table.add_array_to_table.add_keyval_to_table.add_table_to_array/add_table_to_table.add_array_to_table.add_keyval_to_table.add_table_to_array.add_array_to_array/add_table_to_table.add_array_to_table.add_keyval_to_table.add_table_to_array.add_array_to_array.add_keyval_to_array/add_table_to_table.add_array_to_table.add_keyval_to_table.add_table_to_array.add_array_to_array.add_keyval_to_array.new_table_
              β”‚ β”œ size: 8
              β”‚ β”œ start_line: 363
              β”‚ β”” end_line: 371
              β”œ add_table_to_table.add_array_to_table.add_keyval_to_table.add_table_to_array.add_array_to_array.add_keyval_to_array.new_array_
              β”‚ β”œ type: subroutine
              β”‚ β”œ path: build/dependencies/toml-f/src/tomlf/type.f90/tomlf_type/add_table_to_table/add_table_to_table.add_array_to_table/add_table_to_table.add_array_to_table.add_keyval_to_table/add_table_to_table.add_array_to_table.add_keyval_to_table.add_table_to_array/add_table_to_table.add_array_to_table.add_keyval_to_table.add_table_to_array.add_array_to_array/add_table_to_table.add_array_to_table.add_keyval_to_table.add_table_to_array.add_array_to_array.add_keyval_to_array/add_table_to_table.add_array_to_table.add_keyval_to_table.add_table_to_array.add_array_to_array.add_keyval_to_array.new_array_
              β”‚ β”œ size: 8
              β”‚ β”œ start_line: 378
              β”‚ β”” end_line: 386
              β”œ add_table_to_table.add_array_to_table.add_keyval_to_table.add_table_to_array.add_array_to_array.add_keyval_to_array.new_keyval_
              β”‚ β”œ type: subroutine
              β”‚ β”œ path: build/dependencies/toml-f/src/tomlf/type.f90/tomlf_type/add_table_to_table/add_table_to_table.add_array_to_table/add_table_to_table.add_array_to_table.add_keyval_to_table/add_table_to_table.add_array_to_table.add_keyval_to_table.add_table_to_array/add_table_to_table.add_array_to_table.add_keyval_to_table.add_table_to_array.add_array_to_array/add_table_to_table.add_array_to_table.add_keyval_to_table.add_table_to_array.add_array_to_array.add_keyval_to_array/add_table_to_table.add_array_to_table.add_keyval_to_table.add_table_to_array.add_array_to_array.add_keyval_to_array.new_keyval_
              β”‚ β”œ size: 8
              β”‚ β”œ start_line: 393
              β”‚ β”” end_line: 401
              β”” add_table_to_table.add_array_to_table.add_keyval_to_table.add_table_to_array.add_array_to_array.add_keyval_to_array.is_array_of_tables
                β”œ type: function
                β”œ path: build/dependencies/toml-f/src/tomlf/type.f90/tomlf_type/add_table_to_table/add_table_to_table.add_array_to_table/add_table_to_table.add_array_to_table.add_keyval_to_table/add_table_to_table.add_array_to_table.add_keyval_to_table.add_table_to_array/add_table_to_table.add_array_to_table.add_keyval_to_table.add_table_to_array.add_array_to_array/add_table_to_table.add_array_to_table.add_keyval_to_table.add_table_to_array.add_array_to_array.add_keyval_to_array/add_table_to_table.add_array_to_table.add_keyval_to_table.add_table_to_array.add_array_to_array.add_keyval_to_array.is_array_of_tables
                β”œ size: 29
                β”œ start_line: 405
                β”œ end_line: 434
                β”” is
                  β”œ type: program
                  β”œ path: build/dependencies/toml-f/src/tomlf/type.f90/tomlf_type/add_table_to_table/add_table_to_table.add_array_to_table/add_table_to_table.add_array_to_table.add_keyval_to_table/add_table_to_table.add_array_to_table.add_keyval_to_table.add_table_to_array/add_table_to_table.add_array_to_table.add_keyval_to_table.add_table_to_array.add_array_to_array/add_table_to_table.add_array_to_table.add_keyval_to_table.add_table_to_array.add_array_to_array.add_keyval_to_array/add_table_to_table.add_array_to_table.add_keyval_to_table.add_table_to_array.add_array_to_array.add_keyval_to_array.is_array_of_tables/is
                  β”œ size: 5
                  β”œ start_line: 423
                  β”” end_line: 428
flint struct build/dependencies/toml-f/src/tomlf/type.f90  0.24s user 0.02s system 98% cpu 0.271 total
2 Likes

Personally, I would deactivate that one because I generally put a space after ! when writing a sentence but not when using a comment as a delimiter like:

!********************************
!-------------------------------------
1 Like

Maybe the linter can be improved to expect a space after !, except if it is several * or -.

1 Like

Yes, we could for example expect a space if it begins with an alphanumeric character.

I think it’s important to define general rules that are accepted by a majority of people. If the user feels there are two many false positive warnings (from his point of view), he may finally not use flinter (the user may be too lazy to define its own rules).

1 Like

I will have a play with it during the weekend and get back to you. From the looks of it there might be some potential collaboration with our VS Code Modern Fortran extension.

I would be keen on learning more about the underlying parser(s) that you are using, maybe we can start another thread about this.

@Dauptain Observation: Flinter/flint hosted on GitLab is not flint as hosted on GitHub; though, once installed, actually both launch by $ flint [parameters] easy to recall (analogue to e.g., pylint for Python).*

Question: Is there an intent to join the forces on what looks like a partially overlapping target of hint the user to the line better revised while the provision of the maps by flint(GitLab) obviously advance much further?

*) I’m aware setting an alias in .bashrc may remove the ambiguity between the two.

I agree, the homonym btw github and gitlab is a mistake from us. All apologies @marshallward :confounded:. Story is as usual, we started a project, got a minimal satisfied user base in the lab, then decided to put the stuff open source. We forgot the check on github. I will add disclaimers and redirection ASAP in the README.

When we will have some new manpower on this, I plan to divide instead 1) Try to contribute directly to Flint(Github) if we are up to the task 2) and specialize FLint>Gitlab into FlintMap, extending it with some visual greps, mapping of complexities, etc…

However, Manpower in France is scarce this year , the ETA of this division is expected for 2023.

2 Likes

The parser is an extension we added in Lizard, the fortran specific file is here.

No need to apologize, I’m glad to hear about this project. And I think we can all agree that PyPI could use better namespacing :sweat_smile:.

Although the internals are rather different, I think there are a lot of common goals here. Let’s stay in touch and see how things evolve once we both have the resources to come back to these respective projects.

1 Like

True, homonyms one may encounter in business (Merck/Germany vs. Merck & Co in the U.S.; though actually a split [fork] for political reasons), or in computation. Like OpenBabel for the transformation of chemical data which faced a similar situation when transitioning to Python 3:

# OB 2.x
import openbabel as ob
import pybel

# OB 3.0
from openbabel import openbabel as ob
from openbabel import pybel

with the remaining reminder of

Β« While more verbose, the new arrangement is in line with standard practice and helps avoid conflict with a different Python project, PyBEL. Β»

with pyBEL as in Biological Expression Language about handling biological networks e.g., in epigenetics (reference). Or of course the many Β«babelΒ» outside CTAN – including Babel of OpenBabel itself …

Or perhaps issue a note when attempting to deposit a new project in tune of Β«there already is a project of identical/similar enough name on PyPi and GitHub, GitLab, Gitea, BitBucket, … Β».