This commit is contained in:
Bernie White 2022-07-06 21:50:30 +10:00 коммит произвёл GitHub
Родитель fb1fb4a635
Коммит 5967ec1ded
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
45 изменённых файлов: 1482 добавлений и 520 удалений

19
.vscode/tasks.json поставляемый
Просмотреть файл

@ -46,8 +46,8 @@
}
},
{
"label": "Build",
"detail": "Build module.",
"label": "Build module",
"detail": "Build PSRule PowerShell module.",
"type": "shell",
"command": "Invoke-Build Build",
"group": {
@ -140,6 +140,21 @@
"PSRULE_OUTPUT_PATH": "reports/ps-rule-results.sarif"
}
}
},
{
"label": "Build CLI",
"detail": "Builds PSRule CLI.",
"type": "shell",
"command": "Invoke-Build BuildCLI",
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": [],
"presentation": {
"clear": true,
"panel": "dedicated"
}
}
],
"inputs": [

Просмотреть файл

@ -15,6 +15,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PSRule.BuildTool", "src\PSR
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PSRule.SDK", "src\PSRule.SDK\PSRule.SDK.csproj", "{6B21D558-BFC3-4BC6-963E-83B65353196F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PSRule.Tool", "src\PSRule.Tool\PSRule.Tool.csproj", "{F6CFCA60-72D5-474E-8B8B-1AB973434569}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{F5173A23-CCEA-4C39-AB8D-EF6E86C11BD7}"
ProjectSection(SolutionItems) = preProject
src\PSRule.Common.props = src\PSRule.Common.props
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -45,6 +52,10 @@ Global
{6B21D558-BFC3-4BC6-963E-83B65353196F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6B21D558-BFC3-4BC6-963E-83B65353196F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6B21D558-BFC3-4BC6-963E-83B65353196F}.Release|Any CPU.Build.0 = Release|Any CPU
{F6CFCA60-72D5-474E-8B8B-1AB973434569}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F6CFCA60-72D5-474E-8B8B-1AB973434569}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F6CFCA60-72D5-474E-8B8B-1AB973434569}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F6CFCA60-72D5-474E-8B8B-1AB973434569}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

Просмотреть файл

@ -23,6 +23,9 @@ What's changed since pre-release v2.3.0-B0001:
What's changed since v2.2.0:
- Engineering:
- Refactoring and updates to interfaces to allow use outside of PowerShell.
[#1152](https://github.com/microsoft/PSRule/issues/1152)
- Bug fixes:
- Fixed path within SDK package causes `psd1` to compile by @BernieWhite.
[#1146](https://github.com/microsoft/PSRule/issues/1146)

Просмотреть файл

@ -125,6 +125,16 @@ task TestDotNet {
}
}
task BuildCLI BuildModule, {
exec {
# Build library
dotnet publish src/PSRule.Tool -c $Configuration --no-self-contained -r win-x64 -o ./out/cli/win-x64/ -p:version=$Build
# dotnet publish --self-contained true -p:PublishTrimmed=true -p:PublishSingleFile=true -r win-x64 .\src\PSRule.Tool\PSRule.Tool.csproj -o .\out\cli
}
Copy-Item -Path out/modules/PSRule/ -Destination out/cli/win-x64/modules/ -Recurse -Force;
}
task CopyModule {
CopyModuleFiles -Path src/PSRule -DestinationPath out/modules/PSRule;

Просмотреть файл

@ -75,7 +75,7 @@ namespace PSRule.Benchmark
{
var option = new PSRuleOption();
option.Rule.Include = new string[] { "Benchmark" };
var builder = PipelineBuilder.Get(GetSource(), option, null, null);
var builder = PipelineBuilder.Get(GetSource(), option, null);
_GetPipeline = builder.Build();
}
@ -84,7 +84,7 @@ namespace PSRule.Benchmark
var option = new PSRuleOption();
option.Rule.Include = new string[] { "BenchmarkHelp" };
option.Output.Culture = new string[] { "en-ZZ" };
var builder = PipelineBuilder.GetHelp(GetSource(), option, null, null);
var builder = PipelineBuilder.GetHelp(GetSource(), option, null);
_GetHelpPipeline = builder.Build();
}
@ -92,7 +92,7 @@ namespace PSRule.Benchmark
{
var option = new PSRuleOption();
option.Rule.Include = new string[] { "Benchmark" };
var builder = PipelineBuilder.Invoke(GetSource(), option, null, null);
var builder = PipelineBuilder.Invoke(GetSource(), option, null);
_InvokePipeline = builder.Build();
}
@ -100,7 +100,7 @@ namespace PSRule.Benchmark
{
var option = new PSRuleOption();
option.Rule.Include = new string[] { "BenchmarkIf" };
var builder = PipelineBuilder.Invoke(GetSource(), option, null, null);
var builder = PipelineBuilder.Invoke(GetSource(), option, null);
_InvokeIfPipeline = builder.Build();
}
@ -108,7 +108,7 @@ namespace PSRule.Benchmark
{
var option = new PSRuleOption();
option.Rule.Include = new string[] { "BenchmarkType" };
var builder = PipelineBuilder.Invoke(GetSource(), option, null, null);
var builder = PipelineBuilder.Invoke(GetSource(), option, null);
_InvokeTypePipeline = builder.Build();
}
@ -117,7 +117,7 @@ namespace PSRule.Benchmark
var option = new PSRuleOption();
option.Rule.Include = new string[] { "Benchmark" };
option.Output.As = ResultFormat.Summary;
var builder = PipelineBuilder.Invoke(GetSource(), option, null, null);
var builder = PipelineBuilder.Invoke(GetSource(), option, null);
_InvokeSummaryPipeline = builder.Build();
}
@ -125,7 +125,7 @@ namespace PSRule.Benchmark
{
var option = new PSRuleOption();
option.Rule.Include = new string[] { "Benchmark" };
var builder = PipelineBuilder.Assert(GetSource(), option, null, null);
var builder = PipelineBuilder.Assert(GetSource(), option, null);
_AssertPipeline = builder.Build();
}
@ -133,7 +133,7 @@ namespace PSRule.Benchmark
{
var option = new PSRuleOption();
option.Rule.Include = new string[] { "BenchmarkWithin" };
var builder = PipelineBuilder.Invoke(GetWithinSource(), option, null, null);
var builder = PipelineBuilder.Invoke(GetWithinSource(), option, null);
_InvokeWithinPipeline = builder.Build();
}
@ -141,7 +141,7 @@ namespace PSRule.Benchmark
{
var option = new PSRuleOption();
option.Rule.Include = new string[] { "BenchmarkWithinBulk" };
var builder = PipelineBuilder.Invoke(GetWithinSource(), option, null, null);
var builder = PipelineBuilder.Invoke(GetWithinSource(), option, null);
_InvokeWithinBulkPipeline = builder.Build();
}
@ -149,7 +149,7 @@ namespace PSRule.Benchmark
{
var option = new PSRuleOption();
option.Rule.Include = new string[] { "BenchmarkWithinLike" };
var builder = PipelineBuilder.Invoke(GetWithinSource(), option, null, null);
var builder = PipelineBuilder.Invoke(GetWithinSource(), option, null);
_InvokeWithinLikePipeline = builder.Build();
}
@ -157,7 +157,7 @@ namespace PSRule.Benchmark
{
var option = new PSRuleOption();
option.Rule.Include = new string[] { "Assert.HasFieldValue" };
var builder = PipelineBuilder.Invoke(GetSource(), option, null, null);
var builder = PipelineBuilder.Invoke(GetSource(), option, null);
_AssertHasFieldValuePipeline = builder.Build();
}

Просмотреть файл

@ -3,7 +3,7 @@
<!-- Project defaults -->
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>8.0</LangVersion>
<LangVersion>9.0</LangVersion>
<DebugType>portable</DebugType>
<NeutralLanguage>en-US</NeutralLanguage>
<DebugSymbols>true</DebugSymbols>

