Skip to content

Commit

Permalink
Merge pull request #23 from Squidex/sync
Browse files Browse the repository at this point in the history
Sync
  • Loading branch information
SebastianStehle authored Jan 29, 2019
2 parents 0e2564b + a88e11c commit a0e0515
Show file tree
Hide file tree
Showing 11 changed files with 851 additions and 580 deletions.
2 changes: 1 addition & 1 deletion cli/Squidex.CLI/Squidex.CLI.sln
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.28307.168
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Squidex.CLI", "Squidex.CLI\Squidex.CLI.csproj", "{2D435C5F-73FB-47F6-BEDA-49E9F9D8E9F7}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Squidex.CLI", "Squidex.CLI\Squidex.CLI.csproj", "{2D435C5F-73FB-47F6-BEDA-49E9F9D8E9F7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down
69 changes: 51 additions & 18 deletions cli/Squidex.CLI/Squidex.CLI/Commands/App_Config.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
// ==========================================================================

using System;
using System.ComponentModel.DataAnnotations;
using CommandDotNet;
using CommandDotNet.Attributes;
using ConsoleTables;
Expand All @@ -25,16 +24,12 @@ public class Config
[InjectProperty]
public IConfigurationService Configuration { get; set; }

[ApplicationMetadata(Name = "view", Description = "Shows the current configuration.")]
public void View([Option] bool json)
[ApplicationMetadata(Name = "list", Description = "Shows the current configuration.")]
public void List(ListArguments arguments)
{
var config = Configuration.GetConfiguration();

if (json)
{
Console.WriteLine(config.JsonPrettyString());
}
else
if (arguments.Table)
{
var table = new ConsoleTable("Name", "App", "ClientId", "ClientSecret", "Url");

Expand All @@ -48,6 +43,10 @@ public void View([Option] bool json)
Console.WriteLine();
Console.WriteLine("Current App: {0}", config.CurrentApp);
}
else
{
Console.WriteLine(config.JsonPrettyString());
}
}

[ApplicationMetadata(Name = "add", Description = "Add or update an app.")]
Expand All @@ -59,37 +58,71 @@ public void Add(AddArguments arguments)
}

[ApplicationMetadata(Name = "remove", Description = "Remove an app.")]
public void Remove(AppArguments arguments)
public void Remove(RemoveArguments arguments)
{
Configuration.Remove(arguments.Name);

Console.WriteLine("> App removed.");
}

[ApplicationMetadata(Name = "reset", Description = "Reset the config.")]
public void Reset()
{
Configuration.Reset();

Console.WriteLine("> Config reset.");
}

[ApplicationMetadata(Name = "use", Description = "Use an app.")]
public void Use(AppArguments arguments)
public void Use(UseArguments arguments)
{
Configuration.UseApp(arguments.Name);

Console.WriteLine("> App selected.");
}

[Validator(typeof(AppArgumentsValidator))]
public sealed class AppArguments : IArgumentModel
[Validator(typeof(Validator))]
public sealed class ListArguments : IArgumentModel
{
[Option(Description = "Output as table")]
public bool Table { get; set; }

public sealed class Validator : AbstractValidator<ListArguments>
{
}
}

[Validator(typeof(Validator))]
public sealed class RemoveArguments : IArgumentModel
{
[Argument(Name = "name", Description = "The name of the app.")]
public string Name { get; set; }

public sealed class Validator : AbstractValidator<RemoveArguments>
{
public Validator()
{
RuleFor(x => x.Name).NotEmpty();
}
}
}

[Validator(typeof(Validator))]
public sealed class UseArguments : IArgumentModel
{
[Argument(Name = "name", Description = "The name of the app.")]
public string Name { get; set; }

public sealed class AppArgumentsValidator : AbstractValidator<AppArguments>
public sealed class Validator : AbstractValidator<UseArguments>
{
public AppArgumentsValidator()
public Validator()
{
RuleFor(x => x.Name).NotEmpty();
}
}
}

