Import from internal git
This commit is contained in:
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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user