Просмотреть файл

@ -0,0 +1,20 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
namespace PSRule.Tool
{
internal sealed class AnalyzerOptions
{
public string[] Path { get; set; }
public string[] Module { get; set; }
public string Option { get; set; }
public string[] InputPath { get; set; }
public bool Verbose { get; set; }
public bool Debug { get; set; }
}
}

Просмотреть файл

@ -0,0 +1,92 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using System.CommandLine;
using System.IO;
using PSRule.Tool.Resource;
namespace PSRule.Tool
{
internal sealed class ClientBuilder
{
private readonly Option<string> _Option;
private readonly Option<bool> _Verbose;
private readonly Option<bool> _Debug;
private readonly Option<string[]> _Path;
private readonly Option<DirectoryInfo> _OutputPath;
private readonly Option<string> _OutputFormat;
private readonly Option<string[]> _InputPath;
private readonly Option<string[]> _Module;
private ClientBuilder(RootCommand cmd)
{
Command = cmd;
_Option = new Option<string>(
new string[] { "--option" },
CmdStrings.Options_Option_Description
);
_Verbose = new Option<bool>(
new string[] { "--verbose" },
CmdStrings.Options_Verbose_Description
);
_Debug = new Option<bool>(
new string[] { "--debug" },
CmdStrings.Options_Debug_Description
);
_Path = new Option<string[]>(
new string[] { "-p", "--path" }
);
_OutputPath = new Option<DirectoryInfo>(
new string[] { "--output-path" }
);
_OutputFormat = new Option<string>(
new string[] { "-o", "--output" }
);
_InputPath = new Option<string[]>(
new string[] { "-f", "--input-path" }
);
_Module = new Option<string[]>(
new string[] { "-m", "--module" }
);
cmd.AddGlobalOption(_Option);
cmd.AddGlobalOption(_Verbose);
cmd.AddGlobalOption(_Debug);
}
public RootCommand Command { get; }
public static Command New()
{
var cmd = new RootCommand();
var builder = new ClientBuilder(cmd);
builder.AddAnalyze();
return builder.Command;
}
private void AddAnalyze()
{
var cmd = new Command("analyze", CmdStrings.Analyze_Description);
cmd.AddOption(_Path);
cmd.AddOption(_OutputPath);
cmd.AddOption(_OutputFormat);
cmd.AddOption(_InputPath);
cmd.AddOption(_Module);
cmd.SetHandler((invocation) =>
{
var option = new AnalyzerOptions
{
Path = invocation.ParseResult.GetValueForOption(_Path),
InputPath = invocation.ParseResult.GetValueForOption(_InputPath),
Module = invocation.ParseResult.GetValueForOption(_Module),
Option = invocation.ParseResult.GetValueForOption(_Option),
Verbose = invocation.ParseResult.GetValueForOption(_Verbose),
Debug = invocation.ParseResult.GetValueForOption(_Debug),
};
var client = new ClientContext();
ClientHelper.RunAnalyze(option, client, invocation);
});
Command.AddCommand(cmd);
}
}
}

Просмотреть файл

@ -0,0 +1,17 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using System;
namespace PSRule.Tool
{
internal sealed class ClientContext
{
public ClientContext()
{
Path = AppDomain.CurrentDomain.BaseDirectory;
}
public string Path { get; }
}
}

Просмотреть файл

@ -0,0 +1,36 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using System.CommandLine.Invocation;
using PSRule.Configuration;
using PSRule.Pipeline;
namespace PSRule.Tool
{
internal sealed class ClientHelper
{
public static void RunAnalyze(AnalyzerOptions analyzerOptions, ClientContext clientContext, InvocationContext invocation)
{
var option = GetOption();
var host = new ClientHost(invocation, analyzerOptions.Verbose, analyzerOptions.Debug);
var inputPath = analyzerOptions.InputPath == null || analyzerOptions.InputPath.Length == 0 ?
new string[] { PSRuleOption.GetWorkingPath() } : analyzerOptions.InputPath;
var builder = CommandLineBuilder.Assert(new string[] { "PSRule.Rules.Azure" }, option, host);
builder.InputPath(inputPath);
using var pipeline = builder.Build();
pipeline.Begin();
pipeline.Process(null);
pipeline.End();
}
private static PSRuleOption GetOption()
{
var option = PSRuleOption.FromFileOrEmpty();
option.Input.Format = InputFormat.File;
option.Output.Style = OutputStyle.Client;
return option;
}
}
}

Просмотреть файл

@ -0,0 +1,46 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using System.CommandLine;
using System.CommandLine.Invocation;
using System.CommandLine.IO;
using System.Management.Automation;
using PSRule.Pipeline;
namespace PSRule.Tool
{
internal sealed class ClientHost : HostContext
{
private InvocationContext _Invocation;
private readonly bool _Verbose;
private readonly bool _Debug;
public ClientHost(InvocationContext invocation, bool verbose, bool debug)
{
_Invocation = invocation;
_Verbose = verbose;
_Debug = debug;
}
public override void Error(ErrorRecord errorRecord)
{
_Invocation.Console.Error.WriteLine(errorRecord.Exception.Message);
}
public override void Warning(string text)
{
_Invocation.Console.WriteLine(text);
}
public override bool ShouldProcess(string target, string action)
{
return true;
}
public override void Information(InformationRecord informationRecord)
{
if (informationRecord?.MessageData is HostInformationMessage info)
_Invocation.Console.WriteLine(info.Message);
}
}
}

Просмотреть файл

@ -0,0 +1,58 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\PSRule.Common.props" />
<PropertyGroup>
<AssemblyName>Microsoft.PSRule.Tool</AssemblyName>
<PackageId>Microsoft.PSRule.Tool</PackageId>
<RootNamespace>PSRule.Tool</RootNamespace>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<StartupObject>PSRule.Tool.Program</StartupObject>
<IncludeNativeLibrariesForSelfExtract>true</IncludeNativeLibrariesForSelfExtract>
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<PackAsTool>true</PackAsTool>
<ToolCommandName>ps-rule</ToolCommandName>
<PackageReadmeFile>README.md</PackageReadmeFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.PowerShell.SDK" Version="7.2.5" />
<PackageReference Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="6.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ModuleFiles Include="..\PSRule.SDK\PSRule.psd1;" />
</ItemGroup>
<Target Name="CopyModuleFiles" BeforeTargets="Build">
<Copy SourceFiles="@(ModuleFiles)" DestinationFolder="$(TargetDir)Modules\PSRule" />
</Target>
<ItemGroup>
<ProjectReference Include="..\PSRule.SDK\PSRule.SDK.csproj" />
</ItemGroup>
<ItemGroup>
<Compile Update="Resources\CmdStrings.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>CmdStrings.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Resources\CmdStrings.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>CmdStrings.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,20 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using System.CommandLine;
using System.CommandLine.Parsing;
using System.Threading.Tasks;
namespace PSRule.Tool
{
class Program
{
/// <summary>
/// Entry point for CLI tool.
/// </summary>
static async Task<int> Main(string[] args)
{
return await ClientBuilder.New().InvokeAsync(args);
}
}
}

Просмотреть файл

@ -0,0 +1,9 @@
{
"profiles": {
"PSRule.Tool": {
"commandName": "Project",
"commandLineArgs": "analyze",
"workingDirectory": "C:\\Dev\\Workspace\\AzureDevOps-bewhite"
}
}
}

Просмотреть файл

@ -0,0 +1,3 @@
# PSRule CLI tool
This package installs the PSRule CLI tool for .NET.

127
src/PSRule.Tool/Resources/CmdStrings.Designer.cs сгенерированный Normal file
Просмотреть файл

