diff --git a/.gitignore b/.gitignore index a50db38..3e6f133 100644 --- a/.gitignore +++ b/.gitignore @@ -63,5 +63,5 @@ ImportExcel.zip .vscode/settings.json ~$* -InstallModule.ps1 -PublishToGallery.ps1 +# InstallModule.ps1 +# PublishToGallery.ps1 diff --git a/__tests__/CI.ps1 b/CI/CI.ps1 similarity index 71% rename from __tests__/CI.ps1 rename to CI/CI.ps1 index 5a0e6c5..43b92ce 100644 --- a/__tests__/CI.ps1 +++ b/CI/CI.ps1 @@ -11,7 +11,9 @@ param # AppVeyor Only - Upload results to AppVeyor "Tests" tab. [Switch]$Finalize, # AppVeyor and Azure - Upload module as AppVeyor Artifact. - [Switch]$Artifact + [Switch]$Artifact, + # Azure - Runs PsScriptAnalyzer against one or more folders and pivots the results to form a report. + [Switch]$Analyzer ) $ErrorActionPreference = 'Stop' if ($Initialize) { @@ -139,4 +141,68 @@ if ($Artifact) { #Write-Host "##vso[task.setvariable variable=ModuleName]$ModuleName" Copy-Item -Path $ModulePath -Destination $env:Build_ArtifactStagingDirectory -Recurse } +} +if ($Analyzer) { + if (!(Get-Module -Name PSScriptAnalyzer -ListAvailable)) { + '[Progress] Installing PSScriptAnalyzer.' + Install-Module -Name PSScriptAnalyzer -Force + } + + if ($env:System_PullRequest_TargetBranch) { + '[Progress] Get target branch.' + $TempGitClone = Join-Path ([IO.Path]::GetTempPath()) (New-Guid) + Copy-Item -Path $PWD -Destination $TempGitClone -Recurse + (Get-Item (Join-Path $TempGitClone '.git')).Attributes += 'Hidden' + "[Progress] git clean." + git -C $TempGitClone clean -f + "[Progress] git reset." + git -C $TempGitClone reset --hard + "[Progress] git checkout." + git -C $TempGitClone checkout -q $env:System_PullRequest_TargetBranch + + $DirsToProcess = @{ 'Pull Request' = $PWD ; $env:System_PullRequest_TargetBranch = $TempGitClone } + } + else { + $DirsToProcess = @{ 'GitHub' = $PWD } + } + + "[Progress] Running Script Analyzer." + $AnalyzerResults = $DirsToProcess.GetEnumerator() | ForEach-Object { + $DirName = $_.Key + Write-Verbose "[Progress] Running Script Analyzer on $DirName." + Invoke-ScriptAnalyzer -Path $_.Value -Recurse -ErrorAction SilentlyContinue | + Add-Member -MemberType NoteProperty -Name Location -Value $DirName -PassThru + } + + if ($AnalyzerResults) { + if (!(Get-Module -Name ImportExcel -ListAvailable)) { + '[Progress] Installing ImportExcel.' + Install-Module -Name ImportExcel -Force + } + '[Progress] Creating ScriptAnalyzer.xlsx.' + $ExcelParams = @{ + Path = 'ScriptAnalyzer.xlsx' + WorksheetName = 'FullResults' + Now = $true + Activate = $true + Show = $false + } + $PivotParams = @{ + PivotTableName = 'BreakDown' + PivotData = @{RuleName = 'Count' } + PivotRows = 'Severity', 'RuleName' + PivotColumns = 'Location' + PivotTotals = 'Rows' + } + Remove-Item -Path $ExcelParams['Path'] -ErrorAction SilentlyContinue + + $PivotParams['PivotChartDefinition'] = New-ExcelChartDefinition -ChartType 'BarClustered' -Column (1 + $DirsToProcess.Count) -Title "Script analysis" -LegendBold + $ExcelParams['PivotTableDefinition'] = New-PivotTableDefinition @PivotParams + + $AnalyzerResults | Export-Excel @ExcelParams + '[Progress] Analyzer finished.' + } + else { + "[Info] Invoke-ScriptAnalyzer didn't return any problems." + } } \ No newline at end of file diff --git a/__tests__/InstallPowerShell.ps1 b/CI/InstallPowerShell.ps1 similarity index 100% rename from __tests__/InstallPowerShell.ps1 rename to CI/InstallPowerShell.ps1 diff --git a/__tests__/Publish.ps1 b/CI/Publish.ps1 similarity index 96% rename from __tests__/Publish.ps1 rename to CI/Publish.ps1 index 625d5bf..61fc671 100644 --- a/__tests__/Publish.ps1 +++ b/CI/Publish.ps1 @@ -2,6 +2,7 @@ .SYNOPSIS Deploy module to PowerShellGallery. #> +[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseDeclaredVarsMoreThanAssignments", "Success")] [CmdletBinding(DefaultParameterSetName = 'ModuleName')] Param ( diff --git a/Get-ExcelColumnName.ps1 b/Get-ExcelColumnName.ps1 index 7562391..a71ef10 100644 --- a/Get-ExcelColumnName.ps1 +++ b/Get-ExcelColumnName.ps1 @@ -6,10 +6,15 @@ function Get-ExcelColumnName { Process { $dividend = $columnNumber - $columnName = @() + $columnName = New-Object System.Collections.ArrayList($null) + while($dividend -gt 0) { $modulo = ($dividend - 1) % 26 - $columnName += [char](65 + $modulo) + if ($columnName.length -eq 0) { + [char](65 + $modulo) + } else { + $columnName.insert(0,[char](65 + $modulo)) + } $dividend = [int](($dividend -$modulo)/26) } @@ -19,4 +24,4 @@ function Get-ExcelColumnName { } } -} \ No newline at end of file +} diff --git a/InstallModule.ps1 b/InstallModule.ps1 new file mode 100644 index 0000000..d217c5f --- /dev/null +++ b/InstallModule.ps1 @@ -0,0 +1,3 @@ +$fullPath = 'C:\Program Files\WindowsPowerShell\Modules\ImportExcel' + +Robocopy . $fullPath /mir /XD .vscode .git examples data /XF appveyor.yml azure-pipelines.yml .gitattributes .gitignore \ No newline at end of file diff --git a/PublishToGallery.ps1 b/PublishToGallery.ps1 new file mode 100644 index 0000000..0b55bd1 --- /dev/null +++ b/PublishToGallery.ps1 @@ -0,0 +1,6 @@ +$p = @{ + Name = "ImportExcel" + NuGetApiKey = $NuGetApiKey +} + +Publish-Module @p \ No newline at end of file diff --git a/README.md b/README.md index b608c65..e5f7f52 100644 --- a/README.md +++ b/README.md @@ -52,9 +52,29 @@ Install-Module ImportExcel -scope CurrentUser Install-Module ImportExcel ``` +# Continuous Integration Updates + +Big thanks to [Illy](https://github.com/ili101) for taking the Azure DevOps CI to the next level. Improved badges, improved matrix for cross platform OS testing and more. + +Plus, wiring the [PowerShell ScriptAnalyzer Excel report](https://github.com/dfinke/ImportExcel/pull/590#issuecomment-488659081) we built into each run as an artifact. + +![](./images/ScriptAnalyzerReport.png) + # What's new 6.5.2 -- Added the example ReadAllSheets.ps1 based on the thread https://github.com/dfinke/ImportExcel/issues/678 +Thank you [uSlackr](https://github.com/uSlackr)ill +- Fixes Column order issue (plus tests) for `Get-ExcelColumnName` + +Thank you [jhoneill](https://github.com/jhoneill) +- Added -Force to Send-SQLDataToExcel so it sends something even if no rows are returned. (see [#703](https://github.com/dfinke/ImportExcel/issues/703)) +- Added -asText to import-Excel see (#164)[https://github.com/dfinke/ImportExcel/issues/164] and multiple others +- Linux. Now set an environment variable if the support needed for Autosize is present, and use that Environment variable to decide to skip autosize operations. +- Fixed tests which needed autosize to work so they skip of the environment variable is set. +- Fixed another break where on azure the module never loaded. +- Add a comment to ci.ps1 re better .NET version detection and left some commented out code. + +Other +- Added the example [ReadAllSheets.ps1](https://github.com/dfinke/ImportExcel/tree/master/Examples/ReadAllSheets) based on this thread https://github.com/dfinke/ImportExcel/issues/678 # What's new 6.5.0 diff --git a/__tests__/Get-ExcelColumnName.Test.ps1 b/__tests__/Get-ExcelColumnName.Test.ps1 new file mode 100644 index 0000000..295ab83 --- /dev/null +++ b/__tests__/Get-ExcelColumnName.Test.ps1 @@ -0,0 +1,29 @@ +$map = @{ + 1024 = 'AMJ' + 2048 = 'BZT' + 3072 = 'DND' + 4096 = 'FAN' + 5120 = 'GNX' + 6144 = 'IBH' + 7168 = 'JOR' + 8192 = 'LCB' + 9216 = 'MPL' + 10240 = 'OCV' + 11264 = 'PQF' + 12288 = 'RDP' + 13312 = 'SQZ' + 14336 = 'UEJ' + 15360 = 'VRT' + 16384 = 'XFD' +} + +(Get-ExcelColumnName 26).columnName | Should be 'Z' +(Get-ExcelColumnName 27).columnName | Should be 'AA' +(Get-ExcelColumnName 28).columnNamee | Should be 'AB' +(Get-ExcelColumnName 30).columnName | Should be 'AD' +(Get-ExcelColumnName 48).columnName | Should be 'AV' + +1..16 | ForEach-Object { + $number = $_ * 1024 + (Get-ExcelColumnName $number).columnName | Should be $map.$number +} diff --git a/appveyor.yml b/appveyor.yml index 47012cc..fde5af1 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -28,20 +28,20 @@ install: - ps: 'Install-Module -Name Pester -Force -SkipPublisherCheck' - ps: 'Install-Module -Name Assert -Force' # PowerShell Core - - ps: '& .\__tests__\InstallPowerShell.ps1 -Version "7.0.0-preview.3"' # Install other PowerShell Core version (Optional) + - ps: '& .\CI\InstallPowerShell.ps1 -Version "7.0.0-preview.4"' # Install other PowerShell Core version (Optional) - pwsh: 'Install-Module -Name Pester -Force' - pwsh: 'Install-Module -Name Assert -Force' # To run your custom scripts instead of automatic tests test_script: - - ps: '& .\__tests__\CI.ps1 -Test' - - pwsh: '& .\__tests__\CI.ps1 -Test' - - ps: '& .\__tests__\CI.ps1 -Finalize' # Collect and upload results + - ps: '& .\CI\CI.ps1 -Test' + - pwsh: '& .\CI\CI.ps1 -Test' + - ps: '& .\CI\CI.ps1 -Finalize' # Collect and upload results # Deploy deploy_script: - - ps: '& .\__tests__\CI.ps1 -Artifact' - #- ps: '$null = Install-PackageProvider -Name NuGet -Force ; & .\__tests__\Publish.ps1' + - ps: '& .\CI\CI.ps1 -Artifact' + - ps: '$null = Install-PackageProvider -Name NuGet -Force ; & .\CI\Publish.ps1' # Linux setup for: @@ -55,13 +55,13 @@ for: - sh: 'export LANG=en_US.UTF-8' # Fix for PowerShell 7.0.0-preview.2, Remove if using other version. # Scripts that run after cloning repository install: - - pwsh: '& .\__tests__\CI.ps1 -Initialize' # Set AppVeyor build version + - pwsh: '& .\CI\CI.ps1 -Initialize' # Set AppVeyor build version - pwsh: 'Install-Module -Name Pester -Force' - pwsh: 'Install-Module -Name Assert -Force' # To run your custom scripts instead of automatic tests test_script: - - pwsh: '& .\__tests__\CI.ps1 -Test' - - pwsh: '& .\__tests__\CI.ps1 -Finalize' # Collect and upload results + - pwsh: '& .\CI\CI.ps1 -Test' + - pwsh: '& .\CI\CI.ps1 -Finalize' # Collect and upload results # Skip Deploy deploy_script: - pwsh: '"Deploy skiped on Linux."' \ No newline at end of file diff --git a/azure-pipelines.yml b/azure-pipelines.yml index c125bce..e48d3c2 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -22,7 +22,7 @@ jobs: steps: - powershell: 'Install-Module -Name Pester -Force -SkipPublisherCheck' displayName: 'Update Pester' - - powershell: './__tests__/CI.ps1 -Test' + - powershell: './CI/CI.ps1 -Test' displayName: 'Install and Test' - task: PublishTestResults@2 @@ -31,12 +31,14 @@ jobs: testResultsFiles: '**/TestResults*.xml' failTaskOnFailedTests: true - - powershell: './__tests__/CI.ps1 -Artifact' + - powershell: './CI/CI.ps1 -Artifact' displayName: 'Prepare Artifact' - task: PublishPipelineArtifact@1 inputs: targetPath: '$(Build.ArtifactStagingDirectory)' artifact: 'Modules' + - powershell: './CI/CI.ps1 -Analyzer' + displayName: 'Invoke ScriptAnalyzer' - task: PublishPipelineArtifact@1 inputs: targetPath: '$(Build.SourcesDirectory)' @@ -49,7 +51,7 @@ jobs: steps: - pwsh: 'Install-Module -Name Pester -Force' displayName: 'Update Pester' - - pwsh: './__tests__/CI.ps1 -Test' + - pwsh: './CI/CI.ps1 -Test' displayName: 'Install and Test' - task: PublishTestResults@2 @@ -65,7 +67,7 @@ jobs: steps: - powershell: 'Install-Module -Name Pester -Force' displayName: 'Update Pester' - - powershell: './__tests__/CI.ps1 -Test' + - powershell: './CI/CI.ps1 -Test' displayName: 'Install and Test' - task: PublishTestResults@2 @@ -83,7 +85,7 @@ jobs: displayName: 'Install mono-libgdiplus' - powershell: 'Install-Module -Name Pester -Force' displayName: 'Update Pester' - - powershell: './__tests__/CI.ps1 -Test' + - powershell: './CI/CI.ps1 -Test' displayName: 'Install and Test' - task: PublishTestResults@2 diff --git a/images/ScriptAnalyzerReport.png b/images/ScriptAnalyzerReport.png new file mode 100644 index 0000000..6e430d6 Binary files /dev/null and b/images/ScriptAnalyzerReport.png differ