Skip to content
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

Session-global module caching is at odds with ScriptsToProcess feature and scoped unloading of modules with Remove-Module #9582

Open
mklement0 opened this issue May 12, 2019 · 0 comments

Comments

Projects
None yet
1 participant
@mklement0
Copy link
Contributor

commented May 12, 2019

Import-Module can be:

  • implicitly scope-specific, if the same module is imported by different other modules

  • explicitly scope-specific, via -Scope Local (or -Scope Global).

By contrast, certain aspects of module handling are currently invariably session-global, seemingly due to behind-the-scenes session-global module caching:

  • The ScriptsToProcess module manifest key is only honored once per session, namely in whatever scope happens to import the module first.

  • Remove-Module - which doesn't have a -Scope parameter - session-globally unloads a module, so that different scopes that had imported the module scope-locally later cannot unload that module anymore, which means that all its exports linger.

Steps to reproduce

Describe "Global module caching" {
  BeforeAll {
    Push-Location TestDrive:/
    New-Item -Type Directory ./tm
    # .ps1 file to use with ScriptsToSource
    @'
    $foo = 'bar'
'@ > tm/toSource.ps1
    # .psm1 file (root module)
    @'
function foo { 'bar too' }
'@ > tm/tm.psm1
   # Create the manifest.
   New-ModuleManifest -Path ./tm/tm.psd1 -ScriptsToProcess toSource.ps1 -RootModule tm.psm1
  }
  AfterAll {
    Pop-Location
  }
  It "ScriptsToProcess is honored on every import." {
    & {
      Import-Module -Scope Local ./tm -Verbose
      $foo | Should -Be 'bar' # 1st
    }
    & {
      # !! Because Import-Module was previously called in a different
      # !! scope, the ScriptsToProcess script isn't sourced again.
      Import-Module -Scope Local ./tm -Verbose
      $foo | Should -Be 'bar' # 2nd
    }
  }
  It "Remove-Module is honored in every scope." {
    Import-Module -Scope Local ./tm -Verbose
    foo | Should -Be 'bar too'
    & { 
      Import-Module -Scope Local ./tm -Verbose
      # !! This removes the module globally.
      Remove-Module tm
    }
    Remove-Module tm
    { foo } | Should -Throw
  }
}

Expected behavior

All tests should pass.

Actual behavior

The 1st test fails, because the 2nd Import-Module call fails to dot-source the ScriptsToProcess script.

2nd test: The 2nd Remove-Module call fails, because the previous Remove-Module call in a different scope unloaded the module globally.

Environment data

PowerShell Core 6.2.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.