mirror of
https://github.com/dfinke/ImportExcel.git
synced 2025-12-06 00:23:20 +00:00
More file moves
This commit is contained in:
@@ -81,8 +81,9 @@ function Invoke-MultiLike {
|
||||
}
|
||||
}
|
||||
|
||||
Push-Location "$PSScriptRoot\.."
|
||||
try {
|
||||
Write-Verbose -Message 'Module installation started'
|
||||
Write-Verbose -Message "Module installation started. Installing from $PWD"
|
||||
|
||||
if (!$ModulePath) {
|
||||
if ($Scope -eq 'CurrentUser') {
|
||||
@@ -99,6 +100,7 @@ try {
|
||||
}
|
||||
$ModulePath = ($env:PSModulePath -split $ModulePathSeparator)[$ModulePathIndex]
|
||||
}
|
||||
Write-Verbose -Message "Installing to $ModulePath"
|
||||
|
||||
# Get $ModuleName, $TargetPath, [$Links]
|
||||
if ($FromGitHub) {
|
||||
@@ -115,8 +117,8 @@ try {
|
||||
$ModuleVersion = (. ([Scriptblock]::Create((Invoke-WebRequest -Uri ($Links | Where-Object { $_.name -eq "$ModuleName.psd1" }).download_url)))).ModuleVersion
|
||||
}
|
||||
else {
|
||||
$ModuleName = [System.IO.Path]::GetFileNameWithoutExtension((Get-ChildItem -File -Filter *.psm1 -Name -Path $PSScriptRoot))
|
||||
$ModuleVersion = (. ([Scriptblock]::Create((Get-Content -Path (Join-Path $PSScriptRoot "$ModuleName.psd1") | Out-String)))).ModuleVersion
|
||||
$ModuleName = [System.IO.Path]::GetFileNameWithoutExtension((Get-ChildItem -File -Filter *.psm1 -Name -Path $PWD))
|
||||
$ModuleVersion = (. ([Scriptblock]::Create((Get-Content -Path (Join-Path $PWD "$ModuleName.psd1") | Out-String)))).ModuleVersion
|
||||
}
|
||||
$TargetPath = Join-Path -Path $ModulePath -ChildPath $ModuleName
|
||||
$TargetPath = Join-Path -Path $TargetPath -ChildPath $ModuleVersion
|
||||
@@ -160,7 +162,7 @@ try {
|
||||
}
|
||||
}
|
||||
else {
|
||||
Get-ChildItem -Path $PSScriptRoot -Exclude $ExcludeFiles | Where-Object { LikeAny $_.Name $IncludeFiles } | ForEach-Object {
|
||||
Get-ChildItem -Path $PWD -Exclude $ExcludeFiles | Where-Object { LikeAny $_.Name $IncludeFiles } | ForEach-Object {
|
||||
if ($_.Attributes -ne 'Directory') {
|
||||
Copy-Item -Path $_ -Destination $TargetPath
|
||||
Write-Verbose -Message ('Installed module file "{0}"' -f $_)
|
||||
@@ -185,4 +187,5 @@ finally {
|
||||
# [Net.ServicePointManager]::SecurityProtocol = $SecurityProtocol
|
||||
#}
|
||||
Write-Verbose -Message 'Module installation end'
|
||||
Pop-Location
|
||||
}
|
||||
236
CI/PS-CI.ps1
Normal file
236
CI/PS-CI.ps1
Normal file
@@ -0,0 +1,236 @@
|
||||
[cmdletbinding(DefaultParameterSetName='Scope')]
|
||||
Param(
|
||||
[Parameter(Mandatory = $true, ParameterSetName = 'ModulePath')]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[String]$ModulePath,
|
||||
|
||||
# Path to install the module to, PSModulePath "CurrentUser" or "AllUsers", if not provided "CurrentUser" used.
|
||||
[Parameter(ParameterSetName = 'Scope')]
|
||||
[ValidateSet('CurrentUser', 'AllUsers')]
|
||||
[string]
|
||||
$Scope = 'CurrentUser',
|
||||
|
||||
[Parameter(Mandatory=$true, ParameterSetName = 'PreCheckOnly')]
|
||||
[switch]$PreCheckOnly,
|
||||
[Parameter(ParameterSetName = 'ModulePath')]
|
||||
[Parameter(ParameterSetName = 'Scope')]
|
||||
[switch]$SkipPreChecks,
|
||||
[Parameter(ParameterSetName = 'ModulePath')]
|
||||
[Parameter(ParameterSetName = 'Scope')]
|
||||
[switch]$SkipPostChecks,
|
||||
[Parameter(ParameterSetName = 'ModulePath')]
|
||||
[Parameter(ParameterSetName = 'Scope')]
|
||||
[switch]$SkipPesterTests,
|
||||
[Parameter(ParameterSetName = 'ModulePath')]
|
||||
[Parameter(ParameterSetName = 'Scope')]
|
||||
[switch]$CleanModuleDir
|
||||
)
|
||||
if ($PSScriptRoot) { Push-Location "$PSScriptRoot\.."}
|
||||
$psdpath = Get-Item "*.psd1"
|
||||
if (-not $psdpath -or $psdpath.count -gt 1) {
|
||||
if ($PSScriptRoot) { Pop-Location }
|
||||
throw "Did not find a unique PSD file "
|
||||
}
|
||||
else {
|
||||
$ModuleName = $psdpath.Name -replace '\.psd1$' , ''
|
||||
$Settings = $(& ([scriptblock]::Create(($psdpath | Get-Content -Raw))))
|
||||
$approvedVerbs = Get-Verb | Select-Object -ExpandProperty verb
|
||||
}
|
||||
|
||||
#pre-build checks - manifest found, files in it found, public functions and aliases loaded in it. Public functions correct.
|
||||
if (-not $SkipPreChecks) {
|
||||
|
||||
#Check files in the manifest are present
|
||||
foreach ($file in $Settings.FileList) {
|
||||
if (-not (Test-Path $file)) {
|
||||
Write-host "##vso[task.logissue type=warning]File $file in the manifest file list is not present" -ForegroundColor yellow
|
||||
}
|
||||
}
|
||||
|
||||
#Check files in public have Approved_verb-noun names and are 1 function using the file name as its name with
|
||||
# its name and any alias names in the manifest; function should have a param block and help should be in an MD file
|
||||
# We will want a regex which captures from "function verb-noun {" to its closing "}"
|
||||
# need to match each { to a } - $reg is based on https://stackoverflow.com/questions/7898310/using-regex-to-balance-match-parenthesis
|
||||
$reg = [Regex]::new(@"
|
||||
function\s*[-\w]+\s*{ # The function name and opening '{'
|
||||
(?:
|
||||
[^{}]+ # Match all non-braces
|
||||
|
|
||||
(?<open> { ) # Match '{', and capture into 'open'
|
||||
|
|
||||
(?<-open> } ) # Match '}', and delete the 'open' capture
|
||||
)*
|
||||
(?(open)(?!)) # Fails if 'open' stack isn't empty
|
||||
} # Functions closing '}'
|
||||
"@, 57) # 57 = compile,multi-line ignore case and white space.
|
||||
$reg2 = [Regex]::new(@"
|
||||
^function\s*[-\w]+\s*{ # The function name and opening '{'
|
||||
(
|
||||
\#.*?[\r\n]+ # single line comment
|
||||
| # or
|
||||
\s*<\#.*?\#> # <#comment block#>
|
||||
| # or
|
||||
\s*\[.*?\] # [attribute tags]
|
||||
)*
|
||||
"@, 57) # 57 = compile, multi-line, ignore case and white space.
|
||||
foreach ($file in (Get-Item .\Public\*.ps1)) {
|
||||
$name = $file.name -replace(".ps1","")
|
||||
if ($name -notmatch ("(\w+)-\w+")) {Write-Host -ForegroundColor yellow "##vso[task.logissue type=Warning]$name in the public folder is not a verb-noun name"}
|
||||
elseif ($Matches[1] -notin $approvedVerbs) {Write-Host -ForegroundColor yellow "##vso[task.logissue type=Warning]$name in the public folder does not start with an approved verb"}
|
||||
if(-not ($Settings.FunctionsToExport -ceq $name)) {
|
||||
Write-Host -ForegroundColor yellow "##vso[task.logissue type=Warning]File $($file.name) in the public folder does not match an exported function in the manifest"
|
||||
}
|
||||
else {
|
||||
$fileContent = Get-Content $file -Raw
|
||||
$m = $reg.Matches($fileContent)
|
||||
if ($m.Count -eq 0) {Write-Host -ForegroundColor yellow "##vso[task.logissue type=Warning]Could not find $name function in $($file.name)"; continue}
|
||||
elseif ($m.Count -ge 2) {Write-Host -ForegroundColor yellow "##vso[task.logissue type=Warning]Multiple functions in $($item.name)"; Continue}
|
||||
elseif ($m[0] -imatch "^\function\s" -and
|
||||
$m[0] -cnotmatch "^\w+\s+$name") {Write-Host -ForegroundColor yellow "##vso[task.logissue type=Warning]function name does not match file name for $($file.name)"}
|
||||
#$m[0] runs form the f of function to its final } -find the section up to param, check for aliases & comment-based help
|
||||
$m2 = [regex]::Match($m[0],"^.*?param",17) # 17 = multi-line, ignnore case
|
||||
if (-not $m2.Success) {Write-Host -ForegroundColor yellow "##vso[task.logissue type=Warning]function $name has no param() block"}
|
||||
else {
|
||||
if ($m2.value -match "\[\s*Alias\(\s*.([\w-]+).\s*\)\s*\]") {
|
||||
foreach ($a in ($Matches[1] -split '\s*,\s*')) {
|
||||
$a = $a -replace "'","" -replace '"',''
|
||||
if (-not ($Settings.AliasesToExport -eq $a)) {
|
||||
Write-Host -ForegroundColor yellow "##vso[task.logissue type=Warning]Function $name has alias $a which is not in the manifest"
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($m2.value -match "\.syopsis|\.Description|\.Example") {
|
||||
Write-Host -ForegroundColor yellow "##vso[task.logissue type=Warning]Function $name appears to have comment based help."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#Warn about functions which are exported but not found in public
|
||||
$notFromPublic = $Settings.FunctionsToExport.where({-not (Test-Path ".\public\$_.ps1")})
|
||||
If ($notFromPublic) {Write-Host -ForegroundColor yellow "##vso[task.logissue type=Warning]Exported function(s) $($notFromPublic -join ', ') are not loaded from Public"}
|
||||
}
|
||||
|
||||
if ($PreCheckOnly) {return}
|
||||
|
||||
#region build, determine module path if necessary, create target directory if necessary, copy files based on manifest, build help
|
||||
try {
|
||||
Write-verbose -verbose -Message 'Module build started'
|
||||
|
||||
if (-not $ModulePath) {
|
||||
if ($IsLinux -or $IsMacOS) {$ModulePathSeparator = ':' }
|
||||
else {$ModulePathSeparator = ';' }
|
||||
|
||||
if ($Scope -eq 'CurrentUser') { $dir = [System.Environment]::GetFolderPath([System.Environment+SpecialFolder]::UserProfile) }
|
||||
else { $dir = [System.Environment]::GetFolderPath([System.Environment+SpecialFolder]::ProgramFiles) }
|
||||
$ModulePath = ($env:PSModulePath -split $ModulePathSeparator).where({$_ -like "$dir*"},"First",1)
|
||||
$ModulePath = Join-Path -Path $ModulePath -ChildPath $ModuleName
|
||||
$ModulePath = Join-Path -Path $ModulePath -ChildPath $Settings.ModuleVersion
|
||||
}
|
||||
|
||||
# Clean-up / Create Directory
|
||||
if (-not (Test-Path -Path $ModulePath)) {
|
||||
$null = New-Item -Path $ModulePath -ItemType Directory -ErrorAction Stop
|
||||
Write-verbose -verbose -Message ('Created module folder: "{0}"' -f $ModulePath)
|
||||
}
|
||||
elseif ($CleanModuleDir) {
|
||||
Write-verbose -verbose "$ModulePath exists - cleaning before copy"
|
||||
Get-ChildItem -Path $ModulePath | Remove-Item -Force -Recurse
|
||||
}
|
||||
Write-verbose -verbose -Message ('Copying files to "{0}"' -f $ModulePath)
|
||||
$outputFile = $psdpath | Copy-Item -Destination $ModulePath -PassThru
|
||||
foreach ($file in $Settings.FileList) {
|
||||
if ($file -like '.\*') {
|
||||
$dest = ($file -replace '\.\\',"$ModulePath\")
|
||||
if (-not (Test-Path -PathType Container (Split-Path -Parent $dest))) {
|
||||
$null = New-item -Type Directory -Path (Split-Path -Parent $dest)
|
||||
}
|
||||
}
|
||||
else {$dest = $ModulePath }
|
||||
Copy-Item -Path $file -Destination $dest -Force -Recurse
|
||||
}
|
||||
|
||||
if (Test-Path -PathType Container "mdHelp") {
|
||||
if (-not (Get-Module -ListAvailable platyPS)) {
|
||||
Write-Verbose -Verbose -Message ('Installing Platyps to build help files')
|
||||
Install-Module -Name platyPS -Force -SkipPublisherCheck
|
||||
}
|
||||
Import-Module platyPS
|
||||
Get-ChildItem .\mdHelp -Directory | ForEach-Object {
|
||||
Write-verbose -verbose "Building help for language '$($_.Name)' "
|
||||
$Null = New-ExternalHelp -Path $_.FullName -OutputPath (Join-Path $ModulePath $_.Name) -Force
|
||||
}
|
||||
}
|
||||
#Leave module path for things which follow.
|
||||
$env:PSNewBuildModule = $ModulePath
|
||||
}
|
||||
catch {
|
||||
if ($PSScriptRoot) { Pop-Location }
|
||||
throw ('Failed installing module "{0}". Error: "{1}" in Line {2}' -f $ModuleName, $_, $_.InvocationInfo.ScriptLineNumber)
|
||||
}
|
||||
finally { Write-verbose -verbose -Message 'Module installation end'
|
||||
if (-not $outputFile -or -not (Test-Path $outputFile)) {
|
||||
throw "Failed to create module"
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
Copy-Item -Path $ModulePath -Destination $env:Build_ArtifactStagingDirectory -Recurse
|
||||
|
||||
|
||||
#Check valid command names, help, run script analyzer over the files in the module directory
|
||||
if (-not $SkipPostChecks) {
|
||||
try {$outputFile | Import-Module -Force -ErrorAction stop }
|
||||
catch {
|
||||
if ($PSScriptRoot) { Pop-Location }
|
||||
throw "New module failed to load"}
|
||||
$commands = Get-Command -Module $ModuleName -CommandType function,Cmdlet
|
||||
$commands.where({$_.name -notmatch "(\w+)-\w+" -or $Matches[1] -notin $approvedVerbs}) | ForEach-Object {
|
||||
Write-Host -ForegroundColor yellow "##vso[task.logissue type=Warning]$($_.name) does not meet the ApprovedVerb-Noun naming rules"
|
||||
}
|
||||
$helpless = $commands | Get-Help | Where-Object {$_.Synopsis -match "^\s+$($_.name)\s+\["} | Select-Object -ExpandProperty name
|
||||
foreach ($command in $helpless ) {
|
||||
Write-Warning -Message "On-line help is missing for $command"
|
||||
}
|
||||
if (-not (Get-Module -Name PSScriptAnalyzer -ListAvailable)) {
|
||||
Install-Module -Name PSScriptAnalyzer -Force
|
||||
}
|
||||
Import-module -Name PSScriptAnalyzer
|
||||
Write-Verbose -Verbose "Running script analyzer against '$ModulePath' "
|
||||
$AnalyzerResults = Invoke-ScriptAnalyzer -Path $ModulePath -Recurse -ErrorAction SilentlyContinue
|
||||
if ($AnalyzerResults) {
|
||||
if (-not (Get-Module -Name ImportExcel -ListAvailable)) {
|
||||
#ironically we use this to build import-excel Shouldn't need this there!
|
||||
Write-Verbose -verbose 'Installing ImportExcel.'
|
||||
Install-Module -Name ImportExcel -Force
|
||||
}
|
||||
$chartDef = New-ExcelChartDefinition -ChartType 'BarClustered' -Column 2 -Title "Script analysis" -LegendBold
|
||||
$ExcelParams = @{
|
||||
Path = "$PWD\ScriptAnalyzer.xlsx"
|
||||
WorksheetName = 'FullResults'
|
||||
TableStyle = 'Medium6'
|
||||
AutoSize = $true
|
||||
Activate = $true
|
||||
PivotTableDefinition = @{BreakDown = @{
|
||||
PivotData = @{RuleName = 'Count' }
|
||||
PivotRows = 'Severity', 'RuleName'
|
||||
PivotTotals = 'Rows'
|
||||
PivotChartDefinition = $chartDef }}
|
||||
}
|
||||
Remove-Item -Path $ExcelParams['Path'] -ErrorAction SilentlyContinue
|
||||
$AnalyzerResults | Export-Excel @ExcelParams
|
||||
Write-Verbose -verbose "Analysis exported to '$($ExcelParams['Path'])'"
|
||||
}
|
||||
}
|
||||
|
||||
#if there are test files, run pester (unless told not to)
|
||||
if (-not $SkipPesterTests -and (Get-ChildItem -Recurse *.tests.ps1)) {
|
||||
Import-Module -Force $outputFile
|
||||
if (-not (Get-Module -ListAvailable pester | Where-Object -Property version -ge ([version]::new(4,4,1)))) {
|
||||
Install-Module Pester -Force -SkipPublisherCheck
|
||||
}
|
||||
Import-Module Pester
|
||||
if ($PSScriptRoot) { Pop-Location }
|
||||
Invoke-Pester -OutputFile ("$PSScriptRoot\..\TestResultsPS{0}.xml" -f $PSVersionTable.PSVersion)
|
||||
}
|
||||
elseif ($PSScriptRoot) { Pop-Location }
|
||||
@@ -10,11 +10,10 @@ param(
|
||||
[ValidateSet('CurrentUser', 'AllUsers')]
|
||||
[string]
|
||||
$Scope = 'CurrentUser',
|
||||
[switch]$Passthru,
|
||||
[switch]$Tests
|
||||
[switch]$Passthru
|
||||
)
|
||||
|
||||
if ($PSScriptRoot) { Push-Location $PSScriptRoot }
|
||||
if ($PSScriptRoot) { Push-Location "$PSScriptRoot\.." }
|
||||
|
||||
$psdpath = Get-Item "*.psd1"
|
||||
if (-not $psdpath -or $psdpath.count -gt 1) {
|
||||
@@ -76,5 +75,6 @@ catch {
|
||||
throw ('Failed installing module "{0}". Error: "{1}" in Line {2}' -f $ModuleName, $_, $_.InvocationInfo.ScriptLineNumber)
|
||||
}
|
||||
finally {
|
||||
if ($PSScriptRoot) { Pop-Location }
|
||||
Write-Verbose -Message 'Module installation end'
|
||||
}
|
||||
89
CI/pipeline.yml
Normal file
89
CI/pipeline.yml
Normal file
@@ -0,0 +1,89 @@
|
||||
# Add steps that build, run tests, deploy, and more:
|
||||
# https://aka.ms/yaml
|
||||
|
||||
trigger:
|
||||
branches:
|
||||
include:
|
||||
- '*'
|
||||
# - master
|
||||
# - releases/*
|
||||
paths:
|
||||
exclude:
|
||||
- README.md
|
||||
- CHANGELOG.md
|
||||
|
||||
jobs:
|
||||
- job: Windows
|
||||
pool:
|
||||
vmImage: 'windows-latest'
|
||||
|
||||
steps:
|
||||
- powershell: 'Install-Module -Name Pester,PlatyPS,platyPS,PSScriptAnalyzer -Force -SkipPublisherCheck'
|
||||
displayName: 'Update Modules'
|
||||
- powershell: './CI/CI.ps1 -Test'
|
||||
displayName: 'Check Build Check Pack Test'
|
||||
|
||||
- task: PublishTestResults@2
|
||||
inputs:
|
||||
testResultsFormat: 'NUnit'
|
||||
testResultsFiles: '**/TestResults*.xml'
|
||||
failTaskOnFailedTests: true
|
||||
|
||||
- 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'
|
||||
|
||||
- job: WindowsPSCore
|
||||
pool:
|
||||
vmImage: 'windows-latest'
|
||||
|
||||
steps:
|
||||
- pwsh: 'Install-Module -Name Pester -Force'
|
||||
displayName: 'Update Pester'
|
||||
- pwsh: './CI/CI.ps1 -Test'
|
||||
displayName: 'Install and Test'
|
||||
|
||||
- task: PublishTestResults@2
|
||||
inputs:
|
||||
testResultsFormat: 'NUnit'
|
||||
testResultsFiles: '**/TestResults*.xml'
|
||||
failTaskOnFailedTests: true
|
||||
|
||||
- job: Ubuntu
|
||||
pool:
|
||||
vmImage: 'ubuntu-latest'
|
||||
|
||||
steps:
|
||||
- powershell: 'Install-Module -Name Pester -Force'
|
||||
displayName: 'Update Pester'
|
||||
- powershell: './CI/CI.ps1 -Test'
|
||||
displayName: 'Install and Test'
|
||||
|
||||
- task: PublishTestResults@2
|
||||
inputs:
|
||||
testResultsFormat: 'NUnit'
|
||||
testResultsFiles: '**/TestResults*.xml'
|
||||
failTaskOnFailedTests: true
|
||||
|
||||
- job: macOS
|
||||
pool:
|
||||
vmImage: 'macOS-latest'
|
||||
|
||||
steps:
|
||||
- script: brew install mono-libgdiplus
|
||||
displayName: 'Install mono-libgdiplus'
|
||||
- powershell: 'Install-Module -Name Pester -Force'
|
||||
displayName: 'Update Pester'
|
||||
- powershell: './CI/CI.ps1 -Test'
|
||||
displayName: 'Install and Test'
|
||||
|
||||
- task: PublishTestResults@2
|
||||
inputs:
|
||||
testResultsFormat: 'NUnit'
|
||||
testResultsFiles: '**/TestResults*.xml'
|
||||
failTaskOnFailedTests: true
|
||||
@@ -153,6 +153,7 @@ Check out the How To Videos https://www.youtube.com/watch?v=U3Ne_yX4tYo&list=PL5
|
||||
'.\ImportExcel.psm1',
|
||||
'.\LICENSE.txt',
|
||||
'.\README.md',
|
||||
'.\Plot.ps1'
|
||||
'.\en\ImportExcel-help.xml',
|
||||
'.\en\Strings.psd1',
|
||||
'.\Charting\Charting.ps1',
|
||||
|
||||
@@ -7,11 +7,11 @@ if (-not $Strings) {
|
||||
try {[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")}
|
||||
catch {Write-Warning -Message $Strings.SystemDrawingAvaialable}
|
||||
|
||||
foreach ($directory in @('Public','Charting','InferData','Pivot')) {
|
||||
foreach ($directory in @('Private', 'Public','Charting','InferData','Pivot')) {
|
||||
Get-ChildItem -Path "$PSScriptRoot\$directory\*.ps1" | ForEach-Object {. $_.FullName}
|
||||
}
|
||||
|
||||
. $PSScriptRoot\ArgumentCompletion.ps1
|
||||
# . $PSScriptRoot\ArgumentCompletion.ps1
|
||||
|
||||
if ($PSVersionTable.PSVersion.Major -ge 5) {
|
||||
. $PSScriptRoot\Plot.ps1
|
||||
|
||||
Reference in New Issue
Block a user