df10c2a997dd6578f49113d97109816d9eaaee03
chmalee
  Wed Apr 24 10:04:24 2019 -0700
Adding checks for hub and genome description pages and fixing incorrect error message when composite/superTracks have no children, refs #18870

diff --git src/hg/lib/trackHub.c src/hg/lib/trackHub.c
index fe807dd..11878be 100644
--- src/hg/lib/trackHub.c
+++ src/hg/lib/trackHub.c
@@ -776,47 +776,54 @@
 static void validateOneTrack( struct trackHub *hub, 
     struct trackHubGenome *genome, struct trackDb *tdb)
 /* Validate a track's trackDb entry. */
 {
 /* Check for existence of fields required in all tracks */
 requiredSetting(hub, genome, tdb, "shortLabel");
 char *shortLabel  = trackDbSetting(tdb, "shortLabel");
 memSwapChar(shortLabel, strlen(shortLabel), '\t', ' ');
 requiredSetting(hub, genome, tdb, "longLabel");
 char *longLabel  = trackDbSetting(tdb, "longLabel");
 memSwapChar(longLabel, strlen(longLabel), '\t', ' ');
 
 /* Forbid any dangerous settings that should not be allowed */
 forbidSetting(hub, genome, tdb, "idInUrlSql");
 
+if (trackDbLocalSetting(tdb, "superTrack") != NULL || trackDbLocalSetting(tdb, "compositeTrack")
+    || trackDbLocalSetting(tdb, "container"))
+    {
     // subtracks is not NULL if a track said we were its parent
+    // but generate a more helpful error if a track should have children but doesn't
     if (tdb->subtracks != NULL)
         {
         boolean isSuper = FALSE;
         char *superTrack = trackDbSetting(tdb, "superTrack");
         if ((superTrack != NULL) && startsWith("on", superTrack))
         isSuper = TRUE;
 
         if (!(trackDbSetting(tdb, "compositeTrack") ||
               trackDbSetting(tdb, "container") || 
           isSuper))
             {
         errAbort("Parent track %s is not compositeTrack, container, or superTrack in hub %s genome %s", 
             tdb->track, hub->url, genome->name);
         }
         }
     else
+        errAbort("Track %s is declared superTrack, compositeTrack or container but has no subtracks in hub %s genome %s", tdb->track, hub->url, genome->name);
+    }
+else
     {
     /* Check type field. */
     char *type = requiredSetting(hub, genome, tdb, "type");
     if (! isCustomComposite(tdb))
         {
         if (startsWithWord("mathWig", type) )
             {
             requiredSetting(hub, genome, tdb, "mathDataUrl");
             }
         else 
             {
             if (!(startsWithWord("wig", type)||  startsWithWord("bedGraph", type)))
                 {
                 if (!(startsWithWord("bigWig", type) ||
                   startsWithWord("bigBed", type) ||
@@ -1236,15 +1243,45 @@
     else if (startsWithWord("halSnake", type))
         {
         char *errString;
         int handle = halOpenLOD(bigDataUrl, &errString);
         if (handle < 0)
             errAbort("HAL open error: %s", errString);
         if (halClose(handle, &errString) < 0)
             errAbort("HAL close error: %s", errString);
         }
 #endif
     else
         errAbort("unrecognized type %s in genome %s track %s", type, genome->name, tdb->track);
     freez(&bigDataUrl);
     }
 }
+
+void hubCheckGenomeDescription(struct trackHub *hub, struct trackHubGenome *genome)
+/* Warn about missing or incorrect htmlPath settings for each genome in an assembly hub */
+{
+if (genome->twoBitPath != NULL)
+    {
+    char *htmlPath = hashFindVal(genome->settingsHash, "htmlPath");
+    if (htmlPath == NULL)
+        warn("warning: htmlPath setting missing for genome %s", genome->name);
+    else
+        {
+        // check that file actually exists
+        if (!udcExists(htmlPath))
+            warn("warning: htmlPath file does not exist %s", htmlPath);
+        }
+    }
+}
+
+void hubCheckHubDescription(struct trackHub *hub)
+/* Warn about missing or incorrect description page for hub */
+{
+if (!hub->descriptionUrl)
+    warn("warning: descriptionUrl setting missing from %s", hub->url);
+else
+    {
+    // check that file actually exists
+    if (!udcExists(hub->descriptionUrl))
+        warn("warning: descriptionUrl error: file does not exist %s", hub->descriptionUrl);
+    }
+}