CrossplaneSharp 1.0.2

dotnet add package CrossplaneSharp --version 1.0.2
                    
NuGet\Install-Package CrossplaneSharp -Version 1.0.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="CrossplaneSharp" Version="1.0.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="CrossplaneSharp" Version="1.0.2" />
                    
Directory.Packages.props
<PackageReference Include="CrossplaneSharp" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add CrossplaneSharp --version 1.0.2
                    
#r "nuget: CrossplaneSharp, 1.0.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package CrossplaneSharp@1.0.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=CrossplaneSharp&version=1.0.2
                    
Install as a Cake Addin
#tool nuget:?package=CrossplaneSharp&version=1.0.2
                    
Install as a Cake Tool

CrossplaneSharp — Library

NuGet

A unofficial C# port of the Python crossplane library — a fast, reliable NGINX configuration file lexer, parser, and builder for .NET, packaged as a netstandard2.0 NuGet library.


Installation

dotnet add package CrossplaneSharp

The package targets netstandard2.0 and works with .NET 6+, .NET Framework 4.6.1+, .NET Core 2.0+, Mono, Xamarin, and Unity.


Overview

Operation What it does
Lex Tokenise a config file into a stream of (value, line, isQuoted) tokens
Parse Parse a config file (including include directives) into a structured object tree
Build Reconstruct a valid NGINX config string from a parsed object tree
BuildFiles Write a full parsed payload back to disk

All operations are exposed through the single static Crossplane class.


Quick Start

Lex

Tokenise an NGINX config file into raw tokens:

using CrossplaneSharp;

IReadOnlyList<NgxToken> tokens = Crossplane.Lex("/etc/nginx/nginx.conf");

foreach (var token in tokens)
    Console.WriteLine($"[line {token.Line}] {token.Value} (quoted={token.IsQuoted})");

Tokenise from an in-memory string:

var tokens = Crossplane.LexString("worker_processes 4;");
// tokens[0].Value == "worker_processes"
// tokens[1].Value == "4"
// tokens[2].Value == ";"

Parse

Parse a config file into a structured ParseResult:

using CrossplaneSharp;

ParseResult result = Crossplane.Parse("/etc/nginx/nginx.conf");

Console.WriteLine(result.Status); // "ok" or "failed"

foreach (var config in result.Config)
{
    Console.WriteLine($"File: {config.File}");
    foreach (var stmt in config.Parsed)
        Console.WriteLine($"  [{stmt.Line}] {stmt.Directive} {string.Join(" ", stmt.Args)}");
}
Parse options
var options = new ParseOptions
{
    CatchErrors = true,   // collect errors instead of throwing (default: true)
    Comments    = true,   // include # comment blocks in output (default: false)
    Single      = true,   // do not follow include directives (default: false)
    Strict      = false,  // raise on unknown directives (default: false)
    Combine     = false,  // flatten includes into one config entry (default: false)
    CheckCtx    = true,   // validate directive context (default: true)
    CheckArgs   = true,   // validate argument counts (default: true)
    Ignore      = new HashSet<string> { "lua_package_path" },
    OnError     = ex => ex.Message
};

ParseResult result = Crossplane.Parse("/etc/nginx/nginx.conf", options);
Output structure
ParseResult
├── Status          "ok" | "failed"
├── Errors[]        list of { Error, File, Line, Callback }
└── Config[]        one entry per parsed file
    ├── File        absolute path
    ├── Status      "ok" | "failed"
    ├── Errors[]
    └── Parsed[]    list of ConfigBlock
        ├── Directive   e.g. "server", "location", "#"
        ├── Line        1-based line number
        ├── Args[]      directive arguments
        ├── Block[]     child directives (for block directives)
        ├── Comment     comment text (when Directive == "#")
        ├── Includes[]  indices into Config[] (for include directives)
        └── File        source file (in combine mode)

Build

Reconstruct an NGINX config string from a list of ConfigBlock objects:

using CrossplaneSharp;

var blocks = new List<ConfigBlock>
{
    new ConfigBlock { Directive = "worker_processes", Args = new List<string> { "4" } },
    new ConfigBlock {
        Directive = "events",
        Block = new List<ConfigBlock> {
            new ConfigBlock { Directive = "worker_connections", Args = new List<string> { "1024" } }
        }
    }
};

string config = Crossplane.Build(blocks);

Output:

worker_processes 4;
events {
    worker_connections 1024;
}
Build options
var options = new BuildOptions
{
    Indent = 4,      // spaces per indent level (default: 4)
    Tabs   = false,  // use tabs instead of spaces (default: false)
    Header = true    // prepend a "built by crossplane" comment header (default: false)
};

string config = Crossplane.Build(blocks, options);

BuildFiles

Write a full parsed payload back to disk:

ParseResult result = Crossplane.Parse("/etc/nginx/nginx.conf");

// Rebuild all files into /tmp/nginx-out/
Crossplane.BuildFiles(result, dirname: "/tmp/nginx-out", new BuildOptions { Indent = 2 });

Round-trip example

// Parse → modify → rebuild
ParseResult result = Crossplane.Parse("/etc/nginx/nginx.conf",
    new ParseOptions { Comments = true });

// Find worker_processes and change its value
var wp = result.Config[0].Parsed.First(b => b.Directive == "worker_processes");
wp.Args[0] = "8";

string newConfig = Crossplane.Build(result.Config[0].Parsed);
File.WriteAllText("/etc/nginx/nginx.conf", newConfig);

Error handling

By default errors are collected (not thrown) and stored in ParseResult.Errors and ConfigFile.Errors. Set CatchErrors = false to throw on the first error instead:

try
{
    var result = Crossplane.Parse("broken.conf", new ParseOptions { CatchErrors = false });
}
catch (NgxParserSyntaxError ex)
{
    Console.WriteLine($"Syntax error at {ex.Filename}:{ex.Lineno} — {ex.Strerror}");
}

Exception hierarchy

NgxParserBaseException
├── NgxParserSyntaxError              unbalanced braces, unexpected tokens
└── NgxParserDirectiveError
    ├── NgxParserDirectiveUnknownError    unknown directive (strict mode)
    ├── NgxParserDirectiveContextError    directive not allowed in this context
    └── NgxParserDirectiveArgumentsError  wrong number of arguments

Requirements

The library targets netstandard2.0:

Runtime Minimum version
.NET 6.0+
.NET Framework 4.6.1+
.NET Core 2.0+
Mono 5.4+
Xamarin.iOS 10.14+
Xamarin.Android 8.0+
Unity 2018.1+
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.2 154 3/10/2026
1.0.1 118 3/10/2026