From 3d22696a5edd2d302942331f24199e3f27196cc1 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Wed, 17 Nov 2021 10:57:13 +0100 Subject: [PATCH] Do not update current client and some refactorings. --- .../Squidex.CLI/Commands/App_OpenLibrary.cs | 2 +- .../Squidex.CLI/Commands/App_Sync.cs | 15 +++++- .../FileSystem/Emedded/EmbeddedFileSystem.cs | 2 +- .../OpenLibrary/AuthorImporter.cs | 10 ++-- .../Implementation/Sync/App/AppRoleModel.cs | 2 + .../Sync/App/AppSynchronizer.cs | 46 ++++++++----------- .../Implementation/Sync/App/Extensions.cs | 44 ++++++++++++++++++ .../Sync/Assets/AssetsSynchronizer.cs | 4 +- .../Implementation/Sync/Assets/Extensions.cs | 41 +++++++++-------- .../Sync/Contents/ContentsSynchronizer.cs | 2 +- .../Sync/Contents/Extensions.cs | 2 +- .../Implementation/Sync/Rules/Extensions.cs | 25 ++++++++++ .../Implementation/Sync/Rules/RuleModel.cs | 20 -------- .../Implementation/Sync/Schemas/Extensions.cs | 2 +- .../Sync/Schemas/SchemasSynchronizer.cs | 2 +- .../Implementation/Sync/SyncOptions.cs | 2 + .../Implementation/Sync/SyncService.cs | 4 +- .../Squidex.CLI/Squidex.CLI.csproj | 2 +- 18 files changed, 143 insertions(+), 84 deletions(-) create mode 100644 cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/Sync/App/Extensions.cs create mode 100644 cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/Sync/Rules/Extensions.cs diff --git a/cli/Squidex.CLI/Squidex.CLI/Commands/App_OpenLibrary.cs b/cli/Squidex.CLI/Squidex.CLI/Commands/App_OpenLibrary.cs index 8d64d578..8316a5f3 100644 --- a/cli/Squidex.CLI/Squidex.CLI/Commands/App_OpenLibrary.cs +++ b/cli/Squidex.CLI/Squidex.CLI/Commands/App_OpenLibrary.cs @@ -57,7 +57,7 @@ public async Task Authors(ImportArguments arguments) { var session = configuration.StartSession(arguments.App); - using (var stream = new FileStream(arguments.File, FileMode.Open)) + await using (var stream = new FileStream(arguments.File, FileMode.Open)) { var importer = new AuthorImporter(session); diff --git a/cli/Squidex.CLI/Squidex.CLI/Commands/App_Sync.cs b/cli/Squidex.CLI/Squidex.CLI/Commands/App_Sync.cs index 53804fb5..3dea1534 100644 --- a/cli/Squidex.CLI/Squidex.CLI/Commands/App_Sync.cs +++ b/cli/Squidex.CLI/Squidex.CLI/Commands/App_Sync.cs @@ -94,18 +94,31 @@ public sealed class InArguments : AppArguments [Option(ShortName = "t", LongName = "targets", Description = "The targets to sync, e.g. schemas, workflows, app, rules.")] public string[] Targets { get; set; } + [Option(ShortName = "l", LongName = "language", Description = "The content language to synchronize.")] + public string[] Languages { get; set; } + [Option(LongName = "delete", Description = "Use this flag to also delete entities.")] public bool Delete { get; set; } [Option(LongName = "recreate", Description = "Use this flag to also recreate entities.")] public bool Recreate { get; set; } + [Option(LongName = "update-current-client", Description = "Also update the client that is used during the sync process.")] + public bool UpdateCurrentClient { get; set; } + [Option(LongName = "emulate", Description = "Use this flag to not make any updates and to emulate the changes.")] public bool Emulate { get; set; } public SyncOptions ToOptions() { - return new SyncOptions { Delete = Delete, Recreate = Recreate, Targets = Targets }; + return new SyncOptions + { + Delete = Delete, + Recreate = Recreate, + Languages = Languages, + Targets = Targets, + UpdateCurrentClient = UpdateCurrentClient + }; } public sealed class Validator : AbstractValidator diff --git a/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/FileSystem/Emedded/EmbeddedFileSystem.cs b/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/FileSystem/Emedded/EmbeddedFileSystem.cs index 180e2e00..f8536868 100644 --- a/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/FileSystem/Emedded/EmbeddedFileSystem.cs +++ b/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/FileSystem/Emedded/EmbeddedFileSystem.cs @@ -33,7 +33,7 @@ public IFile GetFile(FilePath path) { var relativePath = GetRelativePath(path); - return new EmbeddedFile(assembly, path.Elements.Last(), relativePath, path.ToString()); + return new EmbeddedFile(assembly, path.Elements[^1], relativePath, path.ToString()); } public IEnumerable GetFiles(FilePath path, string extension) diff --git a/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/OpenLibrary/AuthorImporter.cs b/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/OpenLibrary/AuthorImporter.cs index 7d363050..96008077 100644 --- a/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/OpenLibrary/AuthorImporter.cs +++ b/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/OpenLibrary/AuthorImporter.cs @@ -42,27 +42,27 @@ public async Task ImportAsync(Stream stream) var json = JObject.Parse(x.Json); - if (json.TryGetValue("name", out var name)) + if (json.TryGetValue("name", StringComparison.Ordinal, out var name)) { data.Name = GetString(name); } - if (json.TryGetValue("birth_date", out var birthdate)) + if (json.TryGetValue("birth_date", StringComparison.Ordinal, out var birthdate)) { data.Birthdate = GetString(birthdate); } - if (json.TryGetValue("bio", out var bio)) + if (json.TryGetValue("bio", StringComparison.Ordinal, out var bio)) { data.Bio = GetString(bio); } - if (json.TryGetValue("personal_name", out var personalName)) + if (json.TryGetValue("personal_name", StringComparison.Ordinal, out var personalName)) { data.PersonalName = GetString(personalName); } - if (json.TryGetValue("wikipedia", out var wikipedia)) + if (json.TryGetValue("wikipedia", StringComparison.Ordinal, out var wikipedia)) { data.Wikipedia = GetString(wikipedia); } diff --git a/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/Sync/App/AppRoleModel.cs b/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/Sync/App/AppRoleModel.cs index 026180fc..156db9e2 100644 --- a/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/Sync/App/AppRoleModel.cs +++ b/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/Sync/App/AppRoleModel.cs @@ -14,5 +14,7 @@ public sealed class AppRoleModel { [Required] public List Permissions { get; set; } + + public Dictionary Properties { get; set; } } } diff --git a/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/Sync/App/AppSynchronizer.cs b/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/Sync/App/AppSynchronizer.cs index 2d3b15f2..a5bc1e9d 100644 --- a/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/Sync/App/AppSynchronizer.cs +++ b/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/Sync/App/AppSynchronizer.cs @@ -5,6 +5,7 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== +using System; using System.Collections.Generic; using System.Threading.Tasks; using Squidex.CLI.Commands.Implementation.FileSystem; @@ -44,11 +45,7 @@ await log.DoSafeAsync("Exporting clients", async () => foreach (var client in clients.Items) { - model.Clients[client.Name] = new AppClientModel - { - Name = client.Name, - Role = client.Role - }; + model.Clients[client.Name] = client.ToModel(); } }); @@ -60,12 +57,7 @@ await log.DoSafeAsync("Exporting languages", async () => foreach (var language in languages.Items) { - model.Languages[language.Iso2Code] = new UpdateLanguageDto - { - Fallback = language.Fallback, - IsMaster = language.IsMaster, - IsOptional = language.IsOptional - }; + model.Languages[language.Iso2Code] = language.ToModel(); } }); @@ -77,10 +69,7 @@ await log.DoSafeAsync("Exporting Roles", async () => foreach (var role in roles.Items) { - model.Roles[role.Name] = new AppRoleModel - { - Permissions = role.Permissions - }; + model.Roles[role.Name] = role.ToModel(); } }); @@ -128,7 +117,7 @@ private async Task SynchronizeClientsAsync(AppModel model, SyncOptions options, { var generatedClientId = $"{session.App}:{client.Id}"; - if (model.Clients.ContainsKey(client.Id) || session.ClientId.Equals(generatedClientId)) + if (model.Clients.ContainsKey(client.Id) || session.ClientId.Equals(generatedClientId, StringComparison.Ordinal)) { continue; } @@ -157,18 +146,23 @@ await log.DoSafeAsync($"Client '{clientId}' creating", async () => }); } - foreach (var (clientId, value) in model.Clients) + foreach (var (clientId, client) in model.Clients) { var existing = current.Items.Find(x => x.Id == clientId); - if (existing == null || value.JsonEquals(existing)) + if (existing == null || client.JsonEquals(existing)) + { + continue; + } + + if (!options.UpdateCurrentClient && session.ClientId.Equals(clientId, StringComparison.Ordinal)) { continue; } await log.DoSafeAsync($"Client '{clientId}' updating", async () => { - var request = new UpdateClientDto { Role = value.Role }; + var request = client.ToUpdate(); await session.Apps.PutClientAsync(session.App, clientId, request); }); @@ -212,20 +206,18 @@ await log.DoSafeAsync($"Language '{isoCode}' creating", async () => }); } - foreach (var (isoCode, value) in model.Languages) + foreach (var (isoCode, language) in model.Languages) { var existing = current.Items.Find(x => x.Iso2Code == isoCode); - if (existing == null || value.JsonEquals(existing)) + if (existing == null || language.JsonEquals(existing)) { continue; } await log.DoSafeAsync($"Language '{isoCode}' updating", async () => { - var request = value; - - await session.Apps.PutLanguageAsync(session.App, isoCode, request); + await session.Apps.PutLanguageAsync(session.App, isoCode, language); }); } } @@ -270,18 +262,18 @@ await log.DoSafeAsync($"Role '{roleName}' creating", async () => }); } - foreach (var (roleName, value) in model.Roles) + foreach (var (roleName, role) in model.Roles) { var existing = current.Items.Find(x => x.Name == roleName); - if (existing == null || value.JsonEquals(existing)) + if (existing == null || role.JsonEquals(existing)) { continue; } await log.DoSafeAsync($"Role '{roleName}' updating", async () => { - var request = new UpdateRoleDto { Permissions = value.Permissions }; + var request = role.ToUpdate(); await session.Apps.PutRoleAsync(session.App, roleName, request); }); diff --git a/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/Sync/App/Extensions.cs b/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/Sync/App/Extensions.cs new file mode 100644 index 00000000..bd6b407b --- /dev/null +++ b/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/Sync/App/Extensions.cs @@ -0,0 +1,44 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using Squidex.ClientLibrary.Management; + +namespace Squidex.CLI.Commands.Implementation.Sync.App +{ + public static class Extensions + { + public static AppRoleModel ToModel(this RoleDto role) + { + return new AppRoleModel { Permissions = role.Permissions, Properties = role.Properties }; + } + + public static UpdateRoleDto ToUpdate(this AppRoleModel model) + { + return new UpdateRoleDto { Permissions = model.Permissions, Properties = model.Properties }; + } + + public static AppClientModel ToModel(this ClientDto client) + { + return new AppClientModel { Name = client.Name, Role = client.Role }; + } + + public static UpdateClientDto ToUpdate(this AppClientModel model) + { + return new UpdateClientDto { Name = model.Name, Role = model.Role }; + } + + public static UpdateLanguageDto ToModel(this AppLanguageDto language) + { + return new UpdateLanguageDto + { + Fallback = language.Fallback, + IsMaster = language.IsMaster, + IsOptional = language.IsOptional + }; + } + } +} diff --git a/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/Sync/Assets/AssetsSynchronizer.cs b/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/Sync/Assets/AssetsSynchronizer.cs index 94c5b70d..d3784b4d 100644 --- a/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/Sync/Assets/AssetsSynchronizer.cs +++ b/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/Sync/Assets/AssetsSynchronizer.cs @@ -128,8 +128,8 @@ public async Task ImportAsync(ISyncService sync, SyncOptions options, ISession s { var parentId = await tree.GetIdAsync(asset.FolderPath); - request.Jobs.Add(asset.ToMoveJob(parentId)); - request.Jobs.Add(asset.ToAnnotateJob()); + request.Jobs.Add(asset.ToMove(parentId)); + request.Jobs.Add(asset.ToAnnotate()); } var assetIndex = 0; diff --git a/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/Sync/Assets/Extensions.cs b/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/Sync/Assets/Extensions.cs index 8d339892..89f8bb18 100644 --- a/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/Sync/Assets/Extensions.cs +++ b/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/Sync/Assets/Extensions.cs @@ -74,30 +74,31 @@ public static string GetFileHash(this IFile file, string fileName) } } - public static BulkUpdateAssetsJobDto ToMoveJob(this AssetModel model, string parentId) + public static BulkUpdateAssetsJobDto ToMove(this AssetModel model, string parentId) { - return new BulkUpdateAssetsJobDto - { - Id = model.Id, - Type = BulkUpdateAssetType.Move, - ParentId = parentId - }; + var bulkJob = model.ToJob(BulkUpdateAssetType.Move); + + bulkJob.ParentId = parentId; + + return bulkJob; } - public static BulkUpdateAssetsJobDto ToAnnotateJob(this AssetModel model) + public static BulkUpdateAssetsJobDto ToAnnotate(this AssetModel model) { - return new BulkUpdateAssetsJobDto - { - Id = model.Id, - Type = BulkUpdateAssetType.Annotate, - FileName = model.FileName, - ParentId = null, - Permanent = false, - IsProtected = model.IsProtected, - Metadata = model.Metadata, - Slug = model.Slug, - Tags = model.Tags - }; + var bulkJob = model.ToJob(BulkUpdateAssetType.Annotate); + + bulkJob.FileName = model.FileName; + bulkJob.Metadata = model.Metadata; + bulkJob.IsProtected = model.IsProtected; + bulkJob.Slug = model.Slug; + bulkJob.Tags = model.Tags; + + return bulkJob; + } + + private static BulkUpdateAssetsJobDto ToJob(this AssetModel model, BulkUpdateAssetType type) + { + return new BulkUpdateAssetsJobDto { Id = model.Id, Type = type }; } public static async Task ToModelAsync(this AssetDto asset, FolderTree folders) diff --git a/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/Sync/Contents/ContentsSynchronizer.cs b/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/Sync/Contents/ContentsSynchronizer.cs index aa383493..c1142d44 100644 --- a/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/Sync/Contents/ContentsSynchronizer.cs +++ b/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/Sync/Contents/ContentsSynchronizer.cs @@ -114,7 +114,7 @@ public async Task ImportAsync(ISyncService sync, SyncOptions options, ISession s DoNotScript = true, DoNotValidate = false, DoNotValidateWorkflow = true, - Jobs = model.Contents.Select(x => x.ToJob(schemas)).ToList() + Jobs = model.Contents.Select(x => x.ToUpsert(schemas)).ToList() }; var contentIdAssigned = false; diff --git a/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/Sync/Contents/Extensions.cs b/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/Sync/Contents/Extensions.cs index e909ef9a..c9f352b5 100644 --- a/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/Sync/Contents/Extensions.cs +++ b/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/Sync/Contents/Extensions.cs @@ -16,7 +16,7 @@ namespace Squidex.CLI.Commands.Implementation.Sync.Contents { public static class Extensions { - public static BulkUpdateJob ToJob(this ContentModel model, SchemasDto schemas) + public static BulkUpdateJob ToUpsert(this ContentModel model, SchemasDto schemas) { var id = model.Id; diff --git a/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/Sync/Rules/Extensions.cs b/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/Sync/Rules/Extensions.cs new file mode 100644 index 00000000..3d5d7dd6 --- /dev/null +++ b/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/Sync/Rules/Extensions.cs @@ -0,0 +1,25 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using System; +using Squidex.ClientLibrary; + +namespace Squidex.CLI.Commands.Implementation.Sync.Rules +{ + public static class Extensions + { + public static UpdateExtendableRuleDto ToUpdate(this RuleModel model) + { + return new UpdateExtendableRuleDto { Action = model.Action, Trigger = model.Trigger, Name = model.Name }; + } + + public static CreateExtendableRuleDto ToCreate(this RuleModel model) + { + return new CreateExtendableRuleDto { Action = model.Action, Trigger = model.Trigger }; + } + } +} diff --git a/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/Sync/Rules/RuleModel.cs b/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/Sync/Rules/RuleModel.cs index 0a7a3e52..42e7e738 100644 --- a/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/Sync/Rules/RuleModel.cs +++ b/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/Sync/Rules/RuleModel.cs @@ -8,7 +8,6 @@ using System.ComponentModel.DataAnnotations; using Newtonsoft.Json; using Newtonsoft.Json.Linq; -using Squidex.ClientLibrary; using Squidex.ClientLibrary.Management; namespace Squidex.CLI.Commands.Implementation.Sync.Rules @@ -34,24 +33,5 @@ public RuleAction TypedAction Action = new DynamicRuleAction(JObject.FromObject(value)); } } - - public UpdateExtendableRuleDto ToUpdate() - { - return new UpdateExtendableRuleDto - { - Action = Action, - Trigger = Trigger, - Name = Name - }; - } - - public CreateExtendableRuleDto ToCreate() - { - return new CreateExtendableRuleDto - { - Action = Action, - Trigger = Trigger - }; - } } } diff --git a/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/Sync/Schemas/Extensions.cs b/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/Sync/Schemas/Extensions.cs index 707901be..cd6872eb 100644 --- a/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/Sync/Schemas/Extensions.cs +++ b/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/Sync/Schemas/Extensions.cs @@ -14,7 +14,7 @@ namespace Squidex.CLI.Commands.Implementation.Sync.Schemas { public static class Extensions { - public static CreateSchemaDto ToRequest(this SchemaCreateModel model) + public static CreateSchemaDto ToCreate(this SchemaCreateModel model) { var isSingleton = model.IsSingleton; diff --git a/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/Sync/Schemas/SchemasSynchronizer.cs b/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/Sync/Schemas/SchemasSynchronizer.cs index 3a07f7db..afa86e53 100644 --- a/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/Sync/Schemas/SchemasSynchronizer.cs +++ b/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/Sync/Schemas/SchemasSynchronizer.cs @@ -107,7 +107,7 @@ await log.DoSafeAsync($"Schema {name} deleting", async () => await log.DoSafeAsync($"Schema {model.Name} creating", async () => { - var created = await session.Schemas.PostSchemaAsync(session.App, model.ToRequest()); + var created = await session.Schemas.PostSchemaAsync(session.App, model.ToCreate()); schemasByName[model.Name] = created; }); diff --git a/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/Sync/SyncOptions.cs b/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/Sync/SyncOptions.cs index ec415ca9..204d1ed3 100644 --- a/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/Sync/SyncOptions.cs +++ b/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/Sync/SyncOptions.cs @@ -16,5 +16,7 @@ public sealed class SyncOptions public bool Delete { get; set; } public bool Recreate { get; set; } + + public bool UpdateCurrentClient { get; set; } } } diff --git a/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/Sync/SyncService.cs b/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/Sync/SyncService.cs index 1cc2f312..527a1181 100644 --- a/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/Sync/SyncService.cs +++ b/cli/Squidex.CLI/Squidex.CLI/Commands/Implementation/Sync/SyncService.cs @@ -129,7 +129,7 @@ public async Task WriteJsonSchemaAsync(IFile file) { await using (var stream = file.OpenWrite()) { - using (var textWriter = new StreamWriter(stream)) + await using (var textWriter = new StreamWriter(stream)) { var jsonSchema = GetSchema(); var jsonSchemaType = jsonSchemaGeneratorSettings.SchemaType; @@ -140,7 +140,7 @@ public async Task WriteJsonSchemaAsync(IFile file) JsonSchema.CreateJsonSerializerContractResolver(jsonSchemaType), Formatting.Indented); - textWriter.Write(json); + await textWriter.WriteAsync(json); } } } diff --git a/cli/Squidex.CLI/Squidex.CLI/Squidex.CLI.csproj b/cli/Squidex.CLI/Squidex.CLI/Squidex.CLI.csproj index 9ca21d13..128ddad1 100644 --- a/cli/Squidex.CLI/Squidex.CLI/Squidex.CLI.csproj +++ b/cli/Squidex.CLI/Squidex.CLI/Squidex.CLI.csproj @@ -14,7 +14,7 @@ net5.0 true sq - 7.24 + 7.25