- Read this guide (including the Code of Conduct)
- Check out our Trello page to see what features and fixes are planned.
- Fork this repository and clone your fork locally
- Setup your environment to use development tasks (test, lint, etc...)
- Adhere to the project standards
- Write some code and stuff...
- Push your changes and create a pull request
Please read and adhere to the code of conduct
First off, thank you for considering contributing to
Prelude!
If you would like to make a feature request or enhancement suggestion, please open an issue.
If you would like to generously provide a pull request to correct a verified issue, please adhere to this project's standards. Before making a pull request for a desired feature, please socialize the concept by opening an issue first.
The Prelude module entry point, Prelude.psm1, simply imports the functions of every .ps1 file in the src folder. The files in the src directory are named according to the general category of the functions it contains:
Prelude\src\application.ps1: Functions that can be used to create a PowerShell command line applicationapplied.ps1: Functions for performing applied mathematics such as probability, combinatorics, and statisticscore.ps1: Functional helper functions likeInvoke-ReduceandTest-Equal. These functions typically do not have dependencies on other files in the src folderdata.ps1: Functions for ingesting, analyzing, and shaping various types of dataevents.ps1: Functions needed for event-driven operations (inspired byBackbone.EventsAPI)graph.ps1: Helper functions for working with[Node],[Edge], and[Graph]data types.matrix.ps1: Helper functions for using[Matrix]data typeproductivity.ps1: A grab bag that contains functions likeTouch,Take, andTest-Emptyweb.ps1: Functions for working with web technology
Prelude\formats\Prelude\types\Prelude\Prelude.psd1: Prelude module manifest filePrelude\Prelude.psm1: Prelude module entry point
The Prelude project contains C# code that is added to the module as dynamic link libraries (DLLs). The code is organized as a single solution with multiple projects:
csharp\Matrix\- Project directory for
[Matrix]type accelator [5]
- Project directory for
Geodetic\- Project directory for
[Coordinate]and[Datum]type accelators [5]
- Project directory for
Graph\- Project directory for
[Graph],[Edge],[DirectedEdge], and[Node]type accelators [5]
- Project directory for
Performance\- Project directory for C# benchmarks
NOTE: Benchmarks are executed using BenchmarkDotNet
Tests\- Project directory for C# tests
Project Setup [1]
Friends don't let friends use PowerShell without Windows Terminal. Please follow these instructions to customize your terminal and achieve new levels of epic productivity — "I can't believe it's not Linux!" ™
Prelude uses a build script for PowerShell development tasks and dotnet for C# tasks.
Requirements
dotnetcommand line tool is required to install tools, run tasks, and build code- BuildHelpers is required for dev tasks
- Pester is required to run PowerShell tests
- PSScriptAnalyzer is required to lint PowerShell code
dotnet tool restore
Install-Module -Force -Scope CurrentUser -Name BuildHelpers
Install-Module -Force -Scope CurrentUser -Name Pester -SkipPublisherCheck -RequiredVersion 5.0.4
Install-Module -Force -Scope CurrentUser -Name PSScriptAnalyzerAll PowerShell tasks are contained within Invoke-Task.ps1 and can be executed via the following commands:
| Purpose | Command |
|---|---|
| Lint ALL code | .\Invoke-Task.ps1 -Lint |
| Lint ONLY POWERSHELL code | .\Invoke-Task.ps1 -Lint -Skip dotnet |
| Lint ALL code and run ALL tests | .\Invoke-Task.ps1 -Lint -Test |
| ALL tests | .\Invoke-Task.ps1 -Test |
| ONLY PowerShell tests | .\Invoke-Task.ps1 -Test -Skip dotnet |
| ONLY WINDOWS PowerShell tests | .\Invoke-Task.ps1 -Test -Skip 'dotnet' |
| ONLY LINUX PowerShell tests | .\Invoke-Task.ps1 -Test -Skip 'dotnet' -Platform Linux |
| ALL tests with coverage [3] | .\Invoke-Task.ps1 -Test -WithCoverage -GenerateCoverageReport |
| ...and open coverage report | .\Invoke-Task.ps1 -Test -WithCoverage -GenerateCoverageReport -Show |
NOTE: PowerShell tests are located in the
/testsdirectory
Requirements
NOTE: The easiest way to install .NET is to use Visual Studio Community
Lint C# code
.\Invoke-Task.ps1 -Lint -Skip powershellRun C# Tests
.\Invoke-Task.ps1 -Test -Skip powershellNOTE: C# tests are located in the
src/cs/Testsdirectory
Run C# Benchmarks
NOTE: C# benchmarks depend on BenchmarkDotNet
.\Invoke-Task.ps1 -BenchmarkGeneral Development
- Install VSCode
- Install PowerShell VSCode extension
Note: When you open the
pwsh-preludeproject in VS Code, it will suggest you install some extensions...they are all really handy and highly recommended 🤓
Linux Development within Docker Container
-
New functions should be added to the file most closely related to the intended purpose of the new function, in alphabetical order.
-
Running
.\Invoke-Task.ps1 -Lintshould not return any issues (this includes naming functions using PowerShell "approved" verbs) -
Tests should have no failures when run locally
Windows:
.\Invoke-Task.ps1 -Test -Tags LocalLinux:
./Invoke-Task.ps1 -Test -Tags Local -Platform Linux -
Tests should have no failures when run remotely
Platform Status Windows Linux -
Exceptions to any of these standards should be supported by strong reasoning and sufficient effort
-
Although this project has many rules [3], running
./Invoke-Task.ps1 -Lintshould automatically enforce most of them. In any case, here are some standards to keep in mind:- Use four-spaces for indentation [4]
- Variables should be PascalCase (ex:
$Foo,$MyEvent, etc...) - Function names should be of the form,
Verb-SomeThing, whereVerbis an "approved" verb (see PowerShell'sGet-Verbcmdlet) - Types and type accelators should be PascalCase (ex:
[String],[Int], etc...). - Operators should be lowercase (ex:
-eq,-not,-match, etc...) [4] - Variable scopes should be PascalCase (ex:
$Script:,$Env:,$Global:, etc...) - Do not use aliases [4]
- Use single quotes unless double quotes are required (ex: variable interpolation, special characters, etc...) [4]
- Single space after higher-order functions like
ForEach-ObjectandWhere-Object[4] - Single-line scriptblocks should have a single space after the opening bracket and before the closing bracket [4]
# Example Get-ChildItem -File | ForEach-Object { $_.FullName }
- Hashtables (and custom objects) should have a single space after the opening bracket and before the closing bracket [4]
# Example @{ foo = 'bar' }
- Semi-colons should be followed by a single space [4]
# Examples @{ a = 'a'; b = 'b'; c = 'c' } [PSCustomObject]@{ a = 'a'; b = 'b'; c = 'c' }
- Comparison operators (like
=) should have a single space before and after, except for values in[Parameter(...)]decorator (ex:$Foo = 'bar',[Parameter(Mandatory=$true, Position=0)]) [4] - Use the "One True Brace Style" (1TBS) [4]
if ($Condition) { # code code code } else { # code code code } function Invoke-Awesome { # code code code }
- Prefer pipelines and avoid un-necessary variable declarations.
- Use
DarkGraywhen usingWrite-Colorwithin "WhatIf" blocks.if ($PSCmdlet.ShouldProcess($Path)) { # code code code } else { '==> Would have executed code code code' | Write-Color -DarkGray }
- When in doubt, write code that is consistent with preponderance of existing codebase. Let's call this the "priority of pre-existing preponderance rule".
In an effort to maximize cross-platform support, tests are run on Windows and Linux. However, Windows 10 is the only officially supported OS for development on this project. There should be a good reason for tests not passing on all platforms (ex: Using windows speech recognition libraries)
-WithCoverageand-ShowCoverageReportrequire that ReportGenerator is installed andreportgenerator.exeis available from the command line.
The rules for this project are configured in three places:
- Default PSScriptAnalyzer rules
- Rules enabled by
PSScriptAnalyzerSettings.psd1 - Custom rules defined within
PSScriptAnalyzerCustomRules.psm1
Should be "auto-fixed" by
.\Invoke-Task.ps1 -Lint
PowerShell type accelerators are added dynamic link libraries built from associated C# code