-
Notifications
You must be signed in to change notification settings - Fork 53
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
- Loading branch information
1 parent
9fb2147
commit c51fff4
Showing
62 changed files
with
2,335 additions
and
257 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# Emitter specification | ||
|
||
A key component of PSRule design is the ability to read objects from file or PowerShell pipeline. | ||
PSRule provided built-in support for a limited number of file formats and object types. | ||
Conventions could be used to provide support for additional file formats and object types. | ||
|
||
Current challenges: | ||
|
||
- **Performance**: When processing a high volume of objects, reading objects from disk across multiple times can be slow. | ||
Many repositories have a large number of files that need to be read and processed. | ||
CI workflows often executed in container environments where disk access is slow or limited resources are available. | ||
- **Confusing output**: Files processed as objects often end up reporting as unprocessed, generating a default warning. | ||
This is because they are processed by each available rule, but no rules are defined to process them. | ||
- **Expansion**: Handover of objects to conventions can be complex and does not expose strongly typed objects. | ||
Expansion is a pattern used by PSRule for Azure to expand a file into multiple objects. | ||
This is helpful when PSRule does not support a file format or object type natively. | ||
|
||
Goals with emitters: | ||
|
||
- **Single touch**: If a file needs to be read from disk, it should be read once to reduce IO. | ||
- **Extensible**: A interface should be provided to allow for custom emitters that can be used to read objects from any source. | ||
- **Multi-threaded**: Emitters should be thread safe and support parallel processing. | ||
- **Carried as needed**: Emitter should be only emit objects to be processed by rules. | ||
File objects are not processed by default. | ||
|
||
The goal of emitters is to provide a high performance and extensible way to emit custom objects to the input stream. | ||
|
||
Emitters define a C# `IEmitter` interface for emitting objects to the input stream. | ||
The implementation of an emitter must be thread safe, as emitters can be run in parallel. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License. | ||
|
||
namespace PSRule.Emitters; | ||
|
||
/// <summary> | ||
/// A base class for implementing an emitter. | ||
/// </summary> | ||
public abstract class BaseEmitter : IEmitter | ||
{ | ||
private bool _Disposed; | ||
|
||
/// <inheritdoc/> | ||
public abstract bool Visit(IEmitterContext context, object o); | ||
|
||
/// <inheritdoc/> | ||
public abstract bool Accepts(IEmitterContext context, Type type); | ||
|
||
#region IDisposable | ||
|
||
/// <summary> | ||
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. | ||
/// </summary> | ||
/// <param name="disposing">Determines if a dispose is occuring.</param> | ||
protected virtual void Dispose(bool disposing) | ||
{ | ||
if (!_Disposed) | ||
{ | ||
if (disposing) | ||
{ | ||
// TODO: dispose managed state (managed objects) | ||
} | ||
_Disposed = true; | ||
} | ||
} | ||
|
||
/// <inheritdoc/> | ||
public void Dispose() | ||
{ | ||
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method | ||
Dispose(disposing: true); | ||
GC.SuppressFinalize(this); | ||
} | ||
|
||
#endregion IDisposable | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License. | ||
|
||
using PSRule.Data; | ||
|
||
namespace PSRule.Emitters; | ||
|
||
/// <summary> | ||
/// An emitter that implements emitting objects from file streams. | ||
/// </summary> | ||
public abstract class FileEmitter : BaseEmitter | ||
{ | ||
/// <inheritdoc/> | ||
public sealed override bool Accepts(IEmitterContext context, Type type) | ||
{ | ||
return context != null && type != null && | ||
(typeof(IFileInfo).IsAssignableFrom(type) || type == typeof(string)); | ||
} | ||
|
||
/// <inheritdoc/> | ||
public sealed override bool Visit(IEmitterContext context, object o) | ||
{ | ||
if (context == null || o == null) return false; | ||
|
||
if (o is IFileInfo info && AcceptsFilePath(context, info)) | ||
return VisitFile(context, info.GetFileStream()); | ||
|
||
return o is string s && AcceptsString(context) ? VisitString(context, s) : false; | ||
} | ||
|
||
/// <summary> | ||
/// Determines if the emitter accepts a file based on it's path. | ||
/// </summary> | ||
/// <param name="context"></param> | ||
/// <param name="info"></param> | ||
/// <returns></returns> | ||
protected abstract bool AcceptsFilePath(IEmitterContext context, IFileInfo info); | ||
|
||
/// <summary> | ||
/// Determines if the emitter accepts an input string as content. | ||
/// </summary> | ||
/// <param name="context"></param> | ||
/// <returns></returns> | ||
protected virtual bool AcceptsString(IEmitterContext context) | ||
{ | ||
return false; | ||
} | ||
|
||
/// <summary> | ||
/// Visit a specific file. | ||
/// </summary> | ||
/// <param name="context"></param> | ||
/// <param name="stream"></param> | ||
/// <returns></returns> | ||
protected abstract bool VisitFile(IEmitterContext context, IFileStream stream); | ||
|
||
/// <summary> | ||
/// Visit a string. | ||
/// </summary> | ||
/// <param name="context"></param> | ||
/// <param name="content"></param> | ||
/// <returns></returns> | ||
protected virtual bool VisitString(IEmitterContext context, string content) | ||
{ | ||
return false; | ||
} | ||
} |
Oops, something went wrong.