Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions KustoSchemaTools.Tests/Parser/YamlDatabaseHandlerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public async Task GetDatabase()
.WithPlugin(new TablePlugin())
.WithPlugin(new FunctionPlugin())
.WithPlugin(new DatabaseCleanup());
var loader = factory.Create(Path.Combine(BasePath, Deployment), Database);
var loader = factory.Create(Path.Join(BasePath, Deployment), Database);

var db = await loader.LoadAsync();

Expand Down Expand Up @@ -51,7 +51,7 @@ public async Task VerifyFunctionPreformatted()
.WithPlugin(new TablePlugin())
.WithPlugin(new FunctionPlugin());
// DatabaseCleanup intentionally omitted
var loaderWithoutCleanup = factoryWithoutCleanup.Create(Path.Combine(BasePath, Deployment), Database);
var loaderWithoutCleanup = factoryWithoutCleanup.Create(Path.Join(BasePath, Deployment), Database);
var dbWithoutCleanup = await loaderWithoutCleanup.LoadAsync();

// with the DatabaseCleanup plugin
Expand All @@ -60,7 +60,7 @@ public async Task VerifyFunctionPreformatted()
.WithPlugin(new FunctionPlugin())
.WithPlugin(new MaterializedViewsPlugin())
.WithPlugin(new DatabaseCleanup());
var loaderWithCleanup = factoryWithCleanup.Create(Path.Combine(BasePath, Deployment), Database);
var loaderWithCleanup = factoryWithCleanup.Create(Path.Join(BasePath, Deployment), Database);
var dbWithCleanup = await loaderWithCleanup.LoadAsync();

// Assert
Expand Down Expand Up @@ -113,15 +113,15 @@ public async Task VerifyMaterializedView()
.WithPlugin(new TablePlugin())
.WithPlugin(new MaterializedViewsPlugin());
// DatabaseCleanup intentionally omitted
var loaderWithoutCleanup = factoryWithoutCleanup.Create(Path.Combine(BasePath, Deployment), Database);
var loaderWithoutCleanup = factoryWithoutCleanup.Create(Path.Join(BasePath, Deployment), Database);
var dbWithoutCleanup = await loaderWithoutCleanup.LoadAsync();

// with the DatabaseCleanup plugin
var factoryWithCleanup = new YamlDatabaseHandlerFactory<Model.Database>()
.WithPlugin(new TablePlugin())
.WithPlugin(new MaterializedViewsPlugin())
.WithPlugin(new DatabaseCleanup());
var loaderWithCleanup = factoryWithCleanup.Create(Path.Combine(BasePath, Deployment), Database);
var loaderWithCleanup = factoryWithCleanup.Create(Path.Join(BasePath, Deployment), Database);
var dbWithCleanup = await loaderWithCleanup.LoadAsync();

// Assert
Expand Down Expand Up @@ -158,7 +158,7 @@ public async Task VerifyFunctionWithCommentAtEnd()
.WithPlugin(new TablePlugin())
.WithPlugin(new FunctionPlugin())
.WithPlugin(new DatabaseCleanup());
var loader = factory.Create(Path.Combine(BasePath, Deployment), Database);
var loader = factory.Create(Path.Join(BasePath, Deployment), Database);

