Skip to content

Commit

Permalink
CreateOnly/NoRemove - global options
Browse files Browse the repository at this point in the history
  • Loading branch information
Kevin Jump committed Oct 5, 2020
1 parent fb28089 commit ac6f5be
Show file tree
Hide file tree
Showing 16 changed files with 186 additions and 66 deletions.
6 changes: 6 additions & 0 deletions uSync8.BackOffice/Config/uSync8.config
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@
<!-- calls a rebuild cache when an import completes
(for Umbraco 8.3+ recommended value is false) -->
<RebuildCacheOnCompletion>False</RebuildCacheOnCompletion>

<!-- defaults settings that can be used across all handlers -->
<HandlerDefaults>
<Add Key="NoRemove" Value="true" />
<Add Key="CreateOnly" Value="true" />
</HandlerDefaults>

<!-- handler sets -->
<HandlerSets default="default">
Expand Down
42 changes: 36 additions & 6 deletions uSync8.BackOffice/Configuration/BackOfficeConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ public uSyncSettings LoadSettings()

settings.CacheFolderKeys = node.Element("CacheFolderKeys").ValueOrDefault(true);


settings.DefaultHandlerSettings = LoadKeyValueSettings(node.Element("HandlerDefaults"));

// load the handlers
var handlerSets = node.Element("HandlerSets");
if (handlerSets != null)
Expand All @@ -95,6 +98,7 @@ public uSyncSettings LoadSettings()

settings.CustomMappings = LoadAppKeysFromNode(node, "Mappings", true);


// fire the loaded event, so things can tell when they are loaded.
Reloaded?.Invoke(settings);

Expand Down Expand Up @@ -309,21 +313,47 @@ public HandlerSettings LoadHandlerConfig(XElement node, uSyncSettings defaultSet
// can access them as needed (v8.7+ also passed to serializers)
//


var perHandlerSettings = new Dictionary<string, string>();


// merge in the defaults
if (defaultSettings.DefaultHandlerSettings != null)
{
defaultSettings.DefaultHandlerSettings.ToList()
.ForEach(x => perHandlerSettings[x.Key] = x.Value);
}

// merge in the handler.
var handlerSettings = LoadKeyValueSettings(node);
if (handlerSettings != null)
{
handlerSettings.ToList()
.ForEach(x => perHandlerSettings[x.Key] = x.Value);
}

settings.Settings = perHandlerSettings;

return settings;
}

private Dictionary<string, string> LoadKeyValueSettings(XElement node)
{
if (node == null) return null;

Dictionary<string, string> keyValuePairs = new Dictionary<string, string>();

foreach (var settingItem in node.Elements("Add"))
{
var key = settingItem.Attribute("Key").ValueOrDefault(string.Empty);
var value = settingItem.Attribute("Value").ValueOrDefault(string.Empty);

if (string.IsNullOrWhiteSpace(key) || string.IsNullOrWhiteSpace(value))
continue;
perHandlerSettings.Add(key, value);
}

settings.Settings = perHandlerSettings;
keyValuePairs.Add(key, value);
}

return settings;
return keyValuePairs;
}

/// <summary>
Expand Down
6 changes: 6 additions & 0 deletions uSync8.BackOffice/Configuration/uSyncSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,12 @@ public HandlerSet DefaultHandlerSet()
/// to make one property type to behave like an existing one
/// </summary>
public IDictionary<string, string> CustomMappings { get; set; }


/// <summary>
/// options you can set at the top level, that are then set on all handlers.
/// </summary>
public IDictionary<string, string> DefaultHandlerSettings { get; set; }
}

public class HandlerSet
Expand Down
18 changes: 17 additions & 1 deletion uSync8.BackOffice/SyncHandlers/SyncHandlerRoot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -562,7 +562,23 @@ protected virtual IEnumerable<string> GetImportFiles(string folder)
/// <summary>
/// check to see if this element should be imported as part of the process.
/// </summary>
virtual protected bool ShouldImport(XElement node, HandlerSettings config) => true;
virtual protected bool ShouldImport(XElement node, HandlerSettings config)
{
// if createOnly is on, then we only create things that are not already there.
// this lookup is slow(ish) so we only do it if we have to.
if (config.GetSetting<bool>(uSyncConstants.DefaultSettings.CreateOnly, uSyncConstants.DefaultSettings.CreateOnly_Default)
|| config.GetSetting<bool>(uSyncConstants.DefaultSettings.OneWay, uSyncConstants.DefaultSettings.CreateOnly_Default))
{
var item = serializer.FindItem(node);
if (item != null)
{
logger.Debug(handlerType, "CreateOnly: Item {alias} already exist not importing it.", node.GetAlias());
return false;
}
}
return true;
}


/// <summary>
/// Check to see if this elment should be exported.
Expand Down
25 changes: 8 additions & 17 deletions uSync8.ContentEdition/Handlers/ContentHandlerBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,14 @@ protected override string GetXmlMatchString(XElement node)

