src/ConvertTo-Encoding.psm1
|
using namespace System.Diagnostics.CodeAnalysis using namespace System.IO using namespace System.Text <# .SYNOPSIS The list of binary file extensions. #> $BinaryExtensions = @() <# .SYNOPSIS The list of text file extensions. #> $TextExtensions = @() <# .SYNOPSIS Converts the encoding of input files. .PARAMETER Path The path to the files to convert. .PARAMETER LiteralPath The path to the files to convert. .PARAMETER To The destination encoding. .PARAMETER Exclude The list of folders to exclude from the processing. .PARAMETER Recurse Value indicating whether to process the input path recursively. .INPUTS A string that contains a path, but not a literal path. #> function ConvertTo-Encoding { [CmdletBinding(DefaultParameterSetName = "Path")] [OutputType([void])] [SuppressMessage("PSUseOutputTypeCorrectly", "")] param ( [Parameter(Mandatory, ParameterSetName = "Path", Position = 0, ValueFromPipeline)] [SupportsWildcards()] [string[]] $Path, [Parameter(Mandatory, ParameterSetName = "LiteralPath")] [ValidateScript({ Test-Path $_ -IsValid }, ErrorMessage = "The specified literal path is invalid.")] [string[]] $LiteralPath, [Parameter(Mandatory)] [ValidateSet("Latin1", "UTF-8")] [string] $Encoding, [ValidateNotNull()] [string[]] $Exclude = @(".git", "node_modules", "ps_modules", "vendor"), [Parameter()] [switch] $Recurse ) begin { if (-not $Script:BinaryExtensions) { $Script:BinaryExtensions = Get-Content "$PSScriptRoot/../res/BinaryExtensions.json" | ConvertFrom-Json } if (-not $Script:TextExtensions) { $Script:TextExtensions = Get-Content "$PSScriptRoot/../res/TextExtensions.json" | ConvertFrom-Json } } process { $sourceEncoding = [Encoding]::GetEncoding($Encoding -eq "Latin1" ? "UTF-8" : "Latin1") $destinationEncoding = [Encoding]::GetEncoding($Encoding) $parameters = @{ File = $true; Recurse = $Recurse } $files = $PSCmdlet.ParameterSetName -eq "LiteralPath" ? (Get-ChildItem -LiteralPath $LiteralPath @parameters) : (Get-ChildItem $Path @parameters) foreach ($file in $files) { if (Test-IsExcluded $file -Exclude $Exclude) { continue } $extension = Split-Path $file.Name -Extension $isBinary = $extension -and ($extension.Substring(1) -in $Script:BinaryExtensions) if ($isBinary) { continue } $bytes = Get-Content $file.FullName -AsByteStream if (-not $bytes) { continue } $isText = $extension -and ($extension.Substring(1) -in $Script:TextExtensions) if ((-not $isText) -and ([Array]::IndexOf[byte]($bytes, 0, 0, [Math]::Min($bytes.Count, 8000)) -gt 0)) { continue } "Converting: $file" Set-Content $file.FullName ([Encoding]::Convert($sourceEncoding, $destinationEncoding, $bytes)) -AsByteStream } } } <# .SYNOPSIS Checks if the specified file should be excluded from the processing. .PARAMETER File The file to be checked. .PARAMETER Exclude The list of folders to exclude from the processing. .OUTPUTS `$true` if the specified file should be excluded from the processing, otherwise `$false`. #> function Test-IsExcluded { [OutputType([bool])] param ( [Parameter(Mandatory, Position = 0, ValueFromPipeline)] [FileInfo] $File, [ValidateNotNull()] [string[]] $Exclude = @(".git", "node_modules", "ps_modules", "vendor") ) process { $directory = $file.Directory while ($directory) { if ($directory.Name -in $Exclude) { return $true } $directory = $directory.Parent } $false } } |