Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Engine/Commands/InvokeScriptAnalyzerCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,10 @@ protected override void ProcessRecord()
using (var moduleHandler = new ModuleDependencyHandler(rsp))
{
ScriptAnalyzer.Instance.ModuleHandler = moduleHandler;
this.WriteVerbose(
String.Format(
"Temporary module location: {0}",
moduleHandler.TempModulePath));
ProcessInput();
}
}
Expand Down
4 changes: 2 additions & 2 deletions Engine/Generic/ModuleDependencyHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -445,10 +445,10 @@ public static IEnumerable<string> GetModuleNameFromErrorExtent(ParseError error,
}

// find a parameter named modulename
int k;
int k;
for (k = 1; k < dynamicKywdAst.CommandElements.Count; k++)
{
var paramAst = dynamicKywdAst.CommandElements[1] as CommandParameterAst;
var paramAst = dynamicKywdAst.CommandElements[k] as CommandParameterAst;
// TODO match the initial letters only
if (paramAst == null || !paramAst.ParameterName.Equals("ModuleName", StringComparison.OrdinalIgnoreCase))
{
Expand Down
50 changes: 34 additions & 16 deletions Engine/ScriptAnalyzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1290,6 +1290,39 @@ private void BuildScriptPathList(
}
}

private bool TrySaveModules(ParseError[] errors, ScriptBlockAst scriptAst)
{
bool modulesSaved = false;
if (moduleHandler == null || errors == null || errors.Length == 0)
{
return modulesSaved;
}
foreach (var error in errors.Where(IsModuleNotFoundError))
{
var moduleNames = moduleHandler.GetUnavailableModuleNameFromErrorExtent(error, scriptAst);
if (moduleNames == null)
{
continue;
}
foreach(var moduleName in moduleNames)
{
this.outputWriter.WriteVerbose(
String.Format(
"Saving module {0} from PSGallery",
moduleName));
var moduleSaved = moduleHandler.TrySaveModule(moduleName);
if (!moduleSaved)
{
this.outputWriter.WriteVerbose(
String.Format(
"Cannot download {0} from PSGallery",
moduleName));
}
modulesSaved |= moduleSaved;
}
}
return modulesSaved;
}

private IEnumerable<DiagnosticRecord> AnalyzeFile(string filePath)
{
Expand All @@ -1315,23 +1348,8 @@ private IEnumerable<DiagnosticRecord> AnalyzeFile(string filePath)
return null;
}
#if !PSV3
bool parseAgain = false;
if (moduleHandler != null && errors != null && errors.Length > 0)
{
foreach (ParseError error in errors.Where(IsModuleNotFoundError))
{
var moduleNames = moduleHandler.GetUnavailableModuleNameFromErrorExtent(error, scriptAst);
if (moduleNames != null)
{
parseAgain |= moduleNames.Any(x => moduleHandler.TrySaveModule(x));
}
}
}

//try parsing again
//var oldDefault = Runspace.DefaultRunspace;
//Runspace.DefaultRunspace = moduleHandler.Runspace;
if (parseAgain)
if (TrySaveModules(errors, scriptAst))
{
scriptAst = Parser.ParseFile(filePath, out scriptTokens, out errors);
}
Expand Down
21 changes: 18 additions & 3 deletions Tests/Engine/ModuleDependencyHandler.tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ Describe "Resolve DSC Resource Dependency" {
{$moduleHandlerType::new($rsp)} | Should Throw
$rsp.Dispose()
}

It "Extracts 1 module name" {
$sb = @"
{Configuration SomeConfiguration
Expand All @@ -84,9 +84,9 @@ Describe "Resolve DSC Resource Dependency" {
$parseError = $null
$ast = [System.Management.Automation.Language.Parser]::ParseInput($sb, [ref]$tokens, [ref]$parseError)
$resultModuleNames = $moduleHandlerType::GetModuleNameFromErrorExtent($parseError[0], $ast).ToArray()
$resultModuleNames[0] | Should Be 'SomeDscModule1'
$resultModuleNames[0] | Should Be 'SomeDscModule1'
}

It "Extracts more than 1 module names" {
$sb = @"
{Configuration SomeConfiguration
Expand All @@ -102,6 +102,21 @@ Describe "Resolve DSC Resource Dependency" {
$resultModuleNames[1] | Should Be 'SomeDscModule2'
$resultModuleNames[2] | Should Be 'SomeDscModule3'
}


It "Extracts module names when ModuleName parameter is not the first named parameter" {
$sb = @"
{Configuration SomeConfiguration
{
Import-DscResource -Name SomeName -ModuleName SomeDscModule1
}}
"@
$tokens = $null
$parseError = $null
$ast = [System.Management.Automation.Language.Parser]::ParseInput($sb, [ref]$tokens, [ref]$parseError)
$resultModuleNames = $moduleHandlerType::GetModuleNameFromErrorExtent($parseError[0], $ast).ToArray()
$resultModuleNames[0] | Should Be 'SomeDscModule1'
}
}

Context "Invoke-ScriptAnalyzer without switch" {
Expand Down