5b16886cc31572cdab8c383bfbdd2ad60de13617
chmalee
  Thu Feb 20 14:15:01 2020 -0800
Fixups to hubCheck html option so that checking for hub description page and genome description pages works, refs #24958

diff --git src/hg/utils/hubCheck/hubCheck.c src/hg/utils/hubCheck/hubCheck.c
index b148162..9bcb27e 100644
--- src/hg/utils/hubCheck/hubCheck.c
+++ src/hg/utils/hubCheck/hubCheck.c
@@ -470,58 +470,60 @@
 return dyStringCannibalize(&folderString);
 }
 
 char *makeChildObjectString(char *id, char *title, char *shortLabel, char *longLabel,
     char *color, char *name, char *text, char *parent)
 /* Construct a single child item for one of the jstree arrays */
 {
 struct dyString *item = dyStringNew(0);
 dyStringPrintf(item, "{icon: 'fa fa-plus', id:'%s', li_attr:{class: 'hubError', title: '%s', "
         "shortLabel: '%s', longLabel: '%s', color: '%s', name:'%s'}, "
         "text:'%s', parent: '%s', state: {opened: true}}",
         id, title, shortLabel, longLabel, color, name, replaceChars(text, "'", "\\'"), parent);
 return dyStringCannibalize(&item);
 }
 
