800312e66545e7d7fd4805c99717bd32c4b47c33 chmalee Tue Feb 18 16:49:45 2020 -0800 Fixing spurious newline stripping in hubCheck. When checking a subGroupN line for a composite track, a warn is thrown and hubCheck continues, if a single stanza has multiple cases of bad subGroups, then all these warning messages were stuck together and not being printed correctly, refs #24958 diff --git src/hg/utils/hubCheck/hubCheck.c src/hg/utils/hubCheck/hubCheck.c index 424c8d8..73070d2 100644 --- src/hg/utils/hubCheck/hubCheck.c +++ src/hg/utils/hubCheck/hubCheck.c @@ -465,32 +465,32 @@ struct dyString *folderString = dyStringNew(0); dyStringPrintf(folderString, "{icon: '../../images/folderC.png', id: '%s', " "text:\"%s\", parent:'%s'," "li_attr:{title:'%s'}, children:%s, state: {opened: %s}}", id, text, parent, title, children ? "true" : "false", openFolder ? "true" : "false"); 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, text, parent); + "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) /* Construct the right javascript for the jstree for a top level hub.txt error. */ { 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; } @@ -528,46 +528,61 @@ dyStringPrintf(errors, "trackData['%s'] = [%s", genomeName, makeChildObjectString(id, "Error Getting TrackDb", genomeName, genomeName, "#550073", genomeName, strippedMessage, genomeName)); count++; } void trackDbErr(struct dyString *errors, char *message, struct trackHubGenome *genome, struct trackDb *tdb, boolean doHtml) /* Adds the right object for a jstree object of trackDb configuration errors. */ { if (!doHtml) { dyStringPrintf(errors, "%s", message); } else { char *strippedMessage = NULL; + char *splitMessages[16]; // SUBGROUP_MAX=9 but add a few extra just in case char parentOrTrackString[512]; char id[512]; static int count = 0; // forces unique ID's which the jstree object needs + int numMessages = 0; + int i = 0; + // if a subtrack is missing multiple subgroups, then message will contain + // at least two newline separated errors, both should be printed separately: if (message) + { strippedMessage = cloneString(message); + while (lastChar(strippedMessage) == '\n') + trimLastChar(strippedMessage); + numMessages = chopByChar(strippedMessage, '\n', splitMessages, sizeof(splitMessages)); + } - stripChar(strippedMessage, '\n'); + for (; i < numMessages; i++) + { + if (isNotEmpty(splitMessages[i])) + { safef(id, sizeof(id), "%s%d", trackHubSkipHubName(tdb->track), count); safef(parentOrTrackString, sizeof(parentOrTrackString), "%s_%s", trackHubSkipHubName(genome->name), trackHubSkipHubName(tdb->track)); dyStringPrintf(errors, "%s,", makeChildObjectString(id, "TrackDb Error", tdb->shortLabel, tdb->longLabel, - "#550073", trackHubSkipHubName(tdb->track), strippedMessage, parentOrTrackString)); + "#550073", trackHubSkipHubName(tdb->track), splitMessages[i], parentOrTrackString)); count++; } } + } +} boolean checkEmptyMembersForAll(membersForAll_t *membersForAll, struct trackDb *parentTdb) /* membersForAll may be allocated and exist but not have any actual members defined. */ { int i; for (i = 0; i < ArraySize(membersForAll->members); i++) { if (membersForAll->members[i] != NULL) return TRUE; } return FALSE; } int hubCheckSubtrackSettings(struct trackHubGenome *genome, struct trackDb *tdb, struct dyString *errors, struct trackHubCheckOptions *options) /* Check that 'subgroups' are consistent with what is defined at the parent level */ @@ -578,34 +593,31 @@ int i; char *subtrackName = trackHubSkipHubName(tdb->track); sortOrder_t *sortOrder = NULL; membership_t *membership = NULL; membersForAll_t *membersForAll = NULL; struct errCatch *errCatch = errCatchNew(); if (errCatchStart(errCatch)) { membersForAll = membersForAllSubGroupsGet(tdb->parent, NULL); // membersForAllSubGroupsGet() warns about the parent stanza, turn it into an errAbort if (errCatch->gotWarning) { - char *temp = cloneString(errCatch->message->string); - stripChar(temp, '\n'); - dyStringClear(errCatch->message); - errAbort("%s", temp); + errAbort("%s", errCatch->message->string); } if (membersForAll && checkEmptyMembersForAll(membersForAll, tdb->parent)) { membership = subgroupMembershipGet(tdb); sortOrder = sortOrderGet(NULL, tdb->parent); if (membership == NULL) { errAbort("missing 'subgroups' setting for subtrack %s", subtrackName); } // if a sortOrder is defined, make sure every subtrack has that membership if (sortOrder) {