diff --git a/images/linux/scripts/SoftwareReport/SoftwareReport.Android.psm1 b/images/linux/scripts/SoftwareReport/SoftwareReport.Android.psm1 new file mode 100644 index 000000000..7f34143a9 --- /dev/null +++ b/images/linux/scripts/SoftwareReport/SoftwareReport.Android.psm1 @@ -0,0 +1,147 @@ +function Split-TableRowByColumns { + param( + [string] $Row + ) + return $Row.Split("|") | ForEach-Object { $_.trim() } +} + +function Get-AndroidSDKRoot { + return "/usr/local/lib/android/sdk" +} + +function Get-AndroidSDKManagerPath { + $androidSDKDir = Get-AndroidSDKRoot + return Join-Path $androidSDKDir "tools" "bin" "sdkmanager" +} + +function Get-AndroidInstalledPackages { + $androidSDKManagerPath = Get-AndroidSDKManagerPath + $androidSDKManagerList = Invoke-Expression "$androidSDKManagerPath --list --include_obsolete" + $androidInstalledPackages = @() + foreach($packageInfo in $androidSDKManagerList) { + if($packageInfo -Match "Available Packages:") { + break + } + + $androidInstalledPackages += $packageInfo + } + return $androidInstalledPackages +} + + +function Build-AndroidTable { + $packageInfo = Get-AndroidInstalledPackages + return @( + @{ + "Package" = "Android SDK Platform-Tools" + "Version" = Get-AndroidPackageVersions -PackageInfo $packageInfo -MatchedString "Android SDK Platform-Tools" + }, + @{ + "Package" = "Android SDK Tools" + "Version" = Get-AndroidPackageVersions -PackageInfo $packageInfo -MatchedString "Android SDK Tools" + }, + @{ + "Package" = "Android SDK Platforms" + "Version" = Get-AndroidPlatformVersions -PackageInfo $packageInfo + }, + @{ + "Package" = "Android SDK Build-tools" + "Version" = Get-AndroidBuildToolVersions -PackageInfo $packageInfo + }, + @{ + "Package" = "Google APIs" + "Version" = Get-AndroidGoogleAPIsVersions -PackageInfo $packageInfo + }, + @{ + "Package" = "Android Support Repository" + "Version" = Get-AndroidPackageVersions -PackageInfo $packageInfo -MatchedString "Android Support Repository" + }, + @{ + "Package" = "Google Play services" + "Version" = Get-AndroidPackageVersions -PackageInfo $packageInfo -MatchedString "Google Play services" + }, + @{ + "Package" = "Google Repository" + "Version" = Get-AndroidPackageVersions -PackageInfo $packageInfo -MatchedString "Google Repository" + }, + @{ + "Package" = "SDK Patch Applier v4" + "Version" = Get-AndroidPackageVersions -PackageInfo $packageInfo -MatchedString "SDK Patch Applier v4" + }, + @{ + "Package" = "CMake" + "Version" = Get-AndroidPackageVersions -PackageInfo $packageInfo -MatchedString "cmake" + }, + @{ + "Package" = "NDK" + "Version" = Get-AndroidPackageVersions -PackageInfo $packageInfo -MatchedString "ndk-bundle" + } + ) | Where-Object { $_.Version } | ForEach-Object { + [PSCustomObject] @{ + "Package Name" = $_.Package + "Version" = $_.Version + } + } +} + +function Get-AndroidPackageVersions { + param ( + [Parameter(Mandatory)] + [object] $PackageInfo, + [Parameter(Mandatory)] + [object] $MatchedString + ) + + $versions = $packageInfo | Where-Object { $_ -Match $MatchedString } | ForEach-Object { + $packageInfoParts = Split-TableRowByColumns $_ + return $packageInfoParts[1] + } + return ($versions -Join "
") +} + +function Get-AndroidPlatformVersions { + param ( + [Parameter(Mandatory)] + [object] $PackageInfo + ) + + $versions = $packageInfo | Where-Object { $_ -Match "Android SDK Platform " } | ForEach-Object { + $packageInfoParts = Split-TableRowByColumns $_ + $revision = $packageInfoParts[1] + $version = $packageInfoParts[0].split(";")[1] + return "$version, (rev $revision)" + } + [array]::Reverse($versions) + return ($versions -Join "
") +} + +function Get-AndroidBuildToolVersions { + param ( + [Parameter(Mandatory)] + [object] $PackageInfo + ) + + $versions = $packageInfo | Where-Object { $_ -Match "Android SDK Build-Tools" } | ForEach-Object { + $packageInfoParts = Split-TableRowByColumns $_ + return $packageInfoParts[1] + } + $groupVersions = @() + $versions | ForEach-Object { + $majorVersion = $_.Split(".")[0] + $groupVersions += $versions | Where-Object { $_.StartsWith($majorVersion) } | Join-String -Separator " " + } + return ($groupVersions | Sort-Object -Descending -Unique | Join-String -Separator "
") +} + +function Get-AndroidGoogleAPIsVersions { + param ( + [Parameter(Mandatory)] + [object] $PackageInfo + ) + + $versions = $packageInfo | Where-Object { $_ -Match "Google APIs" } | ForEach-Object { + $packageInfoParts = Split-TableRowByColumns $_ + return $packageInfoParts[0].split(";")[1] + } + return ($versions -Join "
") +} \ No newline at end of file diff --git a/images/linux/scripts/SoftwareReport/SoftwareReport.Browsers.psm1 b/images/linux/scripts/SoftwareReport/SoftwareReport.Browsers.psm1 new file mode 100644 index 000000000..96d05ee08 --- /dev/null +++ b/images/linux/scripts/SoftwareReport/SoftwareReport.Browsers.psm1 @@ -0,0 +1,19 @@ +function Get-ChromeVersion { + $googleChromeVersion = google-chrome --version | Take-Part -Part 2 + return "Google Chrome $googleChromeVersion" +} + +function Get-ChromeDriverVersion { + $chromeDriverVersion = chromedriver --version | Take-Part -Part 1 + return "ChromeDriver $chromeDriverVersion" +} + +function Get-FirefoxVersion { + $firefoxVersion = firefox --version + return $firefoxVersion +} + +function Get-GeckodriverVersion { + $geckodriverVersion = geckodriver --version | Select-Object -First 1 | Take-Part -Part 1 + return "Geckodriver $geckodriverVersion" +} \ No newline at end of file diff --git a/images/linux/scripts/SoftwareReport/SoftwareReport.CachedTools.psm1 b/images/linux/scripts/SoftwareReport/SoftwareReport.CachedTools.psm1 new file mode 100644 index 000000000..536b31255 --- /dev/null +++ b/images/linux/scripts/SoftwareReport/SoftwareReport.CachedTools.psm1 @@ -0,0 +1,65 @@ +function Get-ToolcacheRubyVersions { + $toolcachePath = Join-Path $env:AGENT_TOOLSDIRECTORY "Ruby" + return Get-ChildItem $toolcachePath -Name | Sort-Object { [Version]$_ } +} + +function Get-ToolcachePythonVersions { + $toolcachePath = Join-Path $env:AGENT_TOOLSDIRECTORY "Python" + return Get-ChildItem $toolcachePath -Name | Sort-Object { [Version]$_ } +} + +function Get-ToolcachePyPyVersions { + $toolcachePath = Join-Path $env:AGENT_TOOLSDIRECTORY "PyPy" + Get-ChildItem -Path $toolcachePath -Name | Sort-Object { [Version] $_ } | ForEach-Object { + $pypyRootPath = Join-Path $toolcachePath $_ "x64" + [string]$pypyVersionOutput = & "$pypyRootPath/bin/python" -c "import sys;print(sys.version)" + $pypyVersionOutput -match "^([\d\.]+) \(.+\) \[PyPy ([\d\.]+) .+]$" | Out-Null + return "{0} [PyPy {1}]" -f $Matches[1], $Matches[2] + } +} + +function Get-ToolcacheNodeVersions { + $toolcachePath = Join-Path $env:AGENT_TOOLSDIRECTORY "node" + return Get-ChildItem $toolcachePath -Name | Sort-Object { [Version]$_ } +} + +function Get-ToolcacheGoVersions { + $toolcachePath = Join-Path $env:AGENT_TOOLSDIRECTORY "go" + return Get-ChildItem $toolcachePath -Name | Sort-Object { [Version]$_ } +} + +function Get-ToolcacheBoostVersions { + $toolcachePath = Join-Path $env:AGENT_TOOLSDIRECTORY "boost" + if (-not (Test-Path $toolcachePath)) { + return @() + } + return Get-ChildItem $toolcachePath -Name | Sort-Object { [Version]$_ } +} + +function Build-CachedToolsSection { + $output = "" + + $output += New-MDHeader "Ruby" -Level 4 + $output += New-MDList -Lines (Get-ToolcacheRubyVersions) -Style Unordered + + $output += New-MDHeader "Python" -Level 4 + $output += New-MDList -Lines (Get-ToolcachePythonVersions) -Style Unordered + + $output += New-MDHeader "PyPy" -Level 4 + $output += New-MDList -Lines (Get-ToolcachePyPyVersions) -Style Unordered + + $output += New-MDHeader "Node.js" -Level 4 + $output += New-MDList -Lines (Get-ToolcacheNodeVersions) -Style Unordered + + $output += New-MDHeader "Go" -Level 4 + $output += New-MDList -Lines (Get-ToolcacheGoVersions) -Style Unordered + + $boostVersions = Get-ToolcacheBoostVersions + if ($boostVersions.Count -gt 0) { + $output += New-MDHeader "Boost" -Level 4 + $output += New-MDList -Lines $boostVersions -Style Unordered + } + + + return $output +} \ No newline at end of file diff --git a/images/linux/scripts/SoftwareReport/SoftwareReport.Common.psm1 b/images/linux/scripts/SoftwareReport/SoftwareReport.Common.psm1 new file mode 100644 index 000000000..1d96f5550 --- /dev/null +++ b/images/linux/scripts/SoftwareReport/SoftwareReport.Common.psm1 @@ -0,0 +1,296 @@ +Import-Module (Join-Path $PSScriptRoot "SoftwareReport.Helpers.psm1") -DisableNameChecking + +function Get-OSName { + lsb_release -ds +} + +function Get-CPPVersions { + $cppVersions = & apt list --installed | Where-Object { $_ -match "g\+\+-\d+"} | ForEach-Object { + $_ -match "now (?\d+\.\d+\.\d+)-" | Out-Null + $Matches.version + } + return "GNU C++ " + ($cppVersions -Join ", ") +} + +function Get-FortranVersions { + $fortranVersions = & apt list --installed | Where-Object { $_ -match "^gfortran-\d+"} | ForEach-Object { + $_ -match "now (?\d+\.\d+\.\d+)-" | Out-Null + $Matches.version + } + return "GNU Fortran " + ($fortranVersions -Join ", ") +} + +function Get-ClangVersions { + $clangVersions = @() + $clangVersions = & apt list --installed | Where-Object { $_ -match "^clang-\d+"} | ForEach-Object { + $clangCommand = ($_ -Split "/")[0] + Invoke-Expression "$clangCommand --version" | Where-Object { $_ -match "clang version" } | ForEach-Object { + $_ -match "clang version (?\d+\.\d+\.\d+)-" | Out-Null + $Matches.version + } + } + return "Clang " + ($clangVersions -Join ", ") +} + +function Get-ErlangVersion { + $result = Get-CommandResult "erl -version" + $result.Output -match "version (?\d+\.\d+\.\d+)" | Out-Null + $version = $Matches.version + return "Erlang $version" +} + +function Get-MonoVersion { + $monoVersion = $(mono --version) | Out-String | Take-Part -Part 4 + return "Mono $monoVersion" +} + +function Get-NodeVersion { + $nodeVersion = $(node --version).Substring(1) + return "Node $nodeVersion" +} + +function Get-PythonVersion { + $result = Get-CommandResult "python --version" + $version = $result.Output | Take-Part -Part 1 + return "Python $version" +} + +function Get-Python3Version { + $result = Get-CommandResult "python3 --version" + $version = $result.Output | Take-Part -Part 1 + return "Python3 $version" +} + +function Get-PowershellVersion { + $(pwsh --version) +} + +function Get-RubyVersion { + $rubyVersion = $(ruby --version) | Out-String | Take-Part -Part 1 + return "Ruby $rubyVersion" +} + +function Get-SwiftVersion { + $swiftVersion = $(swift --version) | Out-String | Take-Part -Part 2 + return "Swift $swiftVersion" +} + +function Get-JuliaVersion { + $juliaVersion = $(julia --version) | Out-String | Take-Part -Part 2 + return "Julia $juliaVersion" +} + +function Get-HomebrewVersion { + $result = Get-CommandResult "brew -v" + $result.Output -match "Homebrew (?\d+\.\d+\.\d+)" | Out-Null + $version = $Matches.version + return "Homebrew $version" +} + +function Get-GemVersion { + $(gem --version) -match "(?\d+\.\d+\.\d+)" | Out-Null + $gemVersion = $Matches.version + return "Gem $gemVersion" +} + +function Get-MinicondaVersion { + $condaVersion = $(conda --version) + return "Mini$condaVersion" +} + +function Get-HelmVersion { + $(helm version) -match 'Version:"v(?\d+\.\d+\.\d+)"' | Out-Null + $helmVersion = $Matches.version + return "Helm $helmVersion" +} + +function Get-NpmVersion { + $npmVersion = $(npm --version) + return "Npm $npmVersion" +} + +function Get-YarnVersion { + $yarnVersion = $(yarn --version) + return "Yarn $yarnVersion" +} + +function Get-PipVersion { + $result = Get-CommandResult "pip --version" + $result.Output -match "pip (?\d+\.\d+\.\d+)" | Out-Null + $pipVersion = $Matches.version + return "Pip $pipVersion" +} + +function Get-Pip3Version { + $result = Get-CommandResult "pip3 --version" + $result.Output -match "pip (?\d+\.\d+\.\d+)" | Out-Null + $pipVersion = $Matches.version + return "Pip3 $pipVersion" +} + +function Get-VcpkgVersion { + $result = Get-CommandResult "vcpkg version" + $result.Output -match "version (?\d+\.\d+\.\d+)" | Out-Null + $vcpkgVersion = $Matches.version + return "Vcpkg $vcpkgVersion" +} + +function Get-AntVersion { + $result = $(ant -version) | Out-String + $result -match "version (?\d+\.\d+\.\d+)" | Out-Null + $antVersion = $Matches.version + return "Ant $antVersion" +} + +function Get-GradleVersion { + $result = $(gradle -v) | Out-String + $result -match "Gradle (?\d+\.\d+\.\d+)" | Out-Null + $gradleVersion = $Matches.version + return "Gradle $gradleVersion" +} +function Get-MavenVersion { + $result = $(mvn -version) | Out-String + $result -match "Apache Maven (?\d+\.\d+\.\d+)" | Out-Null + $mavenVersion = $Matches.version + return "Maven $mavenVersion" +} +function Get-SbtVersion { + $result = $(sbt -version) | Out-String + $result -match "sbt script version: (?\d+\.\d+\.\d+)" | Out-Null + $sbtVersion = $Matches.version + return "Sbt $sbtVersion" +} + +function Get-PHPVersions { + return $(apt list --installed) | Where-Object { $_ -match "^php\d+\.\d+/"} | ForEach-Object { + $_ -match "now (?\d+\.\d+\.\d+)-" | Out-Null + $Matches.version + } +} + +function Get-ComposerVersion { + $(composer --version) -match "Composer version (?\d+\.\d+\.\d+)\s" | Out-Null + return $Matches.version +} + +function Get-PHPUnitVersion { + $(phpunit --version | Out-String) -match "PHPUnit (?\d+\.\d+\.\d+)\s" | Out-Null + return $Matches.version +} + +function Build-PHPTable { + $php = @{ + "Tool" = "PHP" + "Version" = "$(Get-PHPVersions -Join '
')" + } + $composer = @{ + "Tool" = "Composer" + "Version" = Get-ComposerVersion + } + $phpunit = @{ + "Tool" = "PHPUnit" + "Version" = Get-PHPUnitVersion + } + return @($php, $composer, $phpunit) | ForEach-Object { + [PSCustomObject] @{ + "Tool" = $_.Tool + "Version" = $_.Version + } + } +} + +function Get-GHCVersion { + $(ghc --version) -match "version (?\d+\.\d+\.\d+)" | Out-Null + $ghcVersion = $Matches.version + return "GHC $ghcVersion" +} + +function Get-CabalVersion { + $(cabal --version | Out-String) -match "cabal-install version (?\d+\.\d+\.\d+\.\d+)" | Out-Null + $cabalVersion = $Matches.version + return "Cabal $cabalVersion" +} + +function Get-StackVersion { + $(stack --version | Out-String) -match "Version (?\d+\.\d+\.\d+)" | Out-Null + $stackVersion = $Matches.version + return "Stack $stackVersion" +} + +function Get-RustVersion { + $rustVersion = $(rustc --version) | Take-Part -Part 1 + return "Rust $rustVersion" +} + +function Get-BindgenVersion { + $bindgenVersion = $(bindgen --version) | Take-Part -Part 1 + return "Bindgen $bindgenVersion" +} + +function Get-CargoVersion { + $cargoVersion = $(cargo --version) | Take-Part -Part 1 + return "Cargo $cargoVersion" +} + +function Get-CargoAuditVersion { + $cargoAuditVersion = $(cargo audit --version) | Take-Part -Part 1 + return "Cargo audit $cargoAuditVersion" +} + +function Get-CargoOutdatedVersion { + $cargoOutdatedVersion = $(cargo outdated --version) | Take-Part -Part 1 -Delimiter "v" + return "Cargo outdated $cargoOutdatedVersion" +} + +function Get-CargoClippyVersion { + $cargoClippyVersion = $(cargo-clippy --version) | Take-Part -Part 1 + return "Cargo clippy $cargoClippyVersion" +} + +function Get-CbindgenVersion { + $cbindgenVersion = $(cbindgen --version) | Take-Part -Part 1 + return "Cbindgen $cbindgenVersion" +} + +function Get-RustupVersion { + $rustupVersion = $(rustup --version) | Take-Part -Part 1 + return "Rustup $rustupVersion" +} + +function Get-RustdocVersion { + $rustdocVersion = $(rustdoc --version) | Take-Part -Part 1 + return "Rustdoc $rustdocVersion" +} + +function Get-RustfmtVersion { + $rustfmtVersion = $(rustfmt --version) | Take-Part -Part 1 | Take-Part -Part 0 -Delimiter "-" + return "Rustfmt $rustfmtVersion" +} + +function Get-AzModuleVersions { + $azModuleVersions = Get-ChildItem /usr/share | Where-Object { $_ -match "az_\d+" } | Foreach-Object { + $_.Name.Split("_")[1] + } + + $azModuleVersions = $azModuleVersions -join " " + return $azModuleVersions +} + +function Get-DotNetCoreSdkVersions { + $unsortedDotNetCoreSdkVersion = dotnet --list-sdks list | ForEach-Object { $_ | Take-Part -Part 0 } + $dotNetCoreSdkVersion = $unsortedDotNetCoreSdkVersion -join " " + return $dotNetCoreSdkVersion +} + +function Get-CachedDockerImages { + $toolsetJson = Get-ToolsetContent + $images = $toolsetJson.docker.images + return $images +} + +function Get-AptPackages { + $toolsetJson = Get-ToolsetContent + $apt = $toolsetJson.apt + $pkgs = ($apt.common_packages + $apt.cmd_packages | Sort-Object) -join ", " + return $pkgs +} \ No newline at end of file diff --git a/images/linux/scripts/SoftwareReport/SoftwareReport.Databases.psm1 b/images/linux/scripts/SoftwareReport/SoftwareReport.Databases.psm1 new file mode 100644 index 000000000..6c274184e --- /dev/null +++ b/images/linux/scripts/SoftwareReport/SoftwareReport.Databases.psm1 @@ -0,0 +1,19 @@ +function Get-PostgreSqlVersion { + $postgreSQLVersion = psql --version | Take-Part -Part 2 + return "Postgre SQL $postgreSQLVersion" +} + +function Get-MongoDbVersion { + $mongoDBVersion = mongod --version | Select-Object -First 1 | Take-Part -Part 2 -Delimiter "v" + return "MongoDB $mongoDBVersion" +} + +function Get-SqliteVersion { + $sqliteVersion = sqlite3 --version | Take-Part -Part 0 + return "sqlite3 $sqliteVersion" +} + +function Get-MySqlVersion { + $mySqlVersion = (mysql --version).Split("/usr/bin/")[1] + return "MySQL ($mySqlVersion)" +} \ No newline at end of file diff --git a/images/linux/scripts/SoftwareReport/SoftwareReport.Generator.ps1 b/images/linux/scripts/SoftwareReport/SoftwareReport.Generator.ps1 new file mode 100644 index 000000000..e63f3719a --- /dev/null +++ b/images/linux/scripts/SoftwareReport/SoftwareReport.Generator.ps1 @@ -0,0 +1,221 @@ +param ( + [Parameter(Mandatory)][string] + $OutputDirectory +) + +# Install MarkdownPS module for software report generation +Install-Module MarkdownPS -Force -Scope CurrentUser +Import-Module MarkdownPS +Import-Module (Join-Path $PSScriptRoot "SoftwareReport.CachedTools.psm1") -DisableNameChecking +Import-Module (Join-Path $PSScriptRoot "SoftwareReport.Common.psm1") -DisableNameChecking +Import-Module (Join-Path $PSScriptRoot "SoftwareReport.Helpers.psm1") -DisableNameChecking +Import-Module (Join-Path $PSScriptRoot "SoftwareReport.Tools.psm1") -DisableNameChecking +Import-Module (Join-Path $PSScriptRoot "SoftwareReport.Java.psm1") -DisableNameChecking +Import-Module (Join-Path $PSScriptRoot "SoftwareReport.Databases.psm1") -DisableNameChecking +Import-Module (Join-Path $PSScriptRoot "SoftwareReport.Browsers.psm1") -DisableNameChecking +Import-Module (Join-Path $PSScriptRoot "SoftwareReport.Android.psm1") -DisableNameChecking + +$markdown = "" + +if ($env:ANNOUNCEMENTS) { + $markdown += $env:ANNOUNCEMENTS + $markdown += New-MDNewLine + $markdown += "***" + $markdown += New-MDNewLine +} + +$OSName = Get-OSName +$markdown += New-MDHeader "$OSName" -Level 1 + +$markdown += New-MDList -Style Unordered -Lines @( + "Image Version: $env:ImageVersion" +) + +$markdown += New-MDHeader "Installed Software" -Level 2 +$markdown += New-MDHeader "Language and Runtime" -Level 3 + +$markdown += New-MDList -Style Unordered -Lines @( + (Get-CPPVersions), + (Get-FortranVersions), + (Get-ClangVersions), + (Get-ErlangVersion), + (Get-MonoVersion), + (Get-NodeVersion), + (Get-PythonVersion), + (Get-Python3Version), + (Get-PowershellVersion), + (Get-RubyVersion), + (Get-SwiftVersion), + (Get-JuliaVersion) +) + +$markdown += New-MDHeader "Package Management" -Level 3 +$markdown += New-MDList -Style Unordered -Lines @( + (Get-HomebrewVersion), + (Get-GemVersion), + (Get-MinicondaVersion), + (Get-HelmVersion), + (Get-NpmVersion), + (Get-YarnVersion), + (Get-PipVersion), + (Get-Pip3Version), + (Get-VcpkgVersion) +) + +$markdown += New-MDHeader "Project Management" -Level 3 +$markdown += New-MDList -Style Unordered -Lines @( + (Get-AntVersion), + (Get-GradleVersion), + (Get-MavenVersion), + (Get-SbtVersion) +) + +$markdown += New-MDHeader "Tools" -Level 3 +$toolsList = @( + (Get-7zipVersion), + (Get-AnsibleVersion), + (Get-AzCopy7Version), + (Get-AzCopy10Version), + (Get-BazelVersion), + (Get-BazeliskVersion), + (Get-CMakeVersion), + (Get-CurlVersion), + (Get-DockerComposeVersion), + (Get-DockerMobyVersion), + (Get-DockerBuildxVersion), + (Get-GitVersion), + (Get-GitLFSVersion), + (Get-GitFTPVersion), + (Get-GoogleCloudSDKVersion), + (Get-HavegedVersion), + (Get-HerokuVersion), + (Get-HHVMVersion), + (Get-SVNVersion), + (Get-JqVersion), + (Get-KindVersion), + (Get-KubectlVersion), + (Get-KustomizeVersion), + (Get-LeiningenVersion), + (Get-M4Version), + (Get-HGVersion), + (Get-MinikubeVersion), + (Get-NewmanVersion), + (Get-NvmVersion), + (Get-PackerVersion), + (Get-PhantomJSVersion), + (Get-SwigVersion), + (Get-TerraformVersion), + (Get-UnZipVersion), + (Get-WgetVersion), + (Get-ZipVersion), + (Get-ZstdVersion) +) + +if (-not (Test-IsUbuntu16)) { + $toolsList += @( + (Get-PodManVersion), + (Get-BuildahVersion), + (Get-SkopeoVersion) + ) +} + +$markdown += New-MDList -Style Unordered -Lines ($toolsList | Sort-Object) + +$markdown += New-MDHeader "CLI Tools" -Level 3 +$markdown += New-MDList -Style Unordered -Lines @( + (Get-AlibabaCloudCliVersion), + (Get-AWSCliVersion), + (Get-AWSCliSessionManagerPluginVersion), + (Get-AWSSAMVersion), + (Get-AzureCliVersion), + (Get-AzureDevopsVersion), + (Get-GitHubCliVersion), + (Get-HubCliVersion), + (Get-NetlifyCliVersion), + (Get-OCCliVersion), + (Get-ORASCliVersion), + (Get-VerselCliversion) +) + +$markdown += New-MDHeader "Java" -Level 3 +$markdown += Get-JavaVersions | New-MDTable +$markdown += New-MDNewLine + +$markdown += New-MDHeader "PHP" -Level 3 +$markdown += Build-PHPTable | New-MDTable +$markdown += New-MDNewLine + +$markdown += New-MDHeader "Haskell" -Level 3 +$markdown += New-MDList -Style Unordered -Lines @( + (Get-GHCVersion), + (Get-CabalVersion), + (Get-StackVersion) +) + +$markdown += New-MDHeader "Rust Tools" -Level 3 +$markdown += New-MDList -Style Unordered -Lines @( + (Get-RustVersion), + (Get-RustupVersion), + (Get-RustdocVersion), + (Get-CargoVersion) +) + +$markdown += New-MDHeader "Packages" -Level 4 +$markdown += New-MDList -Style Unordered -Lines @( + (Get-BindgenVersion), + (Get-CargoAuditVersion), + (Get-CargoOutdatedVersion), + (Get-CargoClippyVersion), + (Get-CbindgenVersion), + (Get-RustfmtVersion) +) + +$markdown += New-MDHeader "Browsers and Drivers" -Level 3 +$markdown += New-MDList -Style Unordered -Lines @( + (Get-ChromeVersion), + (Get-ChromeDriverVersion), + (Get-FirefoxVersion), + (Get-GeckodriverVersion) +) + +$markdown += New-MDHeader ".NET Core SDK" -Level 3 +$markdown += New-MDList -Style Unordered -Lines @( + (Get-DotNetCoreSdkVersions) +) + +$markdown += New-MDHeader "Az Module" -Level 3 +$markdown += New-MDList -Style Unordered -Lines @( + (Get-AzModuleVersions) +) + +$markdown += New-MDHeader "Databases" -Level 3 +$markdown += New-MDList -Style Unordered -Lines @( + (Get-PostgreSqlVersion), + (Get-MongoDbVersion), + (Get-SqliteVersion) +) + +$markdown += New-MDHeader "MySQL" -Level 4 +$markdown += New-MDList -Style Unordered -Lines @( + (Get-MySqlVersion), + "MySQL Server (user:root password:root)", + "MS SQL Server Client Tools" +) +$markdown += New-MDCode -Lines @( + "MySQL service is disabled by default. Use the following command as a part of your job to start the service: 'sudo systemctl start mysql.service'" +) + +$markdown += New-MDHeader "Cached Tools" -Level 3 +$markdown += Build-CachedToolsSection + +$markdown += New-MDHeader "Android" -Level 3 +$markdown += Build-AndroidTable | New-MDTable +$markdown += New-MDNewLine + +$markdown += New-MDHeader "Cached Docker images" -Level 3 +$markdown += New-MDList -Style Unordered -Lines @(Get-CachedDockerImages) + +$markdown += New-MDHeader "Installed apt packages" -Level 3 +$markdown += New-MDList -Style Unordered -Lines @(Get-AptPackages) + +$markdown | Out-File -FilePath "${OutputDirectory}/Ubuntu-Readme.md" diff --git a/images/linux/scripts/SoftwareReport/SoftwareReport.Helpers.psm1 b/images/linux/scripts/SoftwareReport/SoftwareReport.Helpers.psm1 new file mode 100644 index 000000000..6f2701c92 --- /dev/null +++ b/images/linux/scripts/SoftwareReport/SoftwareReport.Helpers.psm1 @@ -0,0 +1,52 @@ +function Get-CommandResult { + param ( + [Parameter(Mandatory=$true)] + [string] $Command, + [switch] $Multiline + ) + # Bash trick to suppress and show error output because some commands write to stderr (for example, "python --version") + $stdout = & bash -c "$Command 2>&1" + $exitCode = $LASTEXITCODE + return @{ + Output = If ($Multiline -eq $true) { $stdout } else { [string]$stdout } + ExitCode = $exitCode + } +} + +function Take-Part { + param ( + [Parameter(ValueFromPipeline)] + [string] $toolOutput, + [string] $Delimiter = " ", + [int[]] $Part + ) + $parts = $toolOutput.Split($Delimiter, [System.StringSplitOptions]::RemoveEmptyEntries) + $selectedParts = $parts[$Part] + return [string]::Join($Delimiter, $selectedParts) +} + +function Test-IsUbuntu16 { + return (lsb_release -rs) -eq "16.04" +} + +function Test-IsUbuntu18 { + return (lsb_release -rs) -eq "18.04" +} + +function Test-IsUbuntu20 { + return (lsb_release -rs) -eq "20.04" +} + +function Get-ToolsetContent +{ + $toolset = Join-Path $env:INSTALLER_SCRIPT_FOLDER "toolset.json" + Get-Content $toolset -Raw | ConvertFrom-Json +} + +function New-MDNewLine { + param ( + [int] $Count = 1 + ) + $newLineSymbol = [System.Environment]::NewLine + return $newLineSymbol * $Count +} diff --git a/images/linux/scripts/SoftwareReport/SoftwareReport.Java.psm1 b/images/linux/scripts/SoftwareReport/SoftwareReport.Java.psm1 new file mode 100644 index 000000000..4e54661ab --- /dev/null +++ b/images/linux/scripts/SoftwareReport/SoftwareReport.Java.psm1 @@ -0,0 +1,30 @@ +function Get-JavaFullVersion { + param($JavaRootPath) + + $javaBinPath = Join-Path $javaRootPath "/bin/java" + $javaVersionOutput = (Get-CommandResult "$javaBinPath -version").Output + $matchResult = $javaVersionOutput | Select-String '^openjdk version \"([\d\._]+)\"' + return $matchResult.Matches.Groups[1].Value +} + +function Get-JavaVersions { + $defaultJavaPath = $env:JAVA_HOME + $javaVersions = Get-Item env:JAVA_HOME_*_X64 + $sortRules = @{ + Expression = { [Int32]$_.Name.Split("_")[2] } + Descending = $false + } + + return $javaVersions | Sort-Object $sortRules | ForEach-Object { + $javaPath = $_.Value + $version = Get-JavaFullVersion $javaPath + $vendor = $version.StartsWith("1.7") ? "Zulu" : "AdoptOpenJDK" + $defaultPostfix = ($javaPath -eq $defaultJavaPath) ? " (default)" : "" + + [PSCustomObject] @{ + "Version" = $version + $defaultPostfix + "Vendor" = $vendor + "Environment Variable" = $_.Name + } + } +} \ No newline at end of file diff --git a/images/linux/scripts/SoftwareReport/SoftwareReport.Tools.psm1 b/images/linux/scripts/SoftwareReport/SoftwareReport.Tools.psm1 new file mode 100644 index 000000000..f66f2e4fc --- /dev/null +++ b/images/linux/scripts/SoftwareReport/SoftwareReport.Tools.psm1 @@ -0,0 +1,249 @@ +function Get-7zipVersion { + $7zVersion = 7z i | Select-String "7-Zip" | Take-Part -Part 2 + return "7-Zip $7zVersion" +} + +function Get-AnsibleVersion { + $ansibleVersion = ansible --version | Select-Object -First 1 | Take-Part -Part 1 + return "Ansible $ansibleVersion" +} + +function Get-AzCopy7Version { + $azcopy7Version = azcopy --version | Take-Part -Part 1 | Take-Part -Part 0 -Delimiter "-" + return "AzCopy7 (available by azcopy alias) $azcopy7Version" +} + +function Get-AzCopy10Version { + $azcopy10Version = azcopy10 --version | Take-Part -Part 2 + return "AzCopy10 (available by azcopy10 alias) $azcopy10Version" +} + +function Get-BazelVersion { + $bazelVersion = bazel --version | Select-String "bazel" | Take-Part -Part 1 + return "Bazel $bazelVersion" +} + +function Get-BazeliskVersion { + $bazeliskVersion = bazelisk version 2>&1 | Select-String "Bazelisk version:" | Take-Part -Part 2 | Take-Part -Part 0 -Delimiter "v" + return "Bazelisk $bazeliskVersion" +} + +function Get-PodManVersion { + $podmanVersion = podman --version | Take-Part -Part 2 + return "Podman $podmanVersion" +} + +function Get-BuildahVersion { + $buildahVersion = buildah --version | Take-Part -Part 2 + return "Buildah $buildahVersion" +} + +function Get-SkopeoVersion { + $skopeoVersion = skopeo --version | Take-Part -Part 2 + return "Skopeo $skopeoVersion" +} + +function Get-CMakeVersion { + $cmakeVersion = cmake --version | Select-Object -First 1 | Take-Part -Part 2 + return "CMake $cmakeVersion" +} + +function Get-CurlVersion { + $curlVersion = curl --version | Select-Object -First 1 | Take-Part -Part 0,1 + return $curlVersion +} + +function Get-DockerComposeVersion { + $composeVersion = docker-compose -v | Take-Part -Part 2 | Take-Part -Part 0 -Delimiter "," + return "Docker Compose $composeVersion" +} + +function Get-DockerMobyVersion { + $dockerVersion = docker -v | Take-Part -Part 2 | Take-Part -Part 0 -Delimiter "+" + return "Docker-Moby $dockerVersion" +} + +function Get-DockerBuildxVersion { + $buildxVersion = docker buildx version | Take-Part -Part 1 | Take-Part -Part 0 -Delimiter "+" + return "Docker-Buildx $buildxVersion" +} + +function Get-GitVersion { + $gitVersion = git --version 2>&1 | Take-Part -Part 2 + return "Git $gitVersion" +} + +function Get-GitLFSVersion { + $gitlfsversion = git-lfs --version 2>&1 | Take-Part -Part 0 | Take-Part -Part 1 -Delimiter "/" + return "Git LFS $gitlfsversion" +} + +function Get-GitFTPVersion { + $gitftpVersion = git-ftp --version | Take-Part -Part 2 + return "Git-ftp $gitftpVersion" +} + +function Get-GoogleCloudSDKVersion { + return "$(gcloud --version | Select-Object -First 1)" +} + +function Get-HavegedVersion { + $havegedVersion = dpkg-query --showformat='${Version}' --show haveged | Take-Part -Part 0 -Delimiter "-" + return "Haveged $havegedVersion" +} + +function Get-HerokuVersion { + $herokuVersion = heroku version | Take-Part -Part 0 | Take-Part -Part 1 -Delimiter "/" + return "Heroku $herokuVersion" +} + +function Get-HHVMVersion { + $hhvmVersion = hhvm --version | Select-Object -First 1 | Take-Part -Part 2 + return "HHVM (HipHop VM) $hhvmVersion" +} + +function Get-SVNVersion { + $svnVersion = svn --version | Select-Object -First 1 | Take-Part -Part 2 + return "SVN $svnVersion" +} + +function Get-KustomizeVersion { + $kustomizeVersion = kustomize version --short | Take-Part -Part 0 | Take-Part -Part 1 -Delimiter "v" + return "Kustomize $kustomizeVersion" +} + +function Get-KindVersion { + $kindVersion = kind version | Take-Part -Part 1 | Take-Part -Part 0 -Delimiter "v" + return "Kind $kindVersion" +} + +function Get-KubectlVersion { + $kubectlVersion = kubectl version --client --short | Take-Part -Part 2 | Take-Part -Part 0 -Delimiter "v" + return "Kubectl $kubectlVersion" +} + +function Get-MinikubeVersion { + $minikubeVersion = minikube version --short | Take-Part -Part 2 | Take-Part -Part 0 -Delimiter "v" + return "Minikube $minikubeVersion" +} + +function Get-HGVersion { + $hgVersion = hg --version | Select-Object -First 1 | Take-Part -Part -1 | Take-Part -Part 0 -Delimiter ")" + return "Mercurial $hgVersion" +} + +function Get-M4Version { + $m4Version = m4 --version | Select-Object -First 1 | Take-Part -Part -1 + return "m4 $m4Version" +} + +function Get-LeiningenVersion { + return "$(lein -v | Take-Part -Part 0,1)" +} + +function Get-NewmanVersion { + return "Newman $(newman --version)" +} + +function Get-NvmVersion { + $nvmVersion = bash -c "source $HOME/.nvm/nvm.sh && nvm --version" + return "nvm $nvmVersion" +} + +function Get-PackerVersion { + return "Packer $(packer --version)" +} + +function Get-PhantomJSVersion { + return "PhantomJS $(phantomjs --version)" +} + +function Get-SwigVersion { + $swigVersion = swig -version | Select-String "SWIG Version" | Take-Part -Part 2 + return "Swig $swigVersion" +} + +function Get-TerraformVersion { + return (terraform version | Select-String "^Terraform").Line.Replace('v','') +} + +function Get-UnZipVersion { + $unzipVersion = unzip -v | Select-Object -First 1 | Take-Part -Part 1 + return "unzip $unzipVersion" +} + +function Get-WgetVersion { + $wgetVersion = wget --version | Select-Object -First 1 | Take-Part -Part 2 + return "wget $wgetVersion" +} + +function Get-ZipVersion { + $zipVersion = zip -v | Select-String "This is Zip" | Take-Part -Part 3 + return "zip $zipVersion" +} + +function Get-ZstdVersion { + $zstdVersion = (zstd --version).Split() -match "v\d+" | ForEach-Object {$_.Replace("v","").Replace(",","")} + return "zstd $zstdVersion" +} + +function Get-JqVersion { + $jqVersion = jq --version | Take-Part -Part 1 -Delimiter "-" + return "jq $jqVersion" +} + +function Get-AzureCliVersion { + $azcliVersion = az -v | Select-String "azure-cli" | Take-Part -Part -1 + return "Azure CLI (azure-cli) $azcliVersion" +} + +function Get-AzureDevopsVersion { + $azdevopsVersion = az -v | Select-String "azure-devops" | Take-Part -Part -1 + return "Azure CLI (azure-devops) $azdevopsVersion" +} + +function Get-AlibabaCloudCliVersion { + return "Alibaba Cloud CLI $(aliyun version)" +} + +function Get-AWSCliVersion { + $awsVersion = aws --version 2>&1 | Take-Part -Part 0 | Take-Part -Part 1 -Delimiter "/" + return "AWS CLI $awsVersion" +} + +function Get-AWSCliSessionManagerPluginVersion { + return "AWS CLI Session manager plugin $(session-manager-plugin --version 2>&1)" +} + +function Get-AWSSAMVersion { + return "AWS SAM CLI $(sam --version | Take-Part -Part -1)" +} + +function Get-HubCliVersion { + $hubVersion = hub --version | Select-String "hub version" | Take-Part -Part 2 + return "Hub CLI $hubVersion" +} + +function Get-GitHubCliVersion { + $ghVersion = gh --version | Select-String "gh version" | Take-Part -Part 2 + return "GitHub CLI $ghVersion" +} + +function Get-NetlifyCliVersion { + $netlifyVersion = netlify --version | Take-Part -Part 0 | Take-Part -Part 1 -Delimiter "/" + return "Netlify CLI $netlifyVersion" +} + +function Get-OCCliVersion { + $ocVersion = oc version | Take-Part -Part 2 | Take-Part -Part 0 -Delimiter "-" + return "oc CLI $ocVersion" +} + +function Get-ORASCliVersion { + $orasVersion = oras version | Select-String "^Version:" | Take-Part -Part 1 + return "ORAS CLI $orasVersion" +} + +function Get-VerselCliversion { + return "$(vercel --version 2>&1 | Select-Object -First 1)" +} diff --git a/images/linux/ubuntu1604.json b/images/linux/ubuntu1604.json index 9d8a11ba7..7ef3122a6 100644 --- a/images/linux/ubuntu1604.json +++ b/images/linux/ubuntu1604.json @@ -88,6 +88,11 @@ "source": "{{template_dir}}/scripts/installers", "destination": "{{user `installer_script_folder`}}" }, + { + "type": "file", + "source": "{{ template_dir }}/scripts/SoftwareReport", + "destination": "{{user `image_folder`}}" + }, { "type": "file", "source": "{{template_dir}}/toolsets/toolcache-1604.json", @@ -287,9 +292,19 @@ ], "execute_command": "sudo sh -c '{{ .Vars }} {{ .Path }}'" }, + { + "type": "powershell", + "inline": [ + "pwsh -File '{{user `image_folder`}}/SoftwareReport/SoftwareReport.Generator.ps1' -OutputDirectory '{{user `image_folder`}}'" + ], + "environment_vars":[ + "INSTALLER_SCRIPT_FOLDER={{user `installer_script_folder`}}", + "ANNOUNCEMENTS={{user `announcements`}}" + ] + }, { "type": "file", - "source": "{{user `metadata_file`}}", + "source": "{{user `image_folder`}}/Ubuntu-Readme.md", "destination": "{{template_dir}}/Ubuntu1604-README.md", "direction": "download" }, diff --git a/images/linux/ubuntu1804.json b/images/linux/ubuntu1804.json index aacfe4eea..5f280636d 100644 --- a/images/linux/ubuntu1804.json +++ b/images/linux/ubuntu1804.json @@ -91,6 +91,11 @@ "source": "{{template_dir}}/scripts/installers", "destination": "{{user `installer_script_folder`}}" }, + { + "type": "file", + "source": "{{ template_dir }}/scripts/SoftwareReport", + "destination": "{{user `image_folder`}}" + }, { "type": "file", "source": "{{template_dir}}/toolsets/toolcache-1804.json", @@ -291,9 +296,19 @@ ], "execute_command": "sudo sh -c '{{ .Vars }} {{ .Path }}'" }, + { + "type": "powershell", + "inline": [ + "pwsh -File '{{user `image_folder`}}/SoftwareReport/SoftwareReport.Generator.ps1' -OutputDirectory '{{user `image_folder`}}'" + ], + "environment_vars":[ + "INSTALLER_SCRIPT_FOLDER={{user `installer_script_folder`}}", + "ANNOUNCEMENTS={{user `announcements`}}" + ] + }, { "type": "file", - "source": "{{user `metadata_file`}}", + "source": "{{user `image_folder`}}/Ubuntu-Readme.md", "destination": "{{template_dir}}/Ubuntu1804-README.md", "direction": "download" }, diff --git a/images/linux/ubuntu2004.json b/images/linux/ubuntu2004.json index 17e9143d2..604b863a2 100644 --- a/images/linux/ubuntu2004.json +++ b/images/linux/ubuntu2004.json @@ -93,6 +93,11 @@ "source": "{{template_dir}}/scripts/installers", "destination": "{{user `installer_script_folder`}}" }, + { + "type": "file", + "source": "{{ template_dir }}/scripts/SoftwareReport", + "destination": "{{user `image_folder`}}" + }, { "type": "file", "source": "{{template_dir}}/toolsets/toolcache-2004.json", @@ -293,9 +298,19 @@ ], "execute_command": "sudo sh -c '{{ .Vars }} {{ .Path }}'" }, + { + "type": "powershell", + "inline": [ + "pwsh -File '{{user `image_folder`}}/SoftwareReport/SoftwareReport.Generator.ps1' -OutputDirectory '{{user `image_folder`}}'" + ], + "environment_vars":[ + "INSTALLER_SCRIPT_FOLDER={{user `installer_script_folder`}}", + "ANNOUNCEMENTS={{user `announcements`}}" + ] + }, { "type": "file", - "source": "{{user `metadata_file`}}", + "source": "{{user `image_folder`}}/Ubuntu-Readme.md", "destination": "{{template_dir}}/Ubuntu2004-README.md", "direction": "download" },