From 46da0b07a85abe0c08d3f56d2dbbd0f3ba76cb08 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Wed, 5 Oct 2022 12:42:21 +0200 Subject: [PATCH] Ship two json schema files.. One that reference others, and a CMS one (#13123) * Ship two json schema files.. One that reference others, and a CMS one * git ignore * Build schema files sepearately --- .gitignore | 4 + src/JsonSchema/AppSettings.cs | 133 +++++------------- src/JsonSchema/JsonSchema.csproj | 18 +++ src/JsonSchema/Options.cs | 7 +- src/JsonSchema/Program.cs | 20 ++- src/JsonSchema/UmbracoJsonSchemaGenerator.cs | 95 ++++++++----- src/JsonSchema/appsettings-schema.json | 50 +++++++ .../Umbraco.Cms.Targets.csproj | 23 ++- src/Umbraco.Cms/Umbraco.Cms.csproj | 7 + src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 30 ++++ 10 files changed, 245 insertions(+), 142 deletions(-) create mode 100644 src/JsonSchema/appsettings-schema.json diff --git a/.gitignore b/.gitignore index 8f50db79d069..ab0f1d7d46f5 100644 --- a/.gitignore +++ b/.gitignore @@ -106,4 +106,8 @@ cypress.env.json # Ignore auto-generated schema /src/Umbraco.Cms.Targets/appsettings-schema.json /src/Umbraco.Web.UI/appsettings-schema.json +/src/Umbraco.Web.UI/appsettings-schema.umbraco.json /tests/Umbraco.Tests.Integration/appsettings-schema.json +/src/Umbraco.Cms.Targets/appsettings-schema.json +/src/Umbraco.Cms.Targets/appsettings-schema.umbraco.json + diff --git a/src/JsonSchema/AppSettings.cs b/src/JsonSchema/AppSettings.cs index 18d83b53a358..a8ea2f5dbba5 100644 --- a/src/JsonSchema/AppSettings.cs +++ b/src/JsonSchema/AppSettings.cs @@ -3,133 +3,74 @@ using Umbraco.Cms.Core.Configuration; using Umbraco.Cms.Core.Configuration.Models; -using Umbraco.Deploy.Core.Configuration.DebugConfiguration; -using Umbraco.Deploy.Core.Configuration.DeployConfiguration; -using Umbraco.Deploy.Core.Configuration.DeployProjectConfiguration; -using Umbraco.Forms.Core.Configuration; -using SecuritySettings = Umbraco.Cms.Core.Configuration.Models.SecuritySettings; -namespace JsonSchema -{ - internal class AppSettings - { - /// - /// Gets or sets the Umbraco - /// - public UmbracoDefinition? Umbraco { get; set; } - - /// - /// Configuration of Umbraco CMS and packages - /// - internal class UmbracoDefinition - { - // ReSharper disable once InconsistentNaming - public CmsDefinition? CMS { get; set; } - - public FormsDefinition? Forms { get; set; } +namespace JsonSchema; - public DeployDefinition? Deploy { get; set; } +internal class AppSettings +{ + // ReSharper disable once InconsistentNaming + public CmsDefinition? CMS { get; set; } - /// - /// Configurations for the Umbraco CMS - /// - public class CmsDefinition - { - public ContentSettings? Content { get; set; } - public CoreDebugSettings? Debug { get; set; } + /// + /// Configurations for the Umbraco CMS + /// + public class CmsDefinition + { + public ContentSettings? Content { get; set; } + public CoreDebugSettings? Debug { get; set; } - public ExceptionFilterSettings? ExceptionFilter { get; set; } + public ExceptionFilterSettings? ExceptionFilter { get; set; } - public ModelsBuilderSettings? ModelsBuilder { get; set; } + public ModelsBuilderSettings? ModelsBuilder { get; set; } - public GlobalSettings? Global { get; set; } + public GlobalSettings? Global { get; set; } - public HealthChecksSettings? HealthChecks { get; set; } + public HealthChecksSettings? HealthChecks { get; set; } - public HostingSettings? Hosting { get; set; } + public HostingSettings? Hosting { get; set; } - public ImagingSettings? Imaging { get; set; } + public ImagingSettings? Imaging { get; set; } - public IndexCreatorSettings? Examine { get; set; } + public IndexCreatorSettings? Examine { get; set; } - public KeepAliveSettings? KeepAlive { get; set; } + public KeepAliveSettings? KeepAlive { get; set; } - public LoggingSettings? Logging { get; set; } + public LoggingSettings? Logging { get; set; } public NuCacheSettings? NuCache { get; set; } - public RequestHandlerSettings? RequestHandler { get; set; } + public RequestHandlerSettings? RequestHandler { get; set; } - public RuntimeSettings? Runtime { get; set; } + public RuntimeSettings? Runtime { get; set; } - public SecuritySettings? Security { get; set; } + public SecuritySettings? Security { get; set; } - public TourSettings? Tours { get; set; } + public TourSettings? Tours { get; set; } - public TypeFinderSettings? TypeFinder { get; set; } + public TypeFinderSettings? TypeFinder { get; set; } public WebRoutingSettings? WebRouting { get; set; } - public UmbracoPluginSettings? Plugins { get; set; } - - public UnattendedSettings? Unattended { get; set; } - - public RichTextEditorSettings? RichTextEditor { get; set; } - - public RuntimeMinificationSettings? RuntimeMinification { get; set; } - - public BasicAuthSettings? BasicAuth { get; set; } - - public PackageMigrationSettings? PackageMigration { get; set; } - - public LegacyPasswordMigrationSettings? LegacyPasswordMigration { get; set; } - - public ContentDashboardSettings? ContentDashboard { get; set; } - - public HelpPageSettings? HelpPage { get; set; } - - public InstallDefaultDataSettings? DefaultDataCreation { get; set; } - - public DataTypesSettings? DataTypes { get; set; } - } + public UmbracoPluginSettings? Plugins { get; set; } - /// - /// Configurations for the Umbraco Forms package to Umbraco CMS - /// - public class FormsDefinition - { - public FormDesignSettings? FormDesign { get; set; } + public UnattendedSettings? Unattended { get; set; } - public PackageOptionSettings? Options { get; set; } + public RichTextEditorSettings? RichTextEditor { get; set; } - public Umbraco.Forms.Core.Configuration.SecuritySettings? Security { get; set; } + public RuntimeMinificationSettings? RuntimeMinification { get; set; } - public FieldTypesDefinition? FieldTypes { get; set; } + public BasicAuthSettings? BasicAuth { get; set; } - /// - /// Configurations for the Umbraco Forms Field Types - /// - public class FieldTypesDefinition - { - public DatePickerSettings? DatePicker { get; set; } + public PackageMigrationSettings? PackageMigration { get; set; } - public Recaptcha2Settings? Recaptcha2 { get; set; } + public LegacyPasswordMigrationSettings? LegacyPasswordMigration { get; set; } - public Recaptcha3Settings? Recaptcha3 { get; set; } - } - } + public ContentDashboardSettings? ContentDashboard { get; set; } - /// - /// Configurations for the Umbraco Deploy package to Umbraco CMS - /// - public class DeployDefinition - { - public DeploySettings? Settings { get; set; } + public HelpPageSettings? HelpPage { get; set; } - public DeployProjectConfig? Project { get; set; } + public InstallDefaultDataSettings? DefaultDataCreation { get; set; } - public DebugSettings? Debug { get; set; } - } - } + public DataTypesSettings? DataTypes { get; set; } } } diff --git a/src/JsonSchema/JsonSchema.csproj b/src/JsonSchema/JsonSchema.csproj index 5f255e75d1d3..54d62245dd45 100644 --- a/src/JsonSchema/JsonSchema.csproj +++ b/src/JsonSchema/JsonSchema.csproj @@ -8,6 +8,7 @@ + @@ -15,4 +16,21 @@ + + + + + + + + + $(UserProfile)\.nuget\packages\ + + + + + + + + diff --git a/src/JsonSchema/Options.cs b/src/JsonSchema/Options.cs index 00cb670953fa..7f4ed511a957 100644 --- a/src/JsonSchema/Options.cs +++ b/src/JsonSchema/Options.cs @@ -7,7 +7,10 @@ namespace JsonSchema { internal class Options { - [Option('o', "outputFile", Required = false, HelpText = "Set path of the output file.", Default = "appsettings-schema.json")] - public string OutputFile { get; set; } = null!; + [Option('m', "mainOutputFile", Required = false, HelpText = "Set path of the main output file.", Default = "../../../../Umbraco.Web.UI/appsettings-schema.json")] + public string MainOutputFile { get; set; } = null!; + + [Option('f', "cmsOutputFile", Required = false, HelpText = "Set path of the cms output file.", Default = "../../../../Umbraco.Web.UI/appsettings-schema.umbraco.json")] + public string CmsOutputFile { get; set; } = null!; } } diff --git a/src/JsonSchema/Program.cs b/src/JsonSchema/Program.cs index 98dae7ac22e8..12246ceecb53 100644 --- a/src/JsonSchema/Program.cs +++ b/src/JsonSchema/Program.cs @@ -27,15 +27,23 @@ await Parser.Default.ParseArguments(args) private static async Task Execute(Options options) { var generator = new UmbracoJsonSchemaGenerator(); - var schema = await generator.Generate(); - var path = Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, options.OutputFile)); - Console.WriteLine("Path to use {0}", path); - Directory.CreateDirectory(Path.GetDirectoryName(path)!); + var cmsSchema = await generator.GenerateCmsFile(); + await WriteSchemaToFile(cmsSchema, options.CmsOutputFile); + + var schema = await generator.GenerateMainFile(); + await WriteSchemaToFile(schema, options.MainOutputFile); + } + + private static async Task WriteSchemaToFile(string schema, string filePath) + { + var mainPath = Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, filePath)); + Console.WriteLine("Path to use {0}", mainPath); + Directory.CreateDirectory(Path.GetDirectoryName(mainPath)!); Console.WriteLine("Ensured directory exists"); - await File.WriteAllTextAsync(path, schema); + await File.WriteAllTextAsync(mainPath, schema); - Console.WriteLine("File written at {0}", path); + Console.WriteLine("File written at {0}", mainPath); } } } diff --git a/src/JsonSchema/UmbracoJsonSchemaGenerator.cs b/src/JsonSchema/UmbracoJsonSchemaGenerator.cs index 8cb5bafcbf5a..eeec48bcd717 100644 --- a/src/JsonSchema/UmbracoJsonSchemaGenerator.cs +++ b/src/JsonSchema/UmbracoJsonSchemaGenerator.cs @@ -1,58 +1,83 @@ // Copyright (c) Umbraco. // See LICENSE for more details. +using Microsoft.Extensions.FileProviders; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using NJsonSchema.Generation; using Umbraco.Cms.Core.Configuration.Models; -namespace JsonSchema +namespace JsonSchema; + +/// +/// Generator of the JsonSchema for AppSettings.json including A specific Umbraco version. +/// +public class UmbracoJsonSchemaGenerator { + private static readonly HttpClient s_client = new(); + private readonly JsonSchemaGenerator _innerGenerator; + /// - /// Generator of the JsonSchema for AppSettings.json including A specific Umbraco version. + /// Initializes a new instance of the class. /// - public class UmbracoJsonSchemaGenerator + public UmbracoJsonSchemaGenerator() + => _innerGenerator = new JsonSchemaGenerator(new UmbracoJsonSchemaGeneratorSettings()); + + /// + /// Generates a json representing the JsonSchema for AppSettings.json including A specific Umbraco version.. + /// + public async Task GenerateMainFile() { - private static readonly HttpClient s_client = new (); - private readonly JsonSchemaGenerator _innerGenerator; - - /// - /// Initializes a new instance of the class. - /// - public UmbracoJsonSchemaGenerator() - => _innerGenerator = new JsonSchemaGenerator(new UmbracoJsonSchemaGeneratorSettings()); - - /// - /// Generates a json representing the JsonSchema for AppSettings.json including A specific Umbraco version.. - /// - public async Task Generate() - { - JObject umbracoSchema = GenerateUmbracoSchema(); - JObject officialSchema = await GetOfficialAppSettingsSchema(); + JObject officialSchema = await GetOfficialAppSettingsSchema(); + JObject externalFilePoints = GenerateSchemaWithExternalDefinitions(); - officialSchema.Merge(umbracoSchema); + officialSchema.Merge(externalFilePoints); - return officialSchema.ToString(); - } + return officialSchema.ToString(); + } - private async Task GetOfficialAppSettingsSchema() - { - HttpResponseMessage response = await s_client.GetAsync("https://json.schemastore.org/appsettings.json") - .ConfigureAwait(false); - var result = await response.Content.ReadAsStringAsync(); + /// + /// Generates the CMS file + /// + /// + public Task GenerateCmsFile() + { + JObject cmsSchema = GenerateUmbracoSchema(); - return JsonConvert.DeserializeObject(result)!; - } + return Task.FromResult(cmsSchema.ToString()); + } - private JObject GenerateUmbracoSchema() - { - NJsonSchema.JsonSchema schema = _innerGenerator.Generate(typeof(AppSettings)); - // TODO: when the "UmbracoPath" setter is removed from "GlobalSettings" (scheduled for V12), remove this line as well - schema.Definitions["UmbracoCmsCoreConfigurationModelsGlobalSettings"]?.Properties?.Remove(nameof(GlobalSettings.UmbracoPath)); - return JsonConvert.DeserializeObject(schema.ToJson())!; + private JObject GenerateSchemaWithExternalDefinitions() + { + var fileProvider = new EmbeddedFileProvider(GetType().Assembly); + + IFileInfo schema = fileProvider.GetFileInfo("appsettings-schema.json"); + + using (Stream? stream = schema.CreateReadStream()) + using (var reader = new StreamReader(stream)) + { + return JsonConvert.DeserializeObject(reader.ReadToEnd())!; } } + + private async Task GetOfficialAppSettingsSchema() + { + HttpResponseMessage response = await s_client.GetAsync("https://json.schemastore.org/appsettings.json") + .ConfigureAwait(false); + + var result = await response.Content.ReadAsStringAsync(); + + return JsonConvert.DeserializeObject(result)!; + } + + private JObject GenerateUmbracoSchema() + { + NJsonSchema.JsonSchema schema = _innerGenerator.Generate(typeof(AppSettings)); + + // TODO: when the "UmbracoPath" setter is removed from "GlobalSettings" (scheduled for V12), remove this line as well + schema.Definitions["UmbracoCmsCoreConfigurationModelsGlobalSettings"]?.Properties?.Remove(nameof(GlobalSettings.UmbracoPath));return JsonConvert.DeserializeObject(schema.ToJson())!; + } } diff --git a/src/JsonSchema/appsettings-schema.json b/src/JsonSchema/appsettings-schema.json new file mode 100644 index 000000000000..0de279812c3e --- /dev/null +++ b/src/JsonSchema/appsettings-schema.json @@ -0,0 +1,50 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "properties": { + "Umbraco": { + "description": "The container of all Umbraco content", + "oneOf": [ + { + "type": "null" + }, + { + "properties": { + "CMS": { + "description": "Configuration of Umbraco CMS", + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "appsettings-schema.umbraco.json#/definitions/JsonSchemaCmsDefinition" + } + ] + }, + "Forms": { + "description": "Configuration of Umbraco Forms", + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "appsettings-schema.umbraco.forms.json#/definitions/JsonSchemaFormsDefinition" + } + ] + }, + "Deploy": { + "description": "Configuration of Umbraco Deploy", + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "appsettings-schema.umbraco.deploy.json#/definitions/JsonSchemaDeployDefinition" + } + ] + } + } + } + ] + } + } +} diff --git a/src/Umbraco.Cms.Targets/Umbraco.Cms.Targets.csproj b/src/Umbraco.Cms.Targets/Umbraco.Cms.Targets.csproj index c8968e1955aa..d23e4f59ba82 100644 --- a/src/Umbraco.Cms.Targets/Umbraco.Cms.Targets.csproj +++ b/src/Umbraco.Cms.Targets/Umbraco.Cms.Targets.csproj @@ -14,18 +14,35 @@ + + + $(ProjectDir)appsettings-schema.json + $(ProjectDir)appsettings-schema.umbraco.json + $(ProjectDir)../JsonSchema/ + + + + + + + + $(MSBuildThisFileDirectory)appsettings-schema.json $(MSBuildThisFileDirectory)..\JsonSchema\ - - - + + + + + + + diff --git a/src/Umbraco.Cms/Umbraco.Cms.csproj b/src/Umbraco.Cms/Umbraco.Cms.csproj index b037bd216b7d..cf0d6aeaccb1 100644 --- a/src/Umbraco.Cms/Umbraco.Cms.csproj +++ b/src/Umbraco.Cms/Umbraco.Cms.csproj @@ -11,5 +11,12 @@ + + + + + + + diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index 45d32a65eeb6..b5767d5f81c8 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -17,6 +17,15 @@ + + + appsettings.json + + + appsettings-schema.json + + + true @@ -37,4 +46,25 @@ + + + $(ProjectDir)appsettings-schema.json + $(ProjectDir)appsettings-schema.umbraco.json + $(ProjectDir)../JsonSchema/ + + + + + + + + + + + + + + + +