Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
79 commits
Select commit Hold shift + click to select a range
619f79f
Initial plan
Copilot Mar 20, 2026
2892ed5
Refactor ModuleFastSpec and ModuleFastInfo to C# binary module
Copilot Mar 20, 2026
00727bc
Address code review: simplify IsRequiredVersion logic, remove no-op U…
Copilot Mar 20, 2026
c715753
Update Pester tests for new C# project structure; fix code review issues
Copilot Mar 20, 2026
4e1f6bf
Convert PowerShell functions to C# binary cmdlets
Copilot Mar 20, 2026
4da8061
Add Artifacts Output Layout (Directory.Build.props) and Central Packa…
Copilot Mar 20, 2026
5343eaa
Apply dotnet format
JustinGrote Mar 21, 2026
40bb51f
Cleanup Artifact Publishing
JustinGrote Mar 22, 2026
834e120
Add debug message for loading process
JustinGrote Mar 22, 2026
69537de
Refactor Checkpoint
JustinGrote May 12, 2026
f967d6c
perf: async extraction, parallel pages, SemaphoreSlim throttle, HTTP/…
Copilot Jun 26, 2026
c31081d
fix: named constants for buffer sizes; robust zip-slip check via GetR…
Copilot Jun 26, 2026
0866e96
fix: robust zip-slip guard (canonical dest + StartsWith), safe Conten…
Copilot Jun 26, 2026
0d61067
fix: normalise both / and \\ in zip entry names; clamp Content-Length…
Copilot Jun 26, 2026
cec7484
feat: migrate to .NET 10 with Task.WhenEach, ZipFile.ExtractToDirecto…
Copilot Jun 26, 2026
32bcf97
Update PathHelper
JustinGrote Jun 26, 2026
5d5853a
Add TaskCmdlet and Generics
JustinGrote Jun 26, 2026
275b09c
Futher Updates
JustinGrote Jun 26, 2026
59ee396
Stage updates
JustinGrote Jun 26, 2026
8bd354c
First pass (tests failing)
JustinGrote Jun 27, 2026
a5e3488
Fix so all tests pass
JustinGrote Jun 27, 2026
6f3239f
Fix profile path exception
JustinGrote Jun 27, 2026
93252e0
Update for binary module bootstrap
JustinGrote Jun 27, 2026
5974b00
Add Github Action CI
JustinGrote Jun 27, 2026
58476fd
Improve local module detection performance
JustinGrote Jun 27, 2026
b0283d3
Cancel Token source present
JustinGrote Jun 27, 2026
50bab72
Add Resiliency
JustinGrote Jun 27, 2026
9357d6d
Reorganize into separate projects
JustinGrote Jun 27, 2026
6e84100
Add more coverage tests
JustinGrote Jun 27, 2026
e2c2b5c
merge: integrate origin/main (gitignore + psm1 bug fixes) — keep bina…
Copilot Jun 27, 2026
c94830a
fix: port Linux manifest case-fix, VSCode profile, NoProfileUpdate + …
Copilot Jun 27, 2026
2af58e4
fix: address review feedback — correct VSCode profile path, WriteLine…
Copilot Jun 27, 2026
281f4a2
REmove SMA from Console csproj
JustinGrote Jun 27, 2026
bebdfdc
Fix build process
JustinGrote Jun 27, 2026
507821b
feat: show per-module install progress with count and percentage
Copilot Jun 27, 2026
5cc7c68
fix: use Action callback for thread-safe progress and fix integer div…
Copilot Jun 27, 2026
41279af
Undo git track of artifacts
JustinGrote Jun 28, 2026
6054889
Intermediate conversion to TaskCmdlet
JustinGrote Jun 29, 2026
ffef936
Intermediate Commit for Messaging Issues
JustinGrote Jun 29, 2026
c7d7b40
Add explicit types for modulefastspec
JustinGrote Jun 29, 2026
a2dd516
First steps in fixing abstraction
JustinGrote Jun 29, 2026
a8d7e7d
Fix modulefast bootstrap
JustinGrote Jun 29, 2026
ce3711f
Further abstract logging from the core
JustinGrote Jun 29, 2026
f8d59d0
Reduce to .NET 10
JustinGrote Jun 29, 2026
03bd99b
Bump to 7.6
JustinGrote Jun 29, 2026
da3dc0c
Optimize output path
JustinGrote Jun 29, 2026
89a264e
Double default processor count
JustinGrote Jun 29, 2026
17cf38a
Remove ambiguity and max out concurrency
JustinGrote Jul 1, 2026
d504351
Add await performance optimizations and proxy support
JustinGrote Jul 1, 2026
432c840
Clean up compilation tokens
JustinGrote Jul 1, 2026
4fad1f3
Fix name violation
JustinGrote Jul 1, 2026
9792217
Update localmodulefinder for parallel
JustinGrote Jul 1, 2026
8043f81
Update to use nuget protocol client
JustinGrote Jul 1, 2026
bdf8011
More parallelization improvements
JustinGrote Jul 1, 2026
fa2f2d0
Update to use DirectDownload to avoid disk duplication
JustinGrote Jul 1, 2026
5e7277c
Fix Cmdlet Info
JustinGrote Jul 1, 2026
026047d
Update build and test instructions
JustinGrote Jul 1, 2026
2c3ba9c
Lots of Module Specification Changes, broken tests
JustinGrote Jul 2, 2026
a99a370
Cleanup test failures
JustinGrote Jul 2, 2026
5a1e730
Apply formatting to use explicit variable types
JustinGrote Jul 2, 2026
004e61a
Remove dead code
JustinGrote Jul 9, 2026
574a14d
Add Dependabot true
JustinGrote Jul 9, 2026
940b3d5
Fix devcontainer and trimming
JustinGrote Jul 9, 2026
d1ab1c0
Reduce more trimming
JustinGrote Jul 9, 2026
4122502
Update bootstrap to revert to v06 for now
JustinGrote Jul 10, 2026
d03d83b
Fix Paths
JustinGrote Jul 10, 2026
f5cb9ba
More test fixups
JustinGrote Jul 10, 2026
3e91023
Test
JustinGrote Jul 10, 2026
eaf4489
Try detailedErrorView
JustinGrote Jul 10, 2026
dfea117
Try with confirm
JustinGrote Jul 10, 2026
1d1e352
Bump rev and try again
JustinGrote Jul 10, 2026
0ac408d
Try with -nopsmodulepathupdate
JustinGrote Jul 10, 2026
5a1fd87
Modulepath workaround
JustinGrote Jul 10, 2026
c2c4d43
Update
JustinGrote Jul 10, 2026
26d91a4
Fix case matching
JustinGrote Jul 10, 2026
7fd4e83
Fix path helper to be rooted appropriately
JustinGrote Jul 10, 2026
850a0f5
Remove unnecessary lock file
JustinGrote Jul 11, 2026
631a4fc
Update ModuleFast bootstrap
JustinGrote Jul 11, 2026
9b30d0f
⬆️ Bump to Pester 6.0
JustinGrote Jul 16, 2026
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
30 changes: 30 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/dotnet
{
"name": "ModuleFast",
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
"image": "mcr.microsoft.com/devcontainers/dotnet:2-10.0-noble",
"features": {
// "ghcr.io/devcontainers-extra/features/powershell:1": {}
}

// Features to add to the dev container. More info: https://containers.dev/features.
// "features": {},

// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [5000, 5001],
// "portsAttributes": {
// "5001": {
// "protocol": "https"
// }
// }

// Use 'postCreateCommand' to run commands after the container is created.
// "postCreateCommand": "dotnet restore",

// Configure tool-specific properties.
// "customizations": {},

// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
// "remoteUser": "root"
}
390 changes: 390 additions & 0 deletions .editorconfig

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Testing
- Run `Invoke-Build Test` for tests. To run an individual test, run `Invoke-Build Test -TestName <test name>`.
- To run ModuleFast directly, use `Start-Job -ScriptBlock { Import-Module .\modulefast.psm1; <Your test code here> } | Receive-Job -Wait -AutoRemoveJob` to avoid module locking issues.

