From 3d8427b547824fa2debae231cbb7c76e8c5584f7 Mon Sep 17 00:00:00 2001 From: Jeongsoo Lee Date: Wed, 11 Oct 2023 10:02:16 -0700 Subject: [PATCH 1/8] Sketch out structure for validating syntax and target `qlt pack validate syntax`; `qlt pack validate version` --- .../CodeQLToolkit.Features.Pack.csproj | 5 ++ .../Commands/PackCommandFeature.cs | 63 ----------------- .../HelloJeongsooCommandTarget.cs | 5 +- .../Validate/Targets/ValidateSyntaxTarget.cs | 16 +++++ .../Validate/Targets/ValidateVersionTarget.cs | 21 ++++++ .../Commands/Validate/ValidateFeature.cs | 70 +++++++++++++++++++ .../PackFeatureMain.cs | 7 +- 7 files changed, 120 insertions(+), 67 deletions(-) delete mode 100644 src/CodeQLToolkit.Features.Pack/Commands/PackCommandFeature.cs rename src/CodeQLToolkit.Features.Pack/Commands/{Targets => Targets.old}/HelloJeongsooCommandTarget.cs (90%) create mode 100644 src/CodeQLToolkit.Features.Pack/Commands/Validate/Targets/ValidateSyntaxTarget.cs create mode 100644 src/CodeQLToolkit.Features.Pack/Commands/Validate/Targets/ValidateVersionTarget.cs create mode 100644 src/CodeQLToolkit.Features.Pack/Commands/Validate/ValidateFeature.cs diff --git a/src/CodeQLToolkit.Features.Pack/CodeQLToolkit.Features.Pack.csproj b/src/CodeQLToolkit.Features.Pack/CodeQLToolkit.Features.Pack.csproj index 0fdbb7f..8afb4a9 100644 --- a/src/CodeQLToolkit.Features.Pack/CodeQLToolkit.Features.Pack.csproj +++ b/src/CodeQLToolkit.Features.Pack/CodeQLToolkit.Features.Pack.csproj @@ -15,4 +15,9 @@ + + + + + diff --git a/src/CodeQLToolkit.Features.Pack/Commands/PackCommandFeature.cs b/src/CodeQLToolkit.Features.Pack/Commands/PackCommandFeature.cs deleted file mode 100644 index d01968b..0000000 --- a/src/CodeQLToolkit.Features.Pack/Commands/PackCommandFeature.cs +++ /dev/null @@ -1,63 +0,0 @@ -using CodeQLToolkit.Features.Pack.Commands.Targets; -using System; -using System.Collections.Generic; -using System.CommandLine; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace CodeQLToolkit.Features.Pack.Commands -{ - public class PackCommandFeature : FeatureBase, IToolkitCommandFeature - { - public void Register(Command parentCommand) - { - Log.G().LogInformation("Registering command submodule."); - - var runCommand = new Command("run", "Functions pertaining to running pack-related commands."); - parentCommand.Add(runCommand); - - // a command that installs query packs - var sayHello = new Command("hello-jeongsoo", "Says hello!"); - var howManyTimesHello = new Option("--times", "how many times to say it") { IsRequired = true }; - sayHello.Add(howManyTimesHello); - - var sayGoodbye = new Command("goodbye-jeongsoo", "Says goodbye!"); - - var howManyTimes = new Option("--times", "how many times to say it") { IsRequired = true }; - sayGoodbye.Add(howManyTimes); - - - runCommand.Add(sayHello); - runCommand.Add(sayGoodbye); - - sayHello.SetHandler((basePath, times) => { - - new HelloJeongsooCommandTarget() { - Base = basePath, - Times = times - - }.Run(); - - }, Globals.BasePathOption, howManyTimesHello); - - sayGoodbye.SetHandler((basePath, times) => { - - Console.WriteLine($"Saying goodbye {times} number of times"); - - for (int i = 0; i < times; i++) - { - Console.WriteLine("Goodbye!"); - } - - - }, Globals.BasePathOption, howManyTimes); - - } - - public int Run() - { - throw new NotImplementedException(); - } - } -} diff --git a/src/CodeQLToolkit.Features.Pack/Commands/Targets/HelloJeongsooCommandTarget.cs b/src/CodeQLToolkit.Features.Pack/Commands/Targets.old/HelloJeongsooCommandTarget.cs similarity index 90% rename from src/CodeQLToolkit.Features.Pack/Commands/Targets/HelloJeongsooCommandTarget.cs rename to src/CodeQLToolkit.Features.Pack/Commands/Targets.old/HelloJeongsooCommandTarget.cs index 33b4420..d00c479 100644 --- a/src/CodeQLToolkit.Features.Pack/Commands/Targets/HelloJeongsooCommandTarget.cs +++ b/src/CodeQLToolkit.Features.Pack/Commands/Targets.old/HelloJeongsooCommandTarget.cs @@ -4,6 +4,8 @@ using System.Linq; using System.Text; using System.Threading.Tasks; +using YamlDotNet.Serialization; +using YamlDotNet.Serialization.NamingConventions; namespace CodeQLToolkit.Features.Pack.Commands.Targets { @@ -15,7 +17,8 @@ public class HelloJeongsooCommandTarget : CommandTarget public override void Run() { - for(int i = 0; i < Times; i++) { + for (int i = 0; i < Times; i++) + { Console.WriteLine($"Hello! My Base Target is: {Base}"); } diff --git a/src/CodeQLToolkit.Features.Pack/Commands/Validate/Targets/ValidateSyntaxTarget.cs b/src/CodeQLToolkit.Features.Pack/Commands/Validate/Targets/ValidateSyntaxTarget.cs new file mode 100644 index 0000000..64b9c6f --- /dev/null +++ b/src/CodeQLToolkit.Features.Pack/Commands/Validate/Targets/ValidateSyntaxTarget.cs @@ -0,0 +1,16 @@ +using CodeQLToolkit.Shared.Logging; +using CodeQLToolkit.Shared.Utils; +using YamlDotNet.Serialization; + +namespace CodeQLToolkit.Features.Pack.Commands.Validate.Targets +{ + public class ValidateSyntaxTarget : CommandTarget + { + public string ExtFilePath { get; set; } + + public override void Run() + { + Console.WriteLine("Hello world!"); + } + } +} \ No newline at end of file diff --git a/src/CodeQLToolkit.Features.Pack/Commands/Validate/Targets/ValidateVersionTarget.cs b/src/CodeQLToolkit.Features.Pack/Commands/Validate/Targets/ValidateVersionTarget.cs new file mode 100644 index 0000000..7ffe534 --- /dev/null +++ b/src/CodeQLToolkit.Features.Pack/Commands/Validate/Targets/ValidateVersionTarget.cs @@ -0,0 +1,21 @@ +using CodeQLToolkit.Shared.Logging; +using CodeQLToolkit.Shared.Utils; +using YamlDotNet.Serialization; +using Semver; + +namespace CodeQLToolkit.Features.Pack.Commands.Validate.Targets +{ + public class ValidateVersionTarget : CommandTarget + { + public string[] QlpackYmlFiles { get; set; } + public override void Run() + { + Console.WriteLine("Hello world! I got: "); + foreach (string qlpackYmlFile in QlpackYmlFiles) + { + Console.WriteLine(qlpackYmlFile); + } + var range = SemVersionRange.Parse("^1.0.0"); + } + } +} diff --git a/src/CodeQLToolkit.Features.Pack/Commands/Validate/ValidateFeature.cs b/src/CodeQLToolkit.Features.Pack/Commands/Validate/ValidateFeature.cs new file mode 100644 index 0000000..fb958d3 --- /dev/null +++ b/src/CodeQLToolkit.Features.Pack/Commands/Validate/ValidateFeature.cs @@ -0,0 +1,70 @@ +using CodeQLToolkit.Shared.Logging; +using CodeQLToolkit.Shared.Utils; +using CodeQLToolkit.Shared.Feature; +using CodeQLToolkit.Features.Pack.Commands.Validate.Targets; +using System.CommandLine; +using System.IO; + +namespace CodeQLToolkit.Features.Pack.Commands.Validate +{ + public class ValidateFeature : FeatureBase, IToolkitCommandFeature + { + public void Register(Command parentCommand) + { + Log.G().LogInformation("Registering Validate submodule."); + var validateCommand = new Command("validate", "Checking correctness of various files"); + parentCommand.Add(validateCommand); + + var validateSyntaxCommand = new Command("syntax", "Check if the extensions designators are in correct syntax"); + var extFilePath = new Option("--ext", "path to the extensions' definition file in yml format") { IsRequired = true, Arity = ArgumentArity.ExactlyOne }; + validateSyntaxCommand.Add(extFilePath); + + var validateVersionCommand = new Command("version", "Check if the versions match up across the qlpack.yml files"); + var qlpackYmlFiles = new Option("--yml", "qlpack.yml files to check against") { IsRequired = true, Arity = ArgumentArity.OneOrMore, AllowMultipleArgumentsPerToken = true }; + validateVersionCommand.Add(qlpackYmlFiles); + + validateCommand.Add(validateSyntaxCommand); + validateCommand.Add(validateVersionCommand); + + validateSyntaxCommand.SetHandler((basePath, extFilePath) => + { + var fileExists = File.Exists(extFilePath); + var isYamlFile = Path.GetExtension(extFilePath) == ".yml" || Path.HasExtension(extFilePath); + if (!fileExists) + throw new ArgumentException($"{extFilePath} does not exist."); + if (!isYamlFile) + throw new ArgumentException($"{extFilePath} is not a yaml file."); + new ValidateSyntaxTarget() + { + Base = basePath, + ExtFilePath = extFilePath + }.Run(); + }, Globals.BasePathOption, extFilePath); + validateVersionCommand.SetHandler(() => { throw new NotImplementedException(); }); + + validateVersionCommand.SetHandler((basePath, qlpackYmlFiles) => + { + foreach (var qlpackYmlFile in qlpackYmlFiles) + { + var fileExists = File.Exists(qlpackYmlFile); + var isYamlFile = Path.GetExtension(qlpackYmlFile) == ".yml" || Path.HasExtension(qlpackYmlFile); + if (!fileExists) + throw new ArgumentException($"{qlpackYmlFile} does not exist."); + if (!isYamlFile) + throw new ArgumentException($"{qlpackYmlFile} is not a yaml file."); + } + new ValidateVersionTarget() + { + Base = basePath, + QlpackYmlFiles = qlpackYmlFiles + }.Run(); + }, Globals.BasePathOption, qlpackYmlFiles + ); + } + public int Run() + { + throw new NotImplementedException(); + } + } + +} diff --git a/src/CodeQLToolkit.Features.Pack/PackFeatureMain.cs b/src/CodeQLToolkit.Features.Pack/PackFeatureMain.cs index 9fa81ea..f0d1ad6 100644 --- a/src/CodeQLToolkit.Features.Pack/PackFeatureMain.cs +++ b/src/CodeQLToolkit.Features.Pack/PackFeatureMain.cs @@ -1,4 +1,5 @@ using CodeQLToolkit.Features.Pack.Commands; +using CodeQLToolkit.Features.Pack.Commands.Validate; using System; using System.Collections.Generic; using System.CommandLine; @@ -12,7 +13,7 @@ public class PackFeatureMain : IToolkitFeature { readonly static PackFeatureMain instance; - readonly PackCommandFeature commandFeature; + readonly ValidateFeature validateFeature; static PackFeatureMain() { @@ -21,7 +22,7 @@ static PackFeatureMain() private PackFeatureMain() { - commandFeature = new PackCommandFeature(); + validateFeature = new ValidateFeature(); } public static PackFeatureMain Instance { get { return instance; } } @@ -31,7 +32,7 @@ public void Register(Command parentCommand) parentCommand.Add(packCommand); Log.G().LogInformation("Registering scaffolding submodule."); - commandFeature.Register(packCommand); + validateFeature.Register(packCommand); } public int Run() From b819982b07acb10e9bd16cb9b6a7c9045cfc2414 Mon Sep 17 00:00:00 2001 From: Jeongsoo Lee Date: Wed, 11 Oct 2023 10:52:38 -0700 Subject: [PATCH 2/8] Debug deciding `isYamlFile` --- .../Commands/Validate/ValidateFeature.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/CodeQLToolkit.Features.Pack/Commands/Validate/ValidateFeature.cs b/src/CodeQLToolkit.Features.Pack/Commands/Validate/ValidateFeature.cs index fb958d3..48f983c 100644 --- a/src/CodeQLToolkit.Features.Pack/Commands/Validate/ValidateFeature.cs +++ b/src/CodeQLToolkit.Features.Pack/Commands/Validate/ValidateFeature.cs @@ -29,7 +29,7 @@ public void Register(Command parentCommand) validateSyntaxCommand.SetHandler((basePath, extFilePath) => { var fileExists = File.Exists(extFilePath); - var isYamlFile = Path.GetExtension(extFilePath) == ".yml" || Path.HasExtension(extFilePath); + var isYamlFile = Path.GetExtension(extFilePath) == ".yml" || Path.GetExtension(extFilePath) == ".yaml"; if (!fileExists) throw new ArgumentException($"{extFilePath} does not exist."); if (!isYamlFile) @@ -47,7 +47,7 @@ public void Register(Command parentCommand) foreach (var qlpackYmlFile in qlpackYmlFiles) { var fileExists = File.Exists(qlpackYmlFile); - var isYamlFile = Path.GetExtension(qlpackYmlFile) == ".yml" || Path.HasExtension(qlpackYmlFile); + var isYamlFile = Path.GetExtension(qlpackYmlFile) == ".yml" || Path.GetExtension(qlpackYmlFile) == ".yaml"; if (!fileExists) throw new ArgumentException($"{qlpackYmlFile} does not exist."); if (!isYamlFile) From 5bd180a6af568f0423804470b592087409990eab Mon Sep 17 00:00:00 2001 From: Jeongsoo Lee Date: Wed, 11 Oct 2023 11:15:44 -0700 Subject: [PATCH 3/8] Exit gracefully than throw an exception --- .../Commands/Validate/ValidateFeature.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/CodeQLToolkit.Features.Pack/Commands/Validate/ValidateFeature.cs b/src/CodeQLToolkit.Features.Pack/Commands/Validate/ValidateFeature.cs index 48f983c..2760765 100644 --- a/src/CodeQLToolkit.Features.Pack/Commands/Validate/ValidateFeature.cs +++ b/src/CodeQLToolkit.Features.Pack/Commands/Validate/ValidateFeature.cs @@ -31,9 +31,9 @@ public void Register(Command parentCommand) var fileExists = File.Exists(extFilePath); var isYamlFile = Path.GetExtension(extFilePath) == ".yml" || Path.GetExtension(extFilePath) == ".yaml"; if (!fileExists) - throw new ArgumentException($"{extFilePath} does not exist."); + DieWithError($"{extFilePath} does not exist."); if (!isYamlFile) - throw new ArgumentException($"{extFilePath} is not a yaml file."); + DieWithError($"{extFilePath} is not a yaml file."); new ValidateSyntaxTarget() { Base = basePath, @@ -49,9 +49,9 @@ public void Register(Command parentCommand) var fileExists = File.Exists(qlpackYmlFile); var isYamlFile = Path.GetExtension(qlpackYmlFile) == ".yml" || Path.GetExtension(qlpackYmlFile) == ".yaml"; if (!fileExists) - throw new ArgumentException($"{qlpackYmlFile} does not exist."); + DieWithError($"{qlpackYmlFile} does not exist."); if (!isYamlFile) - throw new ArgumentException($"{qlpackYmlFile} is not a yaml file."); + DieWithError($"{qlpackYmlFile} is not a yaml file."); } new ValidateVersionTarget() { From 5172c6801f12f6d7ce617bdb9a52a5f214464f41 Mon Sep 17 00:00:00 2001 From: Jeongsoo Lee Date: Wed, 11 Oct 2023 12:38:51 -0700 Subject: [PATCH 4/8] Remove outdated directory --- .../Targets.old/HelloJeongsooCommandTarget.cs | 48 ------------------- 1 file changed, 48 deletions(-) delete mode 100644 src/CodeQLToolkit.Features.Pack/Commands/Targets.old/HelloJeongsooCommandTarget.cs diff --git a/src/CodeQLToolkit.Features.Pack/Commands/Targets.old/HelloJeongsooCommandTarget.cs b/src/CodeQLToolkit.Features.Pack/Commands/Targets.old/HelloJeongsooCommandTarget.cs deleted file mode 100644 index d00c479..0000000 --- a/src/CodeQLToolkit.Features.Pack/Commands/Targets.old/HelloJeongsooCommandTarget.cs +++ /dev/null @@ -1,48 +0,0 @@ -using CodeQLToolkit.Shared.Utils; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using YamlDotNet.Serialization; -using YamlDotNet.Serialization.NamingConventions; - -namespace CodeQLToolkit.Features.Pack.Commands.Targets -{ - public class HelloJeongsooCommandTarget : CommandTarget - { - - public int Times { get; set; } - - - public override void Run() - { - for (int i = 0; i < Times; i++) - { - Console.WriteLine($"Hello! My Base Target is: {Base}"); - } - - - var c = new QLTConfig() - { - Base = Base - }; - - if (!File.Exists(c.CodeQLConfigFilePath)) - { - ProcessUtils.DieWithError($"Cannot read values from missing file {c.CodeQLConfigFilePath}"); - } - - var config = c.FromFile(); - - - Console.WriteLine($"---------current settings---------"); - Console.WriteLine($"CodeQL CLI Version: {config.CodeQLCLI}"); - Console.WriteLine($"CodeQL Standard Library Version: {config.CodeQLStandardLibrary}"); - Console.WriteLine($"CodeQL CLI Bundle Version: {config.CodeQLCLIBundle}"); - Console.WriteLine($"----------------------------------"); - Console.WriteLine("(hint: use `qlt codeql set` to modify these values.)"); - - } - } -} From 108297428c3df606c5ec4342e1014fcb5847764d Mon Sep 17 00:00:00 2001 From: Jeongsoo Lee Date: Wed, 11 Oct 2023 18:18:59 -0700 Subject: [PATCH 5/8] Add Yaml file schemas to serve as deserialization targets --- .../Targets/Schemas/ExtQlpackYmlSchema.cs | 31 +++++++++++++++++++ .../Validate/Targets/Schemas/IYmlSchema.cs | 6 ++++ .../Targets/Schemas/LibQlpackYmlSchema.cs | 28 +++++++++++++++++ .../Targets/Schemas/SrcQlpackYmlSchema.cs | 30 ++++++++++++++++++ .../Targets/Schemas/TestQlpackYmlSchema.cs | 24 ++++++++++++++ 5 files changed, 119 insertions(+) create mode 100644 src/CodeQLToolkit.Features.Pack/Commands/Validate/Targets/Schemas/ExtQlpackYmlSchema.cs create mode 100644 src/CodeQLToolkit.Features.Pack/Commands/Validate/Targets/Schemas/IYmlSchema.cs create mode 100644 src/CodeQLToolkit.Features.Pack/Commands/Validate/Targets/Schemas/LibQlpackYmlSchema.cs create mode 100644 src/CodeQLToolkit.Features.Pack/Commands/Validate/Targets/Schemas/SrcQlpackYmlSchema.cs create mode 100644 src/CodeQLToolkit.Features.Pack/Commands/Validate/Targets/Schemas/TestQlpackYmlSchema.cs diff --git a/src/CodeQLToolkit.Features.Pack/Commands/Validate/Targets/Schemas/ExtQlpackYmlSchema.cs b/src/CodeQLToolkit.Features.Pack/Commands/Validate/Targets/Schemas/ExtQlpackYmlSchema.cs new file mode 100644 index 0000000..6cdb3ad --- /dev/null +++ b/src/CodeQLToolkit.Features.Pack/Commands/Validate/Targets/Schemas/ExtQlpackYmlSchema.cs @@ -0,0 +1,31 @@ +namespace CodeQLToolkit.Features.Pack.Commands.Validate.Schemas +{ + public class ExtQlpackYmlFileSchema : IYmlSchema + { + public bool Library { get; set; } + public string Name { get; set; } + public string Version { get; set; } + public Dictionary ExtensionTargets { get; set; } + public List DataExtensions { get; set; } + + override public string ToString() + { + string ExtensionTargetsString = "\n"; + if (ExtensionTargets is not null) + foreach (KeyValuePair pair in ExtensionTargets) + ExtensionTargetsString += $"{pair.Key}: {pair.Value}\n"; + + string DataExtensionString = "\n"; + if (DataExtensions is not null) + foreach (string DataExtension in DataExtensions) + DataExtensionString += $"{DataExtension}, "; + + return $@"Ext qlpack.yml file: + Library: {Library}, + Name: {Name}, + Version: {Version}, + ExtensionTargets: {ExtensionTargetsString} + DataExtensions: {DataExtensionString}"; + } + } +} diff --git a/src/CodeQLToolkit.Features.Pack/Commands/Validate/Targets/Schemas/IYmlSchema.cs b/src/CodeQLToolkit.Features.Pack/Commands/Validate/Targets/Schemas/IYmlSchema.cs new file mode 100644 index 0000000..88ba606 --- /dev/null +++ b/src/CodeQLToolkit.Features.Pack/Commands/Validate/Targets/Schemas/IYmlSchema.cs @@ -0,0 +1,6 @@ +namespace CodeQLToolkit.Features.Pack.Commands.Validate.Schemas { + public interface IYmlSchema { + public string Name { get; set; } + public string Version { get; set; } + } +} \ No newline at end of file diff --git a/src/CodeQLToolkit.Features.Pack/Commands/Validate/Targets/Schemas/LibQlpackYmlSchema.cs b/src/CodeQLToolkit.Features.Pack/Commands/Validate/Targets/Schemas/LibQlpackYmlSchema.cs new file mode 100644 index 0000000..e668dee --- /dev/null +++ b/src/CodeQLToolkit.Features.Pack/Commands/Validate/Targets/Schemas/LibQlpackYmlSchema.cs @@ -0,0 +1,28 @@ +namespace CodeQLToolkit.Features.Pack.Commands.Validate.Schemas +{ + public class LibQlpackYmlFileSchema : IYmlSchema + { + public bool Library { get; set; } + public string Name { get; set; } + public string Version { get; set; } + public string Suites { get; set; } + public string Extractor { get; set; } + public Dictionary Dependencies { get; set; } + + override public string ToString() + { + string DependenciesString = "\n"; + if (Dependencies is not null) + foreach (KeyValuePair pair in Dependencies) + DependenciesString += $"{pair.Key}: {pair.Value}\n"; + + return $@"Test qlpack.yml file: + Library: {Library}, + Name: {Name}, + Version: {Version}, + Suites: {Suites}, + Extractor: {Extractor}, + Dependencies: {DependenciesString}"; + } + } +} diff --git a/src/CodeQLToolkit.Features.Pack/Commands/Validate/Targets/Schemas/SrcQlpackYmlSchema.cs b/src/CodeQLToolkit.Features.Pack/Commands/Validate/Targets/Schemas/SrcQlpackYmlSchema.cs new file mode 100644 index 0000000..91fbf2c --- /dev/null +++ b/src/CodeQLToolkit.Features.Pack/Commands/Validate/Targets/Schemas/SrcQlpackYmlSchema.cs @@ -0,0 +1,30 @@ +namespace CodeQLToolkit.Features.Pack.Commands.Validate.Schemas +{ + public class SrcQlpackYmlSchema : IYmlSchema + { + public bool Library { get; set; } + public string Name { get; set; } + public string Version { get; set; } + public string Suites { get; set; } + public string Extractor { get; set; } + public Dictionary Dependencies { get; set; } + public string DefaultSuiteFile { get; set; } + + public override string ToString() + { + string DependenciesString = "\n"; + if (Dependencies is not null) + foreach (KeyValuePair pair in Dependencies) + DependenciesString += $"{pair.Key}: {pair.Value}\n"; + + return $@"Test qlpack.yml file: + Library: {Library}, + Name: {Name}, + Version: {Version}, + Suites: {Suites}, + Extractor: {Extractor}, + Dependencies: {DependenciesString}, + DefaultSuiteFile: {DefaultSuiteFile}"; + } + } +} \ No newline at end of file diff --git a/src/CodeQLToolkit.Features.Pack/Commands/Validate/Targets/Schemas/TestQlpackYmlSchema.cs b/src/CodeQLToolkit.Features.Pack/Commands/Validate/Targets/Schemas/TestQlpackYmlSchema.cs new file mode 100644 index 0000000..35df92b --- /dev/null +++ b/src/CodeQLToolkit.Features.Pack/Commands/Validate/Targets/Schemas/TestQlpackYmlSchema.cs @@ -0,0 +1,24 @@ +namespace CodeQLToolkit.Features.Pack.Commands.Validate.Schemas +{ + public class TestQlpackYmlFileSchema : IYmlSchema + { + public string Name { get; set; } + public string Version { get; set; } + public string Extractor { get; set; } + public Dictionary Dependencies { get; set; } + + override public string ToString() + { + string DependenciesString = "\n"; + if (Dependencies is not null) + foreach (KeyValuePair pair in Dependencies) + DependenciesString += $"{pair.Key}: {pair.Value}\n"; + + return $@"Test qlpack.yml file: + Name: {Name}, + Version: {Version}, + Extractor: {Extractor}, + Dependencies: {DependenciesString}"; + } + } +} \ No newline at end of file From 382cfca085766c24ffe36bdb21f4a82f956ee284 Mon Sep 17 00:00:00 2001 From: Jeongsoo Lee Date: Thu, 12 Oct 2023 12:17:27 -0700 Subject: [PATCH 6/8] Debug `ToString` and exclude `DefaultSuiteFile` from `CamlCaseConvention` --- .../Validate/Targets/Schemas/LibQlpackYmlSchema.cs | 2 +- .../Validate/Targets/Schemas/SrcQlpackYmlSchema.cs | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/CodeQLToolkit.Features.Pack/Commands/Validate/Targets/Schemas/LibQlpackYmlSchema.cs b/src/CodeQLToolkit.Features.Pack/Commands/Validate/Targets/Schemas/LibQlpackYmlSchema.cs index e668dee..cf765fa 100644 --- a/src/CodeQLToolkit.Features.Pack/Commands/Validate/Targets/Schemas/LibQlpackYmlSchema.cs +++ b/src/CodeQLToolkit.Features.Pack/Commands/Validate/Targets/Schemas/LibQlpackYmlSchema.cs @@ -16,7 +16,7 @@ override public string ToString() foreach (KeyValuePair pair in Dependencies) DependenciesString += $"{pair.Key}: {pair.Value}\n"; - return $@"Test qlpack.yml file: + return $@"Lib qlpack.yml file: Library: {Library}, Name: {Name}, Version: {Version}, diff --git a/src/CodeQLToolkit.Features.Pack/Commands/Validate/Targets/Schemas/SrcQlpackYmlSchema.cs b/src/CodeQLToolkit.Features.Pack/Commands/Validate/Targets/Schemas/SrcQlpackYmlSchema.cs index 91fbf2c..aa1c4cc 100644 --- a/src/CodeQLToolkit.Features.Pack/Commands/Validate/Targets/Schemas/SrcQlpackYmlSchema.cs +++ b/src/CodeQLToolkit.Features.Pack/Commands/Validate/Targets/Schemas/SrcQlpackYmlSchema.cs @@ -1,3 +1,6 @@ +using YamlDotNet.Serialization; +using YamlDotNet.Serialization.NamingConventions; + namespace CodeQLToolkit.Features.Pack.Commands.Validate.Schemas { public class SrcQlpackYmlSchema : IYmlSchema @@ -8,6 +11,8 @@ public class SrcQlpackYmlSchema : IYmlSchema public string Suites { get; set; } public string Extractor { get; set; } public Dictionary Dependencies { get; set; } + + [YamlMember(Alias = "default-suite-file", ApplyNamingConventions = false)] public string DefaultSuiteFile { get; set; } public override string ToString() @@ -17,7 +22,7 @@ public override string ToString() foreach (KeyValuePair pair in Dependencies) DependenciesString += $"{pair.Key}: {pair.Value}\n"; - return $@"Test qlpack.yml file: + return $@"Src qlpack.yml file: Library: {Library}, Name: {Name}, Version: {Version}, From 121dbe11f280e523a3964a49673a99ba1165ec5a Mon Sep 17 00:00:00 2001 From: Jeongsoo Lee Date: Thu, 12 Oct 2023 12:25:22 -0700 Subject: [PATCH 7/8] Use CamlCaseNamingConvention by default with exception on default-suite-file --- .../Validate/Targets/ValidateVersionTarget.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/CodeQLToolkit.Features.Pack/Commands/Validate/Targets/ValidateVersionTarget.cs b/src/CodeQLToolkit.Features.Pack/Commands/Validate/Targets/ValidateVersionTarget.cs index 7ffe534..c3ecb79 100644 --- a/src/CodeQLToolkit.Features.Pack/Commands/Validate/Targets/ValidateVersionTarget.cs +++ b/src/CodeQLToolkit.Features.Pack/Commands/Validate/Targets/ValidateVersionTarget.cs @@ -1,13 +1,25 @@ using CodeQLToolkit.Shared.Logging; using CodeQLToolkit.Shared.Utils; using YamlDotNet.Serialization; +using YamlDotNet.Serialization.NamingConventions; using Semver; +using CodeQLToolkit.Features.Pack.Commands.Validate.Schemas; namespace CodeQLToolkit.Features.Pack.Commands.Validate.Targets { + public class YamlParseException : Exception + { + public string message { get; set; } + public YamlParseException(string failMessage) + { + message = failMessage; + } + } public class ValidateVersionTarget : CommandTarget { public string[] QlpackYmlFiles { get; set; } + private static Deserializer YamlDeserializer = (Deserializer)new DeserializerBuilder().WithNamingConvention(CamelCaseNamingConvention.Instance).Build(); + public override void Run() { Console.WriteLine("Hello world! I got: "); From 92eb92e92b126c56afd2ca1f8fff6bffa9c48e3b Mon Sep 17 00:00:00 2001 From: Jeongsoo Lee Date: Fri, 13 Oct 2023 10:18:30 -0700 Subject: [PATCH 8/8] Add utility methods to compare and find intersection on ranges --- .../Validate/Targets/ValidateVersionTarget.cs | 67 ++++++++++++++++++- 1 file changed, 65 insertions(+), 2 deletions(-) diff --git a/src/CodeQLToolkit.Features.Pack/Commands/Validate/Targets/ValidateVersionTarget.cs b/src/CodeQLToolkit.Features.Pack/Commands/Validate/Targets/ValidateVersionTarget.cs index c3ecb79..54a826b 100644 --- a/src/CodeQLToolkit.Features.Pack/Commands/Validate/Targets/ValidateVersionTarget.cs +++ b/src/CodeQLToolkit.Features.Pack/Commands/Validate/Targets/ValidateVersionTarget.cs @@ -4,6 +4,7 @@ using YamlDotNet.Serialization.NamingConventions; using Semver; using CodeQLToolkit.Features.Pack.Commands.Validate.Schemas; +using System.Diagnostics; namespace CodeQLToolkit.Features.Pack.Commands.Validate.Targets { @@ -24,10 +25,72 @@ public override void Run() { Console.WriteLine("Hello world! I got: "); foreach (string qlpackYmlFile in QlpackYmlFiles) + private static UnbrokenSemVersionRange FindUnbrokenSemverRangeOverlap( + UnbrokenSemVersionRange range1, + UnbrokenSemVersionRange range2 + ) + { + if (range1.End.ComparePrecedenceTo(range2.Start) == -1 || range2.End.ComparePrecedenceTo(range1.Start) == -1) { + return UnbrokenSemVersionRange.Empty; + } else { + var start = range1.Start.ComparePrecedenceTo(range2.Start) == -1 ? range2.Start : range1.Start; + var end = range1.End.ComparePrecedenceTo(range2.End) == -1 ? range1.End : range2.End; + return UnbrokenSemVersionRange.Inclusive(start, end); + } + } + + private static SemVersionRange FindSemverRangeOverlap( + SemVersionRange range1, + SemVersionRange range2 + ) + { + var acc = new List(); + foreach (UnbrokenSemVersionRange unbrokenRange1 in range1) + foreach (UnbrokenSemVersionRange unbrokenRange2 in range2) + acc.Add(FindUnbrokenSemverRangeOverlap(unbrokenRange1, unbrokenRange2)); + + return SemVersionRange.Create(acc); + } + + private static bool thereIsSemVersionRangeOverlap( + SemVersionRange range1, + SemVersionRange range2 + ) + { + var intersection = FindSemverRangeOverlap(range1, range2); + bool foundNonemptyUnbrokenSemVersionRange = false; + + foreach (UnbrokenSemVersionRange unbrokenRange in intersection) { - Console.WriteLine(qlpackYmlFile); + Console.WriteLine($"Inspecting [{unbrokenRange.Start}, {unbrokenRange.End})..."); + if (!unbrokenRange.Equals(UnbrokenSemVersionRange.Empty)) + foundNonemptyUnbrokenSemVersionRange = true; + break; } - var range = SemVersionRange.Parse("^1.0.0"); + + return foundNonemptyUnbrokenSemVersionRange; + } + + private static void testRangeOverlap() + { + var semver21 = SemVersionRange.Parse("1.2.1"); + var semver22 = SemVersionRange.Parse("^1.2.0"); + + Debug.Assert(thereIsSemVersionRangeOverlap(semver21, semver22)); + + var semver31 = SemVersionRange.Parse("^1.2.0"); + var semver32 = SemVersionRange.Parse("1.2.1"); + + Debug.Assert(thereIsSemVersionRangeOverlap(semver31, semver32)); + + var semver41 = UnbrokenSemVersionRange.AtLeast(SemVersion.Parse("1.2.0")); + var semver42 = UnbrokenSemVersionRange.Equals(SemVersion.Parse("1.2.1")); + + Console.WriteLine($"semver41: {semver41.Start}, {semver41.End}"); + Console.WriteLine($"semver42: {semver42.Start}, {semver42.End}"); + + var intersection = FindUnbrokenSemverRangeOverlap(semver41, semver42); + Console.WriteLine($"intersection: {intersection.Start}, {intersection.End}"); } } }