Add Shmuelie.Dsc: class-based DSC v3 resources for machine setup - #115
Conversation
Introduce a new Shmuelie.Dsc module providing five class-based DSC v3 resources for developer machine setup: - SavePSResource: save a PowerShell module to a local path (Save-PSResource). - SymbolicLink: create/verify a symbolic link to a target path. - CopilotPlugin: install a GitHub Copilot CLI plugin. - CopilotMarketplace: register a GitHub Copilot CLI marketplace. - UvTool: install a Python tool via uv. The Copilot and uv resources build on the public copilot and uv CLIs through small private wrappers so the resource classes are unit-testable; the others use built-in PowerShell only. The module is wired into the build, the publish workflow, the documentation site, and the Pester suite. Build-Module.ps1 now stages a module's Public folder only when it exists, so resource-only modules (with no Public scripts) build. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b98f01a0-a039-492f-8576-b1917e54742d
Peer review — multi-persona panel (advisory)Reviewed by a Code panel (Correctness, Skeptic, Craft, Compliance, Architect) plus a Writing pass on the description. Findings below are grouped by severity with the personas that raised each. The build and full test suite are green; these are correctness/robustness observations, not CI failures. 🔴 Blocking1. Recommendation: match whole tokens. For
🟠 Important2. 3. 4. CLI output capture is fragile: 5. No validation of author-supplied args before a 🟡 Minor
✅ Verified solid / dismissed
Advisory review — nothing here gates the PR. The one blocking item (#1, with its test-coverage sibling) is the only "should fix before merge" in my view; the rest are quality/robustness improvements. |
Address the peer-review findings on the DSC resources: - Presence checks (CopilotPlugin/CopilotMarketplace/UvTool) now use whole-token matching over ANSI-stripped CLI output instead of an unanchored substring match, so a desired name that is a substring of an installed one no longer yields a false positive that silently skips installation. - The CLI wrappers set NO_COLOR/UV_NO_COLOR, strip ANSI escapes, and coerce output to strings for robust parsing. - Get() now reports actual state via a read-only Installed property (SymbolicLink already reported the real link target). - CopilotPlugin resolves the plugin name from owner/repo, plugin@marketplace, and market:plugin@marketplace forms, and accepts an explicit Name for URL sources. - CLI arguments are validated as shell-safe before invoking copilot/uv (guards the .cmd/.bat shim re-parsing class on Windows). - SavePSResource gains an optional Version property (version-aware Test and Save). - Set() failures include the CLI output in the error message. - Build-Module.ps1 fails fast if a module declares functions but has no Public folder. Tests expanded to 26 cases covering token matching (incl. substring non-matches), Get()/Installed, URL/market: name resolution, argument validation, ANSI stripping, and versioned SavePSResource. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b98f01a0-a039-492f-8576-b1917e54742d
|
Applied the review findings in 428ecb0: whole-token matching over ANSI-stripped output (blocking substring bug), stateful \Get()\ via a read-only \Installed\ property, \market:/URL name resolution with an explicit \Name, shell-safe argument validation, hardened CLI wrappers (NO_COLOR + string coercion), \SavePSResource\ \Version, CLI output in error messages, and a \Build-Module\ fail-fast. Tests expanded to 26 cases (incl. substring non-matches, \Get()/\Installed, arg validation, ANSI, versioned save); full suite 335 passed, 0 failed. The one dismissed finding (missing module CHANGELOG) remains a false positive — the file exists and Test-Modules enforces it. |
Adds a new
Shmuelie.Dscmodule of class-based DSC v3 resources for developer machine setup — the public-safe counterparts to a private set of setup resources. Each resource is a PowerShell class implementingGet()/Test()/Set(), exported viaDscResourcesToExport.Resources
SavePSResourceNameSave-PSResource, defaults toPSGallery; optionalVersion)Microsoft.PowerShell.PSResourceGetSymbolicLinkPathCopilotPluginSourcecopilotCLICopilotMarketplaceNamecopilotCLIUvToolNameuv tool install)uvCLIDesign details:
NO_COLOR/UV_NO_COLORand strip ANSI escapes so colorized output doesn't defeat the checks.Get()reports actual observed state (a read-onlyInstalledproperty on the CLI/save resources; the real link target onSymbolicLink).CopilotPluginderives the plugin name fromowner/repo,plugin@marketplace, andmarket:plugin@marketplace; for URL sources set the optionalNameproperty so the presence check matches..cmd/.batre-parsing class), andSet()failures include the CLI's output.Build / infra
Shmuelie.DscinBuild-Module.ps1,Publish-Module.ps1,Test-Modules.ps1, and the publish workflow (choice + tag regex).Build-Module.ps1now stages a module'sPublicfolder only when it exists (so resource-only modules build) and fails fast if a module declares functions but has noPublicfolder.docs/index.md,docs/modules.md) and root README updated.Tests
tests/Shmuelie.Dsc.Tests.ps1covers each resource'sGet()/Test()/Set()logic (26 cases), including whole-token matching with substring non-matches,market:/URL name resolution, argument validation, ANSI stripping, and versionedSavePSResource. The tests mock the CLI wrappers, so they validate resource logic and command invocation — not live Copilot/uv output formats. Full suite: 335 passed, 0 failed;Test-Modules.ps1green.Scope
AgencyPluginfrom the private set is intentionally excluded: it depends on internal-only tooling and has no public-safe form.Closes #110
Closes #111
Closes #112
Closes #113
Closes #114