CrossplaneSharp 1.0.2
dotnet add package CrossplaneSharp --version 1.0.2
NuGet\Install-Package CrossplaneSharp -Version 1.0.2
<PackageReference Include="CrossplaneSharp" Version="1.0.2" />
<PackageVersion Include="CrossplaneSharp" Version="1.0.2" />
<PackageReference Include="CrossplaneSharp" />
paket add CrossplaneSharp --version 1.0.2
#r "nuget: CrossplaneSharp, 1.0.2"
#:package CrossplaneSharp@1.0.2
#addin nuget:?package=CrossplaneSharp&version=1.0.2
#tool nuget:?package=CrossplaneSharp&version=1.0.2
CrossplaneSharp — Library
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 | Versions 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. |
-
.NETStandard 2.0
- System.Text.Json (>= 6.0.11)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.