potatoqualitee / psmodulecache

This action makes caching PowerShell modules from the PowerShell Gallery easy for Linux, Windows and macOS runners.
MIT License
31 stars 12 forks source link

If a module with the same name, but with a different GUID, exists in 2 repositories, PsModuleCache saves the version of the first repositories declared. #51

Closed LaurentDardenne closed 1 year ago

LaurentDardenne commented 1 year ago

If a module with the same name, but with a different GUID, exists in 2 repositories, PsModuleCache saves the version of the first repositories declared.

Demo : image

We modify the order of declarations of the repositories : image

According to the order of declarations of the repositories, we observe that we do not save the desired module. In addition, we could rarely have modules with different versions but different GUIDs in the same module directory.

This setting does not resolve the ambiguity.

Possible resolution : add syntax similar to 'Module-Qualified Cmdlet Names'. Example:

  modules-to-cache: PSRepoLocal\String, PSGallery\InvokeBuild:5.9.10,dbatools-core-library:2022.10.25.1

If only one repository exists (most often and by default it is 'PSGallery') we search in it. If several repositories exist, follow the order in which the repositories are declared or specify the one in which to search for the module to be saved.

Another simple solution: do not duplicate modules of the same name in several repositories...

LaurentDardenne commented 1 year ago

This case is fixed : image

To disambiguate we use the syntax that I named 'Repository Qualified Module Name' : image

As a reminder, Find-Module returns all the modules without performing any checks and it is Save-Module which checks the ambiguity in the event of a duplication of module name in several repositories.

LaurentDardenne commented 1 year ago

There remains a case where control of module duplication, with a different GUID, will be the responsibility of the user. The following setting:

modules-to-cache:'PSModuleCache\Duplicate, PSGallery\string'

will register two versions of the 'string' module but not coming from the same repository.

I chose to allow this behavior because we may want to use one repository for stable versions and a second for versions under development. In this case as a user I know that these modules will have the same GUID.

LaurentDardenne commented 1 year ago

Allez, une dernière pour la route !

The following use case with 'Duplicate' module do not works on Unbuntu or MacOs (pwsh.exe), the behavior is erratic in the Github Action or WSL. The result is either right or wrong :

$global:ModuleDependenciesExistsInSeveralRepositories = @(
    @{Modules = 'Duplicate'; Shells = 'pwsh'; Updatable = $false }
    @{PrereleaseModules = 'Duplicate::'; Shells = 'pwsh'; Updatable = $true }
)

    It "Searching for module dependencies returns wrong result from several repositories : '[<Modules> (stable)] / [<PrereleaseModules> (prerelease)]. Updatable:<Updatable>'" -Skip:($isWindows -eq $false) -TestCases $global:ModuleDependenciesExistsInSeveralRepositories {
        param(
            $Modules,
            $PrereleaseModules,
            $Shells,
            [switch]$Updatable
        )

        $ActionParameters = New-ModuleCacheParameter -Modules $Modules -PrereleaseModules $PrereleaseModules -Shells $Shells -Updatable:$Updatable
        $ErrorModulesCache = Get-ModuleCache $ActionParameters -Pester

        #Always true under Windows.
        $ErrorModulesCache.Count | Should -Be 1
        Write-Warning "$($ErrorModulesCache[0])"
        $ErrorModulesCache[0] | Should -Match "Searching for module '.*?' dependencies returns wrong result from several repositories"
    }

image

image

The 'Microsoft.PowerShell.PSResourceGet' module will not encounter this problem because the notion of priority removes this use case:

There are now priorities on repositories so that you can specify a preferred repository that a module will be installed from if a module if found in multiple registered repositories. Valid priority values range from 0 to 100. Lower values have a higher priority ranking. The default value is 50, and can be set at registration or later using the set cmdlet. Repositories are sorted by priority then by name. When searching for resources across multiple repositories, the PSResourceGet cmdlets search the repositories using this sort order.