public static MakeRelativePath ( string basePath, string absolutePath ) : string | ||
basePath | string | Contains the directory that defines the start of the relative path. |
absolutePath | string | Contains the path that defines the endpoint of the relative path. |
리턴 | string |
public override FileModel Load(FileAndType file, ImmutableDictionary <string, object> metadata) { if (file.Type != DocumentType.Article) { throw new NotSupportedException(); } var content = MarkdownReader.ReadMarkdownAsConceptual(file.BaseDir, file.File); foreach (var item in metadata) { if (!content.ContainsKey(item.Key)) { content[item.Key] = item.Value; } } var displayLocalPath = TypeForwardedToPathUtility.MakeRelativePath(EnvironmentContext.BaseDirectory, file.FullPath); return(new FileModel( file, content, serializer: Environment.Is64BitProcess?null: new BinaryFormatter()) { LocalPathFromRepoRoot = (content["source"] as SourceDetail)?.Remote?.RelativePath, LocalPathFromRoot = displayLocalPath }); }
private static ImmutableDictionary <string, object> ApplyFileMetadata( string file, ImmutableDictionary <string, object> metadata, FileMetadata fileMetadata) { if (fileMetadata == null || fileMetadata.Count == 0) { return(metadata); } var result = new Dictionary <string, object>(metadata); var baseDir = string.IsNullOrEmpty(fileMetadata.BaseDir) ? Directory.GetCurrentDirectory() : fileMetadata.BaseDir; var TypeForwardedToRelativePath = TypeForwardedToPathUtility.MakeRelativePath(baseDir, file); foreach (var item in fileMetadata) { // As the latter one overrides the former one, match the pattern from latter to former for (int i = item.Value.Length - 1; i >= 0; i--) { if (item.Value[i].Glob.Match(TypeForwardedToRelativePath)) { // override global metadata if metadata is defined in file metadata result[item.Value[i].Key] = item.Value[i].Value; Logger.LogVerbose($"{TypeForwardedToRelativePath} matches file metadata with glob pattern {item.Value[i].Glob.Raw} for property {item.Value[i].Key}"); break; } } } return(result.ToImmutableDictionary()); }
private IEnumerable <string> GetFiles(string directory, string searchPattern, int searchLevel) { if (searchLevel < 1) { return(Enumerable.Empty <string>()); } var files = Directory.GetFiles(directory, searchPattern, SearchOption.TopDirectoryOnly); var dirs = Directory.GetDirectories(directory); if (searchLevel == 1) { foreach (var dir in dirs) { var remainingFiles = Directory.GetFiles(dir, searchPattern, SearchOption.AllDirectories); if (remainingFiles.Length > 0) { throw new ResourceFileExceedsMaxDepthException(_maxDepth, TypeForwardedToPathUtility.MakeRelativePath(_directory, remainingFiles[0]), Name); } } return(files); } List <string> allFiles = new List <string>(files); foreach (var dir in dirs) { allFiles.AddRange(GetFiles(dir, searchPattern, searchLevel - 1)); } return(allFiles); }
private void WriteLine(ILogItem item) { if (item == null) { throw new ArgumentNullException(nameof(item)); } if (item.File == null) { return; } string fileFromWorkingDir = TypeForwardedToStringExtension.BackSlashToForwardSlash(item.File); if (!TypeForwardedToPathUtility.IsRelativePath(item.File)) { fileFromWorkingDir = TypeForwardedToPathUtility.MakeRelativePath(EnvironmentContext.BaseDirectory, item.File); } List <LogItem> logsPerFile; if (!_logs.TryGetValue(fileFromWorkingDir, out logsPerFile)) { logsPerFile = _logs[fileFromWorkingDir] = new List <LogItem>(); } logsPerFile.Add(new LogItem { File = TypeForwardedToStringExtension.BackSlashToForwardSlash(item.File), Line = item.Line, LogLevel = item.LogLevel, Message = item.Message, Phase = item.Phase, }); }
private static ChangeList ParseCore(string tsvFile, string baseDir) { var result = new ChangeList(); bool hasError = false; foreach (var line in File.ReadLines(tsvFile)) { if (string.IsNullOrWhiteSpace(line)) { continue; } var columns = line.Split('\t'); if (columns.Length >= 2) { if (string.Equals(columns[0], "<from>", StringComparison.OrdinalIgnoreCase)) { result.From = columns[1]; continue; } if (string.Equals(columns[0], "<to>", StringComparison.OrdinalIgnoreCase)) { result.To = columns[1]; continue; } string path; if (TypeForwardedToPathUtility.IsRelativePath(columns[0])) { path = columns[0]; } else { path = TypeForwardedToPathUtility.MakeRelativePath(baseDir, columns[0]); } if (path != null) { ChangeKind kind; if (Enum.TryParse(columns[1], true, out kind)) { if (kind != ChangeKind.Deleted) { if (!File.Exists(Path.Combine(baseDir, path))) { Logger.LogError($"File:{path} not existed."); hasError = true; continue; } } result.Add(path, kind); continue; } } } Logger.LogWarning($"Ignore unknown line: {line}"); } if (hasError) { throw new DocfxException($"Some error ocurred while parsing changelist file: {tsvFile}."); } return(result); }
private string TransformFile(string fileFromRoot) { if (fileFromRoot == null) { return(null); } string file = ((RelativePath)fileFromRoot).RemoveWorkingFolder(); string basePath = Path.GetFullPath(_repoRoot); string fullPath = Path.GetFullPath(Path.Combine(_root, file)); return(PathUtility.MakeRelativePath(basePath, fullPath)); }
public FileResourceCollection(string directory, int maxSearchLevel = MaxSearchLevel) { if (string.IsNullOrEmpty(directory)) { _directory = Directory.GetCurrentDirectory(); } else { _directory = directory; } Name = _directory; _maxDepth = maxSearchLevel; var includedFiles = GetFiles(_directory, "*", maxSearchLevel); Names = includedFiles.Select(s => TypeForwardedToPathUtility.MakeRelativePath(_directory, s)).Where(s => s != null); IsEmpty = !Names.Any(); }
public override FileModel Load(FileAndType file, ImmutableDictionary <string, object> metadata) { switch (file.Type) { case DocumentType.Article: var filePath = Path.Combine(file.BaseDir, file.File); var swaggerContent = File.ReadAllText(filePath); var swagger = SwaggerJsonParser.Parse(swaggerContent); swagger.Metadata[DocumentTypeKey] = RestApiDocumentType; swagger.Raw = swaggerContent; CheckOperationId(swagger, file.File); var repoInfo = GitUtility.GetGitDetail(filePath); if (repoInfo != null) { swagger.Metadata["source"] = new SourceDetail() { Remote = repoInfo }; } swagger.Metadata = MergeMetadata(swagger.Metadata, metadata); var vm = SwaggerModelConverter.FromSwaggerModel(swagger); var displayLocalPath = TypeForwardedToPathUtility.MakeRelativePath(EnvironmentContext.BaseDirectory, file.FullPath); return(new FileModel(file, vm, serializer: Environment.Is64BitProcess?null: new BinaryFormatter()) { Uids = new[] { new UidDefinition(vm.Uid, displayLocalPath) } .Concat(from item in vm.Children select new UidDefinition(item.Uid, displayLocalPath)) .Concat(from tag in vm.Tags select new UidDefinition(tag.Uid, displayLocalPath)).ToImmutableArray(), LocalPathFromRepoRoot = repoInfo?.RelativePath ?? TypeForwardedToStringExtension.ToDisplayPath(filePath), LocalPathFromRoot = displayLocalPath }); case DocumentType.Overwrite: // TODO: Refactor current behavior that overwrite file is read multiple times by multiple processors return(OverwriteDocumentReader.Read(file)); default: throw new NotSupportedException(); } }
public override FileModel Load(FileAndType file, ImmutableDictionary <string, object> metadata) { switch (file.Type) { case DocumentType.Article: var page = YamlUtility.Deserialize <PageViewModel>(Path.Combine(file.BaseDir, file.File)); if (page.Items == null || page.Items.Count == 0) { return(null); } if (page.Metadata == null) { page.Metadata = metadata.ToDictionary(p => p.Key, p => p.Value); } else { foreach (var item in metadata) { if (!page.Metadata.ContainsKey(item.Key)) { page.Metadata[item.Key] = item.Value; } } } var displayLocalPath = TypeForwardedToPathUtility.MakeRelativePath(EnvironmentContext.BaseDirectory, file.FullPath); return(new FileModel(file, page, serializer: Environment.Is64BitProcess?null: new BinaryFormatter()) { Uids = (from item in page.Items select new UidDefinition(item.Uid, displayLocalPath)).ToImmutableArray(), LocalPathFromRepoRoot = displayLocalPath, LocalPathFromRoot = displayLocalPath }); case DocumentType.Overwrite: // TODO: Refactor current behavior that overwrite file is read multiple times by multiple processors return(OverwriteDocumentReader.Read(file)); default: throw new NotSupportedException(); } }
public override FileModel Load(FileAndType file, ImmutableDictionary <string, object> metadata) { var filePath = file.FullPath; var tocViewModel = Utility.LoadSingleToc(filePath); var toc = new TocItemViewModel { Items = tocViewModel }; var repoDetail = GitUtility.GetGitDetail(filePath); var displayLocalPath = TypeForwardedToPathUtility.MakeRelativePath(EnvironmentContext.BaseDirectory, file.FullPath); // todo : metadata. return(new FileModel(file, toc) { Uids = new[] { new UidDefinition(file.File, displayLocalPath) }.ToImmutableArray(), LocalPathFromRepoRoot = repoDetail?.RelativePath ?? filePath, LocalPathFromRoot = displayLocalPath }); }
public override FileModel Load(FileAndType file, ImmutableDictionary <string, object> metadata) { string uid = null; Dictionary <string, object> content = null; var metafile = Path.Combine(file.BaseDir, file.File.TrimEnd('.') + ".meta"); if (File.Exists(metafile)) { content = YamlUtility.Deserialize <Dictionary <string, object> >(metafile); if (content != null) { foreach (var item in metadata) { if (!content.ContainsKey(item.Key)) { content[item.Key] = item.Value; } if (item.Key == Constants.PropertyName.Uid) { uid = item.Value as string; } } } } if (content == null) { content = metadata.ToDictionary(p => p.Key, p => p.Value); } var filePath = Path.Combine(file.BaseDir, file.File); var repoDetail = GitUtility.GetGitDetail(filePath); var displayLocalPath = TypeForwardedToPathUtility.MakeRelativePath(EnvironmentContext.BaseDirectory, file.FullPath); return(new FileModel(file, content) { Uids = string.IsNullOrEmpty(uid) ? ImmutableArray <UidDefinition> .Empty : ImmutableArray <UidDefinition> .Empty.Add(new UidDefinition(uid, displayLocalPath)), LocalPathFromRepoRoot = repoDetail?.RelativePath ?? TypeForwardedToStringExtension.ToDisplayPath(Path.Combine(file.BaseDir, file.File)), LocalPathFromRoot = displayLocalPath }); }
private string GenerateAzureLinkHref(IMarkdownContext context, string href, string rawMarkdown) { StringBuffer content = StringBuffer.Empty; // If the context doesn't have necessary info, return the original href if (!context.Variables.ContainsKey("path") || !context.Variables.ContainsKey("azureMarkdownFileInfoMapping")) { return(href); } // if the href is not relative path, return it if (!TypeForwardedToPathUtility.IsRelativePath(href)) { return(href); } // deal with bookmark. Get file name and anchor string hrefFileName = string.Empty; string anchor = string.Empty; var index = href.IndexOf('#'); if (index == -1) { hrefFileName = Path.GetFileName(href); } else if (index == 0) { return(href); } else { hrefFileName = Path.GetFileName(href.Remove(index)); anchor = href.Substring(index); } // deal with different kinds of relative paths var currentFilePath = (string)context.Variables["path"]; var azureMarkdownFileInfoMapping = (IReadOnlyDictionary <string, AzureFileInfo>)context.Variables["azureMarkdownFileInfoMapping"]; if (azureMarkdownFileInfoMapping == null || !azureMarkdownFileInfoMapping.ContainsKey(hrefFileName)) { Logger.LogWarning($"Can't fild reference file: {href} in azure file system for file {currentFilePath}. Raw: {rawMarkdown}"); return(href); } string azureHref = null; var hrefFileInfo = azureMarkdownFileInfoMapping[hrefFileName]; // Not in docsets and transform to azure external link if (hrefFileInfo.NeedTransformToAzureExternalLink) { azureHref = $"{hrefFileInfo.UriPrefix}/{Path.GetFileNameWithoutExtension(hrefFileName)}{anchor}"; } else { var hrefPath = hrefFileInfo.FilePath; // It is correct for Azure strucuture. Azure articles are all under same folder var isHrefInsameDocset = TypeForwardedToPathUtility.IsPathUnderSpecificFolder(hrefPath, Path.GetDirectoryName(currentFilePath)); // In same docset with current file, use relative path. Otherwise, use docset link prefix if (isHrefInsameDocset) { azureHref = string.Format("{0}{1}", TypeForwardedToPathUtility.MakeRelativePath(Path.GetDirectoryName(currentFilePath), hrefFileInfo.FilePath), anchor); } else { // If the file is in different docset, then append the absolute path prefix. .html should be remove as docs also don't need it now. azureHref = $"{hrefFileInfo.UriPrefix}/{Path.GetFileNameWithoutExtension(hrefFileName)}{anchor}"; } } return(azureHref); }
private string FixNonMdRelativeFileHref(string nonMdHref, IMarkdownContext context, string rawMarkdown) { // If the context doesn't have necessary info or nonMdHref is not a relative path, return the original href if (!context.Variables.ContainsKey("path") || !TypeForwardedToPathUtility.IsRelativePath(nonMdHref)) { return(nonMdHref); } var currentFilePath = (string)context.Variables["path"]; var currentFolderPath = Path.GetDirectoryName(currentFilePath); try { // if the relative path (not from azure resource file info mapping) is under docset. Just return it. var nonMdHrefFullPath = Path.GetFullPath(Path.Combine(currentFolderPath, nonMdHref)); if (TypeForwardedToPathUtility.IsPathUnderSpecificFolder(nonMdHrefFullPath, currentFolderPath)) { return(nonMdHref); } else { Logger.LogVerbose($"Relative path:{nonMdHref} is not under {currentFolderPath} of file {currentFilePath}. Use ex_resource to replace the link."); } // if azure resource file info doesn't exist, log warning and return if (!context.Variables.ContainsKey("azureResourceFileInfoMapping")) { Logger.LogWarning($"Can't find azure resource file info mapping. Couldn't fix href: {nonMdHref} in file {currentFilePath}. raw: {rawMarkdown}"); return(nonMdHref); } var nonMdHrefFileName = Path.GetFileName(nonMdHref); var azureResourceFileInfoMapping = (Dictionary <string, AzureFileInfo>)context.Variables["azureResourceFileInfoMapping"]; AzureFileInfo azureResourceFileInfo; if (!azureResourceFileInfoMapping.TryGetValue(nonMdHrefFileName, out azureResourceFileInfo)) { Logger.LogWarning($"Can't find info for file name {nonMdHrefFileName} in azure resource file info mapping. Couldn't fix href: {nonMdHref} in file {currentFilePath}. raw: {rawMarkdown}"); return(nonMdHref); } // If the nonMdHref is under same docset with current file. No need to fix that. if (TypeForwardedToPathUtility.IsPathUnderSpecificFolder(azureResourceFileInfo.FilePath, currentFolderPath)) { return(nonMdHref); } // If the nonMdHref is under different docset with current file but not exists. Then log warning and won't fix. if (!File.Exists(azureResourceFileInfo.FilePath)) { Logger.LogWarning($"{nonMdHref} refer by {currentFilePath} doesn't exists. Won't do link fix. raw: {rawMarkdown}"); return(nonMdHref); } // If the nonMdHref is under different docset with current file and also exists, then fix the link. // 1. copy the external file to ex_resource folder. 2. Return new href path to the file under external folder var exResourceDir = Directory.CreateDirectory(Path.Combine(currentFolderPath, ExternalResourceFolderName)); var resDestPath = Path.Combine(exResourceDir.FullName, Path.GetFileName(azureResourceFileInfo.FilePath)); File.Copy(azureResourceFileInfo.FilePath, resDestPath, true); return(TypeForwardedToPathUtility.MakeRelativePath(currentFolderPath, resDestPath)); } catch (NotSupportedException nse) { Logger.LogWarning($"Warning: FixNonMdRelativeFileHref can't be apply on reference: {nonMdHref}. Exception: {nse.Message}"); return(nonMdHref); } }
private static bool GenerateAzureFileInfoForMigration( string repositoryRoot, RewriterToolArguments rewriterToolArguments, string azureDocumentUriPrefix, AzureFileInformationCollection azureFileInformationCollection) { var azureMarkdownFileInfoMapping = new ConcurrentDictionary<string, AzureFileInfo>(); var azureResourceFileInfoMapping = new ConcurrentDictionary<string, AzureFileInfo>(); var azureIncludeMarkdownFileInfoMapping = new ConcurrentDictionary<string, AzureFileInfo>(); var azureIncludeResourceFileInfoMapping = new ConcurrentDictionary<string, AzureFileInfo>(); bool hasDupliateMdFileName = false; var files = Directory.GetFiles(repositoryRoot, "*", SearchOption.AllDirectories); Parallel.ForEach( files, new ParallelOptions { MaxDegreeOfParallelism = 8 }, file => { var relativePath = TypeForwardedToPathUtility.MakeRelativePath(repositoryRoot, file); if (IsIgnoreFile(relativePath, rewriterToolArguments.IsMigration)) { return; } var filePath = TypeForwardedToPathUtility.NormalizePath(file); var fileName = Path.GetFileName(file); var azureFileInfo = new AzureFileInfo { FileName = fileName, FilePath = TypeForwardedToPathUtility.NormalizePath(file), NeedTransformToAzureExternalLink = false, UriPrefix = string.Empty }; var isIncludeFile = filePath.Split(new[] { Path.AltDirectorySeparatorChar }, StringSplitOptions.RemoveEmptyEntries) .Any(folder => folder.Equals("includes", StringComparison.OrdinalIgnoreCase)); var isMarkdownFile = Path.GetExtension(relativePath).Equals(MarkdownExtension, StringComparison.OrdinalIgnoreCase); AzureFileInfo conflictFile = null; var isSucceed = true; if (!isIncludeFile && isMarkdownFile) { isSucceed = azureMarkdownFileInfoMapping.TryAdd(fileName, azureFileInfo); azureMarkdownFileInfoMapping.TryGetValue(fileName, out conflictFile); } else if (!isIncludeFile && !isMarkdownFile) { // For resource file, even if has conflicts, we regards that as succeed azureResourceFileInfoMapping.TryAdd(fileName, azureFileInfo); } else if (isIncludeFile && isMarkdownFile) { isSucceed = azureIncludeMarkdownFileInfoMapping.TryAdd(fileName, azureFileInfo); azureIncludeMarkdownFileInfoMapping.TryGetValue(fileName, out conflictFile); } else { // For resource file, even if has conflicts, we regards that as succeed azureIncludeResourceFileInfoMapping.TryAdd(fileName, azureFileInfo); } if (!isSucceed) { hasDupliateMdFileName = true; Logger.LogError($"Error: GenerateAzureFileInfo failed. File: {file} name confilicts with: {conflictFile?.FilePath}"); } }); azureFileInformationCollection.AzureMarkdownFileInfoMapping = azureMarkdownFileInfoMapping.ToDictionary(m => m.Key, m => m.Value); azureFileInformationCollection.AzureResourceFileInfoMapping = azureResourceFileInfoMapping.ToDictionary(m => m.Key, m => m.Value); azureFileInformationCollection.AzureIncludeMarkdownFileInfoMapping = azureIncludeMarkdownFileInfoMapping.ToDictionary(m => m.Key, m => m.Value); azureFileInformationCollection.AzureIncludeResourceFileInfoMapping = azureIncludeResourceFileInfoMapping.ToDictionary(m => m.Key, m => m.Value); return !hasDupliateMdFileName; }
public Manifest Process(Manifest manifest, string outputFolder) { if (outputFolder == null) { throw new ArgumentNullException("Base directory can not be null"); } var indexData = new Dictionary <string, SearchIndexItem>(); var indexDataFilePath = Path.Combine(outputFolder, IndexFileName); var htmlFiles = (from item in manifest.Files ?? Enumerable.Empty <ManifestItem>() from output in item.OutputFiles where output.Key.Equals(".html", StringComparison.OrdinalIgnoreCase) select output.Value.RelativePath).ToList(); if (htmlFiles.Count == 0) { return(manifest); } Logger.LogInfo($"Extracting index data from {htmlFiles.Count} html files"); foreach (var relativePath in htmlFiles) { var filePath = Path.Combine(outputFolder, relativePath); var html = new HtmlDocument(); Logger.LogVerbose($"Extracting index data from {filePath}"); if (File.Exists(filePath)) { try { html.Load(filePath, Encoding.UTF8); } catch (Exception ex) { Logger.LogWarning($"Warning: Can't load content from {filePath}: {ex.Message}"); continue; } var indexItem = ExtractItem(html, relativePath); if (indexItem != null) { indexData[relativePath] = indexItem; } } } JsonUtility.Serialize(indexDataFilePath, indexData, Formatting.Indented); // add index.json to mainfest as resource file var manifestItem = new ManifestItem { DocumentType = "Resource", Metadata = new Dictionary <string, object>(), OutputFiles = new Dictionary <string, OutputFileInfo>() }; manifestItem.OutputFiles.Add("resource", new OutputFileInfo { RelativePath = TypeForwardedToPathUtility.MakeRelativePath(outputFolder, indexDataFilePath), }); manifest.Files?.Add(manifestItem); return(manifest); }
private string GenerateAzureLinkHref(IMarkdownContext context, string href, string rawMarkdown, string line) { if (string.IsNullOrEmpty(href)) { return(string.Empty); } StringBuffer content = StringBuffer.Empty; // If the context doesn't have necessary info, return the original href if (!context.Variables.ContainsKey("path") || !context.Variables.ContainsKey("azureMarkdownFileInfoMapping")) { return(href); } // if the href is not relative path, return it. Add try catch to keep this method safe. try { if (!TypeForwardedToPathUtility.IsRelativePath(href)) { return(href); } } catch (ArgumentException) { Logger.LogWarning($"Invalid reference {href} in file: {(string)context.Variables["path"]}. Raw: {rawMarkdown}", null, (string)context.Variables["path"], line); return(href); } // deal with bookmark. Get file name and anchor string hrefFileName = string.Empty; string anchor = string.Empty; var index = href.IndexOf('#'); if (index == -1) { hrefFileName = Path.GetFileName(href); } else if (index == 0) { return(href); } else { hrefFileName = Path.GetFileName(href.Remove(index)); anchor = href.Substring(index); } // deal with different kinds of relative paths var currentFilePath = (string)context.Variables["path"]; var azureMarkdownFileInfoMapping = (IReadOnlyDictionary <string, AzureFileInfo>)context.Variables["azureMarkdownFileInfoMapping"]; if (azureMarkdownFileInfoMapping == null || !azureMarkdownFileInfoMapping.ContainsKey(hrefFileName)) { Logger.LogWarning($"Can't find markdown reference: {href}. Raw: {rawMarkdown}.", null, currentFilePath, line); return(href); } string azureHref = null; var hrefFileInfo = azureMarkdownFileInfoMapping[hrefFileName]; azureHref = string.Format("{0}{1}", TypeForwardedToPathUtility.MakeRelativePath(Path.GetDirectoryName(currentFilePath), hrefFileInfo.FilePath), anchor); return(azureHref); }
private static bool GenerateAzureFileInfo( string repositoryRoot, RewriterToolArguments rewriterToolArguments, string azureDocumentUriPrefix, AzureFileInformationCollection azureFileInformationCollection) { var azureMarkdownFileInfoMapping = new ConcurrentDictionary<string, AzureFileInfo>(); var azureResourceFileInfoMapping = new ConcurrentDictionary<string, AzureFileInfo>(); var files = Directory.GetFiles(repositoryRoot, "*", SearchOption.AllDirectories); Parallel.ForEach( files, new ParallelOptions { MaxDegreeOfParallelism = 8 }, file => { var relativePath = TypeForwardedToPathUtility.MakeRelativePath(repositoryRoot, file); if (IsIgnoreFile(relativePath, rewriterToolArguments.IsMigration)) { return; } var isSucceed = true; var azureTransformArguments = rewriterToolArguments.AzureTransformArgumentsList.FirstOrDefault(a => TypeForwardedToPathUtility.IsPathUnderSpecificFolder(file, a.SourceDir)); // By default, all the link should be transformed to external link with azure uri prefix // However, if we find that the file is under one of the folder that need to be transformed. Then the prefix uri should be docs but not auzre var needTransformToAzureExternalLink = true; var uriPrefix = azureDocumentUriPrefix; if (azureTransformArguments != null) { needTransformToAzureExternalLink = false; uriPrefix = azureTransformArguments.DocsHostUriPrefix; } var fileName = Path.GetFileName(file); var azureFileInfo = new AzureFileInfo { FileName = fileName, FilePath = TypeForwardedToPathUtility.NormalizePath(file), NeedTransformToAzureExternalLink = needTransformToAzureExternalLink, UriPrefix = uriPrefix }; AzureFileInfo conflictFile; var isMarkdownFile = Path.GetExtension(relativePath).Equals(MarkdownExtension, StringComparison.OrdinalIgnoreCase); if (isMarkdownFile) { isSucceed = azureMarkdownFileInfoMapping.TryAdd(fileName, azureFileInfo); azureMarkdownFileInfoMapping.TryGetValue(fileName, out conflictFile); } else { isSucceed = azureResourceFileInfoMapping.TryAdd(fileName, azureFileInfo); azureResourceFileInfoMapping.TryGetValue(fileName, out conflictFile); } if (!isSucceed) { Console.WriteLine($"GenerateAzureFileInfo warning: can't insert file: {file}, confilicts with: {conflictFile?.FilePath}"); } }); azureFileInformationCollection.AzureMarkdownFileInfoMapping = azureMarkdownFileInfoMapping.ToDictionary(m => m.Key, m => m.Value); azureFileInformationCollection.AzureResourceFileInfoMapping = azureResourceFileInfoMapping.ToDictionary(m => m.Key, m => m.Value); return true; }