-void hubErr(struct dyString *errors, char *message, struct trackHub *hub)
+void hubErr(struct dyString *errors, char *message, struct trackHub *hub, boolean doHtml)
 /* Construct the right javascript for the jstree for a top level hub.txt error. */
 {
+if (!doHtml)
+    dyStringPrintf(errors, "%s", message);
+else
+    {
     char *sl;
     char *strippedMessage = NULL;
     static int count = 0; // force a unique id for the jstree object
     char id[512];
     //TODO: Choose better default labels
     if (hub && hub->shortLabel != NULL)
         {
         sl = hub->shortLabel;
         }
     else
         sl = "Hub Error";
     if (message)
         strippedMessage = cloneString(message);
     stripChar(strippedMessage, '\n');
     safef(id, sizeof(id), "%s%d", sl, count);
 
     // make the error message
     dyStringPrintf(errors, "trackData['%s'] = [%s];\n", sl,
         makeChildObjectString(id, "Hub Error", sl, sl, "#550073", sl, strippedMessage, sl));
 
-// display it by default
-dyStringPrintf(errors, "trackData['#'] = [%s];\n",
-    makeFolderObjectString(sl, "Error getting hub or genomes configuration", "#", "Click to open node", TRUE, TRUE));
     count++;
     }
+}
 
 void genomeErr(struct dyString *errors, char *message, struct trackHub *hub,
     struct trackHubGenome *genome, boolean doHtml)
 /* Construct the right javascript for the jstree for a top-level genomes.txt error or
  * error opening a trackDb.txt file */
 {
 if (!doHtml)
     dyStringPrintf(errors, "%s", message);
 else
     {
     static int count = 0; // forces unique ID's which the jstree object needs
     char id[512];
     char *strippedMessage = NULL;
     char *genomeName = trackHubSkipHubName(genome->name);
     if (message)
@@ -838,40 +840,36 @@
     {
     if (genome->twoBitPath != NULL)
         {
         char *htmlPath = hashFindVal(genome->settingsHash, "htmlPath");
         if (htmlPath == NULL)
             warn("warning: missing htmlPath setting for assembly hub '%s'", genome->name);
         else if (!udcExists(htmlPath))
             warn("warning: htmlPath file does not exist: '%s'", htmlPath);
         }
     tdbList = trackHubTracksForGenome(hub, genome);
     tdbList = trackDbLinkUpGenerations(tdbList);
     tdbList = trackDbPolishAfterLinkup(tdbList, genome->name);
     trackHubPolishTrackNames(hub, tdbList);
     }
 errCatchEnd(errCatch);
-if (errCatch->gotError)
-    {
-    openedGenome = TRUE;
-    genomeErrorCount += 1;
-    genomeErr(errors, errCatch->message->string, hub, genome, options->htmlOut);
-    }
-if (errCatch->gotWarning)
+if (errCatch->gotError || errCatch->gotWarning)
     {
     openedGenome = TRUE;
     genomeErr(errors, errCatch->message->string, hub, genome, options->htmlOut);
+    if (errCatch->gotError)
+        genomeErrorCount += 1;
     }
 errCatchFree(&errCatch);
 
 verbose(2, "%d tracks in %s\n", slCount(tdbList), genome->name);
 struct trackDb *tdb;
 int tdbCheckVal;
 static struct dyString *tdbDyString = NULL;
 if (!tdbDyString)
     tdbDyString = dyStringNew(0);
 
 // build up the track results list, keep track of number of errors, then
 // open up genomes folder
 char *genomeName = trackHubSkipHubName(genome->name);
 for (tdb = tdbList; tdb != NULL; tdb = tdb->next)
     {
@@ -903,85 +901,88 @@
 dyStringPrintf(errors, "%s", tdbDyString->string);
 dyStringClear(tdbDyString);
 
 return genomeErrorCount;
 }
 
 
 int trackHubCheck(char *hubUrl, struct trackHubCheckOptions *options, struct dyString *errors)
 /* Check a track data hub for integrity. Put errors in dyString.
  *      return 0 if hub has no errors, 1 otherwise
  *      if options->checkTracks is TRUE, check remote files of individual tracks
  */
 {
 struct errCatch *errCatch = errCatchNew();
 struct trackHub *hub = NULL;
+struct dyString *hubErrors = dyStringNew(0);
 int retVal = 0;
 
 if (errCatchStart(errCatch))
     {
     hub = trackHubOpen(hubUrl, "");
     if (hub->descriptionUrl == NULL)
         warn("warning: missing hub overview descripton page (descriptionUrl setting)");
     else if (!udcExists(hub->descriptionUrl))
         warn("warning: %s descriptionUrl setting does not exist", hub->descriptionUrl);
     }
 errCatchEnd(errCatch);
 if (errCatch->gotError || errCatch->gotWarning)
     {
     retVal = 1;
+    hubErr(hubErrors, errCatch->message->string, hub, options->htmlOut);
+
     if (options->htmlOut)
-        {
-        hubErr(errors, errCatch->message->string, hub);
-        }
-    else
-        dyStringPrintf(errors, "%s\n", errCatch->message->string);
+        dyStringPrintf(errors, "trackData['#'] = [%s,",
+            makeFolderObjectString(hub->shortLabel, "Hub Errors", "#",
+                "Click to open node", TRUE, TRUE));
     }
-if (errCatch->gotWarning && !errCatch->gotError)
-    dyStringPrintf(errors, "%s", errCatch->message->string);
 errCatchFree(&errCatch);
 
 if (hub == NULL)
+    {
+    dyStringPrintf(errors, "%s", dyStringCannibalize(&hubErrors));
     return 1;
+    }
+if (options->htmlOut && retVal != 1)
+    dyStringPrintf(errors, "trackData['#'] = [");
 
 if (options->checkSettings)
     retVal |= hubSettingsCheckInit(hub, options, errors);
 
 struct trackHubGenome *genome;
-
-if (options->htmlOut)
-    dyStringPrintf(errors, "trackData['#'] = [");
-
 int numGenomeErrors = 0;
 char genomeTitleString[128];
 struct dyString *genomeErrors = dyStringNew(0);
 for (genome = hub->genomeList; genome != NULL; genome = genome->next)
     {
     numGenomeErrors = hubCheckGenome(hub, genome, options, genomeErrors);
     if (options->htmlOut)
         {
         char *genomeName = trackHubSkipHubName(genome->name);
         safef(genomeTitleString, sizeof(genomeTitleString),
             "%s (%d configuration error%s)", genomeName, numGenomeErrors,
             numGenomeErrors == 1 ? "" : "s");
         dyStringPrintf(errors, "%s,", makeFolderObjectString(genomeName, genomeTitleString, "#",
             "Click to open node", TRUE, numGenomeErrors > 0 ? TRUE : FALSE));
         }
     retVal |= numGenomeErrors;
     }
 if (options->htmlOut)
+    {
     dyStringPrintf(errors, "];\n");
+    }
+dyStringPrintf(errors, "%s", dyStringCannibalize(&hubErrors));
 dyStringPrintf(errors, "%s", dyStringCannibalize(&genomeErrors));
 trackHubClose(&hub);
 return retVal;
 }
 
 
 static void addExtras(char *extraFile, struct trackHubCheckOptions *checkOptions)
 /* Add settings from extra file (e.g. for specific hub display site) */
 {
 verbose(2, "Accepting extra settings in '%s'\n", extraFile);
 checkOptions->extraFile = extraFile;
 checkOptions->extra = hashNew(0);
 struct lineFile *lf = NULL;
 if (startsWith("http", extraFile))
     {