-
Notifications
You must be signed in to change notification settings - Fork 233
Create a build script for all functions in a consolidated PSM1 file #1586
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
SamErde
wants to merge
14
commits into
main
Choose a base branch
from
BuildMergedPSM1
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+802
−5
Open
Changes from 8 commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
f7cfc58
fix(style): Fix formatting in optimization plan markdown for clarity …
SamErde 8728809
fix(gitignore): Add module build output directory to .gitignore
SamErde 2666a16
feat(build): Add script to consolidate Maester PowerShell module and …
SamErde 200154f
fix(style): Improve code formatting and consistency in Build-MaesterM…
SamErde d98695b
feat(docs): Add comprehensive build documentation for Maester PowerSh…
SamErde b6f2d18
feat(build): Add -Format parameter to normalize source file indentati…
SamErde 8e89476
feat(docs): Update Build-MaesterModule.md to include -Format paramete…
SamErde 2eab0d1
feat(docs): Add TODO for simplified README creation in Build-MaesterM…
SamErde 2e9aaf2
Update build/Build-MaesterModule.md
SamErde 90b5839
feat(build): Update .gitignore to refine module and test result exclu…
SamErde dbe15ce
feat(docs): Remove README.md from the list of copied files in Build-M…
SamErde 577014f
feat(build): Enhance safety checks for OutputRoot and refine function…
SamErde 1c5ebde
Merge branch 'main' into BuildMergedPSM1
SamErde cfa7d5c
Add an additional safety check to prevent removal of paths outside th…
SamErde File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,179 @@ | ||
| # Build-MaesterModule | ||
|
|
||
| Builds the Maester PowerShell module into a consolidated, publishable artifact | ||
| under `./module/`. The source tree (`powershell/`, `tests/`) is never modified. | ||
|
|
||
| ## Usage | ||
|
|
||
| ```powershell | ||
| # Standard build | ||
| ./build/Build-MaesterModule.ps1 | ||
|
|
||
| # Build with indentation normalization (requires PSScriptAnalyzer) | ||
| ./build/Build-MaesterModule.ps1 -Format | ||
|
|
||
| # Build with import-time profiling | ||
| ./build/Build-MaesterModule.ps1 -Profile | ||
|
|
||
| # Custom output location | ||
| ./build/Build-MaesterModule.ps1 -OutputRoot ./out | ||
| ``` | ||
|
|
||
| ## Parameters | ||
|
|
||
| | Parameter | Type | Default | Description | | ||
| | ----------- | ------ | --------- | ------------- | | ||
| | `SourceRoot` | string | `../powershell` | Path to the module source directory | | ||
| | `TestsRoot` | string | `../tests` | Path to the test suites directory | | ||
| | `OutputRoot` | string | `../module` | Output directory (cleaned on every run) | | ||
| | `Format` | switch | — | Normalize indentation to 4 spaces via `Invoke-Formatter` (requires PSScriptAnalyzer) | | ||
| | `Profile` | switch | — | Measure and report `Import-Module` time | | ||
|
|
||
| ## Build Phases | ||
|
|
||
| ```mermaid | ||
| flowchart TD | ||
| A["Phase A\nClean output directory"] | ||
| B["Phase B\nAST-parse public functions"] | ||
| C["Phase C\nConsolidate Maester.psm1"] | ||
| D["Phase D\nConsolidate OrcaClasses.ps1"] | ||
| E["Phase E\nCopy static assets"] | ||
| F["Phase F\nUpdate module manifest"] | ||
| G["Phase G\nCopy test suites"] | ||
| H{"Profile?"} | ||
| I["Phase H\nImport-Module timing"] | ||
| Done["Build complete"] | ||
|
|
||
| A --> B | ||
| B --> C | ||
| C --> D | ||
| D --> E | ||
| E --> F | ||
| F --> G | ||
| G --> H | ||
| H -- Yes --> I --> Done | ||
| H -- No --> Done | ||
| ``` | ||
|
|
||
| ### Phase A — Clean output directory | ||
|
|
||
| Removes and recreates the output directory (`./module/` by default) to ensure a | ||
| clean build with no stale artifacts. | ||
|
|
||
| ### Phase B — AST-parse public functions | ||
|
|
||
| Scans every `.ps1` file under `powershell/public/` (excluding `*.Tests.ps1`) | ||
| using the PowerShell AST parser to discover top-level function definitions. | ||
|
|
||
| - Only functions matching the `Verb-Noun` naming convention are exported. | ||
| - Helper functions without a `-` separator are logged and skipped. | ||
| - Duplicate function names across files are deduplicated and logged. | ||
| - Functions with unapproved verbs or mismatched filenames generate warnings. | ||
|
|
||
| ### Phase C — Consolidate Maester.psm1 | ||
|
|
||
| Concatenates all internal and public `.ps1` source files into a single | ||
| `Maester.psm1`, organized as: | ||
|
|
||
| 1. **Module preamble** — `#Requires`, `$__MtSession` initialization | ||
| 2. **Internal functions** — from `powershell/internal/` (excluding | ||
| `check-ORCA*.ps1`, which go to Phase D) | ||
| 3. **Public functions** — from `powershell/public/` | ||
| 4. **Export-ModuleMember** — auto-generated function and alias exports | ||
| 5. **Manifest loader** — `Import-PowerShellDataFile` for runtime metadata | ||
|
|
||
| Two transformations are applied to each source file: | ||
|
|
||
| - **Preamble stripping** — Removes file-level `[SuppressMessageAttribute]`, | ||
| `param()`, `using module`, and `# Generated by` lines that are only valid at | ||
| the top of standalone `.ps1` files. Attributes inside function bodies are | ||
| preserved. | ||
| - **`$PSScriptRoot` path adjustment** — Strips parent-directory traversals | ||
| (`../`) that were needed in the original subdirectory structure but are | ||
| incorrect after consolidation to a flat module root. Any remaining | ||
| `$PSScriptRoot/..` references trigger a warning for manual review. | ||
| - **Indentation normalization** (with `-Format`) — Runs `Invoke-Formatter` | ||
| per file to enforce 4-space indentation. Only the | ||
| `PSUseConsistentIndentation` rule is applied. If PSScriptAnalyzer is not | ||
| installed, a warning is emitted and formatting is skipped. | ||
|
|
||
| ### Phase D — Consolidate OrcaClasses.ps1 | ||
|
|
||
| Merges the ORCA class hierarchy into a single `OrcaClasses.ps1`: | ||
|
|
||
| 1. **Base classes and enums** from `orcaClass.psm1` (preamble preserved since | ||
| this file runs standalone via `ScriptsToProcess`) | ||
| 2. **Derived check classes** from each `check-ORCA*.ps1` file, with preambles | ||
| stripped and `using module` directives removed (the base classes are now | ||
| defined inline above) | ||
|
|
||
| This file is registered as `ScriptsToProcess` in the manifest so that class | ||
| definitions are available before the module's `.psm1` loads. | ||
|
|
||
| When `-Format` is specified, each derived check class file is also passed | ||
| through `Invoke-Formatter` for indentation normalization. | ||
|
|
||
| ### Phase E — Copy static assets | ||
|
|
||
| Copies unchanged files to the output directory: | ||
|
|
||
| - `assets/` directory (icons, images) | ||
| - `Maester.Format.ps1xml` (type formatting) | ||
| - `README.md` | ||
|
|
||
| This phase runs before the manifest update (Phase F) so that | ||
| `FormatsToProcess` references can be validated by `Update-ModuleManifest`. | ||
|
|
||
| ### Phase F — Update module manifest | ||
|
|
||
| Copies the source `Maester.psd1` to the output directory and updates: | ||
|
|
||
| - `FunctionsToExport` — set to the sorted, deduplicated list from Phase B | ||
| - `ScriptsToProcess` — set to `@('OrcaClasses.ps1')` | ||
|
|
||
| All other manifest fields (version, GUID, `RequiredModules`, | ||
| `AliasesToExport`, etc.) are preserved from the source. | ||
|
|
||
| ### Phase G — Copy test suites | ||
|
|
||
| Copies the `tests/` directory to `maester-tests/` in the output. Tests are | ||
| copied as-is and not consolidated. | ||
|
|
||
| ### Phase H — Build profiling (optional) | ||
|
|
||
| When `-Profile` is specified, imports the built module and reports: | ||
|
|
||
| - `Import-Module` wall-clock time | ||
| - Number of exported commands | ||
|
|
||
| The module is unloaded after profiling. | ||
|
|
||
| ## Output Structure | ||
|
|
||
| ```text | ||
| module/ | ||
| ├── assets/ # Icons and images | ||
| ├── maester-tests/ # Test suites (copied from tests/) | ||
| ├── Maester.Format.ps1xml # Type formatting definitions | ||
| ├── Maester.psd1 # Updated module manifest | ||
| ├── Maester.psm1 # Consolidated module script | ||
| ├── OrcaClasses.ps1 # Consolidated ORCA class definitions | ||
| └── README.md | ||
| ``` | ||
|
|
||
| ## Design Notes | ||
|
|
||
| - **Source is never modified.** The build reads from `powershell/` and `tests/` | ||
| and writes exclusively to the output directory. | ||
| - **Deterministic output.** Files are sorted by full path before concatenation. | ||
| The `FunctionsToExport` list is sorted alphabetically. Repeated builds from | ||
| the same source produce identical output. | ||
| - **Encoding.** All generated PowerShell files use UTF-8 with BOM (`utf8BOM`), | ||
| matching the project convention. | ||
| - **Preamble stripping is position-aware.** Only lines in the file-level | ||
| preamble region (before the first function/class definition) are stripped. | ||
| Identical attributes inside function bodies are preserved. | ||
| - **The hardcoded PSM1 preamble** (module header, `#Requires`, | ||
| `$__MtSession`) is extracted from the source `Maester.psm1`. If new session | ||
| variables are added to the source, they must also be added to the build | ||
| script's preamble. | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.