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
340 changes: 281 additions & 59 deletions Cargo.lock

Large diffs are not rendered by default.

14 changes: 7 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,19 @@ repository = "https://github.com/link-foundation/link-cli"
crate-type = ["cdylib", "rlib"]

[dependencies]
anyhow = "1.0"
anyhow = "1.0.102"
link-cli = { path = "rust" }
wasm-bindgen = "0.2"
console_error_panic_hook = { version = "0.1.6", optional = true }
wasm-bindgen = "0.2.120"
console_error_panic_hook = { version = "0.1.7", optional = true }
wee_alloc = { version = "0.4.5", optional = true }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
serde = { version = "1.0.228", features = ["derive"] }
serde_json = "1.0.149"

[dev-dependencies]
wasm-bindgen-test = "0.3"
wasm-bindgen-test = "0.3.70"

[dependencies.web-sys]
version = "0.3"
version = "0.3.97"
features = [
"console",
]
Expand Down
5 changes: 5 additions & 0 deletions csharp/.changeset/update-links-notation-dependency.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'Foundation.Data.Doublets.Cli': patch
---

Updated the C# LiNo parser dependency to the current `Link.Foundation.Links.Notation` package and refreshed supported NuGet package versions.
Original file line number Diff line number Diff line change
Expand Up @@ -915,16 +915,15 @@ public void CreateTwoNamedLinksTest()

var finalLinks = GetAllLinks(links);
Console.WriteLine($"[Test] Final links count: {finalLinks.Count}");
Assert.Single(finalLinks.Where(l => l.Index == finalSonId));
var finalSonLink = finalLinks.First(l => l.Index == finalSonId);
var finalSonLink = Assert.Single(finalLinks, l => l.Index == finalSonId);
Assert.Equal(finalFatherId, finalSonLink.Source);
Assert.Equal(finalMotherId, finalSonLink.Target);
Console.WriteLine("[Test] Final state verification completed");
Console.WriteLine("[Test] UpdateNamedLinkNameTest completed successfully");
}, enableTracing: true);
}

[Fact(Timeout = 3000)] // 3 second timeout
[Fact]
public void UpdateNamedLinkNameTest()
{
Console.WriteLine("[Test] ===== Starting UpdateNamedLinkNameTest =====");
Expand Down Expand Up @@ -1613,7 +1612,7 @@ public void CreateLinkWithNonExistentReference_ShouldThrowException()
{
ProcessQueryStrict(links, "(() ((1: 10 20)))");
});

Assert.Contains("Invalid reference to non-existent link '10'", exception.Message);
Assert.Contains("--auto-create-missing-references", exception.Message);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@
<IsTestProject>true</IsTestProject>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="xunit" Version="2.5.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.3" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="10.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.5.1" />
<PackageReference Include="xunit" Version="2.9.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.5" />
</ItemGroup>

<ItemGroup>
<Using Include="Xunit" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
using Platform.Delegates;
using Platform.Data;
using Platform.Data.Doublets;
using Platform.Protocols.Lino;
using LinoLink = Platform.Protocols.Lino.Link<string>;
using Link.Foundation.Links.Notation;
using LinoLink = Link.Foundation.Links.Notation.Link<string>;
using DoubletLink = Platform.Data.Doublets.Link<uint>;