protected override bool ShouldImport(XElement node, HandlerSettings config)
{
// check base first - if it says no - then no point checking this.
if (!base.ShouldImport(node, config)) return false;

// unless the setting is explicit we don't import trashed items.
var trashed = node.Element("Info")?.Element("Trashed").ValueOrDefault(false);
if (trashed.GetValueOrDefault(false) && !GetConfigValue(config, "ImportTrashed", true)) return false;
if (trashed.GetValueOrDefault(false) && !config.GetSetting("ImportTrashed", true)) return false;

var include = GetConfigValue(config, "Include", "")
var include = config.GetSetting("Include", "")
.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

if (include.Length > 0)
Expand All @@ -110,7 +113,7 @@ protected override bool ShouldImport(XElement node, HandlerSettings config)
}
}

var exclude = GetConfigValue(config, "Exclude", "")
var exclude = config.GetSetting("Exclude", "")
.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
if (exclude.Length > 0)
{
Expand Down Expand Up @@ -139,28 +142,16 @@ protected override bool ShouldExport(XElement node, HandlerSettings config)
{
// We export trashed items by default, (but we don't import them by default)
var trashed = node.Element("Info")?.Element("Trashed").ValueOrDefault(false);
if (trashed.GetValueOrDefault(false) && !GetConfigValue(config, "ExportTrashed", true)) return false;
if (trashed.GetValueOrDefault(false) && config.GetSetting<bool>("ExportTrashed", true)) return false;

if (GetConfigValue(config, "RulesOnExport", false))
if (config.GetSetting("RulesOnExport", false))
{
return ShouldImport(node, config);
}

return true;
}

private bool GetConfigValue(HandlerSettings config, string setting, bool defaultValue)
{
if (!config.Settings.ContainsKey(setting)) return defaultValue;
return config.Settings[setting].InvariantEquals("true");
}

private string GetConfigValue(HandlerSettings config, string setting, string defaultValue)
{
if (!config.Settings.ContainsKey(setting)) return defaultValue;
if (string.IsNullOrWhiteSpace(config.Settings[setting])) return defaultValue;
return config.Settings[setting];
}

// we only match duplicate actions by key.
protected override bool DoActionsMatch(uSyncAction a, uSyncAction b)
Expand Down
16 changes: 10 additions & 6 deletions uSync8.ContentEdition/Serializers/RelationTypeSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ protected override SyncAttempt<IRelationType> DeserializeCore(XElement node, Syn
// we have to save before we can add the relations.
this.SaveItem(item);
hasBeenSaved = true;
details.AddRange(DeserializeRelations(node, item));
details.AddRange(DeserializeRelations(node, item, options));
}

return SyncAttempt<IRelationType>.Succeed(item.Name, item, ChangeType.Import, hasBeenSaved, details);
Expand All @@ -103,7 +103,7 @@ protected override SyncAttempt<IRelationType> DeserializeCore(XElement node, Syn
/// <summary>
/// Deserialize the relations for a relation type.
/// </summary>
private IEnumerable<uSyncChange> DeserializeRelations(XElement node, IRelationType relationType)
private IEnumerable<uSyncChange> DeserializeRelations(XElement node, IRelationType relationType, SyncSerializerOptions options)
{
var changes = new List<uSyncChange>();

Expand Down Expand Up @@ -141,12 +141,16 @@ private IEnumerable<uSyncChange> DeserializeRelations(XElement node, IRelationTy
newRelations.Add($"{parentItem.Id}_{childItem.Id}");
}

var obsolete = existing.Where(x => !newRelations.Contains($"{x.ParentId}_{x.ChildId}"));

foreach (var obsoleteRelation in obsolete)
if (options.DeleteItems())
{
changes.Add(uSyncChange.Delete(relationType.Alias, obsoleteRelation.ParentId.ToString(), obsoleteRelation.ChildId.ToString()));
relationService.Delete(obsoleteRelation);
var obsolete = existing.Where(x => !newRelations.Contains($"{x.ParentId}_{x.ChildId}"));

foreach (var obsoleteRelation in obsolete)
{
changes.Add(uSyncChange.Delete(relationType.Alias, obsoleteRelation.ParentId.ToString(), obsoleteRelation.ChildId.ToString()));
relationService.Delete(obsoleteRelation);
}
}

return changes;
Expand Down
65 changes: 37 additions & 28 deletions uSync8.Core/Serialization/Serializers/ContentTypeBaseSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ protected IEnumerable<uSyncChange> DeserializeStructure(TObject item, XElement n
return changes;
}

protected IEnumerable<uSyncChange> DeserializeProperties(TObject item, XElement node)
protected IEnumerable<uSyncChange> DeserializeProperties(TObject item, XElement node, SyncSerializerOptions options)
{
logger.Debug(serializerType, "Deserializing Properties");

Expand Down Expand Up @@ -462,14 +462,20 @@ protected IEnumerable<uSyncChange> DeserializeProperties(TObject item, XElement
}
}
}

}

// move things between tabs.
changes.AddRange(MoveProperties(item, propertiesToMove));

// remove what needs to be removed
changes.AddRange(RemoveProperties(item, propertiesNode));
if (options.DeleteItems())
{
// remove what needs to be removed
changes.AddRange(RemoveProperties(item, propertiesNode));
}
else
{
logger.Debug(serializerType, "Property Removal disabled by config");
}

return changes;

Expand Down Expand Up @@ -575,40 +581,43 @@ protected IEnumerable<uSyncChange> DeserializeTabs(TObject item, XElement node)
}


