Getting Started
Pre-requisites¶
To modify the module, you will need git. You can use scoop to install it. Scoop will also allow you to install vscode that is the preferred development environment.
In order to run pre-commit and build the documentation, you will need python
pipx and uv installed. This can be done easily with scoop:
Then you can install the pre-commit using pipx:
SQLite wrapper¶
Wsl-Manager stores image and image source information in a SQLite database. It
uses a C# wrapper around the SQLite library (Wsl-SQLite\SQLiteHelper.cs). By
default this wrapper is built at runtime using the Add-Type cmdlet and the
pre-installed .NET Framework on Windows. However, you will incur a small delay
when the module is first imported. To avoid this delay, you can pre-build the
wrapper using the dotnet SDK. You can install it using scoop:
You can of course also install the dotnet SDK using other methods (see Microsoft documentation. Then build the wrapper by running the following command from the root of the project under PowerShell 7+ :
About the pre-built SQLite wrapper
The pre-built SQLite wrapper is located in Wsl-SQLite\bin\<sdk>\SQLiteHelper.dll.
SDK is one of net48, net8.0 or net8.0-windows. You will need a recent
version of the .NET SDK (8.0+) to build the net8.0 or net8.0-windows versions.
Getting started¶
To modify the module, first fork it on github and in clone your copy in your local modules directory:
PS> New-Item -Path $env:USERPROFILE\Documents\WindowsPowerShell\Modules -Force | Out-Null
PS> cd $env:USERPROFILE\Documents\WindowsPowerShell\Modules\
PS> git clone https://github.com/<yourusername>/PowerShell-Wsl-Manager Wsl-Manager
Having it in $env:USERPROFILE\Documents\WindowsPowerShell\Modules\ ensures
that the module is loaded from the correct location when you import it in your
PowerShell session.
Another option (not recommended) is to add the directory where the module source
code has been cloned to $env:PSModulePath:
PS> $env:PSModulePath = (Get-Item -Path .).Parent.FullName + [System.IO.Path]::PathSeparator + $env:PSModulePath
However, this approach is not recommended as it can lead to confusion about the module's location and make it harder to manage dependencies.
The source code of the module is organized as follows (only the relevant files/directories are shown):
.
|-- .editorconfig # Editor configuration
|-- .github/ # GitHub configuration (GHA workflows)
|-- .pre-commit-config.yaml # Pre-commit hooks configuration
|-- .prettierrc # Prettier configuration
|-- .python-version # Python version
|-- .vscode/ # Visual Studio settings and launch configurations
|-- Dockerfile # Sample image Dockerfile
|-- PowerShell-Wsl-Manager.sln # Visual Studio solution file for SQLite wrapper
|-- Wsl-Common/ # Common PowerShell code
|-- Wsl-Image/ # Image management PowerShell code
|-- Wsl-ImageSource/ # Image source management PowerShell code
|-- Wsl-Instance/ # Instance management PowerShell code
|-- Wsl-SQLite/ # SQLite wrapper PowerShell and C# code
|-- Wsl-Manager.Format.ps1xml # [WslImage] and [WslInstance] formatting rules
|-- Wsl-Manager.Types.ps1xml # Classes computed properties
|-- Wsl-Manager.psd1 # Module definition
|-- Wsl-Manager.psm1 # Main Module file
|-- configure.sh # Instance configuration script
|-- cspell.json # Spell checker configuration
|-- docs/ # Module documentation
|-- hack/ # Additional code
|-- mkdocs.yml # Documentation configuration (mkdocs)
|-- p10k.zsh # Powerlevel10k configuration
|-- pyproject.toml # Python project configuration (mkdocs)
|-- src/ # Python Source code (mkdocs)
|-- tests/ # Unit tests
`-- uv.lock # UV lock file (documentation dependencies)
The source code of the module is located in Wsl-Common, Wsl-Image,
Wsl-ImageSource, Wsl-Instance and Wsl-SQLite directories, as well as in
the Wsl-Manager.psm1 file. After a modification, you need to ensure that the
new version is loaded into memory with:
No unloading of Classes
Class definitions are not unloaded when the module is reloaded (see powershell documentation). This means that if you modify a class definition, you need to close and re-create your Powershell session.
Adding a new Exported cmdlet¶
To add a new cmdlet, you need to first create the function in one of the
Wsl-<Class>\Wsl-<Class>.Cmdlets.ps1 files, where <Class> is the class on
which the cmdlet operates. For example, to add a cmdlet operating on
WslInstance objects, you would add it to the
Wsl-Instance\Wsl-Instance.Cmdlets.ps1 file.
We prefer to put the documentation after the function declaration and before
the parameters declaration.
About Cmdlet Verbs
PowerShell is picky about cmdlet verbs. The list of approved verbs is available here.
Then export the function by adding it to the FunctionsToExport array of the
Wsl-Manager.psd1 file:
# Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export.
FunctionsToExport = @("New-WslInstance", ..., "<approved_verb>-Wsl...")
We encourage you to create aliases for your cmdlets to make them easier to use.
Add your aliases at the end of Wsl-Manager.psm1:
And add them to the AliasesToExport array in the Wsl-Manager.psd1 file:
Then by removing the module, you are able to test the cmdlet:
Adding a new Object class¶
To add a new Object class, create a directory named after the name of the class,
Wsl-<Something>. Inside this directory, split the code into several files.
Let's look at the Wsl-Instance directory:
./Wsl-Instance/
|-- Wsl-Instance.Cmdlets.ps1 # Cmdlets operating on WslInstance objects
|-- Wsl-Instance.Helpers.ps1 # Helper functions for WslInstance objects
`-- Wsl-Instance.Types.ps1 # Type definitions for WslInstance objects
Once the code created and tested (see testing), add the new files
to the Wsl-Manager.psd1 file in NestedModules and FileList:
NestedModules = @(
'Wsl-Common\Wsl-Common.Types.ps1',
'Wsl-Common\Wsl-Common.Helpers.ps1',
...
# Add your files here
)
...
FileList = @(
"p10k.zsh",
...
# Add your files here
)
Building the documentation¶
The documentation is built using mkdocs. You can build and serve the
documentation locally by running:
When you modify the documentation, the changes are automatically refreshed in your browser.
About documentation auto-update
On windows, the refresh of the documentation after a modification is quite
slow. It's much more convenient to update the documentation inside a WSL
instance .
However, don't use the source code cloned on a Windows directory,
but instead re-clone the project under WSL.
The final documentation can be built with:
Pre-commit routine¶
Before committing your changes, ensure that you have:
- Updated the documentation (see above)
- Write the appropriate tests in order to test the new features and stay above 85% of code coverage.
-
Run all tests with the following command:
-
Updated the cmdlets reference documentation with the following command:
-
Check for typos / linting errors by running
pre-commit: