For AI agents: This document covers Eagle's four official integration sub-projects (MSBuild, WiX, PowerShell, MonoDevelop). For core language syntax, see core_language.md. For worked examples, see core_examples.md. For script library procedures, see core_script_library.md. For the Garuda native Tcl package, see garuda.md.
Eagle provides four integration sub-projects that embed the Eagle interpreter into external host environments. Each integration adapts Eagle's core evaluation and substitution capabilities to a specific platform: two build-time tools (MSBuild, WiX), one shell (PowerShell), and one IDE (MonoDevelop).
- Overview
- MSBuild Integration (Eagle/Build)
- WiX Toolset Integration (Eagle/Installer)
- PowerShell Integration (Eagle/Management)
- MonoDevelop Integration (Eagle/MonoDevelop)
- Cross-Integration Comparison
These four sub-projects serve three complementary purposes:
1. Direct use with their respective host environments. Each integration is a fully functional component designed for production use in its target platform (with the exception of the MonoDevelop add-in, which is an explicit proof-of-concept). The MSBuild tasks, WiX preprocessor extension, and PowerShell cmdlets are all shipped, tested, and used in real build and deployment pipelines.
2. Idiomatic examples of how to embed the Eagle interpreter.
Beyond their immediate utility, these sub-projects serve as reference
implementations that demonstrate how to write code that uses the Eagle core
library. Each one illustrates a different embedding pattern: inheriting from
a host base class (Task, PreprocessorExtension, Cmdlet,
CommandHandler), creating and configuring an Interpreter instance with
appropriate creation flags, calling the five Engine methods, and managing
the interpreter lifecycle. Developers building their own Eagle integrations
can study these sub-projects to see how interpreter creation, startup option
processing, object registration (e.g., __task), policy enforcement, and
error handling are done idiomatically in practice.
3. Customizable starting points for new integrations.
The source code for these integrations is not written in stone. The
architectural choices documented in this file -- interpreter lifecycle
management, creation flag defaults, parameter surface area, bridge object
registration -- are all deliberate design decisions made for the specific
host environment, but they can be changed rather easily to suit different
requirements. For example, the MSBuild integration creates a new interpreter
per task invocation for clean isolation; if a particular workflow would
benefit from a shared interpreter across tasks (for state continuity or
reduced startup overhead), the Script base class can be modified to
support that. Similarly, the PowerShell integration uses
CreateFlags.SafeEmbeddedUse by default, but this is a single constant
that can be changed to EmbeddedUse or any other combination. This ease of
customization is a core part of Eagle's design philosophy: the interpreter
is straightforward to integrate with in a variety of different ways, and
these sub-projects demonstrate the range of possibilities while providing
practical starting points.
All four integrations expose the same five core operations, which map directly
to methods on the Eagle Engine class:
| Operation | Engine Method | Mode | Input |
|---|---|---|---|
| EvaluateExpression | Engine.EvaluateExpression |
Evaluation | Mathematical or logical expression |
| EvaluateScript | Engine.EvaluateScript |
Evaluation | Eagle script text |
| EvaluateFile | Engine.EvaluateFile |
Evaluation | Path to an Eagle script file |
| SubstituteString | Engine.SubstituteString |
Substitution | Template string with embedded commands/variables |
| SubstituteFile | Engine.SubstituteFile |
Substitution | Path to a template file |
Evaluation fully parses and executes the input as Eagle code, returning the script result.
Substitution performs command, variable, and backslash substitutions within
the input text but does not parse it as a complete script. This is analogous to
Tcl's [subst] command.
| Name | Directory | Host Environment | Production Status | Interpreter Lifecycle | Parameter Count |
|---|---|---|---|---|---|
| Eagle/Build | Eagle/Build/ |
MSBuild | Production | New per task | 12 input + 2 output |
| Eagle/Installer | Eagle/Installer/ |
WiX Toolset | Production | Shared per compilation | N/A (host-driven) |
| Eagle/Management | Eagle/Management/ |
PowerShell | Production | New per cmdlet | 20+ input |
| Eagle/MonoDevelop | Eagle/MonoDevelop/ |
MonoDevelop IDE | Proof-of-concept | Shared per add-in lifetime | None (text input only) |
| Integration | File | Description |
|---|---|---|
| MSBuild | Eagle/Build/Tasks/Script.cs |
Abstract base class (689 lines) |
| MSBuild | Eagle/Build/Tasks/EvaluateExpression.cs |
Expression evaluation task |
| MSBuild | Eagle/Build/Tasks/EvaluateScript.cs |
Script evaluation task |
| MSBuild | Eagle/Build/Tasks/EvaluateFile.cs |
File evaluation task |
| MSBuild | Eagle/Build/Tasks/SubstituteString.cs |
String substitution task |
| MSBuild | Eagle/Build/Tasks/SubstituteFile.cs |
File substitution task |
| MSBuild | Eagle/Targets/Eagle.tasks |
UsingTask declarations |
| MSBuild | Eagle/Targets/Eagle.Settings.targets |
Build settings |
| MSBuild | Eagle/Targets/Eagle.Sample.targets |
Usage examples (226 lines) |
| WiX | Eagle/Installer/Extensions/Eagle.cs |
WixExtension class |
| WiX | Eagle/Installer/Extensions/Preprocessor.cs |
PreprocessorExtension (571 lines) |
| WiX | Eagle/Installer/Tests/test.wxs |
Test WiX source |
| WiX | Eagle/Installer/Tests/Scripts/test.eagle |
Test Eagle helper script |
| PowerShell | Eagle/Management/Cmdlets/Script.cs |
Abstract base class (~1,900 lines) |
| PowerShell | Eagle/Management/Cmdlets/EvaluateExpression.cs |
Expression cmdlet |
| PowerShell | Eagle/Management/Cmdlets/EvaluateScript.cs |
Script cmdlet |
| PowerShell | Eagle/Management/Cmdlets/EvaluateFile.cs |
File cmdlet |
| PowerShell | Eagle/Management/Cmdlets/SubstituteString.cs |
String substitution cmdlet |
| PowerShell | Eagle/Management/Cmdlets/SubstituteFile.cs |
File substitution cmdlet |
| PowerShell | Eagle/Management/Commands/Cmdlet.cs |
Meta-command (~700 lines) |
| PowerShell | Eagle/Management/Components/Private/Constants.cs |
Help strings and constants |
| PowerShell | Eagle/Management/SnapIns/Default.cs |
PSSnapIn registration |
| PowerShell | Eagle/Management/Tools/EagleCmdlets.ps1 |
Installation script |
| MonoDevelop | Eagle/MonoDevelop/Handlers/Script.cs |
Abstract base class (~600 lines) |
| MonoDevelop | Eagle/MonoDevelop/Handlers/EvaluateExpression.cs |
Expression handler |
| MonoDevelop | Eagle/MonoDevelop/Handlers/EvaluateScript.cs |
Script handler |
| MonoDevelop | Eagle/MonoDevelop/Handlers/EvaluateFile.cs |
File handler |
| MonoDevelop | Eagle/MonoDevelop/Handlers/SubstituteString.cs |
String substitution handler |
| MonoDevelop | Eagle/MonoDevelop/Handlers/SubstituteFile.cs |
File substitution handler |
| MonoDevelop | Eagle/MonoDevelop/Resources/Eagle.MonoDevelop.addin.xml |
Add-in manifest |
The MSBuild integration provides five custom build tasks that allow Eagle scripts to be executed during the build process. This enables build-time code generation, validation, file-version queries, and other tasks that are difficult or impossible with MSBuild alone.
The integration uses a template method pattern:
-
Script(Eagle._Tasks.Script) is an abstract base class that inherits fromMicrosoft.Build.Utilities.Taskand implementsIDisposable. It contains all parameter definitions, interpreter creation logic, and the five engine helper methods. -
Five sealed task classes each override the
Executemethod to call one specific engine helper:Class Engine Call EvaluateExpressionEngine.EvaluateExpressionEvaluateScriptEngine.EvaluateScriptEvaluateFileEngine.EvaluateFileSubstituteStringEngine.SubstituteStringSubstituteFileEngine.SubstituteFile
Default interpreter creation flags:
CreateFlags.EmbeddedUse-- initializes the script library, throws on disposed object access, throws on interpreter creation failure, keeps only existing directories in the auto-path.HostCreateFlags.EmbeddedUse-- does not change console title, does not change console icon, does not intercept Ctrl-C.
Each Execute method follows the same pattern:
PreCreateInterpreter-- updates creation flags from startup options.CreateInterpreter-- creates a newInterpreterinstance.PostCreateInterpreter-- processes startup options and registers the__taskobject handle.- Calls the appropriate engine method.
- Disposes the interpreter.
Three MSBuild files control the integration:
Eagle.Settings.targets defines default properties:
EagleTaskTargets(default:true) -- switch for enabling Eagle build tasks.EagleTaskPath-- path to the directory containingEagleTasks.dll.
Eagle.tasks contains UsingTask declarations that register each task.
All five tasks are loaded from the same EagleTasks.dll assembly, conditional
on the assembly file existing at $(EagleTaskPath):
<UsingTask TaskName="EvaluateExpression"
Condition="'$(EagleTaskPath)' != '' And
HasTrailingSlash('$(EagleTaskPath)') And
Exists('$(EagleTaskPath)EagleTasks.dll')"
AssemblyFile="$(EagleTaskPath)EagleTasks.dll" />The same pattern applies to EvaluateScript, EvaluateFile,
SubstituteString, and SubstituteFile.
.user file overrides -- both Eagle.tasks and Eagle.Sample.targets
check for a .user companion file (e.g., Eagle.tasks.user,
Eagle.Sample.targets.user) and import it if present. This allows per-user
settings to override the defaults without modifying the checked-in files.
| Task | Text Parameter Meaning | Operation |
|---|---|---|
EvaluateExpression |
Expression string (e.g., 2 + 2) |
Evaluates a mathematical/logical expression |
EvaluateScript |
Eagle script text | Evaluates a complete Eagle script |
EvaluateFile |
File path to an Eagle script | Evaluates the contents of a script file |
SubstituteString |
Template string with embedded substitutions | Performs command, variable, and backslash substitutions |
SubstituteFile |
File path to a template file | Performs substitutions on file contents |
All five tasks share the same parameter set, defined in the Script base
class:
Input parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
Text |
[string] |
Yes | The expression, script, file path, or template to process |
Args |
[string] |
No | Command-line arguments for the interpreter (space-separated list) |
CreateFlags |
CreateFlags |
No | Interpreter creation flags (default: EmbeddedUse) |
HostCreateFlags |
HostCreateFlags |
No | Host creation flags (default: EmbeddedUse) |
EngineFlags |
EngineFlags |
No | Flags for modifying engine behavior (default: None) |
SubstitutionFlags |
SubstitutionFlags |
No | Flags for substitution behavior (default: Default) |
EventFlags |
EventFlags |
No | Flags for event handling (default: Default) |
ExpressionFlags |
ExpressionFlags |
No | Flags for expression evaluation (default: Default) |
Exceptions |
bool |
No | Allow non-Ok return codes as success (default: false) |
ShowStackTrace |
bool |
No | Display exception stack traces in error output (default: true) |
Each flag parameter also has a corresponding *String variant (e.g.,
CreateFlagsString) that accepts a parseable string representation instead
of the enum value.
Output parameters:
| Parameter | Type | Description |
|---|---|---|
Code |
ReturnCode |
The Eagle return code (Ok, Error, etc.) |
Result |
[string] |
The result value on success, or error message on failure |
After interpreter creation, the PostCreateInterpreter method registers the
task instance itself as an opaque object handle named __task in the
interpreter. This allows Eagle scripts running inside the task to call back
into the MSBuild build engine.
The most common use is accessing BuildEngine to log messages:
catch {
__task BuildEngine.LogMessageEvent [set e \
[object create \
Microsoft.Build.Framework.BuildMessageEventArgs \
{some high-priority build message} null \
EagleTasks $argv]]
unset e
}The [catch] wrapper is necessary (see Known Limitations)
because a CLR version mismatch between the built Eagle assembly and MSBuild
can cause reflection errors when accessing BuildEngine.
All examples are derived from Eagle/Targets/Eagle.Sample.targets.
Simple expression evaluation:
<EvaluateExpression Text="2 + 2">
<Output TaskParameter="Code"
PropertyName="EvaluateExpressionCode" />
<Output TaskParameter="Result"
PropertyName="EvaluateExpressionResult" />
</EvaluateExpression>Result: Code = Ok, Result = 4.
Script: query a file version:
<EvaluateScript Text="return [file version {$(TargetPath)}]">
<Output TaskParameter="Code"
PropertyName="EvaluateScriptCode1" />
<Output TaskParameter="Result"
PropertyName="EvaluateScriptResult1" />
</EvaluateScript>Uses the MSBuild property $(TargetPath) embedded in the script text. The
Eagle [file version] command retrieves the Win32 file version.
Script with Args parameter:
<EvaluateScript Args="one two {three four}"
Text="return [list [llength $argv] $argv]">
<Output TaskParameter="Code"
PropertyName="EvaluateScriptCode2" />
<Output TaskParameter="Result"
PropertyName="EvaluateScriptResult2" />
</EvaluateScript>Result: Code = Ok, Result = 3 one two {three four}.
__task BuildEngine logging with catch:
<EvaluateScript
Args="High"
Text="catch {__task BuildEngine.LogMessageEvent
[set e [object create
Microsoft.Build.Framework.BuildMessageEventArgs
{some high-priority build message} null
EagleTasks $argv]]; unset e}">
<Output TaskParameter="Code"
PropertyName="EvaluateScriptCode3" />
<Output TaskParameter="Result"
PropertyName="EvaluateScriptResult3" />
</EvaluateScript>The [catch] command prevents build errors from CLR version mismatches. The
Args parameter sets $argv to High, which becomes the message importance
level.
SubstituteString:
<SubstituteString Text="[file version {$(TargetPath)}]">
<Output TaskParameter="Code"
PropertyName="SubstituteStringCode" />
<Output TaskParameter="Result"
PropertyName="SubstituteStringResult" />
</SubstituteString>Performs command substitution on the template. The [file version ...] command
is evaluated inline, and the result replaces the command substitution in the
output string.
EvaluateFile with conditional path check:
<EvaluateFile
Condition="'$(EagleLibraryDir)' != '' And
HasTrailingSlash('$(EagleLibraryDir)') And
Exists('$(EagleLibraryDir)Tests\data\evaluate.eagle')"
Text="$(EagleLibraryDir)Tests\data\evaluate.eagle">
<Output TaskParameter="Code"
PropertyName="EvaluateFileCode" />
<Output TaskParameter="Result"
PropertyName="EvaluateFileResult" />
</EvaluateFile>The MSBuild Condition attribute ensures the file exists before attempting
evaluation. The Text parameter specifies the file path, not a script string.
-
CLR version mismatch: When Eagle is built for one .NET Framework version (e.g., .NET 2.0) and MSBuild runs under another (e.g., .NET 4.0), accessing
BuildEngineor other MSBuild types through the__taskobject may cause reflection errors. Wrap such calls in[catch]to handle this gracefully. -
New interpreter per task invocation (design choice): Each task creates and disposes its own interpreter instance, providing clean isolation between tasks. This is a deliberate default, not a fixed constraint -- the
Scriptbase class can be modified to share an interpreter across tasks if a particular workflow benefits from state continuity or reduced startup overhead. With the current default, if you need state across tasks, write intermediate values to MSBuild properties or files. -
Mono: resource generation targets disabled: The
EagleSamplePackagesResGentarget is disabled when$(BuildTool)is notMSBuild(i.e., when building under Mono), due to incorrect handling ofUseSourcePathsemantics that causes referenced file paths to contain extra directory components.
The WiX integration embeds Eagle into the WiX Toolset preprocessor, enabling Eagle variables, functions, and scripts to be used during installer compilation. This is useful for injecting build-time values (timestamps, version numbers, environment data) into WiX source files and for generating dynamic XML fragments.
The integration consists of two classes:
-
Eagle(Eagle._Extensions.Eagle) is aninternal sealedclass that extendsWixExtensionand implementsIDisposable. It serves as the entry point and lazily initializes thePreprocessorinstance. -
Preprocessor(Eagle._Extensions.Preprocessor) is aninternal sealedclass that extendsPreprocessorExtensionand implementsIDisposable. This class (571 lines) contains all the integration logic: variable access, function invocation, and pragma processing.
The preprocessor prefix is "eagle", derived from the Eagle script file
extension (.eagle with the leading dot removed).
Default flags:
CreateFlags.EmbeddedUse(withThrowOnDisposedremoved for pre-3.5 builds)HostCreateFlags.EmbeddedUse
Eagle variables are accessed from WiX source files using the syntax:
$(eagle.variableName)Bracket-to-parenthesis translation: Because WiX uses parentheses for its
own preprocessor syntax, array element access requires bracket notation. The
preprocessor automatically translates [ to ( and ] to ) before
querying the Eagle interpreter:
| WiX Syntax | Eagle Variable |
|---|---|
$(eagle.tcl_platform[os]) |
tcl_platform(os) |
$(eagle.env[USERNAME]) |
env(USERNAME) |
$(eagle.myVar) |
myVar |
If the variable does not exist, a ScriptException is thrown with the error
details.
Eagle commands can be invoked from WiX using the function call syntax:
$(eagle.commandName(arg1,arg2,...))The preprocessor calls Interpreter.Invoke with the command name and
arguments. The string result is returned to WiX. For example:
| WiX Syntax | Eagle Command |
|---|---|
$(eagle.set(dir,value)) |
set dir value |
$(eagle.clock(build)) |
clock build |
WiX 3.5 and later support custom pragma processing instructions. The Eagle
preprocessor handles pragmas with the eagle prefix:
<?pragma eagle.Mode arguments?>Where Mode is one of:
| Mode | Description |
|---|---|
EvaluateExpression |
Evaluate an Eagle expression |
EvaluateScript |
Evaluate an Eagle script |
EvaluateFile |
Evaluate an Eagle script file |
SubstituteString |
Perform substitutions on a string |
SubstituteFile |
Perform substitutions on a file |
The result of the operation is written as raw XML at the pragma location
in the output document using XmlWriter.WriteRaw. This means the result must
be valid XML (or empty) for the WiX compilation to succeed.
Line endings in the pragma arguments are normalized before processing.
The WiX integration uses a single interpreter per compilation session:
-
InitializePreprocess: Creates the interpreter with the configured creation flags, processes startup options, and makes it available for all subsequent variable, function, and pragma operations. -
FinalizePreprocess(WiX 3.5+): Disposes the interpreter at the end of the compilation session.
Because the interpreter persists across the entire compilation, variables set in one pragma or function call are available to later ones. This enables patterns like setting a directory variable early and referencing it in subsequent pragmas.
All examples are derived from Eagle/Installer/Tests/test.wxs and
Eagle/Installer/Tests/Scripts/test.eagle.
Variable access -- operating system:
<Property Id="BuildOperatingSystem"
Value="$(eagle.tcl_platform[os])" />Accesses tcl_platform(os) (the bracket-to-parenthesis translation converts
[os] to (os)). The WiX property receives the operating system name from
the Eagle interpreter.
Function invocation -- set a directory variable:
<Property Id="BuildSourceFileDir"
Value="$(eagle.set(dir,$(sys.SOURCEFILEDIR)))" />Invokes the Eagle [set] command to store the WiX system variable
$(sys.SOURCEFILEDIR) into an Eagle variable named dir. This variable is
then available to subsequent scripts and pragmas in the same compilation
session.
Function invocation -- build number:
<Property Id="BuildNumber"
Value="$(eagle.clock(build))" />Invokes the Eagle clock build command to get the daily build number.
Pragma -- EvaluateScript with source and makeProperty:
<?pragma eagle.EvaluateScript
#
# NOTE: This is a fairly trivial example of how to do something
# useful in an Eagle script that is being evaluated from
# inside the WiX preprocessor. The final result of this
# script will be inserted as raw XML into the XML document
# at this location.
#
source [file normalize [file join $dir Scripts test.eagle]]
makeProperty BuildUserName $env(USERNAME)
?>This pragma evaluates an Eagle script that:
- Sources a helper script (
test.eagle) from theScriptssubdirectory. - Calls
makePropertyto generate a WiX<Property>XML element.
The makeProperty helper procedure (from test.eagle):
proc makeProperty { name value } {
return [appendArgs <Property " " \
Id=\" $name "\" " Value=\" $value "\" />"]
}This procedure generates a WiX <Property> XML element as a string. When
returned from a pragma, the raw XML is inserted into the output document at
the pragma location.
| WiX Version | Variable Access | Function Invocation | Pragma Processing |
|---|---|---|---|
| 3.0 | Yes | Yes | No |
| 3.5 | Yes | Yes | Yes |
| 3.6 | Yes | Yes | Yes |
| 3.7 | Yes | Yes | Yes |
| 3.8 | Yes | Yes | Yes |
| 3.9 | Yes | Yes | Yes |
| 3.10 | Yes | Yes | Yes |
| 3.11 | Yes | Yes | Yes |
Pragma processing requires WiX 3.5 or higher. The FinalizePreprocess method
(which properly disposes the interpreter) also requires WiX 3.5+.
-
Bracket syntax for array access: Accessing array elements requires brackets (
[os]) instead of the natural Tcl/Eagle parentheses ((os)). This is because WiX reserves parentheses for its own preprocessor syntax. -
Pragma support requires WiX 3.5+: The five-operation pragma mechanism is not available in WiX versions prior to 3.5. Only variable access and function invocation are available in WiX 3.0.
-
Shared interpreter state (design choice): Because a single interpreter is shared across the entire compilation session, variables and state changes from one operation are visible to all subsequent operations. This is deliberate -- it enables useful patterns like setting a directory variable early and referencing it in later pragmas. If isolation between operations is preferred, the
Preprocessorclass can be modified to create a fresh interpreter for each pragma or function call. Scripts that need cleanup within the shared model can useunset -nocomplainor[try]/finallyblocks to manage state explicitly.
The PowerShell integration provides a set of cmdlets that allow Eagle expressions, scripts, and files to be evaluated directly from the PowerShell command line or scripts. It includes a policy engine for controlling command execution and a meta-command that bridges Eagle scripts back into the PowerShell pipeline.
The integration is structured as a PSSnapIn (PowerShell snap-in):
-
Default(Eagle._SnapIns.Default) is the PSSnapIn registration class, marked with[RunInstaller(true)]. It registers the snap-in under the name"EagleCmdlets". -
Script(Eagle._Cmdlets.Script) is the abstract base class (~1,900 lines) that inherits fromSystem.Management.Automation.Cmdletand implementsIDisposable. It defines all parameters, manages the interpreter lifecycle, and provides the five engine helper methods. -
Five sealed cmdlet classes each override
ProcessRecordto call one specific engine helper. -
Cmdlet(Eagle._Commands.Cmdlet, ~700 lines) is the internal meta-command that can optionally be injected into the interpreter to bridge Eagle scripts back into PowerShell.
Default interpreter creation flags:
CreateFlags.SafeEmbeddedUseHostCreateFlags.SafeEmbeddedUse
Note the use of Safe embedded flags (unlike MSBuild and WiX which use
plain EmbeddedUse), restricting available commands by default.
The snap-in is installed using the EagleCmdlets.ps1 script:
# Install the snap-in and add it to the current session
.\EagleCmdlets.ps1 install
# Uninstall the snap-in
.\EagleCmdlets.ps1 uninstallThe script:
- Detects the .NET Framework version and platform (x86/x64).
- Locates
InstallUtil.exein the appropriate framework directory. - Runs
InstallUtil /LogFile= EagleCmdlets.dllto register the snap-in. - On successful installation, runs
Add-PSSnapin EagleCmdletsto load the snap-in into the current session.
The integration provides five cmdlets (plus one internal meta-command). Each cmdlet has two possible verb names depending on compile-time configuration:
| Default Name | APPROVED_VERBS Name | Operation |
|---|---|---|
Evaluate-EagleExpression |
Invoke-EagleExpression |
Evaluate an expression |
Evaluate-EagleScript |
Invoke-EagleScript |
Evaluate a script |
Evaluate-EagleScriptFile |
Invoke-EagleScriptFile |
Evaluate a script file |
Substitute-EagleText |
Resolve-EagleText |
Substitute a string |
Substitute-EagleTextFile |
Resolve-EagleTextFile |
Substitute a file |
All cmdlets declare SupportsShouldProcess = true.
All cmdlets share the same parameter set, defined in the Script base class.
The Text parameter (position 0) is mandatory and accepts pipeline input.
All other parameters accept pipeline input by property name.
| Parameter | Type | Description |
|---|---|---|
-Text |
[string] |
The string, expression, script, or file name to process (required) |
-Args |
[string] |
Command-line arguments for the interpreter |
-PreInitialize |
[string] |
Script to evaluate during interpreter creation |
-CreateFlags |
CreateFlags |
Flags for interpreter creation (default: SafeEmbeddedUse) |
-HostCreateFlags |
HostCreateFlags |
Flags for interpreter host creation (default: SafeEmbeddedUse) |
-InitializeFlags |
InitializeFlags |
Flags for interpreter initialization (default: Default) |
-ScriptFlags |
ScriptFlags |
Flags for script library behavior (default: Default) |
-InterpreterFlags |
InterpreterFlags |
Flags for interpreter behavior (default: Default) |
-EngineFlags |
EngineFlags |
Flags for engine behavior (default: None) |
-SubstitutionFlags |
SubstitutionFlags |
Flags for substitution behavior (default: Default) |
-EventFlags |
EventFlags |
Flags for event handling (default: Default) |
-ExpressionFlags |
ExpressionFlags |
Flags for expression evaluation (default: Default) |
-Console |
SwitchParameter |
Allow console messages |
-Unsafe |
SwitchParameter |
Allow unsafe commands |
-Standard |
SwitchParameter |
Allow only standard commands |
-Force |
SwitchParameter |
Skip confirmation prompts |
-Exceptions |
SwitchParameter |
Allow non-Ok return codes as success |
-Policies |
SwitchParameter |
Use the cmdlet command execution policies |
-Deny |
SwitchParameter |
Deny command execution by default |
-MetaCommand |
SwitchParameter |
Add the [cmdlet] meta-command to the interpreter |
The -Text parameter accepts several aliases: -Expression, -String,
-Script, -File, -FileName.
When the -MetaCommand switch is enabled, the [cmdlet] command is added to
the interpreter. This command bridges Eagle scripts back into the PowerShell
pipeline, providing 9 sub-commands:
| Sub-Command | Arguments | Description |
|---|---|---|
about |
(none) | Returns plugin about information |
[debug] |
text |
Calls WriteDebug on the PowerShell cmdlet |
[error] |
code result |
Writes an error record to the PowerShell error stream |
[invoke] |
?options? script |
Invokes a PowerShell pipeline command |
options |
(none) | Returns compile-time define constants or plugin options |
progress |
?options? activityId activity statusDescription |
Writes a progress record |
remove |
(none) | Removes the meta-command from the interpreter |
status |
(none) | Returns cmdlet object status and properties |
verbose |
text |
Calls WriteVerbose on the PowerShell cmdlet |
The [invoke] sub-command supports the -addToHistory option. The progress
sub-command supports -currentOperation, -parentActivityId,
-percentComplete, -recordType, and -secondsRemaining options.
The -Policies switch enables command execution policies within the Eagle
interpreter. When active:
- Each command execution is subject to a policy callback
(
_Policies._Cmdlet.PolicyCallback). - The callback uses
ShouldProcessandShouldContinuefor user confirmation. - The
-Denyswitch inverts the default policy: approved commands are denied instead of allowed. - The
-Forceswitch suppresses confirmation prompts.
Policy descriptions shown to the user:
- Process caption:
"Eagle Cmdlet Policy" - Continue caption:
"Eagle Cmdlet Policy (Confirm)" - Verbose description:
"Executing command: {0}" - Unsafe warning:
"Detected use of the command name \"{0}\", marked as 'unsafe', allow anyway?"
Each cmdlet invocation creates a new interpreter (full isolation):
-
BeginProcessing: Creates the interpreter with the configured flags, sets up policies (if-Policiesis enabled), evaluates the pre-initialization script (if-PreInitializeis specified), and adds the meta-command (if-MetaCommandis enabled). -
ProcessRecord: Calls the appropriate engine method with theTextparameter. -
EndProcessing: Disposes the interpreter and resets policy data. -
StopProcessing: Cancels any in-progress evaluation and disposes the interpreter (called when the pipeline is stopped).
The cmdlet verb names are controlled by a compile-time flag:
-
Default (without
APPROVED_VERBS): UsesEvaluateandSubstituteverbs, which are compatible with Tcl terminology but are not on the PowerShell approved verb list. -
With
APPROVED_VERBSdefined: UsesInvokeandResolveverbs, which are on the PowerShell approved verb list.
This choice is fixed at build time and cannot be changed at runtime.
Simple expression evaluation:
Evaluate-EagleExpression "2 + 2"Script evaluation with -Args:
Evaluate-EagleScript -Args "one two" -Text "return [llength $argv]"Using -MetaCommand with [cmdlet invoke]:
Evaluate-EagleScript -MetaCommand -Text "cmdlet invoke Get-Date"The [cmdlet invoke] sub-command executes a PowerShell pipeline command from
within an Eagle script and returns the result.
Using -Policies and -Force:
Evaluate-EagleScript -Policies -Force -Text "return hello"Enables the policy engine but suppresses confirmation prompts with -Force.
-
PSSnapIn is legacy: The integration uses the PSSnapIn registration mechanism, which is supported only in Windows PowerShell (versions up to 5.1). It is not compatible with PowerShell Core (6.0+) or PowerShell 7+.
-
New interpreter per invocation (design choice): Each cmdlet call creates and disposes a fresh interpreter, providing full isolation. This is a deliberate default -- the
Scriptbase class can be modified to cache and reuse an interpreter across invocations if a particular workflow benefits from shared state or reduced startup overhead. -
Safe mode by default: The default
CreateFlags.SafeEmbeddedUserestricts the set of available commands. Use the-Unsafeswitch to access the full command set, or specify custom-CreateFlagsto fine-tune behavior. -
APPROVED_VERBS choice is fixed at build time: You cannot switch between
Evaluate/SubstituteandInvoke/Resolveverb names at runtime. The choice must be made when compiling theEagleCmdlets.dllassembly.
WARNING: This integration is a proof-of-concept only. It is NOT production ready.
The following warning appears verbatim in all source files:
*WARNING* *WARNING* *WARNING* *WARNING* *WARNING* *WARNING* *WARNING*
Please do not use this code, it is a proof-of-concept only. It is not
production ready.
*WARNING* *WARNING* *WARNING* *WARNING* *WARNING* *WARNING* *WARNING*The MonoDevelop integration is packaged as a MonoDevelop add-in:
-
addin.xmldeclares the add-in metadata:- ID:
Eagle - Namespace:
MonoDevelop - Name:
Eagle Handlers for MonoDevelop - Category:
Scripting - Version:
1.0 - Dependencies: MonoDevelop Core >= 2.6, MonoDevelop Ide >= 2.6
- Runtime assembly:
Eagle.dll - Commands are registered under the
"Eagle Integration"category in/MonoDevelop/Ide/Commandsand added to the Edit menu.
- ID:
-
Script(Eagle._Handlers.Script) is aninternalbase class (~600 lines) that inherits fromMonoDevelop.Components.Commands.CommandHandlerand implementsIDisposable. It manages the shared interpreter and provides the five engine helper methods. -
Five sealed handler classes each override the
RunandUpdatemethods fromCommandHandler:Class Menu Label Input Source Result Mode EvaluateExpressionEvaluate Eagle Expression Selected text Replace or Document EvaluateScriptEvaluate Eagle Script Selected text Replace or Document EvaluateFileEvaluate Eagle File Active document path Document SubstituteStringSubstitute Eagle String Selected text Replace or Document SubstituteFileSubstitute Eagle File Active document path Document
Default interpreter creation flags:
CreateFlags.EmbeddedUseHostCreateFlags.EmbeddedUse
All five commands appear in the MonoDevelop Edit menu under the
"Eagle Integration" category:
| Command | Description | Enabled When |
|---|---|---|
| Evaluate Eagle Expression | Evaluates the selected text as an Eagle expression | Text is selected |
| Evaluate Eagle Script | Evaluates the selected text as an Eagle script | Text is selected |
| Evaluate Eagle File | Evaluates the active document as an Eagle script file | Document is open |
| Substitute Eagle String | Performs substitutions on the selected text | Text is selected |
| Substitute Eagle File | Performs substitutions on the active document file | Document is open |
The Update method on each handler enables or disables the command based on
whether the required input (selected text or open document) is available.
The MonoDevelop integration uses a single shared interpreter for the lifetime of the add-in:
- The interpreter is created once in the
Initializemethod of the baseScriptclass, usingInterpreter.Createwith the configured creation flags. - The same interpreter instance is used for all subsequent command invocations.
- The interpreter is disposed when the handler is disposed.
Because the interpreter persists, state accumulates across invocations. Variables set by one evaluation are visible to later evaluations. This is by design for interactive use but can lead to unexpected side effects.
Results are presented in one of two modes:
-
Replace mode (default for text-based operations): The selected text in the active editor buffer is replaced with the formatted result. The replacement is performed inside an atomic undo block, so it can be reverted with a single undo.
-
Document mode (used by file-based operations and as an alternative for text-based operations): A new document tab is opened with the result. The document is named
"Eagle {Type} {Result/Error} #{id}".
The EvaluateFile and SubstituteFile commands always use document mode
because they operate on the entire file, not on a text selection.
The MonoDevelop integration has no cmdlet-style parameters. Configuration is limited to environment variables:
| Environment Variable | Effect |
|---|---|
Eagle_Console |
Enables console output when set |
Eagle_NoConsole |
Disables console output when set |
The NeedConsole method checks these environment variables to determine
whether console output should be enabled.
- Not production ready: The integration is explicitly marked as a proof-of-concept. Do not use it for production work.
- No syntax highlighting, debugging, or code completion: The add-in provides only evaluation and substitution commands. There is no Eagle language support integrated into the IDE editor.
- Single shared interpreter (design choice): State persists across
invocations -- variables and side effects from one command are visible to
subsequent commands. This is convenient for interactive exploration but may
cause surprises. The
Scriptbase class can be modified to create a fresh interpreter per invocation if isolation is preferred. - No parameters beyond text input: Unlike MSBuild and PowerShell, there are no flags, creation options, or policy controls. The only input is the selected text or active document.
- MonoDevelop 2.6+ required: The add-in requires MonoDevelop version 2.6 or higher. MonoDevelop is largely unmaintained as a standalone IDE (its successor is Visual Studio for Mac, which has itself been discontinued).
| Feature | MSBuild | WiX | PowerShell | MonoDevelop |
|---|---|---|---|---|
| Host Environment | MSBuild build engine | WiX Toolset preprocessor | PowerShell shell | MonoDevelop IDE |
| Production Status | Production | Production | Production | Proof-of-concept |
| Configurable Parameters | 12 input + 2 output | N/A (host-driven) | 20+ input | None |
| Interpreter Lifecycle | New per task | Shared per compilation | New per cmdlet | Shared per add-in lifetime |
| Bridge Object | __task (BuildEngine) |
N/A | [cmdlet] meta-command |
N/A |
| Policy Engine | No | No | Yes (-Policies) |
No |
| Pragma/Macro Support | N/A | Yes (WiX 3.5+) | N/A | N/A |
| Default CreateFlags | EmbeddedUse |
EmbeddedUse |
SafeEmbeddedUse |
EmbeddedUse |
| Pipeline/Output Support | MSBuild properties | Raw XML injection | PowerShell pipeline | Text replace / new document |
| Integration | Lifecycle | State Sharing | Default Trade-off | Customizable? |
|---|---|---|---|---|
| MSBuild | New per task invocation | None between tasks | Clean isolation; startup cost per task | Yes -- Script base class can be modified to share |
| WiX | Shared per compilation session | Yes, across all operations | Enables cross-reference; requires state discipline | Yes -- Preprocessor can create per-operation interpreters |
| PowerShell | New per cmdlet invocation | None between cmdlets | Clean isolation; startup cost per cmdlet | Yes -- Script base class can be modified to cache |
| MonoDevelop | Shared per add-in lifetime | Yes, across all commands | Interactive convenience; state accumulates | Yes -- Script base class can create per-invocation interpreters |
-
MSBuild: Use for build-time code generation, validation, file-version queries, and other tasks that need to run as part of the MSBuild pipeline. Best when you need Eagle's string processing, file inspection, or .NET interop capabilities during a build.
-
WiX: Use for injecting build-time values into Windows Installer packages. Best for dynamic property generation, build numbers, environment-dependent configuration, and conditional XML fragment generation during installer compilation.
-
PowerShell: Use for interactive or scripted Eagle evaluation from the command line. Best for ad-hoc scripting, automation pipelines, and scenarios where you want to combine Eagle's capabilities with PowerShell's ecosystem.
-
MonoDevelop: Use for experimentation and proof-of-concept only. The add-in can evaluate expressions and scripts interactively within the IDE, but it lacks the polish and features needed for production use.