Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: PowerShell Archive Support #81

Open
wants to merge 30 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
902582d
Set Foundation for PR
romero126 Oct 18, 2019
f732cc5
Initial Big Push
romero126 Nov 13, 2019
989f3e1
Remove dependency for StringUtility.Format
romero126 Jan 8, 2020
6268bb2
PinvokeDllNames should still exist as a static resource.
romero126 Jan 8, 2020
237fafb
Remove requirements for FileSystemProvider resource.
romero126 Jan 8, 2020
ea71d38
Squashed more dependencies on PowerShell Core Components.
romero126 Mar 13, 2020
269fe16
Squashed more dependencies
romero126 Mar 13, 2020
46a988e
Finalize full staging of code
romero126 Mar 13, 2020
a86e198
Squished all Dependencies
romero126 Apr 6, 2020
24b57e9
Added Pester Tests
romero126 Apr 9, 2020
734b2a9
Update to ProviderName to match module
romero126 Apr 9, 2020
16abf54
Added Formatting for filesystem objects
romero126 Apr 9, 2020
8030ac8
Update to failfast on Non Core PowerShell.
romero126 Apr 9, 2020
aad7e03
Build Cleanup
romero126 Apr 9, 2020
2057af9
PSD1 Cleanup
romero126 Apr 9, 2020
412dbfc
Update Appveyor
romero126 Apr 9, 2020
ca7da56
Reimplement ArgumentCompletionsAttribute
romero126 Apr 10, 2020
1b84470
Enabled ArgumentOutOfRange Exception
romero126 Apr 10, 2020
3cc4695
Enabled ArgumentOutOfRangeException
romero126 Apr 10, 2020
f8e0ebb
Fixed a bug where Encoding was not resolving encoding from string
romero126 Apr 10, 2020
0096e27
Remove Auto Generated Resources from Code
romero126 Apr 10, 2020
b915d54
Update GitIgnore to hide Generated Resources
romero126 Apr 10, 2020
3dd6589
Fix a bug with Remove-Item improperly erroring when file does not exist.
romero126 Apr 11, 2020
9dac42d
Fix New-Item to properly evaluate tests.
romero126 Apr 11, 2020
79abab6
ParentDirectoyDoes Not exist should error as NewItemIOError
romero126 Apr 11, 2020
cd7d626
Code Cleanup
romero126 Apr 12, 2020
08b1369
Fixed an issue with an edge case resolution of the provider dyn params
romero126 Apr 12, 2020
a172415
Fix a bug where Archive was not loading file due to a relative path i…
romero126 Apr 12, 2020
f7e104c
Code Cleanup
romero126 Apr 30, 2020
ef09f82
Cleanup Todo comments used as a checklist for functionality
romero126 Apr 30, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*\bin
*\obj
*\gen
27 changes: 27 additions & 0 deletions Microsoft.PowerShell.Archive.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26730.10
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.PowerShell.Archive", "SRC\Microsoft.PowerShell.Archive\Microsoft.PowerShell.Archive.csproj", "{B37E6EC2-E22D-407B-AB2D-F4C02C7EDA71}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{3DCDF473-9667-4F84-B1A3-D3843766DAE8}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{B37E6EC2-E22D-407B-AB2D-F4C02C7EDA71}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B37E6EC2-E22D-407B-AB2D-F4C02C7EDA71}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B37E6EC2-E22D-407B-AB2D-F4C02C7EDA71}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B37E6EC2-E22D-407B-AB2D-F4C02C7EDA71}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BB182DC0-D6FC-4C77-807F-2F4618457F7C}
EndGlobalSection
EndGlobal
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8" ?>
<Configuration>
<ViewDefinitions>
<View>
<Name>Microsoft.PowerShell.Archive.ArchiveItemInfo</Name>
<ViewSelectedBy>
<TypeName>Microsoft.PowerShell.Archive.ArchiveItemInfo</TypeName>
</ViewSelectedBy>
<TableControl>
<TableHeaders>
<TableColumnHeader>
<Width>25</Width>
</TableColumnHeader>
<TableColumnHeader>
<Width>8</Width>
</TableColumnHeader>
<TableColumnHeader>
<Width>25</Width>
</TableColumnHeader>
<TableColumnHeader>
</TableColumnHeader>
</TableHeaders>
<TableRowEntries>
<TableRowEntry>
<TableColumnItems>
<TableColumnItem>
<PropertyName>LastWriteTime</PropertyName>
</TableColumnItem>
<TableColumnItem>
<PropertyName>Length</PropertyName>
</TableColumnItem>
<TableColumnItem>
<PropertyName>Name</PropertyName>
</TableColumnItem>
<TableColumnItem>
<PropertyName>FullName</PropertyName>
</TableColumnItem>
</TableColumnItems>
</TableRowEntry>
</TableRowEntries>
</TableControl>
</View>
</ViewDefinitions>
</Configuration>
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ CmdletsToExport = @()
AliasesToExport = @()
NestedModules="Microsoft.PowerShell.Archive.psm1"
HelpInfoURI = 'https://go.microsoft.com/fwlink/?LinkId=393254'
FormatsToProcess = @('Microsoft.PowerShell.Archive.ArchiveItemInfo.Format.ps1xml')
}
10 changes: 10 additions & 0 deletions Microsoft.PowerShell.Archive/Microsoft.PowerShell.Archive.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -1310,3 +1310,13 @@ function ArchivePathCompareHelper

