0c504951ad80a920183bcb6406ab5f6f1264cc53
braney
  Tue Sep 1 10:24:09 2026 -0700
trackDbConditions: work out what has to be true before a setting does anything, refs #37908

The types list in trackDbLibrary.shtml is flat, so it cannot say "only in
coverage mode", "only when the track is in pack", "only when another setting is
on".  Those conditions are real and there are a lot of them.  This finds them by
reading the C.

harvestConditions.py records, for every read of a track setting, the conditions
that enclose it, using offset ranges rather than brace depth so that
`if (x) return;` is handled as exactly as a braced block, and an early return
contributes its negation to the rest of the function.  That alone finds little,
because the read is usually plain and the test sits at the caller, so it also
builds a call graph and computes the conditions that hold on EVERY path into
each function.  Only those are reported, which keeps every claim a necessary
condition rather than a guess.  A function whose address is taken can be a track
method and is reached from outside the scan, so it reports nothing rather than
something false.

Render and config are scanned as separate call graphs.  What has to be true for
a setting to change the picture is a different question from what has to be true
for its control to appear, and mixing them empties every intersection.

trackDbConditions.py sorts the conditions into kinds and reports them against
the documented settings.  --check is the cron mode and fails when a documented
setting gains its first condition or loses its last, since either way the
documentation and the code have parted company.

Where it stands: 325 settings read across 779 sites.  In the render scope 96
have a condition that holds at every read, 43 of them documented, and 27 of
those turn on something other than the track type.  Known limits, all in the
module docstrings: a name built with safef is invisible, a condition carried in
a variable to a later use is not followed, and the boundary between drawing and
the configuration popup inside hgTracks.c is not clean, which is why
configurable and filterBy come back with popup plumbing in their lists.

diff --git src/hg/utils/trackDbConditions/conditionBaseline.txt src/hg/utils/trackDbConditions/conditionBaseline.txt
new file mode 100644
index 00000000000..0a1eb39564d
--- /dev/null
+++ src/hg/utils/trackDbConditions/conditionBaseline.txt
@@ -0,0 +1,45 @@
+# Documented settings whose reads all sit behind a condition.
+# Accepted state for trackDbConditions.py --check.  One scope:name per line.
+render:barChartBars
+render:barChartCategoryUrl
+render:barChartColors
+render:barChartMerge
+render:baseColorTickColor
+render:baseColorUseCds
+render:centerLabelsDense
+render:chainNormScoreAvailable
+render:configurable
+render:configureByPopup
+render:dataVersion
+render:detailsBoxesEnabled
+render:drawMode
+render:exonNumbers
+render:filterBy
+render:frames
+render:hapClusterHeight
+render:hapClusterTreeAngle
+render:hicArcLimit
+render:hideEmptySubtracks
+render:hideEmptySubtracksMultiBedUrl
+render:hideEmptySubtracksSourcesUrl
+render:irows
+render:labelOnFeature
+render:linkDataUrl
+render:lollyMaxSize
+render:lollyNoStems
+render:metadata
+render:minGrayLevel
+render:minQual
+render:noInherit
+render:normalization
+render:otherTwoBitUrl
+render:pennantIcon
+render:resolution
+render:saturationScore
+render:showCdsMaxZoom
+render:smoothingWindow
+render:speciesCodonDefault
+render:subGroups
+render:thickDrawItem
+render:viewLimits
+render:windowingFunction