Import from internal git
This commit is contained in:
28
Generator/Controllers/AnalyzeController.cs
Normal file
28
Generator/Controllers/AnalyzeController.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using Core;
|
||||
using Core.Events;
|
||||
using Core.Interfaces;
|
||||
using Generator.Services;
|
||||
|
||||
namespace Generator.Controllers;
|
||||
|
||||
public class AnalyzeController : IController
|
||||
{
|
||||
private readonly AnalyzeService _analyzeService;
|
||||
public DisplayEmitter Emitter { get; set; }
|
||||
|
||||
public AnalyzeController(DisplayEmitter emitter, AnalyzeService service)
|
||||
{
|
||||
_analyzeService = service;
|
||||
Emitter = emitter;
|
||||
}
|
||||
|
||||
public string GetSpecText(string folder, string spec) => _analyzeService.GetSpecText(folder, spec);
|
||||
|
||||
public bool CanBeGenerated(string folder, string spec)
|
||||
{
|
||||
return _analyzeService.CanBeGenerated(folder, spec);
|
||||
}
|
||||
|
||||
public IEnumerable<Location> ListSpecs() => _analyzeService.ListSpecs();
|
||||
|
||||
}
|
||||
31
Generator/Controllers/ExportController.cs
Normal file
31
Generator/Controllers/ExportController.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using Core;
|
||||
using Core.Events;
|
||||
using Core.Interfaces;
|
||||
using Generator.Services;
|
||||
using Generator.views;
|
||||
|
||||
namespace Generator.Controllers;
|
||||
|
||||
public class ExportController : IController
|
||||
{
|
||||
private readonly ExportService _exportService;
|
||||
public DisplayEmitter Emitter { get; set; }
|
||||
|
||||
public ExportController(DisplayEmitter emitter, ExportService service)
|
||||
{
|
||||
_exportService = service;
|
||||
Emitter = emitter;
|
||||
}
|
||||
|
||||
public void PlantUml(ISpecFile file)
|
||||
{
|
||||
try
|
||||
{
|
||||
_exportService.ExportAsPuml(file);
|
||||
} catch (Exception e)
|
||||
{
|
||||
Emitter.Warn(this, $"{e.Message} \n Cause : {e.Source} \n Full stacktrace : \n {e.StackTrace}");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
30
Generator/Controllers/GenerationController.cs
Normal file
30
Generator/Controllers/GenerationController.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using Core.Events;
|
||||
using Core.Interfaces;
|
||||
using Core.Process;
|
||||
using Generator.Services;
|
||||
|
||||
namespace Generator.Controllers;
|
||||
|
||||
public class GenerationController : IController
|
||||
{
|
||||
private readonly GenerationService _genService;
|
||||
public DisplayEmitter Emitter { get; set; }
|
||||
|
||||
public GenerationController(DisplayEmitter emitter, GenerationService service)
|
||||
{
|
||||
_genService = service;
|
||||
Emitter = emitter;
|
||||
}
|
||||
|
||||
public async Task Launch(GenerationProcess process)
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach (var task in process) await _genService.Launch(task);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Emitter.Warn(this, $"{e.Message} \n Cause : {e.Source} \n Full stacktrace : \n {e.StackTrace}");
|
||||
}
|
||||
}
|
||||
}
|
||||
37
Generator/Controllers/PreGenerationController.cs
Normal file
37
Generator/Controllers/PreGenerationController.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using Core;
|
||||
using Core.Events;
|
||||
using Core.Interfaces;
|
||||
using Core.Process;
|
||||
using Core.SpecConfig;
|
||||
using Generator.Services;
|
||||
using Generator.views;
|
||||
|
||||
namespace Generator.Controllers;
|
||||
|
||||
public class PreGenerationController : IController
|
||||
{
|
||||
private readonly PreGenerationService _preGenService;
|
||||
private readonly ConsoleView _view;
|
||||
public DisplayEmitter Emitter { get; set; }
|
||||
|
||||
public PreGenerationController(DisplayEmitter emitter, PreGenerationService preGenService)
|
||||
{
|
||||
_view = new ConsoleView();
|
||||
_preGenService = preGenService;
|
||||
Emitter = emitter;
|
||||
}
|
||||
|
||||
public GenerationProcess ComputeGeneration(string specPath, GenerationType? generationType, PublishType publishType)
|
||||
{
|
||||
try
|
||||
{
|
||||
return _preGenService.ComputeGeneration(specPath, generationType, publishType);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Emitter.Warn(this, e.Message);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
33
Generator/Controllers/PublicationController.cs
Normal file
33
Generator/Controllers/PublicationController.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using Core.Events;
|
||||
using Core.Interfaces;
|
||||
using Core.Process;
|
||||
using Generator.Services;
|
||||
using Generator.views;
|
||||
|
||||
namespace Generator.Controllers;
|
||||
|
||||
public class PublicationController : IController
|
||||
{
|
||||
|
||||
private readonly PublicationService _pubService;
|
||||
public DisplayEmitter Emitter { get; set; }
|
||||
|
||||
public PublicationController(DisplayEmitter emitter, PublicationService pubService)
|
||||
{
|
||||
_pubService = pubService;
|
||||
Emitter = emitter;
|
||||
}
|
||||
|
||||
public async Task Publish(GenerationProcess process)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _pubService.Publish(process);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Emitter.Warn(this, $"{e.Message} \n Cause : {e.Source} \n Full stacktrace : \n {e.StackTrace}");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
17
Generator/Daos/AbstractDao.cs
Normal file
17
Generator/Daos/AbstractDao.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using Generator.DataSource.Settings;
|
||||
|
||||
namespace Generator.Daos;
|
||||
|
||||
public abstract class AbstractDao
|
||||
{
|
||||
protected readonly ConfigManager ConfManager;
|
||||
|
||||
protected AbstractDao(ConfigManager confManager, string spec)
|
||||
{
|
||||
ConfManager = confManager;
|
||||
}
|
||||
|
||||
protected AbstractDao(ConfigManager confManager) : this(confManager, confManager.GetDefArgs().SpecIdentifier)
|
||||
{ }
|
||||
|
||||
}
|
||||
19
Generator/Daos/CredentialsDao.cs
Normal file
19
Generator/Daos/CredentialsDao.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using Core.Actions;
|
||||
using Generator.DataSource.Settings;
|
||||
using Generator.Mappers;
|
||||
|
||||
namespace Generator.Daos;
|
||||
|
||||
public class CredentialsDao : AbstractDao
|
||||
{
|
||||
public string Username => ConfManager.Credentials.Username;
|
||||
public string Password => ConfManager.Credentials.Password;
|
||||
|
||||
public CredentialsDao(ConfigManager confManager)
|
||||
: base(confManager, confManager.GetDefArgs().SpecIdentifier)
|
||||
{
|
||||
}
|
||||
|
||||
public PackageDeletion GetPackageDeletion() => ConfManager.Credentials.ToPackageDeletion();
|
||||
|
||||
}
|
||||
40
Generator/Daos/DotnetDao.cs
Normal file
40
Generator/Daos/DotnetDao.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
using Core;
|
||||
using Core.Actions;
|
||||
using Core.Settings;
|
||||
using Core.SpecConfig;
|
||||
using Generator.DataSource.Settings;
|
||||
using Generator.Mappers;
|
||||
|
||||
namespace Generator.Daos;
|
||||
|
||||
public class DotnetDao : AbstractDao
|
||||
{
|
||||
|
||||
public DotnetDao(ConfigManager confManager)
|
||||
: base(confManager, confManager.GetDefArgs().SpecIdentifier)
|
||||
{
|
||||
}
|
||||
|
||||
public DotnetConfig GetDotnetGenerate(GenerationType type, ISpecFile file)
|
||||
{
|
||||
var config = ConfManager.Dotnet.Map(ConfManager, file);
|
||||
config.Type = type;
|
||||
return config ;
|
||||
}
|
||||
|
||||
public DotnetPublish GetDotnetPublish(GenerationType type, ISpecFile file)
|
||||
{
|
||||
var d = GetDotnetGenerate(type, file);
|
||||
return new DotnetPublish
|
||||
{
|
||||
LocalRoot = d.LocalRoot,
|
||||
DockerRoot = d.DockerRoot,
|
||||
Image = d.BuildImage,
|
||||
Registry = d.Registry,
|
||||
PackageFolder = d.PackageFolderPath(),
|
||||
PackageVersion = file.Version,
|
||||
PackageFile = d.PackageFile,
|
||||
AuthorizationToken = d.AuthorizationToken,
|
||||
};
|
||||
}
|
||||
}
|
||||
14
Generator/Daos/EnvironmentDao.cs
Normal file
14
Generator/Daos/EnvironmentDao.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using Core;
|
||||
using Generator.DataSource.Settings;
|
||||
|
||||
namespace Generator.Daos;
|
||||
|
||||
public class EnvironmentDao : AbstractDao
|
||||
{
|
||||
public Location ApiFolder() => new ([ConfManager.GetBase().LocalRoot, ConfManager.GetGeneral().ApiFolder]);
|
||||
|
||||
public string Invite => ConfManager.GetBase().Invite;
|
||||
|
||||
public EnvironmentDao(ConfigManager confManager) : base(confManager)
|
||||
{ }
|
||||
}
|
||||
37
Generator/Daos/JavaDao.cs
Normal file
37
Generator/Daos/JavaDao.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using Core;
|
||||
using Core.Actions;
|
||||
using Core.Settings;
|
||||
using Core.SpecConfig;
|
||||
using Generator.DataSource.Settings;
|
||||
using Generator.Mappers;
|
||||
|
||||
namespace Generator.Daos;
|
||||
|
||||
public class JavaDao : AbstractDao
|
||||
{
|
||||
|
||||
public JavaDao(ConfigManager confManager) : base(confManager)
|
||||
{ }
|
||||
|
||||
public JavaConfig GetJavaGenerate(ISpecFile file) => ConfManager.Java.Map(ConfManager, file);
|
||||
|
||||
public JavaPublish GetJavaPublish(GenerationType type, ISpecFile file)
|
||||
{
|
||||
var config = GetJavaGenerate(file);
|
||||
return new JavaPublish
|
||||
{
|
||||
LocalRoot = config.LocalRoot,
|
||||
DockerRoot = config.DockerRoot,
|
||||
Image = config.BuildImage,
|
||||
Registry = config.Registry,
|
||||
TemplateFolder = config.TemplateFolder,
|
||||
OutputFolder = config.OutputFolder(),
|
||||
Group = file.MavenGroup,
|
||||
Artifact = config.Artifact,
|
||||
Version = config.Version,
|
||||
Username = config.Username,
|
||||
Password = config.Password,
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
35
Generator/Daos/JavascriptDao.cs
Normal file
35
Generator/Daos/JavascriptDao.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
using Core;
|
||||
using Core.Actions;
|
||||
using Core.Settings;
|
||||
using Core.SpecConfig;
|
||||
using Generator.DataSource.Settings;
|
||||
using Generator.Mappers;
|
||||
|
||||
namespace Generator.Daos;
|
||||
|
||||
public class JavascriptDao : AbstractDao
|
||||
{
|
||||
|
||||
public JavascriptDao(ConfigManager confManager) : base(confManager, confManager.GetDefArgs().SpecIdentifier)
|
||||
{ }
|
||||
|
||||
public JavascriptConfig GetJavascript(ISpecFile file) => ConfManager.Javascript.Map(ConfManager, file);
|
||||
|
||||
public JavascriptPublish GetJavascriptPublish(GenerationType type, ISpecFile file)
|
||||
{
|
||||
var j = GetJavascript(file);
|
||||
return new JavascriptPublish
|
||||
{
|
||||
LocalRoot = j.LocalRoot,
|
||||
DockerRoot = j.DockerRoot,
|
||||
Image = j.BuildImage,
|
||||
|
||||
Registry = j.Registry,
|
||||
PackageName = j.PackageName,
|
||||
Version = file.Version,
|
||||
SpecFile = j.OpenApiSpecFile(),
|
||||
FrontFolder = j.OutputFolder(),
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
23
Generator/Daos/OpenApiDao.cs
Normal file
23
Generator/Daos/OpenApiDao.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using Core;
|
||||
using Core.Settings;
|
||||
using Generator.DataSource.Settings;
|
||||
using Generator.Mappers;
|
||||
|
||||
namespace Generator.Daos;
|
||||
|
||||
public class OpenApiDao : AbstractDao
|
||||
{
|
||||
|
||||
public OpenApiDao(ConfigManager confManager) : base(confManager)
|
||||
{ }
|
||||
|
||||
public Location ConfigOf(string spec) => GetOpenApi(true, spec).SpecConfig;
|
||||
|
||||
public OpenApiConfig GetOpenApi(bool isLocal, string file)
|
||||
{
|
||||
var items = file.Split("/");
|
||||
var o = ConfManager.OpenApi.Map(ConfManager, items[0], items[1]);
|
||||
o.AddRoot(ConfManager.GetRoot(isLocal));
|
||||
return o;
|
||||
}
|
||||
}
|
||||
23
Generator/Daos/TemplateDao.cs
Normal file
23
Generator/Daos/TemplateDao.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using Core;
|
||||
using Core.Actions;
|
||||
using Generator.DataSource.Settings;
|
||||
using Generator.Mappers;
|
||||
|
||||
namespace Generator.Daos;
|
||||
|
||||
public class TemplateDao : AbstractDao
|
||||
{
|
||||
public TemplateDao(ConfigManager confManager) : base(confManager)
|
||||
{ }
|
||||
|
||||
public PlantUmlExport PlantUml(ISpecFile file)
|
||||
{
|
||||
var config = ConfManager.Templates.Map();
|
||||
return new PlantUmlExport
|
||||
{
|
||||
LocalRoot = ConfManager.GetBase().LocalRoot,
|
||||
Template = config.PlantUml,
|
||||
Output = ConfManager.GetGeneral().ApiFolder.ConcatenateWith([file.Folder, $"{file.Name}.puml"])
|
||||
};
|
||||
}
|
||||
}
|
||||
46
Generator/DataSource/JsonLoader.cs
Normal file
46
Generator/DataSource/JsonLoader.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
using Core.Dto.Settings;
|
||||
using Core.Interfaces;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
namespace Generator.DataSource;
|
||||
|
||||
/// <summary>
|
||||
/// Provides some methods to load json objects from a json data source
|
||||
/// </summary>
|
||||
public class JsonLoader : IDataSourceLoader
|
||||
{
|
||||
private readonly IServiceCollection _services;
|
||||
private readonly IConfiguration _configuration;
|
||||
|
||||
|
||||
public JsonLoader(IServiceCollection services, IConfiguration configuration)
|
||||
{
|
||||
_services = services;
|
||||
_configuration = configuration;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load data that can be found in appsettings.json
|
||||
/// </summary>
|
||||
public void LoadAppsettings()
|
||||
{
|
||||
_services.AddOptions<EnvironmentConfigDto>().Bind(_configuration.GetSection("Environment"));
|
||||
_services.AddOptions<DefaultArgumentsConfigDto>().Bind(_configuration.GetSection("DefaultArguments"));
|
||||
_services.AddOptions<GeneralConfigDto>().Bind(_configuration.GetSection("General"));
|
||||
|
||||
_services.AddOptions<PublishConfigDto>().Bind(_configuration.GetSection("Publish"));
|
||||
_services.AddOptions<CredentialsConfigDto>().Bind(_configuration.GetSection("Credentials"));
|
||||
|
||||
_services.AddOptions<DockerImagesConfigDto>().Bind(_configuration.GetSection("DockerImages"));
|
||||
|
||||
_services.AddOptions<JavaConfigDto>().Bind(_configuration.GetSection("Java"));
|
||||
_services.AddOptions<DotnetConfigDto>().Bind(_configuration.GetSection("Dotnet"));
|
||||
_services.AddOptions<JavascriptConfigDto>().Bind(_configuration.GetSection("Javascript"));
|
||||
_services.AddOptions<OpenApiConfigDto>().Bind(_configuration.GetSection("OpenApi"));
|
||||
|
||||
_services.AddOptions<TemplatesConfigDto>().Bind(_configuration.GetSection("Templates"));
|
||||
}
|
||||
}
|
||||
64
Generator/DataSource/Settings/ConfigManager.cs
Normal file
64
Generator/DataSource/Settings/ConfigManager.cs
Normal file
@@ -0,0 +1,64 @@
|
||||
using Core;
|
||||
using Core.Dto;
|
||||
using Core.Dto.Settings;
|
||||
using Core.Settings;
|
||||
using Generator.Mappers;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Generator.DataSource.Settings;
|
||||
|
||||
/// <summary>
|
||||
/// This class is intended to encapsulate configurations objects
|
||||
/// </summary>
|
||||
public class ConfigManager
|
||||
{
|
||||
private readonly ArgumentsDto _args;
|
||||
|
||||
private readonly EnvironmentConfigDto _env;
|
||||
private readonly DefaultArgumentsConfigDto _defArgs;
|
||||
private readonly GeneralConfigDto _general;
|
||||
|
||||
public readonly DockerImagesConfigDto DockerImages;
|
||||
public readonly TemplatesConfigDto Templates;
|
||||
public readonly PublishConfigDto Publish;
|
||||
public readonly CredentialsConfigDto Credentials;
|
||||
public readonly DotnetConfigDto Dotnet;
|
||||
public readonly JavaConfigDto Java;
|
||||
public readonly JavascriptConfigDto Javascript;
|
||||
public readonly OpenApiConfigDto OpenApi;
|
||||
|
||||
public ConfigManager(
|
||||
ArgumentsDto args,
|
||||
IOptions<EnvironmentConfigDto> env,
|
||||
IOptions<DefaultArgumentsConfigDto> defArgs,
|
||||
IOptions<GeneralConfigDto> general,
|
||||
IOptions<PublishConfigDto> publish,
|
||||
IOptions<CredentialsConfigDto> creds,
|
||||
IOptions<DockerImagesConfigDto> images,
|
||||
IOptions<DotnetConfigDto> dotnet,
|
||||
IOptions<JavaConfigDto> java,
|
||||
IOptions<JavascriptConfigDto> javascript,
|
||||
IOptions<OpenApiConfigDto> openapi,
|
||||
IOptions<TemplatesConfigDto> templates)
|
||||
{
|
||||
_args = args;
|
||||
_env = env.Value;
|
||||
Publish = publish.Value;
|
||||
Credentials = creds.Value;
|
||||
_defArgs = defArgs.Value;
|
||||
_general = general.Value;
|
||||
|
||||
DockerImages = images.Value;
|
||||
Templates = templates.Value;
|
||||
Dotnet = dotnet.Value;
|
||||
Java = java.Value;
|
||||
Javascript = javascript.Value;
|
||||
OpenApi = openapi.Value;
|
||||
}
|
||||
|
||||
public BaseConfig GetBase() => _env.Map();
|
||||
public DefaultArgumentsConfig GetDefArgs() => _defArgs.Map(_args);
|
||||
public GeneralConfig GetGeneral() => _general.Map();
|
||||
public Location GetRoot(bool isLocal) => isLocal ? GetBase().LocalRoot : GetBase().DockerRoot;
|
||||
|
||||
}
|
||||
109
Generator/DataSource/Yaml/OpenApiYamlExtractor.cs
Normal file
109
Generator/DataSource/Yaml/OpenApiYamlExtractor.cs
Normal file
@@ -0,0 +1,109 @@
|
||||
using System.Text.RegularExpressions;
|
||||
using Core;
|
||||
using Core.Dto.Yaml;
|
||||
using Core.Exceptions;
|
||||
using Core.Helpers;
|
||||
using Core.Yaml;
|
||||
using Generator.Mappers;
|
||||
using Newtonsoft.Json;
|
||||
using YamlDotNet.Serialization;
|
||||
|
||||
namespace Generator.DataSource.Yaml;
|
||||
|
||||
public class OpenApiYamlExtractor
|
||||
{
|
||||
/// <summary>
|
||||
/// Retrieves an openapi-formatted yaml at a specific location
|
||||
/// </summary>
|
||||
/// <param name="path">file location</param>
|
||||
/// <returns></returns>
|
||||
public OpenApiYaml ExtractNode(string path)
|
||||
{
|
||||
var text = PathHelper.TextFrom(path);
|
||||
var deserializer = new DeserializerBuilder()
|
||||
.IgnoreUnmatchedProperties()
|
||||
.Build();
|
||||
|
||||
var dto = deserializer.Deserialize<OpenApiYamlDto>(text);
|
||||
return dto.ToModel(path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads all configs that can be found in the config file located at the given path
|
||||
/// </summary>
|
||||
/// <param name="configPath">Given path</param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="InvalidOperationException">When config file couldn't has been deserialize</exception>
|
||||
/// <exception cref="ConfigException">When the given path does not exists</exception>
|
||||
public Dictionary<string, YamlConfig> LoadConfigs(string configPath)
|
||||
{
|
||||
try
|
||||
{
|
||||
var json = PathHelper.TextFrom(configPath);
|
||||
var configDto = JsonConvert.DeserializeObject<SpecConfigDto>(json);
|
||||
return (configDto ?? throw new InvalidOperationException()).Map();
|
||||
}
|
||||
catch (FileNotFoundException)
|
||||
{
|
||||
throw new ConfigException($"No config file found at {configPath}. Fix it or i'll never generate anything for you");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extract all scoped references of a specification file. In other words, this will extracts all references
|
||||
/// between the given spec file and the closer reference-related schemas, including paths and params files
|
||||
/// </summary>
|
||||
/// <param name="filePath">Given file path</param>
|
||||
/// <returns></returns>
|
||||
public ISet<string> ExtractScopedRefs(string filePath) => ExtractRefs(filePath, false, new HashSet<string>());
|
||||
|
||||
/// <summary>
|
||||
/// Extract all possibles references from a given specification file
|
||||
/// </summary>
|
||||
/// <param name="filePath">Given file path</param>
|
||||
/// <returns></returns>
|
||||
public ISet<string> ExtractAllRefs(string filePath) => ExtractRefs(filePath, true, new HashSet<string>());
|
||||
|
||||
|
||||
private ISet<string> ExtractRefs(string filePath, bool deepSearch, ISet<string> refs)
|
||||
{
|
||||
const string pattern = """(\$ref):\s{1}['|"](.+)['|"]""";
|
||||
var text = PathHelper.TextFrom(filePath);
|
||||
var matches = Regex.Matches(text, pattern);
|
||||
|
||||
foreach (Match m in matches)
|
||||
{
|
||||
var rawReference = m.Groups[2].Value;
|
||||
var absolutePath = AbsolutePathFromRef(filePath, rawReference);
|
||||
|
||||
//If path references itself or circular dependency is detected
|
||||
if (absolutePath == string.Empty || refs.Contains(absolutePath)) continue;
|
||||
|
||||
if (!deepSearch && IsSchema(absolutePath))
|
||||
{
|
||||
refs.Add(absolutePath);
|
||||
continue;
|
||||
}
|
||||
|
||||
var subRefs = ExtractRefs(absolutePath, deepSearch, refs);
|
||||
refs.UnionWith(subRefs);
|
||||
refs.Add(absolutePath);
|
||||
}
|
||||
return refs;
|
||||
}
|
||||
|
||||
|
||||
private string AbsolutePathFromRef(string relative, string reference)
|
||||
{
|
||||
var result = PathHelper.GetFolder(relative) + reference;
|
||||
var r = result.Split("#")[0];
|
||||
return r[^1].Equals('/') ? string.Empty : PathHelper.AbsolutePath(r);
|
||||
}
|
||||
|
||||
private bool IsSchema(string path)
|
||||
{
|
||||
var l = new Location(path);
|
||||
return l.LastElement().Contains("schemas");
|
||||
}
|
||||
|
||||
}
|
||||
164
Generator/DataSource/Yaml/YamlBuilder.cs
Normal file
164
Generator/DataSource/Yaml/YamlBuilder.cs
Normal file
@@ -0,0 +1,164 @@
|
||||
using System.Text;
|
||||
using Core;
|
||||
using Core.Helpers;
|
||||
using Core.Yaml;
|
||||
using MoreLinq;
|
||||
|
||||
namespace Generator.DataSource.Yaml;
|
||||
|
||||
public class YamlBuilder
|
||||
{
|
||||
private OpenApiYaml _file;
|
||||
private bool _isSubNode;
|
||||
|
||||
private readonly string _configIdentifier;
|
||||
private readonly Dictionary<string, YamlConfig> _configs;
|
||||
private readonly OpenApiYamlExtractor _extractor;
|
||||
|
||||
public YamlBuilder(string filePath, string configIdentifier)
|
||||
{
|
||||
_isSubNode = false;
|
||||
_configIdentifier = configIdentifier;
|
||||
_file = new OpenApiYaml(filePath);
|
||||
_configs = new Dictionary<string, YamlConfig>();
|
||||
_extractor = new OpenApiYamlExtractor();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds all raw references to the object to build
|
||||
/// </summary>
|
||||
public void AddReferences()
|
||||
{
|
||||
var scopedRefs = _extractor.ExtractScopedRefs(_file.Location.ToString());
|
||||
var allRefs = _extractor.ExtractAllRefs(_file.Location.ToString());
|
||||
_file.ScopedRefs = scopedRefs;
|
||||
_file.OutScopedRefs = allRefs;
|
||||
_file.OutScopedRefs.ExceptWith(scopedRefs);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attributes the dedicated config file to the object to build
|
||||
/// </summary>
|
||||
public void SelectConfig()
|
||||
{
|
||||
if (_configs.ContainsKey(_file.Location.GetFileName()))
|
||||
{
|
||||
_file.Config = _configs[_file.Location.GetFileName()];
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception($"{_file.Location} cannot be generated. You either made a typo " +
|
||||
$"or forgot to register file in {GetConfig(_file.Location)}");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds all built schemas to the object to build
|
||||
/// </summary>
|
||||
public void AddSchema()
|
||||
{
|
||||
using var enumerator = _file.ScopedRefs.GetEnumerator();
|
||||
while (enumerator.MoveNext())
|
||||
{
|
||||
var loc = new Location(enumerator.Current);
|
||||
var fileName = loc.GetFileName();
|
||||
|
||||
if(!_configs.ContainsKey(fileName)) continue;
|
||||
|
||||
var schema = _isSubNode ?
|
||||
_extractor.ExtractNode(loc.ToString())
|
||||
: CreateSubNode(loc.ToString());
|
||||
|
||||
schema.Config = _configs[fileName];
|
||||
_file.ReferencedSchemas.Add(schema);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the models that will be ignored to the object to build
|
||||
/// </summary>
|
||||
public void AddIgnoredModels()
|
||||
{
|
||||
foreach (var reference in _file.Refs)
|
||||
{
|
||||
var loc = new Location(reference);
|
||||
var schema = _extractor.ExtractNode(loc.ToString());
|
||||
_file.IgnoredModels.UnionWith(schema.Models);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Simply output the object to build
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public OpenApiYaml Create() => _file;
|
||||
|
||||
/// <summary>
|
||||
/// Loads the object to build
|
||||
/// </summary>
|
||||
public void LoadSpec()
|
||||
{
|
||||
_file = _extractor.ExtractNode(_file.Location.ToString());
|
||||
_file.Openapi = _file.Openapi;
|
||||
if (_file.Info != null) _file.Info = new Dictionary<string, object>(_file.Info);
|
||||
_file.Tags = _file.Tags == null ? new List<object>() : [.._file.Tags];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load all the found config files into the builder
|
||||
/// </summary>
|
||||
public void LoadConfigs()
|
||||
{
|
||||
LoadConfig(_file.Location);
|
||||
foreach (var reference in _file.Refs) LoadConfig(new Location(reference));
|
||||
}
|
||||
|
||||
private void LoadConfig(Location path)
|
||||
{
|
||||
var configPath = GetConfig(path)?.ToString();
|
||||
|
||||
if (configPath == null || _configs.ContainsKey(path.GetFileName())) return;
|
||||
|
||||
_extractor.LoadConfigs(configPath)
|
||||
.ForEach(c => _configs.TryAdd(c.Key, c.Value));
|
||||
}
|
||||
|
||||
private void SetForSubNode() => _isSubNode = true;
|
||||
|
||||
private OpenApiYaml CreateSubNode(string path)
|
||||
{
|
||||
var yamlBuilder = new YamlBuilder(path, _configIdentifier);
|
||||
|
||||
yamlBuilder.SetForSubNode();
|
||||
yamlBuilder.LoadSpec();
|
||||
yamlBuilder.AddReferences();
|
||||
yamlBuilder.LoadConfigs();
|
||||
yamlBuilder.AddSchema();
|
||||
yamlBuilder.AddIgnoredModels();
|
||||
return yamlBuilder.Create();
|
||||
}
|
||||
|
||||
private Location? GetConfig(Location loc)
|
||||
{
|
||||
var spec = loc.GetFolder();
|
||||
var pathItems = loc.Path.Split(['/', '\\']);
|
||||
pathItems[^1] = spec + _configIdentifier;
|
||||
|
||||
var builder = new StringBuilder();
|
||||
builder.AppendJoin("/", pathItems);
|
||||
|
||||
var configPath = builder.ToString();
|
||||
|
||||
try
|
||||
{
|
||||
PathHelper.CheckPathValidity(configPath);
|
||||
}
|
||||
catch (FileNotFoundException)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return new Location(configPath);
|
||||
}
|
||||
}
|
||||
36
Generator/DataSource/Yaml/YamlDirector.cs
Normal file
36
Generator/DataSource/Yaml/YamlDirector.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using Core;
|
||||
using Core.Yaml;
|
||||
using Generator.Daos;
|
||||
|
||||
namespace Generator.DataSource.Yaml;
|
||||
|
||||
public class YamlDirector
|
||||
{
|
||||
|
||||
private readonly OpenApiDao _openApiDao;
|
||||
|
||||
public YamlDirector(OpenApiDao openApiDao)
|
||||
{
|
||||
_openApiDao = openApiDao;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Build a yaml object lmao what do you want me to say ? All the information's are in the method signature
|
||||
/// </summary>
|
||||
/// <param name="specPath"></param>
|
||||
/// <returns></returns>
|
||||
public OpenApiYaml BuildYaml(string specPath)
|
||||
{
|
||||
var openApiConfig = _openApiDao.GetOpenApi(true, specPath);
|
||||
var yamlBuilder = new YamlBuilder(openApiConfig.SpecFile.ToString(), openApiConfig.ConfigIdentifier);
|
||||
|
||||
yamlBuilder.LoadSpec();
|
||||
yamlBuilder.AddReferences();
|
||||
yamlBuilder.LoadConfigs();
|
||||
yamlBuilder.SelectConfig();
|
||||
yamlBuilder.AddSchema();
|
||||
yamlBuilder.AddIgnoredModels();
|
||||
|
||||
return yamlBuilder.Create();
|
||||
}
|
||||
}
|
||||
26
Generator/Generator.csproj
Normal file
26
Generator/Generator.csproj
Normal file
@@ -0,0 +1,26 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<RootNamespace>Generator</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CommandLineParser" Version="2.9.1" />
|
||||
<PackageReference Include="Microsoft.OpenApi" Version="1.6.13" />
|
||||
<PackageReference Include="Microsoft.OpenApi.Readers" Version="1.6.13" />
|
||||
<PackageReference Include="Moq" Version="4.20.70" />
|
||||
<PackageReference Include="mustache-sharp" Version="1.0.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="NUnit" Version="4.1.0" />
|
||||
<PackageReference Include="Services.Common" Version="1.0.0" />
|
||||
<PackageReference Include="YamlDotNet" Version="15.1.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Core\Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
89
Generator/GeneratorHostedService.cs
Normal file
89
Generator/GeneratorHostedService.cs
Normal file
@@ -0,0 +1,89 @@
|
||||
using Core;
|
||||
using Core.Dto;
|
||||
using Core.Events;
|
||||
using Generator.Controllers;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Generator;
|
||||
|
||||
public class GeneratorHostedService : IHostedService
|
||||
{
|
||||
private readonly ArgumentsDto _args;
|
||||
private readonly IHostApplicationLifetime _applicationLifetime;
|
||||
private readonly ILogger<GeneratorHostedService> _logger;
|
||||
private readonly PreGenerationController _preGenController;
|
||||
private readonly GenerationController _genController;
|
||||
private readonly ExportController _exportController;
|
||||
|
||||
public GeneratorHostedService(
|
||||
ArgumentsDto args,
|
||||
IHostApplicationLifetime applicationLifetime,
|
||||
ILogger<GeneratorHostedService> logger,
|
||||
PreGenerationController preGenController,
|
||||
GenerationController genController,
|
||||
ExportController exportController)
|
||||
{
|
||||
_args = args;
|
||||
_applicationLifetime = applicationLifetime;
|
||||
_logger = logger;
|
||||
_preGenController = preGenController;
|
||||
_genController = genController;
|
||||
_exportController = exportController;
|
||||
|
||||
_genController.Emitter.OnSay += Display;
|
||||
_genController.Emitter.OnWarn += Warn;
|
||||
}
|
||||
|
||||
public Task StartAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
_applicationLifetime.ApplicationStarted.Register(() =>
|
||||
{
|
||||
Task.Run(async() =>
|
||||
{
|
||||
var startTime = DateTime.Now;
|
||||
try
|
||||
{
|
||||
var extractor = new ArgumentsExtractor(_args);
|
||||
|
||||
var genProcess = _preGenController.ComputeGeneration(extractor.Spec, extractor.GenType, extractor.PublishType);
|
||||
|
||||
if (extractor.ExportPuml) _exportController.PlantUml(genProcess.BaseFile);
|
||||
|
||||
await _genController.Launch(genProcess);
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.Log(LogLevel.Critical, e, $"A critical exception was thrown. {e.Message}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
var endTime = DateTime.Now;
|
||||
Console.WriteLine($"Process started at : {startTime}");
|
||||
Console.WriteLine($"Process ended at : {endTime}");
|
||||
Console.WriteLine($"Duration : {(endTime - startTime).Duration():mm':'ss}");
|
||||
_applicationLifetime.StopApplication();
|
||||
}
|
||||
}, cancellationToken);
|
||||
});
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task StopAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private void Display(object? sender, DisplayEventArgs args)
|
||||
{
|
||||
Console.WriteLine(args.Content);
|
||||
}
|
||||
|
||||
private void Warn(object? sender, DisplayEventArgs args)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.WriteLine(args.Content);
|
||||
Console.ResetColor();
|
||||
}
|
||||
}
|
||||
91
Generator/Infrastructure/CommandExecutor.cs
Normal file
91
Generator/Infrastructure/CommandExecutor.cs
Normal file
@@ -0,0 +1,91 @@
|
||||
using System.Diagnostics;
|
||||
using Core.Events;
|
||||
using Core.Exceptions;
|
||||
|
||||
namespace Generator.Infrastructure;
|
||||
|
||||
public class CommandExecutor
|
||||
{
|
||||
|
||||
private readonly Queue<string> _commands;
|
||||
private string _invite;
|
||||
private DisplayEmitter _emitter;
|
||||
|
||||
public CommandExecutor(string invite, DisplayEmitter emitter)
|
||||
{
|
||||
_commands = new Queue<string>();
|
||||
_invite = invite;
|
||||
_emitter = emitter;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs a single asynchronous command
|
||||
/// </summary>
|
||||
/// <param name="command">Command to run</param>
|
||||
/// <exception cref="CommandExecutionException">When the command hasn't been terminated successfully</exception>
|
||||
public async Task RunAsync(string command)
|
||||
{
|
||||
await Task.Run(() =>
|
||||
{
|
||||
using var process = new Process();
|
||||
process.StartInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = _invite,
|
||||
Arguments = $"{command}",
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
WindowStyle = ProcessWindowStyle.Normal
|
||||
};
|
||||
process.Start();
|
||||
ReadOutput(process);
|
||||
ReadError(process);
|
||||
process.WaitForExit();
|
||||
|
||||
if(process.ExitCode == 1)
|
||||
throw new CommandExecutionException($"The following task has failed : \n '{command}'");
|
||||
});
|
||||
}
|
||||
|
||||
private void ReadError(Process process)
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
using var output = process.StandardError;
|
||||
while (!output.EndOfStream)
|
||||
{
|
||||
var line = await output.ReadLineAsync();
|
||||
_emitter.Warn(this, line);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void ReadOutput(Process process)
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
using var output = process.StandardOutput;
|
||||
while (!output.EndOfStream)
|
||||
{
|
||||
var line = await output.ReadLineAsync();
|
||||
_emitter.Say(this, line);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers a command to execute later
|
||||
/// </summary>
|
||||
/// <param name="command"></param>
|
||||
public void Register(string command) => _commands.Enqueue(command);
|
||||
|
||||
/// <summary>
|
||||
/// Runs all previously registered command
|
||||
/// </summary>
|
||||
public async Task RunRegistered()
|
||||
{
|
||||
while (_commands.TryDequeue(out var c))
|
||||
{
|
||||
await RunAsync(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
60
Generator/Infrastructure/Export/Exporter.cs
Normal file
60
Generator/Infrastructure/Export/Exporter.cs
Normal file
@@ -0,0 +1,60 @@
|
||||
using Core;
|
||||
using Core.Actions;
|
||||
using Core.Helpers;
|
||||
using Core.Templates;
|
||||
using Core.Yaml;
|
||||
using Generator.Infrastructure.TemplateFiller;
|
||||
|
||||
namespace Generator.Infrastructure.Export;
|
||||
|
||||
/// <summary>
|
||||
/// Provides multiple methods to specification references
|
||||
/// </summary>
|
||||
public class Exporter
|
||||
{
|
||||
private readonly ITemplateFactory _templateFactory;
|
||||
|
||||
public Exporter(ITemplateFactory factory)
|
||||
{
|
||||
_templateFactory = factory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Export file references as plant uml diagram
|
||||
/// </summary>
|
||||
/// <param name="export">plantuml data needed for exportation</param>
|
||||
/// <param name="file">File to export</param>
|
||||
public void PlantUml(PlantUmlExport export, ISpecFile file)
|
||||
{
|
||||
var yaml = TypeHelper.SafeCast<ISpecFile, OpenApiYaml>(file);
|
||||
var input = export.LocalRoot.ConcatenateWith(export.Template);
|
||||
var output = export.LocalRoot.ConcatenateWith(export.Output);
|
||||
|
||||
var references = new List<(string Package, string Reference)>();
|
||||
var schemas = yaml.ReferencedSchemas.ToList();
|
||||
|
||||
for (var i = -1; i < schemas.Count; i++)
|
||||
{
|
||||
var baseFile = i == -1 ? yaml : schemas[i];
|
||||
if(!baseFile.Location.IsInSameFolder(yaml.Location)) continue;
|
||||
|
||||
foreach (var reference in baseFile.ReferencedSchemas)
|
||||
{
|
||||
references.Add((baseFile.NugetPackage, reference.NugetPackage));
|
||||
}
|
||||
}
|
||||
|
||||
var data = new Dictionary<string, object>()
|
||||
{
|
||||
{"specName", file.Folder},
|
||||
{"packages", references.Select(t => t.Package).ToHashSet()},
|
||||
{"references", references}
|
||||
};
|
||||
|
||||
var template = _templateFactory.GetTemplate(input.ToString(), data);
|
||||
var f = new MustacheFiller(template);
|
||||
f.Fill();
|
||||
f.Write(output.ToString());
|
||||
}
|
||||
|
||||
}
|
||||
64
Generator/Infrastructure/OpenApi/Builders/AbstractBuilder.cs
Normal file
64
Generator/Infrastructure/OpenApi/Builders/AbstractBuilder.cs
Normal file
@@ -0,0 +1,64 @@
|
||||
using Core;
|
||||
using Core.Events;
|
||||
using Core.Helpers;
|
||||
using Core.Templates;
|
||||
using Generator.Infrastructure.TemplateFiller;
|
||||
using Microsoft.OpenApi.Exceptions;
|
||||
|
||||
namespace Generator.Infrastructure.OpenApi.Builders;
|
||||
|
||||
/// <summary>
|
||||
/// Provides base behavior for generation purpose
|
||||
/// </summary>
|
||||
/// <typeparam name="TFile">Derived type from ISpecFile</typeparam>
|
||||
public abstract class AbstractBuilder<TFile> where TFile : ISpecFile
|
||||
{
|
||||
private readonly ITemplateFactory _templateFactory;
|
||||
protected readonly CommandExecutor Executor;
|
||||
protected TFile? SpecFile;
|
||||
|
||||
public AbstractBuilder(string invite, DisplayEmitter emitter)
|
||||
{
|
||||
Executor = new CommandExecutor(invite, emitter);
|
||||
_templateFactory = new MustacheTemplateFactory();
|
||||
SpecFile = default;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers file used for generation
|
||||
/// </summary>
|
||||
/// <param name="specFile"></param>
|
||||
public void Load(TFile specFile) => SpecFile = TypeHelper.SafeCast<ISpecFile, TFile>(specFile);
|
||||
|
||||
/// <summary>
|
||||
/// Launches generation
|
||||
/// </summary>
|
||||
public async Task ExecuteAllAsync() => await Executor.RunRegistered();
|
||||
|
||||
/// <summary>
|
||||
/// Registers generation process
|
||||
/// </summary>
|
||||
public abstract void Generate();
|
||||
|
||||
/// <summary>
|
||||
/// Registers build process
|
||||
/// </summary>
|
||||
public abstract void Build();
|
||||
|
||||
/// <summary>
|
||||
/// Check if the spec file has been loaded
|
||||
/// </summary>
|
||||
/// <exception cref="OpenApiException"></exception>
|
||||
protected void CheckForNullSpec()
|
||||
{
|
||||
if (SpecFile == null) throw new OpenApiException("Spec file hasn't been loaded yet.");
|
||||
}
|
||||
|
||||
protected void MakeTemplate(string inputPath, string outputPath, IDictionary<string, object> data)
|
||||
{
|
||||
var template = _templateFactory.GetTemplate(inputPath, data);
|
||||
var f = new MustacheFiller(template);
|
||||
f.Fill();
|
||||
f.Write(outputPath);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
using System.Text;
|
||||
using Core;
|
||||
using Core.Events;
|
||||
using Core.Helpers;
|
||||
using Core.Settings;
|
||||
using Core.Yaml;
|
||||
using YamlDotNet.Core;
|
||||
|
||||
namespace Generator.Infrastructure.OpenApi.Builders;
|
||||
|
||||
public class OpenApiDotnetClientBuilder : AbstractBuilder<OpenApiYaml>
|
||||
{
|
||||
private readonly DotnetConfig _config;
|
||||
public OpenApiDotnetClientBuilder(DotnetConfig config, DisplayEmitter emitter)
|
||||
: base(config.Invite, emitter)
|
||||
{
|
||||
_config = config;
|
||||
}
|
||||
|
||||
///<inheritdoc/>
|
||||
public override void Generate()
|
||||
{
|
||||
CheckForNullSpec();
|
||||
|
||||
CreateIgnore();
|
||||
GenerateOpenApi();
|
||||
|
||||
var inputFile = new Location([_config.DockerRoot, _config.OpenApiConfigFile()]);
|
||||
|
||||
var command = $"docker run --rm -it -v {_config.LocalRoot}:{_config.DockerRoot} {_config.GenerationImage} batch --clean {inputFile}";
|
||||
Executor.Register(command);
|
||||
}
|
||||
|
||||
///<inheritdoc/>
|
||||
public override void Build()
|
||||
{
|
||||
CheckForNullSpec();
|
||||
|
||||
var templateFolder = new Location([_config.DockerRoot, _config.TemplateFolder]);
|
||||
var packageFolder = new Location([_config.DockerRoot, _config.PackageFolderPath()]);
|
||||
|
||||
var stringBuilder = new StringBuilder();
|
||||
stringBuilder
|
||||
.Append($"docker run --rm -it -v {_config.LocalRoot}:{_config.DockerRoot} {_config.BuildImage} /bin/sh -c '")
|
||||
.Append($"cp {templateFolder}/NuGet.config {packageFolder} && ")
|
||||
.Append($"cd {packageFolder} && ")
|
||||
.Append($"dotnet pack -c Release -o out -p:PackageVersion={SpecFile.Version}'");
|
||||
|
||||
var command = stringBuilder.ToString();
|
||||
Executor.Register(command);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates config file used by openapi generator
|
||||
/// </summary>
|
||||
public void CreateGeneratorConfig()
|
||||
{
|
||||
CheckForNullSpec();
|
||||
|
||||
var inputPath = new Location([_config.LocalRoot, _config.ClientConfigTemplate]);
|
||||
var outputPath = new Location([_config.LocalRoot, _config.ConfigFilePath()]);
|
||||
|
||||
PathHelper.CreateFileIfNotExists(outputPath.ToString());
|
||||
|
||||
var data = new Dictionary<string, object>
|
||||
{
|
||||
{"specPath", new Location([_config.DockerRoot, _config.OpenApiSpecFile()]).ToString()},
|
||||
{"templateFolder", new Location([_config.DockerRoot, _config.TemplateFolder]).ToString()},
|
||||
{"generatorVersion", "7.3.0"},
|
||||
{"outputFolder", new Location([_config.DockerRoot, _config.OutputFolder()]).ToString()},
|
||||
{"removeModelPackage", false},
|
||||
{"modelSuffix", SpecFile.Config.ModelSuffix},
|
||||
{"packageName", SpecFile.Config.NugetPackage},
|
||||
{"packageVersion", SpecFile.Info["version"]},
|
||||
{"refs", SpecFile.ReferencedSchemas},
|
||||
{"modelNameSpace", SpecFile.ReferencedSchemas},
|
||||
};
|
||||
|
||||
MakeTemplate(inputPath.ToString(), outputPath.ToString(), data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers the generation of the openapi spec file
|
||||
/// </summary>
|
||||
private void GenerateOpenApi()
|
||||
{
|
||||
CheckForNullSpec();
|
||||
|
||||
var specFile = new Location([_config.DockerRoot, _config.SpecFile]);
|
||||
var output = new Location([_config.DockerRoot, _config.OpenApiFolder()]);
|
||||
|
||||
var command = $"docker run --rm -it -v {_config.LocalRoot}:{_config.DockerRoot} {_config.GenerationImage} " +
|
||||
$"generate -g openapi-yaml -i {specFile} -o {output}";
|
||||
Executor.Register(command);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates the ignore file used by openapi generator
|
||||
/// </summary>
|
||||
private void CreateIgnore()
|
||||
{
|
||||
CheckForNullSpec();
|
||||
|
||||
var inputPath = new Location([_config.LocalRoot, _config.ClientIgnoreTemplate]).ToString();
|
||||
var outputPath = new Location([_config.LocalRoot, _config.IgnoreFilePath()]).ToString();
|
||||
|
||||
PathHelper.CreateFileIfNotExists(outputPath);
|
||||
|
||||
var data = new Dictionary<string, object>
|
||||
{
|
||||
{"modelSuffix", SpecFile!.Config.ModelSuffix},
|
||||
{"keepModels", SpecFile.Config.KeepModels},
|
||||
};
|
||||
|
||||
MakeTemplate(inputPath, outputPath, data);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
using System.Text;
|
||||
using Core;
|
||||
using Core.Events;
|
||||
using Core.Helpers;
|
||||
using Core.Settings;
|
||||
using Core.SpecConfig;
|
||||
using Core.Yaml;
|
||||
|
||||
namespace Generator.Infrastructure.OpenApi.Builders;
|
||||
|
||||
public class OpenApiDotnetServerBuilder : AbstractBuilder<OpenApiYaml>
|
||||
{
|
||||
private readonly DotnetConfig _config;
|
||||
|
||||
public OpenApiDotnetServerBuilder(DotnetConfig config, DisplayEmitter emitter)
|
||||
: base(config.Invite, emitter)
|
||||
{
|
||||
_config = config;
|
||||
}
|
||||
|
||||
///<inheritdoc/>
|
||||
public override void Generate()
|
||||
{
|
||||
CheckForNullSpec();
|
||||
|
||||
CreateIgnore();
|
||||
GenerateOpenApi();
|
||||
|
||||
var inputFile = new Location([_config.DockerRoot, _config.OpenApiConfigFile()]);
|
||||
|
||||
var command = $"docker run --rm -it -v {_config.LocalRoot}:{_config.DockerRoot} " +
|
||||
$"{_config.GenerationImage} batch --clean {inputFile}";
|
||||
Executor.Register(command);
|
||||
}
|
||||
|
||||
///<inheritdoc/>
|
||||
public override void Build()
|
||||
{
|
||||
CheckForNullSpec();
|
||||
|
||||
var templateFolder = new Location([_config.DockerRoot, _config.TemplateFolder]);
|
||||
var packageFolder = new Location([_config.DockerRoot, _config.PackageFolderPath()]);
|
||||
|
||||
var stringBuilder = new StringBuilder();
|
||||
stringBuilder
|
||||
.Append($"docker run --rm -it -v {_config.LocalRoot}:{_config.DockerRoot} {_config.BuildImage} /bin/sh -c '")
|
||||
.Append($"cp {templateFolder}/NuGet.config {packageFolder} && ")
|
||||
.Append($"cd {packageFolder} && ")
|
||||
.Append($"dotnet pack -c Release -o out -p:PackageVersion={SpecFile.Version}'");
|
||||
|
||||
var command = stringBuilder.ToString();
|
||||
Executor.Register(command);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates config file used by openapi generator
|
||||
/// </summary>
|
||||
public void CreateGeneratorConfig()
|
||||
{
|
||||
CheckForNullSpec();
|
||||
|
||||
var inputPath = new Location([_config.LocalRoot, _config.ServerConfigTemplate]);
|
||||
var outputPath = new Location([_config.LocalRoot, _config.ConfigFilePath()]);
|
||||
|
||||
PathHelper.CreateFileIfNotExists(outputPath.ToString());
|
||||
|
||||
var templateData = new Dictionary<string, object>
|
||||
{
|
||||
{"specPath", new Location([_config.DockerRoot, _config.OpenApiSpecFile()]).ToString()},
|
||||
{"templateFolder", new Location([_config.DockerRoot, _config.TemplateFolder]).ToString()},
|
||||
{"generatorVersion", "7.3.0"},
|
||||
{"outputFolder", new Location([_config.DockerRoot, _config.OutputFolder()]).ToString()},
|
||||
{"modelSuffix", SpecFile.Config.ModelSuffix},
|
||||
{"aspnetCoreVersion", "3.1"},
|
||||
{"packageName", SpecFile.Config.NugetPackage},
|
||||
{"packageVersion", SpecFile.Info!["version"]},
|
||||
{"refs", SpecFile.ReferencedSchemas},
|
||||
{"modelNameSpace", SpecFile.ReferencedSchemas},
|
||||
};
|
||||
|
||||
MakeTemplate(inputPath.ToString(), outputPath.ToString(), templateData);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers the generation of the openapi spec file
|
||||
/// </summary>
|
||||
private void GenerateOpenApi()
|
||||
{
|
||||
CheckForNullSpec();
|
||||
|
||||
var specFile = new Location([_config.DockerRoot, _config.SpecFile]);
|
||||
var output = new Location([_config.DockerRoot, _config.OpenApiFolder()]);
|
||||
|
||||
var command = $"docker run --rm -it -v {_config.LocalRoot}:{_config.DockerRoot} {_config.GenerationImage} " +
|
||||
$"generate -g openapi-yaml -i {specFile} -o {output}";
|
||||
Executor.Register(command);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates the ignore file used by openapi generator
|
||||
/// </summary>
|
||||
private void CreateIgnore()
|
||||
{
|
||||
CheckForNullSpec();
|
||||
|
||||
var inputPath = new Location([_config.LocalRoot, _config.ServerIgnoreTemplate]).ToString();
|
||||
var outputPath = new Location([_config.LocalRoot, _config.IgnoreFilePath()]).ToString();
|
||||
|
||||
PathHelper.CreateFileIfNotExists(outputPath);
|
||||
|
||||
var data = new Dictionary<string, object>
|
||||
{
|
||||
{"modelSuffix", SpecFile!.Config.ModelSuffix},
|
||||
{"keepModels", SpecFile.Config.KeepModels},
|
||||
{"ignoredModels", SpecFile.IgnoredModels},
|
||||
{"isCommon", SpecFile.SpecType == SpecType.Model}
|
||||
};
|
||||
|
||||
MakeTemplate(inputPath, outputPath, data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
using System.Text;
|
||||
using Core;
|
||||
using Core.Events;
|
||||
using Core.Helpers;
|
||||
using Core.Settings;
|
||||
using Core.Yaml;
|
||||
|
||||
namespace Generator.Infrastructure.OpenApi.Builders;
|
||||
|
||||
public class OpenApiJavaBuilder : AbstractBuilder<OpenApiYaml>
|
||||
{
|
||||
private readonly JavaConfig _config;
|
||||
|
||||
public OpenApiJavaBuilder(JavaConfig config, DisplayEmitter emitter)
|
||||
: base(config.Invite, emitter)
|
||||
{
|
||||
_config = config;
|
||||
}
|
||||
|
||||
///<inheritdoc/>
|
||||
public override void Generate()
|
||||
{
|
||||
CheckForNullSpec();
|
||||
|
||||
GenerateOpenApi();
|
||||
|
||||
var configFile = new Location([_config.DockerRoot, _config.ConfigFilePath()]);
|
||||
var command = $"docker run --rm -it -v {_config.LocalRoot}:{_config.DockerRoot} {_config.GenerationImage} " +
|
||||
$"batch --clean {configFile}";
|
||||
|
||||
Executor.Register(command);
|
||||
}
|
||||
|
||||
///<inheritdoc/>
|
||||
public override void Build()
|
||||
{
|
||||
CheckForNullSpec();
|
||||
|
||||
var templateFolder = new Location([_config.DockerRoot, _config.TemplateFolder]);
|
||||
var outputFolder = new Location([_config.DockerRoot, _config.OutputFolder()]);
|
||||
|
||||
var stringBuilder = new StringBuilder();
|
||||
stringBuilder.Append($"docker run --rm -it -v {_config.LocalRoot}:{_config.DockerRoot} {_config.BuildImage} /bin/sh -c '");
|
||||
stringBuilder.Append($"cp {templateFolder}/settings.xml /root/.m2 && ");
|
||||
stringBuilder.Append($"cd {outputFolder} && ");
|
||||
stringBuilder.Append("mvn package'");
|
||||
|
||||
var command = stringBuilder.ToString();
|
||||
|
||||
Executor.Register(command);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates config file used by openapi generator
|
||||
/// </summary>
|
||||
public void CreateGeneratorConfig()
|
||||
{
|
||||
CheckForNullSpec();
|
||||
|
||||
var inputPath = new Location([_config.LocalRoot, _config.ServerConfigTemplate]);
|
||||
var outputPath = new Location([_config.LocalRoot, _config.ConfigFilePath()]);
|
||||
|
||||
PathHelper.CreateFileIfNotExists(outputPath.ToString());
|
||||
|
||||
var artifact = $"{SpecFile.Name}-api";
|
||||
|
||||
var data = new Dictionary<string, object>
|
||||
{
|
||||
{"specPath", new Location([_config.DockerRoot, _config.OpenApiSpecFile()]).ToString()},
|
||||
{"templateFolder", new Location([_config.DockerRoot, _config.TemplateFolder]).ToString()},
|
||||
{"generatorVersion", "7.3.0"},
|
||||
{"outputFolder", new Location([_config.DockerRoot, _config.OutputFolder()]).ToString()},
|
||||
{"groupId", SpecFile.Config.JavaGroup},
|
||||
{"artifactId", artifact},
|
||||
{"artifactVersion", SpecFile.Info["version"]},
|
||||
};
|
||||
|
||||
MakeTemplate(inputPath.ToString(), outputPath.ToString(), data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers the generation of the openapi spec file
|
||||
/// </summary>
|
||||
private void GenerateOpenApi()
|
||||
{
|
||||
CheckForNullSpec();
|
||||
|
||||
var specFile = new Location([_config.DockerRoot, _config.SpecFile]);
|
||||
var output = new Location([_config.DockerRoot, _config.OpenApiFolder()]);
|
||||
|
||||
PathHelper.CreateFileIfNotExists(output.ToString());
|
||||
|
||||
var command = $"docker run --rm -it -v {_config.LocalRoot}:{_config.DockerRoot} {_config.GenerationImage} " +
|
||||
$"generate -g openapi-yaml -i {specFile} -o {output}";
|
||||
Executor.Register(command);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
using System.Text;
|
||||
using Core;
|
||||
using Core.Events;
|
||||
using Core.Settings;
|
||||
using Core.Yaml;
|
||||
|
||||
namespace Generator.Infrastructure.OpenApi.Builders;
|
||||
|
||||
public class OpenApiJavascriptBuilder : AbstractBuilder<OpenApiYaml>
|
||||
{
|
||||
|
||||
private readonly JavascriptConfig _config;
|
||||
|
||||
public OpenApiJavascriptBuilder(JavascriptConfig config, DisplayEmitter emitter)
|
||||
: base(config.Invite, emitter)
|
||||
{
|
||||
_config = config;
|
||||
}
|
||||
|
||||
///<inheritdoc/>
|
||||
public override void Generate()
|
||||
{
|
||||
CheckForNullSpec();
|
||||
|
||||
GenerateOpenApi();
|
||||
|
||||
var outputFolder = new Location([_config.DockerRoot, _config.ClientFolder]);
|
||||
var specFile = new Location([_config.DockerRoot, _config.OpenApiSpecFile()]).ToString();
|
||||
|
||||
var stringBuilder = new StringBuilder();
|
||||
stringBuilder
|
||||
.Append($"docker run --rm -it -v {_config.LocalRoot}:{_config.DockerRoot} {_config.BuildImage} /bin/sh -c '")
|
||||
.Append($"npm run prepare-workspace -- --apiName={_config.PackageName} --apiVersion={_config.OpenApiVersion} ")
|
||||
.Append($"--apiFile={specFile} --registry={_config.Registry} && ")
|
||||
.Append("npm run package && ")
|
||||
.Append($"mkdir -p {outputFolder} && ")
|
||||
.Append($"cp -r dist/* {outputFolder}'");
|
||||
|
||||
var command = stringBuilder.ToString();
|
||||
|
||||
Executor.Register(command);
|
||||
}
|
||||
|
||||
///<inheritdoc/>
|
||||
public override void Build()
|
||||
=> throw new InvalidOperationException("Why the heck do you want to compile javascript code ?");
|
||||
|
||||
/// <summary>
|
||||
/// Registers the generation of the openapi spec file
|
||||
/// </summary>
|
||||
private void GenerateOpenApi()
|
||||
{
|
||||
CheckForNullSpec();
|
||||
|
||||
var specFile = new Location([_config.DockerRoot, _config.SpecFile]);
|
||||
var output = new Location([_config.DockerRoot, _config.OpenApiFolder()]);
|
||||
|
||||
var command = $"docker run --rm -it -v {_config.LocalRoot}:{_config.DockerRoot} {_config.GenerationImage} " +
|
||||
$"generate -g openapi-yaml -i {specFile} -o {output}";
|
||||
Executor.Register(command);
|
||||
}
|
||||
|
||||
}
|
||||
76
Generator/Infrastructure/OpenApi/OpenApiDirector.cs
Normal file
76
Generator/Infrastructure/OpenApi/OpenApiDirector.cs
Normal file
@@ -0,0 +1,76 @@
|
||||
using Core.Events;
|
||||
using Core.Interfaces;
|
||||
using Core.Settings;
|
||||
using Core.Yaml;
|
||||
using Generator.Infrastructure.OpenApi.Builders;
|
||||
|
||||
namespace Generator.Infrastructure.OpenApi;
|
||||
|
||||
public class OpenApiDirector : IGeneratorDirector<OpenApiYaml>
|
||||
{
|
||||
private DisplayEmitter _emitter;
|
||||
|
||||
public OpenApiDirector(DisplayEmitter emitter)
|
||||
{
|
||||
_emitter = emitter;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Launches dotnet server generation
|
||||
/// </summary>
|
||||
/// <param name="file"></param>
|
||||
/// <param name="config"></param>
|
||||
public async Task DotnetServer(OpenApiYaml file, DotnetConfig config)
|
||||
{
|
||||
var dotnetServerBuilder = new OpenApiDotnetServerBuilder(config, _emitter);
|
||||
dotnetServerBuilder.Load(file);
|
||||
dotnetServerBuilder.CreateGeneratorConfig();
|
||||
dotnetServerBuilder.Generate();
|
||||
dotnetServerBuilder.Build();
|
||||
await dotnetServerBuilder.ExecuteAllAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Launches dotnet client generation
|
||||
/// </summary>
|
||||
/// <param name="file"></param>
|
||||
/// <param name="config"></param>
|
||||
public async Task DotnetClient(OpenApiYaml file, DotnetConfig config)
|
||||
{
|
||||
var dotnetClientBuilder = new OpenApiDotnetClientBuilder(config, _emitter);
|
||||
dotnetClientBuilder.Load(file);
|
||||
dotnetClientBuilder.CreateGeneratorConfig();
|
||||
dotnetClientBuilder.Generate();
|
||||
dotnetClientBuilder.Build();
|
||||
await dotnetClientBuilder.ExecuteAllAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Launches java generation
|
||||
/// </summary>
|
||||
/// <param name="file"></param>
|
||||
/// <param name="config"></param>
|
||||
public async Task Java(OpenApiYaml file, JavaConfig config)
|
||||
{
|
||||
var javaBuilder = new OpenApiJavaBuilder(config, _emitter);
|
||||
javaBuilder.Load(file);
|
||||
javaBuilder.CreateGeneratorConfig();
|
||||
javaBuilder.Generate();
|
||||
javaBuilder.Build();
|
||||
await javaBuilder.ExecuteAllAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Launches javascript generation
|
||||
/// </summary>
|
||||
/// <param name="file"></param>
|
||||
/// <param name="config"></param>
|
||||
public async Task Javascript(OpenApiYaml file, JavascriptConfig config)
|
||||
{
|
||||
_emitter.Warn(this, "Javascript generation is temporally disabled");
|
||||
/*var jsBuilder = new OpenApiJavascriptBuilder(config, _emitter);
|
||||
jsBuilder.Load(file);
|
||||
jsBuilder.Generate();
|
||||
await jsBuilder.ExecuteAllAsync();*/
|
||||
}
|
||||
}
|
||||
90
Generator/Infrastructure/Publication/Publisher.cs
Normal file
90
Generator/Infrastructure/Publication/Publisher.cs
Normal file
@@ -0,0 +1,90 @@
|
||||
using System.Text;
|
||||
using Core;
|
||||
using Core.Actions;
|
||||
using Core.Events;
|
||||
|
||||
namespace Generator.Infrastructure.Publication;
|
||||
|
||||
public class Publisher
|
||||
{
|
||||
private readonly CommandExecutor _executor;
|
||||
|
||||
public Publisher(string invite, DisplayEmitter emitter)
|
||||
{
|
||||
_executor = new CommandExecutor(invite, emitter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Published nuget package
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
public async Task PublishNugget(DotnetPublish data)
|
||||
{
|
||||
|
||||
var packageFolder = new Location([data.DockerRoot, data.PackageFolder]);
|
||||
|
||||
var stringBuilder = new StringBuilder();
|
||||
stringBuilder
|
||||
.Append($"docker run --rm -it -v {data.LocalRoot}:{data.DockerRoot} {data.Image} /bin/sh -c '")
|
||||
.Append($"cd {packageFolder} && ")
|
||||
.Append($"dotnet nuget push out/{data.PackageFile}.{data.PackageVersion}.nupkg -k {data.AuthorizationToken} -s {data.Registry}'");
|
||||
|
||||
await _executor.RunAsync(stringBuilder.ToString());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Publishes npm packages
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
public async Task PublishNpm(JavascriptPublish data)
|
||||
{
|
||||
var specFile = new Location([data.DockerRoot, data.SpecFile]).ToString().Replace("/api/", "");
|
||||
var frontFolder = new Location([data.DockerRoot, data.FrontFolder]);
|
||||
var creds = data.DockerRoot.ConcatenateWith(".npmrc");
|
||||
|
||||
var stringBuilder = new StringBuilder();
|
||||
stringBuilder.Append($"docker run --rm -it -v {data.LocalRoot}:{data.DockerRoot} {data.Image} /bin/sh -c '");
|
||||
stringBuilder.Append("cd front && ");
|
||||
stringBuilder.Append($"npm run prepare-workspace -- --apiName={data.PackageName} --apiVersion={data.Version} ");
|
||||
stringBuilder.Append($"--apiFile={specFile} --registry={data.Registry} && ");
|
||||
stringBuilder.Append("npm run package && ");
|
||||
stringBuilder.Append($"cp {creds} ./ && ");
|
||||
stringBuilder.Append($"mkdir -p {frontFolder} && ");
|
||||
stringBuilder.Append($"cp -r dist/* {frontFolder} && ");
|
||||
stringBuilder.Append("npm run publish'");
|
||||
|
||||
await _executor.RunAsync(stringBuilder.ToString());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Publishes maven package
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
public async Task PublishMaven(JavaPublish data)
|
||||
{
|
||||
var templateFolder = new Location([data.DockerRoot, data.TemplateFolder]);
|
||||
var outputFolder = new Location([data.DockerRoot, data.OutputFolder]);
|
||||
|
||||
var stringBuilder = new StringBuilder();
|
||||
stringBuilder.Append($"docker run --rm -it -v {data.LocalRoot}:{data.DockerRoot} ");
|
||||
stringBuilder.Append($"-v {data.LocalRoot}maven-generated:/root/.m2/repository {data.Image} /bin/sh -c '");
|
||||
stringBuilder.Append($"cp {templateFolder}/settings.xml /root/.m2 && ");
|
||||
stringBuilder.Append($"cd {outputFolder} && ");
|
||||
stringBuilder.Append("mvn -e deploy:deploy-file ");
|
||||
stringBuilder.Append($"-D file=target/{data.Artifact}-{data.Version}.jar ");
|
||||
stringBuilder.Append($"-D groupId={data.Group} ");
|
||||
stringBuilder.Append($"-D artifactId={data.Artifact} ");
|
||||
stringBuilder.Append($"-D version={data.Version} ");
|
||||
stringBuilder.Append("-D packaging=jar ");
|
||||
stringBuilder.Append("-D generatePom=true ");
|
||||
stringBuilder.Append("-D repositoryId=fcsd ");
|
||||
stringBuilder.Append("-D skipTests ");
|
||||
stringBuilder.Append($"-D url={data.Registry} ");
|
||||
stringBuilder.Append("-D repo.id=fcsd ");
|
||||
stringBuilder.Append($"-D repo.username={data.Username} ");
|
||||
stringBuilder.Append($"-D repo.password={data.Password}'");
|
||||
|
||||
await _executor.RunAsync(stringBuilder.ToString());
|
||||
}
|
||||
|
||||
}
|
||||
20
Generator/Infrastructure/TemplateFiller/AbstractFiller.cs
Normal file
20
Generator/Infrastructure/TemplateFiller/AbstractFiller.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using Core.Templates;
|
||||
|
||||
namespace Generator.Infrastructure.TemplateFiller;
|
||||
|
||||
public abstract class AbstractFiller
|
||||
{
|
||||
protected string Render;
|
||||
protected ITemplate Template;
|
||||
|
||||
/// <summary>
|
||||
/// Fills the text extracted from the template file
|
||||
/// </summary>
|
||||
public abstract void Fill();
|
||||
|
||||
/// <summary>
|
||||
/// Output the filled text in a file
|
||||
/// </summary>
|
||||
/// <param name="outputPath"></param>
|
||||
public abstract void Write(string outputPath);
|
||||
}
|
||||
35
Generator/Infrastructure/TemplateFiller/MustacheFiller.cs
Normal file
35
Generator/Infrastructure/TemplateFiller/MustacheFiller.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
using Core.Exceptions;
|
||||
using Core.Templates;
|
||||
using Mustache;
|
||||
|
||||
namespace Generator.Infrastructure.TemplateFiller;
|
||||
|
||||
public class MustacheFiller : AbstractFiller
|
||||
{
|
||||
public MustacheFiller(ITemplate template)
|
||||
{
|
||||
Template = template;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Fill()
|
||||
{
|
||||
var compiler = new FormatCompiler
|
||||
{
|
||||
RemoveNewLines = false
|
||||
};
|
||||
var generator = compiler.Compile(Template?.GetText());
|
||||
|
||||
Render = generator.Render(Template?.GetData());
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Write(string outputPath)
|
||||
{
|
||||
if (Render == null) throw new FillerException(
|
||||
"Filler Exception : No text can be written. Have you forgot to call the Fill method ?");
|
||||
|
||||
using StreamWriter file = new StreamWriter(outputPath);
|
||||
file.Write(Render);
|
||||
}
|
||||
}
|
||||
27
Generator/Mappers/CredentialsMapper.cs
Normal file
27
Generator/Mappers/CredentialsMapper.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using Core.Actions;
|
||||
using Core.Dto.Settings;
|
||||
using Core.Settings;
|
||||
|
||||
namespace Generator.Mappers;
|
||||
|
||||
public static class CredentialsMapper
|
||||
{
|
||||
public static CredentialsConfig Map(this CredentialsConfigDto dto)
|
||||
=> new()
|
||||
{
|
||||
Email = dto.Email,
|
||||
Token = dto.Token,
|
||||
Username = dto.Username,
|
||||
Password = dto.Password,
|
||||
AlwaysAuth = dto.AlwaysAuth
|
||||
};
|
||||
|
||||
public static PackageDeletion ToPackageDeletion(this CredentialsConfigDto dto)
|
||||
{
|
||||
return new PackageDeletion
|
||||
{
|
||||
Username = dto.Username,
|
||||
Password = dto.Password
|
||||
};
|
||||
}
|
||||
}
|
||||
54
Generator/Mappers/DotnetMapper.cs
Normal file
54
Generator/Mappers/DotnetMapper.cs
Normal file
@@ -0,0 +1,54 @@
|
||||
using Core;
|
||||
using Core.Dto.Settings;
|
||||
using Core.Settings;
|
||||
using Generator.DataSource.Settings;
|
||||
|
||||
namespace Generator.Mappers;
|
||||
|
||||
public static class DotnetMapper
|
||||
{
|
||||
public static DotnetConfig Map(this DotnetConfigDto dto, ConfigManager configManager, ISpecFile file)
|
||||
{
|
||||
var specName = file.Name;
|
||||
var specFolder = file.Folder;
|
||||
var generationFolder = configManager.GetGeneral().GenerationFolder;
|
||||
var apiFolder = configManager.GetGeneral().ApiFolder;
|
||||
var templatesConfig = configManager.Templates;
|
||||
var baseConfig = configManager.GetBase();
|
||||
var openApiConfig = configManager.OpenApi.Map(configManager, specFolder, specName);
|
||||
var publishConfig = configManager.Publish;
|
||||
var credConfig = configManager.Credentials;
|
||||
var d = new DotnetConfig
|
||||
{
|
||||
LocalRoot = baseConfig.LocalRoot,
|
||||
DockerRoot = baseConfig.DockerRoot,
|
||||
GenerationImage = configManager.DockerImages.OpenApiGeneratorImage,
|
||||
BuildImage = configManager.DockerImages.DotnetSdkImage,
|
||||
Invite = baseConfig.Invite,
|
||||
|
||||
SpecFile = apiFolder.ConcatenateWith([specFolder, $"{specName}{openApiConfig.SpecExtension}"]),
|
||||
OpenApi = openApiConfig.Folder,
|
||||
|
||||
PackageFolder = "src",
|
||||
PackageFile = file.NugetPackage,
|
||||
|
||||
TemplateFolder = new Location(templatesConfig.Folder),
|
||||
CommonFolder = generationFolder.ConcatenateWith([specFolder, dto.CommonFolder, specName]),
|
||||
ServerFolder = generationFolder.ConcatenateWith([specFolder, dto.ServerFolder, specName]),
|
||||
ClientFolder = generationFolder.ConcatenateWith([specFolder, dto.ClientFolder, specName]),
|
||||
|
||||
ConfigFile = openApiConfig.GeneratorConfigFile,
|
||||
IgnoreFile = openApiConfig.GeneratorIgnoreFile,
|
||||
|
||||
ServerConfigTemplate = new Location([templatesConfig.Folder, templatesConfig.DotnetServerGeneratorConfig]),
|
||||
ClientConfigTemplate = new Location([templatesConfig.Folder, templatesConfig.DotnetClientGeneratorConfig]),
|
||||
ServerIgnoreTemplate = new Location([templatesConfig.Folder, templatesConfig.ServerIgnore]),
|
||||
ClientIgnoreTemplate = new Location([templatesConfig.Folder, templatesConfig.ClientIgnore]),
|
||||
Registry = publishConfig.NugetRegistry,
|
||||
AuthorizationToken = credConfig.Token
|
||||
|
||||
};
|
||||
|
||||
return d;
|
||||
}
|
||||
}
|
||||
49
Generator/Mappers/JavaMapper.cs
Normal file
49
Generator/Mappers/JavaMapper.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
using Core;
|
||||
using Core.Dto.Settings;
|
||||
using Core.Settings;
|
||||
using Generator.DataSource.Settings;
|
||||
|
||||
namespace Generator.Mappers;
|
||||
|
||||
public static class JavaMapper
|
||||
{
|
||||
public static JavaConfig Map(this JavaConfigDto dto, ConfigManager configManager, ISpecFile file)
|
||||
{
|
||||
var apiFolder = configManager.GetGeneral().ApiFolder;
|
||||
var specFolder = file.Folder;
|
||||
var specName = file.Name;
|
||||
var templatesConfig = configManager.Templates;
|
||||
var pubConfig = configManager.Publish;
|
||||
var credConfig = configManager.Credentials;
|
||||
var openApiConfig = configManager.OpenApi.Map(configManager, specFolder, specName);;
|
||||
var generationFolder = configManager.GetGeneral().GenerationFolder;
|
||||
var baseConfig = configManager.GetBase();
|
||||
var j = new JavaConfig
|
||||
{
|
||||
LocalRoot = baseConfig.LocalRoot,
|
||||
DockerRoot = baseConfig.DockerRoot,
|
||||
Invite = baseConfig.Invite,
|
||||
|
||||
BuildImage = configManager.DockerImages.MavenImage,
|
||||
GenerationImage = configManager.DockerImages.OpenApiGeneratorImage,
|
||||
|
||||
ServerFolder = generationFolder.ConcatenateWith([specFolder, dto.Folder, specName]),
|
||||
|
||||
ConfigOutput = generationFolder.ConcatenateWith(openApiConfig.GeneratorConfigFile),
|
||||
|
||||
SpecFile = apiFolder.ConcatenateWith([specFolder, $"{specName}{openApiConfig.SpecExtension}"]),
|
||||
ConfigFile = openApiConfig.GeneratorConfigFile,
|
||||
OpenApi = configManager.OpenApi.Map(configManager, specFolder, specName).Folder,
|
||||
|
||||
TemplateFolder = new Location(templatesConfig.Folder),
|
||||
ServerConfigTemplate = new Location([templatesConfig.Folder, templatesConfig.JavaGeneratorConfig]),
|
||||
Registry = pubConfig.MavenRegistry,
|
||||
Artifact = $"{file.Name}-api",
|
||||
Version = file.Version,
|
||||
Username = credConfig.Username,
|
||||
Password = credConfig.Password,
|
||||
};
|
||||
|
||||
return j;
|
||||
}
|
||||
}
|
||||
36
Generator/Mappers/JavascriptMapper.cs
Normal file
36
Generator/Mappers/JavascriptMapper.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using Core;
|
||||
using Core.Dto.Settings;
|
||||
using Core.Settings;
|
||||
using Generator.DataSource.Settings;
|
||||
|
||||
namespace Generator.Mappers;
|
||||
|
||||
public static class JavascriptMapper
|
||||
{
|
||||
public static JavascriptConfig Map(this JavascriptConfigDto dto, ConfigManager configManager, ISpecFile file)
|
||||
{
|
||||
var apiFolder = configManager.GetGeneral().ApiFolder;
|
||||
var specFolder = file.Folder;
|
||||
var specName = file.Name;
|
||||
var templatesConfig = configManager.Templates;
|
||||
var openApiConfig = configManager.OpenApi.Map(configManager, specFolder, specName);
|
||||
var generationFolder = configManager.GetGeneral().GenerationFolder;
|
||||
var baseConfig = configManager.GetBase();
|
||||
return new JavascriptConfig
|
||||
{
|
||||
LocalRoot = baseConfig.LocalRoot,
|
||||
DockerRoot = baseConfig.DockerRoot,
|
||||
GenerationImage = configManager.DockerImages.OpenApiGeneratorImage,
|
||||
BuildImage = configManager.DockerImages.JavascriptImage,
|
||||
Invite = baseConfig.Invite,
|
||||
|
||||
ClientFolder = generationFolder.ConcatenateWith([specFolder, dto.Folder, specName]),
|
||||
SpecFile = apiFolder.ConcatenateWith([specFolder, $"{specName}{openApiConfig.SpecExtension}"]),
|
||||
PackageName = file.NpmPackage,
|
||||
OpenApiVersion = file.Version,
|
||||
Registry = configManager.Publish.NpmRegistry,
|
||||
TemplateFolder = new Location(templatesConfig.Folder),
|
||||
OpenApi = configManager.OpenApi.Map(configManager, specFolder, specName).Folder
|
||||
};
|
||||
}
|
||||
}
|
||||
92
Generator/Mappers/OpenApiYamlMapper.cs
Normal file
92
Generator/Mappers/OpenApiYamlMapper.cs
Normal file
@@ -0,0 +1,92 @@
|
||||
using Core.Dto.Yaml;
|
||||
using Core.Exceptions;
|
||||
using Core.SpecConfig;
|
||||
using Core.Yaml;
|
||||
|
||||
namespace Generator.Mappers;
|
||||
|
||||
public static class OpenApiYamlMapper
|
||||
{
|
||||
public static OpenApiYaml ToModel(this OpenApiYamlDto dto, string loc)
|
||||
{
|
||||
ISet<string> models = new HashSet<string>();
|
||||
if (dto.Components is not null && dto.Components.TryGetValue("schemas", out var component))
|
||||
{
|
||||
models = component.Keys.ToHashSet();
|
||||
}
|
||||
|
||||
return new OpenApiYaml(loc)
|
||||
{
|
||||
Info = dto.Info,
|
||||
Openapi = dto.Openapi,
|
||||
Tags = dto.Tags,
|
||||
Models = models,
|
||||
IgnoredModels = new HashSet<string>(),
|
||||
};
|
||||
}
|
||||
|
||||
public static Dictionary<string, YamlConfig> Map(this SpecConfigDto dto)
|
||||
{
|
||||
var result = new Dictionary<string, YamlConfig>();
|
||||
|
||||
foreach (var config in dto.Packages)
|
||||
{
|
||||
var yaml = new YamlConfig
|
||||
{
|
||||
Priority = config.Priority,
|
||||
ModelSuffix = dto.ModelSuffix,
|
||||
JavaGroup = dto.JavaGroup,
|
||||
NugetPackage = config.DotnetPackage,
|
||||
NpmPackage = config.JavascriptPackage,
|
||||
KeepModels = config.KeepModels,
|
||||
Type = ConvertSpecType(config.Type),
|
||||
PackageTypes = ConvertPackagesTypes(dto.PackageTypes)
|
||||
};
|
||||
result.Add(config.Name, yaml);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static PackageTypes ConvertPackagesTypes(Dictionary<string, List<string>> dto)
|
||||
{
|
||||
var res = new PackageTypes();
|
||||
foreach (var d in dto)
|
||||
{
|
||||
var language = d.Key.ToLower() switch
|
||||
{
|
||||
"dotnet" => Language.Dotnet,
|
||||
"java" => Language.Java,
|
||||
"javascript" => Language.Javascript,
|
||||
_ => throw new ConfigException($"Currently supported languages are dotnet, java and javascript. {d.Key} is not one of them. Fix it or consequences")
|
||||
};
|
||||
|
||||
var generationTypes = d.Value.Select(t => t.ToLower() switch
|
||||
{
|
||||
"server" => GenerationType.Server,
|
||||
"common" => GenerationType.Common,
|
||||
"client" => GenerationType.Client,
|
||||
_ => throw new ConfigException($"Currently supported generation types are server, common and client. {t} is not one of them. Fix it or consequences")
|
||||
}).ToList();
|
||||
|
||||
generationTypes.ForEach(gt =>
|
||||
{
|
||||
if (!res.TryAdd(language, gt))
|
||||
res.Add(language, [gt]);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
private static SpecType ConvertSpecType(string type)
|
||||
{
|
||||
return type.ToLower() switch
|
||||
{
|
||||
"api" => SpecType.Api,
|
||||
"model" => SpecType.Model,
|
||||
_ => throw new ConfigException($"Currently supported spec types are api and model. {type} is not one of them. Fix it or consequences")
|
||||
};
|
||||
}
|
||||
}
|
||||
18
Generator/Mappers/PackageDataMapper.cs
Normal file
18
Generator/Mappers/PackageDataMapper.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using Core;
|
||||
using Core.Dto;
|
||||
|
||||
namespace Generator.Mappers;
|
||||
|
||||
public static class PackageDataMapper
|
||||
{
|
||||
public static List<PackageData> Map(this List<PackageDataDto> dto)
|
||||
{
|
||||
return dto.Select(pdd
|
||||
=> new PackageData()
|
||||
{
|
||||
Id = pdd.Id,
|
||||
Name = pdd.Name,
|
||||
Version = pdd.Version
|
||||
}).ToList();
|
||||
}
|
||||
}
|
||||
76
Generator/Mappers/SettingsMapper.cs
Normal file
76
Generator/Mappers/SettingsMapper.cs
Normal file
@@ -0,0 +1,76 @@
|
||||
using Core;
|
||||
using Core.Dto;
|
||||
using Core.Dto.Settings;
|
||||
using Core.Settings;
|
||||
using Generator.DataSource.Settings;
|
||||
|
||||
namespace Generator.Mappers;
|
||||
|
||||
public static class SettingsMapper
|
||||
{
|
||||
public static DefaultArgumentsConfig Map(this DefaultArgumentsConfigDto dto, ArgumentsDto args)
|
||||
{
|
||||
|
||||
var identifier = args.SpecName ?? dto.SpecIdentifier;
|
||||
return new DefaultArgumentsConfig
|
||||
{
|
||||
SpecIdentifier = identifier,
|
||||
};
|
||||
}
|
||||
|
||||
public static DockerImagesConfig Map(this DockerImagesConfigDto dto)
|
||||
=> new()
|
||||
{
|
||||
JavaImage = dto.MavenImage,
|
||||
DotnetSdkImage = dto.DotnetSdkImage,
|
||||
OpenApiGeneratorImage = dto.OpenApiGeneratorImage,
|
||||
JavascriptImage = dto.JavascriptImage,
|
||||
};
|
||||
|
||||
public static BaseConfig Map(this EnvironmentConfigDto dto)
|
||||
=> new()
|
||||
{
|
||||
Invite = dto.Invite,
|
||||
LocalRoot = new Location(dto.LocalRoot),
|
||||
DockerRoot = new Location(dto.DockerRoot),
|
||||
TemplateFolder = null,
|
||||
};
|
||||
|
||||
public static PublishConfig Map(this PublishConfigDto dto)
|
||||
=> new()
|
||||
{
|
||||
MavenRegistry = dto.MavenRegistry,
|
||||
NpmRegistry = dto.NpmRegistry,
|
||||
NugetRegistry = dto.NugetRegistry
|
||||
};
|
||||
|
||||
public static OpenApiConfig Map(this OpenApiConfigDto dto, ConfigManager configManager, string folder, string name)
|
||||
{
|
||||
var apiFolder = configManager.GetGeneral().ApiFolder;
|
||||
|
||||
var config = new OpenApiConfig
|
||||
{
|
||||
Folder = new Location(dto.OutputFolder),
|
||||
GeneratorConfigFile = new Location(dto.GeneratorConfigFile),
|
||||
GeneratorIgnoreFile = new Location(dto.GeneratorIgnoreFile),
|
||||
SpecFile = apiFolder.ConcatenateWith([folder, $"{name}{dto.SpecExtension}"]),
|
||||
SpecConfig = apiFolder.ConcatenateWith([folder, $"{name}{dto.ConfigIdentifier}{dto.ConfigExtension}"]),
|
||||
SpecExtension = dto.SpecExtension,
|
||||
SchemasIdentifier = dto.SchemasIdentifier,
|
||||
ConfigIdentifier = $"{dto.ConfigIdentifier}{dto.ConfigExtension}",
|
||||
};
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
|
||||
public static GeneralConfig Map(this GeneralConfigDto dto)
|
||||
=> new()
|
||||
{
|
||||
ApiFolder = new Location(dto.ApiFolder),
|
||||
GenerationFolder = new Location(dto.OutputFolder),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
21
Generator/Mappers/TemplateMapper.cs
Normal file
21
Generator/Mappers/TemplateMapper.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
using Core;
|
||||
using Core.Dto.Settings;
|
||||
using Core.Settings;
|
||||
|
||||
namespace Generator.Mappers;
|
||||
|
||||
public static class TemplateMapper
|
||||
{
|
||||
public static TemplatesConfig Map(this TemplatesConfigDto dto)
|
||||
=> new()
|
||||
{
|
||||
Folder = new Location(dto.Folder),
|
||||
PlantUml = new Location([dto.Folder, dto.PlantUml]),
|
||||
DotnetServerGeneratorConfig = new Location(dto.DotnetServerGeneratorConfig),
|
||||
DotnetClientGeneratorConfig = new Location(dto.DotnetClientGeneratorConfig),
|
||||
JavaGeneratorConfig = new Location(dto.JavaGeneratorConfig),
|
||||
ServerIgnore = new Location(dto.ServerIgnore),
|
||||
ClientIgnore = new Location(dto.ClientIgnore),
|
||||
};
|
||||
|
||||
}
|
||||
45
Generator/Repo/ApiAnalyzer.cs
Normal file
45
Generator/Repo/ApiAnalyzer.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
using Core;
|
||||
using Core.Helpers;
|
||||
using Generator.Daos;
|
||||
using Generator.DataSource.Yaml;
|
||||
|
||||
namespace Generator.Repo;
|
||||
|
||||
public class ApiAnalyzer
|
||||
{
|
||||
|
||||
private readonly EnvironmentDao _envDao;
|
||||
private readonly OpenApiDao _openApiDao;
|
||||
|
||||
public ApiAnalyzer(OpenApiDao openApiDao, EnvironmentDao envDao)
|
||||
{
|
||||
_envDao = envDao;
|
||||
_openApiDao = openApiDao;
|
||||
}
|
||||
|
||||
public IEnumerable<Location> ListSpecifications()
|
||||
{
|
||||
var res = new List<string>();
|
||||
var directories = Directory.GetDirectories(_envDao.ApiFolder().ToString());
|
||||
|
||||
foreach (var d in directories) res.AddRange(Directory.EnumerateFiles(d));
|
||||
|
||||
return res
|
||||
.Select(s => new Location(s))
|
||||
.Where(s => s.HasExtension("yaml"));
|
||||
}
|
||||
|
||||
public bool CanBeGenerated(string folder, string spec)
|
||||
{
|
||||
var extractor = new OpenApiYamlExtractor();
|
||||
var path = _openApiDao.ConfigOf($"{folder}/{folder}");
|
||||
var configs = extractor.LoadConfigs(path.ToString());
|
||||
return configs.ContainsKey(spec);
|
||||
}
|
||||
|
||||
public string GetText(string folder, string spec)
|
||||
{
|
||||
var path = _envDao.ApiFolder().ConcatenateWith([folder, $"{spec}.yaml"]);
|
||||
return PathHelper.TextFrom(path.ToString());
|
||||
}
|
||||
}
|
||||
26
Generator/Repo/ExportRepo.cs
Normal file
26
Generator/Repo/ExportRepo.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using Core;
|
||||
using Core.Templates;
|
||||
using Generator.Daos;
|
||||
using Generator.Infrastructure.Export;
|
||||
|
||||
namespace Generator.Repo;
|
||||
|
||||
public class ExportRepo
|
||||
{
|
||||
|
||||
private readonly TemplateDao _templateDao;
|
||||
private readonly Exporter _exporter;
|
||||
|
||||
public ExportRepo(TemplateDao templateDao)
|
||||
{
|
||||
_templateDao = templateDao;
|
||||
_exporter = new Exporter(new MustacheTemplateFactory());
|
||||
}
|
||||
|
||||
public void PlantUml(ISpecFile file)
|
||||
{
|
||||
var export = _templateDao.PlantUml(file);
|
||||
_exporter.PlantUml(export, file);
|
||||
}
|
||||
|
||||
}
|
||||
58
Generator/Repo/GenerateRepo.cs
Normal file
58
Generator/Repo/GenerateRepo.cs
Normal file
@@ -0,0 +1,58 @@
|
||||
using Core;
|
||||
using Core.Helpers;
|
||||
using Core.Interfaces;
|
||||
using Core.SpecConfig;
|
||||
using Core.Yaml;
|
||||
using Generator.Daos;
|
||||
using Generator.Infrastructure.OpenApi;
|
||||
|
||||
namespace Generator.Repo;
|
||||
|
||||
public class GenerateRepo
|
||||
{
|
||||
private readonly IGeneratorDirector<OpenApiYaml> _genDirector;
|
||||
private readonly DotnetDao _dotnetDao;
|
||||
private readonly JavaDao _javaDao;
|
||||
private readonly JavascriptDao _javascriptDao;
|
||||
|
||||
public GenerateRepo(
|
||||
OpenApiDirector genDirector,
|
||||
DotnetDao dotnetDao,
|
||||
JavaDao javaDao,
|
||||
JavascriptDao jsDao)
|
||||
{
|
||||
_genDirector = genDirector;
|
||||
_dotnetDao = dotnetDao;
|
||||
_javaDao = javaDao;
|
||||
_javascriptDao = jsDao;
|
||||
}
|
||||
|
||||
public async Task GenerateDotnet(GenerationType type, ISpecFile specFile)
|
||||
{
|
||||
var file = TypeHelper.SafeCast<ISpecFile, OpenApiYaml>(specFile);
|
||||
var config = _dotnetDao.GetDotnetGenerate(type, specFile);
|
||||
if (type != GenerationType.Client)
|
||||
{
|
||||
await _genDirector.DotnetServer(file, config);
|
||||
}
|
||||
else
|
||||
{
|
||||
await _genDirector.DotnetClient(file, config);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task GenerateJava(ISpecFile specFile)
|
||||
{
|
||||
var file = TypeHelper.SafeCast<ISpecFile, OpenApiYaml>(specFile);
|
||||
|
||||
var config = _javaDao.GetJavaGenerate(specFile);
|
||||
await _genDirector.Java(file, config);
|
||||
}
|
||||
|
||||
public async Task GenerateJavascript(ISpecFile specFile)
|
||||
{
|
||||
var file = TypeHelper.SafeCast<ISpecFile, OpenApiYaml>(specFile);
|
||||
var config = _javascriptDao.GetJavascript(file);
|
||||
await _genDirector.Javascript(file, config);
|
||||
}
|
||||
}
|
||||
22
Generator/Repo/PreGenerationRepo.cs
Normal file
22
Generator/Repo/PreGenerationRepo.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using Core.Process;
|
||||
using Core.SpecConfig;
|
||||
using Generator.Daos;
|
||||
using Generator.DataSource.Yaml;
|
||||
|
||||
namespace Generator.Repo;
|
||||
|
||||
public class PreGenerationRepo
|
||||
{
|
||||
private readonly YamlDirector _specDirector;
|
||||
|
||||
public PreGenerationRepo(OpenApiDao openApiDao)
|
||||
{
|
||||
_specDirector = new YamlDirector(openApiDao);
|
||||
}
|
||||
|
||||
public GenerationProcess GetProcess(string specPath, GenerationType? generationType, PublishType publishType)
|
||||
{
|
||||
var file = _specDirector.BuildYaml(specPath);
|
||||
return new GenerationProcess(file, publishType, generationType);
|
||||
}
|
||||
}
|
||||
48
Generator/Repo/PublisherRepo.cs
Normal file
48
Generator/Repo/PublisherRepo.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
using Core;
|
||||
using Core.Events;
|
||||
using Core.SpecConfig;
|
||||
using Generator.Daos;
|
||||
using Generator.Infrastructure.Publication;
|
||||
using YamlDotNet.Core;
|
||||
|
||||
namespace Generator.Repo;
|
||||
|
||||
public class PublisherRepo
|
||||
{
|
||||
private readonly Publisher _publisher;
|
||||
private readonly DotnetDao _dotnetDao;
|
||||
private readonly JavaDao _javaDao;
|
||||
private readonly JavascriptDao _javascriptDao;
|
||||
|
||||
public PublisherRepo(
|
||||
EnvironmentDao envDao,
|
||||
DotnetDao dotnetDao,
|
||||
JavaDao javaDao,
|
||||
JavascriptDao jsDao,
|
||||
DisplayEmitter emitter)
|
||||
{
|
||||
_publisher = new Publisher(envDao.Invite, emitter);
|
||||
_dotnetDao = dotnetDao;
|
||||
_javaDao = javaDao;
|
||||
_javascriptDao = jsDao;
|
||||
}
|
||||
|
||||
public async Task PublishDotnet(GenerationType type, ISpecFile file)
|
||||
{
|
||||
var config = _dotnetDao.GetDotnetPublish(type, file);
|
||||
await _publisher.PublishNugget(config);
|
||||
}
|
||||
|
||||
public async Task PublishJava(GenerationType type, ISpecFile file)
|
||||
{
|
||||
var config = _javaDao.GetJavaPublish(type, file);
|
||||
await _publisher.PublishMaven(config);
|
||||
}
|
||||
|
||||
public async Task PublishJavascript(GenerationType type, ISpecFile file)
|
||||
{
|
||||
var config = _javascriptDao.GetJavascriptPublish(type, file);
|
||||
await _publisher.PublishNpm(config);
|
||||
}
|
||||
|
||||
}
|
||||
32
Generator/Repo/RepositoryActions.cs
Normal file
32
Generator/Repo/RepositoryActions.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using Core;
|
||||
using Core.Interfaces;
|
||||
using Core.SpecConfig;
|
||||
using Generator.Daos;
|
||||
using Generator.DataSource.Packages;
|
||||
using Generator.Mappers;
|
||||
|
||||
namespace Generator.Repo;
|
||||
|
||||
public class RepositoryActions
|
||||
{
|
||||
private readonly CredentialsDao _credentialsDao;
|
||||
private readonly IRepositoryRequest _requester;
|
||||
|
||||
public RepositoryActions(CredentialsDao credentialsDao)
|
||||
{
|
||||
_credentialsDao = credentialsDao;
|
||||
_requester = new NexusRequester(_credentialsDao.Username, _credentialsDao.Password);
|
||||
}
|
||||
|
||||
public async Task<List<PackageData>> GetVersions(Language language, string package)
|
||||
{
|
||||
var packages = await _requester.GetVersions(language, package);
|
||||
return packages.Map();
|
||||
}
|
||||
|
||||
public async Task DeleteVersion(string packageId)
|
||||
{
|
||||
await _requester.DeleteVersion(packageId);
|
||||
}
|
||||
|
||||
}
|
||||
61
Generator/ServiceExtension.cs
Normal file
61
Generator/ServiceExtension.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
using Core.Dto;
|
||||
using Core.Events;
|
||||
using Core.Interfaces;
|
||||
using Core.Yaml;
|
||||
using Generator.Controllers;
|
||||
using Generator.Daos;
|
||||
using Generator.DataSource.Settings;
|
||||
using Generator.Infrastructure.OpenApi;
|
||||
using Generator.Repo;
|
||||
using Generator.Services;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Generator;
|
||||
|
||||
public static class ServiceExtension
|
||||
{
|
||||
public static void AddServices(this IServiceCollection services, IDataSourceLoader loader, ArgumentsDto args)
|
||||
{
|
||||
loader.LoadAppsettings();
|
||||
|
||||
services.AddSingleton(args);
|
||||
services.AddSingleton<ConfigManager>();
|
||||
|
||||
services.AddSingleton<DisplayEmitter>();
|
||||
|
||||
services.AddScoped<EnvironmentDao>();
|
||||
services.AddScoped<TemplateDao>();
|
||||
services.AddScoped<OpenApiDao>();
|
||||
services.AddScoped<DotnetDao>();
|
||||
services.AddScoped<JavaDao>();
|
||||
services.AddScoped<JavascriptDao>();
|
||||
services.AddScoped<CredentialsDao>();
|
||||
|
||||
services.AddScoped<IGeneratorDirector<OpenApiYaml>, OpenApiDirector>();
|
||||
|
||||
services.AddScoped<ApiAnalyzer>();
|
||||
|
||||
services.AddScoped<OpenApiDirector>();
|
||||
|
||||
services.AddScoped<PreGenerationRepo>();
|
||||
services.AddScoped<GenerateRepo>();
|
||||
services.AddScoped<PublisherRepo>();
|
||||
services.AddScoped<RepositoryActions>();
|
||||
services.AddScoped<ExportRepo>();
|
||||
|
||||
services.AddScoped<PreGenerationService>();
|
||||
services.AddScoped<GenerationService>();
|
||||
services.AddScoped<PublicationService>();
|
||||
services.AddScoped<AnalyzeService>();
|
||||
services.AddScoped<RepositoryService>();
|
||||
services.AddScoped<ExportService>();
|
||||
|
||||
services.AddScoped<PreGenerationController>();
|
||||
services.AddScoped<GenerationController>();
|
||||
services.AddScoped<PublicationController>();
|
||||
services.AddScoped<AnalyzeController>();
|
||||
services.AddScoped<ExportController>();
|
||||
|
||||
services.AddLogging();
|
||||
}
|
||||
}
|
||||
20
Generator/Services/AnalyzeService.cs
Normal file
20
Generator/Services/AnalyzeService.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using Core;
|
||||
using Generator.Repo;
|
||||
|
||||
namespace Generator.Services;
|
||||
|
||||
public class AnalyzeService
|
||||
{
|
||||
private readonly ApiAnalyzer _analyzer;
|
||||
|
||||
public AnalyzeService(ApiAnalyzer analyzer)
|
||||
{
|
||||
_analyzer = analyzer;
|
||||
}
|
||||
|
||||
public IEnumerable<Location> ListSpecs() => _analyzer.ListSpecifications();
|
||||
|
||||
public bool CanBeGenerated(string folder, string spec) => _analyzer.CanBeGenerated(folder, spec);
|
||||
|
||||
public string GetSpecText(string folder, string spec) => _analyzer.GetText(folder, spec);
|
||||
}
|
||||
19
Generator/Services/ExportService.cs
Normal file
19
Generator/Services/ExportService.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using Core;
|
||||
using Generator.Repo;
|
||||
|
||||
namespace Generator.Services;
|
||||
|
||||
public class ExportService
|
||||
{
|
||||
private readonly ExportRepo _repo;
|
||||
|
||||
public ExportService(ExportRepo repo)
|
||||
{
|
||||
_repo = repo;
|
||||
}
|
||||
|
||||
public void ExportAsPuml(ISpecFile file)
|
||||
{
|
||||
_repo.PlantUml(file);
|
||||
}
|
||||
}
|
||||
68
Generator/Services/GenerationService.cs
Normal file
68
Generator/Services/GenerationService.cs
Normal file
@@ -0,0 +1,68 @@
|
||||
using Core.Exceptions;
|
||||
using Core.SpecConfig;
|
||||
using Generator.Repo;
|
||||
|
||||
namespace Generator.Services;
|
||||
|
||||
public class GenerationService
|
||||
{
|
||||
private readonly GenerateRepo _repo;
|
||||
private readonly PublicationService _pubService;
|
||||
|
||||
public GenerationService(PublicationService publicationService, GenerateRepo repo)
|
||||
{
|
||||
_repo = repo;
|
||||
_pubService = publicationService;
|
||||
}
|
||||
|
||||
public async Task Launch(ProcessTask task)
|
||||
{
|
||||
switch (task.Language)
|
||||
{
|
||||
case Language.Dotnet:
|
||||
await LaunchDotnet(task);
|
||||
break;
|
||||
case Language.Java:
|
||||
await LaunchJava(task);
|
||||
break;
|
||||
case Language.Javascript:
|
||||
await LaunchJavascript(task);
|
||||
break;
|
||||
default:
|
||||
throw new WeirdException("You broke me :(");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task LaunchDotnet(ProcessTask task)
|
||||
{
|
||||
while (task.Tasks.TryDequeue(out var file))
|
||||
{
|
||||
await _repo.GenerateDotnet(task.GenerationType, file);
|
||||
|
||||
if (task.PublishType == PublishType.No) continue;
|
||||
await _pubService.PublishDotnet(file, task.GenerationType, task.PublishType);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task LaunchJava(ProcessTask task)
|
||||
{
|
||||
while (task.Tasks.TryDequeue(out var file))
|
||||
{
|
||||
await _repo.GenerateJava(file);
|
||||
|
||||
if (task.PublishType == PublishType.No) continue;
|
||||
await _pubService.PublishJava(file, task.GenerationType, task.PublishType);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task LaunchJavascript(ProcessTask task)
|
||||
{
|
||||
while (task.Tasks.TryDequeue(out var file))
|
||||
{
|
||||
await _repo.GenerateJavascript(file);
|
||||
|
||||
if (task.PublishType == PublishType.No) continue;
|
||||
await _pubService.PublishJavascript(file, task.GenerationType, task.PublishType);
|
||||
}
|
||||
}
|
||||
}
|
||||
22
Generator/Services/PreGenerationService.cs
Normal file
22
Generator/Services/PreGenerationService.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using Core.Process;
|
||||
using Core.SpecConfig;
|
||||
using Generator.Repo;
|
||||
|
||||
namespace Generator.Services;
|
||||
|
||||
public class PreGenerationService
|
||||
{
|
||||
|
||||
private readonly PreGenerationRepo _repo;
|
||||
|
||||
public PreGenerationService(PreGenerationRepo repo)
|
||||
{
|
||||
_repo = repo;
|
||||
}
|
||||
|
||||
public GenerationProcess ComputeGeneration(string specPath, GenerationType? generationType, PublishType publishType)
|
||||
{
|
||||
return _repo.GetProcess(specPath, generationType, publishType);
|
||||
}
|
||||
|
||||
}
|
||||
123
Generator/Services/PublicationService.cs
Normal file
123
Generator/Services/PublicationService.cs
Normal file
@@ -0,0 +1,123 @@
|
||||
using Core;
|
||||
using Core.Process;
|
||||
using Core.SpecConfig;
|
||||
using Generator.Repo;
|
||||
|
||||
namespace Generator.Services;
|
||||
|
||||
public class PublicationService
|
||||
{
|
||||
|
||||
private readonly PublisherRepo _publisherRepo;
|
||||
private readonly RepositoryService _repoService;
|
||||
public PublicationService(
|
||||
PublisherRepo pubRepo,
|
||||
RepositoryService repoService)
|
||||
{
|
||||
_publisherRepo = pubRepo;
|
||||
_repoService = repoService;
|
||||
}
|
||||
|
||||
public async Task Publish(GenerationProcess process)
|
||||
{
|
||||
foreach (var task in process)
|
||||
{
|
||||
switch (task.Language)
|
||||
{
|
||||
case Language.Dotnet:
|
||||
await PublishDotnet(task);
|
||||
break;
|
||||
case Language.Java:
|
||||
await PublishJava(task);
|
||||
break;
|
||||
case Language.Javascript:
|
||||
await PublishJavascript(task);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async Task PublishDotnet(ProcessTask task)
|
||||
{
|
||||
while (task.Tasks.TryDequeue(out var file))
|
||||
{
|
||||
await PublishDotnet(file, task.GenerationType, task.PublishType);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task PublishJava(ProcessTask task)
|
||||
{
|
||||
while (task.Tasks.TryDequeue(out var file))
|
||||
{
|
||||
await PublishJava(file, task.GenerationType, task.PublishType);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task PublishJavascript(ProcessTask task)
|
||||
{
|
||||
while (task.Tasks.TryDequeue(out var file))
|
||||
{
|
||||
await PublishJavascript(file, task.GenerationType, task.PublishType);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task PublishDotnet(ISpecFile file, GenerationType genType, PublishType pubType)
|
||||
{
|
||||
var data = await _repoService.GetVersions(Language.Dotnet, file.NugetPackage);
|
||||
var package = data.FirstOrDefault(pd => pd.Version == file.Version);
|
||||
|
||||
if(pubType == PublishType.Force)
|
||||
{
|
||||
if (package != null) await _repoService.DeletePackage(package.Id);
|
||||
await _publisherRepo.PublishDotnet(genType, file);
|
||||
return;
|
||||
}
|
||||
|
||||
if(pubType == PublishType.Safe)
|
||||
{
|
||||
if (package == null) await _publisherRepo.PublishDotnet(genType, file);
|
||||
else Console.WriteLine($"The version {file.Version} of package {file.NugetPackage} already exists on the repository");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task PublishJava(ISpecFile file, GenerationType genType, PublishType pubType)
|
||||
{
|
||||
var artifact = $"{file.Name}-api";
|
||||
var data = await _repoService.GetVersions(Language.Java, artifact);
|
||||
var package = data.FirstOrDefault(pd => pd.Version == file.Version);
|
||||
|
||||
if(pubType == PublishType.Force)
|
||||
{
|
||||
if (package != null) await _repoService.DeletePackage(package.Id);
|
||||
await _publisherRepo.PublishJava(genType, file);
|
||||
return;
|
||||
}
|
||||
|
||||
if(pubType == PublishType.Safe)
|
||||
{
|
||||
if (package == null) await _publisherRepo.PublishJava(genType, file);
|
||||
else Console.WriteLine($"The version {file.Version} of package {artifact} already exists on the repository");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task PublishJavascript(ISpecFile file, GenerationType genType, PublishType pubType)
|
||||
{
|
||||
var data = await _repoService.GetVersions(Language.Javascript, file.NpmPackage);
|
||||
var package = data.FirstOrDefault(pd => pd.Version == file.Version);
|
||||
|
||||
if(pubType == PublishType.Force)
|
||||
{
|
||||
if (package != null) await _repoService.DeletePackage(package.Id);
|
||||
await _publisherRepo.PublishJavascript(genType, file);
|
||||
return;
|
||||
}
|
||||
|
||||
if(pubType == PublishType.Safe)
|
||||
{
|
||||
if (package == null) await _publisherRepo.PublishJavascript(genType, file);
|
||||
else Console.WriteLine($"The version {file.Version} of package {file.NpmPackage} already exists on the repository");
|
||||
}
|
||||
}
|
||||
}
|
||||
25
Generator/Services/RepositoryService.cs
Normal file
25
Generator/Services/RepositoryService.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using Core;
|
||||
using Core.SpecConfig;
|
||||
using Generator.Repo;
|
||||
|
||||
namespace Generator.Services;
|
||||
|
||||
public class RepositoryService
|
||||
{
|
||||
private readonly RepositoryActions _actions;
|
||||
|
||||
public RepositoryService(RepositoryActions actions)
|
||||
{
|
||||
_actions = actions;
|
||||
}
|
||||
|
||||
public async Task<List<PackageData>> GetVersions(Language language, string package)
|
||||
{
|
||||
return await _actions.GetVersions(language, package);
|
||||
}
|
||||
|
||||
public async Task DeletePackage(string packageId)
|
||||
{
|
||||
await _actions.DeleteVersion(packageId);
|
||||
}
|
||||
}
|
||||
50
Generator/views/ConsoleView.cs
Normal file
50
Generator/views/ConsoleView.cs
Normal file
@@ -0,0 +1,50 @@
|
||||
using Core.Interfaces;
|
||||
|
||||
namespace Generator.views;
|
||||
|
||||
public class ConsoleView : IView
|
||||
{
|
||||
public ConsoleView()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void Display(string item)
|
||||
{
|
||||
Console.WriteLine(item);
|
||||
}
|
||||
|
||||
public void Exception(string message)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Display($"##############################\n{message}\n##############################");
|
||||
Console.ResetColor();
|
||||
}
|
||||
|
||||
public void Warning(string message)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||
Display(message);
|
||||
Console.ResetColor();
|
||||
}
|
||||
|
||||
public void Info(string message)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Blue;
|
||||
Display(message);
|
||||
Console.ResetColor();
|
||||
}
|
||||
|
||||
public void Success(string message)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Green;
|
||||
Display(message);
|
||||
Display("##############################");
|
||||
Console.ResetColor();
|
||||
}
|
||||
|
||||
public void Progress(int percentage)
|
||||
{
|
||||
Display($"|..........| {percentage}%");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user