diff --git a/examples/.gitignore b/examples/.gitignore new file mode 100644 index 0000000000..a89a881917 --- /dev/null +++ b/examples/.gitignore @@ -0,0 +1,5 @@ +# Don't checkin this output dir +Release/ + +# Auto-generated test file +foo[1].ps1 diff --git a/examples/.vscode/tasks.json b/examples/.vscode/tasks.json index 912b450b12..071a48339c 100644 --- a/examples/.vscode/tasks.json +++ b/examples/.vscode/tasks.json @@ -1,9 +1,10 @@ // A task runner that invokes Pester to run all Pester tests under the // current workspace folder. -// NOTE: This Pester task runner requires an updated version of Pester (>=3.4.0) +// NOTE: This Test task runner requires an updated version of Pester (>=3.4.0) // in order for the problemMatcher to find failed test information (message, line, file). -// If you don't have that version, you can update Pester from the PSGallery like so: +// If you don't have that version, you can update Pester from the PowerShell Gallery +// with this command: // // PS C:\> Update-Module Pester // @@ -14,6 +15,12 @@ // PS C:\> Install-Module Pester -Scope CurrentUser -Force // +// NOTE: The Clean, Build and Publish tasks require PSake. PSake can be installed +// from the PowerShell Gallery with this command: +// +// PS C:\> Install-Module PSake -Scope CurrentUser -Force +// + // Available variables which can be used inside of strings. // ${workspaceRoot}: the root folder of the team // ${file}: the current opened file @@ -21,7 +28,6 @@ // ${fileDirname}: the current opened file's dirname // ${fileExtname}: the current opened file's extension // ${cwd}: the current working directory of the spawned process - { "version": "0.1.0", @@ -34,17 +40,49 @@ // Show the output window always "showOutput": "always", - "args": [ - "-NoProfile", "-ExecutionPolicy", "Bypass", - "Write-Host 'Invoking Pester...'; Invoke-Pester -PesterOption @{IncludeVSCodeMarker=$true};", - "Invoke-Command { Write-Host \"Completed all tasks in task runner: $($args[0])\" } -args" - ], + "args": [ + "-NoProfile", "-ExecutionPolicy", "Bypass" + ], // Associate with test task runner "tasks": [ { - "taskName": "Pester", + "taskName": "Clean", + "suppressTaskName": true, + "showOutput": "always", + "args": [ + "Write-Host 'Invoking PSake...'; Invoke-PSake build.ps1 -taskList Clean;", + "Invoke-Command { Write-Host 'Completed Clean task in task runner.' }" + ] + }, + { + "taskName": "Build", + "suppressTaskName": true, + "isBuildCommand": true, + "showOutput": "always", + "args": [ + "Write-Host 'Invoking PSake...'; Invoke-PSake build.ps1 -taskList Build;", + "Invoke-Command { Write-Host 'Completed Build task in task runner.' }" + ] + }, + { + "taskName": "Publish", + "suppressTaskName": true, + "showOutput": "always", + "args": [ + "Write-Host 'Invoking PSake...'; Invoke-PSake build.ps1 -taskList Publish;", + "Invoke-Command { Write-Host 'Completed Publish task in task runner.' }" + ] + }, + { + "taskName": "Test", + "suppressTaskName": true, "isTestCommand": true, + "showOutput": "always", + "args": [ + "Write-Host 'Invoking Pester...'; Invoke-Pester -PesterOption @{IncludeVSCodeMarker=$true};", + "Invoke-Command { Write-Host 'Completed Test task in task runner.' }" + ], "problemMatcher": [ { "owner": "powershell", diff --git a/examples/Build.ps1 b/examples/Build.ps1 new file mode 100644 index 0000000000..d8aa852c04 --- /dev/null +++ b/examples/Build.ps1 @@ -0,0 +1,227 @@ +############################################################################## +# PREVIEW VERSION OF PSAKE SCRIPT FOR MODULE BUILD & PUBLISH TO THE PSGALLERY +############################################################################## +# +# We are hoping to add support for publishing modules to the PowerShell gallery +# and private repositories in a future release of this extension. This is an +# early look at the approach we are considering which is to supply a +# PSake-based script that will: +# +# 1. Create a directory from which to publish your module. +# 2. Copy the appropriate module files to that directory excluding items like +# the .vscode directory, Pester tests, etc. These are configurable in Build.ps1. +# 3. Verify all existing Pester tests pass. +# 4. Publish the module to the desired repository (defaulting to the PSGallery). +# +# Requirements: PSake. If you don't have this module installed use the following +# command to install it: +# +# PS C:\> Install-Module PSake -Scope CurrentUser +# +############################################################################## +# This is a PSake script that supports the following tasks: +# clean, build, test and publish. The default task is build. +# +# The publish task uses the Publish-Module command to publish +# to either the PowerShell Gallery (the default) or you can change +# the $Repository property to the name of an alternate repository. +# +# The test task invokes Pester to run any Pester tests in your +# workspace folder. Name your test scripts .Tests.ps1 +# and Pester will find and run the tests contained in the files. +# +# You can run this build script directly using the invoke-psake +# command which will execute the build task. This task "builds" +# a temporary folder from which the module can be published. +# +# PS C:\> invoke-psake build.ps1 +# +# You can run your Pester tests (if any) by running the following command. +# +# PS C:\> invoke-psake build.ps1 -taskList test +# +# You can execute the publish task with the following command. Note that +# the publish task will run the test task first. The Pester tests must pass +# before the publish task will run. The first time you run the publish +# command, you will be prompted to enter your PowerShell Gallery NuGetApiKey. +# After entering the key, it is encrypted and stored so you will not have to +# enter it again. +# +# PS C:\> invoke-psake build.ps1 -taskList publish +# +# You can verify the stored and encrypted NuGetApiKey by running the following +# command. This will display your NuGetApiKey in plain text! +# +# PS C:\> invoke-psake build.ps1 -taskList showKey +# +# You can store a new NuGetApiKey with this command. You can leave off +# the -properties parameter and you'll be prompted for the key. +# +# PS C:\> invoke-psake build.ps1 -taskList storeKey -properties @{NuGetApiKey='test123'} +# + +############################################################################### +# Customize these properties for your module. +############################################################################### +Properties { + # The name of your module should match the basename of the PSD1 file. + $ModuleName = (Get-Item $PSScriptRoot\*.psd1)[0].BaseName + + # Path to the release notes file. Set to $null if the release notes reside in the manifest file. + $ReleaseNotesPath = "$PSScriptRoot\ReleaseNotes.md" + + # The directory used to publish the module from. If you are using Git, the + # $PublishDir should be ignored if it is under the workspace directory. + $PublishDir = "$PSScriptRoot\Release\$ModuleName" + + # The following items will not be copied to the $PublishDir. + # Add items that should not be published with the module. + $Exclude = @( + 'Release', + 'Tests', + '.git*', + '.vscode', + # The next three files are unique to this examples dir. + 'DebugTest.ps1', + 'Stop*.ps1', + 'Readme.md', + (Split-Path $PSCommandPath -Leaf) + ) + + # Name of the repository you wish to publish to. Default repo is the PSGallery. + $PublishRepository = $null + + # Your NuGet API key for the PSGallery. Leave it as $null and the first time + # you publish you will be prompted to enter your API key. The build will + # store the key encrypted in a file, so that on subsequent publishes you + # will no longer be prompted for the API key. + $NuGetApiKey = $null + $EncryptedApiKeyPath = "$env:LOCALAPPDATA\vscode-powershell\NuGetApiKey.clixml" +} + +############################################################################### +# Customize these tasks for performing operations before and/or after publish. +############################################################################### +Task PrePublish { +} + +Task PostPublish { +} + +############################################################################### +# Core task implementations - this possibly "could" ship as part of the +# vscode-powershell extension and then get dot sourced into this file. +############################################################################### +Task default -depends Build + +Task Publish -depends Test, PrePublish, PublishImpl, PostPublish { +} + +Task PublishImpl -depends Test -requiredVariables PublishDir, EncryptedApiKeyPath { + $NuGetApiKey = Get-NuGetApiKey $NuGetApiKey $EncryptedApiKeyPath + + $publishParams = @{ + Path = $PublishDir + NuGetApiKey = $NuGetApiKey + } + + if ($PublishRepository) { + $publishParams['Repository'] = $PublishRepository + } + + # Consider not using -ReleaseNotes parameter when Update-ModuleManifest has been fixed. + if ($ReleaseNotesPath) { + $publishParams['ReleaseNotes'] = @(Get-Content $ReleaseNotesPath) + } + + "Calling Publish-Module..." + Publish-Module @publishParams -WhatIf +} + +Task Test -depends Build { + Import-Module Pester + Invoke-Pester $PSScriptRoot +} + +Task Build -depends Clean -requiredVariables PublishDir, Exclude, ModuleName { + Copy-Item $PSScriptRoot\* -Destination $PublishDir -Recurse -Exclude $Exclude + + # Get contents of the ReleaseNotes file and update the copied module manifest file + # with the release notes. + # DO NOT USE UNTIL UPDATE-MODULEMANIFEST IS FIXED - HORRIBLY BROKEN RIGHT NOW. + # if ($ReleaseNotesPath) { + # $releaseNotes = @(Get-Content $ReleaseNotesPath) + # Update-ModuleManifest -Path $PublishDir\${ModuleName}.psd1 -ReleaseNotes $releaseNotes + # } +} + +Task Clean -depends Init -requiredVariables PublishDir { + # Sanity check the dir we are about to "clean". If $PublishDir were to + # inadvertently get set to $null, the Remove-Item commmand removes the + # contents of \*. That's a bad day. Ask me how I know? :-( + if ($PublishDir.Contains($PSScriptRoot)) { + Remove-Item $PublishDir\* -Recurse -Force + } +} + +Task Init -requiredVariables PublishDir { + if (!(Test-Path $PublishDir)) { + $null = New-Item $PublishDir -ItemType Directory + } +} + +Task StoreKey -requiredVariables EncryptedApiKeyPath { + if (Test-Path $EncryptedApiKeyPath) { + Remove-Item $EncryptedApiKeyPath + } + + $null = Get-NuGetApiKey $NuGetApiKey $EncryptedApiKeyPath + "The NuGetApiKey has been stored in $EncryptedApiKeyPath" +} + +Task ShowKey -requiredVariables EncryptedApiKeyPath { + $NuGetApiKey = Get-NuGetApiKey $NuGetApiKey $EncryptedApiKeyPath + "The stored NuGetApiKey is: $NuGetApiKey" +} + +Task ? -description 'Lists the available tasks' { + "Available tasks:" + $psake.context.Peek().tasks.Keys | Sort +} + +############################################################################### +# Helper functions +############################################################################### +function Get-NuGetApiKey($NuGetApiKey, $EncryptedApiKeyPath) { + $storedKey = $null + if (!$NuGetApiKey) { + if (Test-Path $EncryptedApiKeyPath) { + $storedKey = Import-Clixml $EncryptedApiKeyPath | ConvertTo-SecureString + $cred = New-Object -TypeName PSCredential -ArgumentList 'kh',$storedKey + $NuGetApiKey = $cred.GetNetworkCredential().Password + Write-Verbose "Retrieved encrypted NuGetApiKey from $EncryptedApiKeyPath" + } + else { + $cred = Get-Credential -Message "Enter your NuGet API Key in the password field (or nothing, this isn't used yet in the preview)" -UserName "user" + $apiKeySS = $cred.Password + $NuGetApiKey = $cred.GetNetworkCredential().Password + } + } + + if (!$storedKey) { + # Store encrypted NuGet API key to use for future invocations + if (!$apiKeySS) { + $apiKeySS = ConvertTo-SecureString -String $NuGetApiKey -AsPlainText -Force + } + + $parentDir = Split-Path $EncryptedApiKeyPath -Parent + if (!(Test-Path -Path $parentDir)) { + $null = New-Item -Path $parentDir -ItemType Directory + } + + $apiKeySS | ConvertFrom-SecureString | Export-Clixml $EncryptedApiKeyPath + Write-Verbose "Stored encrypted NuGetApiKey to $EncryptedApiKeyPath" + } + + $NuGetApiKey +} diff --git a/examples/DebugTest.ps1 b/examples/DebugTest.ps1 index 68f648b1d5..b5c3422cad 100644 Binary files a/examples/DebugTest.ps1 and b/examples/DebugTest.ps1 differ diff --git a/examples/PathProcessingNoWildcards.ps1 b/examples/PathProcessingNoWildcards.ps1 index 8773db94b7..25889fd301 100644 --- a/examples/PathProcessingNoWildcards.ps1 +++ b/examples/PathProcessingNoWildcards.ps1 @@ -1,3 +1,16 @@ +<# +.SYNOPSIS + Demonstrates how to write a command that works with paths that do + not allow wildards but must exist. +.DESCRIPTION + This command does not require a LiteralPath parameter because the + Path parameter can handle paths that use wildcard characters. That's + because this command does not "resolve" the supplied path. +.EXAMPLE + C:\PS> Import-FileNoWildcard -Path ..\..\Tests\foo[1].txt -WhatIf + This example shows how the Path parameter can handle a path that happens + to use the wildcard chars "[" and "]". +#> function Import-FileNoWildcard { [CmdletBinding(SupportsShouldProcess=$true)] param( @@ -13,10 +26,10 @@ function Import-FileNoWildcard { [string[]] $Path ) - + begin { } - + process { # Modify [CmdletBinding()] to [CmdletBinding(SupportsShouldProcess=$true)] $paths = @() @@ -28,11 +41,11 @@ function Import-FileNoWildcard { $psCmdlet.WriteError($errRecord) continue } - + # Resolve any relative paths $paths += $psCmdlet.SessionState.Path.GetUnresolvedProviderPathFromPSPath($aPath) } - + foreach ($aPath in $paths) { if ($pscmdlet.ShouldProcess($aPath, 'Operation')) { # Process each path @@ -40,7 +53,7 @@ function Import-FileNoWildcard { } } } - + end { } } \ No newline at end of file diff --git a/examples/PathProcessingNonExistingPaths.ps1 b/examples/PathProcessingNonExistingPaths.ps1 index d8a06e1ecc..d11e025303 100644 --- a/examples/PathProcessingNonExistingPaths.ps1 +++ b/examples/PathProcessingNonExistingPaths.ps1 @@ -1,3 +1,18 @@ +<# +.SYNOPSIS + Demonstrates how to write a command that works with paths that do + not allow wildards and do not have to exist. +.DESCRIPTION + This command does not require a LiteralPath parameter because the + Path parameter can handle paths that use wildcard characters. That's + because this command does not "resolve" the supplied path. This command + also does not verify the path exists because the point of the command is + to create a new file at the specified path. +.EXAMPLE + C:\PS> New-File -Path xyzzy[1].txt -WhatIf + This example shows how the Path parameter can handle a path that happens + to use the wildcard chars "[" and "]" and does not exist to start with. +#> function New-File { [CmdletBinding(SupportsShouldProcess=$true)] param( @@ -13,10 +28,10 @@ function New-File { [string[]] $Path ) - + begin { } - + process { # Modify [CmdletBinding()] to [CmdletBinding(SupportsShouldProcess=$true)] $paths = @() @@ -24,7 +39,7 @@ function New-File { # Resolve any relative paths $paths += $psCmdlet.SessionState.Path.GetUnresolvedProviderPathFromPSPath($aPath) } - + foreach ($aPath in $paths) { if ($pscmdlet.ShouldProcess($aPath, 'Operation')) { # Process each path @@ -32,7 +47,7 @@ function New-File { } } } - + end { } } \ No newline at end of file diff --git a/examples/PathProcessingWildcards.ps1 b/examples/PathProcessingWildcards.ps1 index bc88d2d0bb..6ba85f9e67 100644 --- a/examples/PathProcessingWildcards.ps1 +++ b/examples/PathProcessingWildcards.ps1 @@ -1,3 +1,19 @@ +<# +.SYNOPSIS + Demonstrates how to write a command that works with paths that allow + wildards and must exist. +.DESCRIPTION + This command also demonstrates how you need to supply a LiteralPath + parameter when your Path parameter accepts wildcards. This is in order + to handle paths like foo[1].txt. If you pass this path to the Path + parameter, it will fail to find this file because "[1]" is interpreted + as a wildcard spec e.g it resolves to foo1.txt. The LiteralPath parameter + is used in this case as it does not interpret wildcard chars. +.EXAMPLE + C:\PS> Import-FileWildcard -LiteralPath ..\..\Tests\foo[1].txt -WhatIf + This example shows how to use the LiteralPath parameter with a path + that happens to use the wildcard chars "[" and "]". +#> function Import-FileWildcard { [CmdletBinding(SupportsShouldProcess=$true, DefaultParameterSetName='Path')] param( @@ -12,7 +28,7 @@ function Import-FileWildcard { [SupportsWildcards()] [string[]] $Path, - + # Specifies a path to one or more locations. Unlike the Path parameter, the value of the LiteralPath parameter is # used exactly as it is typed. No characters are interpreted as wildcards. If the path includes escape characters, # enclose it in single quotation marks. Single quotation marks tell Windows PowerShell not to interpret any @@ -27,10 +43,10 @@ function Import-FileWildcard { [string[]] $LiteralPath ) - + begin { } - + process { # Modify [CmdletBinding()] to [CmdletBinding(SupportsShouldProcess=$true, DefaultParameterSetName='Path')] $paths = @() @@ -43,7 +59,7 @@ function Import-FileWildcard { $psCmdlet.WriteError($errRecord) continue } - + # Resolve any wildcards that might be in the path $provider = $null $paths += $psCmdlet.SessionState.Path.GetResolvedProviderPathFromPSPath($aPath, [ref]$provider) @@ -58,12 +74,12 @@ function Import-FileWildcard { $psCmdlet.WriteError($errRecord) continue } - + # Resolve any relative paths $paths += $psCmdlet.SessionState.Path.GetUnresolvedProviderPathFromPSPath($aPath) } } - + foreach ($aPath in $paths) { if ($pscmdlet.ShouldProcess($aPath, 'Operation')) { # Process each path @@ -71,7 +87,7 @@ function Import-FileWildcard { } } } - + end { } } \ No newline at end of file diff --git a/examples/README.md b/examples/README.md index 3f2c4cf281..9460d1fa59 100644 --- a/examples/README.md +++ b/examples/README.md @@ -3,18 +3,22 @@ *NOTE: For a more comfortable reading experience, use the key combination `Ctrl+Shift+V`* This folder contains a few basic PowerShell script files that you can use -to experiment with the new PowerShell editing and debugging capabilities. +to experiment with the new PowerShell editing debugging capabilities as well +as an early preview of a workflow for publishing a module to the PowerShell +Gallery. + Here are some ideas for what you can try with these scripts: ## Language Features - **Integrated syntax checks** from the PowerShell engine and **integrated rule-based analysis** using PowerShell Script Analyzer - - Try opening `DebugTest.ps1` and `StopTest.ps1` by double-clicking on their - file names. You will see red and green squiggles for rule-based checks. - You can introduce a syntax error somewhere to see the red squiggle for - that as well. To see a list of all errors and warnings, try pressing - `Ctrl+Shift+M`. + - Try opening `DebugTest.ps1` by double-clicking on its file name in the + Explorer view. You will see a green squiggle on the function name `Do-Work` + indicating that `Do` is not an approved verb. These rule-based checks use + PSScriptAnalyzer to analyze/lint your scripts. You can introduce a syntax + error somewhere to see a red squiggle for that as well. To see a list of + all errors and warnings, try pressing `Ctrl+Shift+M`. - **Go to definition `(F12)`** and **Peek definition `(Alt+F12)`** for cmdlet and variable names - Try this on the `Stop-Process2` cmdlet in `StopTest.ps1` @@ -84,6 +88,42 @@ You can also set the parameter explicitly e.g.: `"cwd": "C:\\Users\\JSnover\\Documents\\MonadUberAlles"` +## Module Publishing Preview + +### Requirements: +* [PSake](https://github.com/psake/psake) - install PSake with the command: + + PS C:\\> `Install-Module PSake -Scope CurrentUser` + +The are two files (Build.ps1 and tasks.json) that facilitate building a directory from which +to publish a module from and then publishing from that directory. The act of creating or +building this "Release" directory can be executed with the key combination `Ctrl+Shift+B` +which is the `Build` keyboard shortcut in Visual Studio Code. + +When you execute the `Build` command, the build task from the `.vscode\tasks.json` file +is executed. This task invokes PSake on the file `Build.ps1`. This file +contains items you might want to customize such as `$PublishRepository` or the +`$ReleaseNotesPath`. It also contains two PSake tasks which you might want to +customize: `PrePublish` and `PostPublish`. If you sign your scripts, you can +use the `PrePublish` task and the script in it will get executed after the build +but before the `Publish` task is executed. + +To execute the `Publish` task, press `Ctrl+P` then type `"task publish"` and press `Enter`. + +NOTE: the `Publish` task does not actually publish to allow for experimentation. +If you wish to publish, remove the `-WhatIf` parameter on the `Publish-Module` command +in Build.ps1. But make sure you've modified the module manifest (psd1) file or supplied your own +in order to give your module a unique name and guid. + +NOTE: the very first time you execute the publish task, you will be prompted for +a NuGet API Key. This would normally be the NuGet API Key you are assigned when you +register for an account on the [PowerShell Gallery](https://www.powershellgallery.com/). +However since this is just an example of how this feature could work in the future, +you can supply any string you want. + +For more details on how this works, inspect the `.vscode\tasks.json` file and the +`Build.ps1` file. + ## Feedback We would love to hear your feedback! Please post feature requests or issue diff --git a/examples/ReleaseNotes.md b/examples/ReleaseNotes.md new file mode 100644 index 0000000000..44a2053ddc --- /dev/null +++ b/examples/ReleaseNotes.md @@ -0,0 +1,11 @@ +## What is New in SampleModule 1.0 +March 9, 2016 + +* Note: Due to a bug in `Update-ModuleManifest` you cannot put a single +quote in your release notes. + +* Initial release with support for New-File, Import-FileNoWildcard and +Import-FileWildcard commands. + +### Feedback +Please send your feedback to http://github.com/____.com/issues \ No newline at end of file diff --git a/examples/SampleModule.psd1 b/examples/SampleModule.psd1 new file mode 100644 index 0000000000..ba44134758 Binary files /dev/null and b/examples/SampleModule.psd1 differ diff --git a/examples/SampleModule.psm1 b/examples/SampleModule.psm1 new file mode 100644 index 0000000000..1eb7d5ec62 --- /dev/null +++ b/examples/SampleModule.psm1 @@ -0,0 +1,4 @@ + +. $PSScriptRoot\PathProcessingNonExistingPaths.ps1 +. $PSScriptRoot\PathProcessingNoWildcards.ps1 +. $PSScriptRoot\PathProcessingWildcards.ps1 diff --git a/examples/Stop-Process2.ps1 b/examples/Stop-Process2.ps1 index 9fa66141d6..4174844499 100644 --- a/examples/Stop-Process2.ps1 +++ b/examples/Stop-Process2.ps1 @@ -8,40 +8,30 @@ .EXAMPLE Another example of how to use this cmdlet #> -function Stop-Process2 -{ +function Stop-Process2 { [CmdletBinding(SupportsShouldProcess = $true)] [Alias()] [OutputType([int])] - Param - ( + param( # Param1 help description [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=0)] $Name ) - - Begin - { - } - Process - { + + process { if ($PSCmdlet.ShouldProcess("")) { $processes = Get-Process -Name $Name - foreach ($process in $processes) - { + foreach ($process in $processes) { $id = $process.Id $name = $process.Name Write-Output "Killing $name ($id)" - + $process.Kill(); - + Start-Sleep -Seconds 1 } } } - End - { - } } \ No newline at end of file diff --git a/examples/StopTest.ps1 b/examples/StopTest.ps1 index 0884e47a5a..4e0291a978 100644 --- a/examples/StopTest.ps1 +++ b/examples/StopTest.ps1 @@ -1,4 +1,3 @@ - . .\Stop-Process2.ps1 notepad.exe diff --git a/examples/PathProcessing.Tests.ps1 b/examples/Tests/PathProcessing.Tests.ps1 similarity index 50% rename from examples/PathProcessing.Tests.ps1 rename to examples/Tests/PathProcessing.Tests.ps1 index 9d5cd35b58..7e751a59fe 100644 --- a/examples/PathProcessing.Tests.ps1 +++ b/examples/Tests/PathProcessing.Tests.ps1 @@ -8,91 +8,92 @@ # test task runner defined in .vscode\tasks.json. # This (empty) file is required by some of the tests. -$null = New-Item -Path 'foo[1].txt' -Force +$null = New-Item -Path "$PSScriptRoot\foo[1].txt" -Force + +Import-Module $PSScriptRoot\..\SampleModule.psd1 + +$WorkspaceRoot = $pwd -. $PSScriptRoot\PathProcessingNonExistingPaths.ps1 Describe 'Verify Path Processing for Non-existing Paths Allowed Impl' { It 'Processes non-wildcard absolute path to non-existing file via -Path param' { - New-File -Path $PSScriptRoot\ReadmeNew.md | Should Be "$PSScriptRoot\READMENew.md" + New-File -Path $WorkspaceRoot\ReadmeNew.md | Should Be "$WorkspaceRoot\READMENew.md" } It 'Processes multiple absolute paths via -Path param' { - New-File -Path $PSScriptRoot\Readme.md, $PSScriptRoot\XYZZY.ps1 | - Should Be @("$PSScriptRoot\README.md", "$PSScriptRoot\XYZZY.ps1") + New-File -Path $WorkspaceRoot\Readme.md, $WorkspaceRoot\XYZZY.ps1 | + Should Be @("$WorkspaceRoot\README.md", "$WorkspaceRoot\XYZZY.ps1") } It 'Processes relative path via -Path param' { - New-File -Path ..\examples\READMENew.md | Should Be "$PSScriptRoot\READMENew.md" + New-File -Path ..\Examples\READMENew.md | Should Be "$WorkspaceRoot\READMENew.md" } It 'Processes multiple relative path via -Path param' { - New-File -Path ..\examples\README.md, XYZZY.ps1 | - Should Be @("$PSScriptRoot\README.md", "$PSScriptRoot\XYZZY.ps1") + New-File -Path ..\Examples\README.md, XYZZY.ps1 | + Should Be @("$WorkspaceRoot\README.md", "$WorkspaceRoot\XYZZY.ps1") } It 'Should accept pipeline input to Path' { - Get-ChildItem -LiteralPath "$pwd\foo[1].txt" | New-File | Should Be "$PSScriptRoot\foo[1].txt" + Get-ChildItem -LiteralPath "$WorkspaceRoot\Tests\foo[1].txt" | New-File | Should Be "$PSScriptRoot\foo[1].txt" } } -. $PSScriptRoot\PathProcessingNoWildcards.ps1 Describe 'Verify Path Processing for NO Wildcards Allowed Impl' { It 'Processes non-wildcard absolute path via -Path param' { - Import-FileNoWildcard -Path $PSScriptRoot\Readme.md | Should Be "$PSScriptRoot\README.md" + Import-FileNoWildcard -Path $WorkspaceRoot\Readme.md | Should Be "$WorkspaceRoot\README.md" } It 'Processes multiple absolute paths via -Path param' { - Import-FileNoWildcard -Path $PSScriptRoot\Readme.md, $PSScriptRoot\PathProcessingWildcards.ps1 | - Should Be @("$PSScriptRoot\README.md", "$PSScriptRoot\PathProcessingWildcards.ps1") + Import-FileNoWildcard -Path $WorkspaceRoot\Readme.md, $WorkspaceRoot\PathProcessingWildcards.ps1 | + Should Be @("$WorkspaceRoot\README.md", "$WorkspaceRoot\PathProcessingWildcards.ps1") } It 'Processes relative path via -Path param' { - Import-FileNoWildcard -Path ..\examples\README.md | Should Be "$PSScriptRoot\README.md" + Import-FileNoWildcard -Path ..\examples\README.md | Should Be "$WorkspaceRoot\README.md" } It 'Processes multiple relative path via -Path param' { Import-FileNoWildcard -Path ..\examples\README.md, .vscode\launch.json | - Should Be @("$PSScriptRoot\README.md", "$PSScriptRoot\.vscode\launch.json") + Should Be @("$WorkspaceRoot\README.md", "$WorkspaceRoot\.vscode\launch.json") } It 'Should accept pipeline input to Path' { - Get-ChildItem -LiteralPath "$pwd\foo[1].txt" | Import-FileNoWildcard | Should Be "$PSScriptRoot\foo[1].txt" + Get-ChildItem -LiteralPath "$WorkspaceRoot\Tests\foo[1].txt" | Import-FileNoWildcard | Should Be "$PSScriptRoot\foo[1].txt" } } -. $PSScriptRoot\PathProcessingWildcards.ps1 Describe 'Verify Path Processing for Wildcards Allowed Impl' { It 'Processes non-wildcard absolute path via -Path param' { - Import-FileWildcard -Path $PSScriptRoot\Readme.md | Should Be "$PSScriptRoot\README.md" + Import-FileWildcard -Path $WorkspaceRoot\Readme.md | Should Be "$WorkspaceRoot\README.md" } It 'Processes multiple absolute paths via -Path param' { - Import-FileWildcard -Path $PSScriptRoot\Readme.md, $PSScriptRoot\PathProcessingWildcards.ps1 | - Should Be @("$PSScriptRoot\README.md", "$PSScriptRoot\PathProcessingWildcards.ps1") + Import-FileWildcard -Path $WorkspaceRoot\Readme.md, $WorkspaceRoot\PathProcessingWildcards.ps1 | + Should Be @("$WorkspaceRoot\README.md", "$WorkspaceRoot\PathProcessingWildcards.ps1") } It 'Processes wildcard absolute path via -Path param' { - Import-FileWildcard -Path $PSScriptRoot\*.md | Should Be "$PSScriptRoot\README.md" + Import-FileWildcard -Path $WorkspaceRoot\*.psd1 | Should Be "$WorkspaceRoot\SampleModule.psd1" } It 'Processes wildcard relative path via -Path param' { - Import-FileWildcard -Path *.md | Should Be "$PSScriptRoot\README.md" + Import-FileWildcard -Path *.psd1 | Should Be "$WorkspaceRoot\SampleModule.psd1" } It 'Processes relative path via -Path param' { - Import-FileWildcard -Path ..\examples\README.md | Should Be "$PSScriptRoot\README.md" + Import-FileWildcard -Path ..\examples\README.md | Should Be "$WorkspaceRoot\README.md" } It 'Processes multiple relative path via -Path param' { Import-FileWildcard -Path ..\examples\README.md, .vscode\launch.json | - Should Be @("$PSScriptRoot\README.md", "$PSScriptRoot\.vscode\launch.json") + Should Be @("$WorkspaceRoot\README.md", "$WorkspaceRoot\.vscode\launch.json") } It 'DefaultParameterSet should be Path' { - Import-FileWildcard *.md | Should Be "$PSScriptRoot\README.md" + Import-FileWildcard *.psd1 | Should Be "$WorkspaceRoot\SampleModule.psd1" } It 'Should process absolute literal paths via -LiteralPath param'{ Import-FileWildcard -LiteralPath "$PSScriptRoot\foo[1].txt" | Should Be "$PSScriptRoot\foo[1].txt" } It 'Should process relative literal paths via -LiteralPath param'{ - Import-FileWildcard -LiteralPath "..\examples\foo[1].txt" | Should Be "$PSScriptRoot\foo[1].txt" + Import-FileWildcard -LiteralPath "..\examples\Tests\foo[1].txt" | Should Be "$PSScriptRoot\foo[1].txt" } It 'Should process multiple literal paths via -LiteralPath param'{ - Import-FileWildcard -LiteralPath "..\examples\foo[1].txt", "$PSScriptRoot\README.md" | - Should Be @("$PSScriptRoot\foo[1].txt", "$PSScriptRoot\README.md") + Import-FileWildcard -LiteralPath "..\examples\Tests\foo[1].txt", "$WorkspaceRoot\README.md" | + Should Be @("$PSScriptRoot\foo[1].txt", "$WorkspaceRoot\README.md") } It 'Should accept pipeline input to LiteralPath' { - Get-ChildItem -LiteralPath "$pwd\foo[1].txt" | Import-FileWildcard | Should Be "$PSScriptRoot\foo[1].txt" + Get-ChildItem -LiteralPath "$WorkspaceRoot\Tests\foo[1].txt" | Import-FileWildcard | Should Be "$PSScriptRoot\foo[1].txt" } } diff --git a/examples/Tests/SampleModule.Tests.ps1 b/examples/Tests/SampleModule.Tests.ps1 new file mode 100644 index 0000000000..40985d6f63 --- /dev/null +++ b/examples/Tests/SampleModule.Tests.ps1 @@ -0,0 +1,9 @@ +$ModuleManifestName = 'SampleModule.psd1' +Import-Module $PSScriptRoot\..\$ModuleManifestName + +Describe 'Module Manifest Tests' { + It 'Passes Test-ModuleManifest' { + Test-ModuleManifest -Path $PSScriptRoot\..\$ModuleManifestName + $? | Should Be $true + } +} diff --git a/examples/en-US/about_SampleModule.help.txt b/examples/en-US/about_SampleModule.help.txt new file mode 100644 index 0000000000..7dc37ae5aa --- /dev/null +++ b/examples/en-US/about_SampleModule.help.txt @@ -0,0 +1,15 @@ +TOPIC + SampleModule 1.0.0 + +SHORT DESCRIPTION + You should considering providing an introduction and overview of your + module here. + +LONG DESCRIPTION + Discuss what the "primary" commands are in your module especially if + there are many commands. Discuss how to get started using this module + providing examples where appropriate. + +YOUR HEADER HERE + About topics in PowerShell are free-form text. Add headers to your + about topic as necessary. \ No newline at end of file