Browse Source

fix: address the review of the issue fixes

Nine cmdlets still read the PWD variable for the default location when
-Path was omitted, so #86 remained for that form; they now use
GetCurrentLocation. Copy-Item2 writes the object that CopyTo returns for the
copy instead of relying on AlphaFS to update the source object, and a test
covers a folder.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
pull/105/head
Raimund Andree 7 days ago
parent
commit
f660d24bbc
  1. 5
      .memory-bank/progress.md
  2. 2
      NTFSSecurity/AccessCmdlets/GetAccess.cs
  3. 2
      NTFSSecurity/AccessCmdlets/GetEffectiveAccess.cs
  4. 2
      NTFSSecurity/AuditCmdlets/GetAudit.cs
  5. 11
      NTFSSecurity/BaseCmdlets.cs
  6. 2
      NTFSSecurity/InheritanceCmdlets/GetInheritance.cs
  7. 8
      NTFSSecurity/ItemCmdlets/CopyItem2.cs
  8. 2
      NTFSSecurity/ItemCmdlets/GetChildItem2.cs
  9. 2
      NTFSSecurity/ItemCmdlets/GetItem2.cs
  10. 2
      NTFSSecurity/LinkCmdlets/GetHardLink.cs
  11. 2
      NTFSSecurity/PathCmdlets/TestPath2.cs
  12. 2
      NTFSSecurity/SecurityDescriptorCmdlets/GetSecurityDescriptor.cs
  13. 12
      Tests/ItemCmdlets.Tests.ps1
  14. 19
      Tests/Owner.Tests.ps1

5
.memory-bank/progress.md

@ -182,8 +182,9 @@ Numbered as agreed with the maintainer; each is documented on its page.
#### Issue triage (fixes on `ai/issue-fixes`, not merged) #### Issue triage (fixes on `ai/issue-fixes`, not merged)
- Fixed: #3 (braces in a path), #86 (`$PWD` shadowed), #88 (an object - Fixed: #3 (braces in a path), #86 (`$PWD` shadowed, also for the default
passed by position); `Docs/FAQ.md` answers the recurring questions. location of nine cmdlets, found by the review), #88 (an object passed by
position); `Docs/FAQ.md` answers the recurring questions.
- Open bugs: #5 (`-Attributes` matches all, `Get-ChildItem` any; needs a - Open bugs: #5 (`-Attributes` matches all, `Get-ChildItem` any; needs a
decision), #17 (`GenericAll`), #34 and #67 (writes owner and group), decision), #17 (`GenericAll`), #34 and #67 (writes owner and group),
#41 (drive root), #82 (`Size` type data), #90 (trailing space). #41 (drive root), #82 (`Size` type data), #90 (trailing space).

2
NTFSSecurity/AccessCmdlets/GetAccess.cs

@ -74,7 +74,7 @@ namespace NTFSSecurity
if (paths.Count == 0) if (paths.Count == 0)
{ {
paths = new List<string>() { GetVariableValue("PWD").ToString() }; paths = new List<string>() { GetCurrentLocation() };
} }
} }

2
NTFSSecurity/AccessCmdlets/GetEffectiveAccess.cs

@ -109,7 +109,7 @@ namespace NTFSSecurity
} }
// Like the other cmdlets, use the current location when -Path is omitted. // Like the other cmdlets, use the current location when -Path is omitted.
var targets = paths.Count > 0 ? paths : new List<string>() { GetVariableValue("PWD").ToString() }; var targets = paths.Count > 0 ? paths : new List<string>() { GetCurrentLocation() };
foreach (var path in targets) foreach (var path in targets)
{ {

2
NTFSSecurity/AuditCmdlets/GetAudit.cs

@ -74,7 +74,7 @@ namespace NTFSSecurity
if (paths.Count == 0) if (paths.Count == 0)
{ {
paths = new List<string>() { GetVariableValue("PWD").ToString() }; paths = new List<string>() { GetCurrentLocation() };
} }
} }

11
NTFSSecurity/BaseCmdlets.cs

