-
Notifications
You must be signed in to change notification settings - Fork 0
Developer Guide
Relevant source files
The following files were used as context for generating this wiki page:
This guide provides comprehensive information for developers contributing to OfficeScrubC2R. It covers the development environment setup, build process, code organization, testing procedures, and release workflow. For information about using OfficeScrubC2R as an end user, see User Guide. For architectural details about how the system works internally, see Architecture.
This guide is intended for:
- Contributors adding features or fixing bugs
- Maintainers managing releases and CI/CD
- Developers creating forks or derivative works
- Technical reviewers understanding the codebase
Before beginning development, you must have:
| Requirement | Version | Purpose |
|---|---|---|
| Windows | 10/11 or Server 2016+ | Development and testing platform |
| PowerShell | 5.1 or 7+ | Module development and testing |
| .NET Framework | 4.5+ | Native library compilation (csc.exe) |
| .NET SDK | 7.0+ (optional) | Cross-platform compilation |
| Git | Latest | Version control |
| Administrator Rights | Required | Testing cleanup operations |
Optional but Recommended:
- PSScriptAnalyzer module for code analysis
- Pester module for testing
- Windows Sandbox or Hyper-V for safe testing
Sources: docs/memory-bank/product.md:59-64, CONTRIBUTING.md:44-56
# Clone the repository
git clone https://github.com/Calvindd2f/OfficeScrubC2R.git
cd OfficeScrubC2R
# Install development dependencies
Install-Module -Name PSScriptAnalyzer -Scope CurrentUser
Install-Module -Name Pester -Scope CurrentUser
# Build the native library
.\build.ps1
# Import the module for testing
Import-Module .\OfficeScrubC2R.psd1 -Force
# Run code analysis
Invoke-ScriptAnalyzer -Path . -Recurse
# Test detection (safe, no modifications)
Invoke-OfficeScrubC2R -DetectOnly -VerboseSources: CONTRIBUTING.md:44-69
graph TB
subgraph "Development Machine"
Editor["Code Editor<br/>VS Code / ISE"]
Git["Git Client<br/>Version Control"]
PS["PowerShell<br/>5.1 or 7+"]
end
subgraph "Source Files"
PSM["OfficeScrubC2R.psm1<br/>Main Module"]
UTIL["OfficeScrubC2R-Utilities.psm1<br/>Utilities"]
CS["OfficeScrubC2R-Native.cs<br/>C# Source"]
PSD["OfficeScrubC2R.psd1<br/>Manifest"]
end
subgraph "Build Tools"
BuildScript["build.ps1<br/>Build Orchestrator"]
CSC["csc.exe<br/>.NET Framework Compiler"]
DotNet["dotnet build<br/>.NET Core Compiler"]
end
subgraph "Build Artifacts"
DLL["OfficeScrubNative.dll<br/>.NET Framework 4.5"]
CoreDLL["OfficeScrubNative.Core.dll<br/>.NET Core 7+"]
end
subgraph "Verification Tools"
PSA["PSScriptAnalyzer<br/>Code Analysis"]
Pester["Pester<br/>Unit Tests"]
Verify["Verify-NativeBuild.ps1<br/>Build Verification"]
Validate["Validate-Module.ps1<br/>Module Validation"]
end
subgraph "Testing Environment"
Sandbox["Windows Sandbox<br/>Safe Testing"]
VM["Virtual Machine<br/>Full Testing"]
end
Editor --> PSM
Editor --> UTIL
Editor --> CS
Editor --> PSD
BuildScript --> CSC
BuildScript --> DotNet
CS --> CSC
CS --> DotNet
CSC --> DLL
DotNet --> CoreDLL
PSM --> PSA
UTIL --> PSA
DLL --> Verify
CoreDLL --> Verify
PSD --> Validate
DLL --> PS
PSM --> PS
PS --> Sandbox
PS --> VM
Git --> PSM
Git --> CS
Diagram: Development Environment Setup
This diagram shows the complete development environment. Developers work with four main source files (OfficeScrubC2R.psm1, OfficeScrubC2R-Utilities.psm1, OfficeScrubC2R-Native.cs, OfficeScrubC2R.psd1) using their preferred editor. The build.ps1 script orchestrates compilation using either csc.exe for .NET Framework or dotnet build for .NET Core. Verification tools (PSScriptAnalyzer, Pester, Verify-NativeBuild.ps1, Validate-Module.ps1) ensure code quality and correctness. Testing occurs in isolated environments (Windows Sandbox or VMs) to prevent damage to the development machine.
Sources: docs/memory-bank/structure.md:1-59, CONTRIBUTING.md:44-56
flowchart TD
Start["Start Development"] --> Fork["Fork Repository"]
Fork --> Clone["git clone<br/>Local Copy"]
Clone --> Branch["git checkout -b<br/>feature/branch-name"]
Branch --> Code["Edit Source Files"]
Code --> Build[".\build.ps1<br/>Compile Native DLL"]
Build --> BuildOK{Build<br/>Success?}
BuildOK -->|No| FixBuild["Fix Build Errors"]
FixBuild --> Build
BuildOK -->|Yes| Analyze["Invoke-ScriptAnalyzer<br/>Code Quality Check"]
Analyze --> AnalyzeOK{PSScriptAnalyzer<br/>Pass?}
AnalyzeOK -->|No| FixAnalyze["Fix Analysis Issues"]
AnalyzeOK -->|Yes| Test["Manual Testing<br/>Import & Run"]
FixAnalyze --> Analyze
Test --> TestOK{Tests<br/>Pass?}
TestOK -->|No| FixTest["Fix Test Failures"]
FixTest --> Code
TestOK -->|Yes| Commit["git commit -m<br/>'Clear Message'"]
Commit --> Push["git push origin<br/>feature/branch-name"]
Push --> PR["Create Pull Request<br/>on GitHub"]
PR --> CI["GitHub Actions<br/>CI Pipeline Runs"]
CI --> CIOK{CI<br/>Pass?}
CIOK -->|No| FixCI["Fix CI Failures"]
FixCI --> Code
CIOK -->|Yes| Review["Code Review<br/>by Maintainers"]
Review --> ReviewOK{Review<br/>Approved?}
ReviewOK -->|Changes Needed| Address["Address Feedback"]
Address --> Code
ReviewOK -->|Approved| Merge["Merge to Main"]
Merge --> Release["Release Process<br/>if applicable"]
Diagram: Development and Contribution Workflow
This flowchart illustrates the complete development cycle. Developers fork the repository, create feature branches, make code changes, and build using build.ps1. Code quality is verified with Invoke-ScriptAnalyzer, followed by manual testing. Changes are committed with clear messages and pushed to the fork. Pull requests trigger the GitHub Actions CI pipeline (.github/workflows/ci.yml), which must pass before code review. After maintainer approval, changes merge to the main branch and may be included in releases.
Sources: CONTRIBUTING.md:34-43, docs/memory-bank/structure.md:37-46
graph TB
subgraph "Root Files"
PSD1["OfficeScrubC2R.psd1<br/>Module Manifest<br/>Version, Dependencies, Exports"]
PSM1["OfficeScrubC2R.psm1<br/>Main Module<br/>Entry Points, Orchestration"]
UTIL["OfficeScrubC2R-Utilities.psm1<br/>Nested Module<br/>Helper Functions"]
CS["OfficeScrubC2R-Native.cs<br/>C# Source<br/>4000+ lines"]
DLL["OfficeScrubNative.dll<br/>Pre-compiled Binary<br/>Performance Layer"]
BUILD["build.ps1<br/>Build Script<br/>Compilation Logic"]
end
subgraph "Configuration"
PSAA["PSScriptAnalyzerSettings.psd1<br/>Linter Rules"]
GIT[".gitignore<br/>.gitattributes<br/>Git Config"]
end
subgraph "docs/"
BUILD_MD["BUILD.md<br/>Build Instructions"]
CHANGELOG["CHANGELOG.md<br/>Version History"]
CONTRIB["CONTRIBUTING.md<br/>Contributor Guide"]
CHECKLIST["CHECKLIST.md<br/>Development Checklist"]
SOURCE["source/<br/>Original VBScript<br/>Reference Implementation"]
end
subgraph ".github/"
CI["workflows/ci.yml<br/>GitHub Actions<br/>Test & Validate Jobs"]
SCRIPTS["scripts/<br/>utils.ps1<br/>Validate-Module.ps1"]
end
subgraph "tests/"
TEST["Test-OfficeScrubC2R.ps1<br/>Module Test Suite"]
VERIFY["Verify-NativeBuild.ps1<br/>Build Verification"]
end
subgraph "Native Library Classes"
ORCH["OfficeScrubOrchestrator<br/>Central Coordinator"]
REG["RegistryHelper<br/>Registry Operations"]
FILE["FileHelper<br/>File Operations"]
PROC["ProcessHelper<br/>Process Management"]
MSI["WindowsInstallerHelper<br/>MSI Cleanup"]
OTHER["TypeLibHelper<br/>LicenseHelper<br/>ServiceHelper<br/>ShellHelper<br/>GuidHelper"]
end
PSM1 -.imports.-> UTIL
PSM1 -.loads.-> DLL
BUILD -.compiles.-> CS
CS -.produces.-> DLL
CS -.contains.-> ORCH
CS -.contains.-> REG
CS -.contains.-> FILE
CS -.contains.-> PROC
CS -.contains.-> MSI
CS -.contains.-> OTHER
CI -.runs.-> BUILD
CI -.runs.-> TEST
CI -.validates.-> PSD1
Diagram: Repository Structure and Component Relationships
This diagram maps the physical file structure to logical components. The root contains the four primary source files (OfficeScrubC2R.psd1, OfficeScrubC2R.psm1, OfficeScrubC2R-Utilities.psm1, OfficeScrubC2R-Native.cs) along with the pre-compiled OfficeScrubNative.dll and build.ps1 script. The docs/ directory holds documentation, .github/ contains CI/CD configuration, and tests/ has validation scripts. The OfficeScrubC2R-Native.cs file contains nine major classes (shown bottom right): OfficeScrubOrchestrator coordinates eight specialized helpers for different Windows subsystems.
Sources: docs/memory-bank/structure.md:1-59, docs/memory-bank/structure.md:61-79
The codebase uses a two-layer hybrid architecture:
| Layer | Technology | Files | Purpose |
|---|---|---|---|
| Orchestration Layer | PowerShell |
OfficeScrubC2R.psm1OfficeScrubC2R-Utilities.psm1
|
User interface, workflow control, parameter handling |
| Performance Layer | C# |
OfficeScrubC2R-Native.csOfficeScrubNative.dll
|
High-speed registry/file operations, Win32 APIs |
Why This Matters for Developers:
- PowerShell changes affect user interface, parameter validation, logging, workflow
- C# changes affect performance-critical operations, Win32 API calls, parallel processing
- Changes to helper classes in C# require recompilation with
build.ps1 - Changes to PowerShell only require module reload (
Import-Module -Force)
Sources: docs/memory-bank/structure.md:80-99, docs/memory-bank/product.md:26-32
flowchart LR
subgraph "Input"
Source["OfficeScrubC2R-Native.cs<br/>4000+ lines C#"]
end
subgraph "build.ps1 Logic"
Check{".NET<br/>Framework<br/>Available?"}
Framework["csc.exe<br/>/target:library<br/>/optimize+"]
Core["dotnet build<br/>--configuration Release"]
end
subgraph "Outputs"
FW["OfficeScrubNative.dll<br/>.NET Framework 4.5+<br/>Windows PowerShell"]
NC["OfficeScrubNative.Core.dll<br/>.NET Core 7+<br/>PowerShell 7+"]
end
subgraph "Verification"
Load["Test Assembly Load<br/>both PS editions"]
Export["Verify Type Export<br/>Classes Available"]
end
Source --> Check
Check -->|Yes| Framework
Check -->|No| Core
Framework --> FW
Core --> NC
FW --> Load
NC --> Load
Load --> Export
Diagram: Build System Flow
The build.ps1 script detects available .NET tools and compiles OfficeScrubC2R-Native.cs using the appropriate compiler. When .NET Framework is available, it uses csc.exe with optimization flags to produce OfficeScrubNative.dll for Windows PowerShell 5.1. Optionally, it uses dotnet build to create OfficeScrubNative.Core.dll for PowerShell 7+. Verification steps ensure both assemblies load correctly and export expected types (OfficeScrubOrchestrator, helper classes).
Sources: docs/memory-bank/structure.md:117-124, CONTRIBUTING.md:58-68
The OfficeScrubC2R-Native.cs file defines the following class structure:
OfficeScrubOrchestrator (main coordinator)
├── RegistryHelper (constructor parameter)
│ ├── KeyExists()
│ ├── DeleteKey()
│ ├── DeleteValue()
│ ├── EnumerateKeys()
│ ├── GetValue()
│ └── SetValue()
├── FileHelper (constructor parameter)
│ ├── DeleteFile()
│ ├── DeleteDirectory()
│ └── PendingDeletes (property)
├── ProcessHelper (constructor parameter)
│ ├── TerminateProcesses()
│ ├── GetProcessesUsingPath()
│ └── IsProcessRunning()
├── WindowsInstallerHelper (constructor parameter)
│ ├── CleanupUpgradeCodes()
│ ├── CleanupProducts()
│ ├── CleanupComponents()
│ └── CleanupPublishedComponents()
├── TypeLibHelper (constructor parameter)
│ └── CleanupTypeLibraries()
├── LicenseHelper (constructor parameter)
│ ├── RemoveLicenses()
│ └── ClearvNextCache()
├── ServiceHelper (constructor parameter)
│ ├── DeleteService()
│ └── ServiceExists()
└── ShellHelper (constructor parameter)
├── UnpinFromTaskbar()
└── UnpinFromStartMenu()
GuidHelper (static utility class)
├── GetExpandedGuid()
├── GetCompressedGuid()
└── GetDecodedGuid()
OfficeConstants (static constants class)
├── OFFICE_ID
├── PROD_LEN
├── CULTURE_LEN
└── Registry paths, process names, etc.
Design Principle: Each helper class is dependency-injected into OfficeScrubOrchestrator constructor. This enables testing with mock helpers and maintains separation of concerns.
Sources: docs/memory-bank/structure.md:61-79, docs/memory-bank/guidelines.md:44-56
# Function naming: Verb-Noun with approved verbs
function Get-OfficeScrubHelpers {
[CmdletBinding()] # Always use for advanced functions
param(
[Parameter(Mandatory)] # Explicit attributes
[string]$Path, # Explicit types
[switch]$Force # Use [switch] for boolean flags
)
# Comment-based help required for exported functions
<#
.SYNOPSIS
Brief description
.PARAMETER Path
Parameter description
#>
}Key Rules:
- PascalCase for function names
- Use approved verbs (
Get-Verbto check) - Always specify parameter types
- Add
[CmdletBinding()]for advanced functions - Include comment-based help
Sources: CONTRIBUTING.md:71-96, docs/memory-bank/guidelines.md:5-12
// Class naming: PascalCase
public class RegistryHelper
{
// Private fields: _camelCase
private readonly bool _is64Bit;
private readonly HashSet<string> _processedKeys;
// Properties: PascalCase
public RegistryKey Registry { get; }
// Methods: PascalCase
public bool DeleteKey(string keyPath)
{
// Silent failure pattern: try-catch returning bool
try
{
// Implementation
return true;
}
catch
{
return false;
}
}
// Constants: UPPER_CASE
private const int KEY_WOW64_64KEY = 0x0100;
}Key Rules:
- PascalCase for classes, methods, properties
-
_camelCasefor private fields -
UPPER_CASEfor constants - Silent failure pattern for operation methods
- Always dispose resources in
finallyblocks
Sources: docs/memory-bank/guidelines.md:5-12, docs/memory-bank/guidelines.md:26-42, CONTRIBUTING.md:98-121
| Pattern | Implementation | Example Location |
|---|---|---|
| WOW64 Support | Check both 64-bit and 32-bit registry views |
OfficeScrubC2R-Native.cs - RegistryHelper
|
| Parallel Processing | Use Task.Run() with Task.WaitAll()
|
OfficeScrubC2R-Native.cs - ProcessHelper.TerminateProcesses()
|
| Helper Injection | Constructor dependency injection |
OfficeScrubC2R-Native.cs - OfficeScrubOrchestrator
|
| P/Invoke | Internal static NativeMethods class |
OfficeScrubC2R-Native.cs - NativeMethods
|
| Silent Failure | Return bool/null, don't throw | All helper methods |
| Resource Disposal |
using statements or finally blocks |
OfficeScrubC2R-Native.cs - ProcessHelper
|
Sources: docs/memory-bank/guidelines.md:44-68, docs/memory-bank/guidelines.md:69-118
graph TB
subgraph "Static Analysis"
PSA["PSScriptAnalyzer<br/>Invoke-ScriptAnalyzer"]
Rules["PSScriptAnalyzerSettings.psd1<br/>Rule Configuration"]
end
subgraph "Build Verification"
BuildTest["Verify-NativeBuild.ps1<br/>Assembly Load Test"]
TypeCheck["Type Export Verification<br/>Class Availability"]
end
subgraph "Module Validation"
Validate["Validate-Module.ps1<br/>Gallery Compatibility"]
Manifest["Test-ModuleManifest<br/>Manifest Validation"]
Files["File List Check<br/>Required Files Present"]
end
subgraph "Functional Testing"
Import["Import-Module Test<br/>Module Loads"]
Detect["Detection-Only Test<br/>Safe Execution"]
Manual["Manual Full Test<br/>VM/Sandbox Only"]
end
subgraph "CI/CD Testing"
GHA["GitHub Actions<br/>.github/workflows/ci.yml"]
TestJob["Test Job<br/>Build + Import + Analyze"]
ValidateJob["Validate Job<br/>Gallery Readiness"]
end
Code["Code Changes"] --> PSA
Code --> BuildTest
PSA --> Rules
BuildTest --> TypeCheck
TypeCheck --> Import
Validate --> Manifest
Validate --> Files
Import --> Detect
Detect --> Manual
Code --> GHA
GHA --> TestJob
GHA --> ValidateJob
TestJob --> PSA
TestJob --> BuildTest
ValidateJob --> Validate
Diagram: Multi-Layer Testing Strategy
Testing occurs at multiple levels. Static Analysis uses PSScriptAnalyzer with custom rules from PSScriptAnalyzerSettings.psd1. Build Verification (Verify-NativeBuild.ps1) ensures the compiled DLL loads in both PowerShell editions and exports expected types. Module Validation (Validate-Module.ps1) checks PowerShell Gallery compatibility, manifest correctness, and required file presence. Functional Testing progresses from safe module import through detection-only mode to full cleanup (VM/Sandbox only). CI/CD Testing runs automatically via GitHub Actions (.github/workflows/ci.yml) with parallel Test and Validate jobs.
Sources: CONTRIBUTING.md:123-155, docs/memory-bank/structure.md:37-46
Use this checklist before submitting a pull request:
# 1. Static Analysis
Invoke-ScriptAnalyzer -Path . -Recurse -Settings PSScriptAnalyzerSettings.psd1
# 2. Build Verification
.\build.ps1
.\tests\Verify-NativeBuild.ps1
# 3. Module Import (both editions)
# Windows PowerShell 5.1
powershell.exe -Command "Import-Module .\OfficeScrubC2R.psd1 -Force; Get-Command -Module OfficeScrubC2R"
# PowerShell 7+
pwsh -Command "Import-Module .\OfficeScrubC2R.psd1 -Force; Get-Command -Module OfficeScrubC2R"
# 4. Manifest Validation
Test-ModuleManifest .\OfficeScrubC2R.psd1
# 5. Detection-Only Test (Safe)
Import-Module .\OfficeScrubC2R.psd1 -Force
Invoke-OfficeScrubC2R -DetectOnly -Verbose
# 6. Full Test (VM/Sandbox Only - DESTRUCTIVE)
# DO NOT RUN ON DEVELOPMENT MACHINE
Invoke-OfficeScrubC2R -Force -VerboseSources: CONTRIBUTING.md:123-155
When adding functionality to an existing helper class:
-
Locate the helper class in
OfficeScrubC2R-Native.cs - Add method following naming conventions (PascalCase, action-oriented)
- Implement silent failure pattern (try-catch returning bool/null)
-
Handle resources with
usingorfinallyblocks - Add XML documentation comments
-
Rebuild with
.\build.ps1 -
Test assembly load with
.\tests\Verify-NativeBuild.ps1 - Update documentation if user-facing
Example adding a method to FileHelper:
/// <summary>
/// Checks if a file is locked by another process
/// </summary>
/// <param name="filePath">Full path to file</param>
/// <returns>True if file is locked, false otherwise</returns>
public bool IsFileLocked(string filePath)
{
try
{
using (var stream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.None))
{
return false; // Successfully opened, not locked
}
}
catch
{
return true; // Failed to open, likely locked
}
}Sources: docs/memory-bank/guidelines.md:26-42, CONTRIBUTING.md:98-121
When modifying PowerShell module functions:
-
Locate function in
OfficeScrubC2R.psm1orOfficeScrubC2R-Utilities.psm1 - Update implementation following PowerShell best practices
- Update comment-based help if signature or behavior changes
-
Test with PSScriptAnalyzer:
Invoke-ScriptAnalyzer -Path .\OfficeScrubC2R.psm1 -
Reload module:
Import-Module .\OfficeScrubC2R.psd1 -Force -
Test manually with
-Verboseand-WhatIfwhere applicable -
Update manifest (
OfficeScrubC2R.psd1) if adding/removing exports
Sources: CONTRIBUTING.md:71-96, docs/memory-bank/structure.md:61-65
To add an entirely new helper class to the native library:
-
Add class definition in
OfficeScrubC2R-Native.csfollowing existing patterns - Create constructor accepting required dependencies
- Implement methods with silent failure pattern
-
Add to OfficeScrubOrchestrator:
- Add private field:
private readonly NewHelper _newHelper; - Add constructor parameter
- Assign in constructor body
- Expose as property:
public NewHelper NewHelper => _newHelper;
- Add private field:
-
Rebuild:
.\build.ps1 -
Expose in PowerShell via
Get-OfficeScrubHelpersfunction - Add tests and documentation
Sources: docs/memory-bank/guidelines.md:44-56, docs/memory-bank/structure.md:61-79
The .github/workflows/ci.yml file defines two parallel jobs:
- name: Test
runs-on: windows-latest
steps:
- Checkout code
- Build native DLL (build.ps1)
- Import module
- Run PSScriptAnalyzer
- Verify build (Verify-NativeBuild.ps1)Purpose: Ensures code compiles, imports cleanly, passes static analysis, and builds successfully on both PowerShell editions.
- name: Validate
runs-on: windows-latest
steps:
- Checkout code
- Validate module manifest
- Check required files present
- Verify PowerShell Gallery compatibility
- Check zone identifiers (unblocked files)Purpose: Ensures module meets PowerShell Gallery requirements and can be published.
Note: CI/CD runs automatically on push and pull requests. Both jobs must pass before merging.
Sources: docs/memory-bank/structure.md:37-46
The release workflow follows semantic versioning (MAJOR.MINOR.PATCH):
-
Update Version
- Edit
ModuleVersioninOfficeScrubC2R.psd1 - Follow semantic versioning rules
- Edit
-
Update CHANGELOG.md
- Add new version section
- Document changes under Added/Changed/Fixed/Removed
-
Build and Test
.\build.ps1 Test-ModuleManifest .\OfficeScrubC2R.psd1 Invoke-ScriptAnalyzer -Path . -Recurse
-
Create Git Tag
git tag -a v2.19.3 -m "Release v2.19.3" git push --tags -
Create GitHub Release
- Navigate to repository → Releases → Draft new release
- Select tag, add release notes
- Attach compiled DLL if applicable
-
Publish to PowerShell Gallery (Maintainers only)
Publish-Module -Path . -NuGetApiKey $apiKey -Verbose
Important: Versions published to PowerShell Gallery cannot be deleted or overwritten. Ensure thorough testing before publishing.
Sources: CONTRIBUTING.md:184-211, CHANGELOG.md:1-18
| Issue | Cause | Solution |
|---|---|---|
| "csc.exe not found" | .NET Framework not installed | Install .NET Framework 4.5+ or use dotnet build
|
| "error CS0234: Type or namespace" | Missing assembly reference | Check build.ps1 references: System.Management.dll, Microsoft.CSharp.dll
|
| "Assembly load failed" | DLL blocked by Windows | Unblock: Unblock-File .\OfficeScrubNative.dll
|
| Issue | Cause | Solution |
|---|---|---|
| "File not found" | DLL not compiled | Run .\build.ps1 first |
| "Cannot load type" | DLL compilation failed | Check build output for errors |
| "Assembly version mismatch" | Mixed PS editions | Clean rebuild: Remove-Item .\*.dll; .\build.ps1
|
Common issues:
-
PSAvoidUsingCmdletAliases: Use full cmdlet names (
Where-Objectnotwhere) - PSUseSingularNouns: Function names should use singular nouns
-
PSAvoidUsingWriteHost: Use
Write-Output,Write-Verbose, orWrite-Information
Fix all issues before submitting pull requests. Check with:
Invoke-ScriptAnalyzer -Path . -Recurse -Settings PSScriptAnalyzerSettings.psd1Sources: CONTRIBUTING.md:123-155
For deeper information on specific topics covered in this guide:
- Building from Source: See Building from Source for detailed compilation instructions
- Code Organization: See Code Organization for repository structure details
- Development Guidelines: See Development Guidelines for comprehensive coding standards
- Testing and Validation: See Testing and Validation for test procedures
- CI/CD Pipeline: See CI/CD Pipeline for GitHub Actions workflow details
- Release Process: See Release Process for complete release instructions
Sources: CONTRIBUTING.md:1-232, docs/memory-bank/product.md:1-72, docs/memory-bank/guidelines.md:1-179, docs/memory-bank/structure.md:1-132