# Style
Read `.editorconfig` for style rules and indentation. Run `dotnet format` after making changes to C# files to update the formatting.
20 changes: 20 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for more information:
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
# https://containers.dev/guide/dependabot

version: 2
updates:
- package-ecosystem: devcontainers
directory: /
schedule:
interval: weekly
- package-ecosystem: nuget
directory: /
schedule:
interval: weekly
- package-ecosystem: dotnet-sdk
directory: /
schedule:
interval: weekly
110 changes: 110 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
name: ♻️ ModuleFast CI

on:
push:
branches:
- '*'
tags:
- 'v[0-9]*.[0-9]*.[0-9]*'
pull_request:
branches: [ main ]

defaults:
run:
shell: pwsh

jobs:
build:
name: 👷 Build
runs-on: ubuntu-24.04
outputs:
nupkg_artifact_id: ${{ steps.upload_nupkg.outputs.artifact-id }}
steps:
- name: 🚚 Checkout
uses: actions/checkout@v7
with:
fetch-depth: 0
- name: ⚡ Setup .NET
uses: actions/setup-dotnet@v5

- name: ⚡ Cache NuGet packages
uses: actions/cache@v6
with:
path: |
~/.nuget/packages
key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json', '**/Directory.Packages.props') }}
restore-keys: |
${{ runner.os }}-nuget-
- name: 👷 Build & Package
env:
MODULEVERSION: ${{ startsWith(github.ref, 'refs/tags/') && github.ref_name || null }}
run: |
try { ./build.ps1 BuildNoTest }
catch {
"::error::Build failed: $($_.Exception.Message)`n$(Get-Error | Out-String)" -replace "`n","%0A"
throw
}
- name: 📤 Upload Module
uses: actions/upload-artifact@v7
with:
name: ModuleFast
path: ./Artifacts/Module
- name: 📤 Upload Nupkg
id: upload_nupkg
uses: actions/upload-artifact@v7
with:
name: ModuleFast-nupkg
path: ./Artifacts/*.nupkg
archive: false

test:
name: 🧪 Test (${{ matrix.os }})
needs: build
strategy:
fail-fast: false
matrix:
os: [ubuntu-24.04, windows-2025]
runs-on: ${{ matrix.os }}
steps:
- name: 🚚 Checkout
uses: actions/checkout@v7
- name: 📥 Download Module
uses: actions/download-artifact@v8
with:
name: ModuleFast
path: ./Artifacts/Module
- name: 🧪 Test
run: |
$errorView = 'DetailedView'
.\build.ps1 Pester

publish:
name: 🚢 Publish to PowerShell Gallery
if: startsWith(github.ref, 'refs/tags/v')
needs: [build, test]
environment:
name: PowerShell Gallery
url: https://www.powershellgallery.com/packages/ModuleFast
runs-on: ubuntu-24.04
steps:
- name: 📥 Download Nupkg
uses: actions/download-artifact@v8
with:
artifact-ids: ${{ needs.build.outputs.nupkg_artifact_id }}
path: ./Release
- name: 🚢 Publish to PowerShell Gallery
env:
PSGALLERY_API_KEY: ${{ secrets.PSGALLERY }}
run: |
$DebugPreference = 'Continue'
$VerbosePreference = 'Continue'

$nupkg = Get-ChildItem -Path ./Release/*.nupkg
if ($nupkg.Count -eq 0) {
throw "No nupkg found in Release directory"
} elseif ($nupkg.Count -gt 1) {
throw "Multiple nupkg files found: $($nupkg.FullName -join ', ')"
}

Register-PSResourceRepository -PSGallery -Force
Publish-PSResource -Nupkg $nupkg.FullName -ApiKey $env:PSGALLERY_API_KEY
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
Build
artifacts
/[aA]rtifacts
18 changes: 18 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"configurations": [
{
"name": "PowerShell: Binary Module Interactive",
"type": "PowerShell",
"request": "launch",
"createTemporaryIntegratedConsole": true,
"attachDotnetDebugger": true
},
{
"name": "ModuleFast: Pester",
"type": "PowerShell",
"request": "launch",
"script": "Invoke-Build Test",
"createTemporaryIntegratedConsole": true
}
]
}
21 changes: 21 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"type": "shell",
"command": "Invoke-Build",
"args": [
"Build"
],
"group": {
"isDefault": true,
"kind": "build"
},
"presentation": {
"reveal": "silent"
},
"problemMatcher": "$msCompile"
}
]
}
7 changes: 7 additions & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<Project>
<PropertyGroup>
<!-- Use the .NET SDK Artifacts Output Layout: all bin/obj go to artifacts/ -->
<UseArtifactsOutput>true</UseArtifactsOutput>
<ArtifactsPath>$(MSBuildThisFileDirectory)/Artifacts</ArtifactsPath>
</PropertyGroup>
</Project>
12 changes: 12 additions & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<Project>
<PropertyGroup>
<!-- Central Package Management: all NuGet versions defined here -->
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="System.Management.Automation" Version="7.6.0" />
<PackageVersion Include="NuGet.Protocol" Version="7.6.0" />
<PackageVersion Include="NuGet.Versioning" Version="7.6.0" />
<PackageVersion Include="Polly.Core" Version="8.7.0" />
</ItemGroup>
</Project>
70 changes: 70 additions & 0 deletions ModuleFast.Format.ps1xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<Configuration>
<ViewDefinitions>
<View>
<Name>ModuleFastSpec</Name>
<ViewSelectedBy>
<TypeName>ModuleFast.ModuleFastSpec</TypeName>
<TypeName>ModuleFastSpec</TypeName>
</ViewSelectedBy>
<TableControl>
<AutoSize>true</AutoSize>
<TableHeaders>
<TableColumnHeader>
<Label>Name</Label>
</TableColumnHeader>
<TableColumnHeader>
<Label>Version</Label>
</TableColumnHeader>
</TableHeaders>
<TableRowEntries>
<TableRowEntry>
<TableColumnItems>
<TableColumnItem>
<PropertyName>Name</PropertyName>
</TableColumnItem>
<TableColumnItem>
<ScriptBlock>$_.GetVersionString() -replace '^@'</ScriptBlock>
</TableColumnItem>
</TableColumnItems>
</TableRowEntry>
</TableRowEntries>
</TableControl>
</View>
<View>
<Name>ModuleFastInfo</Name>
<ViewSelectedBy>
<TypeName>ModuleFast.ModuleFastInfo</TypeName>
<TypeName>ModuleFastInfo</TypeName>
</ViewSelectedBy>
<TableControl>
<AutoSize>true</AutoSize>
<TableHeaders>
<TableColumnHeader>
<Label>Name</Label>
</TableColumnHeader>
<TableColumnHeader>
<Label>ModuleVersion</Label>
</TableColumnHeader>
<TableColumnHeader>
<Label>Location</Label>
</TableColumnHeader>
</TableHeaders>
<TableRowEntries>
<TableRowEntry>
<TableColumnItems>
<TableColumnItem>
<PropertyName>Name</PropertyName>
</TableColumnItem>
<TableColumnItem>
<PropertyName>ModuleVersion</PropertyName>
</TableColumnItem>
<TableColumnItem>
<PropertyName>Location</PropertyName>
</TableColumnItem>
</TableColumnItems>
</TableRowEntry>
</TableRowEntries>
</TableControl>
</View>
</ViewDefinitions>
</Configuration>
Loading