@ -122,10 +122,13 @@ namespace NTFSSecurity
return path; return path;
} }
// Read from the session state, not from $PWD: a variable named PWD in the caller's scope shadows the /// <summary>
// automatic variable and can be $null (#86). In a location of another provider, such as the registry, this /// Returns the current file system location of the session. It is read from the session state, not from
// is the last file system location. /// $PWD, which a variable named PWD in the scope of the caller can hide (#86). In a location of another
private string GetCurrentLocation() /// provider, such as the registry, this is the last file system location.
/// </summary>
/// <returns>The provider path of the current file system location.</returns>
protected string GetCurrentLocation()
{ {
return SessionState.Path.CurrentFileSystemLocation.ProviderPath; return SessionState.Path.CurrentFileSystemLocation.ProviderPath;
} }

2
NTFSSecurity/InheritanceCmdlets/GetInheritance.cs

@ -42,7 +42,7 @@ namespace NTFSSecurity
if (paths.Count == 0) if (paths.Count == 0)
{ {
paths = new List<string>() { GetVariableValue("PWD").ToString() }; paths = new List<string>() { GetCurrentLocation() };
} }
} }

8
NTFSSecurity/ItemCmdlets/CopyItem2.cs

@ -97,12 +97,13 @@ namespace NTFSSecurity
try try
{ {
var processed = false; var processed = false;
FileSystemInfo copy = null;
if (item is FileInfo) if (item is FileInfo)
{ {
if (ShouldProcess(resolvedPath, "Copy File")) if (ShouldProcess(resolvedPath, "Copy File"))
{ {
((FileInfo)item).CopyTo(actualDestination, force ? CopyOptions.None : CopyOptions.FailIfExists, PathFormat.RelativePath); copy = ((FileInfo)item).CopyTo(actualDestination, force ? CopyOptions.None : CopyOptions.FailIfExists, PathFormat.RelativePath);
WriteVerbose(string.Format("File '{0}' copied to '{1}'", resolvedPath, actualDestination)); WriteVerbose(string.Format("File '{0}' copied to '{1}'", resolvedPath, actualDestination));
processed = true; processed = true;
} }
@ -114,14 +115,15 @@ namespace NTFSSecurity
// AlphaFS 2.2 copies into an existing folder only and otherwise fails with a // AlphaFS 2.2 copies into an existing folder only and otherwise fails with a
// DirectoryNotFoundException for the first file. // DirectoryNotFoundException for the first file.
Directory.CreateDirectory(actualDestination); Directory.CreateDirectory(actualDestination);
((DirectoryInfo)item).CopyTo(actualDestination, force ? CopyOptions.None : CopyOptions.FailIfExists, PathFormat.RelativePath); copy = ((DirectoryInfo)item).CopyTo(actualDestination, force ? CopyOptions.None : CopyOptions.FailIfExists, PathFormat.RelativePath);
WriteVerbose(string.Format("Directory '{0}' copied to '{1}'", resolvedPath, actualDestination)); WriteVerbose(string.Format("Directory '{0}' copied to '{1}'", resolvedPath, actualDestination));
processed = true; processed = true;
} }
} }
// Write the object for the copy that CopyTo returns, not the source item.
if (passThru && processed) if (passThru && processed)
WriteObject(item); WriteObject(copy);
} }
catch (System.IO.IOException ex) catch (System.IO.IOException ex)
{ {

2
NTFSSecurity/ItemCmdlets/GetChildItem2.cs

@ -134,7 +134,7 @@ namespace NTFSSecurity
if (paths.Count == 0) if (paths.Count == 0)
{ {
paths = new List<string>() { GetVariableValue("PWD").ToString() }; paths = new List<string>() { GetCurrentLocation() };
} }
wildcard = new WildcardPattern(filter, WildcardOptions.Compiled | WildcardOptions.IgnoreCase); wildcard = new WildcardPattern(filter, WildcardOptions.Compiled | WildcardOptions.IgnoreCase);

2
NTFSSecurity/ItemCmdlets/GetItem2.cs

@ -30,7 +30,7 @@ namespace NTFSSecurity
if (paths.Count == 0) if (paths.Count == 0)
{ {
paths = new List<string>() { GetVariableValue("PWD").ToString() }; paths = new List<string>() { GetCurrentLocation() };
} }
modeMethodInfo = typeof(FileSystemCodeMembers).GetMethod("Mode"); modeMethodInfo = typeof(FileSystemCodeMembers).GetMethod("Mode");

2
NTFSSecurity/LinkCmdlets/GetHardLink.cs

@ -31,7 +31,7 @@ namespace NTFSSecurity
if (paths.Count == 0) if (paths.Count == 0)
{ {
paths = new List<string>() { GetVariableValue("PWD").ToString() }; paths = new List<string>() { GetCurrentLocation() };
} }
modeMethodInfo = typeof(FileSystemCodeMembers).GetMethod("Mode"); modeMethodInfo = typeof(FileSystemCodeMembers).GetMethod("Mode");

2
NTFSSecurity/PathCmdlets/TestPath2.cs

@ -37,7 +37,7 @@ namespace NTFSSecurity
if (paths.Count == 0) if (paths.Count == 0)
{ {
paths = new List<string>() { GetVariableValue("PWD").ToString() }; paths = new List<string>() { GetCurrentLocation() };
} }
} }

