Skip to content

Commit

Permalink
Include Module Version in error messages when module is not found (Po…
Browse files Browse the repository at this point in the history
  • Loading branch information
ArmaanMcleod authored Sep 12, 2023
1 parent 5dd8d53 commit 2a7384c
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ internal static void VerifyRequiredModules(ExternalScriptInfo scriptInfo, Execut
ScriptRequiresException scriptRequiresException =
new ScriptRequiresException(
scriptInfo.Name,
new Collection<string> { requiredModule.Name },
new Collection<string> { requiredModule.GetRequiredModuleNotFoundVersionMessage() },
"ScriptRequiresMissingModules",
false,
error);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,49 @@ internal static Exception ModuleSpecificationInitHelper(ModuleSpecification modu
return null;
}

internal string GetRequiredModuleNotFoundVersionMessage()
{
if (RequiredVersion is not null)
{
return StringUtil.Format(
Modules.RequiredModuleNotFoundRequiredVersion,
Name,
RequiredVersion);
}

bool hasVersion = Version is not null;
bool hasMaximumVersion = MaximumVersion is not null;

if (hasVersion && hasMaximumVersion)
{
return StringUtil.Format(
Modules.RequiredModuleNotFoundModuleAndMaximumVersion,
Name,
Version,
MaximumVersion);
}

if (hasVersion)
{
return StringUtil.Format(
Modules.RequiredModuleNotFoundModuleVersion,
Name,
Version);
}

if (hasMaximumVersion)
{
return StringUtil.Format(
Modules.RequiredModuleNotFoundMaximumVersion,
Name,
MaximumVersion);
}

return StringUtil.Format(
Modules.RequiredModuleNotFoundWithoutVersion,
Name);
}

internal ModuleSpecification(PSModuleInfo moduleInfo)
{
ArgumentNullException.ThrowIfNull(moduleInfo);
Expand Down
15 changes: 15 additions & 0 deletions src/System.Management.Automation/resources/Modules.resx
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,21 @@
<data name="RequiredModuleNotLoadedWrongMinimumVersionAndMaximumVersion" xml:space="preserve">
<value>The required module '{1}' with MinimumVersion '{2}' and MaximumVersion '{3}' is not loaded. Load the module or remove the module from 'RequiredModules' in the file '{0}'.</value>
</data>
<data name="RequiredModuleNotFoundModuleVersion" xml:space="preserve">
<value>The module '{0}' cannot be found with ModuleVersion '{1}'.</value>
</data>
<data name="RequiredModuleNotFoundRequiredVersion" xml:space="preserve">
<value>The module '{0}' cannot be found with RequiredVersion '{1}'.</value>
</data>
<data name="RequiredModuleNotFoundMaximumVersion" xml:space="preserve">
<value>The module '{0}' cannot be found with MaximumVersion '{1}'.</value>
</data>
<data name="RequiredModuleNotFoundModuleAndMaximumVersion" xml:space="preserve">
<value>The module '{0}' cannot be found with ModuleVersion '{1}' and MaximumVersion '{2}'.</value>
</data>
<data name="RequiredModuleNotFoundWithoutVersion" xml:space="preserve">
<value>The module '{0}' cannot be found.</value>
</data>
<data name="NoModulesRemoved" xml:space="preserve">
<value>No modules were removed. Verify that the specification of modules to remove is correct and those modules exist in the runspace.</value>
</data>
Expand Down
64 changes: 58 additions & 6 deletions test/powershell/Language/Scripting/Requires.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -118,21 +118,73 @@ Describe "#requires -Modules" -Tags "CI" {
$badName = 'ModuleThatDoesNotExist'
$badPath = Join-Path $TestDrive 'ModuleThatDoesNotExist'
$version = '1.0'
$requiredVersion = '1.1'
$maximumVersion = '1.2'
$testCases = @(
@{ ModuleRequirement = "'$badName'"; Scenario = 'name' }
@{ ModuleRequirement = "'$badPath'"; Scenario = 'path' }
@{ ModuleRequirement = "@{ ModuleName = '$badName'; ModuleVersion = '$version' }"; Scenario = 'fully qualified name with name' }
@{ ModuleRequirement = "@{ ModuleName = '$badPath'; ModuleVersion = '$version' }"; Scenario = 'fully qualified name with path' }
@{
ModuleRequirement = $badName
Scenario = 'fully qualified with module name'
ExpectedMessageStrings = @($badName)
}
@{
ModuleRequirement = $badPath
Scenario = 'fully qualified with module path'
ExpectedMessageStrings = @($badPath)
}
@{
ModuleRequirement = "@{ ModuleName = '$badName'; ModuleVersion = '$version' }"
Scenario = 'fully qualified with module name and version'
ExpectedMessageStrings = @($badName, $version)
}
@{
ModuleRequirement = "@{ ModuleName = '$badPath'; ModuleVersion = '$version' }"
Scenario = 'fully qualified with module name and version'
ExpectedMessageStrings = @($badPath, $version)
}
@{
ModuleRequirement = "@{ ModuleName = '$badName'; RequiredVersion = '$requiredVersion' }"
Scenario = 'fully qualified with module name and required version'
ExpectedMessageStrings = @($badName, $requiredVersion)
}
@{
ModuleRequirement = "@{ ModuleName = '$badPath'; RequiredVersion = '$requiredVersion' }"
Scenario = 'fully qualified with module path and required version'
ExpectedMessageStrings = @($badPath, $requiredVersion)
}
@{
ModuleRequirement = "@{ ModuleName = '$badName'; MaximumVersion = '$maximumVersion' }"
Scenario = 'fully qualified with module name and maximum version'
ExpectedMessageStrings = @($badName, $maximumVersion)
}
@{
ModuleRequirement = "@{ ModuleName = '$badPath'; MaximumVersion = '$maximumVersion' }"
Scenario = 'fully qualified with module path and maximum version'
ExpectedMessageStrings = @($badPath, $maximumVersion)
}
@{
ModuleRequirement = "@{ ModuleName = '$badName'; ModuleVersion = '$version'; MaximumVersion = '$maximumVersion' }"
Scenario = 'fully qualified with module name and version and maximum version'
ExpectedMessageStrings = @($badName, $version, $maximumVersion)
}
@{
ModuleRequirement = "@{ ModuleName = '$badPath'; ModuleVersion = '$version'; MaximumVersion = '$maximumVersion' }"
Scenario = 'fully qualified with module path and version and maximum version'
ExpectedMessageStrings = @($badPath, $version, $maximumVersion)
}
)
}

It "Fails parsing a script that requires module by <Scenario>" -TestCases $testCases {
param([string]$ModuleRequirement, [string]$Scenario)
param([string]$ModuleRequirement, [string]$Scenario, [string[]]$ExpectedMessageStrings)

$script = "#requires -Modules $ModuleRequirement`n`nWrite-Output 'failed'"
$null = New-Item -Path $scriptPath -Value $script -Force

{ & $scriptPath } | Should -Throw -ErrorId 'ScriptRequiresMissingModules'
$ex = { & $scriptPath } | Should -Throw -ErrorId 'ScriptRequiresMissingModules' -PassThru

$expectedPattern = $ExpectedMessageStrings.ForEach{ [regex]::Escape($_) } -join '|'
$stringMatches = [regex]::Matches($ex.Exception.Message, $expectedPattern)
$stringMatches | Should -HaveCount $ExpectedMessageStrings.Count
}
}

Expand Down

0 comments on commit 2a7384c

Please sign in to comment.