Skip to content

Commit

Permalink
🐛 Adds Platform Guards Around UnixFileMode Enum
Browse files Browse the repository at this point in the history
The UnixFileMode enum type is not defined before PowerShell 7.3 and/or .NET 7, (which our GitHub runners don't have yet.)
  • Loading branch information
brucificus committed Dec 6, 2023
1 parent 59cae0e commit cc8aac5
Show file tree
Hide file tree
Showing 4 changed files with 192 additions and 45 deletions.
115 changes: 73 additions & 42 deletions src/ConvertTo-NixMode.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -3,56 +3,87 @@ $ErrorActionPreference = "Stop"
Set-StrictMode -Version Latest


<#
.SYNOPSIS
Converts a value to a strongly-typed [System.IO.UnixFileMode] enum value.
.DESCRIPTION
Converts a value to a strongly-typed [System.IO.UnixFileMode] enum value.
.EXAMPLE
ConvertTo-NixMode -FromOctal 755
#>
function ConvertTo-NixMode() {
[CmdletBinding()]
[OutputType([System.IO.UnixFileMode])]
param(
[Parameter(Mandatory = $true, Position = 0, ParameterSetName = 'FromOctal')]
[ValidateNotNullOrEmpty()]
[string] $FromOctal,
if ([Type]::GetType("System.IO.UnixFileMode")) {
<#
.SYNOPSIS
Converts a value to a strongly-typed [System.IO.UnixFileMode] enum value.
.DESCRIPTION
Converts a value to a strongly-typed [System.IO.UnixFileMode] enum value.
.EXAMPLE
ConvertTo-NixMode -FromOctal 755
#>
function ConvertTo-NixMode() {
[System.Runtime.Versioning.SupportedOSPlatform("net7.0")]
[CmdletBinding()]
[OutputType([System.IO.UnixFileMode])]
param(
[Parameter(Mandatory = $true, Position = 0, ParameterSetName = 'FromOctal')]
[ValidateNotNullOrEmpty()]
[string] $FromOctal,

[Parameter(Mandatory = $true, Position = 0, ParameterSetName = 'FromDecimal')]
[ValidateNotNullOrEmpty()]
[int] $FromDecimal
)
Begin {
function Factor-EnumValue() {
[OutputType([System.IO.UnixFileMode])]
param(
[Parameter(Mandatory = $true)]
[int]
$Value
)
$value = [int]$Value
$result = [System.IO.UnixFileMode]::None
[Parameter(Mandatory = $true, Position = 0, ParameterSetName = 'FromDecimal')]
[ValidateNotNullOrEmpty()]
[int] $FromDecimal
)
Begin {
function Factor-EnumValue() {
[OutputType([System.IO.UnixFileMode])]
param(
[Parameter(Mandatory = $true)]
[int]
$Value
)
$value = [int]$Value
$result = [System.IO.UnixFileMode]::None

foreach ($enumValue in [System.Enum]::GetValues([System.IO.UnixFileMode])) {
if (($value -band $enumValue) -eq $enumValue) {
$result = $result -bor $enumValue
$value = $value -bxor $enumValue
foreach ($enumValue in [System.Enum]::GetValues([System.IO.UnixFileMode])) {
if (($value -band $enumValue) -eq $enumValue) {
$result = $result -bor $enumValue
$value = $value -bxor $enumValue
}
}

if ($value -ne 0) {
throw [System.ArgumentException]::new("Unable to interpret value '$FromDecimal' as a value of [System.IO.UnixFileMode].")
} else {
return $result
}
}

if ($value -ne 0) {
throw [System.ArgumentException]::new("Unable to interpret value '$FromDecimal' as a value of [System.IO.UnixFileMode].")
} else {
return $result
if ($FromOctal) {
$FromDecimal = [Convert]::ToInt32($FromOctal, 8)
}
}

if ($FromOctal) {
$FromDecimal = [Convert]::ToInt32($FromOctal, 8)
Process {
return (Factor-EnumValue $FromDecimal)
}
}
Process {
return (Factor-EnumValue $FromDecimal)
} else {
<#
.SYNOPSIS
Converts a value to a strongly-typed [System.IO.UnixFileMode] enum value.
.DESCRIPTION
Converts a value to a strongly-typed [System.IO.UnixFileMode] enum value.
.EXAMPLE
ConvertTo-NixMode -FromOctal 755
#>
function ConvertTo-NixMode() {
[System.Runtime.Versioning.SupportedOSPlatform("net7.0")]
[CmdletBinding()]
# [OutputType([System.IO.UnixFileMode])]
param(
[Parameter(Mandatory = $true, Position = 0, ParameterSetName = 'FromOctal')]
[ValidateNotNullOrEmpty()]
[string] $FromOctal,

[Parameter(Mandatory = $true, Position = 0, ParameterSetName = 'FromDecimal')]
[ValidateNotNullOrEmpty()]
[int] $FromDecimal
)
Begin {
throw [System.PlatformNotSupportedException]::new()
}
Process {
}
}
}
26 changes: 24 additions & 2 deletions src/Set-ItemNixMode.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,38 @@ Set-StrictMode -Version Latest

if ($IsLinux) {
function Set-ItemNixMode() {
[System.Runtime.Versioning.UnsupportedOSPlatform("windows")]
param(
[Parameter(Mandatory = $true)]
[string[]]
$Path,

[Parameter(Mandatory = $true)]
[ValidateScript({ ConvertTo-NixMode -FromOctal $_ })]
# [ValidateScript({ ConvertTo-NixMode -FromOctal $_ })]
[string] $ModeOctal
)
Get-Item $Path | ForEach-Object { chmod $ModeOctal $_.FullName } | Out-Null
DynamicParam {
# Add the ValidateScript attribute to the ModeOctal parameter, but
# only if the UnixFileMode type is available.
if ([Type]::GetType("System.IO.UnixFileMode")) {
$Attribute = [System.Management.Automation.ValidateScriptAttribute]::new(
[ScriptBlock]::Create("ConvertTo-NixMode -FromOctal $_")
)
$RuntimeParameterDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new()
$RuntimeParameterDictionary.Add(
"ModeOctal",
[System.Management.Automation.RuntimeDefinedParameter]::new(
"ModeOctal",
[string],
[System.Collections.ObjectModel.Collection[System.Attribute]]::new($Attribute)
)
)
return $RuntimeParameterDictionary
}
}
Process {
Get-Item $Path | ForEach-Object { chmod $ModeOctal $_.FullName } | Out-Null
}
}
} else {
function Set-ItemNixMode() {
Expand Down
6 changes: 5 additions & 1 deletion test/ConvertTo-NixMode.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,15 @@ Describe "SUT file" {
}

Describe "function" {
BeforeDiscovery {
$FileModeSettingNotSupported = $IsWindows -or ($null -eq [Type]::GetType("System.IO.UnixFileMode"))
}

It "should be defined" {
Get-Command -Name $SutName -CommandType Function | Should -Not -BeNullOrEmpty
}

Context "when invoked" {
Context "when invoked" -Skip:$FileModeSettingNotSupported {
Context "with no arguments" {
It "should throw" {
{ & $SutName } | Should -Throw
Expand Down
90 changes: 90 additions & 0 deletions test/Set-ItemNixMode.Tests.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#!/usr/bin/env pwsh
#Requires -Modules "Pester"
$ErrorActionPreference = "Stop"
Set-StrictMode -Version Latest


BeforeAll {
$SutFile = Get-Item "$PSScriptRoot/../src/Set-ItemNixMode.ps1"
$SutName = $SutFile.BaseName
}

Describe "SUT file" {
It "should exist" {
$SutFile | Should -Exist
}

It "should be sourceable" {
{ . $SutFile.FullName } | Should -Not -Throw
}

Context "when sourced" {
BeforeEach {
. $SutFile
}

Describe "function" {
BeforeDiscovery {
$FileModeSettingNotSupported = $IsWindows -or ($null -eq [Type]::GetType("System.IO.UnixFileMode"))
}

It "should be defined" {
Get-Command -Name $SutName -CommandType Function | Should -Not -BeNullOrEmpty
}

Context "when invoked" -Skip:$FileModeSettingNotSupported {
Context "with no arguments" {
It "should throw" {
{ & $SutName } | Should -Throw
}
}

Context "for an existing file" {
BeforeEach {
$targetFile = New-TemporaryFile
}

AfterEach {
Remove-Item $targetFile.FullName -Force
}

Context "ModeOctal is 700" {
It "should set the mode" {
$modeOctalParameter = '700'
[System.IO.UnixFileMode] $expectedMode = [System.IO.UnixFileMode]::OwnerRead -bor [System.IO.UnixFileMode]::OwnerWrite -bor [System.IO.UnixFileMode]::OwnerExecute

Set-ItemNixMode -Path $targetFile -ModeOctal $modeOctalParameter

$targetFile.Refresh()
$targetFile.Mode | Should -Be $expectedMode
}
}

Context "ModeOctal is 555" {
It "should set the mode" {
$modeOctalParameter = '555'
[System.IO.UnixFileMode] $expectedMode = [System.IO.UnixFileMode]::OwnerRead -bor [System.IO.UnixFileMode]::OwnerExecute -bor [System.IO.UnixFileMode]::GroupRead -bor [System.IO.UnixFileMode]::GroupExecute -bor [System.IO.UnixFileMode]::OthersRead -bor [System.IO.UnixFileMode]::OthersExecute

Set-ItemNixMode -Path $targetFile -ModeOctal $modeOctalParameter

$targetFile.Refresh()
$targetFile.Mode | Should -Be $expectedMode
}
}

Context "ModeOctal is 644" {
It "should set the mode" {
$modeOctalParameter = '644'
[System.IO.UnixFileMode] $expectedMode = [System.IO.UnixFileMode]::OwnerRead -bor [System.IO.UnixFileMode]::OwnerWrite -bor [System.IO.UnixFileMode]::GroupRead -bor [System.IO.UnixFileMode]::OthersRead

Set-ItemNixMode -Path $targetFile -ModeOctal $modeOctalParameter

$targetFile.Refresh()
$targetFile.Mode | Should -Be $expectedMode
}
}
}
}
}
}
}

0 comments on commit cc8aac5

Please sign in to comment.