be4311c07e14feb728abc6425ee606ffaa611a58
markd
  Fri Jan 22 06:46:58 2021 -0800
merge with master

diff --git src/hg/lib/trackDbCustom.c src/hg/lib/trackDbCustom.c
index 085790e..c7ce5ee 100644
--- src/hg/lib/trackDbCustom.c
+++ src/hg/lib/trackDbCustom.c
@@ -288,33 +288,34 @@
 char *file;
 
 if (startsWith("include", line))
     {
     splitPath(raFile, incFile, NULL, NULL);
     nextWord(&line);
     file = nextQuotedWord(&line);
     strcat(incFile, file);
     *releaseTag = nextWord(&line);
     return cloneString(incFile);
     }
 else
     return NULL;
 }
 
-struct trackDb *trackDbFromOpenRa(struct lineFile *lf, char *releaseTag)
+struct trackDb *trackDbFromOpenRa(struct lineFile *lf, char *releaseTag, struct dyString *incFiles)
 /* Load track info from ra file already opened as lineFile into list.  If releaseTag is
- * non-NULL then only load tracks that mesh with release. */
+ * non-NULL then only load tracks that mesh with release. If incFiles is not-NULL, put
+ * list of included files in there. */
 {
 char *raFile = lf->fileName;
 char *line, *word;
 struct trackDb *btList = NULL, *bt;
 boolean done = FALSE;
 char *incFile;
 
 for (;;)
     {
     /* Seek to next line that starts with 'track' */
     for (;;)
         {
         char *subRelease;
 
         if (!lineFileNextFull(lf, &line, NULL, NULL, NULL))
@@ -322,32 +323,34 @@
             done = TRUE;
 	   break;
 	   }
 	line = skipLeadingSpaces(line);
         if (startsWithWord("track", line))
             {
             lineFileReuseFull(lf); // NOTE: only works with previous lineFileNextFull call
             break;
             }
         else if ((incFile = trackDbInclude(raFile, line, &subRelease)) != NULL)
             {
             if (subRelease)
                 trackDbCheckValidRelease(subRelease);
             if (releaseTag && subRelease && !sameString(subRelease, releaseTag))
                 errAbort("Include with release %s inside include with release %s line %d of %s", subRelease, releaseTag, lf->lineIx, lf->fileName);
-            struct trackDb *incTdb = trackDbFromRa(incFile, subRelease);
+            struct trackDb *incTdb = trackDbFromRa(incFile, subRelease, incFiles);
             btList = slCat(btList, incTdb);
+            if (incFiles)
+                dyStringPrintf(incFiles, "%s\n", incFile);
             }
 	}
     if (done)
         break;
 
     /* Allocate track structure and fill it in until next blank line. */
     bt = trackDbNew();
     slAddHead(&btList, bt);
     for (;;)
         {
         /* Break at blank line or EOF. */
         if (!lineFileNextFull(lf, &line, NULL, NULL, NULL))  // NOTE: joins continuation lines
             break;
         line = skipLeadingSpaces(line);
         if (line == NULL || line[0] == 0)
@@ -385,36 +388,37 @@
 char *words[5];
 
 int count = chopString(cloneString(tag), ",", words, ArraySize(words));
 if (count > 3)
     return FALSE;
 
 int ii;
 for(ii=0; ii < count; ii++)
     if (!sameString(words[ii], "alpha") && !sameString(words[ii], "beta") &&
         !sameString(words[ii], "public"))
             return FALSE;
 
 return TRUE;
 }
 
-struct trackDb *trackDbFromRa(char *raFile, char *releaseTag)
+struct trackDb *trackDbFromRa(char *raFile, char *releaseTag, struct dyString *incFiles)
 /* Load track info from ra file into list.  If releaseTag is non-NULL
- * then only load tracks that mesh with release. */
+ * then only load tracks that mesh with release. if incFiles is non-null, 
+ * add included file names to it.*/
 {
 struct lineFile *lf = udcWrapShortLineFile(raFile, NULL, 16*1024*1024);
-struct trackDb *tdbList = trackDbFromOpenRa(lf, releaseTag);
+struct trackDb *tdbList = trackDbFromOpenRa(lf, releaseTag, incFiles);
 lineFileClose(&lf);
 return tdbList;
 }
 
 struct hash *trackDbHashSettings(struct trackDb *tdb)
 /* Force trackDb to hash up it's settings.  Usually this is just
  * done on demand. Returns settings hash. */
 {
 if (tdb->settingsHash == NULL)
     tdb->settingsHash = trackDbSettingsFromString(tdb, tdb->settings);
 return tdb->settingsHash;
 }
 
 struct hash *trackDbSettingsFromString(struct trackDb *tdb, char *string)
 /* Return hash of key/value pairs from string.  Differs
@@ -1555,30 +1559,42 @@
     if (tabSepMeta)
         return tabSepMetaPairs(tabSepMeta, tdb, metaTag);
 
     char *tagStormFile = trackDbSetting(tdb, "metaDb");
     if (tagStormFile)
         return tagRepoPairs(tagStormFile, "meta", metaTag);
     }
 
 char *metadataInTdb = trackDbSetting(tdb, "metadata");
 if (metadataInTdb)
     return convertNameValueString(metadataInTdb);
 
 return NULL;
 }
 
+boolean trackSettingIsFile(char *setting)
+/* Returns TRUE if setting found in trackDb stanza is a file setting that
+ * would benefit from directory $D substitution among other things - looks for
+ * settings that ends in "Url" and a few others. */
+{
+return endsWith(setting, "Url") ||
+    sameString(setting, "bigDataIndex") ||
+    sameString(setting, "frames") ||
+    sameString(setting, "summary") ||
+    sameString(setting, "searchTrix");
+}
+
 char *labelAsFilteredNumber(char *label, unsigned numOut)
 /* add text to label to indicate filter is active */
 {
 char buffer[2048];
 safef(buffer, sizeof buffer, " (%d items filtered)", numOut);
 return catTwoStrings(label, buffer);
 }
 
 char *labelAsFiltered(char *label)
 /* add text to label to indicate filter is active */
 {
 #define FILTER_ACTIVATED " (filter activated)"
 if (stringIn(FILTER_ACTIVATED, label))
     return label;
 return (catTwoStrings(label, FILTER_ACTIVATED));