2
NTFSSecurity/SecurityDescriptorCmdlets/GetSecurityDescriptor.cs

@ -29,7 +29,7 @@ namespace NTFSSecurity
if (paths.Count == 0) if (paths.Count == 0)
{ {
paths.Add(GetVariableValue("PWD").ToString()); paths.Add(GetCurrentLocation());
} }
} }

12
Tests/ItemCmdlets.Tests.ps1

@ -137,6 +137,18 @@ Describe 'Copy-Item2, Move-Item2, and Remove-Item2 with several paths' {
$first | Should -Exist $first | Should -Exist
} }
It 'Copy-Item2 -PassThru should return the copy of a folder' {
$sourceFolder = Join-Path -Path $folder -ChildPath 'SourceFolder'
Assert-TestSandboxPath -Sandbox $sandbox -Path $sourceFolder
New-Item -ItemType Directory -Path $sourceFolder | Out-Null
Set-Content -LiteralPath (Join-Path -Path $sourceFolder -ChildPath 'Inner.txt') -Value 'Inner'
$result = Copy-Item2 -Path $sourceFolder -Destination (Join-Path -Path $destination -ChildPath 'Copied') -PassThru $true
$result.FullName | Should -Be (Join-Path -Path $destination -ChildPath 'Copied')
$sourceFolder | Should -Exist
}
It 'Move-Item2 -PassThru should return the item at its new location' { It 'Move-Item2 -PassThru should return the item at its new location' {
$result = Move-Item2 -Path $first -Destination $destination -PassThru $true $result = Move-Item2 -Path $first -Destination $destination -PassThru $true

19
Tests/Owner.Tests.ps1

@ -58,6 +58,8 @@ Describe 'Get-NTFSOwner' {
Describe 'Current location' { Describe 'Current location' {
BeforeAll { BeforeAll {
# The command runs in a child scope of this function, so the cmdlets see its $PWD = $null through the scope
# chain, as in the report.
function Invoke-WithShadowedPwd { function Invoke-WithShadowedPwd {
param ([scriptblock] $Command) param ([scriptblock] $Command)
@ -84,6 +86,21 @@ Describe 'Current location' {
$result.FullName | Should -Be $file $result.FullName | Should -Be $file
} }
It '<_> should use the current location without -Path despite a variable named PWD' -ForEach @(
'Get-NTFSAccess', 'Get-NTFSAudit', 'Get-NTFSEffectiveAccess', 'Get-NTFSInheritance', 'Get-ChildItem2',
'Get-Item2', 'Get-NTFSSecurityDescriptor'
) {
$cmdlet = $_
{ Invoke-WithShadowedPwd -Command { & $cmdlet -ErrorAction SilentlyContinue -WarningAction SilentlyContinue } } |
Should -Not -Throw
}
It 'Get-NTFSHardLink should report the folder of the current location, not a NullReferenceException' {
{ Invoke-WithShadowedPwd -Command { Get-NTFSHardLink -ErrorAction SilentlyContinue } } |
Should -Throw -ExpectedMessage '*must be a file*'
}
} }
Describe 'File and folder objects as arguments' { Describe 'File and folder objects as arguments' {
@ -108,4 +125,4 @@ Describe 'File and folder objects as arguments' {
$result.FullName | Should -Be $file $result.FullName | Should -Be $file
} }
} }

Loading…
Cancel
Save