diff --git a/Engine/Settings.cs b/Engine/Settings.cs index 0947b77d8..35a941781 100644 --- a/Engine/Settings.cs +++ b/Engine/Settings.cs @@ -202,13 +202,25 @@ internal static Settings Create(object settingsObj, string cwd, IOutputWriter ou case SettingsMode.Preset: case SettingsMode.File: - var resolvedPath = getResolvedProviderPathFromPSPathDelegate(settingsFound.ToString(), out ProviderInfo providerInfo).Single(); - settingsFound = resolvedPath; - outputWriter?.WriteVerbose( - String.Format( - CultureInfo.CurrentCulture, - Strings.SettingsUsingFile, - resolvedPath)); + var userProvidedSettingsString = settingsFound.ToString(); + try + { + var resolvedPath = getResolvedProviderPathFromPSPathDelegate(userProvidedSettingsString, out ProviderInfo providerInfo).Single(); + settingsFound = resolvedPath; + outputWriter?.WriteVerbose( + String.Format( + CultureInfo.CurrentCulture, + Strings.SettingsUsingFile, + resolvedPath)); + } + catch + { + outputWriter?.WriteVerbose( + String.Format( + CultureInfo.CurrentCulture, + Strings.SettingsCannotFindFile, + userProvidedSettingsString)); + } break; case SettingsMode.Hashtable: @@ -218,20 +230,15 @@ internal static Settings Create(object settingsObj, string cwd, IOutputWriter ou Strings.SettingsUsingHashtable)); break; - default: // case SettingsMode.None + default: outputWriter?.WriteVerbose( String.Format( CultureInfo.CurrentCulture, - Strings.SettingsCannotFindFile)); - break; - } - - if (settingsMode != SettingsMode.None) - { - return new Settings(settingsFound); + Strings.SettingsObjectCouldNotBResolved)); + return null; } - return null; + return new Settings(settingsFound); } /// @@ -703,6 +710,16 @@ internal static SettingsMode FindSettingsMode(object settings, string path, out { settingsMode = SettingsMode.Hashtable; } + else // if the provided argument is wrapped in an expressions then PowerShell resolves it but it will be of type PSObject and we have to operate then on the BaseObject + { + if (settingsFound is PSObject settingsFoundPSObject) + { + if (settingsFoundPSObject.BaseObject is String) + { + settingsMode = SettingsMode.File; + } + } + } } } diff --git a/Engine/Strings.Designer.cs b/Engine/Strings.Designer.cs index 1f8db8c92..d7234f283 100644 --- a/Engine/Strings.Designer.cs +++ b/Engine/Strings.Designer.cs @@ -458,7 +458,7 @@ internal static string SettingsAutoDiscovered { } /// - /// Looks up a localized string similar to Cannot find a settings file.. + /// Looks up a localized string similar to Cannot resolve settings file path '{0}'.. /// internal static string SettingsCannotFindFile { get { @@ -511,6 +511,15 @@ internal static string SettingsNotProvided { } } + /// + /// Looks up a localized string similar to Settings object could not be resolved.. + /// + internal static string SettingsObjectCouldNotBResolved { + get { + return ResourceManager.GetString("SettingsObjectCouldNotBResolved", resourceCulture); + } + } + /// /// Looks up a localized string similar to Using settings file at {0}.. /// diff --git a/Engine/Strings.resx b/Engine/Strings.resx index 5194830c3..99d90761f 100644 --- a/Engine/Strings.resx +++ b/Engine/Strings.resx @@ -268,7 +268,7 @@ Using settings hashtable. - Cannot find a settings file. + Cannot resolve settings file path '{0}'. Cannot parse settings. Will abort the invocation. @@ -321,4 +321,7 @@ Input position should be less than that of the invoking object. + + Settings object could not be resolved. + \ No newline at end of file diff --git a/Tests/Engine/InvokeScriptAnalyzer.tests.ps1 b/Tests/Engine/InvokeScriptAnalyzer.tests.ps1 index e358d42c5..554749bb2 100644 --- a/Tests/Engine/InvokeScriptAnalyzer.tests.ps1 +++ b/Tests/Engine/InvokeScriptAnalyzer.tests.ps1 @@ -387,13 +387,23 @@ Describe "Test CustomizedRulePath" { Context "When used from settings file" { It "Should process relative settings path" { try { - $initialLocation = Get-Location - Set-Location $PSScriptRoot + Push-Location $PSScriptRoot $warnings = Invoke-ScriptAnalyzer -ScriptDefinition 'gci' -Settings .\SettingsTest\..\SettingsTest\Project1\PSScriptAnalyzerSettings.psd1 $warnings.Count | Should -Be 1 } finally { - Set-Location $initialLocation + Pop-Location + } + } + + It "Should process relative settings path even when settings path object is not resolved to a string yet" { + try { + Push-Location $PSScriptRoot + $warnings = Invoke-ScriptAnalyzer -ScriptDefinition 'gci' -Settings (Join-Path (Get-Location).Path '.\SettingsTest\..\SettingsTest\Project1\PSScriptAnalyzerSettings.psd1') + $warnings.Count | Should -Be 1 + } + finally { + Pop-Location } }