Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
update_readme_metrics Namespace Reference

Functions

 fetch (component, metrics)
 
 relocate (project, path)
 
 component_of (url)
 
 format_like (old, value, metric)
 
 _engine_excluded (path)
 
 measure_engine (source_dir="src")
 
 engine_table (spec, previous="")
 
 _code_health ()
 
 measure_functions (source_dir="src")
 
 measure_includes (repo_root=".", source_dir="src")
 
 build_doxygen_db (doxyfile="doc/Doxyfile")
 
 measure_docs (db_path)
 
 _columns (spec)
 
 functions_table (spec)
 
 includes_table (spec)
 
 similarity_table (spec, trees=None, previous="", source_dir="src")
 
 main ()
 

Variables

str API = "https://sonarcloud.io/api/measures/component"
 
str TREE = "https://sonarcloud.io/api/components/tree"
 
 CELL
 
 BLOCK
 
dict FROZEN_ENGINE
 
tuple ENGINE_EXCLUDE
 
tuple ENGINE_SUFFIXES = (".c", ".cc", ".cpp", ".cxx", ".h", ".hpp", ".hxx")
 
 ENGINE_LANGUAGES = frozenset(("C", "C/C++ Header", "C++"))
 
dict FROZEN_DOCS
 
dict FROZEN_DOCS_OTHER
 
dict FROZEN_FUNCTIONS
 
dict FROZEN_INCLUDES
 
dict FROZEN_SIMILARITY
 
list DOXYGEN_DB = [None]
 
dict TREE_DIRS
 

Detailed Description

Refresh the SonarCloud figures quoted in README.md, in place.

The README compares Ansel against darktable release by release, with every number
linked to the SonarCloud measure it came from. Those numbers go stale silently, and a
stale number in a document meant to be read by people deciding whether to trust the
project is worse than no number at all.

Rather than keeping a second copy of the table here, this reads the README itself.
Every SonarCloud link already names the component it refers to, so the file IS the
specification: the script finds each link, asks SonarCloud what that component measures
today, and rewrites the figure. Descriptions, ordering, footnotes and prose are never
touched, and a row added by hand is picked up on the next run with no change here.

