public static OrgsMappingFile ConvertYamls(string sourceRootDir, OrgsMappingFile orgsMappingFile) { if (!Directory.Exists(sourceRootDir)) { throw new ArgumentException($"{nameof(sourceRootDir)} '{sourceRootDir}' should exist."); } Guard.ArgumentNotNull(orgsMappingFile, nameof(orgsMappingFile)); foreach (var orgInfo in orgsMappingFile.OrgInfos) { foreach (var service in orgInfo.Services) { if (service.SwaggerInfo != null) { foreach (var swagger in service.SwaggerInfo) { var sourceFile = Path.Combine(sourceRootDir, swagger.Source.TrimEnd()); if (Path.GetExtension(sourceFile) == ".yaml") { ConvertYamlToJson(sourceFile, Path.ChangeExtension(sourceFile, ".json")); swagger.Source = Path.ChangeExtension(swagger.Source, ".json"); } } } } } return(orgsMappingFile); }
private static void SortOrgsMappingFile(OrgsMappingFile orgsMappingFile) { orgsMappingFile.OrgInfos.Sort((x, y) => string.CompareOrdinal(x.OrgName, y.OrgName)); foreach (var orgInfo in orgsMappingFile.OrgInfos) { orgInfo.Services.Sort((x, y) => string.CompareOrdinal(x.TocTitle, y.TocTitle)); } }
private void GenerateAutoPage(string targetRootDir, OrgsMappingFile orgsMappingFile) { if (orgsMappingFile.ApisPageOptions == null || !orgsMappingFile.ApisPageOptions.EnableAutoGenerate) { return; } var targetIndexPath = Path.Combine(targetRootDir, orgsMappingFile.ApisPageOptions.TargetFile); if (File.Exists(targetIndexPath)) { Console.WriteLine($"Cleaning up previous existing {targetIndexPath}."); File.Delete(targetIndexPath); } using (var writer = new StreamWriter(targetIndexPath)) { var summaryFile = Path.Combine(targetRootDir, orgsMappingFile.ApisPageOptions.SummaryFile); if (File.Exists(summaryFile)) { foreach (var line in File.ReadAllLines(summaryFile)) { writer.WriteLine(line); } writer.WriteLine(); } writer.WriteLine("## All Product APIs"); foreach (var orgInfo in orgsMappingFile.OrgInfos) { // Org name as title if (!string.IsNullOrWhiteSpace(orgInfo.OrgName)) { writer.WriteLine($"### {orgInfo.OrgName}"); writer.WriteLine(); } // Service table if (orgInfo.Services.Count > 0) { writer.WriteLine("| Service | Description |"); writer.WriteLine("|---------|-------------|"); foreach (var service in orgInfo.Services) { if (string.IsNullOrWhiteSpace(service.IndexFile) && !File.Exists(service.IndexFile)) { throw new InvalidOperationException($"Index file {service.IndexFile} of service {service.TocTitle} should exists."); } var summary = Utility.GetYamlHeaderByMeta(Path.Combine(targetRootDir, service.IndexFile), orgsMappingFile.ApisPageOptions.ServiceDescriptionMetadata); writer.WriteLine($"| [{service.TocTitle}](~/{service.IndexFile}) | {summary ?? string.Empty} |"); } writer.WriteLine(); } } } }
public RestSplitter(string sourceRootDir, string targetRootDir, OrgsMappingFile mappingFile, string outputDir) { Guard.ArgumentNotNullOrEmpty(sourceRootDir, nameof(sourceRootDir)); Guard.ArgumentNotNullOrEmpty(targetRootDir, nameof(targetRootDir)); Guard.ArgumentNotNull(mappingFile, nameof(mappingFile)); Guard.ArgumentNotNullOrEmpty(outputDir, nameof(outputDir)); _sourceRootDir = sourceRootDir; _targetRootDir = targetRootDir; _mappingFile = mappingFile; _outputDir = outputDir; _restFileInfos = new List <RestFileInfo>(); }
protected BaseGenerator(JObject rootJObj, string targetDir, string filePath, OrgsMappingFile orgsMappingFile, IDictionary <string, int> lineNumberMappingDict, RepoFile repoFile, string swaggerRelativePath, string version) { Guard.ArgumentNotNull(rootJObj, nameof(rootJObj)); Guard.ArgumentNotNullOrEmpty(targetDir, nameof(targetDir)); Guard.ArgumentNotNullOrEmpty(filePath, nameof(filePath)); Guard.ArgumentNotNull(orgsMappingFile, nameof(orgsMappingFile)); RootJObj = rootJObj; TargetDir = targetDir; FilePath = filePath; OrgsMappingFile = orgsMappingFile; LineNumberMappingDict = lineNumberMappingDict; RepoFile = repoFile; SwaggerRelativePath = swaggerRelativePath; Version = version; }
public static RestFileInfo Split(string targetDir, string filePath, string swaggerRelativePath, string serviceId, string serviceName, string subGroupName, OperationGroupMapping operationGroupMapping, OrgsMappingFile orgsMappingFile, RepoFile repoFile, string version) { if (!Directory.Exists(targetDir)) { throw new ArgumentException($"{nameof(targetDir)} '{targetDir}' should exist."); } if (!File.Exists(filePath)) { throw new ArgumentException($"{nameof(filePath)} '{filePath}' should exist."); } var sourceSwaggerFilePath = Utility.GetSourceSwaggerFilePath(filePath); IDictionary <string, int> lineNumberMappingDict = new Dictionary <string, int>(); using (var streamReader = File.OpenText(sourceSwaggerFilePath)) { using (var reader = new JsonTextReader(streamReader)) { var rootJObj = JObject.Load(reader); lineNumberMappingDict = GetLineNumberMappingInfo(rootJObj); } } var restFileInfo = new RestFileInfo(); using (var streamReader = File.OpenText(filePath)) { using (var reader = new JsonTextReader(streamReader)) { reader.DateParseHandling = DateParseHandling.None; var rootJObj = JObject.Load(reader); // Resolve $ref with json file instead of definition reference in the same swagger var refResolver = new RefResolver(rootJObj, filePath); refResolver.Resolve(); if (orgsMappingFile.NeedResolveXMsPaths) { var xMsPathsResolver = new XMsPathsResolver(rootJObj); xMsPathsResolver.Resolve(); } rootJObj["x-internal-service-id"] = serviceId; rootJObj["x-internal-service-name"] = serviceName; rootJObj["x-internal-sub-group-name"] = subGroupName; var generator = GeneratorFactory.CreateGenerator(rootJObj, targetDir, filePath, operationGroupMapping, orgsMappingFile, lineNumberMappingDict, repoFile, swaggerRelativePath, version); var fileNameInfos = generator.Generate().ToList(); if (fileNameInfos.Any()) { restFileInfo.FileNameInfos = fileNameInfos; } restFileInfo.TocTitle = GetInfoTitle(rootJObj); } } return(restFileInfo); }
public TagsGenerator(JObject rootJObj, string targetDir, string filePath, OperationGroupMapping operationGroupMapping, OrgsMappingFile orgsMappingFile, IDictionary <string, int> lineNumberMappingDict, RepoFile repoFile, string swaggerRelativePath, string version) : base(rootJObj, targetDir, filePath, orgsMappingFile, lineNumberMappingDict, repoFile, swaggerRelativePath, version) { OperationGroupMapping = operationGroupMapping; }
public static IList <RestFileInfo> RestSpliter(string sourceRootDir, string targetRootDir, OrgsMappingFile mappingFile, string outputDir) { if (!Directory.Exists(sourceRootDir)) { throw new ArgumentException($"{nameof(sourceRootDir)} '{sourceRootDir}' should exist."); } if (string.IsNullOrEmpty(targetRootDir)) { throw new ArgumentException($"{nameof(targetRootDir)} should not be null or empty."); } if (string.IsNullOrEmpty(outputDir)) { throw new ArgumentException($"{nameof(outputDir)} should not be null or empty."); } var splitter = new RestSplitter(sourceRootDir, targetRootDir, mappingFile, outputDir); var restFileInfos = splitter.Process(); Console.WriteLine("Done processing all swagger files"); return(restFileInfos); }
private static SortedDictionary <string, List <SwaggerToc> > SplitSwaggers(string sourceRootDir, string targetApiVersionDir, ServiceInfo service, OrgsMappingFile orgsMappingFile, RepoFile repoFile, string version, string lineNumberMappingFilePath) { var subTocDict = new SortedDictionary <string, List <SwaggerToc> >(); foreach (var swagger in service.SwaggerInfo) { var subGroupName = swagger.SubGroupTocTitle ?? string.Empty; var targetDir = FileUtility.CreateDirectoryIfNotExist(Path.Combine(targetApiVersionDir, service.UrlGroup, subGroupName.TrimSubGroupName())); var sourceFile = Path.Combine(sourceRootDir, swagger.Source.TrimEnd()); var restFileInfo = RestSplitHelper.Split(targetDir, sourceFile, swagger.Source.TrimEnd(), orgsMappingFile.UseServiceUrlGroup ? service.UrlGroup : service.TocTitle, service.TocTitle, swagger.OperationGroupMapping, orgsMappingFile, repoFile, version); var sourceSwaggerMappingDict = new Dictionary <string, string>(); if (restFileInfo == null) { continue; } _restFileInfos.Add(restFileInfo); var tocTitle = Utility.ExtractPascalNameByRegex(restFileInfo.TocTitle, orgsMappingFile.NoSplitWords); List <SwaggerToc> subTocList; if (!subTocDict.TryGetValue(subGroupName, out subTocList)) { subTocList = new List <SwaggerToc>(); subTocDict.Add(subGroupName, subTocList); } foreach (var fileNameInfo in restFileInfo.FileNameInfos) { var subTocTitle = fileNameInfo.TocName; var filePath = FileUtility.NormalizePath(Path.Combine(service.UrlGroup, subGroupName.TrimSubGroupName(), fileNameInfo.FileName)); if (subTocList.Any(toc => toc.Title == subTocTitle)) { throw new InvalidOperationException($"Sub toc '{subTocTitle}' under '{tocTitle}' has been added into toc.md, please add operation group name mapping for file '{swagger.Source}' to avoid conflicting"); } var childrenToc = new List <SwaggerToc>(); if (fileNameInfo.ChildrenFileNameInfo != null && fileNameInfo.ChildrenFileNameInfo.Count > 0) { foreach (var nameInfo in fileNameInfo.ChildrenFileNameInfo) { childrenToc.Add(new SwaggerToc(nameInfo.TocName, FileUtility.NormalizePath(Path.Combine(service.UrlGroup, subGroupName.TrimSubGroupName(), nameInfo.FileName)))); var normalizedFileName = FileUtility.NormalizePath(nameInfo.FileName); // Write into ref mapping dict if (!sourceSwaggerMappingDict.ContainsKey(normalizedFileName)) { sourceSwaggerMappingDict.Add(normalizedFileName, nameInfo.SwaggerSourceUrl); } } } subTocList.Add(new SwaggerToc(subTocTitle, filePath, childrenToc)); } Console.WriteLine($"Done splitting swagger file from '{swagger.Source}' to '{service.UrlGroup}'"); // Write into source swagger mapping file Utility.WriteDictToFile(lineNumberMappingFilePath, sourceSwaggerMappingDict); } return(subTocDict); }
private static void WriteToc(string sourceRootDir, string targetRootDir, OrgsMappingFile orgsMappingFile, string targetApiVersionDir, string version) { var targetTocPath = Path.Combine(targetApiVersionDir, TocFileName); var lineNumberMappingFilePath = Path.Combine(targetRootDir, SourceSwaggerMappingFileName); Utility.ClearFile(lineNumberMappingFilePath); RepoFile repoFile = null; if (File.Exists(Path.Combine(targetRootDir, "repo.json"))) { repoFile = JsonUtility.ReadFromFile <RepoFile>(Path.Combine(targetRootDir, "repo.json")); } using (var writer = new StreamWriter(targetTocPath)) { // Write auto generated apis page if (orgsMappingFile.ApisPageOptions?.EnableAutoGenerate == true) { if (string.IsNullOrEmpty(orgsMappingFile.ApisPageOptions.TargetFile)) { throw new InvalidOperationException("Target file of apis page options should not be null or empty."); } var targetIndexPath = Path.Combine(targetRootDir, orgsMappingFile.ApisPageOptions.TargetFile); writer.WriteLine($"# [{orgsMappingFile.ApisPageOptions.TocTitle}]({FileUtility.GetRelativePath(targetIndexPath, targetApiVersionDir)})"); } // Write organization info foreach (var orgInfo in orgsMappingFile.OrgInfos) { if (version == null || string.Equals(orgInfo.Version, version)) { // Deal with org name and index var subTocPrefix = string.Empty; if (!string.IsNullOrEmpty(orgInfo.OrgName)) { // Write index writer.WriteLine(!string.IsNullOrEmpty(orgInfo.OrgIndex) ? $"# [{orgInfo.OrgName}]({GenerateIndexHRef(targetRootDir, orgInfo.OrgIndex, targetApiVersionDir)})" : $"# {orgInfo.OrgName}"); subTocPrefix = "#"; } else if (orgsMappingFile.ApisPageOptions?.EnableAutoGenerate != true && !string.IsNullOrEmpty(orgInfo.DefaultTocTitle) && !string.IsNullOrEmpty(orgInfo.OrgIndex)) { writer.WriteLine($"# [{orgInfo.DefaultTocTitle}]({GenerateIndexHRef(targetRootDir, orgInfo.OrgIndex, targetApiVersionDir)})"); } // Sort by service name orgInfo.Services.Sort((a, b) => a.TocTitle.CompareTo(b.TocTitle)); // Write service info foreach (var service in orgInfo.Services) { // 1. Top toc Console.WriteLine($"Created conceptual toc item '{service.TocTitle}'"); writer.WriteLine(!string.IsNullOrEmpty(service.IndexFile) ? $"{subTocPrefix}# [{service.TocTitle}]({GenerateIndexHRef(targetRootDir, service.IndexFile, targetApiVersionDir)})" : $"{subTocPrefix}# {service.TocTitle}"); // 2. Parse and split REST swaggers var subTocDict = new SortedDictionary <string, List <SwaggerToc> >(); if (service.SwaggerInfo != null) { subTocDict = SplitSwaggers(sourceRootDir, targetApiVersionDir, service, orgsMappingFile, repoFile, version, lineNumberMappingFilePath); } // 3. Conceptual toc List <string> tocLines = null; if (!string.IsNullOrEmpty(service.TocFile)) { tocLines = GenerateDocTocItems(targetRootDir, service.TocFile, targetApiVersionDir).Where(i => !string.IsNullOrEmpty(i)).ToList(); if (tocLines.Any()) { foreach (var tocLine in tocLines) { // Insert one heading before to make it sub toc writer.WriteLine($"{subTocPrefix}#{tocLine}"); } Console.WriteLine($"-- Created sub referenced toc items under conceptual toc item '{service.TocTitle}'"); } } // 4. Write REST toc if (service.SwaggerInfo?.Count > 0) { var subRefTocPrefix = string.Empty; if (tocLines?.Count > 0) { subRefTocPrefix = IncreaseSharpCharacter(subRefTocPrefix); writer.WriteLine($"{subTocPrefix}#{subRefTocPrefix} Reference"); } foreach (var pair in subTocDict) { var subGroupTocPrefix = subRefTocPrefix; if (!string.IsNullOrEmpty(pair.Key)) { subGroupTocPrefix = IncreaseSharpCharacter(subRefTocPrefix); writer.WriteLine($"{subTocPrefix}#{subGroupTocPrefix} {pair.Key}"); } var subTocList = pair.Value; subTocList.Sort((x, y) => string.CompareOrdinal(x.Title, y.Title)); foreach (var subToc in subTocList) { writer.WriteLine($"{subTocPrefix}##{subGroupTocPrefix} [{subToc.Title}]({subToc.FilePath})"); if (subToc.ChildrenToc.Count > 0) { foreach (var child in subToc.ChildrenToc) { writer.WriteLine($"{subTocPrefix}###{subGroupTocPrefix} [{child.Title}]({child.FilePath})"); } } } } } } } } } if (orgsMappingFile.UserYamlToc) { TocConverter.Convert(targetTocPath); if (File.Exists(targetTocPath)) { File.Delete(targetTocPath); } } }
public static IGenerator CreateGenerator(JObject rootJObj, string targetDir, string filePath, OperationGroupMapping operationGroupMapping, OrgsMappingFile orgsMappingFile, IDictionary <string, int> lineNumberMappingDict, RepoFile repoFile, string swaggerSourcePath, string version) { if (orgsMappingFile.IsGroupdedByTag) { return(new TagsGenerator(rootJObj, targetDir, filePath, operationGroupMapping, orgsMappingFile, lineNumberMappingDict, repoFile, swaggerSourcePath, version)); } return(new OperationGroupGenerator(rootJObj, targetDir, filePath, operationGroupMapping, orgsMappingFile, lineNumberMappingDict, repoFile, swaggerSourcePath, version)); }