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

Once saved and placed in the cache, some modules will be impossible to load under Ubuntu #54

Closed
LaurentDardenne opened this issue Aug 30, 2023 · 3 comments
Assignees
Labels
documentation Improvements or additions to documentation PSResourceGet Affected in case of migration to PSResourceGet Resolution-External The issue is caused by external component(s)

Comments

@LaurentDardenne
Copy link
Collaborator

LaurentDardenne commented Aug 30, 2023

Once saved and placed in the cache, some modules will be impossible to load under Ubuntu. This concerns primary modules or dependent modules.

While some module name duplication scenarios across multiple repositories are problematic, the content of a nuget package is case-sensitive only for OSs using a case-sensitive FileSystem.

This is a different naming issue between directory name and manifest or module name if no manifest exists. This issue is seen here.

The use of Publish-Module seems to limit this naming problem which is known as much on the Powershell repository as that of PowershellGetv2 and to a lesser extent for PSGallery.
Unfortunately, there is no solution at the moment. In addition, the new version PowershellGet seems for the moment also concerned...

For PSModuleCache I plan to add a check on the respect of naming between the name of the nuget package, the name of the manifest and the name of the module.
This control will generate a warning which is not intended to be blocking.

We can reproduce this bug as follows (we can publish a module without using Publish-module):

#use https://github.com/LaurentDardenne/Nuspec

$Result = nuspec 'wrongnamingrule' '1.0.0' {
   Properties @{
      Authors                           = $Env:USERNAME
      Description                       = 'test'
      title                             = ''
      summary                           = ''
      #owners=''
      copyright                         = 'Copyleft'

      #default $false
      requireLicenseAcceptance          = $False
      requireLicenseAcceptanceSpecified = $False

      #default en-US'
      language                          = 'en-US'

      #PSData
      projectUrl                        = 'https://github.com/LaurentDardenne/'
      releaseNotes                      = ''
      tags                              = $null
   }
   files {
      file -src 'G:\PS\psmodulecache\test\Dependencies\Gallery\Wrongnamingrule\1.0.0\WrongNamingRule.psd1'
      file -src 'G:\PS\psmodulecache\test\Dependencies\Gallery\Wrongnamingrule\1.0.0\WrongNamingRule.psm1'
   }
}
$Result |
Push-nupkg -Path c:\temp -Source 'https://nuget.cloudsmith.io/psmodulecache/test/v2/' -Apikey $S


$NugetName = 'wrongnamingrule'
$SavePath = 'C:\temp\CacheTemp'
$Modulepath = "$SavePath\$nugetname"

Save-Module $NugetName "$SavePath\$nugetname"

$ManifestRegex = "$nugetname\.$"
$ModuleRegex = "$nugetname\.(psd1|psm1|dll|exe)$"

# .psm1 or .exe or .dll [windows Powershell only : CDXML or .xaml (Workflow) or ".ni.dll" (see PS source 'PowerShellNgenAssemblyExtension') ]

   Foreach ($File in Get-ChildItem "$Savepath\$NugetName\*\$NugetName.*") {
      $isNammingCorrect = $File -cnotmatch $ModuleRegex
      switch ($File.Extension) {
         '.psd1' { if ($isNammingCorrect) { Write-Warning "Module manifest name is invalid under Ubuntu : '$file'" ; return } }
         '.psm1' { if ($isNammingCorrect) { Write-Warning "Script module name is invalid under Ubuntu : '$file'"; return } }
         '.dll'  { if ($isNammingCorrect) { Write-Warning "Binary module name is invalid under Ubuntu : '$file'"; return } } #todo Test
           #todo use case :https://github.com/PowerShell/PowerShell/issues/6741#issuecomment-385746538
         '.exe'  { if ($isNammingCorrect) { Write-Warning "Executable name is invalid under Ubuntu : '$file'"; return } } #todo Test
      }
   }

In the next version we know each module to save and its dependencies, this control can be done on all the modules installed via a call to Save-Module.

Examples of modules concerned :
https://www.powershellgallery.com/packages/AzureRM.profile/5.8.3
https://www.powershellgallery.com/packages/psnotification/0.5.3
https://www.powershellgallery.com/packages/PSColor/1.0.0.0
https://www.powershellgallery.com/packages/fifa2018/0.2.45

Other issue:
https://stackoverflow.com/questions/55411029/azure-powershell-az-module-not-working-on-ubuntu-hosted-build-agent

@LaurentDardenne LaurentDardenne added documentation Improvements or additions to documentation PSResourceGet Affected in case of migration to PSResourceGet Resolution-External The issue is caused by external component(s) labels Aug 30, 2023
@LaurentDardenne LaurentDardenne self-assigned this Aug 30, 2023
@LaurentDardenne
Copy link
Collaborator Author

In fact under Linux all entries in a manifest referencing a file name must be case sensitive :

image

Test:
image

@LaurentDardenne
Copy link
Collaborator Author

Module name collision in Linux.

The 'string' module exists in the PSGallery repository (version 1.1.3).
The 'String' module exists in the PSModuleCache repository (version 1.0.0 as a dependency of the Duplicate module).
The two modules with the same name, but different case, do not have the same GUID in their respective manifest.

If the PSModuleCache Action is configured as follows:
modules-to-cache: PSGallery\string , PSModuleCache\Duplicate

Under Linux the filesystem is case sensitive, Save-Module creates two separate directories because nuget package names are case sensitive.
Here this fulfills the following condition: if two modules with the same name but different GUID are installed on the same machine then they must be recorded in two separate module directories (both of which must be specified in %PSmodulePath%).

But the Import-Module search mechanism, without specifying a version number, will find the 'String' directory first (version 1.0.0 indicated depending on the Duplicate module).
The following test will fail:

    $M = Import-Module string -PassThru
    $M.Version | Should -Be '1.1.3'

image

This is an extreme but possible scenario.

@LaurentDardenne
Copy link
Collaborator Author

fixed in version v6.0 :
image

LaurentDardenne added a commit to LaurentDardenne/psmodulecache that referenced this issue Oct 31, 2023
Refactoring and bug fixes around managing multiple repositories.
Close potatoqualitee#54, Close potatoqualitee#51, Close potatoqualitee#50, Close potatoqualitee#47, Close potatoqualitee#45, Close potatoqualitee#48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation PSResourceGet Affected in case of migration to PSResourceGet Resolution-External The issue is caused by external component(s)
Projects
None yet
Development

No branches or pull requests

1 participant