Skip to content
Snippets Groups Projects
Commit e567d4b5 authored by Benedikt Heinrichs's avatar Benedikt Heinrichs
Browse files

Refactor Coscine.CodeGen

parent be371a20
Branches
No related tags found
1 merge request!1New: Create a Api Client Script
......@@ -4,6 +4,7 @@
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<AssemblyName>Coscine.CodeGen</AssemblyName>
<RootNamespace>Coscine.CodeGen</RootNamespace>
</PropertyGroup>
<ItemGroup>
......
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace Coscine.CodeGen.CodeGenerator
{
public abstract class CodeGenerator
{
public async Task GenerateCode()
{
var jarFileName = await GetClientGenerator();
var keys = await GetApiNames();
var outputPath = await GetOutputPath();
if (!Directory.Exists(outputPath))
{
Directory.CreateDirectory(outputPath);
}
await RetrieveDefinitions(outputPath, jarFileName, keys);
await WriteDefinitions(outputPath);
}
private async Task<string> RetrieveDefinitions(string outputPath, string jarFileName, IEnumerable<string> keys)
{
var domainName = System.Net.NetworkInformation.IPGlobalProperties.GetIPGlobalProperties().DomainName;
var hostName = Dns.GetHostName();
foreach (var key in keys)
{
Console.WriteLine(key);
string swaggerUrl = await GetSwaggerUrl(domainName, hostName, key);
var command = $"java \"-Dio.swagger.parser.util.RemoteUrl.trustAll=true\" \"-Dio.swagger.v3.parser.util.RemoteUrl.trustAll=true\" -jar \"{jarFileName}\" generate -i \"{swaggerUrl}\" -g typescript-axios -o \"{outputPath}/{key}\" --skip-validate-spec";
await ExecuteCommand(command);
}
return outputPath;
}
private async Task WriteDefinitions(string outputPath)
{
var combinationFile = outputPath + "/apis.ts";
var indexFile = outputPath + "/index.ts";
var combinationFileImports = new List<string>();
var combinationFileExports = new List<string>();
var concreteApiNames = new List<string>();
var first = true;
var apiRegex = new Regex("(?<= )(.*?)(?= extends BaseAPI)");
foreach (var directory in Directory.GetDirectories(outputPath))
{
var apiName = directory[(directory.LastIndexOf(".") + 1)..];
var directoryName = directory[(directory.LastIndexOf("\\") + 1)..];
apiName = apiName.Replace("Resources", "Resource");
apiName = apiName.Replace("Notices", "Notice");
var apiContent = File.ReadAllText($"./{outputPath}/{directoryName}/api.ts");
var apiImplementations = apiRegex.Matches(apiContent);
var customBasePath = await GetCustomBasePath(directoryName);
foreach (var apiImplementation in apiImplementations)
{
var concreteApiName = apiImplementation.ToString().Replace("class ", "");
concreteApiNames.Add(concreteApiName);
combinationFileImports.Add($"import {{ {concreteApiName}Factory }} from './{directoryName}/api';");
if (first)
{
first = false;
combinationFileImports.Add($"import {{ Configuration }} from './{directoryName}/configuration';");
}
combinationFileExports.Add($"{concreteApiName}: {concreteApiName}Factory(new Configuration({{ 'accessToken': accessToken }}), '{customBasePath}', axios)");
}
}
combinationFileExports.Sort();
concreteApiNames.Sort();
await WriteCombinationFile(combinationFile, combinationFileImports, combinationFileExports);
await WriteIndexFile(indexFile, concreteApiNames);
}
private async Task WriteCombinationFile(string combinationFile, IEnumerable<string> combinationFileImports, IEnumerable<string> combinationFileExports)
{
var combinationFileText = "import { AxiosInstance } from 'axios';\n\n";
combinationFileText += string.Join('\n', combinationFileImports);
combinationFileText += "\n\n";
combinationFileText = await GetCustomCodeForCombinationFile(combinationFileText);
combinationFileText += @"function implementations(axios?: AxiosInstance) {
return {
";
combinationFileText += string.Join(",\n ", combinationFileExports);
combinationFileText += "\n };\n};\n\nexport default implementations;\n";
await File.WriteAllTextAsync(combinationFile, combinationFileText);
}
private async Task WriteIndexFile(string indexFile, IEnumerable<string> concreteApiNames)
{
var indexFileText = @"import implementations from './apis';
import instance from './axios-basic';
const apis = implementations(instance);
";
foreach (var concreteApiName in concreteApiNames)
{
indexFileText += $"export const {concreteApiName} = apis.{concreteApiName};\n";
}
indexFileText += "\nexport default apis;\n";
await File.WriteAllTextAsync(indexFile, indexFileText);
}
internal Task ExecuteCommand(string command)
{
var startInfo = new ProcessStartInfo
{
FileName = @"C:\Windows\System32\cmd.exe",
Arguments = "/c " + command,
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true,
};
using (var process = new Process
{
StartInfo = startInfo
})
{
process.Start();
var outputTask = process.StandardOutput.ReadToEndAsync();
var errorTask = process.StandardError.ReadToEndAsync();
Task.WaitAll(outputTask, errorTask);
Console.WriteLine(outputTask.Result);
Console.WriteLine(errorTask.Result);
return process.WaitForExitAsync();
}
}
internal abstract Task<string> GetSwaggerUrl(string domainName, string hostName, string key);
internal abstract Task<string> GetCustomBasePath(string directoryName);
internal abstract Task<string> GetCustomCodeForCombinationFile(string combinationFileText);
internal abstract Task<string> GetOutputPath();
public abstract Task<string> GetClientGenerator();
public abstract Task<IEnumerable<string>> GetApiNames();
}
}
using Coscine.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
namespace Coscine.CodeGen.CodeGenerator
{
public class CoscineCodeGenerator : CodeGenerator
{
private readonly IConfiguration _configuration;
public CoscineCodeGenerator(IConfiguration configuration)
{
this._configuration = configuration;
}
public async override Task<string> GetClientGenerator()
{
var jarDownloadLink = await _configuration.GetStringAsync("coscine/local/codegen/jarlink",
//"https://repo1.maven.org/maven2/io/swagger/codegen/v3/swagger-codegen-cli/3.0.27/swagger-codegen-cli-3.0.27.jar"
"https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/5.2.1/openapi-generator-cli-5.2.1.jar"
);
var webClient = new WebClient();
var jarFileName = await _configuration.GetStringAsync("coscine/local/codegen/jarpath", "codegen.jar");
await webClient.DownloadFileTaskAsync(new Uri(jarDownloadLink), jarFileName);
return jarFileName;
}
public async override Task<IEnumerable<string>> GetApiNames()
{
var apiPrefix = "coscine/apis/";
var keys = await _configuration.KeysAsync(apiPrefix);
return keys.Select((entry) => entry.Split('/')[2]).Distinct();
}
internal async override Task<string> GetOutputPath()
{
return await _configuration.GetStringAsync("coscine/local/codegen/outputpath", "Output");
}
internal override Task<string> GetSwaggerUrl(string domainName, string hostName, string key)
{
return Task.FromResult($"https://{hostName}.{domainName}/coscine/api/{key}/swagger/v1/swagger.json");
}
internal override Task<string> GetCustomBasePath(string directoryName)
{
return Task.FromResult($"https://' + getHostName() + '/coscine/api/{directoryName}");
}
internal override Task<string> GetCustomCodeForCombinationFile(string combinationFileText)
{
combinationFileText += "let accessToken = '';";
combinationFileText += @"
if (typeof coscine !== 'undefined') {
accessToken = coscine.authorization.bearer;
}
const getHostName = () => {
let hostName = typeof window !== 'undefined' ? window.location.hostname : 'coscine.rwth-aachen.de';
if (hostName.indexOf(':') !== -1) {
if (hostName.indexOf('https://') !== -1) {
hostName = hostName.replace('https://', '');
}
hostName = hostName.substr(0, hostName.indexOf(':'));
}
return hostName;
};
";
return Task.FromResult(combinationFileText);
}
}
}
using Coscine.Configuration;
using System;
using System.Net;
using System.Linq;
using System.Threading.Tasks;
using System.Diagnostics;
using System.IO;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using Coscine.CodeGen.CodeGenerator;
namespace Coscine.CodeGen
{
......@@ -14,168 +7,7 @@ namespace Coscine.CodeGen
{
public static void Main(string[] args)
{
GenerateCode().Wait();
}
public static async Task GenerateCode()
{
var configuration = new ConsulConfiguration();
var jarDownloadLink = await configuration.GetStringAsync("coscine/local/codegen/jarlink",
//"https://repo1.maven.org/maven2/io/swagger/codegen/v3/swagger-codegen-cli/3.0.27/swagger-codegen-cli-3.0.27.jar"
"https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/5.2.1/openapi-generator-cli-5.2.1.jar"
);
var webClient = new WebClient();
var jarFileName = await configuration.GetStringAsync("coscine/local/codegen/jarpath", "codegen.jar");
await webClient.DownloadFileTaskAsync(new Uri(jarDownloadLink), jarFileName);
var apiPrefix = "coscine/apis/";
var keys = await configuration.KeysAsync(apiPrefix);
var domainName = System.Net.NetworkInformation.IPGlobalProperties.GetIPGlobalProperties().DomainName;
var hostName = Dns.GetHostName();
var outputPath = await configuration.GetStringAsync("coscine/local/codegen/outputpath", "Output");
if (!Directory.Exists(outputPath))
{
Directory.CreateDirectory(outputPath);
}
foreach (var key in keys.Select((entry) => entry.Split('/')[2]).Distinct())
{
Console.WriteLine(key);
var swaggerUrl = $"https://{hostName}.{domainName}/coscine/api/{key}/swagger/v1/swagger.json";
var command = $"java \"-Dio.swagger.parser.util.RemoteUrl.trustAll=true\" \"-Dio.swagger.v3.parser.util.RemoteUrl.trustAll=true\" -jar \"{jarFileName}\" generate -i \"{swaggerUrl}\" -g typescript-axios -o \"{outputPath}/{key}\" --skip-validate-spec";
await ExecuteCommand(command);
}
var combinationFile = outputPath + "/apis.ts";
var indexFile = outputPath + "/index.ts";
var combinationFileImports = new List<string>();
var combinationFileExports = new List<string>();
var concreteApiNames = new List<string>();
var first = true;
var apiRegex = new Regex("(?<= )(.*?)(?= extends BaseAPI)");
foreach (var directory in Directory.GetDirectories(outputPath))
{
var apiName = directory[(directory.LastIndexOf(".") + 1)..];
var directoryName = directory[(directory.LastIndexOf("\\") + 1)..];
apiName = apiName.Replace("Resources", "Resource");
apiName = apiName.Replace("Notices", "Notice");
var apiContent = File.ReadAllText($"./{outputPath}/{directoryName}/api.ts");
var apiImplementations = apiRegex.Matches(apiContent);
foreach (var apiImplementation in apiImplementations)
{
var concreteApiName = apiImplementation.ToString().Replace("class ", "");
concreteApiNames.Add(concreteApiName);
combinationFileImports.Add($"import {{ {concreteApiName}Factory }} from './{directoryName}/api';");
if (first)
{
first = false;
combinationFileImports.Add($"import {{ Configuration }} from './{directoryName}/configuration';");
}
combinationFileExports.Add($"{concreteApiName}: {concreteApiName}Factory(new Configuration({{ 'accessToken': accessToken }}), 'https://' + getHostName() + '/coscine/api/{directoryName}', axios)");
}
}
combinationFileExports.Sort();
concreteApiNames.Sort();
var combinationFileText = "import { AxiosInstance } from 'axios';\n\n";
combinationFileText += string.Join('\n', combinationFileImports);
combinationFileText += "\n\n";
combinationFileText += "let accessToken = '';";
combinationFileText += @"
if (typeof coscine !== 'undefined') {
accessToken = coscine.authorization.bearer;
}
const getHostName = () => {
let hostName = typeof window !== 'undefined' ? window.location.hostname : 'coscine.rwth-aachen.de';
if (hostName.indexOf(':') !== -1) {
if (hostName.indexOf('https://') !== -1) {
hostName = hostName.replace('https://', '');
}
hostName = hostName.substr(0, hostName.indexOf(':'));
}
return hostName;
};
";
combinationFileText += @"function implementations(axios?: AxiosInstance) {
return {
";
combinationFileText += string.Join(",\n ", combinationFileExports);
combinationFileText += "\n };\n};\n\nexport default implementations;\n";
await File.WriteAllTextAsync(combinationFile, combinationFileText);
var indexFileText = @"import implementations from './apis';
import instance from './axios-basic';
const apis = implementations(instance);
";
foreach (var concreteApiName in concreteApiNames)
{
indexFileText += $"export const {concreteApiName} = apis.{concreteApiName};\n";
}
indexFileText += "\nexport default apis;\n";
await File.WriteAllTextAsync(indexFile, indexFileText);
}
private static Task ExecuteCommand(string command)
{
var startInfo = new ProcessStartInfo
{
FileName = @"C:\Windows\System32\cmd.exe",
Arguments = "/c " + command,
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true,
};
using (var process = new Process
{
StartInfo = startInfo
})
{
process.Start();
var outputTask = process.StandardOutput.ReadToEndAsync();
var errorTask = process.StandardError.ReadToEndAsync();
Task.WaitAll(outputTask, errorTask);
Console.WriteLine(outputTask.Result);
Console.WriteLine(errorTask.Result);
return process.WaitForExitAsync();
}
new CoscineCodeGenerator(new ConsulConfiguration()).GenerateCode().GetAwaiter().GetResult();
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment