Fix Rename-Item -Path with wildcard char (#7398)
This commit is contained in:
parent
4118fd2829
commit
caad7ed471
4 changed files with 124 additions and 12 deletions
|
@ -3519,22 +3519,87 @@ namespace Microsoft.PowerShell.Commands
|
||||||
|
|
||||||
#region Command code
|
#region Command code
|
||||||
|
|
||||||
|
private Collection<PathInfo> GetResolvedPaths(string path)
|
||||||
|
{
|
||||||
|
Collection<PathInfo> results = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
results = SessionState.Path.GetResolvedPSPathFromPSPath(path, CmdletProviderContext);
|
||||||
|
}
|
||||||
|
catch (PSNotSupportedException notSupported)
|
||||||
|
{
|
||||||
|
WriteError(
|
||||||
|
new ErrorRecord(
|
||||||
|
notSupported.ErrorRecord,
|
||||||
|
notSupported));
|
||||||
|
}
|
||||||
|
catch (DriveNotFoundException driveNotFound)
|
||||||
|
{
|
||||||
|
WriteError(
|
||||||
|
new ErrorRecord(
|
||||||
|
driveNotFound.ErrorRecord,
|
||||||
|
driveNotFound));
|
||||||
|
}
|
||||||
|
catch (ProviderNotFoundException providerNotFound)
|
||||||
|
{
|
||||||
|
WriteError(
|
||||||
|
new ErrorRecord(
|
||||||
|
providerNotFound.ErrorRecord,
|
||||||
|
providerNotFound));
|
||||||
|
}
|
||||||
|
catch (ItemNotFoundException pathNotFound)
|
||||||
|
{
|
||||||
|
WriteError(
|
||||||
|
new ErrorRecord(
|
||||||
|
pathNotFound.ErrorRecord,
|
||||||
|
pathNotFound));
|
||||||
|
}
|
||||||
|
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Moves the specified item to the specified destination
|
/// Moves the specified item to the specified destination
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected override void ProcessRecord()
|
protected override void ProcessRecord()
|
||||||
|
{
|
||||||
|
if (SuppressWildcardExpansion)
|
||||||
|
{
|
||||||
|
RenameItem(Path, literalPath: true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Collection<PathInfo> resolvedPaths = GetResolvedPaths(Path);
|
||||||
|
|
||||||
|
if (resolvedPaths == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resolvedPaths.Count == 1)
|
||||||
|
{
|
||||||
|
RenameItem(resolvedPaths[0].Path, literalPath: true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RenameItem(WildcardPattern.Unescape(Path), literalPath: true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RenameItem(string path, bool literalPath = false)
|
||||||
{
|
{
|
||||||
CmdletProviderContext currentContext = CmdletProviderContext;
|
CmdletProviderContext currentContext = CmdletProviderContext;
|
||||||
|
currentContext.SuppressWildcardExpansion = literalPath;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!InvokeProvider.Item.Exists(Path, currentContext))
|
if (!InvokeProvider.Item.Exists(path, currentContext))
|
||||||
{
|
{
|
||||||
PSInvalidOperationException invalidOperation =
|
PSInvalidOperationException invalidOperation =
|
||||||
(PSInvalidOperationException)
|
(PSInvalidOperationException)
|
||||||
PSTraceSource.NewInvalidOperationException(
|
PSTraceSource.NewInvalidOperationException(
|
||||||
NavigationResources.RenameItemDoesntExist,
|
NavigationResources.RenameItemDoesntExist,
|
||||||
Path);
|
path);
|
||||||
|
|
||||||
WriteError(
|
WriteError(
|
||||||
new ErrorRecord(
|
new ErrorRecord(
|
||||||
|
@ -3580,7 +3645,7 @@ namespace Microsoft.PowerShell.Commands
|
||||||
bool isCurrentLocationOrAncestor = false;
|
bool isCurrentLocationOrAncestor = false;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
isCurrentLocationOrAncestor = SessionState.Path.IsCurrentLocationOrAncestor(_path, currentContext);
|
isCurrentLocationOrAncestor = SessionState.Path.IsCurrentLocationOrAncestor(path, currentContext);
|
||||||
}
|
}
|
||||||
catch (PSNotSupportedException notSupported)
|
catch (PSNotSupportedException notSupported)
|
||||||
{
|
{
|
||||||
|
@ -3621,7 +3686,7 @@ namespace Microsoft.PowerShell.Commands
|
||||||
(PSInvalidOperationException)
|
(PSInvalidOperationException)
|
||||||
PSTraceSource.NewInvalidOperationException(
|
PSTraceSource.NewInvalidOperationException(
|
||||||
NavigationResources.RenamedItemInUse,
|
NavigationResources.RenamedItemInUse,
|
||||||
Path);
|
path);
|
||||||
|
|
||||||
WriteError(
|
WriteError(
|
||||||
new ErrorRecord(
|
new ErrorRecord(
|
||||||
|
@ -3635,12 +3700,12 @@ namespace Microsoft.PowerShell.Commands
|
||||||
|
|
||||||
currentContext.PassThru = PassThru;
|
currentContext.PassThru = PassThru;
|
||||||
|
|
||||||
tracer.WriteLine("Rename {0} to {1}", Path, NewName);
|
tracer.WriteLine("Rename {0} to {1}", path, NewName);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Now do the rename
|
// Now do the rename
|
||||||
InvokeProvider.Item.Rename(Path, NewName, currentContext);
|
InvokeProvider.Item.Rename(path, NewName, currentContext);
|
||||||
}
|
}
|
||||||
catch (PSNotSupportedException notSupported)
|
catch (PSNotSupportedException notSupported)
|
||||||
{
|
{
|
||||||
|
@ -3674,7 +3739,7 @@ namespace Microsoft.PowerShell.Commands
|
||||||
pathNotFound));
|
pathNotFound));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} // ProcessRecord
|
}
|
||||||
#endregion Command code
|
#endregion Command code
|
||||||
|
|
||||||
} // RenameItemCommand
|
} // RenameItemCommand
|
||||||
|
|
|
@ -433,7 +433,13 @@ namespace System.Management.Automation
|
||||||
|
|
||||||
s_pathResolutionTracer.WriteLine("Path is DRIVE-QUALIFIED");
|
s_pathResolutionTracer.WriteLine("Path is DRIVE-QUALIFIED");
|
||||||
|
|
||||||
string relativePath = GetDriveRootRelativePathFromPSPath(path, context, true, out drive, out providerInstance);
|
string relativePath =
|
||||||
|
GetDriveRootRelativePathFromPSPath(
|
||||||
|
path,
|
||||||
|
context,
|
||||||
|
!context.SuppressWildcardExpansion,
|
||||||
|
out drive,
|
||||||
|
out providerInstance);
|
||||||
|
|
||||||
Dbg.Diagnostics.Assert(
|
Dbg.Diagnostics.Assert(
|
||||||
drive != null,
|
drive != null,
|
||||||
|
|
|
@ -104,7 +104,7 @@ Describe "Basic Function Provider Tests" -Tags "CI" {
|
||||||
}
|
}
|
||||||
|
|
||||||
It "Fails to rename not existing function" {
|
It "Fails to rename not existing function" {
|
||||||
{ Rename-Item $nonExistingFunction -NewName $newName -ErrorAction Stop } | Should -Throw -ErrorId "InvalidOperation,Microsoft.PowerShell.Commands.RenameItemCommand"
|
{ Rename-Item $nonExistingFunction -NewName $newName -ErrorAction Stop } | Should -Throw -ErrorId "PathNotFound,Microsoft.PowerShell.Commands.RenameItemCommand"
|
||||||
}
|
}
|
||||||
|
|
||||||
It "Fails to rename function which is Constant" {
|
It "Fails to rename function which is Constant" {
|
||||||
|
@ -113,8 +113,8 @@ Describe "Basic Function Provider Tests" -Tags "CI" {
|
||||||
}
|
}
|
||||||
|
|
||||||
It "Fails to rename function which is ReadOnly" {
|
It "Fails to rename function which is ReadOnly" {
|
||||||
Set-Item $nonExistingFunction -Options "ReadOnly"
|
Set-Item $nonExistingFunction -Options "ReadOnly" -Value $functionValue
|
||||||
{ Rename-Item $nonExistingFunction -NewName $newName -ErrorAction Stop } | Should -Throw -ErrorId "InvalidOperation,Microsoft.PowerShell.Commands.RenameItemCommand"
|
{ Rename-Item $nonExistingFunction -NewName $newName -ErrorAction Stop } | Should -Throw -ErrorId "CannotRenameFunction,Microsoft.PowerShell.Commands.RenameItemCommand"
|
||||||
}
|
}
|
||||||
|
|
||||||
It "Renames ReadOnly function when -Force parameter is on" {
|
It "Renames ReadOnly function when -Force parameter is on" {
|
||||||
|
|
|
@ -2,10 +2,15 @@
|
||||||
# Licensed under the MIT License.
|
# Licensed under the MIT License.
|
||||||
Describe "Rename-Item tests" -Tag "CI" {
|
Describe "Rename-Item tests" -Tag "CI" {
|
||||||
BeforeAll {
|
BeforeAll {
|
||||||
$content = "This is content"
|
|
||||||
Setup -f originalFile.txt -content "This is content"
|
Setup -f originalFile.txt -content "This is content"
|
||||||
$source = "$TESTDRIVE/originalFile.txt"
|
$source = "$TESTDRIVE/originalFile.txt"
|
||||||
$target = "$TESTDRIVE/ItemWhichHasBeenRenamed.txt"
|
$target = "$TESTDRIVE/ItemWhichHasBeenRenamed.txt"
|
||||||
|
Setup -f [orig-file].txt -content "This is not content"
|
||||||
|
$sourceSp = "$TestDrive/``[orig-file``].txt"
|
||||||
|
$targetSpName = "ItemWhichHasBeen[Renamed].txt"
|
||||||
|
$targetSp = "$TestDrive/ItemWhichHasBeen``[Renamed``].txt"
|
||||||
|
Setup -Dir [test-dir]
|
||||||
|
$wdSp = "$TestDrive/``[test-dir``]"
|
||||||
}
|
}
|
||||||
It "Rename-Item will rename a file" {
|
It "Rename-Item will rename a file" {
|
||||||
Rename-Item $source $target
|
Rename-Item $source $target
|
||||||
|
@ -13,4 +18,40 @@ Describe "Rename-Item tests" -Tag "CI" {
|
||||||
test-path $target | Should -BeTrue
|
test-path $target | Should -BeTrue
|
||||||
"$target" | Should -FileContentMatchExactly "This is content"
|
"$target" | Should -FileContentMatchExactly "This is content"
|
||||||
}
|
}
|
||||||
|
It "Rename-Item will rename a file when path contains special char" {
|
||||||
|
Rename-Item $sourceSp $targetSpName
|
||||||
|
$sourceSp | Should -Not -Exist
|
||||||
|
$targetSp | Should -Exist
|
||||||
|
$targetSp | Should -FileContentMatchExactly "This is not content"
|
||||||
|
}
|
||||||
|
It "Rename-Item will rename a file when -Path and CWD contains special char" {
|
||||||
|
$content = "This is content"
|
||||||
|
$oldSpName = "[orig]file.txt"
|
||||||
|
$oldSpBName = "``[orig``]file.txt"
|
||||||
|
$oldSp = "$wdSp/$oldSpBName"
|
||||||
|
$newSpName = "[renamed]file.txt"
|
||||||
|
$newSp = "$wdSp/``[renamed``]file.txt"
|
||||||
|
In $wdSp -Execute {
|
||||||
|
$null = New-Item -Name $oldSpName -ItemType File -Value $content -Force
|
||||||
|
Rename-Item -Path $oldSpBName $newSpName
|
||||||
|
}
|
||||||
|
$oldSp | Should -Not -Exist
|
||||||
|
$newSp | Should -Exist
|
||||||
|
$newSp | Should -FileContentMatchExactly $content
|
||||||
|
}
|
||||||
|
It "Rename-Item will rename a file when -LiteralPath and CWD contains special char" {
|
||||||
|
$content = "This is not content"
|
||||||
|
$oldSpName = "[orig]file2.txt"
|
||||||
|
$oldSpBName = "``[orig``]file2.txt"
|
||||||
|
$oldSp = "$wdSp/$oldSpBName"
|
||||||
|
$newSpName = "[renamed]file2.txt"
|
||||||
|
$newSp = "$wdSp/``[renamed``]file2.txt"
|
||||||
|
In $wdSp -Execute {
|
||||||
|
$null = New-Item -Name $oldSpName -ItemType File -Value $content -Force
|
||||||
|
Rename-Item -LiteralPath $oldSpName $newSpName
|
||||||
|
}
|
||||||
|
$oldSp | Should -Not -Exist
|
||||||
|
$newSp | Should -Exist
|
||||||
|
$newSp | Should -FileContentMatchExactly $content
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue