1b6caec24e9f9acb5aa00306e6019787856a5b33
hiram
  Thu Sep 17 12:17:08 2026 -0700
special case genark hub attach when on hgwdev - use the alpha.hub.txt instead of the hub.txt refs #35415

diff --git src/hg/hgGateway/hgGateway.c src/hg/hgGateway/hgGateway.c
index 3331582b0fc..866bf218411 100644
--- src/hg/hgGateway/hgGateway.c
+++ src/hg/hgGateway/hgGateway.c
@@ -1024,44 +1024,57 @@
     jsonWriteString(jw, "db", gHubMatch->asmName);
     jsonWriteString(jw, "hubUrl", gHubMatch->hubUrl);
     jsonWriteString(jw, "scientificName", gHubMatch->scientificName);
     // Add a category label for customized autocomplete-with-categories.
     jsonWriteString(jw, "category", "UCSC GenArk - bulk-annotated assemblies from NCBI Genbank/RefSeq");
     jsonWriteString(jw, "value", gHubMatch->asmName);
     // Use just the db as label, since shortLabel is included in the category label.
     jsonWriteStringf(jw, "label", "%s - %s (%s)", comBold, sciBold, gcxBold);
     jsonWriteObjectEnd(jw);
     }
 }
 
 /* maximum limit of how many matches to display from genark */
 #define GENARK_LIMIT 20
 
+static char *devAlphaHubTxt(char *hubUrl)
+/* On hgwdev, genome-test and hgwdev sandboxes, GenArk hubs are staged under
+ * alpha.hub.txt instead of hub.txt.  On those hosts, swap the trailing
+ * hub.txt for alpha.hub.txt; otherwise return an unchanged copy.
+ * Result is always newly allocated; free when done. */
+{
+if (hIsPrivateHost())
+    return replaceChars(hubUrl, "hub.txt", "alpha.hub.txt");
+return cloneString(hubUrl);
+}
+
 static struct gHubMatch *filterGenarkMatches(char *genarkHubUrl, struct genark *matchList)
 /* Turn the sql results into a struct gHubMatch list */
 {
 struct genark *match;
 struct gHubMatch *ret = NULL;
 
 int c = 0;
 for (match = matchList; match != NULL; match = match->next)
     {
     ++c;
     // the match contains tab-sep accession, hubUrl, asmName, scientificName, commonName
     char hubUrl[PATH_LEN+1];
     safef(hubUrl, sizeof(hubUrl), "%s/%s", genarkHubUrl, match->hubUrl);
-    slAddHead(&ret, gHubMatchNew(match->gcAccession, hubUrl, match->asmName, match->scientificName, match->commonName, -1));
+    char *finalHubUrl = devAlphaHubTxt(hubUrl);
+    slAddHead(&ret, gHubMatchNew(match->gcAccession, finalHubUrl, match->asmName, match->scientificName, match->commonName, -1));
+    freeMem(finalHubUrl);
     if (c > GENARK_LIMIT)
 	break;
     }
 if (ret)
     slReverse(&ret);
 return ret;
 }
 
 static struct gHubMatch *filterAssemblyListMatches(struct sqlConnection *conn,
    struct dbDb *dbDbList, struct dbDbMatch **dbDbMatchList, char *asmListTable, char *term, char *genarkPrefix, boolean wildCard)
 {
 struct gHubMatch *ret = NULL;
 struct dyString *query = dyStringNew(64);
 /* LIMIT of 100 will allow enough results to include some genArk assemblies */
 if (wildCard)
@@ -1069,31 +1082,33 @@
 else
     sqlDyStringPrintf(query, "SELECT * FROM %s WHERE MATCH(name, commonName, scientificName, clade, description, refSeqCategory, versionStatus, assemblyLevel) AGAINST ('%s' IN BOOLEAN MODE) AND browserExists=1 ORDER BY priority LIMIT 100", asmListTable, term);
 
 struct sqlResult *sr = sqlGetResult(conn, query->string);
 dyStringFree(&query);
 char **row;
 int c = 0;
 while ((row = sqlNextRow(sr)) != NULL)
     {
     struct assemblyList *el = assemblyListLoadWithNull(row);
     if (isGenArk(el->name))
 	{
 	++c;
 	char genarkUrl[PATH_MAX];
 	safef(genarkUrl, sizeof(genarkUrl), "%s/%s", genarkPrefix, el->hubUrl);
-	slAddHead(&ret, gHubMatchNew(el->name, genarkUrl, NULL, el->scientificName, el->commonName, *el->priority));
+	char *finalHubUrl = devAlphaHubTxt(genarkUrl);
+	slAddHead(&ret, gHubMatchNew(el->name, finalHubUrl, NULL, el->scientificName, el->commonName, *el->priority));
+	freeMem(finalHubUrl);
 	}
 	else
 	{
         struct dbDb *dbDb;
         for (dbDb = dbDbList;  dbDb != NULL; dbDb = dbDb->next)
 	    {
             if (sameWord(dbDb->name, el->name))
 		{
 		// Make uppercase version of target for case-insensitive matching.
 		int targetLen = strlen(el->name);
 		char targetUpcase[targetLen + 1];
 		safencpy(targetUpcase, sizeof(targetUpcase), el->name, targetLen);
 		touppers(targetUpcase);
                 struct dbDbMatch *extraList = searchDbDb(dbDbList, targetUpcase);
 		struct dbDbMatch *match;