// Act - Load the database
var db = await loader.LoadAsync();
Expand Down
12 changes: 10 additions & 2 deletions KustoSchemaTools/Changes/ClusterChanges.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,17 @@ public static ClusterChangeSet GenerateChanges(Cluster oldCluster, Cluster newCl
// Run Kusto code diagnostics
foreach (var script in changeSet.Scripts)
{
var code = KustoCode.Parse(script.Text);
var code = KustoCode.Parse(script.Script.Text);
var diagnostics = code.GetDiagnostics();
script.IsValid = !diagnostics.Any();
Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Diagnostics should be captured in the Diagnostics property for consistency with ScriptCompareChange. Currently, diagnostics are only used to set IsValid but not stored. Consider adding:

script.Diagnostics = diagnostics.Any()
    ? diagnostics.Select(diagnostic => new ScriptDiagnostic
    {
        Start = diagnostic.Start,
        End = diagnostic.End,
        Description = diagnostic.Description
    }).ToList()
    : null;
Suggested change
script.IsValid = !diagnostics.Any();
script.IsValid = !diagnostics.Any();
script.Diagnostics = diagnostics.Any()
? diagnostics.Select(diagnostic => new ScriptDiagnostic
{
Start = diagnostic.Start,
End = diagnostic.End,
Description = diagnostic.Description
}).ToList()
: null;

Copilot uses AI. Check for mistakes.
script.Diagnostics = diagnostics.Any()
? diagnostics.Select(diagnostic => new ScriptDiagnostic
{
Start = diagnostic.Start,
End = diagnostic.End,
Description = diagnostic.Description
}).ToList()
: null;
}

changeSet.Markdown = GenerateClusterMarkdown(changeSet);
Expand Down Expand Up @@ -244,7 +252,7 @@ private static string GenerateClusterMarkdown(ClusterChangeSet changeSet)
sb.AppendLine("```kql");
foreach (var script in changeSet.Scripts)
{
sb.AppendLine(script.Text);
sb.AppendLine(script.Script.Text);
sb.AppendLine();
}
sb.AppendLine("```");
Expand Down
12 changes: 10 additions & 2 deletions KustoSchemaTools/Changes/DatabaseChanges.cs
Original file line number Diff line number Diff line change
Expand Up @@ -261,9 +261,17 @@ .. GenerateFollowerCachingChanges(oldState, newState, db => db.MaterializedViews

foreach(var script in result.SelectMany(itm => itm.Scripts))
{
var code = KustoCode.Parse(script.Text);
var code = KustoCode.Parse(script.Script.Text);
var diagnostics = code.GetDiagnostics();
script.IsValid = diagnostics.Any() == false;
script.IsValid = !diagnostics.Any();
script.Diagnostics = diagnostics.Any()
? diagnostics.Select(diagnostic => new ScriptDiagnostic
{
Start = diagnostic.Start,
End = diagnostic.End,
Description = diagnostic.Description
}).ToList()
: null;
}

return result;
Expand Down
20 changes: 15 additions & 5 deletions KustoSchemaTools/Changes/DatabaseScriptContainer.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using KustoSchemaTools.Model;
using System.Collections.Generic;
using KustoSchemaTools.Model;
using Newtonsoft.Json;

namespace KustoSchemaTools.Changes
{
Expand All @@ -23,11 +25,19 @@ public DatabaseScriptContainer(string kind, int order, string script, bool isAsy
IsAsync = isAsync;
}

[JsonProperty("script")]
public DatabaseScript Script { get; set; }
public string Kind{ get; set; }

[JsonProperty("kind")]
public string Kind { get; set; }

[JsonProperty("isValid")]
public bool? IsValid { get; set; }
public string Text => Script.Text;
public int Order => Script.Order;
public bool IsAsync { get;set; }

[JsonProperty("isAsync")]
public bool IsAsync { get; set; }

[JsonProperty("diagnostics", NullValueHandling = NullValueHandling.Ignore)]
public List<ScriptDiagnostic>? Diagnostics { get; set; }
}
}
16 changes: 13 additions & 3 deletions KustoSchemaTools/Changes/DeletionChange.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using KustoSchemaTools.Parser;
using KustoSchemaTools.Model;
using KustoSchemaTools.Parser;
using System.Text;
using System.Linq;
using Kusto.Language;


Expand All @@ -22,9 +24,17 @@ public List<DatabaseScriptContainer> Scripts
get
{
var sc = new DatabaseScriptContainer("Deletion", 0, $".drop {EntityType} {Entity}");
var code = KustoCode.Parse(sc.Text);
var code = KustoCode.Parse(sc.Script.Text);
var diagnostics = code.GetDiagnostics();
sc.IsValid = diagnostics.Any() == false;
sc.IsValid = !diagnostics.Any();
sc.Diagnostics = diagnostics.Any()
? diagnostics.Select(diagnostic => new ScriptDiagnostic
{
Start = diagnostic.Start,
End = diagnostic.End,
Description = diagnostic.Description
}).ToList()
: null;
return new List<DatabaseScriptContainer> { sc };
}
}
Expand Down
14 changes: 11 additions & 3 deletions KustoSchemaTools/Changes/EntityGroupChange.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,23 @@ private void Init()
var toEntityArr = string.Join(",", toEntityStrings);
var toScript = new DatabaseScriptContainer("EntityGroup", 3, $".create-or-alter entity_group {Entity} ({toEntityArr})");

if (added.Any() == false && removed.Any() == false)
if (!added.Any() && !removed.Any())
{
return;
}