namespace Foundation.Data.Doublets.Cli
Expand Down Expand Up @@ -75,7 +75,7 @@ public static void ProcessQuery(INamedTypesLinks<uint> links, Options options)
if (restrictionLink.Values?.Count == 0 && (substitutionLink.Values?.Count ?? 0) > 0)
{
TraceIfEnabled(options, "[ProcessQuery] No restriction, but substitution is non-empty => creation scenario.");

// VALIDATION: Validate that all references in creation scenario are valid
try
{
Expand All @@ -87,7 +87,7 @@ public static void ProcessQuery(INamedTypesLinks<uint> links, Options options)
TraceIfEnabled(options, $"[ProcessQuery] Creation validation failed: {ex.Message}");
throw;
}

foreach (var linkToCreate in substitutionLink.Values ?? new List<LinoLink>())
{
var createdId = EnsureNestedLinkCreatedRecursively(links, linkToCreate, options);
Expand Down
4 changes: 2 additions & 2 deletions csharp/Foundation.Data.Doublets.Cli/BasicQueryProcessor.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using Platform.Data.Doublets;
using Platform.Protocols.Lino;
using Link.Foundation.Links.Notation;

using LinoLink = Platform.Protocols.Lino.Link<string>;
using LinoLink = Link.Foundation.Links.Notation.Link<string>;
using DoubletLink = Platform.Data.Doublets.Link<uint>;

namespace Foundation.Data.Doublets.Cli
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
<PackageReference Include="Platform.Data" Version="0.16.1" />
<PackageReference Include="Platform.Data.Doublets" Version="0.18.1" />
<PackageReference Include="Platform.Data.Doublets.Sequences" Version="0.6.5" />
<PackageReference Include="Platform.Protocols.Lino" Version="0.4.5" />
<PackageReference Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
<PackageReference Include="Link.Foundation.Links.Notation" Version="0.13.0" />
<PackageReference Include="System.CommandLine" Version="2.0.7" />
</ItemGroup>

<ItemGroup>
Expand Down
4 changes: 2 additions & 2 deletions csharp/Foundation.Data.Doublets.Cli/MixedQueryProcessor.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using Platform.Data.Doublets;
using Platform.Protocols.Lino;
using Link.Foundation.Links.Notation;

using LinoLink = Platform.Protocols.Lino.Link<string>;
using LinoLink = Link.Foundation.Links.Notation.Link<string>;
using DoubletLink = Platform.Data.Doublets.Link<uint>;
using Platform.Data;
using Platform.Delegates;
Expand Down
168 changes: 74 additions & 94 deletions csharp/Foundation.Data.Doublets.Cli/Program.cs
Original file line number Diff line number Diff line change
@@ -1,113 +1,96 @@
using System.CommandLine;
using System.CommandLine.Invocation;
using Foundation.Data.Doublets.Cli;
using Platform.Data;
using Platform.Data.Doublets;
using Platform.Protocols.Lino;

using static Foundation.Data.Doublets.Cli.ChangesSimplifier;
using DoubletLink = Platform.Data.Doublets.Link<uint>;
using QueryProcessor = Foundation.Data.Doublets.Cli.AdvancedMixedQueryProcessor;

const string defaultDatabaseFilename = "db.links";

var dbOption = new Option<string>(
name: "--db",
description: "Path to the links database file",
getDefaultValue: () => defaultDatabaseFilename
);
dbOption.AddAlias("--data-source");
dbOption.AddAlias("--data");
dbOption.AddAlias("-d");

var queryOption = new Option<string>(
name: "--query",
description: "LiNo query for CRUD operation"
);
queryOption.AddAlias("--apply");
queryOption.AddAlias("--do");
queryOption.AddAlias("-q");
var dbOption = new Option<string>("--db", "--data-source", "--data", "-d")
{
Description = "Path to the links database file",
DefaultValueFactory = _ => defaultDatabaseFilename
};

var queryArgument = new Argument<string>(
name: "query",
description: "LiNo query for CRUD operation"
);
queryArgument.Arity = ArgumentArity.ZeroOrOne;
var queryOption = new Option<string?>("--query", "--apply", "--do", "-q")
{
Description = "LiNo query for CRUD operation"
};

var traceOption = new Option<bool>(
name: "--trace",
description: "Enable trace (verbose output)",
getDefaultValue: () => false
);
traceOption.AddAlias("-t");
var queryArgument = new Argument<string?>("query")
{
Description = "LiNo query for CRUD operation",
Arity = ArgumentArity.ZeroOrOne
};

var autoCreateMissingReferencesOption = new Option<bool>(
name: "--auto-create-missing-references",
description: "Create missing numeric and named references as self-referential point links",
getDefaultValue: () => false
);
var traceOption = new Option<bool>("--trace", "-t")
{
Description = "Enable trace (verbose output)",
DefaultValueFactory = _ => false
};

var structureOption = new Option<uint?>(
name: "--structure",
description: "ID of the link to format its structure"
);
structureOption.AddAlias("-s");
var autoCreateMissingReferencesOption = new Option<bool>("--auto-create-missing-references")
{
Description = "Create missing numeric and named references as self-referential point links",
DefaultValueFactory = _ => false
};

var beforeOption = new Option<bool>(
name: "--before",
description: "Print the state of the database before applying changes",
getDefaultValue: () => false
);
beforeOption.AddAlias("-b");
var structureOption = new Option<uint?>("--structure", "-s")
{
Description = "ID of the link to format its structure"
};

var changesOption = new Option<bool>(
name: "--changes",
description: "Print the changes applied by the query",
getDefaultValue: () => false
);
changesOption.AddAlias("-c");
var beforeOption = new Option<bool>("--before", "-b")
{
Description = "Print the state of the database before applying changes",
DefaultValueFactory = _ => false
};

var afterOption = new Option<bool>(
name: "--after",
description: "Print the state of the database after applying changes",
getDefaultValue: () => false
);
afterOption.AddAlias("--links");
afterOption.AddAlias("-a");
var changesOption = new Option<bool>("--changes", "-c")
{
Description = "Print the changes applied by the query",
DefaultValueFactory = _ => false
};

var outputOption = new Option<string?>(
name: "--out",
description: "Path to write the complete database as a LiNo file"
);
outputOption.AddAlias("--lino-output");
var afterOption = new Option<bool>("--after", "--links", "-a")
{
Description = "Print the state of the database after applying changes",
DefaultValueFactory = _ => false
};

var rootCommand = new RootCommand("LiNo CLI Tool for managing links data store")
var outputOption = new Option<string?>("--out", "--lino-output")
{
dbOption,
queryOption,
queryArgument,
traceOption,
autoCreateMissingReferencesOption,
structureOption,
beforeOption,
changesOption,
afterOption,
outputOption
Description = "Path to write the complete database as a LiNo file"
};

rootCommand.SetHandler(
(InvocationContext context) =>
var rootCommand = new RootCommand("LiNo CLI Tool for managing links data store");
rootCommand.Options.Add(dbOption);
rootCommand.Options.Add(queryOption);
rootCommand.Arguments.Add(queryArgument);
rootCommand.Options.Add(traceOption);
rootCommand.Options.Add(autoCreateMissingReferencesOption);
rootCommand.Options.Add(structureOption);
rootCommand.Options.Add(beforeOption);
rootCommand.Options.Add(changesOption);
rootCommand.Options.Add(afterOption);
rootCommand.Options.Add(outputOption);

rootCommand.SetAction(
parseResult =>
{
var db = context.ParseResult.GetValueForOption(dbOption)!;
var queryOptionValue = context.ParseResult.GetValueForOption(queryOption) ?? "";
var queryArgumentValue = context.ParseResult.GetValueForArgument(queryArgument) ?? "";
var trace = context.ParseResult.GetValueForOption(traceOption);
var autoCreateMissingReferences = context.ParseResult.GetValueForOption(autoCreateMissingReferencesOption);
var structure = context.ParseResult.GetValueForOption(structureOption);
var before = context.ParseResult.GetValueForOption(beforeOption);
var changes = context.ParseResult.GetValueForOption(changesOption);
var after = context.ParseResult.GetValueForOption(afterOption);
var outputPath = context.ParseResult.GetValueForOption(outputOption);
var db = parseResult.GetValue(dbOption)!;
var queryOptionValue = parseResult.GetValue(queryOption) ?? "";
var queryArgumentValue = parseResult.GetValue(queryArgument) ?? "";
var trace = parseResult.GetValue(traceOption);
var autoCreateMissingReferences = parseResult.GetValue(autoCreateMissingReferencesOption);
var structure = parseResult.GetValue(structureOption);
var before = parseResult.GetValue(beforeOption);
var changes = parseResult.GetValue(changesOption);
var after = parseResult.GetValue(afterOption);
var outputPath = parseResult.GetValue(outputOption);

var decoratedLinks = new NamedTypesDecorator<uint>(db, trace);

Expand All @@ -122,12 +105,10 @@
catch (Exception ex)
{
Console.Error.WriteLine($"Error formatting structure for link ID {linkId}: {ex.Message}");
context.ExitCode = 1;
return;
return 1;
}

TryWriteLinoOutput(decoratedLinks, outputPath, context);
return;
return TryWriteLinoOutput(decoratedLinks, outputPath) ? 0 : 1;
}

if (before)
Expand Down Expand Up @@ -187,11 +168,11 @@
PrintAllLinks(decoratedLinks);
}

TryWriteLinoOutput(decoratedLinks, outputPath, context);
return TryWriteLinoOutput(decoratedLinks, outputPath) ? 0 : 1;
}
);

await rootCommand.InvokeAsync(args);
return rootCommand.Parse(args).Invoke();

static void PrintAllLinks(INamedTypesLinks<uint> links)
{
Expand All @@ -203,7 +184,7 @@ static void PrintChange(INamedTypesLinks<uint> links, DoubletLink linkBefore, Do
Console.WriteLine(LinoDatabaseOutput.FormatChange(links, linkBefore, linkAfter));
}

static bool TryWriteLinoOutput(INamedTypesLinks<uint> links, string? outputPath, InvocationContext context)
static bool TryWriteLinoOutput(INamedTypesLinks<uint> links, string? outputPath)
{
if (string.IsNullOrWhiteSpace(outputPath))
{
Expand All @@ -218,7 +199,6 @@ static bool TryWriteLinoOutput(INamedTypesLinks<uint> links, string? outputPath,
catch (Exception ex) when (ex is IOException || ex is UnauthorizedAccessException || ex is ArgumentException || ex is NotSupportedException)
{
Console.Error.WriteLine($"Error writing LiNo output file '{outputPath}': {ex.Message}");
context.ExitCode = 1;
return false;
}
}
Loading
Loading