7204d8c80f457039e942c33cb832900010a65270
braney
  Thu Feb 13 12:33:50 2025 -0800
don't create hub in hgCollection on invocation.  Wait till something
gets added to the collection.   Refs #35088

diff --git src/hg/hgCollection/hgCollection.c src/hg/hgCollection/hgCollection.c
index f876e94d277..3cef96f7f06 100644
--- src/hg/hgCollection/hgCollection.c
+++ src/hg/hgCollection/hgCollection.c
@@ -188,39 +188,42 @@
 jsInlineF("{%s id:'%s',li_attr:{title:'%s',shortlabel:'%s', longlabel:'%s',color:'#%06x',name:'%s'},text:'%s (%s)',parent:'%s'}",userString, trackHubSkipHubName(tdb->track),title, escapeLabel(tdb->shortLabel), escapeLabel(tdb->longLabel), IMAKECOLOR_32(tdb->colorR,tdb->colorG,tdb->colorB),trackHubSkipHubName(tdb->track),escapeLabel(tdb->shortLabel),escapeLabel(tdb->longLabel),parent);
 }
 
 static void outHubHeader(FILE *f, char *db)
 // output a track hub header
 {
 fprintf(f,"hub hub1\n\
 shortLabel Track Collections\n\
 longLabel Track Collections\n\
 useOneFile on\n\
 email genome-www@soe.ucsc.edu\n\n");
 fprintf(f,"genome %s\n\n", db);  
 }
 
 
-static char *getHubName(struct cart *cart, char *db)
-// get the name of the hub to use for user collections
+static char *getHubName(struct cart *cart, char *db, boolean doCreate)
+// get the name of the hub to use for user collections.  Create the hub if doCreate is TRUE
 {
 struct tempName hubTn;
 char buffer[4096];
 safef(buffer, sizeof buffer, "%s-%s", customCompositeCartName, db);
 char *hubName = cartOptionalString(cart, buffer);
 int fd = -1;
 
+if (!doCreate && (hubName == NULL))
+    return NULL;
+
 if ((hubName == NULL) || ((fd = open(hubName, 0)) < 0))
     {
     trashDirDateFile(&hubTn, "hgComposite", "hub", ".txt");
     hubName = cloneString(hubTn.forCgi);
     cartSetString(cart, buffer, hubName);
     FILE *f = mustOpen(hubName, "a");
     outHubHeader(f, db);
     fclose(f);
     }
 
 if (fd >= 0)
     close(fd);
 
 cartSetString(cart, "hubUrl", hubName);
 cartSetString(cart, hgHubConnectRemakeTrackHub, hubName);
@@ -401,31 +404,31 @@
 {
 if (parentTdb->subtracks == NULL)
     return;
 
 struct trackDb *tdb;
 for(tdb = parentTdb->subtracks; tdb;  tdb = tdb->next)
     {
     dyStringPrintf(dy, "collectionNames['%s']=1;", trackHubSkipHubName(tdb->track));
     addSubtrackNames(dy, tdb);
     }
 }
 
 static void doTable(struct cart *cart, char *db, struct grp *groupList, struct trackDb *trackList)
 // output the tree table
 {
-char *hubName = hubNameFromUrl(getHubName(cart, db));
+char *hubName = hubNameFromUrl(getHubName(cart, db, FALSE));
 struct grp *curGroup;
 struct hash *groupHash = newHash(10);
 int count = 0;
 
 for(curGroup = groupList; curGroup;  curGroup = curGroup->next)
     {
     if (curGroup->priority == 0)
         curGroup->priority = count--;
     hashAdd(groupHash, curGroup->name, curGroup);
     }
 
 curGroup = NULL;
 if (hubName != NULL)
     curGroup = hashFindVal(groupHash, hubName);
 
@@ -685,31 +688,31 @@
         hashStore(collectionNameHash,  tdb->track);
 
     char *bigDataUrl = trackDbSetting(tdb, "bigDataUrl");
     if (bigDataUrl == NULL)
         {
         char *table = trackDbSetting(tdb, "table");
         if (table == NULL)
             hashAdd(tdb->settingsHash, "table", tdb->track);
         }
     }
 }
 
 static void updateHub(struct cart *cart, char *db, struct track *collectionList, struct hash *nameHash)
 // save our state to the track hub
 {
-char *filename = getHubName(cart, db);
+char *filename = getHubName(cart, db, TRUE);
 char *hubName = hubNameFromUrl(filename);
 
 FILE *f = mustOpen(filename, "w");
 chmod(filename, 0666);
 
 struct hash *collectionNameHash = newHash(6);
 
 outHubHeader(f, db);
 struct track *collection;
 struct sqlConnection *conn = NULL;
 if (!trackHubDatabase(db))
     conn = hAllocConn(db);
 int priority = 1;
 for(collection = collectionList; collection; collection = collection->next)
     {
@@ -806,30 +809,31 @@
 struct hash *trackHash = hashNew(5);
 struct jsonParseData jpd = {&collectionList, trackHash};
 jsonElementRecurse(collectionElements, NULL, FALSE, jsonObjStart, NULL, &jpd);
 
 slReverse(&collectionList);
 return collectionList;
 }
 
 static void doAjax(struct cart *cart, char *db, char *jsonText, struct hash *nameHash)
 // Save our state
 {
 cgiDecodeFull(jsonText, jsonText, strlen(jsonText));
 struct jsonElement *collectionElements = jsonParse(jsonText);
 struct track *collectionList = parseJsonElements(collectionElements);
 
+if (slCount(collectionList))
     updateHub(cart, db, collectionList, nameHash);
 }
 
 static void buildNameHash(struct hash *nameHash, struct hash *labelHash, struct trackDb *list)
 {
 if (list == NULL)
     return;
 
 struct trackDb *tdb = list;
 for(tdb = list; tdb;  tdb = tdb->next)
     {
     hashAdd(nameHash, trackHubSkipHubName(tdb->track), tdb);
     if (labelHash)
         hashAdd(labelHash, tdb->shortLabel, tdb);
     buildNameHash(nameHash, NULL,  tdb->subtracks);
@@ -944,31 +948,31 @@
                 {
                 printTdbToHub(db, conn, f, subTdb, numTabs + 1, priority++);
                 }
             }
         else
             printTdbToHub(db, conn, f, newTdb, numTabs + 1, priority++);
         }
 
     printTrackDbListToHub(db, conn, f, hubName,  tdb->subtracks, collectionName, newTdb, numTabs + 1, priority);
     }
 }
 
 static void doAddTrack(struct cart *cart, char *db, struct trackDb *trackList,  char *trackName, char *collectionName, struct hash *nameHash)
 /* Add a track to a collection in a hub. */
 {
-char *fileName = getHubName(cart, db);
+char *fileName = getHubName(cart, db, TRUE);
 char *hubName = hubNameFromUrl(fileName);
 FILE *f = fopen(fileName, "w");
 struct trackDb *newTdb = hashMustFindVal(nameHash, trackHubSkipHubName(trackName));
 if (newTdb->subtracks)
     {
     struct trackDb *subTdb;
     for(subTdb = newTdb->subtracks; subTdb; subTdb = subTdb->next)
         {
         hashReplace(subTdb->settingsHash, "track", makeUniqueName(nameHash, subTdb->track));
         hashReplace(subTdb->settingsHash, "parent", trackHubSkipHubName(collectionName));
         }
     }
 else
     {
     hashReplace(newTdb->settingsHash, "track", makeUniqueName(nameHash, trackName));