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;
        }
Example #6
0
        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;
 }
Example #8
0
        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));
 }