protected IEnumerable<uSyncChange> CleanTabs(TObject item, XElement node)
protected IEnumerable<uSyncChange> CleanTabs(TObject item, XElement node, SyncSerializerOptions options)
{
logger.Debug(serializerType, "Cleaning Tabs Base");
if (options.DeleteItems())
{
logger.Debug(serializerType, "Cleaning Tabs Base");

var tabNode = node?.Element("Tabs");
if (tabNode == null) return Enumerable.Empty<uSyncChange>();
var tabNode = node?.Element("Tabs");
if (tabNode == null) return Enumerable.Empty<uSyncChange>();

var newTabs = tabNode.Elements("Tab")
.Where(x => x.Element("Caption") != null)
.Select(x => x.Element("Caption").ValueOrDefault(string.Empty))
.ToList();
var newTabs = tabNode.Elements("Tab")
.Where(x => x.Element("Caption") != null)
.Select(x => x.Element("Caption").ValueOrDefault(string.Empty))
.ToList();

List<string> removals = new List<string>();
foreach (var tab in item.PropertyGroups)
{
if (!newTabs.InvariantContains(tab.Name))
List<string> removals = new List<string>();
foreach (var tab in item.PropertyGroups)
{
removals.Add(tab.Name);
if (!newTabs.InvariantContains(tab.Name))
{
removals.Add(tab.Name);
}
}
}

if (removals.Count > 0)
{
var changes = new List<uSyncChange>();

foreach (var name in removals)
if (removals.Count > 0)
{
logger.Debug(serializerType, "Removing {0}", name);
changes.Add(uSyncChange.Delete($"Tabs/{name}", name, name));
var changes = new List<uSyncChange>();

item.PropertyGroups.Remove(name);
}
foreach (var name in removals)
{
logger.Debug(serializerType, "Removing {0}", name);
changes.Add(uSyncChange.Delete($"Tabs/{name}", name, name));

return changes;
item.PropertyGroups.Remove(name);
}

return changes;
}
}

return Enumerable.Empty<uSyncChange>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,13 +105,13 @@ protected override SyncAttempt<IContentType> DeserializeCore(XElement node, Sync

details.AddRange(DeserializeBase(item, node));
details.AddRange(DeserializeTabs(item, node));
details.AddRange(DeserializeProperties(item, node));
details.AddRange(DeserializeProperties(item, node, options));

// content type only property stuff.
details.AddRange(DeserializeContentTypeProperties(item, node));

// clean tabs
details.AddRange(CleanTabs(item, node));
details.AddRange(CleanTabs(item, node, options));

// templates
details.AddRange(DeserializeTemplates(item, node));
Expand Down
5 changes: 4 additions & 1 deletion uSync8.Core/Serialization/Serializers/MacroSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,10 @@ protected override SyncAttempt<IMacro> DeserializeCore(XElement node, SyncSerial

}

RemoveOrphanProperties(item, properties);
if (options.DeleteItems())
{
RemoveOrphanProperties(item, properties);
}

return SyncAttempt<IMacro>.Succeed(item.Name, item, ChangeType.Import, details);
}
Expand Down
5 changes: 3 additions & 2 deletions uSync8.Core/Serialization/Serializers/MediaTypeSerializer.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Xml.Linq;

using Umbraco.Core;
Expand Down Expand Up @@ -73,9 +74,9 @@ protected override SyncAttempt<IMediaType> DeserializeCore(XElement node, SyncSe

// mediaTypeService.Save(item);

details.AddRange(DeserializeProperties(item, node));
details.AddRange(DeserializeProperties(item, node, options));

CleanTabs(item, node);
CleanTabs(item, node, options);

return SyncAttempt<IMediaType>.Succeed(item.Name, item, ChangeType.Import, details);
}
Expand Down
4 changes: 2 additions & 2 deletions uSync8.Core/Serialization/Serializers/MemberTypeSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,9 @@ protected override SyncAttempt<IMemberType> DeserializeCore(XElement node, SyncS

details.AddRange(DeserializeBase(item, node));
details.AddRange(DeserializeTabs(item, node));
details.AddRange(DeserializeProperties(item, node));
details.AddRange(DeserializeProperties(item, node, options));

CleanTabs(item, node);
CleanTabs(item, node, options);

// memberTypeService.Save(item);

Expand Down
18 changes: 18 additions & 0 deletions uSync8.Core/Serialization/SyncOptionsExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;

namespace uSync8.Core.Serialization
{
public static class SyncOptionsExtensions
{
/// <summary>
/// perform the removal of properties and items.
/// </summary>
public static bool DeleteItems(this SyncSerializerOptions options)
=> !options.GetSetting<bool>(uSyncConstants.DefaultSettings.NoRemove, uSyncConstants.DefaultSettings.NoRemove_Default);
}
}
Loading

0 comments on commit ac6f5be

Please sign in to comment.