From 656d9522e0d2abf699503dd38f4f9ee15561e084 Mon Sep 17 00:00:00 2001 From: bogdan-damian-bgd <108331162+bogdan-damian-bgd@users.noreply.github.com> Date: Mon, 12 Dec 2022 14:56:04 +0100 Subject: [PATCH] Move SoftwareReport modules to global location (#6720) --- .../software-report/SoftwareReport.Base.ps1 | 370 ------------------ .../SoftwareReport.Generator.ps1 | 4 +- images/macos/templates/macOS-10.15.json | 5 + images/macos/templates/macOS-11.anka.pkr.hcl | 4 + images/macos/templates/macOS-11.json | 5 + images/macos/templates/macOS-12.anka.pkr.hcl | 4 + images/macos/templates/macOS-12.json | 5 + 7 files changed, 26 insertions(+), 371 deletions(-) delete mode 100644 images/macos/software-report/SoftwareReport.Base.ps1 diff --git a/images/macos/software-report/SoftwareReport.Base.ps1 b/images/macos/software-report/SoftwareReport.Base.ps1 deleted file mode 100644 index 35475ada9..000000000 --- a/images/macos/software-report/SoftwareReport.Base.ps1 +++ /dev/null @@ -1,370 +0,0 @@ -class SoftwareReport { - [HeaderNode] $Root - - SoftwareReport([String] $Title) { - $this.Root = [HeaderNode]::new($Title) - } - - SoftwareReport([HeaderNode] $Root) { - $this.Root = $Root - } - - [String] ToJson() { - return $this.Root.ToJsonObject() | ConvertTo-Json -Depth 10 - } - - static [SoftwareReport] FromJson($jsonString) { - $jsonObj = $jsonString | ConvertFrom-Json - $rootNode = [SoftwareReport]::ParseNodeFromObject($jsonObj) - return [SoftwareReport]::new($rootNode) - } - - [String] ToMarkdown() { - return $this.Root.ToMarkdown(1).Trim() - } - - # This method is Nodes factory that simplifies parsing different types of notes - # Every node has own logic of parsing and this method just invokes "FromJsonObject" of correct node type - static [BaseNode] ParseNodeFromObject($jsonObj) { - if ($jsonObj.NodeType -eq [HeaderNode].Name) { - return [HeaderNode]::FromJsonObject($jsonObj) - } elseif ($jsonObj.NodeType -eq [ToolNode].Name) { - return [ToolNode]::FromJsonObject($jsonObj) - } elseif ($jsonObj.NodeType -eq [ToolVersionsNode].Name) { - return [ToolVersionsNode]::FromJsonObject($jsonObj) - } elseif ($jsonObj.NodeType -eq [TableNode].Name) { - return [TableNode]::FromJsonObject($jsonObj) - } elseif ($jsonObj.NodeType -eq [NoteNode].Name) { - return [NoteNode]::FromJsonObject($jsonObj) - } - - throw "Unknown node type in ParseNodeFromObject '$($jsonObj.NodeType)'" - } -} - -# class BaseNode doesn't really have any business logic or functionality -# We just create it to unite all types of Nodes and differ them from "object" type -class BaseNode {} - -# It is a node type to describe headers: "# Node.js" -# Header has Title and children nodes (HeaderNode is the single node type who has children) -class HeaderNode: BaseNode { - [String] $Title - [System.Collections.ArrayList] $Children - - HeaderNode([String] $Title) { - $this.Title = $Title - $this.Children = @() - } - - [void] AddNode([BaseNode] $node) { - if ($node.GetType() -eq [TableNode]) { - $existingTableNodesCount = $this.Children.Where({ $_.GetType() -eq [TableNode] }).Count - if ($existingTableNodesCount -gt 0) { - throw "Having multiple TableNode on the same header level is not supported" - } - } - - $this.Children.Add($node) - } - - [void] AddNodes([Array] $nodes) { - $nodes | ForEach-Object { $this.AddNode($_) } - } - - [HeaderNode] AddHeaderNode([String] $Title) { - $node = [HeaderNode]::new($Title) - $this.AddNode($node) - return $node - } - - [void] AddToolNode([String] $ToolName, [String] $Version) { - $this.AddNode([ToolNode]::new($ToolName, $Version)) - } - - [void] AddToolVersionsNode([String] $ToolName, [Array] $Version) { - $this.AddNode([ToolVersionsNode]::new($ToolName, $Version)) - } - - [void] AddTableNode([Array] $Table) { - $this.AddNode([TableNode]::FromObjectsArray($Table)) - } - - [void] AddNoteNode([String] $Content) { - $this.AddNode([NoteNode]::new($Content)) - } - - [String] ToMarkdown($level) { - $sb = [System.Text.StringBuilder]::new() - $sb.AppendLine() - $sb.AppendLine("$("#" * $level) $($this.Title)") - $this.Children | ForEach-Object { - $sb.AppendLine($_.ToMarkdown($level + 1)) - } - - return $sb.ToString().TrimEnd() - } - - [PSCustomObject] ToJsonObject() { - return [PSCustomObject]@{ - NodeType = $this.GetType().Name - Title = $this.Title - Children = $this.Children | ForEach-Object { $_.ToJsonObject() } - } - } - - static [HeaderNode] FromJsonObject($jsonObj) { - $node = [HeaderNode]::new($jsonObj.Title) - $jsonObj.Children | Where-Object { $_ } | ForEach-Object { $node.AddNode([SoftwareReport]::ParseNodeFromObject($_)) } - return $node - } - - [Boolean] IsSimilarTo([BaseNode] $OtherNode) { - if ($OtherNode.GetType() -ne [HeaderNode]) { - return $false - } - - return $this.Title -eq $OtherNode.Title - } - - [Boolean] IsIdenticalTo([BaseNode] $OtherNode) { - return $this.IsSimilarTo($OtherNode) - } -} - -# It is a node type to describe the single tool "Bash 5.1.16(1)-release" -class ToolNode: BaseNode { - [String] $ToolName - [String] $Version - - ToolNode([String] $ToolName, [String] $Version) { - $this.ToolName = $ToolName - $this.Version = $Version - } - - [String] ToMarkdown($level) { - return "- $($this.ToolName) $($this.Version)" - } - - [String] ToString() { - return "$($this.ToolName) $($this.Version)" - } - - [PSCustomObject] ToJsonObject() { - return [PSCustomObject]@{ - NodeType = $this.GetType().Name - ToolName = $this.ToolName - Version = $this.Version - } - } - - static [BaseNode] FromJsonObject($jsonObj) { - return [ToolNode]::new($jsonObj.ToolName, $jsonObj.Version) - } - - [Boolean] IsSimilarTo([BaseNode] $OtherNode) { - if ($OtherNode.GetType() -ne [ToolNode]) { - return $false - } - - # Don't compare by Version in SimilarTo method - # It is necessary to treat changing of tool version as "ChangedNodes" rather than "RemovedNodes" + "AddedNodes" - return $this.ToolName -eq $OtherNode.ToolName - } - - [Boolean] IsIdenticalTo([BaseNode] $OtherNode) { - return $this.IsSimilarTo($OtherNode) -and $this.Version -eq $OtherNode.Version - } -} - -# It is a node type to describe the single tool "Toolcache Node.js 14.17.6 16.2.0 18.2.3" -class ToolVersionsNode: BaseNode { - [String] $ToolName - [Array] $Versions - - ToolVersionsNode([String] $ToolName, [Array] $Versions) { - $this.ToolName = $ToolName - $this.Versions = $Versions - } - - [String] ToMarkdown($level) { - $sb = [System.Text.StringBuilder]::new() - $sb.AppendLine() - $sb.AppendLine("$("#" * $level) $($this.ToolName)") - $this.Versions | ForEach-Object { - $sb.AppendLine("- $_") - } - - return $sb.ToString().TrimEnd() - } - - [String] ToString() { - return "$($this.ToolName) $($this.Versions -join ', ')" - } - - [PSCustomObject] ToJsonObject() { - return [PSCustomObject]@{ - NodeType = $this.GetType().Name - ToolName = $this.ToolName - Versions = $this.Versions - } - } - - static [ToolVersionsNode] FromJsonObject($jsonObj) { - return [ToolVersionsNode]::new($jsonObj.ToolName, $jsonObj.Versions) - } - - [Boolean] IsSimilarTo([BaseNode] $OtherNode) { - if ($OtherNode.GetType() -ne [ToolVersionsNode]) { - return $false - } - - return $this.ToolName -eq $OtherNode.ToolName - } - - [Boolean] IsIdenticalTo([BaseNode] $OtherNode) { - if (-not $this.IsSimilarTo($OtherNode)) { - return $false - } - - return ($this.Versions -join " ") -eq ($OtherNode.Versions -join " ") - } -} - -# It is a node type to describe tables -class TableNode: BaseNode { - # It is easier to store the table as rendered lines because we will simplify finding differences in rows later - [String] $Headers - [System.Collections.ArrayList] $Rows - - TableNode($Headers, $Rows) { - $this.Headers = $Headers - $this.Rows = $Rows - } - - static [TableNode] FromObjectsArray([Array] $Table) { - # take column names from the first row in table because all rows that should have the same columns - [String] $tableHeaders = [TableNode]::ArrayToTableRow($Table[0].PSObject.Properties.Name) - [System.Collections.ArrayList] $tableRows = @() - - $Table | ForEach-Object { - $tableRows.Add([TableNode]::ArrayToTableRow($_.PSObject.Properties.Value)) - } - - return [TableNode]::new($tableHeaders, $tableRows) - } - - [String] ToMarkdown($level) { - $maxColumnWidths = $this.Headers.Split("|") | ForEach-Object { $_.Length } - $columnsCount = $maxColumnWidths.Count - - $this.Rows | ForEach-Object { - $columnWidths = $_.Split("|") | ForEach-Object { $_.Length } - for ($colIndex = 0; $colIndex -lt $columnsCount; $colIndex++) { - $maxColumnWidths[$colIndex] = [Math]::Max($maxColumnWidths[$colIndex], $columnWidths[$colIndex]) - } - } - - $delimeterLine = [String]::Join("|", @("-") * $columnsCount) - - $sb = [System.Text.StringBuilder]::new() - @($this.Headers) + @($delimeterLine) + $this.Rows | ForEach-Object { - $sb.Append("|") - $row = $_.Split("|") - for ($colIndex = 0; $colIndex -lt $columnsCount; $colIndex++) { - $padSymbol = $row[$colIndex] -eq "-" ? "-" : " " - $cellContent = $row[$colIndex].PadRight($maxColumnWidths[$colIndex], $padSymbol) - $sb.Append(" $($cellContent) |") - } - $sb.AppendLine() - } - - return $sb.ToString().TrimEnd() - } - - [PSCustomObject] ToJsonObject() { - return [PSCustomObject]@{ - NodeType = $this.GetType().Name - Headers = $this.Headers - Rows = $this.Rows - } - } - - static [TableNode] FromJsonObject($jsonObj) { - return [TableNode]::new($jsonObj.Headers, $jsonObj.Rows) - } - - [Boolean] IsSimilarTo([BaseNode] $OtherNode) { - if ($OtherNode.GetType() -ne [TableNode]) { - return $false - } - - # We don't support having multiple TableNode instances on the same header level so such check is fine - return $true - } - - [Boolean] IsIdenticalTo([BaseNode] $OtherNode) { - if (-not $this.IsSimilarTo($OtherNode)) { - return $false - } - - if ($this.Headers -ne $OtherNode.Headers) { - return $false - } - - if ($this.Rows.Count -ne $OtherNode.Rows.Count) { - return $false - } - - for ($rowIndex = 0; $rowIndex -lt $this.Rows.Count; $rowIndex++) { - if ($this.Rows[$rowIndex] -ne $OtherNode.Rows[$rowIndex]) { - return $false - } - } - - return $true - } - - hidden static [String] ArrayToTableRow([Array] $Values) { - return [String]::Join("|", $Values) - } -} - -class NoteNode: BaseNode { - [String] $Content - - NoteNode([String] $Content) { - $this.Content = $Content - } - - [String] ToMarkdown($level) { - return @( - '```', - $this.Content, - '```' - ) -join "`n" - } - - [PSCustomObject] ToJsonObject() { - return [PSCustomObject]@{ - NodeType = $this.GetType().Name - Content = $this.Content - } - } - - static [NoteNode] FromJsonObject($jsonObj) { - return [NoteNode]::new($jsonObj.Content) - } - - [Boolean] IsSimilarTo([BaseNode] $OtherNode) { - if ($OtherNode.GetType() -ne [NoteNode]) { - return $false - } - - return $this.Content -eq $OtherNode.Content - } - - [Boolean] IsIdenticalTo([BaseNode] $OtherNode) { - return $this.IsSimilarTo($OtherNode) - } -} \ No newline at end of file diff --git a/images/macos/software-report/SoftwareReport.Generator.ps1 b/images/macos/software-report/SoftwareReport.Generator.ps1 index 8dea33c3d..f6e796d5d 100644 --- a/images/macos/software-report/SoftwareReport.Generator.ps1 +++ b/images/macos/software-report/SoftwareReport.Generator.ps1 @@ -1,3 +1,6 @@ +using module ./software-report-base/SoftwareReport.psm1 +using module ./software-report-base/SoftwareReport.Nodes.psm1 + param ( [Parameter(Mandatory)][string] $OutputDirectory, @@ -6,7 +9,6 @@ param ( $ErrorActionPreference = "Stop" -. ("$PSScriptRoot/SoftwareReport.Base.ps1") Import-Module "$PSScriptRoot/SoftwareReport.Common.psm1" -DisableNameChecking Import-Module "$PSScriptRoot/SoftwareReport.Xcode.psm1" -DisableNameChecking Import-Module "$PSScriptRoot/SoftwareReport.Android.psm1" -DisableNameChecking diff --git a/images/macos/templates/macOS-10.15.json b/images/macos/templates/macOS-10.15.json index b876d53e9..e912ade37 100644 --- a/images/macos/templates/macOS-10.15.json +++ b/images/macos/templates/macOS-10.15.json @@ -58,6 +58,11 @@ "source": "./software-report", "destination": "~/image-generation/" }, + { + "type": "file", + "source": "../../helpers/software-report-base", + "destination": "~/image-generation/software-report/" + }, { "type": "file", "source": "./helpers", diff --git a/images/macos/templates/macOS-11.anka.pkr.hcl b/images/macos/templates/macOS-11.anka.pkr.hcl index 387969d7f..672dd8ee0 100644 --- a/images/macos/templates/macOS-11.anka.pkr.hcl +++ b/images/macos/templates/macOS-11.anka.pkr.hcl @@ -77,6 +77,10 @@ build { "./helpers" ] } + provisioner "file" { + destination = "image-generation/software-report/" + source = "../../helpers/software-report-base" + } provisioner "file" { destination = "image-generation/add-certificate.swift" source = "./provision/configuration/add-certificate.swift" diff --git a/images/macos/templates/macOS-11.json b/images/macos/templates/macOS-11.json index b6ef7e894..164db8626 100644 --- a/images/macos/templates/macOS-11.json +++ b/images/macos/templates/macOS-11.json @@ -58,6 +58,11 @@ "source": "./software-report", "destination": "~/image-generation/" }, + { + "type": "file", + "source": "../../helpers/software-report-base", + "destination": "~/image-generation/software-report/" + }, { "type": "file", "source": "./helpers", diff --git a/images/macos/templates/macOS-12.anka.pkr.hcl b/images/macos/templates/macOS-12.anka.pkr.hcl index c612bcefa..fa2fb2878 100644 --- a/images/macos/templates/macOS-12.anka.pkr.hcl +++ b/images/macos/templates/macOS-12.anka.pkr.hcl @@ -77,6 +77,10 @@ build { "./helpers" ] } + provisioner "file" { + destination = "image-generation/software-report/" + source = "../../helpers/software-report-base" + } provisioner "file" { destination = "image-generation/add-certificate.swift" source = "./provision/configuration/add-certificate.swift" diff --git a/images/macos/templates/macOS-12.json b/images/macos/templates/macOS-12.json index 5cd163ba2..2ee5c7193 100644 --- a/images/macos/templates/macOS-12.json +++ b/images/macos/templates/macOS-12.json @@ -58,6 +58,11 @@ "source": "./software-report", "destination": "~/image-generation/" }, + { + "type": "file", + "source": "../../helpers/software-report-base", + "destination": "~/image-generation/software-report/" + }, { "type": "file", "source": "./helpers",