return $normalizedPathArgA -eq $normalizedPathArgB
}



if ($PSVersionTable.PSEdition -eq "Core") {
Write-Host -Object "Microsoft.PowerShell.Archive PSProvider is now Available in pwsh Core" -ForegroundColor Cyan
Import-Module "$PSScriptRoot\bin\Microsoft.PowerShell.Archive.dll"
}
else {
Write-Host -Object "Microsoft.PowerShell.Archive PSProvider is now Available in pwsh Core" -ForegroundColor Cyan
}
81 changes: 81 additions & 0 deletions Tests/PSProvider/Add-Content.Tests.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
Describe "Add-Content cmdlet tests" -Tags "CI" {
BeforeAll {
Import-Module "$PSScriptRoot\..\..\Microsoft.PowerShell.Archive\Microsoft.PowerShell.Archive.psd1"
New-PSDrive -Name TestDrive -PSProvider Microsoft.PowerShell.Archive -root "$PSScriptRoot/ZipFile.Zip" -ErrorAction "Stop"
#Current tests run persistanence for zipfile.
Remove-Item TestDrive:\file* -ErrorAction Continue
Remove-Item TestDrive:\dynamic* -ErrorAction Continue

$file1 = "file1.txt"
New-Item -Path "TestDrive:\$file1" -ItemType File -Force
}

Context "Add-Content should actually add content" {
It "should Add-Content to TestDrive:\$file1" {
$result = Add-Content -Path TestDrive:\$file1 -Value "ExpectedContent" -PassThru
$result | Should -BeExactly "ExpectedContent"
}

It "should return expected string from TestDrive:\$file1" {
$result = Get-Content -Path TestDrive:\$file1
$result | Should -BeExactly "ExpectedContent"
}

It "should Add-Content to TestDrive:\dynamicfile.txt with dynamic parameters" -Pending:($IsLinux -Or $IsMacOS) {#https://github.com/PowerShell/PowerShell/issues/891
$result = Add-Content -Path TestDrive:\dynamicfile.txt -Value "ExpectedContent" -PassThru
$result | Should -BeExactly "ExpectedContent"
}

It "should return expected string from TestDrive:\dynamicfile.txt" -Pending:($IsLinux -Or $IsMacOS) {#https://github.com/PowerShell/PowerShell/issues/891
$result = Get-Content -Path TestDrive:\dynamicfile.txt
$result | Should -BeExactly "ExpectedContent"
}

It "should Add-Content to TestDrive:\$file1 even when -Value is `$null" {
$AsItWas = Get-Content -Path TestDrive:\$file1
{ Add-Content -Path TestDrive:\$file1 -Value $null -ErrorAction Stop } | Should -Not -Throw
Get-Content -Path TestDrive:\$file1 | Should -BeExactly $AsItWas
}

It "should throw 'ParameterArgumentValidationErrorNullNotAllowed' when -Path is `$null" {
{ Add-Content -Path $null -Value "ShouldNotWorkBecausePathIsNull" -ErrorAction Stop } | Should -Throw -ErrorId "ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.AddContentCommand"
}

#[BugId(BugDatabase.WindowsOutOfBandReleases, 903880)]
It "should throw `"Cannot bind argument to parameter 'Path'`" when -Path is `$()" {
{ Add-Content -Path $() -Value "ShouldNotWorkBecausePathIsInvalid" -ErrorAction Stop } | Should -Throw -ErrorId "ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.AddContentCommand"
}

It "Should throw an error on a directory" {
{ Add-Content -Path . -Value "WriteContainerContentException" -ErrorAction Stop } | Should -Throw -ErrorId "WriteContainerContentException,Microsoft.PowerShell.Commands.AddContentCommand"
}

#[BugId(BugDatabase.WindowsOutOfBandReleases, 9058182)]
It "should be able to pass multiple [string]`$objects to Add-Content through the pipeline to output a dynamic Path file" -Pending:($IsLinux -Or $IsMacOS) {#https://github.com/PowerShell/PowerShell/issues/891
"hello","world" | Add-Content -Path TestDrive:\dynamicfile2.txt
$result = Get-Content -Path TestDrive:\dynamicfile2.txt
$result.length | Should -Be 2
$result[0] | Should -BeExactly "hello"
$result[1] | Should -BeExactly "world"
}

It "Should not block reads while writing" {
$logpath = Join-Path $testdrive "test.log"

Set-Content $logpath -Value "hello"

$f = [System.IO.FileStream]::new($logpath, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read, [System.IO.FileShare]::ReadWrite)

Add-Content $logpath -Value "world"

$f.Close()

$content = Get-Content $logpath
$content | Should -HaveCount 2
$content[0] | Should -BeExactly "hello"
$content[1] | Should -BeExactly "world"
}
}
}
116 changes: 116 additions & 0 deletions Tests/PSProvider/Clear-Content.Tests.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

