From 879c5f287ea770f808b956a37449e9ba4ffc2d22 Mon Sep 17 00:00:00 2001 From: Amber Erickson Date: Wed, 10 Nov 2021 11:39:23 -0800 Subject: [PATCH 1/5] Bug fix for publish-psresource deleting a temp dir that contains a readonly file --- src/code/PublishPSResource.cs | 18 +++++++++++++++++- test/PublishPSResource.Tests.ps1 | 15 +++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/code/PublishPSResource.cs b/src/code/PublishPSResource.cs index d43babfef..b061d27e3 100644 --- a/src/code/PublishPSResource.cs +++ b/src/code/PublishPSResource.cs @@ -413,7 +413,23 @@ protected override void ProcessRecord() } finally { WriteVerbose(string.Format("Deleting temporary directory '{0}'", outputDir)); - Directory.Delete(outputDir, recursive:true); + + try + { + Directory.Delete(outputDir, recursive: true); + } + catch (UnauthorizedAccessException) + { + // If an exception was thrown due to an access denied exception, attempt to change file attributes to normal + string[] filesLeftToDelete = Directory.GetFiles(outputDir); + foreach (var file in filesLeftToDelete) + { + File.SetAttributes(file, FileAttributes.Normal); + } + + // Try to delete temp files again + Directory.Delete(outputDir, recursive: true); + } } } diff --git a/test/PublishPSResource.Tests.ps1 b/test/PublishPSResource.Tests.ps1 index 2a4feb5b2..d5a96b45b 100644 --- a/test/PublishPSResource.Tests.ps1 +++ b/test/PublishPSResource.Tests.ps1 @@ -278,4 +278,19 @@ Describe "Test Publish-PSResource" { $expectedPath = Join-Path -Path $tmpPath -ChildPath "$script:PublishModuleName.$version.nupkg" (Get-ChildItem $tmpPath).FullName | Should -Be $expectedPath } + + It "Publish a module and clean up properly when file in module is readonly" { + $version = "1.0.0" + New-ModuleManifest -Path (Join-Path -Path $script:PublishModuleBase -ChildPath "$script:PublishModuleName.psd1") -ModuleVersion $version -Description "$script:PublishModuleName module" + + # Create a readonly file that will throw access denied error if deletion is attempted + $file = Join-Path -Path $script:PublishModuleBase -ChildPath "inaccessiblefile.txt" + New-Item $file -Itemtype file -Force + Set-ItemProperty -Path $file -Name IsReadOnly -Value $true + + Publish-PSResource -Path $script:PublishModuleBase -Repository $testRepository2 + + $expectedPath = Join-Path -Path $script:repositoryPath2 -ChildPath "$script:PublishModuleName.$version.nupkg" + (Get-ChildItem $script:repositoryPath2).FullName | Should -Be $expectedPath + } } From 8db39be56b75ec3909f7d82d124a37a5d1f1455b Mon Sep 17 00:00:00 2001 From: Amber Erickson Date: Wed, 10 Nov 2021 16:50:11 -0800 Subject: [PATCH 2/5] Incorporate code review suggestions --- src/code/PublishPSResource.cs | 17 +---------------- src/code/Utils.cs | 6 ++++++ 2 files changed, 7 insertions(+), 16 deletions(-) diff --git a/src/code/PublishPSResource.cs b/src/code/PublishPSResource.cs index b061d27e3..101e2b8c5 100644 --- a/src/code/PublishPSResource.cs +++ b/src/code/PublishPSResource.cs @@ -414,22 +414,7 @@ protected override void ProcessRecord() finally { WriteVerbose(string.Format("Deleting temporary directory '{0}'", outputDir)); - try - { - Directory.Delete(outputDir, recursive: true); - } - catch (UnauthorizedAccessException) - { - // If an exception was thrown due to an access denied exception, attempt to change file attributes to normal - string[] filesLeftToDelete = Directory.GetFiles(outputDir); - foreach (var file in filesLeftToDelete) - { - File.SetAttributes(file, FileAttributes.Normal); - } - - // Try to delete temp files again - Directory.Delete(outputDir, recursive: true); - } + Utils.DeleteDirectory(outputDir); } } diff --git a/src/code/Utils.cs b/src/code/Utils.cs index 55b222571..ebfc66cf4 100644 --- a/src/code/Utils.cs +++ b/src/code/Utils.cs @@ -569,6 +569,12 @@ public static void DeleteDirectory(string dirPath) { foreach (var dirFilePath in Directory.GetFiles(dirPath)) { + FileAttributes attribute = File.GetAttributes(dirFilePath); + if (!attribute.Equals(FileAttributes.Normal)) + { + File.SetAttributes(dirFilePath, FileAttributes.Normal); + } + File.Delete(dirFilePath); } From 9cf4350bdd0b8c5e51c046bbf28d2bd262e47611 Mon Sep 17 00:00:00 2001 From: Amber Erickson Date: Mon, 29 Nov 2021 19:17:03 -0800 Subject: [PATCH 3/5] Add bitwise operands to get and set file attributes --- src/code/Utils.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/code/Utils.cs b/src/code/Utils.cs index a15d546d2..a2e158873 100644 --- a/src/code/Utils.cs +++ b/src/code/Utils.cs @@ -562,6 +562,12 @@ public static void DeleteDirectory(string dirPath) { foreach (var dirFilePath in Directory.GetFiles(dirPath)) { + FileAttributes attribute = File.GetAttributes(dirFilePath); + if ((attribute & FileAttributes.ReadOnly) == FileAttributes.ReadOnly) + { + File.SetAttributes(dirFilePath, attribute | FileAttributes.Hidden); + } + File.Delete(dirFilePath); } From f17686c369bca28834d4ba8777e38d7f35101f12 Mon Sep 17 00:00:00 2001 From: Amber Erickson Date: Mon, 29 Nov 2021 19:29:07 -0800 Subject: [PATCH 4/5] Change set attribute to simply overwrite former attributes --- src/code/Utils.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/code/Utils.cs b/src/code/Utils.cs index a2e158873..1a7cbacc0 100644 --- a/src/code/Utils.cs +++ b/src/code/Utils.cs @@ -562,10 +562,9 @@ public static void DeleteDirectory(string dirPath) { foreach (var dirFilePath in Directory.GetFiles(dirPath)) { - FileAttributes attribute = File.GetAttributes(dirFilePath); - if ((attribute & FileAttributes.ReadOnly) == FileAttributes.ReadOnly) + if ((File.GetAttributes(dirFilePath) & FileAttributes.ReadOnly) == FileAttributes.ReadOnly) { - File.SetAttributes(dirFilePath, attribute | FileAttributes.Hidden); + File.SetAttributes(dirFilePath, FileAttributes.Normal); } File.Delete(dirFilePath); From 7410d156e03345f9ba51de157cae22fee294c2ee Mon Sep 17 00:00:00 2001 From: Amber Erickson Date: Tue, 30 Nov 2021 14:31:13 -0800 Subject: [PATCH 5/5] Refactor getting and setting file attributes --- src/code/Utils.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/code/Utils.cs b/src/code/Utils.cs index 1a7cbacc0..2b5e5b9aa 100644 --- a/src/code/Utils.cs +++ b/src/code/Utils.cs @@ -562,9 +562,9 @@ public static void DeleteDirectory(string dirPath) { foreach (var dirFilePath in Directory.GetFiles(dirPath)) { - if ((File.GetAttributes(dirFilePath) & FileAttributes.ReadOnly) == FileAttributes.ReadOnly) + if (File.GetAttributes(dirFilePath).HasFlag(FileAttributes.ReadOnly)) { - File.SetAttributes(dirFilePath, FileAttributes.Normal); + File.SetAttributes(dirFilePath, (File.GetAttributes(dirFilePath) & ~FileAttributes.ReadOnly)); } File.Delete(dirFilePath);