From b0eee07d5e2a01f960f0661d606109010395aad4 Mon Sep 17 00:00:00 2001 From: Daniel Siegl <41949368+danielsiegl@users.noreply.github.com> Date: Thu, 13 Feb 2025 12:18:17 +0100 Subject: [PATCH] [#68] Integrate Model Orphans Reporting (#69) * [#68] Integrate Model Orphans Reporting --- .github/workflows/TestModelCheck.yml | 2 +- .github/workflows/release.yml | 7 ++ .gitignore | 3 + .obsidian/app.json | 1 + README.md | 21 ++++++ .../Checks/Checks.cs | 64 +++++++++++++++++-- .../Checks/Issue.cs | 2 + .../Checks/Issues.cs | 2 - .../CommandLineOptions/ModelCheckOptions.cs | 3 + .../Program.cs | 47 +++++++++----- .../Properties/launchSettings.json | 6 +- 11 files changed, 132 insertions(+), 26 deletions(-) create mode 100644 .obsidian/app.json diff --git a/.github/workflows/TestModelCheck.yml b/.github/workflows/TestModelCheck.yml index 44a2071..306a5fe 100644 --- a/.github/workflows/TestModelCheck.yml +++ b/.github/workflows/TestModelCheck.yml @@ -49,7 +49,7 @@ jobs: ./LemonTree.Pipeline.Tools.ModelCheck --model "${{inputs.model-path}}" --tablesize --out "./output.md" } elseif ('${{runner.os}}' -eq 'Windows') { - ./LemonTree.Pipeline.Tools.ModelCheck.exe --model "${{inputs.model-path}}" --tablesize --out "./output.md" + ./LemonTree.Pipeline.Tools.ModelCheck.exe --model "${{inputs.model-path}}" --tablesize --orphans --out "./output.md" } else { Write-Output "${{runner.os}} is not supported" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8363abb..39c7171 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -4,6 +4,13 @@ on: release: types: [created] +# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages +permissions: + contents: read + pages: write + id-token: write + deployments: write + jobs: prepareVersion: runs-on: windows-latest diff --git a/.gitignore b/.gitignore index ac6fc33..2b53aa1 100644 --- a/.gitignore +++ b/.gitignore @@ -354,3 +354,6 @@ src/Models/GPUCache/data_2 src/Models/GPUCache/data_3 src/Models/GPUCache/index *.ldb +/.obsidian/appearance.json +/.obsidian/core-plugins.json +/.obsidian/workspace.json diff --git a/.obsidian/app.json b/.obsidian/app.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/.obsidian/app.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/README.md b/README.md index 9d66e05..6cf655f 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,27 @@ https://nexus.lieberlieber.com/#browse/browse:lemontree-pipeline-tools Used to check Models for LemonTree Readiness. https://nexus.lieberlieber.com/repository/lemontree-pipeline-tools/LemonTree.Pipeline.Tools.ModelCheck.exe +### Commandline Reference + +``` + --Out File to output .md e.g.: 'out.md' + + --NoCompact If set the Checks that compact the Model are not run! + + --FailOnErrors If set the Exitcode will be 2 if there is at least on Check of Status Error! + + --FailOnWarnings If set the Exitcode will be 1 if there is at least on Check of Status Warning! + + --TableSize If set the size of the tables in the database will be reported! + + --Orphans If set Model Orphans will be reported! + + --Model Required. The 'Model' used for the operation. + + --help Display this help screen. + + --version Display version information. +``` ### Powershell Example: ``` diff --git a/src/LemonTree.Pipeline.Tools.ModelCheck/Checks/Checks.cs b/src/LemonTree.Pipeline.Tools.ModelCheck/Checks/Checks.cs index 15ab977..e8f110f 100644 --- a/src/LemonTree.Pipeline.Tools.ModelCheck/Checks/Checks.cs +++ b/src/LemonTree.Pipeline.Tools.ModelCheck/Checks/Checks.cs @@ -410,10 +410,10 @@ select count(t_object.Object_Type) as ['Count'], t_object.Object_Type as ['Measu result.Level = IssueLevel.Information; result.Title = "Project Statistics"; + result.Detail = "Executed Project Statistics on Model"; - - result.Detail = ToMD(resultTable.DefaultView.ToTable(), header: true); + result.Markdown = ToMD(resultTable.DefaultView.ToTable(), header: true); #endregion @@ -431,11 +431,8 @@ internal static Issue CheckTableSize(string model) //resultTable.DefaultView.Sort = "table_size"; resultTable.Columns[1].ColumnName = "table_size (bytes)"; - Console.WriteLine(ToMD(resultTable, header: true)); - #endregion - #region process result table and calculate Issue number @@ -447,10 +444,65 @@ internal static Issue CheckTableSize(string model) result.Level = IssueLevel.Information; result.Title = "Table Statistics (all >32)"; + result.Detail = $"Found {resultTable.Rows.Count} Tables bigger 32"; + + + result.Markdown = ToMD(resultTable.DefaultView.ToTable(), header: true); + + + #endregion + + return result; + } + + internal static Issue CheckModelOrphans(string model) + { + #region get result table + + const string statisticSql = @" + SELECT ea_guid AS CLASSGUID, Object_Type AS CLASSTYPE, t_object.* + FROM t_object + WHERE t_object.Object_Type <> 'Package' + AND t_object.Object_ID NOT IN (SELECT t_diagramobjects.Object_ID FROM t_diagramobjects) + AND t_object.Object_ID NOT IN (SELECT t_object.Classifier FROM t_object WHERE t_object.Classifier <> 0) + AND t_object.Object_ID NOT IN (SELECT a.Object_ID FROM t_object AS a JOIN t_object AS b ON b.PDATA1 = a.ea_guid) + AND t_object.Object_ID NOT IN (SELECT CAST(t_attribute.Classifier AS INTEGER) FROM t_attribute WHERE t_attribute.Classifier <> '0' AND t_attribute.Classifier <> '') + AND t_object.Object_ID NOT IN (SELECT CAST(t_operation.Classifier AS INTEGER) FROM t_operation WHERE t_operation.Classifier <> '0' AND t_operation.Classifier <> '') + AND t_object.Object_ID NOT IN (SELECT CAST(t_operationparams.Classifier AS INTEGER) FROM t_operationparams WHERE t_operationparams.Classifier <> '0' AND t_operationparams.Classifier <> '') + AND t_object.Object_ID NOT IN (SELECT t_connector.Start_Object_ID FROM t_connector) + AND t_object.Object_ID NOT IN (SELECT t_connector.End_Object_ID FROM t_connector) + AND t_object.Object_ID NOT IN (SELECT t_object.ParentID FROM t_object) + AND t_object.Object_ID NOT IN (SELECT t_object.Object_ID FROM t_xref JOIN t_object ON t_xref.Description LIKE '%' || t_object.ea_guid || '%' WHERE t_xref.Name = 'MOFProps') + AND t_object.ea_guid NOT IN (SELECT t_operation.Behaviour FROM t_operation WHERE t_operation.Behaviour <> '') + AND t_object.Object_ID NOT IN (SELECT CAST(t_connector.PDATA1 AS INTEGER) FROM t_connector WHERE t_connector.Connector_Type = 'Association' AND t_connector.SubType = 'Class'); + "; + + var resultTable = ModelAccess.RunSql(statisticSql); + #endregion + + #region process result table and calculate Issue number - result.Detail = ToMD(resultTable.DefaultView.ToTable(), header: true); + #endregion + + #region set Issue Level + + Issue result = new Issue(); + + result.Level = IssueLevel.Information; + result.Title = "Model Orphans Statistics"; + + + if (resultTable.Rows.Count > 0) + { + result.Markdown = ToMD(resultTable.DefaultView.ToTable(), header: true); + result.Detail = $"Found {resultTable.Rows.Count} Orphans in Model"; + } + else + { + result.Detail = "No Orphans found in Model!"; + } #endregion diff --git a/src/LemonTree.Pipeline.Tools.ModelCheck/Checks/Issue.cs b/src/LemonTree.Pipeline.Tools.ModelCheck/Checks/Issue.cs index 96d2867..d1b58fe 100644 --- a/src/LemonTree.Pipeline.Tools.ModelCheck/Checks/Issue.cs +++ b/src/LemonTree.Pipeline.Tools.ModelCheck/Checks/Issue.cs @@ -6,6 +6,8 @@ internal class Issue internal string Detail { get; set; } internal string Title { get; set; } + internal string Markdown { get; set; } + internal string Symbol { get diff --git a/src/LemonTree.Pipeline.Tools.ModelCheck/Checks/Issues.cs b/src/LemonTree.Pipeline.Tools.ModelCheck/Checks/Issues.cs index 92cde8a..ccfaeef 100644 --- a/src/LemonTree.Pipeline.Tools.ModelCheck/Checks/Issues.cs +++ b/src/LemonTree.Pipeline.Tools.ModelCheck/Checks/Issues.cs @@ -17,8 +17,6 @@ internal string ToMd() var mySortedList = this.OrderBy(x => x.Level); foreach (Issue issue in mySortedList) { - - sb.AppendLine($"|{issue.Symbol}|{issue.Level}|{issue.Title}|{issue.Detail}|"); } return sb.ToString(); diff --git a/src/LemonTree.Pipeline.Tools.ModelCheck/CommandLineOptions/ModelCheckOptions.cs b/src/LemonTree.Pipeline.Tools.ModelCheck/CommandLineOptions/ModelCheckOptions.cs index bef3f14..c6ff1d7 100644 --- a/src/LemonTree.Pipeline.Tools.ModelCheck/CommandLineOptions/ModelCheckOptions.cs +++ b/src/LemonTree.Pipeline.Tools.ModelCheck/CommandLineOptions/ModelCheckOptions.cs @@ -19,5 +19,8 @@ internal class ModelCheckOptions:BaseOptions [Option("TableSize", Required = false, HelpText = "If set the size of the tables in the database will be reported!")] public bool TableSize { get; set; } + + [Option("Orphans", Required = false, HelpText = "If set Model Orphans will be reported!")] + public bool Orphans { get; set; } } } diff --git a/src/LemonTree.Pipeline.Tools.ModelCheck/Program.cs b/src/LemonTree.Pipeline.Tools.ModelCheck/Program.cs index 47aea6a..8f65bda 100644 --- a/src/LemonTree.Pipeline.Tools.ModelCheck/Program.cs +++ b/src/LemonTree.Pipeline.Tools.ModelCheck/Program.cs @@ -69,22 +69,14 @@ private static int RunModelCheck(ModelCheckOptions opts) issues.AddIfNotNull(Checks.Checks.CheckStrippedCompact(opts.Model)); } - - // issues.WriteOutPut(Checks.Checks.CheckProjectStatitics(opts.Model)); - - - Console.WriteLine(issues.ToString()); - - StringBuilder sb = new StringBuilder(); - sb.AppendLine(issues.ToMd()); - sb.AppendLine("# Project Statistics"); - sb.AppendLine(Checks.Checks.CheckProjectStatitics(opts.Model).Detail); - + Issue resultTableSize = null; if (opts.TableSize == true) { if (ModelAccess.IsSqlLite()) { - sb.AppendLine(Checks.Checks.CheckTableSize(opts.Model).Detail); + resultTableSize = Checks.Checks.CheckTableSize(opts.Model); + + issues.AddIfNotNull(resultTableSize); } else { @@ -92,16 +84,39 @@ private static int RunModelCheck(ModelCheckOptions opts) } } - + Issue resultOrphans = null; + if (opts.Orphans == true) + { + if (ModelAccess.IsSqlLite()) + { + resultOrphans = Checks.Checks.CheckModelOrphans(opts.Model); + issues.AddIfNotNull(resultOrphans); + } + else + { + Console.WriteLine("Orphans reporting only supported for SqlLite!"); + } + } + Console.WriteLine(issues.ToString()); + StringBuilder sb = new StringBuilder(); + sb.AppendLine(issues.ToMd()); + sb.AppendLine("# Project Statistics"); + sb.AppendLine(Checks.Checks.CheckProjectStatitics(opts.Model).Markdown); + if (resultTableSize != null) + { + sb.AppendLine(resultTableSize.Markdown); + } + if (resultOrphans != null) + { + sb.AppendLine(resultOrphans.Markdown); + } if (opts.Out != null) { - File.WriteAllText(opts.Out, sb.ToString()); + File.WriteAllText(opts.Out, sb.ToString()); } - - if (opts.FailOnErrors == true) { if (issues.HasErrors()) diff --git a/src/LemonTree.Pipeline.Tools.ModelCheck/Properties/launchSettings.json b/src/LemonTree.Pipeline.Tools.ModelCheck/Properties/launchSettings.json index df2d139..789418f 100644 --- a/src/LemonTree.Pipeline.Tools.ModelCheck/Properties/launchSettings.json +++ b/src/LemonTree.Pipeline.Tools.ModelCheck/Properties/launchSettings.json @@ -2,7 +2,11 @@ "profiles": { "LemonTree.Pipeline.Tools.ModelCheck": { "commandName": "Project", - "commandLineArgs": "--model models\\model.qeax --tablesize" + "commandLineArgs": "--model models\\model.qeax --tablesize --orphans" + }, + "ExampleModel": { + "commandName": "Project", + "commandLineArgs": "--model \"C:\\repos\\SixthForth\\lemontree_demo\\EAExample.qeax\" --tablesize --orphans" } } } \ No newline at end of file