@ -0,0 +1,127 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace PSRule.Tool.Resource
{
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class CmdStrings
{
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal CmdStrings()
{
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager
{
get
{
if (object.ReferenceEquals(resourceMan, null))
{
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("PSRule.Tool.Resources.CmdStrings", typeof(CmdStrings).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture
{
get
{
return resourceCulture;
}
set
{
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized string similar to Run rule analysis.
/// </summary>
internal static string Analyze_Description
{
get
{
return ResourceManager.GetString("Analyze_Description", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Return debug output.
/// </summary>
internal static string Options_Debug_Description
{
get
{
return ResourceManager.GetString("Options_Debug_Description", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to An options file.
/// </summary>
internal static string Options_Option_Description
{
get
{
return ResourceManager.GetString("Options_Option_Description", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to .
/// </summary>
internal static string Options_Path_Description
{
get
{
return ResourceManager.GetString("Options_Path_Description", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Return verbose output.
/// </summary>
internal static string Options_Verbose_Description
{
get
{
return ResourceManager.GetString("Options_Verbose_Description", resourceCulture);
}
}
}
}

Просмотреть файл

@ -0,0 +1,135 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Analyze_Description" xml:space="preserve">
<value>Run rule analysis</value>
</data>
<data name="Options_Debug_Description" xml:space="preserve">
<value>Return debug output</value>
</data>
<data name="Options_Option_Description" xml:space="preserve">
<value>An options file</value>
</data>
<data name="Options_Path_Description" xml:space="preserve">
<value />
</data>
<data name="Options_Verbose_Description" xml:space="preserve">
<value>Return verbose output</value>
</data>
</root>

Просмотреть файл

@ -242,6 +242,18 @@ namespace PSRule.Configuration
return !File.Exists(filePath) ? new PSRuleOption() : FromEnvironment(FromYaml(path: filePath, yaml: File.ReadAllText(filePath)));
}
/// <summary>
/// Load a YAML formatted PSRuleOption object from disk.
/// </summary>
/// <returns>An options object.</returns>
/// <remarks>
/// This method is called from PowerShell.
/// </remarks>
public static PSRuleOption FromFileOrEmpty()
{
return FromFileOrEmpty(GetWorkingPath());
}
/// <summary>
/// Load a YAML formatted PSRuleOption object from disk.
/// </summary>

Просмотреть файл

@ -152,7 +152,8 @@ function Invoke-PSRule {
$Option.Output.Culture = $Culture;
}
$builder = [PSRule.Pipeline.PipelineBuilder]::Invoke($sourceFiles, $Option, $PSCmdlet, $ExecutionContext);
$hostContext = [PSRule.Pipeline.PSHostContext]::new($PSCmdlet, $ExecutionContext);
$builder = [PSRule.Pipeline.PipelineBuilder]::Invoke($sourceFiles, $Option, $hostContext);
$builder.Name($Name);
$builder.Tag($Tag);
$builder.Convention($Convention);
@ -300,7 +301,8 @@ function Test-PSRuleTarget {
$Option.Output.Culture = $Culture;
}
$builder = [PSRule.Pipeline.PipelineBuilder]::Test($sourceFiles, $Option, $PSCmdlet, $ExecutionContext);
$hostContext = [PSRule.Pipeline.PSHostContext]::new($PSCmdlet, $ExecutionContext);
$builder = [PSRule.Pipeline.PipelineBuilder]::Test($sourceFiles, $Option, $hostContext);
$builder.Name($Name);
$builder.Tag($Tag);
$builder.Convention($Convention);
@ -405,7 +407,8 @@ function Get-PSRuleTarget {
$Option.Output.Path = $OutputPath;
}
$builder = [PSRule.Pipeline.PipelineBuilder]::GetTarget($Option, $PSCmdlet, $ExecutionContext);
$hostContext = [PSRule.Pipeline.PSHostContext]::new($PSCmdlet, $ExecutionContext);
$builder = [PSRule.Pipeline.PipelineBuilder]::GetTarget($Option, $hostContext);
if ($PSBoundParameters.ContainsKey('InputPath')) {
$builder.InputPath($InputPath);
@ -583,7 +586,8 @@ function Assert-PSRule {
$Option.Output.Culture = $Culture;
}
$builder = [PSRule.Pipeline.PipelineBuilder]::Assert($sourceFiles, $Option, $PSCmdlet, $ExecutionContext);;
$hostContext = [PSRule.Pipeline.PSHostContext]::new($PSCmdlet, $ExecutionContext);
$builder = [PSRule.Pipeline.PipelineBuilder]::Assert($sourceFiles, $Option, $hostContext);;
$builder.Name($Name);
$builder.Tag($Tag);
$builder.Convention($Convention);
@ -723,7 +727,8 @@ function Get-PSRule {
$Option.Output.Culture = $Culture;
}
$builder = [PSRule.Pipeline.PipelineBuilder]::Get($sourceFiles, $Option, $PSCmdlet, $ExecutionContext);
$hostContext = [PSRule.Pipeline.PSHostContext]::new($PSCmdlet, $ExecutionContext);
$builder = [PSRule.Pipeline.PipelineBuilder]::Get($sourceFiles, $Option, $hostContext);
$builder.Name($Name);
$builder.Tag($Tag);
$builder.UseBaseline($Baseline);
@ -835,7 +840,8 @@ function Get-PSRuleBaseline {
$Option.Output.Format = $OutputFormat;
}
$builder = [PSRule.Pipeline.PipelineBuilder]::GetBaseline($sourceFiles, $Option, $PSCmdlet, $ExecutionContext);;
$hostContext = [PSRule.Pipeline.PSHostContext]::new($PSCmdlet, $ExecutionContext);
$builder = [PSRule.Pipeline.PipelineBuilder]::GetBaseline($sourceFiles, $Option, $hostContext);;
$builder.Name($Name);
try {
$pipeline = $builder.Build();
@ -944,7 +950,8 @@ function Export-PSRuleBaseline {
$Option.Output.Encoding = $OutputEncoding;
}
$builder = [PSRule.Pipeline.PipelineBuilder]::ExportBaseline($sourceFiles, $Option, $PSCmdlet, $ExecutionContext);;
$hostContext = [PSRule.Pipeline.PSHostContext]::new($PSCmdlet, $ExecutionContext);
$builder = [PSRule.Pipeline.PipelineBuilder]::ExportBaseline($sourceFiles, $Option, $hostContext);;
$builder.Name($Name);
try {
$pipeline = $builder.Build();
@ -1055,7 +1062,8 @@ function Get-PSRuleHelp {
$Option.Output.Culture = $Culture;
}
$builder = [PSRule.Pipeline.PipelineBuilder]::GetHelp($sourceFiles, $Option, $PSCmdlet, $ExecutionContext);;
$hostContext = [PSRule.Pipeline.PSHostContext]::new($PSCmdlet, $ExecutionContext);
$builder = [PSRule.Pipeline.PipelineBuilder]::GetHelp($sourceFiles, $Option, $hostContext);;
if ($Online) {
$builder.Online();
@ -1970,7 +1978,8 @@ function GetSource {
[PSRule.Configuration.PSRuleOption]$Option
)
process {
$builder = [PSRule.Pipeline.PipelineBuilder]::RuleSource($Option, $PSCmdlet, $ExecutionContext);
$hostContext = [PSRule.Pipeline.PSHostContext]::new($PSCmdlet, $ExecutionContext);
$builder = [PSRule.Pipeline.PipelineBuilder]::RuleSource($Option, $hostContext);
$moduleParams = @{};
if ($PSBoundParameters.ContainsKey('Module')) {

Просмотреть файл

@ -18,7 +18,7 @@ namespace PSRule.Pipeline
{
private AssertWriter _Writer;
internal AssertPipelineBuilder(Source[] source, HostContext hostContext)
internal AssertPipelineBuilder(Source[] source, IHostContext hostContext)
: base(source, hostContext) { }
/// <summary>
@ -29,8 +29,7 @@ namespace PSRule.Pipeline
internal readonly IAssertFormatter _Formatter;
private readonly PipelineWriter _InnerWriter;
private readonly string _ResultVariableName;
private readonly PSCmdlet _CmdletContext;
private readonly EngineIntrinsics _ExecutionContext;
private readonly IHostContext _HostContext;
private readonly List<RuleRecord> _Results;
private int _ErrorCount;
private int _FailCount;
@ -38,13 +37,12 @@ namespace PSRule.Pipeline
private bool _PSError;
private SeverityLevel _Level;
internal AssertWriter(PSRuleOption option, Source[] source, PipelineWriter inner, PipelineWriter next, OutputStyle style, string resultVariableName, PSCmdlet cmdletContext, EngineIntrinsics executionContext)
internal AssertWriter(PSRuleOption option, Source[] source, PipelineWriter inner, PipelineWriter next, OutputStyle style, string resultVariableName, IHostContext hostContext)
: base(inner, option)
{
_InnerWriter = next;
_ResultVariableName = resultVariableName;
_CmdletContext = cmdletContext;
_ExecutionContext = executionContext;
_HostContext = hostContext;
if (!string.IsNullOrEmpty(resultVariableName))
_Results = new List<RuleRecord>();
@ -95,7 +93,7 @@ namespace PSRule.Pipeline
public override void WriteWarning(string message)
{
var warningPreference = GetPreferenceVariable(_ExecutionContext.SessionState, WarningPreference);
var warningPreference = _HostContext.GetPreferenceVariable(WarningPreference);
if (warningPreference == ActionPreference.Ignore || warningPreference == ActionPreference.SilentlyContinue)
return;
@ -104,7 +102,7 @@ namespace PSRule.Pipeline
public override void WriteError(ErrorRecord errorRecord)
{
var errorPreference = GetPreferenceVariable(_ExecutionContext.SessionState, ErrorPreference);
var errorPreference = _HostContext.GetPreferenceVariable(ErrorPreference);
if (errorPreference == ActionPreference.Ignore || errorPreference == ActionPreference.SilentlyContinue)
return;
@ -154,8 +152,8 @@ namespace PSRule.Pipeline
if (_FailCount > 0 && _Level == SeverityLevel.Information)
base.WriteHost(new HostInformationMessage() { Message = PSRuleResources.RuleFailPipelineException });
if (_Results != null && _CmdletContext != null)
_CmdletContext.SessionState.PSVariable.Set(_ResultVariableName, _Results.ToArray());
if (_Results != null && _HostContext != null)
_HostContext.SetVariable(_ResultVariableName, _Results.ToArray());
}
finally
{
@ -198,8 +196,7 @@ namespace PSRule.Pipeline
next: next,
style: Option.Output.Style ?? OutputOption.Default.Style.Value,
resultVariableName: _ResultVariableName,
cmdletContext: HostContext.CmdletContext,
executionContext: HostContext.ExecutionContext
hostContext: HostContext
);
}
return _Writer;

Просмотреть файл

@ -0,0 +1,34 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using PSRule.Configuration;
namespace PSRule.Pipeline
{
public static class CommandLineBuilder
{
public static IInvokePipelineBuilder Invoke(string[] module, PSRuleOption option, IHostContext hostContext)
{
var sourcePipeline = new SourcePipelineBuilder(hostContext, option);
for (var i = 0; i < module.Length; i++)
sourcePipeline.ModuleByName(module[i]);
var source = sourcePipeline.Build();
var pipeline = new InvokeRulePipelineBuilder(source, hostContext);
pipeline.Configure(option);
return pipeline;
}
public static IInvokePipelineBuilder Assert(string[] module, PSRuleOption option, IHostContext hostContext)
{
var sourcePipeline = new SourcePipelineBuilder(hostContext, option);
for (var i = 0; i < module.Length; i++)
sourcePipeline.ModuleByName(module[i]);
var source = sourcePipeline.Build();
var pipeline = new AssertPipelineBuilder(source, hostContext);
pipeline.Configure(option);
return pipeline;
}
}
}

Просмотреть файл

@ -10,7 +10,7 @@ namespace PSRule.Pipeline
{
private string[] _Name;
internal ExportBaselinePipelineBuilder(Source[] source, HostContext hostContext)
internal ExportBaselinePipelineBuilder(Source[] source, IHostContext hostContext)
: base(source, hostContext) { }
/// <summary>

Просмотреть файл

@ -10,7 +10,7 @@ namespace PSRule.Pipeline
{
private string[] _Name;
internal GetBaselinePipelineBuilder(Source[] source, HostContext hostContext)
internal GetBaselinePipelineBuilder(Source[] source, IHostContext hostContext)
: base(source, hostContext) { }
/// <summary>

Просмотреть файл

@ -24,7 +24,7 @@ namespace PSRule.Pipeline
private bool _Full;
private bool _Online;
internal GetRuleHelpPipelineBuilder(Source[] source, HostContext hostContext)
internal GetRuleHelpPipelineBuilder(Source[] source, IHostContext hostContext)
: base(source, hostContext) { }
public override IPipelineBuilder Configure(PSRuleOption option)

Просмотреть файл

@ -17,7 +17,7 @@ namespace PSRule.Pipeline
{
private bool _IncludeDependencies;
internal GetRulePipelineBuilder(Source[] source, HostContext hostContext)
internal GetRulePipelineBuilder(Source[] source, IHostContext hostContext)
: base(source, hostContext) { }
public override IPipelineBuilder Configure(PSRuleOption option)

Просмотреть файл

@ -20,7 +20,7 @@ namespace PSRule.Pipeline
{
private InputFileInfo[] _InputPath;
internal GetTargetPipelineBuilder(Source[] source, HostContext hostContext)
internal GetTargetPipelineBuilder(Source[] source, IHostContext hostContext)
: base(source, hostContext)
{
_InputPath = null;

Просмотреть файл

@ -1,15 +1,34 @@
// Copyright (c) Microsoft Corporation.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using System.Management.Automation;
using PSRule.Definitions;
namespace PSRule.Pipeline
{
public interface IHostContext
{
bool InSession { get; }
ActionPreference GetPreferenceVariable(string variableName);
T GetVariable<T>(string variableName);
void SetVariable<T>(string variableName, T value);
void Error(ErrorRecord errorRecord);
void Warning(string text);
void Information(InformationRecord informationRecord);
void Verbose(string text);
void Debug(string text);
void Object(object sendToPipeline, bool enumerateCollection);
bool ShouldProcess(string target, string action);
}
internal static class HostContextExtensions
@ -52,17 +71,81 @@ namespace PSRule.Pipeline
}
}
internal sealed class HostContext : IHostContext
public abstract class HostContext : IHostContext
{
private const string ErrorPreference = "ErrorActionPreference";
private const string WarningPreference = "WarningPreference";
public virtual bool InSession => false;
public virtual void Debug(string text)
{
}
public virtual void Error(ErrorRecord errorRecord)
{
}
public virtual ActionPreference GetPreferenceVariable(string variableName)
{
return variableName == ErrorPreference ||
variableName == WarningPreference ? ActionPreference.Continue : ActionPreference.Ignore;
}
public virtual T GetVariable<T>(string variableName)
{
return default;
}
public virtual void Information(InformationRecord informationRecord)
{
}
public virtual void Object(object sendToPipeline, bool enumerateCollection)
{
if (sendToPipeline is IResultRecord record)
Record(record);
//else if (enumerateCollection)
// foreach (var item in record)
}
public virtual void SetVariable<T>(string variableName, T value)
{
}
public abstract bool ShouldProcess(string target, string action);
public virtual void Verbose(string text)
{
}
public virtual void Warning(string text)
{
}
public virtual void Record(IResultRecord record)
{
}
}
public sealed class PSHostContext : IHostContext
{
internal readonly PSCmdlet CmdletContext;
internal readonly EngineIntrinsics ExecutionContext;
/// <summary>
/// Determine if running is remote session.
/// Determine if running in a remote session.
/// </summary>
internal bool InSession;
public bool InSession { get; }
public HostContext(PSCmdlet commandRuntime, EngineIntrinsics executionContext)
public PSHostContext(PSCmdlet commandRuntime, EngineIntrinsics executionContext)
{
InSession = false;
CmdletContext = commandRuntime;
@ -82,9 +165,44 @@ namespace PSRule.Pipeline
return ExecutionContext == null ? default : (T)ExecutionContext.SessionState.PSVariable.GetValue(variableName);
}
public void SetVariable<T>(string variableName, T value)
{
CmdletContext.SessionState.PSVariable.Set(variableName, value);
}
public bool ShouldProcess(string target, string action)
{
return CmdletContext == null || CmdletContext.ShouldProcess(target, action);
}
public void Error(ErrorRecord errorRecord)
{
CmdletContext.WriteError(errorRecord);
}
public void Warning(string text)
{
CmdletContext.WriteWarning(text);
}
public void Information(InformationRecord informationRecord)
{
CmdletContext.WriteInformation(informationRecord);
}
public void Verbose(string text)
{
CmdletContext.WriteVerbose(text);
}
public void Debug(string text)
{
CmdletContext.WriteDebug(text);
}
public void Object(object sendToPipeline, bool enumerateCollection)
{
CmdletContext.WriteObject(sendToPipeline, enumerateCollection);
}
}
}

Просмотреть файл

@ -25,7 +25,7 @@ namespace PSRule.Pipeline
protected InputFileInfo[] _InputPath;
protected string _ResultVariableName;
protected InvokePipelineBuilderBase(Source[] source, HostContext hostContext)
protected InvokePipelineBuilderBase(Source[] source, IHostContext hostContext)
: base(source, hostContext)
{
_InputPath = null;
@ -152,7 +152,7 @@ namespace PSRule.Pipeline
/// </summary>
internal sealed class InvokeRulePipelineBuilder : InvokePipelineBuilderBase
{
internal InvokeRulePipelineBuilder(Source[] source, HostContext hostContext)
internal InvokeRulePipelineBuilder(Source[] source, IHostContext hostContext)
: base(source, hostContext) { }
}

Просмотреть файл

@ -35,13 +35,13 @@ namespace PSRule.Pipeline.Output
private string _ScopeName;
internal HostPipelineWriter(HostContext hostContext, PSRuleOption option)
internal HostPipelineWriter(IHostContext hostContext, PSRuleOption option)
: base(null, option)
{
if (hostContext != null)
{
UseCommandRuntime(hostContext.CmdletContext);
UseExecutionContext(hostContext.ExecutionContext);
UseCommandRuntime(hostContext);
UseExecutionContext(hostContext);
}
}
@ -54,34 +54,34 @@ namespace PSRule.Pipeline.Output
_DebugFilter = new HashSet<string>(Option.Logging.LimitDebug);
}
private void UseCommandRuntime(PSCmdlet commandRuntime)
private void UseCommandRuntime(IHostContext hostContext)
{
if (commandRuntime == null)
if (hostContext == null)
return;
OnWriteVerbose = commandRuntime.WriteVerbose;
OnWriteWarning = commandRuntime.WriteWarning;
OnWriteError = commandRuntime.WriteError;
OnWriteInformation = commandRuntime.WriteInformation;
OnWriteDebug = commandRuntime.WriteDebug;
OnWriteObject = commandRuntime.WriteObject;
OnWriteVerbose = hostContext.Verbose;
OnWriteWarning = hostContext.Warning;
OnWriteError = hostContext.Error;
OnWriteInformation = hostContext.Information;
OnWriteDebug = hostContext.Debug;
OnWriteObject = hostContext.Object;
}
private void UseExecutionContext(EngineIntrinsics executionContext)
private void UseExecutionContext(IHostContext hostContext)
{
if (executionContext == null)
if (hostContext == null)
return;
_LogError = GetPreferenceVariable(executionContext, ErrorPreference);
_LogWarning = GetPreferenceVariable(executionContext, WarningPreference);
_LogVerbose = GetPreferenceVariable(executionContext, VerbosePreference);
_LogInformation = GetPreferenceVariable(executionContext, InformationPreference);
_LogDebug = GetPreferenceVariable(executionContext, DebugPreference);
_LogError = GetPreferenceVariable(hostContext, ErrorPreference);
_LogWarning = GetPreferenceVariable(hostContext, WarningPreference);
_LogVerbose = GetPreferenceVariable(hostContext, VerbosePreference);
_LogInformation = GetPreferenceVariable(hostContext, InformationPreference);
_LogDebug = GetPreferenceVariable(hostContext, DebugPreference);
}
private static bool GetPreferenceVariable(EngineIntrinsics executionContext, string variableName)
private static bool GetPreferenceVariable(IHostContext hostContext, string variableName)
{
var preference = GetPreferenceVariable(executionContext.SessionState, variableName);
var preference = hostContext.GetPreferenceVariable(variableName);
return preference != ActionPreference.Ignore && !(preference == ActionPreference.SilentlyContinue && (
variableName == VerbosePreference ||
variableName == DebugPreference)

Просмотреть файл

@ -1,6 +1,7 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
@ -19,72 +20,63 @@ namespace PSRule.Pipeline
{
public static class PipelineBuilder
{
public static IInvokePipelineBuilder Assert(Source[] source, PSRuleOption option, PSCmdlet commandRuntime, EngineIntrinsics executionContext)
public static IInvokePipelineBuilder Assert(Source[] source, PSRuleOption option, IHostContext hostContext)
{
var hostContext = new HostContext(commandRuntime, executionContext);
var pipeline = new AssertPipelineBuilder(source, hostContext);
pipeline.Configure(option);
return pipeline;
}
public static IInvokePipelineBuilder Invoke(Source[] source, PSRuleOption option, PSCmdlet commandRuntime, EngineIntrinsics executionContext)
public static IInvokePipelineBuilder Invoke(Source[] source, PSRuleOption option, IHostContext hostContext)
{
var hostContext = new HostContext(commandRuntime, executionContext);
var pipeline = new InvokeRulePipelineBuilder(source, hostContext);
pipeline.Configure(option);
return pipeline;
}
public static IInvokePipelineBuilder Test(Source[] source, PSRuleOption option, PSCmdlet commandRuntime, EngineIntrinsics executionContext)
public static IInvokePipelineBuilder Test(Source[] source, PSRuleOption option, IHostContext hostContext)
{
var hostContext = new HostContext(commandRuntime, executionContext);
var pipeline = new TestPipelineBuilder(source, hostContext);
pipeline.Configure(option);
return pipeline;
}
public static IGetPipelineBuilder Get(Source[] source, PSRuleOption option, PSCmdlet commandRuntime, EngineIntrinsics executionContext)
public static IGetPipelineBuilder Get(Source[] source, PSRuleOption option, IHostContext hostContext)
{
var hostContext = new HostContext(commandRuntime, executionContext);
var pipeline = new GetRulePipelineBuilder(source, hostContext);
pipeline.Configure(option);
return pipeline;
}
public static IHelpPipelineBuilder GetHelp(Source[] source, PSRuleOption option, PSCmdlet commandRuntime, EngineIntrinsics executionContext)
public static IHelpPipelineBuilder GetHelp(Source[] source, PSRuleOption option, IHostContext hostContext)
{
var hostContext = new HostContext(commandRuntime, executionContext);
var pipeline = new GetRuleHelpPipelineBuilder(source, hostContext);
pipeline.Configure(option);
return pipeline;
}
public static SourcePipelineBuilder RuleSource(PSRuleOption option, PSCmdlet commandRuntime, EngineIntrinsics executionContext)
public static ISourcePipelineBuilder RuleSource(PSRuleOption option, IHostContext hostContext)
{
var hostContext = new HostContext(commandRuntime, executionContext);
var pipeline = new SourcePipelineBuilder(hostContext, option);
return pipeline;
}
public static IPipelineBuilder GetBaseline(Source[] source, PSRuleOption option, PSCmdlet commandRuntime, EngineIntrinsics executionContext)
public static IPipelineBuilder GetBaseline(Source[] source, PSRuleOption option, IHostContext hostContext)
{
var hostContext = new HostContext(commandRuntime, executionContext);
var pipeline = new GetBaselinePipelineBuilder(source, hostContext);
pipeline.Configure(option);
return pipeline;
}
public static IPipelineBuilder ExportBaseline(Source[] source, PSRuleOption option, PSCmdlet commandRuntime, EngineIntrinsics executionContext)
public static IPipelineBuilder ExportBaseline(Source[] source, PSRuleOption option, IHostContext hostContext)
{
var hostContext = new HostContext(commandRuntime, executionContext);
var pipeline = new ExportBaselinePipelineBuilder(source, hostContext);
pipeline.Configure(option);
return pipeline;
}
public static IGetTargetPipelineBuilder GetTarget(PSRuleOption option, PSCmdlet commandRuntime, EngineIntrinsics executionContext)
public static IGetTargetPipelineBuilder GetTarget(PSRuleOption option, IHostContext hostContext)
{
var hostContext = new HostContext(commandRuntime, executionContext);
var pipeline = new GetTargetPipelineBuilder(null, hostContext);
pipeline.Configure(option);
return pipeline;
@ -98,7 +90,7 @@ namespace PSRule.Pipeline
IPipeline Build(IPipelineWriter writer = null);
}
public interface IPipeline
public interface IPipeline : IDisposable
{
void Begin();
@ -114,7 +106,7 @@ namespace PSRule.Pipeline
protected readonly PSRuleOption Option;
protected readonly Source[] Source;
protected readonly HostContext HostContext;
protected readonly IHostContext HostContext;
protected BindTargetMethod BindTargetNameHook;
protected BindTargetMethod BindTargetTypeHook;
protected BindTargetMethod BindFieldHook;
@ -131,7 +123,7 @@ namespace PSRule.Pipeline
private const int MIN_JSON_INDENT = 0;
private const int MAX_JSON_INDENT = 4;
protected PipelineBuilderBase(Source[] source, HostContext hostContext)
protected PipelineBuilderBase(Source[] source, IHostContext hostContext)
{
Option = new PSRuleOption();
Source = source;

Просмотреть файл

@ -52,7 +52,7 @@ namespace PSRule.Pipeline
internal readonly Dictionary<string, SelectorVisitor> Selector;
internal readonly List<SuppressionGroupVisitor> SuppressionGroup;
internal readonly OptionContext Baseline;
internal readonly HostContext HostContext;
internal readonly IHostContext HostContext;
internal readonly PipelineReader Reader;
internal readonly BindTargetMethod BindTargetName;
internal readonly BindTargetMethod BindTargetType;
@ -72,7 +72,7 @@ namespace PSRule.Pipeline
}
}
private PipelineContext(PSRuleOption option, HostContext hostContext, PipelineReader reader, BindTargetMethod bindTargetName, BindTargetMethod bindTargetType, BindTargetMethod bindField, OptionContext baseline, IList<ResourceRef> unresolved)
private PipelineContext(PSRuleOption option, IHostContext hostContext, PipelineReader reader, BindTargetMethod bindTargetName, BindTargetMethod bindTargetType, BindTargetMethod bindField, OptionContext baseline, IList<ResourceRef> unresolved)
{
Option = option;
HostContext = hostContext;
@ -94,7 +94,7 @@ namespace PSRule.Pipeline
RunTime = Stopwatch.StartNew();
}
public static PipelineContext New(PSRuleOption option, HostContext hostContext, PipelineReader reader, BindTargetMethod bindTargetName, BindTargetMethod bindTargetType, BindTargetMethod bindField, OptionContext baseline, IList<ResourceRef> unresolved)
public static PipelineContext New(PSRuleOption option, IHostContext hostContext, PipelineReader reader, BindTargetMethod bindTargetName, BindTargetMethod bindTargetType, BindTargetMethod bindField, OptionContext baseline, IList<ResourceRef> unresolved)
{
var context = new PipelineContext(option, hostContext, reader, bindTargetName, bindTargetType, bindField, baseline, unresolved);
CurrentThread = context;

Просмотреть файл

@ -7,7 +7,7 @@ using PSRule.Runtime;
namespace PSRule.Pipeline
{
internal abstract class RulePipeline : IDisposable, IPipeline
internal abstract class RulePipeline : IPipeline
{
protected readonly PipelineContext Pipeline;
protected readonly RunspaceContext Context;

Просмотреть файл

@ -121,6 +121,18 @@ namespace PSRule.Pipeline
Version = string.Concat(Version, PRERELEASE_SEPARATOR, psData[FIELD_PRERELEASE].ToString());
}
public ModuleInfo(string path, string name, string version, string projectUri, string guid, string companyName, string prerelease)
{
Path = path;
Name = name;
Version = version;
ProjectUri = projectUri;
Guid = guid;
CompanyName = companyName;
if (!string.IsNullOrEmpty(prerelease))
Version = string.Concat(version, PRERELEASE_SEPARATOR, prerelease);
}
private static bool TryPrivateData(PSModuleInfo info, string propertyName, out Hashtable value)
{
value = null;

Просмотреть файл

@ -2,10 +2,12 @@
// Licensed under the MIT License.
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Management.Automation;
using System.Reflection;
using System.Threading;
using PSRule.Configuration;
using PSRule.Pipeline.Output;
@ -13,10 +15,40 @@ using PSRule.Resources;
namespace PSRule.Pipeline
{
public interface ISourcePipelineBuilder
{
bool ShouldLoadModule { get; }
void VerboseScanSource(string path);
void VerboseFoundModules(int count);
void VerboseScanModule(string moduleName);
void Directory(string[] path, bool excludeDefaultRulePath = false);
void Directory(string path, bool excludeDefaultRulePath = false);
void Module(PSModuleInfo[] module);
Source[] Build();
}
public interface ISourceCommandlineBuilder
{
void Directory(string[] path, bool excludeDefaultRulePath = false);
void Directory(string path, bool excludeDefaultRulePath = false);
void ModuleByName(string name);
Source[] Build();
}
/// <summary>
/// A helper to build a list of rule sources for discovery.
/// </summary>
public sealed class SourcePipelineBuilder
public sealed class SourcePipelineBuilder : ISourcePipelineBuilder, ISourceCommandlineBuilder
{
private const string SourceFileExtension_YAML = ".yaml";
private const string SourceFileExtension_YML = ".yml";
@ -27,17 +59,19 @@ namespace PSRule.Pipeline
private const string DefaultRulePath = ".ps-rule/";
private readonly Dictionary<string, Source> _Source;
private readonly HostContext _HostContext;
private readonly IHostContext _HostContext;
private readonly HostPipelineWriter _Writer;
private readonly bool _UseDefaultPath;
private readonly string _LocalPath;
internal SourcePipelineBuilder(HostContext hostContext, PSRuleOption option)
internal SourcePipelineBuilder(IHostContext hostContext, PSRuleOption option)
{
_Source = new Dictionary<string, Source>(StringComparer.OrdinalIgnoreCase);
_HostContext = hostContext;
_Writer = new HostPipelineWriter(hostContext, option);
_Writer.EnterScope("[Discovery.Source]");
_UseDefaultPath = option == null || option.Include == null || option.Include.Path == null;
_LocalPath = PSRuleOption.GetRootedBasePath(Path.GetDirectoryName(typeof(SourcePipelineBuilder).Assembly.Location));
// Include paths from options
if (!_UseDefaultPath)
@ -110,6 +144,64 @@ namespace PSRule.Pipeline
Module(module[i], dependency: false);
}
/// <summary>
/// Add a module source.
/// </summary>
/// <param name="name">The name of the module.</param>
public void ModuleByName(string name)
{
var basePath = FindModule(name);
var info = LoadManifest(basePath);
if (info == null)
throw new PipelineBuilderException(PSRuleResources.ModuleNotFound);
VerboseScanModule(info.Name);
var files = GetFiles(basePath, basePath, excludeDefaultRulePath: false, info.Name);
if (files == null || files.Length == 0)
return;
Source(new Source(info, files, dependency: false));
// Import dependencies
//for (var i = 0; module.RequiredModules != null && i < module.RequiredModules.Count; i++)
// Module(module.RequiredModules[i], dependency: true);
}
private string FindModule(string name)
{
return PSRuleOption.GetRootedBasePath(Path.Combine(_LocalPath, "Modules", name));
}
private static Source.ModuleInfo LoadManifest(string basePath)
{
var name = Path.GetFileName(Path.GetDirectoryName(basePath));
var path = Path.Combine(basePath, string.Concat(name, ".psd1"));
if (!File.Exists(path))
return null;
var reader = new StreamReader(path);
var data = reader.ReadToEnd();
var ast = System.Management.Automation.Language.Parser.ParseInput(data, out _, out _);
var hashtable = ast.FindAll(item => item is System.Management.Automation.Language.HashtableAst, false).FirstOrDefault();
var manifest = hashtable.SafeGetValue() as Hashtable;
if (manifest == null)
return null;
var version = manifest["ModuleVersion"] as string;
var guid = manifest["GUID"] as string;
var companyName = manifest["CompanyName"] as string;
var privateData = manifest["PrivateData"] as Hashtable;
var psData = privateData["PSData"] as Hashtable;
var projectUri = psData["ProjectUri"] as string;
var prerelease = psData["Prerelease"] as string;
var requiredAssemblies = manifest["RequiredAssemblies"] as Array;
foreach (var a in requiredAssemblies.OfType<string>())
Assembly.LoadFile(Path.Combine(basePath, a));
return new Source.ModuleInfo(basePath, name, version, projectUri, guid, companyName, prerelease);
}
/// <summary>
/// Add a module source
/// </summary>

Просмотреть файл

@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using PSRule.Rules;
@ -7,7 +7,7 @@ namespace PSRule.Pipeline
{
internal sealed class TestPipelineBuilder : InvokePipelineBuilderBase
{
internal TestPipelineBuilder(Source[] source, HostContext hostContext)
internal TestPipelineBuilder(Source[] source, IHostContext hostContext)
: base(source, hostContext) { }
private sealed class BooleanWriter : PipelineWriter

107
src/PSRule/Resources/DocumentStrings.Designer.cs сгенерированный
Просмотреть файл

@ -8,11 +8,10 @@
// </auto-generated>
//------------------------------------------------------------------------------
namespace PSRule.Resources
{
namespace PSRule.Resources {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
@ -20,139 +19,115 @@ namespace PSRule.Resources
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class DocumentStrings
{
internal class DocumentStrings {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal DocumentStrings()
{
internal DocumentStrings() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager
{
get
{
if (object.ReferenceEquals(resourceMan, null))
{
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("PSRule.Resources.DocumentStrings", typeof(DocumentStrings).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture
{
get
{
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set
{
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized string similar to DESCRIPTION.
/// </summary>
internal static string Description
{
get
{
internal static string Description {
get {
return ResourceManager.GetString("Description", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to DISPLAY NAME.
/// </summary>
internal static string DisplayName
{
get
{
internal static string DisplayName {
get {
return ResourceManager.GetString("DisplayName", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to LINKS.
/// </summary>
internal static string Links
{
get
{
internal static string Links {
get {
return ResourceManager.GetString("Links", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to MODULE NAME.
/// </summary>
internal static string ModuleName
{
get
{
internal static string ModuleName {
get {
return ResourceManager.GetString("ModuleName", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to NAME.
/// </summary>
internal static string Name
{
get
{
internal static string Name {
get {
return ResourceManager.GetString("Name", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to NOTES.
/// </summary>
internal static string Notes
{
get
{
internal static string Notes {
get {
return ResourceManager.GetString("Notes", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to RECOMMENDATION.
/// </summary>
internal static string Recommendation
{
get
{
internal static string Recommendation {
get {
return ResourceManager.GetString("Recommendation", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to SYNOPSIS.
/// </summary>
internal static string Synopsis
{
get
{
internal static string Synopsis {
get {
return ResourceManager.GetString("Synopsis", resourceCulture);
}
}

9
src/PSRule/Resources/PSRuleResources.Designer.cs сгенерированный
Просмотреть файл

@ -321,6 +321,15 @@ namespace PSRule.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Not valid module can be found with that name..
/// </summary>
internal static string ModuleNotFound {
get {
return ResourceManager.GetString("ModuleNotFound", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Target object &apos;{0}&apos; has not been processed because no matching rules were found..
/// </summary>

Просмотреть файл

@ -339,4 +339,7 @@
<data name="InfoOutputPath" xml:space="preserve">
<value>Output written to the following file: '{0}'</value>
</data>
<data name="ModuleNotFound" xml:space="preserve">
<value>Not valid module can be found with that name.</value>
</data>
</root>

609
src/PSRule/Resources/ReasonStrings.Designer.cs сгенерированный

Разница между файлами не показана из-за своего большого размера Загрузить разницу

2
src/PSRule/Resources/ReportStrings.Designer.cs сгенерированный
Просмотреть файл

@ -19,7 +19,7 @@ namespace PSRule.Resources {
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class ReportStrings {

179
src/PSRule/Resources/ViewStrings.Designer.cs сгенерированный
Просмотреть файл

@ -8,11 +8,10 @@
// </auto-generated>
//------------------------------------------------------------------------------
namespace PSRule.Resources
{
namespace PSRule.Resources {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
@ -20,238 +19,196 @@ namespace PSRule.Resources
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class ViewStrings
{
internal class ViewStrings {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal ViewStrings()
{
internal ViewStrings() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager
{
get
{
if (object.ReferenceEquals(resourceMan, null))
{
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("PSRule.Resources.ViewStrings", typeof(ViewStrings).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture
{
get
{
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set
{
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized string similar to Description.
/// </summary>
internal static string Description
{
get
{
internal static string Description {
get {
return ResourceManager.GetString("Description", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Fail.
/// </summary>
internal static string Fail
{
get
{
internal static string Fail {
get {
return ResourceManager.GetString("Fail", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Message.
/// </summary>
internal static string Message
{
get
{
internal static string Message {
get {
return ResourceManager.GetString("Message", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Module.
/// </summary>
internal static string Module
{
get
{
internal static string Module {
get {
return ResourceManager.GetString("Module", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to ModuleName.
/// </summary>
internal static string ModuleName
{
get
{
internal static string ModuleName {
get {
return ResourceManager.GetString("ModuleName", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Name.
/// </summary>
internal static string Name
{
get
{
internal static string Name {
get {
return ResourceManager.GetString("Name", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to # PSRule options.
/// </summary>
internal static string OptionsComment
{
get
{
internal static string OptionsComment {
get {
return ResourceManager.GetString("OptionsComment", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Outcome.
/// </summary>
internal static string Outcome
{
get
{
internal static string Outcome {
get {
return ResourceManager.GetString("Outcome", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to OutcomeReason.
/// </summary>
internal static string OutcomeReason
{
get
{
internal static string OutcomeReason {
get {
return ResourceManager.GetString("OutcomeReason", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Pass.
/// </summary>
internal static string Pass
{
get
{
internal static string Pass {
get {
return ResourceManager.GetString("Pass", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Reason.
/// </summary>
internal static string Reason
{
get
{
internal static string Reason {
get {
return ResourceManager.GetString("Reason", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Recommendation.
/// </summary>
internal static string Recommendation
{
get
{
internal static string Recommendation {
get {
return ResourceManager.GetString("Recommendation", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to RuleName.
/// </summary>
internal static string RuleName
{
get
{
internal static string RuleName {
get {
return ResourceManager.GetString("RuleName", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Synopsis.
/// </summary>
internal static string Synopsis
{
get
{
internal static string Synopsis {
get {
return ResourceManager.GetString("Synopsis", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Tag.
/// </summary>
internal static string Tag
{
get
{
internal static string Tag {
get {
return ResourceManager.GetString("Tag", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to TargetName.
/// </summary>
internal static string TargetName
{
get
{
internal static string TargetName {
get {
return ResourceManager.GetString("TargetName", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to TargetType.
/// </summary>
internal static string TargetType
{
get
{
internal static string TargetType {
get {
return ResourceManager.GetString("TargetType", resourceCulture);
}
}

Просмотреть файл

@ -2,7 +2,6 @@
// Licensed under the MIT License.
using System;
using Microsoft.CodeAnalysis.Sarif;
namespace PSRule.Runtime
{

Просмотреть файл

@ -20,7 +20,7 @@ namespace PSRule
var option = GetOption();
option.Rule.Include = new string[] { "ConventionTest" };
option.Convention.Include = new string[] { "Convention1" };
var builder = PipelineBuilder.Invoke(GetSource(), option, null, null);
var builder = PipelineBuilder.Invoke(GetSource(), option, null);
var pipeline = builder.Build();
Assert.NotNull(pipeline);
@ -39,7 +39,7 @@ namespace PSRule
// Order 1
option.Convention.Include = new string[] { "Convention1", "Convention2" };
var writer = new TestWriter(option);
var builder = PipelineBuilder.Invoke(GetSource(), option, null, null);
var builder = PipelineBuilder.Invoke(GetSource(), option, null);
var pipeline = builder.Build(writer);
pipeline.Begin();
pipeline.Process(PSObject.AsPSObject(testObject1));
@ -51,7 +51,7 @@ namespace PSRule
// Order 2
option.Convention.Include = new string[] { "Convention2", "Convention1" };
writer = new TestWriter(option);
builder = PipelineBuilder.Invoke(GetSource(), option, null, null);
builder = PipelineBuilder.Invoke(GetSource(), option, null);
pipeline = builder.Build(writer);
pipeline.Begin();
pipeline.Process(PSObject.AsPSObject(testObject1));

Просмотреть файл

@ -1033,7 +1033,7 @@ Describe 'Invoke-PSRule' -Tag 'Invoke-PSRule','Common' {
}
$option = New-PSRuleOption -Option @{ 'execution.mode' = 'ConstrainedLanguage' } -BindTargetName $bindFn;
{ $Null = $testObject | Invoke-PSRule -Path $ruleFilePath -Name 'ConstrainedTest1' -Option $option -ErrorAction Stop } | Should -Throw 'Exception calling "Invoke" with "4" argument(s): "Binding functions are not supported in this language mode."';
{ $Null = $testObject | Invoke-PSRule -Path $ruleFilePath -Name 'ConstrainedTest1' -Option $option -ErrorAction Stop } | Should -Throw 'Exception calling "Invoke" with "3" argument(s): "Binding functions are not supported in this language mode."';
}
}
@ -1546,7 +1546,7 @@ Describe 'Test-PSRuleTarget' -Tag 'Test-PSRuleTarget','Common' {
}
$option = New-PSRuleOption -Option @{ 'execution.mode' = 'ConstrainedLanguage' } -BindTargetName $bindFn;
{ $Null = $testObject | Test-PSRuleTarget -Path $ruleFilePath -Name 'ConstrainedTest1' -Option $option -ErrorAction Stop } | Should -Throw 'Exception calling "Test" with "4" argument(s): "Binding functions are not supported in this language mode."';
{ $Null = $testObject | Test-PSRuleTarget -Path $ruleFilePath -Name 'ConstrainedTest1' -Option $option -ErrorAction Stop } | Should -Throw 'Exception calling "Test" with "3" argument(s): "Binding functions are not supported in this language mode."';
}
}
}
@ -1804,7 +1804,7 @@ Describe 'Assert-PSRule' -Tag 'Assert-PSRule','Common' {
}
$option = New-PSRuleOption -Option @{ 'execution.mode' = 'ConstrainedLanguage' } -BindTargetName $bindFn;
{ $Null = $testObject | Assert-PSRule -Path $ruleFilePath -Name 'ConstrainedTest1' -Option $option -ErrorAction Stop 6>&1 } | Should -Throw 'Exception calling "Assert" with "4" argument(s): "Binding functions are not supported in this language mode."';
{ $Null = $testObject | Assert-PSRule -Path $ruleFilePath -Name 'ConstrainedTest1' -Option $option -ErrorAction Stop 6>&1 } | Should -Throw 'Exception calling "Assert" with "3" argument(s): "Binding functions are not supported in this language mode."';
}
}
}

Просмотреть файл

@ -24,7 +24,7 @@ namespace PSRule
public void BuildInvokePipeline()
{
var option = GetOption();
var builder = PipelineBuilder.Invoke(GetSource(), option, null, null);
var builder = PipelineBuilder.Invoke(GetSource(), option, null);
Assert.NotNull(builder.Build());
}
@ -34,7 +34,7 @@ namespace PSRule
var testObject1 = new TestObject { Name = "TestObject1" };
var option = GetOption();
option.Rule.Include = new string[] { "FromFile1" };
var builder = PipelineBuilder.Invoke(GetSource(), option, null, null);
var builder = PipelineBuilder.Invoke(GetSource(), option, null);
var pipeline = builder.Build();
Assert.NotNull(pipeline);
@ -48,7 +48,7 @@ namespace PSRule
[Fact]
public void BuildGetPipeline()
{
var builder = PipelineBuilder.Get(GetSource(), GetOption(), null, null);
var builder = PipelineBuilder.Get(GetSource(), GetOption(), null);
Assert.NotNull(builder.Build());
}
@ -98,7 +98,7 @@ namespace PSRule
public void PipelineWithOptions()
{
var option = GetOption(GetSourcePath("PSRule.Tests.yml"));
var builder = PipelineBuilder.Get(GetSource(), option, null, null);
var builder = PipelineBuilder.Get(GetSource(), option, null);
Assert.NotNull(builder.Build());
}
@ -106,7 +106,7 @@ namespace PSRule
public void PipelineWithRequires()
{
var option = GetOption(GetSourcePath("PSRule.Tests6.yml"));
var builder = PipelineBuilder.Get(GetSource(), option, null, null);
var builder = PipelineBuilder.Get(GetSource(), option, null);
Assert.Null(builder.Build());
}
@ -126,7 +126,7 @@ namespace PSRule
// Default
var writer = new TestWriter(option);
var builder = PipelineBuilder.Invoke(GetSource(), option, null, null);
var builder = PipelineBuilder.Invoke(GetSource(), option, null);
builder.InputPath(new string[] { "./**/ObjectFromFile*.json" });
var pipeline = builder.Build(writer);
Assert.NotNull(pipeline);
@ -145,8 +145,8 @@ namespace PSRule
// With IgnoreObjectSource
option.Input.IgnoreObjectSource = true;
writer = new TestWriter(option);
builder = PipelineBuilder.Invoke(GetSource(), option, null, null);
PipelineBuilder.Invoke(GetSource(), option, null, null);
builder = PipelineBuilder.Invoke(GetSource(), option, null);
PipelineBuilder.Invoke(GetSource(), option, null);
builder.InputPath(new string[] { "./**/ObjectFromFile*.json" });
pipeline = builder.Build(writer);
Assert.NotNull(pipeline);
@ -170,7 +170,7 @@ namespace PSRule
var option = GetOption();
option.Input.Format = InputFormat.File;
option.Rule.Include = new string[] { "FromFile1" };
var builder = PipelineBuilder.Invoke(GetSource(), option, null, null);
var builder = PipelineBuilder.Invoke(GetSource(), option, null);
builder.InputPath(new string[] { "./**/ObjectFromFile.json" });
var writer = new TestWriter(option);
var pipeline = builder.Build(writer);