# get a random string of characters a-z and A-Z
function Get-RandomString
{
param ( [int]$Length = 8 )
$chars = .{ ([int][char]'a')..([int][char]'z');([int][char]'A')..([int][char]'Z') }
([char[]]($chars | Get-Random -Count $Length)) -join ""
}

# get a random string which is not the name of an existing provider
function Get-NonExistantProviderName
{
param ( [int]$Length = 8 )
do {
$providerName = Get-RandomString -Length $Length
} until ( $null -eq (Get-PSProvider -PSProvider $providername -ErrorAction SilentlyContinue) )
$providerName
}

# get a random string which is not the name of an existing drive
function Get-NonExistantDriveName
{
param ( [int]$Length = 8 )
do {
$driveName = Get-RandomString -Length $Length
} until ( $null -eq (Get-PSDrive $driveName -ErrorAction SilentlyContinue) )
$drivename
}

# get a random string which is not the name of an existing function
function Get-NonExistantFunctionName
{
param ( [int]$Length = 8 )
do {
$functionName = Get-RandomString -Length $Length
} until ( (Test-Path -Path function:$functionName) -eq $false )
$functionName
}

Describe "Clear-Content cmdlet tests" -Tags "CI" {
BeforeAll {
Import-Module "$PSScriptRoot\..\..\Microsoft.PowerShell.Archive\Microsoft.PowerShell.Archive.psd1"
New-PSDrive -Name TestDrive -PSProvider Microsoft.PowerShell.Archive -root "$PSScriptRoot/ZipFile.Zip" -ErrorAction "Stop"

$file1 = "file1.txt"
$file2 = "file2.txt"
$file3 = "file3.txt"
$content1 = "This is content"
$content2 = "This is content for alternate stream tests"


New-Item -Path "TestDrive:\$file1" -ItemType File -Force
New-Item -Path "TestDrive:\$file2" -ItemType File -Value $content1 -Force
New-Item -Path "TestDrive:\$file3" -ItemType File -Value $content2 -Force

$streamContent = "content for alternate stream"
$streamName = "altStream1"
}

Context "Clear-Content should actually clear content" {
It "should clear-Content of TestDrive:\$file1" {
Set-Content -Path TestDrive:\$file1 -Value "ExpectedContent" -PassThru | Should -BeExactly "ExpectedContent"
Clear-Content -Path TestDrive:\$file1
}

It "shouldn't get any content from TestDrive:\$file1" {
$result = Get-Content -Path TestDrive:\$file1
$result | Should -BeNullOrEmpty
}

# we could suppress the WhatIf output here if we use the testhost, but it's not necessary
It "The filesystem provider supports should process" -skip:(!$IsWindows) {
Clear-Content -Path TestDrive:\$file2 -WhatIf
Get-Content -Path "TestDrive:\$file2" | Should -be "This is content"
}

It "The filesystem provider should support ShouldProcess (reference ProviderSupportsShouldProcess member)" {
$cci = ((Get-Command -Name Clear-Content).ImplementingType)::new()
$cci.SupportsShouldProcess | Should -BeTrue
}

}
Context "Proper errors should be delivered when bad locations are specified" {
It "should throw when targetting a directory." {
{ Clear-Content -Path . -ErrorAction Stop } | Should -Throw -ErrorId "ClearDirectoryContent"
}

It "should throw `"Cannot bind argument to parameter 'Path'`" when -Path is `$null" {
{ Clear-Content -Path $null -ErrorAction Stop } |
Should -Throw -ErrorId "ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.ClearContentCommand"
}

#[BugId(BugDatabase.WindowsOutOfBandReleases, 903880)]
It "should throw `"Cannot bind argument to parameter 'Path'`" when -Path is `$()" {
{ Clear-Content -Path $() -ErrorAction Stop } |
Should -Throw -ErrorId "ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.ClearContentCommand"
}

#[DRT][BugId(BugDatabase.WindowsOutOfBandReleases, 906022)]
It "should throw 'PSNotSupportedException' when you clear-content to an unsupported provider" {
$functionName = Get-NonExistantFunctionName
$null = New-Item -Path function:$functionName -Value { 1 }
{ Clear-Content -Path function:$functionName -ErrorAction Stop } |
Should -Throw -ErrorId "NotSupported,Microsoft.PowerShell.Commands.ClearContentCommand"
}

It "should throw FileNotFound error when referencing a non-existant file" {
$badFile = "TestDrive:/badfilename.txt"
{ Clear-Content -Path $badFile -ErrorAction Stop } |
Should -Throw -ErrorId "PathNotFound,Microsoft.PowerShell.Commands.ClearContentCommand"

}
}
}
Loading