functions/HelperFunctions.psm1
<#
.SYNOPSIS Restore NPM, Nuget, and/or Libman packages within this directory or sub-directories .PARAMETER NPM Restore NPM packages .PARAMETER Nuget Restore Nuget packages .PARAMETER Libman Restore Libman packages #> Function Restore-WorkspacePackages { [Alias('rwp')] [CmdletBinding(DefaultParameterSetName = "Default")] Param ( [Parameter(ParameterSetName = "NPM", HelpMessage = "Restore only NPM packages")] [switch]$NPM, [Parameter(ParameterSetName = "Nuget", HelpMessage = "Restore only Nuget packages")] [switch]$Nuget, [Parameter(ParameterSetName = "Libman", HelpMessage = "Restore only Library Manager packages")] [switch]$Libman ) DynamicParam { $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary if ($NPM) { $cleanSlateAttribute = New-Object System.Management.Automation.ParameterAttribute $cleanSlateAttribute.Position = 1 $cleanSlateAttribute.Mandatory = $false $cleanSlateAttribute.HelpMessage = "Installs NPM packages with a clean slate" $attributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute] $attributeCollection.Add($cleanSlateAttribute) $cleanSlateParam = New-Object System.Management.Automation.RuntimeDefinedParameter('CI', [switch], $attributeCollection) $paramDictionary.Add('CI', $cleanSlateParam) } return $paramDictionary } Process { $restoreNpm = -not ($null -eq (Get-Command npm -ErrorAction SilentlyContinue)) $restoreDotnet = -not ($null -eq (Get-Command dotnet -ErrorAction SilentlyContinue)) $restoreLibman = -not ($null -eq (Get-Command libman -ErrorAction SilentlyContinue)) if ($restoreNpm -and ($PSCmdlet.ParameterSetName -eq "Default" -or $PSCmdlet.ParameterSetName -eq "NPM")) { Write-Host "Restoring NPM packages" -NoNewLine $children = Get-ChildItem -Filter package.json -Recurse | Where-Object Directory -NotLike "*node_module*" Write-Host (": Found {0} NPM projects" -f $children.Count) -ForegroundColor Yellow $children | ForEach-Object { Write-Host "- Restoring $($_.Directory)..." -ForegroundColor Yellow Push-Location $_.Directory if ($PSBoundParameters.ContainsKey("CI")) { Write-Host "Cleaning Slate..." npm ci } else { npm install } Pop-Location } } if ($restoreDotnet -and ($PSCmdlet.ParameterSetName -eq "Default" -or $PSCmdlet.ParameterSetName -eq "Nuget")) { Write-Host "Restoring NuGet packages" Get-ChildItem -Filter *.*proj -Recurse | ForEach-Object { Write-Host "- Restoring $($_.Directory)..." -ForegroundColor Yellow Push-Location $_.Directory dotnet restore Pop-Location } } if ($restoreLibman -and ($PSCmdlet.ParameterSetName -eq "Default" -or $PSCmdlet.ParameterSetName -eq "Libman")) { Write-Host "Restoring Libman packages" Get-ChildItem -Filter libman.json -Recurse | ForEach-Object { Write-Host "- Restoring $($_.Directory)..." -ForegroundColor Yellow Push-Location $_.Directory libman restore Pop-Location } } } } Function Get-Syntax { [CmdletBinding()] [Alias('Syntax')] param ( [Parameter(Mandatory)] $Command, [switch] [Alias('Normalize', 'Horizontal')] $Normalise ) $check = Get-Command -Name $Command $params = @{ Name = if ($check.CommandType -eq 'Alias') { Get-Command -Name $check.Definition } else { $Command } Syntax = $true } if ($Normalise) { Get-Command @params } else { (Get-Command @params) -replace '(\s(?=\[)|\s(?=-))', "`r`n " } } Function Invoke-ReverseSort { [Alias("Sort-Reverse")] # Sort is not an approved verb... Not sure of better one that is an approved verb. Will just leave this comment with link for future reference: https://github.com/PowerShell/PowerShell/issues/3370 $rank = [int]::MaxValue $input | Sort-Object { (--(Get-Variable rank -Scope 1).Value) } } <# .SYNOPSIS Opens the Windows hosts file in an editor. #> Function Edit-HostsFile { [Alias('hosts')] [CmdletBinding()] Param() # TO CONSIDER: Should we take a # Make sure we're on Windows... if ($PSVersionTable.PSVersion.Major -lt 6 -or $IsWindows) { # Default editor to notepad.exe $fileEditor = 'notepad' # Find code if it exists. Giving preference to Stable code over insiders. if (Get-Command code -ErrorAction SilentlyContinue) { $fileEditor = 'code' } elseif (Get-Command code-insiders -ErrorAction SilentlyContinue) { $fileEditor = 'code-insiders' } # Use Start-Process to ensure that we're elevated. If already elevated, will not reprompt. Start-Process -FilePath $fileEditor -ArgumentList "C:\Windows\System32\drivers\etc\hosts" -Verb RunAs } } <# .SYNOPSIS Check to see if the current user is an administrator #> Function Test-PSHostHasAdministrator { [Alias("IsAdmin")] param() $p = New-Object System.Security.Principal.WindowsPrincipal([System.Security.Principal.WindowsIdentity]::GetCurrent()) if ($p.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)) { return $true } else { return $false } return $false } Function Restart-PSHost { # [Alias("Reload")] [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')] param ( [switch]$AsAdministrator, [switch]$Force ) $proc = Get-Process -Id $PID $cmdArgs = [Environment]::GetCommandLineArgs() | Select-Object -Skip 1 $params = @{FilePath = $proc.Path } if ($AsAdministrator) { $params.Verb = 'runas' } if ($cmdArgs) { $params.ArgumentList = $cmdArgs } if ($Force -or $PSCmdlet.ShouldProcess($proc.Name, "Restart the console")) { if ($host.Name -eq 'Windows PowerShell ISE Host' -and $psISE.PowerShellTabs.Files.IsSaved -contains $false) { if ($Force -or $PSCmdlet.ShouldProcess('Unsaved work detected?', 'Unsaved work detected. Save changes?', 'Confirm')) { foreach ($IseTab in $psISE.PowerShellTabs) { $IseTab.Files | ForEach-Object { if ($_.IsUntitled -and !$_.IsSaved) { $_.SaveAs($_.FullPath, [System.Text.Encoding]::UTF8) } elseif (!$_.IsSaved) { $_.Save() } } } } else { foreach ($IseTab in $psISE.PowerShellTabs) { $unsavedFiles = $IseTab.Files | Where-Object IsSaved -eq $false $unsavedFiles | ForEach-Object { $IseTab.Files.Remove($_, $true) } } } } Start-Process @params $proc.CloseMainWindow() } } Function Out-Menu { [Alias("menu")] param( [Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [object[]]$Object, [string]$Header, [string]$Footer, [switch]$AllowCancel, [switch]$AllowMultiple ) if ($input) { $Object = @($input) } Write-Host "" do { $prompt = New-Object System.Text.StringBuilder switch ($true) { { [bool]$Header -and $Header -notmatch '^(?:\s+)?$' } { $null = $prompt.Append($Header); break } $true { $null = $prompt.Append('Choose an option:') } $AllowCancel { $null = $prompt.Append(', or enter "c" to cancel.') } $AllowMultiple { $null = $prompt.Append('`nTo select multiple, enter numbers separated by a comma. EX: 1, 2') } } Write-Host $prompt.ToString() $nums = $Object.Count.ToString().Length for ($i = 0; $i -lt $Object.Count; $i++) { Write-Host "$("{0:D$nums}" -f ($i+1)). $($Object[$i])" } if ($Footer) { if ($Footer.EndsWith(".")) { $Footer = $Footer.Replace(".",":") } Write-Host $Footer " " -NoNewLine } if ($AllowMultiple) { $answers = @(Read-Host).Split(",").Trim() if ($AllowCancel -and $answers -match 'c') { return } $ok = $true foreach ($ans in $answers) { if ($ans -in 1..$Object.Count) { $Object[$ans - 1] } else { Write-Host "Not an option!" -ForegroundColor Red Write-Host "" $ok = $false } } } else { $answer = Read-Host if ($AllowCancel -and $answer -eq 'c') { return } $ok = $true if ($answer -in 1..$Object.Count) { $Object[$answer - 1] } else { Write-Host "Not an option!" -ForegroundColor Red Write-Host "" $ok = $false } } } while (-not $ok) } |