/// <summary>
        /// Gets an instance of <see cref="ICacheConfigData"/> from cache configuration.
        /// </summary>
        internal static Possible <ICacheConfigData> TryGetCacheConfigData(
            PathTable pathTable,
            string cacheDirectory,
            ICacheConfiguration config,
            RootTranslator rootTranslator = null)
        {
            Contract.Requires(pathTable != null);
            Contract.Requires(pathTable.IsValid);
            Contract.Requires(config != null);
            Contract.Requires(config.CacheLogFilePath.IsValid);
            Contract.Requires(config.CacheConfigFile.IsValid);
            Contract.Requires(!string.IsNullOrWhiteSpace(cacheDirectory));

            Possible <string> maybeConfigData = TryReadCacheConfigFile(config.CacheConfigFile.ToString(pathTable));

            if (!maybeConfigData.Succeeded)
            {
                return(maybeConfigData.Failure);
            }

            // Update the cache config to dynamically set the cache path if it is configured to use the per-invocation path.
            // TODO: Ideally this would be exposed as config constructor parameters to BuildXL to not require manipulating the json config.
            //       But for now we just modify the config text before passing it along to the cache.
            string cacheConfigContent = maybeConfigData.Result;

            cacheConfigContent = cacheConfigContent.Replace("[DominoSelectedLogPath]", config.CacheLogFilePath.ToString(pathTable).Replace(@"\", @"\\"));  // Escape path separation chars to json format
            cacheConfigContent = cacheConfigContent.Replace("[BuildXLSelectedLogPath]", config.CacheLogFilePath.ToString(pathTable).Replace(@"\", @"\\")); // Escape path separation chars to json format
            cacheConfigContent = cacheConfigContent.Replace("[DominoSelectedRootPath]", cacheDirectory.Replace(@"\", @"\\"));
            cacheConfigContent = cacheConfigContent.Replace("[BuildXLSelectedRootPath]", cacheDirectory.Replace(@"\", @"\\"));
            cacheConfigContent = cacheConfigContent.Replace("[UseDedupStore]", config.UseDedupStore.ToString());
            cacheConfigContent = cacheConfigContent.Replace("[ReplaceExistingFileOnMaterialization]", config.ReplaceExistingFileOnMaterialization.ToString());

            var vfsCasRoot = config.VfsCasRoot.IsValid
                ? config.VfsCasRoot.ToString(pathTable)
                : "";

            if (rootTranslator != null && !string.IsNullOrEmpty(vfsCasRoot))
            {
                // VFS needs real path so use root translator to resolve to real path.
                vfsCasRoot = rootTranslator.Translate(vfsCasRoot);
            }

            // Escape path separation chars to json format
            vfsCasRoot = vfsCasRoot.Replace(@"\", @"\\");

            cacheConfigContent = cacheConfigContent.Replace("[VfsCasRoot]", vfsCasRoot);

            ICacheConfigData cacheConfigData;
            Exception        exception;

            if (!CacheFactory.TryCreateCacheConfigData(cacheConfigContent, out cacheConfigData, out exception))
            {
                return(new Failure <string>(I($"Unable to create cache config data: {exception.GetLogEventMessage()}")));
            }

            return(new Possible <ICacheConfigData>(cacheConfigData));
        }
Exemple #2
0
        /// <summary>
        /// Gets the expanded path for the cache to use when putting/placing file. This allows
        /// the cache to pick a correct CAS root if CAS roots exist on various drives which
        /// would allow it to use a hardlink rather than copy if the appropriate CAS root is chosen.
        /// </summary>
        public string GetExpandedPathForCache(ExpandedAbsolutePath path)
        {
            if (m_rootTranslator == null)
            {
                return(path.ExpandedPath);
            }
            else
            {
                var translatedPath = m_rootTranslator.Translate(path.ExpandedPath);
                if (translatedPath[0].ToUpperInvariantFast() == path.ExpandedPath[0].ToUpperInvariantFast() &&
                    translatedPath.Length > path.ExpandedPath.Length)
                {
                    // The path root did not change as a result of path translation and its longer
                    // so , just return the original path since the cache only cares about the root
                    // when deciding a particular CAS to hardlink from to avoid MAX_PATH issues
                    return(path.ExpandedPath);
                }

                return(translatedPath);
            }
        }
        private void TestRootTranslation(string path, string expectedPath)
        {
            var translatedPath = m_translator.Translate(path);

            Assert.Equal(expectedPath, translatedPath);
        }