[Validator(typeof(AddArgumentsValidator))]
[Validator(typeof(Validator))]
public sealed class AddArguments : IArgumentModel
{
[Argument(Name = "name", Description = "The name of the app.")]
Expand All @@ -114,12 +147,12 @@ public string ToEntryName()

public ConfiguredApp ToModel()
{
return new ConfiguredApp { ClientId = ClientId, ClientSecret = ClientSecret, Name = Name };
return new ConfiguredApp { ClientId = ClientId, ClientSecret = ClientSecret, Name = Name, ServiceUrl = ServiceUrl };
}

public sealed class AddArgumentsValidator : AbstractValidator<AddArguments>
public sealed class Validator : AbstractValidator<AddArguments>
{
public AddArgumentsValidator()
public Validator()
{
RuleFor(x => x.Name).NotEmpty();
RuleFor(x => x.ClientId).NotEmpty();
Expand Down
4 changes: 2 additions & 2 deletions cli/Squidex.CLI/Squidex.CLI/Commands/App_Content.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public async Task Export(ExportArguments arguments)
{
var ctx = QueryContext.Default.Unpublished(arguments.Unpublished);

var client = Configuration.GetClient().GetClient<DummyEntity, DummyData>(arguments.Schema);
var client = Configuration.GetClient().Client.GetClient<DummyEntity, DummyData>(arguments.Schema);

if (arguments.Format == Format.JSON)
{
Expand Down Expand Up @@ -201,7 +201,7 @@ private async Task ExportAsync(ExportArguments arguments, Action<DummyEntity> ha
{
var ctx = QueryContext.Default.Unpublished(arguments.Unpublished);

var client = Configuration.GetClient().GetClient<DummyEntity, DummyData>(arguments.Schema);
var client = Configuration.GetClient().Client.GetClient<DummyEntity, DummyData>(arguments.Schema);

var total = 0L;
var totalRead = 0;
Expand Down
159 changes: 149 additions & 10 deletions cli/Squidex.CLI/Squidex.CLI/Commands/App_Schemas.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,17 @@
// ==========================================================================

using System;
using System.IO;
using System.Threading.Tasks;
using CommandDotNet;
using CommandDotNet.Attributes;
using ConsoleTables;
using FluentValidation;
using FluentValidation.Attributes;
using Newtonsoft.Json;
using Squidex.CLI.Configuration;
using Squidex.ClientLibrary;
using Squidex.ClientLibrary.Management;

namespace Squidex.CLI.Commands
{
Expand All @@ -22,19 +29,15 @@ public class Schemas
[InjectProperty]
public IConfigurationService Configuration { get; set; }

[ApplicationMetadata(Name = "view", Description = "List all schemas.")]
public async Task View([Option] bool json)
[ApplicationMetadata(Name = "list", Description = "List all schemas.")]
public async Task List(ListArguments arguments)
{
var service = Configuration.GetClient();
var client = service.CreateSchemasClient();
var (app, service) = Configuration.GetClient();

var schemas = await client.GetSchemasAsync(service.App);
var schemasClient = service.CreateSchemasClient();
var schemas = await schemasClient.GetSchemasAsync(app);

if (json)
{
Console.WriteLine(schemas.JsonPrettyString());
}
else
if (arguments.Table)
{
var table = new ConsoleTable("Id", "Name", "Published", "LastUpdate");

Expand All @@ -45,6 +48,142 @@ public async Task View([Option] bool json)

table.Write(Format.Default);
}
else
{
Console.WriteLine(schemas.JsonPrettyString());
}
}

[ApplicationMetadata(Name = "get", Description = "Get a schema by name.")]
public async Task Get(GetArguments arguments)
{
var (app, service) = Configuration.GetClient();

var schemasClient = service.CreateSchemasClient();
var schema = await schemasClient.GetSchemaAsync(app, arguments.Name);

Console.WriteLine(schema.JsonPrettyString());
}

[ApplicationMetadata(Name = "sync", Description = "Sync the schema.")]
public async Task Sync(SyncArguments arguments)
{
var (app, service) = Configuration.GetClient();

var schemasClient = service.CreateSchemasClient();

var schemaText = (string)null;
var schemaName = arguments.Name;

var targetSchema = (SchemaDetailsDto)null;
try
{
schemaText = File.ReadAllText(arguments.File);
}
catch (IOException)
{
throw new SquidexException("Cannot read schema file.");
}

if (string.IsNullOrWhiteSpace(schemaName))
{
try
{
var sourceSchema = JsonConvert.DeserializeObject<SchemaDetailsDto>(schemaText);

schemaName = sourceSchema.Name;
}
catch (JsonException ex)
{
throw new SquidexException($"Cannot deserialize schema: {ex.Message}");
}
}

if (string.IsNullOrWhiteSpace(schemaName))
{
throw new SquidexException("Schema name cannot be empty.");
}

try
{
targetSchema = await schemasClient.GetSchemaAsync(app, schemaName);
}
catch
{
targetSchema = null;
}

if (targetSchema == null)
{
var create = JsonConvert.DeserializeObject<CreateSchemaDto>(schemaText);

create.Name = schemaName;

await schemasClient.PostSchemaAsync(app, create);

Console.WriteLine("> Created schema because it does not exists in the target system.");
}
else
{
var request = JsonConvert.DeserializeObject<SynchronizeSchemaDto>(schemaText);

request.NoFieldDeletion = arguments.NoFieldDeletion;
request.NoFieldRecreation = arguments.NoFieldRecreation;

await schemasClient.PutSchemaSyncAsync(app, schemaName, request);

Console.WriteLine("> Synchronized schema");
}
}

[Validator(typeof(Validator))]
public sealed class ListArguments : IArgumentModel
{
[Option(Description = "Output as table")]
public bool Table { get; set; }

public sealed class Validator : AbstractValidator<ListArguments>
{
}
}

[Validator(typeof(GetArgumentsValidator))]
public sealed class GetArguments : IArgumentModel
{
[Argument(Name = "name", Description = "The name of the schema.")]
public string Name { get; set; }

public sealed class GetArgumentsValidator : AbstractValidator<GetArguments>
{
public GetArgumentsValidator()
{
RuleFor(x => x.Name).NotEmpty();
}
}
}

[Validator(typeof(SyncArgumentsValidator))]
public sealed class SyncArguments : IArgumentModel
{
[Argument(Name = "file", Description = "The file with the schema json.")]
public string File { get; set; }

[Option(LongName = "name", Description = "The new schema name.")]
public string Name { get; set; }

[Option(LongName = "no-delete", Description = "Do not delete fields.")]
public bool NoFieldDeletion { get; set; }

[Option(LongName = "no-recreate", Description = "Do not recreate fields.")]
public bool NoFieldRecreation { get; set; }

public sealed class SyncArgumentsValidator : AbstractValidator<SyncArguments>
{
public SyncArgumentsValidator()
{
RuleFor(x => x.File).NotEmpty();
}
}
}
}
}
Expand Down
29 changes: 26 additions & 3 deletions cli/Squidex.CLI/Squidex.CLI/Configuration/ConfigurationService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public sealed class ConfigurationService : IConfigurationService
private const string CloudUrl = "https://cloud.squidex.io";
private readonly JsonSerializer jsonSerializer = new JsonSerializer();
private readonly Configuration configuration;
private string sessionApp;

public ConfigurationService()
{
Expand Down Expand Up @@ -80,6 +81,14 @@ private void Save()
}
}

public void Reset()
{
configuration.Apps.Clear();
configuration.CurrentApp = null;

Save();
}

public void Upsert(string config, ConfiguredApp appConfig)
{
if (string.IsNullOrWhiteSpace(appConfig.ServiceUrl))
Expand Down Expand Up @@ -126,11 +135,25 @@ public void Remove(string entry)
Save();
}

public SquidexClientManager GetClient()
public void UseAppInSession(string entry)
{
if (!string.IsNullOrWhiteSpace(configuration.CurrentApp) && configuration.Apps.TryGetValue(configuration.CurrentApp, out var app))
sessionApp = entry;
}

public (string App, SquidexClientManager Client) GetClient()
{
if (!string.IsNullOrWhiteSpace(sessionApp) && configuration.Apps.TryGetValue(sessionApp, out var app))
{
var authenticator = new Authenticator(app.ServiceUrl, app.ClientId, app.ClientSecret);

return (app.Name, new SquidexClientManager(app.ServiceUrl, app.Name, authenticator));
}

if (!string.IsNullOrWhiteSpace(configuration.CurrentApp) && configuration.Apps.TryGetValue(configuration.CurrentApp, out app))
{
return new SquidexClientManager(app.ServiceUrl, configuration.CurrentApp, new Authenticator(app.ServiceUrl, app.ClientId, app.ClientSecret));
var authenticator = new Authenticator(app.ServiceUrl, app.ClientId, app.ClientSecret);

return (app.Name, new SquidexClientManager(app.ServiceUrl, app.Name, authenticator));
}

throw new SquidexException("Cannot find valid configuration.");
Expand Down
Loading

0 comments on commit a0e0515

Please sign in to comment.