Skip to content

Add documentation for defining module dependencies using #Requires statements #293

@MariusStorhaug

Description

Context

When building a PowerShell module with Process-PSModule, developers often need to declare that their module depends on other modules (e.g., Microsoft.Graph.Authentication, PSSemVer). The natural instinct is to populate the RequiredModules key in src/manifest.psd1, since the module manifest documentation defines RequiredModules as the standard way to declare module dependencies.

However, Process-PSModule uses a different convention: module dependencies are declared via #Requires -Modules statements at the top of individual PowerShell function files. The Build-PSModule action compiles these statements across all source files, aggregates the unique requirements, and writes them into the RequiredModules field of the final built manifest. This behavior is not documented anywhere in the README.

This missing documentation was identified in issue #291, where a user spent time debugging why their src/manifest.psd1 RequiredModules entries were silently dropped from the built output.

Request

There is no documentation in the README or elsewhere explaining:

  • That RequiredModules added to src/manifest.psd1 are not propagated to the built manifest
  • That the correct approach is to declare dependencies using #Requires -Modules in individual function files
  • How the build process compiles those #Requires statements into the final manifest
  • The supported syntax variants (plain module name, hashtable with ModuleVersion, RequiredVersion)

What happens today

A developer adds RequiredModules to src/manifest.psd1:

@{
    RequiredModules = @(
        @{ ModuleName = 'Microsoft.Graph.Authentication'; ModuleVersion = '2.28.0' }
    )
}

After the build runs, the compiled manifest contains no RequiredModules entry. There is no warning, error, or hint that this approach is unsupported. The dependency is silently lost.

What is expected

The README should document that module dependencies must be declared using #Requires -Modules in individual PowerShell function files:

#Requires -Modules Microsoft.Graph.Authentication
#Requires -Modules @{ ModuleName = 'Microsoft.Graph.Authentication'; ModuleVersion = '2.28.0' }

The documentation should explain that this approach co-locates dependency declarations with the functions that need them, and that the build system aggregates these into the final manifest automatically.

The README should also clarify that src/manifest.psd1 does not support RequiredModules as a way to declare module dependencies.

Acceptance criteria

  • The README explains the #Requires -Modules approach for declaring module dependencies in function files
  • The README clarifies the behavior of src/manifest.psd1 with respect to RequiredModules (not propagated)
  • The documentation shows the supported #Requires -Modules syntax variants (bare name, ModuleVersion, RequiredVersion)
  • A developer reading the README can successfully declare a module dependency without consulting an issue or the source code of Build-PSModule

Technical decisions

Documentation location: The primary documentation lives in README.md at the repository root (974 lines). The most relevant existing section is "Module source code structure" (around line 920), which documents the src/ folder tree with descriptions of each file and folder. This is where the #Requires behavior should be documented — both inline in the folder tree description and in a dedicated subsection below it.

The src/manifest.psd1 entry in the folder tree currently reads:

│   ├── manifest.psd1 (optional)            # Source manifest reused when present

This entry should be updated to clarify that RequiredModules is not a supported key in this file for dependency declaration purposes.

Scope of #Requires documentation: The documentation should cover:

  • src/functions/public/ and src/functions/private/ function files as the location where #Requires -Modules statements are placed
  • The compilation behavior: the build collects all #Requires -Modules declarations and merges unique entries into the built manifest's RequiredModules
  • Both plain-name (#Requires -Modules ModuleName) and hashtable syntax (#Requires -Modules @{ ModuleName = 'X'; ModuleVersion = 'Y' }) variants
  • The design rationale: co-locating dependency declarations with the functions that require them makes it clear which commands drive each external dependency

Example code: The test fixture at tests/srcTestRepo/src/functions/public/PSModule/Get-PSModuleTest.ps1 already demonstrates the correct #Requires usage pattern and can serve as the basis for documentation examples.

Cross-reference with src/manifest.psd1: The folder tree entry for manifest.psd1 should note that RequiredModules must not be set there; the inline annotation is the right place for a short note, with a reference to the new documentation subsection for full details.

Format: The README uses GitHub Flavored Markdown with fenced code blocks (language-tagged), ATX headings, and inline code for file paths and function names. New content should follow the same conventions. Examples should use powershell as the fenced code block language.


Implementation plan

README — Module source code structure section

  • Update the manifest.psd1 entry in the folder tree to note that RequiredModules is not propagated from this file and link to the new subsection
  • Update the functions/ folder tree entries to mention that #Requires -Modules statements in these files are compiled into the manifest

README — New "Declaring module dependencies" subsection

  • Add a new subsection under "Module source code structure" titled "Declaring module dependencies"
  • Explain that dependencies are declared using #Requires -Modules at the top of individual function files
  • Show a code example demonstrating both the bare-name and hashtable syntax variants (ModuleVersion, RequiredVersion)
  • Describe the compilation behavior: the build aggregates all #Requires -Modules statements across all source files into the RequiredModules field of the built manifest
  • Explain the design rationale (co-location of dependency with the function that needs it)
  • Add a note explicitly stating that adding RequiredModules to src/manifest.psd1 is not supported for this purpose and will be silently ignored

Verification

  • Confirm that the test fixture tests/srcTestRepo/src/functions/public/PSModule/Get-PSModuleTest.ps1 is accurately referenced or quoted in the new documentation

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions