Skip to content

Commit

Permalink
V13/roots export fix (#631)
Browse files Browse the repository at this point in the history
* Fix: Exception when a handler doesn't have a tracker.

* Fix naming when type isn't an interface.

* UI Fix

* Fix bug - error when target config is blank

* Ignore v13.0 build warning

* Fix #623 - Export should only write changes to child folder.

* - fix when target object in block/image merge is already null.

* Also fix #622 - apply button when the source is 'combined'

* Comment methods.
  • Loading branch information
KevinJump authored Apr 22, 2024
1 parent 0774378 commit 6f9c21a
Show file tree
Hide file tree
Showing 23 changed files with 194 additions and 152 deletions.
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

<TreatWarningsAsErrors>True</TreatWarningsAsErrors>

<NoWarn>CS0618</NoWarn>
<NoWarn>CS0618,NU1902</NoWarn>

<PackageReleaseNotes>
<![CDATA[9.0 : Dotnet core version
Expand Down
34 changes: 30 additions & 4 deletions uSync.BackOffice/Services/SyncFileService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@
using System.Xml.Linq;
using System.Xml.Serialization;

using MessagePack.Formatters;

using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

using Umbraco.Cms.Core.Extensions;
using Umbraco.Extensions;

using uSync.BackOffice.Models;
using uSync.Core;
Expand Down Expand Up @@ -511,7 +514,7 @@ public IEnumerable<OrderedNodeInfo> MergeFolders(string[] folders, string extens
if (elements.ContainsKey(item.Key))
{
// merge these files.
item.Value.SetNode(trackerBase.MergeFiles(elements[item.Key].Node, item.Value.Node));
item.Value.SetNode(MergeNodes(elements[item.Key].Node, item.Value.Node, trackerBase));
item.Value.FileName = $"{uSyncConstants.MergedFolderName}/{Path.GetFileName(item.Value.FileName)}";
}

Expand All @@ -522,7 +525,27 @@ public IEnumerable<OrderedNodeInfo> MergeFolders(string[] folders, string extens
return elements.Values;
}

private IEnumerable<KeyValuePair<string, OrderedNodeInfo>> GetFolderItems(string folder, string extension)
/// <summary>
/// merge the files into a single XElement that can be imported as if it was on disk.
/// </summary>
public XElement MergeFiles(string[] filenames, ISyncTrackerBase trackerBase)
{
if (filenames.Length == 0) return null;
var latest = LoadXElementSafe(filenames[0]);
if (filenames.Length == 1) return latest;

for (var n = 1; n < filenames.Length; n++) {
var node = LoadXElementSafe(filenames[n]);
if (node is null) continue;
latest = MergeNodes(latest, node, trackerBase);
}
return latest;
}

private XElement MergeNodes(XElement source, XElement target, ISyncTrackerBase trackerBase)
=> trackerBase is null ? target : trackerBase.MergeFiles(source, target);

private IEnumerable<KeyValuePair<string, OrderedNodeInfo>> GetFolderItems(string folder, string extension)
{
foreach (var file in GetFilePaths(folder, extension))
{
Expand Down Expand Up @@ -568,10 +591,13 @@ public XElement GetDifferences(List<XElement> nodes, ISyncTrackerBase trackerBas
{
if (nodes?.Count == 0) return null;
if (nodes.Count == 1) return nodes[0];

return trackerBase.GetDifferences(nodes);
if (trackerBase is null)
return SyncRootMergerHelper.GetDifferencesByFileContents(nodes);

return trackerBase?.GetDifferences(nodes);
}


/// <summary>
/// get all xml elements that represent this item across
/// all folders.
Expand Down
9 changes: 4 additions & 5 deletions uSync.BackOffice/Services/uSyncService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -391,16 +391,15 @@ private static IEnumerable<uSyncAction> PerformPostImport(IEnumerable<HandlerCon
/// <returns>Action detailing change or not</returns>
public uSyncAction ImportSingleAction(uSyncAction action)
{
var folders = _uSyncConfig.Settings.Folders;

var handlerConfig = _handlerFactory.GetValidHandler(action.HandlerAlias);
if (handlerConfig is null) return new uSyncAction();

if (handlerConfig != null)
{

return handlerConfig.Handler
.Import(action.FileName, handlerConfig.Settings, true)
.FirstOrDefault();
}

return new uSyncAction();

}

Expand Down
46 changes: 0 additions & 46 deletions uSync.BackOffice/SyncHandlers/Handlers/ContentTypeBaseHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,51 +39,5 @@ protected ContentTypeBaseHandler(
ISyncItemFactory syncItemFactory)
: base(logger, entityService, appCaches, shortStringHelper, syncFileService, mutexService, uSyncConfig, syncItemFactory)
{ }

/// <inheritdoc />
protected override SyncAttempt<XElement> Export_DoExport(TObject item, string filename, string[] folders, HandlerSettings config)
{
// all the possible files that there could be.
var files = folders.Select(x => GetPath(x, item, config.GuidNames, config.UseFlatStructure)).ToArray();
var nodes = syncFileService.GetAllNodes(files[..^1]);

// with roots enabled - we attempt to merge doctypes !
//
var attempt = SerializeItem(item, new Core.Serialization.SyncSerializerOptions(config.Settings));
if (attempt.Success)
{
if (ShouldExport(attempt.Item, config))
{
if (nodes.Count > 0)
{
nodes.Add(attempt.Item);
var difference = syncFileService.GetDifferences(nodes, trackers.FirstOrDefault());
if (difference != null)
{
syncFileService.SaveXElement(difference, filename);
}
else
{
if (syncFileService.FileExists(filename))
syncFileService.DeleteFile(filename);
}

}
else
{
syncFileService.SaveXElement(attempt.Item, filename);
}

if (config.CreateClean && HasChildren(item))
CreateCleanFile(GetItemKey(item), filename);
}
else
{
return SyncAttempt<XElement>.Succeed(filename, ChangeType.NoChange, "Not Exported (Based on configuration)");
}
}

return attempt;
}
}
}
45 changes: 0 additions & 45 deletions uSync.BackOffice/SyncHandlers/Handlers/DataTypeHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,50 +116,5 @@ protected override void DeleteFolder(int id)
protected override string GetItemFileName(IDataType item)
=> GetItemAlias(item).ToSafeAlias(shortStringHelper);

/// <inheritdoc />
protected override SyncAttempt<XElement> Export_DoExport(IDataType item, string filename, string[] folders, HandlerSettings config)
{
// all the possible files that there could be.
var files = folders.Select(x => GetPath(x, item, config.GuidNames, config.UseFlatStructure)).ToArray();
var nodes = syncFileService.GetAllNodes(files[..^1]);

// with roots enabled - we attempt to merge doctypes !
//
var attempt = SerializeItem(item, new Core.Serialization.SyncSerializerOptions(config.Settings));
if (attempt.Success)
{
if (ShouldExport(attempt.Item, config))
{
if (nodes.Count > 0)
{
nodes.Add(attempt.Item);
var difference = syncFileService.GetDifferences(nodes, trackers.FirstOrDefault());
if (difference != null)
{
syncFileService.SaveXElement(difference, filename);
}
else
{
if (syncFileService.FileExists(filename))
syncFileService.DeleteFile(filename);
}

}
else
{
syncFileService.SaveXElement(attempt.Item, filename);
}

if (config.CreateClean && HasChildren(item))
CreateCleanFile(GetItemKey(item), filename);
}
else
{
return SyncAttempt<XElement>.Succeed(filename, ChangeType.NoChange, "Not Exported (Based on configuration)");
}
}

return attempt;
}
}
}
74 changes: 61 additions & 13 deletions uSync.BackOffice/SyncHandlers/SyncHandlerRoot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
using System.Threading;
using System.Xml.Linq;

using J2N.Collections.ObjectModel;

using Microsoft.Extensions.Logging;

using Umbraco.Cms.Core;
Expand All @@ -18,7 +20,6 @@

using uSync.BackOffice.Configuration;
using uSync.BackOffice.Extensions;
using uSync.BackOffice.Models;
using uSync.BackOffice.Services;
using uSync.BackOffice.SyncHandlers.Models;
using uSync.Core;
Expand All @@ -29,13 +30,13 @@

namespace uSync.BackOffice.SyncHandlers
{
/// <summary>
/// Root base class for all handlers
/// </summary>
/// <remarks>
/// If the Handler manages something that Implements IEntity use SyncBaseHandler
/// </remarks>
public abstract class SyncHandlerRoot<TObject, TContainer>
/// <summary>
/// Root base class for all handlers
/// </summary>
/// <remarks>
/// If the Handler manages something that Implements IEntity use SyncBaseHandler
/// </remarks>
public abstract class SyncHandlerRoot<TObject, TContainer>
{
/// <summary>
/// Reference to the Logger
Expand Down Expand Up @@ -349,7 +350,22 @@ protected virtual IReadOnlyList<OrderedNodeInfo> GetMergedItems(string[] folders
return syncFileService.MergeFolders(folders, uSyncConfig.Settings.DefaultExtension, baseTracker).ToArray();
}

private void PerformImportClean(List<string> cleanMarkers, List<uSyncAction> actions, HandlerSettings config, SyncUpdateCallback callback)
/// <summary>
/// given a file path, will give you the merged values across all folders.
/// </summary>
protected virtual XElement GetMergedNode(string filePath)
{
var allFiles = uSyncConfig.GetFolders()
.Select(x => syncFileService.GetAbsPath($"{x}/{this.DefaultFolder}/{filePath}"))
.ToArray();

var baseTracker = trackers.FirstOrDefault() as ISyncTrackerBase;
return syncFileService.MergeFiles(allFiles, baseTracker);
}



private void PerformImportClean(List<string> cleanMarkers, List<uSyncAction> actions, HandlerSettings config, SyncUpdateCallback callback)
{
foreach (var item in cleanMarkers.Select((filePath, Index) => new { filePath, Index }))
{
Expand Down Expand Up @@ -467,7 +483,7 @@ public virtual IEnumerable<uSyncAction> Import(string filePath, HandlerSettings
{
try
{
syncFileService.EnsureFileExists(filePath);
syncFileService.EnsureFileExists(filePath);
var node = syncFileService.LoadXElement(filePath);
return Import(node, filePath, config, flags);
}
Expand Down Expand Up @@ -501,6 +517,15 @@ virtual public IEnumerable<uSyncAction> Import(string file, HandlerSettings conf
var flags = SerializerFlags.OnePass;
if (force) flags |= SerializerFlags.Force;

if (file.InvariantStartsWith($"{uSyncConstants.MergedFolderName}/"))
{
var node = GetMergedNode(file.Substring(uSyncConstants.MergedFolderName.Length+1));
if (node is not null)
return Import(node, file, config, flags);
else
throw new Exception("Unable to merge files from root folder");
}

return Import(file, config, flags);
}

Expand Down Expand Up @@ -1064,8 +1089,32 @@ protected virtual SyncAttempt<XElement> Export_DoExport(TObject item, string fil
{
if (ShouldExport(attempt.Item, config))
{
// only write the file to disk if it should be exported.
syncFileService.SaveXElement(attempt.Item, filename);
var files = folders.Select(x => GetPath(x, item, config.GuidNames, config.UseFlatStructure)).ToArray();
var nodes = syncFileService.GetAllNodes(files[..^1]);
if (nodes.Count > 0)
{
nodes.Add(attempt.Item);
var differences = syncFileService.GetDifferences(nodes, trackers.FirstOrDefault());
if (differences is not null && differences.HasElements)
{
syncFileService.SaveXElement(attempt.Item, filename);
}
else
{

if (syncFileService.FileExists(filename))
{
// we don't delete them - because in deployments they might then hang around
// we mark them as reverted and then they don't get processed.
var emptyNode = XElementExtensions.MakeEmpty(attempt.Item.GetKey(), SyncActionType.None, "Reverted to root");
syncFileService.SaveXElement(emptyNode, filename);
}
}
}
else
{
syncFileService.SaveXElement(attempt.Item, filename);
}

if (config.CreateClean && HasChildren(item))
{
Expand All @@ -1077,7 +1126,6 @@ protected virtual SyncAttempt<XElement> Export_DoExport(TObject item, string fil
return SyncAttempt<XElement>.Succeed(Path.GetFileName(filename), ChangeType.NoChange, "Not Exported (Based on configuration)");
}
}

return attempt;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,13 +183,20 @@
visible: false,
icon: getGroupIcon(group),
counts: getCounts(group),
name: key.substring(1) + "s"
name: getGroupName(key)
};
});

return grouped;
}

function getGroupName(name) {
if (name?.startsWith('I') == true) {
return name.substring(1) + 's';
}
return name + 's';
}

function getCounts(group, addItemInfo) {

var counts = {
Expand Down
24 changes: 24 additions & 0 deletions uSync.Core/Extensions/XElementExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Xml;
using System.Xml.Linq;

using Umbraco.Extensions;
Expand Down Expand Up @@ -309,5 +312,26 @@ public static TObject ValueOrDefault<TObject>(this XAttribute attribute, TObject
return defaultValue;
}
#endregion

/// <summary>
/// gets a hash of the xml, in a platform agnostic way.
/// </summary>
public static string MakePlatformSafeHash(this XElement node)
{
using (MemoryStream s = new MemoryStream())
{
// for consistency across platforms we need to harmonize line endings.
using (var writer = XmlWriter.Create(s, new XmlWriterSettings { NewLineChars = "\r\n" }))
{
node.Save(writer);
writer.Flush();
s.Position = 0;
using (HashAlgorithm hashAlgorithm = CryptoConfig.AllowOnlyFipsAlgorithms ? SHA1.Create() : MD5.Create())
{
return BitConverter.ToString(hashAlgorithm.ComputeHash(s)).Replace("-", "").ToLower();
}
}
}
}
}
}
3 changes: 3 additions & 0 deletions uSync.Core/Roots/Configs/BlockGridConfigMerger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ public virtual object GetMergedConfig(string root, string target)
x => x.Name,
x => x.Name?.StartsWith(_removedLabel) == true);

if (targetConfig.BlockGroups.Length == 0 && targetConfig.Blocks.Length == 0)
return null;

return targetConfig;
}

Expand Down
Loading

0 comments on commit 6f9c21a

Please sign in to comment.