/// <summary> /// Processes the specification file. /// </summary> /// <returns>The specification file.</returns> /// <param name="file">File.</param> /// <param name="output">Output.</param> public static async Task ProcessSpecificationFile(string file, string output) { var spec = await SwaggerDocument.FromFileAsync(file); spec.ExtensionData?.Clear(); foreach (var definition in spec.Definitions) { definition.Value.ExtensionData?.Clear(); } foreach (var path in spec.Paths) { foreach (var operation in path.Value) { foreach (var param in operation.Value.Parameters) { param.ExtensionData?.Clear(); } operation.Value.ExtensionData.TryGetValue("x-ms-vss-method", out object descriptor); operation.Value.ExtensionData?.Clear(); operation.Value.OperationId = descriptor.ToString(); } } var content = spec.ToJson(SchemaType.Swagger2); var outFile = Path.Join(output, new DirectoryInfo(file).Name); File.WriteAllText(outFile, content); }
private async Task <SwaggerDocument> GetSwaggerDocument() { // Workaround: NSwag semm to have a bug in enum handling void editEnumType(JsonSchema4 type) { if (type.IsEnumeration && type.Type == JsonObjectType.None) { type.Type = JsonObjectType.Integer; } foreach (var t in type.Properties.Values) { editEnumType(t); } } var d = await SwaggerDocument.FromFileAsync("c:/users/exyi/Downloads/github-swagger.json"); this.PopulateOperationIds(d); foreach (var t in d.Definitions.Values) { editEnumType(t); } return(d); var settings = new WebApiToSwaggerGeneratorSettings(); var generator = new WebApiToSwaggerGenerator(settings); var controllers = typeof(GeneratorViewModel) .GetTypeInfo() .Assembly.GetTypes() .Where(t => typeof(Controller).IsAssignableFrom(t)); return(await generator.GenerateForControllersAsync(controllers)); }
public static void WriteServices(FileInfo inputSchema, FileInfo outputCSharp, SwaggerToCSharpClientGeneratorSettings settings) { SwaggerDocument document; try { document = SwaggerDocument.FromFileAsync(inputSchema.FullName).Result; } catch (Exception exception) { Console.WriteLine(exception); throw; } SwaggerToCSharpClientGenerator generator = new SwaggerToCSharpClientGenerator(document, settings); try { File.WriteAllText(outputCSharp.FullName, generator.GenerateFile()); } catch (Exception exception) { Console.WriteLine(exception); throw; } }
/// <summary> /// 获取swagger文档 /// </summary> /// <param name="swagger"></param> /// <returns></returns> private static SwaggerDocument GetDocument(string swagger) { Console.WriteLine($"正在分析swagger:{swagger}"); if (Uri.TryCreate(swagger, UriKind.Absolute, out var _) == true) { return(SwaggerDocument.FromUrlAsync(swagger).Result); } else { return(SwaggerDocument.FromFileAsync(swagger).Result); } }
private static Task <SwaggerDocument> LoadDocument(Uri swaggerUri) { if (!swaggerUri.IsAbsoluteUri) { return(SwaggerDocument.FromFileAsync(swaggerUri.ToString())); } else if (swaggerUri.Scheme == "file") { return(SwaggerDocument.FromFileAsync(swaggerUri.LocalPath)); } return(SwaggerDocument.FromUrlAsync(swaggerUri.ToString())); }
public static async Task RegenApiClient(ApiClientDefinition definition) { var document = !definition.SwaggerFile.IsAbsoluteUri ? await SwaggerDocument.FromFileAsync(definition.SwaggerFile.ToString()) : definition.SwaggerFile.Scheme == "file" ? await SwaggerDocument.FromFileAsync(definition.SwaggerFile.LocalPath) : await SwaggerDocument.FromUrlAsync(definition.SwaggerFile.ToString()); PopulateOperationIds(document); var(isSingleClient, typeName) = GenerateCSharp(document, definition); GenerateTS(document, definition); Console.WriteLine($"Api clients generated. To register in dotvvm put following to your DotvvmStartup: "); Console.WriteLine($"config.RegisterApi{(isSingleClient ? "Client" : "Group")}(typeof({definition.Namespace}.{(definition.GenerateWrapperClass || isSingleClient ? typeName : " ... your client wrapper class ...")}), \"{ document.BasePath ?? "... you api endpoint ..." }\", \"{(definition.CompileTypescript ? Path.ChangeExtension(definition.TypescriptClient, "js") : "... path to your compiled javascript")}\");"); }
private async Task <SwaggerDocument> GetSwaggerDocument() { return(await SwaggerDocument.FromFileAsync("c:/users/exyi/Downloads/github-swagger.json")); var settings = new WebApiToSwaggerGeneratorSettings(); var generator = new WebApiToSwaggerGenerator(settings); var controllers = typeof(GeneratorViewModel) .GetTypeInfo() .Assembly.GetTypes() .Where(t => typeof(Controller).IsAssignableFrom(t)); return(await generator.GenerateForControllersAsync(controllers)); }
/// <summary> /// A constructor that creates a Swagger object from a file /// </summary> /// <param name="swaggerPath">Path to Swagger file</param> public Swagger(string swaggerPath) { SwaggerDocument document; if (Path.GetExtension(swaggerPath) == ".json") { document = SwaggerDocument.FromFileAsync(swaggerPath).Result; } else { var fs = new FileStream(swaggerPath, FileMode.Open); var reader = new StreamReader(fs); var deserializer = new Deserializer(namingConvention: new CamelCaseNamingConvention()); //TODO this is deprecated, update to use deserializer var yamlObject = deserializer.Deserialize(reader); // now convert the object to JSON. Simple! JsonSerializer js = new JsonSerializer(); var writer = new StringWriter(); js.Serialize(writer, yamlObject); string jsonText = writer.ToString(); document = SwaggerDocument.FromJsonAsync(jsonText).Result; } Routes = new Dictionary <string, List <Action> >(); document.Operations.ToList().ForEach(operationDescription => { var path = operationDescription.Path.Trim('/').ToLower(); List <Action> methods; if (Routes.TryGetValue(path, out methods)) { methods.Add(new Action(operationDescription)); } else { Routes.Add(path, new List <Action>() { new Action(operationDescription) }); } }); foreach (var r in Routes.Values) { Endpoints += r.Count(); } ; }
/// <summary>Loads the Swagger spec.</summary> public async Task <SwaggerDocument> RunAsync() { if (!string.IsNullOrEmpty(Swagger)) { return(await SwaggerDocument.FromJsonAsync(Swagger).ConfigureAwait(false)); } else if (Url.StartsWith("http://") || Url.StartsWith("https://")) { return(await SwaggerDocument.FromUrlAsync(Url).ConfigureAwait(false)); } else { return(await SwaggerDocument.FromFileAsync(Url).ConfigureAwait(false)); } }
public async static Task <string> GenerateFromFile(string file, string namespaceName, string className) { var document = await SwaggerDocument.FromFileAsync(file); var settings = new SwaggerToCSharpClientGeneratorSettings { ClassName = className, CSharpGeneratorSettings = { Namespace = namespaceName } }; var generator = new SwaggerToCSharpClientGenerator(document, settings); return(generator.GenerateFile()); }
public byte[] GetContent(string documentPath) { var settings = new SwaggerToCSharpClientGeneratorSettings { ClassName = _className, CSharpGeneratorSettings = { Namespace = _ns } }; var document = SwaggerDocument.FromFileAsync(documentPath).Result; var generator = new SwaggerToCSharpClientGenerator(document, settings); var code = generator.GenerateFile(); return(Encoding.UTF8.GetBytes(code)); }
static void Main(string[] args) { var document = SwaggerDocument.FromFileAsync("./swagger-doc.json").Result; var settings = new SwaggerToTypeScriptClientGeneratorSettings { TypeScriptGeneratorSettings = { TypeScriptVersion = 2.3m, TypeStyle = TypeScriptTypeStyle.Class, NullHandling = NullHandling.Swagger }, Template = TypeScriptTemplate.Angular }; var generator = new SwaggerToTypeScriptClientGenerator(document, settings); Console.WriteLine(generator.GenerateFile()); }
/// <exception cref="ArgumentException">The argument 'Input' was empty.</exception> protected async Task <SwaggerDocument> GetInputSwaggerDocument() { var document = Input as SwaggerDocument; if (document == null) { var inputString = Input.ToString(); if (string.IsNullOrEmpty(inputString)) { throw new ArgumentException("The argument 'Input' was empty."); } if (IsJson(inputString)) { document = await SwaggerDocument.FromJsonAsync(inputString).ConfigureAwait(false); } else if (inputString.StartsWith("http://") || inputString.StartsWith("https://")) { document = await SwaggerDocument.FromUrlAsync(inputString).ConfigureAwait(false); } else { document = await SwaggerDocument.FromFileAsync(inputString).ConfigureAwait(false); } } if (ServiceHost == ".") { document.Host = string.Empty; } else if (!string.IsNullOrEmpty(ServiceHost)) { document.Host = ServiceHost; } if (ServiceSchemes != null && ServiceSchemes.Any()) { document.Schemes = ServiceSchemes.Select(s => (SwaggerSchema)Enum.Parse(typeof(SwaggerSchema), s, true)).ToList(); } return(document); }
protected async Task <SwaggerDocument> ReadSwaggerDocumentAsync(string input) { if (!IsJson(input) && !IsYaml(input)) { if (input.StartsWith("http://") || input.StartsWith("https://")) { if (input.EndsWith(".yaml", StringComparison.OrdinalIgnoreCase) || input.EndsWith(".yml", StringComparison.OrdinalIgnoreCase)) { return(await SwaggerYamlDocument.FromUrlAsync(input).ConfigureAwait(false)); } else { return(await SwaggerDocument.FromUrlAsync(input).ConfigureAwait(false)); } } else { if (input.EndsWith(".yaml", StringComparison.OrdinalIgnoreCase) || input.EndsWith(".yml", StringComparison.OrdinalIgnoreCase)) { return(await SwaggerYamlDocument.FromFileAsync(input).ConfigureAwait(false)); } else { return(await SwaggerDocument.FromFileAsync(input).ConfigureAwait(false)); } } } else { if (IsYaml(input)) { return(await SwaggerYamlDocument.FromYamlAsync(input).ConfigureAwait(false)); } else { return(await SwaggerDocument.FromJsonAsync(input).ConfigureAwait(false)); } } }
private void GenerateSwaggerTypescriptClient() { if (!_env.IsDevelopment()) { return; } var document = SwaggerDocument.FromFileAsync($"{Environment.CurrentDirectory}/wwwroot/docs/api-specification.json").Result; var settings = new SwaggerToTypeScriptClientGeneratorSettings { ClassName = "{controller}Client", Template = TypeScriptTemplate.Angular, RxJsVersion = (decimal)6.3, InjectionTokenType = InjectionTokenType.InjectionToken, HttpClass = HttpClass.HttpClient }; var generator = new SwaggerToTypeScriptClientGenerator(document, settings); var code = generator.GenerateFile(); File.WriteAllText($"{Environment.CurrentDirectory}/ClientApp/src/app/shared/enarudzbenice2-api.ts", code); }
public string GenerateCode(IVsGeneratorProgress pGenerateProgress) { try { pGenerateProgress?.Progress(10); var document = SwaggerDocument .FromFileAsync(swaggerFile) .GetAwaiter() .GetResult(); pGenerateProgress?.Progress(20); var settings = new SwaggerToCSharpClientGeneratorSettings { ClassName = GetClassName(document), InjectHttpClient = options.InjectHttpClient, GenerateClientInterfaces = options.GenerateClientInterfaces, GenerateDtoTypes = options.GenerateDtoTypes, UseBaseUrl = options.UseBaseUrl, CSharpGeneratorSettings = { Namespace = defaultNamespace, ClassStyle = options.ClassStyle }, }; pGenerateProgress?.Progress(50); var generator = new SwaggerToCSharpClientGenerator(document, settings); return(generator.GenerateFile()); } finally { pGenerateProgress?.Progress(90); } }
/// <summary>Loads the Swagger spec.</summary> public async Task <SwaggerDocument> RunAsync() { if (!string.IsNullOrEmpty(Swagger)) { if (Swagger.StartsWith("{")) { return(await SwaggerDocument.FromJsonAsync(Swagger).ConfigureAwait(false)); } else { return(await SwaggerYamlDocument.FromYamlAsync(Swagger).ConfigureAwait(false)); } } else if (Url.StartsWith("http://") || Url.StartsWith("https://")) { if (Url.EndsWith(".yaml", StringComparison.OrdinalIgnoreCase)) { return(await SwaggerYamlDocument.FromUrlAsync(Url).ConfigureAwait(false)); } else { return(await SwaggerDocument.FromUrlAsync(Url).ConfigureAwait(false)); } } else { if (Url.EndsWith(".yaml", StringComparison.OrdinalIgnoreCase)) { return(await SwaggerYamlDocument.FromFileAsync(Url).ConfigureAwait(false)); } else { return(await SwaggerDocument.FromFileAsync(Url).ConfigureAwait(false)); } } }
static async Task Main(string[] args) { // Initialize variables - such as the Kubernetes branch for which to generate the API. string kubernetesBranch = "v1.10.0"; if (Environment.GetEnvironmentVariable("KUBERNETES_BRANCH") != null) { kubernetesBranch = Environment.GetEnvironmentVariable("KUBERNETES_BRANCH"); Console.WriteLine($"Using Kubernetes branch {kubernetesBranch}, as set by the KUBERNETES_BRANCH environment variable"); } const string outputDirectory = "../../../../../src/KubernetesClient/generated/"; var specUrl = $"https://raw.githubusercontent.com/kubernetes/kubernetes/{kubernetesBranch}/api/openapi-spec/swagger.json"; var specPath = $"{kubernetesBranch}-swagger.json"; // Download the Kubernetes spec, and cache it locally. Don't download it if already present in the cache. if (!File.Exists(specPath)) { HttpClient client = new HttpClient(); using (var response = await client.GetAsync(specUrl, HttpCompletionOption.ResponseHeadersRead)) using (var stream = await response.Content.ReadAsStreamAsync()) using (var output = File.Open(specPath, FileMode.Create, FileAccess.ReadWrite)) { await stream.CopyToAsync(output); } } // Read the spec var swagger = await SwaggerDocument.FromFileAsync(specPath); // Register helpers used in the templating. Helpers.Register(nameof(ToXmlDoc), ToXmlDoc); Helpers.Register(nameof(GetClassName), GetClassName); Helpers.Register(nameof(GetMethodName), GetMethodName); Helpers.Register(nameof(GetDotNetName), GetDotNetName); Helpers.Register(nameof(GetDotNetType), GetDotNetType); Helpers.Register(nameof(GetPathExpression), GetPathExpression); Helpers.Register(nameof(GetGroup), GetGroup); Helpers.Register(nameof(GetApiVersion), GetApiVersion); Helpers.Register(nameof(GetKind), GetKind); // Generate the Watcher operations // We skip operations where the name of the class in the C# client could not be determined correctly. // That's usually because there are different version of the same object (e.g. for deployments). Collection <string> blacklistedOperations = new Collection <string>() { "watchAppsV1beta1NamespacedDeployment", "watchAppsV1beta2NamespacedDeployment", "watchExtensionsV1beta1NamespacedDeployment", "watchExtensionsV1beta1NamespacedNetworkPolicy", "watchPolicyV1beta1PodSecurityPolicy", "watchExtensionsV1beta1PodSecurityPolicy" }; var watchOperations = swagger.Operations.Where( o => o.Path.Contains("/watch/") && o.Operation.ActualParameters.Any(p => p.Name == "name") && !blacklistedOperations.Contains(o.Operation.OperationId)).ToArray(); // Render. Render.FileToFile("IKubernetes.Watch.cs.template", watchOperations, $"{outputDirectory}IKubernetes.Watch.cs"); Render.FileToFile("Kubernetes.Watch.cs.template", watchOperations, $"{outputDirectory}Kubernetes.Watch.cs"); // Generate the interface declarations var skippedTypes = new Collection <string>() { "V1beta1Deployment", "V1beta1DeploymentList", "V1beta1DeploymentRollback", "V1beta1DeploymentRollback", "V1beta1Scale", "V1beta1PodSecurityPolicy", "V1beta1PodSecurityPolicyList", "V1WatchEvent", }; var definitions = swagger.Definitions.Values .Where( d => d.ExtensionData != null && d.ExtensionData.ContainsKey("x-kubernetes-group-version-kind") && !skippedTypes.Contains(GetClassName(d))); // Render. Render.FileToFile("ModelExtensions.cs.template", definitions, $"{outputDirectory}ModelExtensions.cs"); }
internal static List <ExplorerItem> GetSchemaAndBuildAssembly(string driverLocation, ConnectionProperties props, AssemblyName name, ref string nameSpace, ref string typeName) { List <ExplorerItem> schema = new List <ExplorerItem>(); var uri = new Uri(props.Uri); SwaggerDocument document = null; if (uri.Scheme == "file") { document = SwaggerDocument.FromFileAsync(uri.LocalPath).Result; } else if (uri.Scheme == "http" || uri.Scheme == "https") { if (props.AuthOption == AuthenticationType.None) { document = DownloadDefinition(props.Uri, props); } else if (props.AuthOption == AuthenticationType.Basic) { document = DownloadDefinition(props.Uri, props, new NetworkCredential(props.UserName, props.Password, props.Domain)); } else if (props.AuthOption == AuthenticationType.CurrentUser) { document = DownloadDefinition(props.Uri, props, CredentialCache.DefaultNetworkCredentials); } else { throw new NotSupportedException("Authentication method not supported."); } if (document.BaseUrl.StartsWith("/") && document.BasePath.StartsWith("/")) { var t = document.BaseUrl; document.BasePath = uri.Scheme + "://" + uri.Host + ":" + uri.Port + document.BaseUrl; System.Diagnostics.Debug.WriteLine("Changing BaseUrl from '{0}' to '{1}'", t, document.BasePath); } if (string.IsNullOrEmpty(document.Host)) { document.Host = uri.Host; System.Diagnostics.Debug.WriteLine("Host was null, setting it to '{0}'", document.Host); } } switch (props.GenOption) { case GeneratorType.SingleClientFromOperatinoId: // Compile the code into the assembly, using the assembly name provided: BuildAssemblySingleClientFromOpId(document, driverLocation, name, nameSpace, ref typeName, props); // Use the schema to populate the Schema Explorer: schema = GetSchemaSingleClient(document, typeName); break; case GeneratorType.SingleClientFromPathSegment: // Compile the code into the assembly, using the assembly name provided: BuildAssemblySingleClientFromPathSegOp(document, driverLocation, name, nameSpace, ref typeName, props); // Use the schema to populate the Schema Explorer: //schema = GetSchemaSingleClientPath(document, typeName); schema = GetSchemaViaReflection(name, nameSpace, typeName); break; case GeneratorType.MultipleClientsFromOperationId: // Compile the code into the assembly, using the assembly name provided: BuildAssemblyMultiClientFromOpId(document, driverLocation, name, nameSpace, ref typeName, props); // Use the schema to populate the Schema Explorer: schema = GetSchemaMultiClient(document, typeName); break; } return(schema); }
static async Task Main(string[] args) { if (args.Length < 2) { Console.Error.WriteLine($"usage {args[0]} path/to/csharp.settings"); Environment.Exit(1); } var(kubernetesBranch, outputDirectory) = LoadSettings(args[1]); var specUrl = $"https://raw.githubusercontent.com/kubernetes/kubernetes/{kubernetesBranch}/api/openapi-spec/swagger.json"; var specPath = $"{kubernetesBranch}-swagger.json"; // Download the Kubernetes spec, and cache it locally. Don't download it if already present in the cache. if (!File.Exists(specPath)) { HttpClient client = new HttpClient(); using (var response = await client.GetAsync(specUrl, HttpCompletionOption.ResponseHeadersRead)) using (var stream = await response.Content.ReadAsStreamAsync()) using (var output = File.Open(specPath, FileMode.Create, FileAccess.ReadWrite)) { await stream.CopyToAsync(output); } } // Read the spec var swagger = await SwaggerDocument.FromFileAsync(specPath); // Register helpers used in the templating. Helpers.Register(nameof(ToXmlDoc), ToXmlDoc); Helpers.Register(nameof(GetClassName), GetClassName); Helpers.Register(nameof(GetMethodName), GetMethodName); Helpers.Register(nameof(GetDotNetName), GetDotNetName); Helpers.Register(nameof(GetDotNetType), GetDotNetType); Helpers.Register(nameof(GetPathExpression), GetPathExpression); Helpers.Register(nameof(GetGroup), GetGroup); Helpers.Register(nameof(GetApiVersion), GetApiVersion); Helpers.Register(nameof(GetKind), GetKind); // Generate the Watcher operations // We skip operations where the name of the class in the C# client could not be determined correctly. // That's usually because there are different version of the same object (e.g. for deployments). var blacklistedOperations = new HashSet <string>() { "watchAppsV1beta1NamespacedDeployment", "watchAppsV1beta2NamespacedDeployment", "watchExtensionsV1beta1NamespacedDeployment", "watchExtensionsV1beta1NamespacedNetworkPolicy", "watchPolicyV1beta1PodSecurityPolicy", "watchExtensionsV1beta1PodSecurityPolicy", "watchExtensionsV1beta1NamespacedIngress", "watchExtensionsV1beta1NamespacedIngressList", "watchNetworkingV1beta1NamespacedIngress", "watchNetworkingV1beta1NamespacedIngressList", }; var watchOperations = swagger.Operations.Where( o => o.Path.Contains("/watch/") && o.Operation.ActualParameters.Any(p => p.Name == "name") && !blacklistedOperations.Contains(o.Operation.OperationId)).ToArray(); // Render. Render.FileToFile("IKubernetes.Watch.cs.template", watchOperations, $"{outputDirectory}IKubernetes.Watch.cs"); Render.FileToFile("Kubernetes.Watch.cs.template", watchOperations, $"{outputDirectory}Kubernetes.Watch.cs"); // Generate the interface declarations var skippedTypes = new HashSet <string>() { "V1beta1Deployment", "V1beta1DeploymentList", "V1beta1DeploymentRollback", "V1beta1DeploymentRollback", "V1beta1Scale", "V1beta1PodSecurityPolicy", "V1beta1PodSecurityPolicyList", "V1WatchEvent", "V1beta1Ingress", "V1beta1IngressList" }; var definitions = swagger.Definitions.Values .Where( d => d.ExtensionData != null && d.ExtensionData.ContainsKey("x-kubernetes-group-version-kind") && !skippedTypes.Contains(GetClassName(d))); // Render. Render.FileToFile("ModelExtensions.cs.template", definitions, $"{outputDirectory}ModelExtensions.cs"); }
async Task <string> GetSwaggerWay1() { //see Web -> GenerateSwaggerFiles DotNetTasks.DotNetRun( s => s //.SetWorkingDirectory(MySolutionDirectory) .SetProjectFile(Solution.GetProject("Web").Path) .SetLaunchProfile("localProfile") .SetApplicationArguments("swagger") ); var apiVersion = "v1"; var document = await SwaggerDocument.FromFileAsync($"./swagger/swagger-Web-{apiVersion}.json"); var tsGenerator = new SwaggerToTypeScriptClientGenerator(document, new SwaggerToTypeScriptClientGeneratorSettings { ClassName = "{controller}Client", CodeGeneratorSettings = { GenerateDefaultValues = true, SchemaType = SchemaType.JsonSchema, }, //RxJsVersion = 6, Template = TypeScriptTemplate.Angular, HttpClass = HttpClass.HttpClient, PromiseType = PromiseType.Promise, WrapResponses = false, GenerateClientClasses = true, GenerateClientInterfaces = false, GenerateDtoTypes = true, GenerateOptionalParameters = true, GenerateResponseClasses = true, ImportRequiredTypes = true, InjectionTokenType = InjectionTokenType.InjectionToken, UseSingletonProvider = true, OperationNameGenerator = new SingleClientFromPathSegmentsOperationNameGenerator(), WrapDtoExceptions = false, BaseUrlTokenName = "API_BASE_URL", TypeScriptGeneratorSettings = { GenerateDefaultValues = true, SchemaType = SchemaType.JsonSchema, NullValue = TypeScriptNullValue.Null, ExportTypes = true, TypeStyle = TypeScriptTypeStyle.Class, DateTimeType = TypeScriptDateTimeType.MomentJS, MarkOptionalProperties = true, TypeScriptVersion = 2.7m, ConvertConstructorInterfaceData = false, ModuleName = null, }, UseGetBaseUrlMethod = false, UseTransformOptionsMethod = false, UseTransformResultMethod = false, }); var ngApiClient = tsGenerator.GenerateFile(); return(ngApiClient); }
private static async Task Main(string[] args) { if (args.Length < 2) { Console.Error.WriteLine($"usage {args[0]} path/to/generated"); Environment.Exit(1); } var outputDirectory = args[1]; // Read the spec trimmed // here we cache all name in gen project for later use var swagger = await SwaggerDocument.FromFileAsync(Path.Combine(args[1], "swagger.json")).ConfigureAwait(false); foreach (var(k, v) in swagger.Definitions) { if (v.ExtensionData?.TryGetValue("x-kubernetes-group-version-kind", out var _) == true) { var groupVersionKindElements = (object[])v.ExtensionData["x-kubernetes-group-version-kind"]; var groupVersionKind = (Dictionary <string, object>)groupVersionKindElements[0]; var group = (string)groupVersionKind["group"]; var kind = (string)groupVersionKind["kind"]; var version = (string)groupVersionKind["version"]; ClassNameMap[$"{group}_{kind}_{version}"] = ToPascalCase(k.Replace(".", "")); } } // gen project removed all watch operations, so here we switch back to unprocessed version swagger = await SwaggerDocument.FromFileAsync(Path.Combine(args[1], "swagger.json.unprocessed")).ConfigureAwait(false); _schemaToNameMap = swagger.Definitions.ToDictionary(x => x.Value, x => x.Key); _schemaDefinitionsInMultipleGroups = _schemaToNameMap.Values.Select(x => { var parts = x.Split("."); return(new { FullName = x, Name = parts[parts.Length - 1], Version = parts[parts.Length - 2], Group = parts[parts.Length - 3], }); }) .GroupBy(x => new { x.Name, x.Version }) .Where(x => x.Count() > 1) .SelectMany(x => x) .Select(x => x.FullName) .ToHashSet(); _classNameToPluralMap = swagger.Operations .Where(x => x.Operation.OperationId.StartsWith("list")) .Select(x => { return(new { PluralName = x.Path.Split("/").Last(), ClassName = GetClassNameForSchemaDefinition(x.Operation.Responses["200"] .ActualResponseSchema), }); }) .Distinct() .ToDictionary(x => x.ClassName, x => x.PluralName); // dictionary only contains "list" plural maps. assign the same plural names to entities those lists support _classNameToPluralMap = _classNameToPluralMap .Where(x => x.Key.EndsWith("List")) .Select(x => new { ClassName = x.Key.Remove(x.Key.Length - 4), PluralName = x.Value }) .ToDictionary(x => x.ClassName, x => x.PluralName) .Union(_classNameToPluralMap) .ToDictionary(x => x.Key, x => x.Value); // Register helpers used in the templating. Helpers.Register(nameof(ToXmlDoc), ToXmlDoc); Helpers.Register(nameof(GetClassName), GetClassName); Helpers.Register(nameof(GetInterfaceName), GetInterfaceName); Helpers.Register(nameof(GetMethodName), GetMethodName); Helpers.Register(nameof(GetDotNetName), GetDotNetName); Helpers.Register(nameof(GetDotNetType), GetDotNetType); Helpers.Register(nameof(GetPathExpression), GetPathExpression); Helpers.Register(nameof(GetGroup), GetGroup); Helpers.Register(nameof(GetApiVersion), GetApiVersion); Helpers.Register(nameof(GetKind), GetKind); Helpers.Register(nameof(GetPlural), GetPlural); Helpers.Register(nameof(GetTuple), GetTuple); // Generate the Watcher operations // We skip operations where the name of the class in the C# client could not be determined correctly. // That's usually because there are different version of the same object (e.g. for deployments). var blacklistedOperations = new HashSet <string>() { }; var watchOperations = swagger.Operations.Where( o => o.Path.Contains("/watch/") && o.Operation.ActualParameters.Any(p => p.Name == "name") && !blacklistedOperations.Contains(o.Operation.OperationId)).ToArray(); // Render. Render.FileToFile("IKubernetes.Watch.cs.template", watchOperations, Path.Combine(outputDirectory, "IKubernetes.Watch.cs")); Render.FileToFile("Kubernetes.Watch.cs.template", watchOperations, Path.Combine(outputDirectory, "Kubernetes.Watch.cs")); // Generate the interface declarations var skippedTypes = new HashSet <string>() { "V1WatchEvent", }; var definitions = swagger.Definitions.Values .Where( d => d.ExtensionData != null && d.ExtensionData.ContainsKey("x-kubernetes-group-version-kind") && !skippedTypes.Contains(GetClassName(d))); var modelsDir = Path.Combine(outputDirectory, "Models"); _classesWithValidation = Directory.EnumerateFiles(modelsDir) .Select(x => new { Class = Path.GetFileNameWithoutExtension(x), Content = File.ReadAllText(x) }) .Where(x => x.Content.Contains("public virtual void Validate()")) .Select(x => x.Class) .ToHashSet(); Render.FileToFile("ModelExtensions.cs.template", definitions, Path.Combine(outputDirectory, "ModelExtensions.cs")); // generate version converter maps var allGeneratedModelClassNames = Directory .EnumerateFiles(Path.Combine(outputDirectory, "Models")) .Select(Path.GetFileNameWithoutExtension) .ToList(); var versionRegex = @"(^V|v)[0-9]+((alpha|beta)[0-9]+)?"; var typePairs = allGeneratedModelClassNames .OrderBy(x => x) .Select(x => new { Version = Regex.Match(x, versionRegex).Value?.ToLower(), Kinda = Regex.Replace(x, versionRegex, string.Empty), Type = x }) .Where(x => !string.IsNullOrEmpty(x.Version)) .GroupBy(x => x.Kinda) .Where(x => x.Count() > 1) .SelectMany(x => x.SelectMany((value, index) => x.Skip(index + 1), (first, second) => new { first, second })) .OrderBy(x => x.first.Kinda) .ThenBy(x => x.first.Version) .Select(x => (ITuple)Tuple.Create(x.first.Type, x.second.Type)) .ToList(); var versionFile = File.ReadAllText(Path.Combine(outputDirectory, "..", "Versioning", "VersionConverter.cs")); var manualMaps = Regex.Matches(versionFile, @"\.CreateMap<(?<T1>.+?),\s?(?<T2>.+?)>") .Select(x => Tuple.Create(x.Groups["T1"].Value, x.Groups["T2"].Value)) .ToList(); var versionConverterPairs = typePairs.Except(manualMaps).ToList(); Render.FileToFile("VersionConverter.cs.template", versionConverterPairs, Path.Combine(outputDirectory, "VersionConverter.cs")); Render.FileToFile("ModelOperators.cs.template", typePairs, Path.Combine(outputDirectory, "ModelOperators.cs")); }
/// <summary> /// Fetch Swagger document from swagger file path or Uri. /// </summary> /// <remarks> /// FilePath takes precidence over Uri /// </remarks> private void FetchSwaggerDocument() { Document = Task.Run(() => !string.IsNullOrEmpty(_settings.ApiSpecPath) ? SwaggerDocument.FromFileAsync(_settings.ApiSpecPath) : SwaggerDocument.FromUrlAsync(_settings.ApiSpecUri)).GetAwaiter().GetResult(); }