Two cell shapes are recognised:

    [61,373](https://sonarcloud.io/component_measures?metric=complexity&id=PROJECT)
        a single measure; the metric comes from the URL.

    [536](https://sonarcloud.io/...&selected=PROJECT:src/x.c...) / 2206
        the per-file shape used in the comparison tables: cyclomatic complexity,
        then lines of code. The trailing number is updated too. The metric named in
        the URL is IGNORED for these - a few of the hand-written links say
        metric=ncloc while displaying complexity, and the position is what the
        surrounding table promises the reader.

Only public projects are read, over the anonymous API, so this needs no token.

Usage:
  python3 tools/update_readme_metrics.py [--readme README.md] [--check]

  --check  report what would change and exit non-zero if anything is stale, without
           writing. Suitable for CI.

Function Documentation

◆ _code_health()

update_readme_metrics._code_health ( )
protected
Import the sibling analysis module, which owns the include-graph measurement.

Definition at line 404 of file update_readme_metrics.py.

Referenced by measure_includes().

◆ _columns()

update_readme_metrics._columns (   spec)
protected

Definition at line 554 of file update_readme_metrics.py.

Referenced by functions_table(), includes_table(), and similarity_table().

◆ _engine_excluded()

update_readme_metrics._engine_excluded (   path)
protected

Definition at line 156 of file update_readme_metrics.py.

Referenced by measure_docs(), measure_engine(), and measure_functions().

◆ build_doxygen_db()

update_readme_metrics.build_doxygen_db (   doxyfile = "doc/Doxyfile")
Produce Doxygen's symbol table, when one has not been built already.

The documentation build makes this in its first pass, but running this script by
hand should not require having run that first. Only the SQLite output is asked for -
no HTML, no graphs - which takes seconds rather than minutes.

Definition at line 490 of file update_readme_metrics.py.

Referenced by engine_table().

◆ component_of()

update_readme_metrics.component_of (   url)
The component a measure link points at, and the metric it names.

Definition at line 97 of file update_readme_metrics.py.

Referenced by main().

◆ engine_table()

update_readme_metrics.engine_table (   spec,
  previous = "" 
)
The engine comparison: local tooling for size and complexity, Sonar for cognitive.

Comparing the projects as a whole compares their feature sets: the set of pixel
operations under src/iop has diverged between the forks, and those modules are
independent of one another, so their bulk says little about maintainability.
Subtracting them compares the engine, which is what both projects need whatever
their module set.

Cyclomatic complexity, lines of code and comment ratio come from ONE tool applied
identically to every version, because SonarCloud and lizard do not define
cyclomatic complexity the same way and mixing them silently compares nothing.
Cognitive complexity has no local equivalent, so it is reported from SonarCloud for
the three versions that have a project there, and left blank for the rest rather
than approximated.

Definition at line 212 of file update_readme_metrics.py.

References build_doxygen_db(), fetch(), max, measure_docs(), and measure_engine().

◆ fetch()

update_readme_metrics.fetch (   component,
  metrics 
)
Ask SonarCloud for one component's measures. Returns {metric: raw string}.

Definition at line 60 of file update_readme_metrics.py.

Referenced by engine_table(), and main().

◆ format_like()

update_readme_metrics.format_like (   old,
  value,
  metric 
)
Render a fresh value the way the README already renders that column.

Definition at line 106 of file update_readme_metrics.py.

Referenced by main().

◆ functions_table()

update_readme_metrics.functions_table (   spec)
Per-function engine complexity. Ansel measured live, releases frozen.

Definition at line 565 of file update_readme_metrics.py.

References _columns(), and measure_functions().

◆ includes_table()

update_readme_metrics.includes_table (   spec)
Include-graph exposure. Ansel measured live, releases frozen.

Definition at line 586 of file update_readme_metrics.py.

References _columns(), and measure_includes().

◆ main()

update_readme_metrics.main ( void  )

Definition at line 675 of file update_readme_metrics.py.

References component_of(), fetch(), format_like(), main(), relocate(), and similarity_table().

Referenced by main().

◆ measure_docs()

update_readme_metrics.measure_docs (   db_path)
Share of engine functions carrying a documentation comment.

Reads the SQLite symbol table Doxygen produces (GENERATE_SQLITE3), which the
documentation build already generates in its first pass, and filters to the engine
the same way everything else here does. A function counts as documented when Doxygen
recorded a brief or detailed description for it - that is, when it carries a real
doc-comment rather than an ordinary one.

Definition at line 517 of file update_readme_metrics.py.

References _engine_excluded().

Referenced by engine_table().

◆ measure_engine()

update_readme_metrics.measure_engine (   source_dir = "src")
Measure this working tree's engine with lizard and cloc.

Returns None if either tool is missing, so the table is left untouched rather than
written with half of it guessed.

Definition at line 163 of file update_readme_metrics.py.

References _engine_excluded().

Referenced by engine_table().

◆ measure_functions()

update_readme_metrics.measure_functions (   source_dir = "src")
Per-function complexity of this tree's engine, via lizard.

Definition at line 413 of file update_readme_metrics.py.

References _engine_excluded().

Referenced by functions_table().

◆ measure_includes()

update_readme_metrics.measure_includes (   repo_root = ".",
  source_dir = "src" 
)
Include-graph exposure of this tree's engine.

Definition at line 443 of file update_readme_metrics.py.

References _code_health(), and max.

Referenced by includes_table().

◆ relocate()

update_readme_metrics.relocate (   project,
  path 
)
Find a file that has moved, by basename, within the same project.

Ansel reorganises: bauhaus.c went from src/bauhaus/ to src/widgets/, mipmap_cache.c
to src/caches/, and so on. The README then points at components that 404, and the
figures beside them quietly stop being refreshed - which is exactly the failure this
script exists to prevent. Searching the project tree by basename recovers them, but
only when the answer is unambiguous: two files of the same name are left alone for a
human to resolve rather than guessed at.

Definition at line 72 of file update_readme_metrics.py.

Referenced by main().

◆ similarity_table()

update_readme_metrics.similarity_table (   spec,
  trees = None,
  previous = "",
  source_dir = "src" 
)
Upper-triangle similarity matrix.

Release-to-release cells are frozen. The cells involving Ansel move with Ansel and
need the Darktable sources to recompute, so they are refreshed only when
--darktable-trees points at a directory holding dt38/ dt40/ dt50/ dt56/ checkouts.
Without it the values already in the README are KEPT, not blanked: a table that
loses real numbers because an optional input was missing is worse than one that is
slightly out of date, and the omission is reported on stderr either way.

Definition at line 611 of file update_readme_metrics.py.

References _columns(), and max.

Referenced by main().

Variable Documentation

◆ API

str update_readme_metrics.API = "https://sonarcloud.io/api/measures/component"

Definition at line 50 of file update_readme_metrics.py.

◆ BLOCK

update_readme_metrics.BLOCK
Initial value:
1= re.compile(
2 r"(?P<open><!-- BEGIN GENERATED (?P<name>[\w-]+):(?P<spec>[^>]*)-->\n)"
3 r"(?P<body>.*?)"
4 r"(?P<close><!-- END GENERATED (?P=name) -->)",
5 re.DOTALL)

Definition at line 117 of file update_readme_metrics.py.

◆ CELL

update_readme_metrics.CELL
Initial value:
1= re.compile(
2 r"\[(?P<value>[\d.,]+)(?P<pct>%?)\]\‍((?P<url>https://sonarcloud\.io/[^)]+)\‍)"
3 r"(?P<tail>\s*/\s*(?P<second>[\d,]+))?"
4)

Definition at line 54 of file update_readme_metrics.py.

◆ DOXYGEN_DB

list update_readme_metrics.DOXYGEN_DB = [None]

Definition at line 398 of file update_readme_metrics.py.

◆ ENGINE_EXCLUDE

tuple update_readme_metrics.ENGINE_EXCLUDE
Initial value:
1= ("/external/", "/apps/ansel-chart/", "/iop/",
2 "/tests/", "/image_test/samples/",
3 "/doxygen-awesome-css/")

Definition at line 149 of file update_readme_metrics.py.

◆ ENGINE_LANGUAGES

update_readme_metrics.ENGINE_LANGUAGES = frozenset(("C", "C/C++ Header", "C++"))

Definition at line 153 of file update_readme_metrics.py.

◆ ENGINE_SUFFIXES

tuple update_readme_metrics.ENGINE_SUFFIXES = (".c", ".cc", ".cpp", ".cxx", ".h", ".hpp", ".hxx")

Definition at line 152 of file update_readme_metrics.py.

◆ FROZEN_DOCS

dict update_readme_metrics.FROZEN_DOCS
Initial value:
1= {
2 "Darktable 3.8": {"functions": 9308, "documented": 1997},
3 "Darktable 4.0": {"functions": 9600, "documented": 2008},
4 "Darktable 5.0": {"functions": 10212, "documented": 2048},
5 "Darktable 5.6": {"functions": 11316, "documented": 2228},
6}

Definition at line 354 of file update_readme_metrics.py.

◆ FROZEN_DOCS_OTHER

dict update_readme_metrics.FROZEN_DOCS_OTHER
Initial value:
1= {
2 "Darktable 3.8": {"symbols": 6363, "documented": 332},
3 "Darktable 4.0": {"symbols": 6695, "documented": 329},
4 "Darktable 5.0": {"symbols": 7373, "documented": 349},
5 "Darktable 5.6": {"symbols": 8190, "documented": 404},
6}

Definition at line 365 of file update_readme_metrics.py.

◆ FROZEN_ENGINE

dict update_readme_metrics.FROZEN_ENGINE
Initial value:
1= {
2 "Darktable 3.8": {"tag": "release-3.8.1", "complexity": 35244,
3 "code": 199820, "comment": 28736},
4 "Darktable 4.0": {"tag": "release-4.0.0", "complexity": 37156,
5 "code": 207304, "comment": 31877},
6 "Darktable 5.0": {"tag": "release-5.0.0", "complexity": 38016,
7 "code": 229248, "comment": 34431},
8 "Darktable 5.6": {"tag": "release-5.6.0", "complexity": 44059,
9 "code": 260318, "comment": 40879},
10}

Definition at line 132 of file update_readme_metrics.py.

◆ FROZEN_FUNCTIONS

dict update_readme_metrics.FROZEN_FUNCTIONS
Initial value:
1= {
2 "Darktable 3.8": {"functions": 7242, "mean": 4.87, "max": 194, "over15": 428, "over50": 45},
3 "Darktable 4.0": {"functions": 7484, "mean": 4.96, "max": 210, "over15": 456, "over50": 48},
4 "Darktable 5.0": {"functions": 7759, "mean": 4.90, "max": 252, "over15": 453, "over50": 48},
5 "Darktable 5.6": {"functions": 8691, "mean": 5.07, "max": 249, "over15": 522, "over50": 63},
6}

Definition at line 372 of file update_readme_metrics.py.

◆ FROZEN_INCLUDES

dict update_readme_metrics.FROZEN_INCLUDES
Initial value:
1= {
2 "Darktable 3.8": {"med_dep": 14.5, "avg_aff": 84, "over25": 32,
3 "cycles": 4, "trapped": 17, "god": 30},
4 "Darktable 4.0": {"med_dep": 13.4, "avg_aff": 83, "over25": 31,
5 "cycles": 4, "trapped": 17, "god": 30},
6 "Darktable 5.0": {"med_dep": 15.0, "avg_aff": 95, "over25": 34,
7 "cycles": 4, "trapped": 17, "god": 36},
8 "Darktable 5.6": {"med_dep": 14.1, "avg_aff": 96, "over25": 32,
9 "cycles": 4, "trapped": 17, "god": 38},
10}

Definition at line 379 of file update_readme_metrics.py.

◆ FROZEN_SIMILARITY

dict update_readme_metrics.FROZEN_SIMILARITY
Initial value:
1= {
2 ("Darktable 3.8", "Darktable 4.0"): 87.3,
3 ("Darktable 3.8", "Darktable 5.6"): 39.6,
4 ("Darktable 4.0", "Darktable 5.6"): 43.2,
5}

Definition at line 392 of file update_readme_metrics.py.

◆ TREE

str update_readme_metrics.TREE = "https://sonarcloud.io/api/components/tree"

Definition at line 51 of file update_readme_metrics.py.

◆ TREE_DIRS

dict update_readme_metrics.TREE_DIRS
Initial value:
1= {"Darktable 3.8": "dt38", "Darktable 4.0": "dt40",
2 "Darktable 5.0": "dt50", "Darktable 5.6": "dt56"}

Definition at line 400 of file update_readme_metrics.py.