Scripts.Add(toScript);
var code = KustoCode.Parse(toScript.Text);
var code = KustoCode.Parse(toScript.Script.Text);
var diagnostics = code.GetDiagnostics();
Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Diagnostics should be captured in the Diagnostics property for consistency with ScriptCompareChange. Currently, diagnostics are only used to set IsValid but not stored. Consider adding:

toScript.Diagnostics = diagnostics.Any()
    ? diagnostics.Select(diagnostic => new ScriptDiagnostic
    {
        Start = diagnostic.Start,
        End = diagnostic.End,
        Description = diagnostic.Description
    }).ToList()
    : null;
Suggested change
var diagnostics = code.GetDiagnostics();
var diagnostics = code.GetDiagnostics();
toScript.Diagnostics = diagnostics.Any()
? diagnostics.Select(diagnostic => new ScriptDiagnostic
{
Start = diagnostic.Start,
End = diagnostic.End,
Description = diagnostic.Description
}).ToList()
: null;

Copilot uses AI. Check for mistakes.
toScript.IsValid = diagnostics.Any() == false;
toScript.IsValid = !diagnostics.Any();
toScript.Diagnostics = diagnostics.Any()
? diagnostics.Select(diagnostic => new ScriptDiagnostic
{
Start = diagnostic.Start,
End = diagnostic.End,
Description = diagnostic.Description
}).ToList()
: null;
var logo = toScript.IsValid.Value ? ":green_circle:" : ":red_circle:";


Expand Down
26 changes: 18 additions & 8 deletions KustoSchemaTools/Changes/ScriptCompareChange.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Data;
using DiffPlex.DiffBuilder.Model;
using Kusto.Language.Editor;
using System.Linq;

namespace KustoSchemaTools.Changes
{
Expand All @@ -23,7 +24,7 @@ private void Init()
var to = To.CreateScripts(Entity, From == null);
Markdown = string.Empty;

if (to.Any() == false) return;
if (!to.Any()) return;

StringBuilder sb = new StringBuilder($"## {Entity}");
sb.AppendLine();
Expand All @@ -32,8 +33,8 @@ private void Init()
foreach (var change in to)
{
var before = from.ContainsKey(change.Kind) ? from[change.Kind] : null;
var beforeText = before?.Text ?? "";
var afterText = change.Text;
var beforeText = before?.Script.Text ?? string.Empty;
var afterText = change.Script.Text;

var singleLinebeforeText = new KustoCodeService(KustoCode.Parse(beforeText)).GetMinimalText(MinimalTextKind.SingleLine);
var singleLineafterText = new KustoCodeService(KustoCode.Parse(afterText)).GetMinimalText(MinimalTextKind.SingleLine);
Expand All @@ -43,18 +44,27 @@ private void Init()

var zipped = reducedBefore.GetLexicalTokens().Zip(reducedAfter.GetLexicalTokens()).ToList();
var diffs = zipped.Where(itm => itm.First.Text != itm.Second.Text).ToList();
if(diffs.Any() == false) continue;
if (!diffs.Any()) continue;

if (singleLinebeforeText.Equals(singleLineafterText)) continue;

var differ = new Differ();
var diff = InlineDiffBuilder.Diff(beforeText, afterText, true);
if (diff.Lines.All(itm => itm.Type == ChangeType.Unchanged)) continue;

var code = KustoCode.Parse(change.Text);
var code = KustoCode.Parse(change.Script.Text);

var diagnostics = code.GetDiagnostics();
change.IsValid = diagnostics.Any() == false || change.Order == -1;
var hasDiagnostics = diagnostics.Any();
change.IsValid = !hasDiagnostics || change.Script.Order == -1;
change.Diagnostics = hasDiagnostics
? diagnostics.Select(diagnostic => new ScriptDiagnostic
{
Start = diagnostic.Start,
End = diagnostic.End,
Description = diagnostic.Description
}).ToList()
: null;
Scripts.Add(change);


Expand Down Expand Up @@ -102,10 +112,10 @@ private void Init()
}
sb.AppendLine("<tr>");
sb.AppendLine($" <td colspan=\"2\">Script:</td>");
sb.AppendLine($" <td colspan=\"10\"><pre lang=\"kql\">{change.Text.PrettifyKql()}</pre></td>");
sb.AppendLine($" <td colspan=\"10\"><pre lang=\"kql\">{change.Script.Text.PrettifyKql()}</pre></td>");
sb.AppendLine("</tr>");

if (change.IsValid == false)
if (change.IsValid is false)
{
foreach (var diagnostic in diagnostics)
{
Expand Down
Loading
Loading