A .NET 10 library and console application for compiling AdGuard filter rules using @adguard/hostlist-compiler.
- Full compilation support: All configuration options for filter compilation
- Multi-format configuration: JSON, YAML, and TOML configuration file support
- Configuration validation: Validates configuration before compilation with detailed error/warning reporting
- Interactive and CLI modes: Use interactively with menus or from command line with arguments
- Verbose mode: Detailed output from the compiler for debugging
- Cross-platform: Runs on Windows, Linux, and macOS
| Requirement | Version | Notes |
|---|---|---|
| .NET SDK | 10.0+ | Cross-platform runtime |
| Deno | 2.0+ | Required for hostlist-compiler |
| hostlist-compiler | Latest | Accessed via Deno's npm compatibility |
cd src/rules-compiler-dotnet
dotnet restore RulesCompiler.slnx
dotnet build RulesCompiler.slnxRun without arguments to start interactive mode:
dotnet run --project src/RulesCompiler.ConsoleInteractive menu options:
- View Configuration - Display parsed configuration details
- Validate Configuration - Validate configuration without compiling
- Compile Rules - Compile filter rules
- Compile Rules (Verbose) - Compile with detailed output
- Compile and Copy to Rules - Compile and copy output to rules directory
- Show Available Transformations - List all supported transformations
- Version Info - Show version information for all components
# Basic compilation
dotnet run --project src/RulesCompiler.Console -- --config path/to/config.yaml
# Compile with specific output path
dotnet run --project src/RulesCompiler.Console -- -c config.json -o output.txt
# Compile and copy to rules directory
dotnet run --project src/RulesCompiler.Console -- -c config.yaml --copy
# Verbose output
dotnet run --project src/RulesCompiler.Console -- -c config.yaml --verbose
# Validate configuration only
dotnet run --project src/RulesCompiler.Console -- -c config.yaml --validate
# Disable validation before compilation
dotnet run --project src/RulesCompiler.Console -- -c config.yaml --no-validate-config
# Fail compilation on validation warnings
dotnet run --project src/RulesCompiler.Console -- -c config.yaml --fail-on-warnings
# Show version information
dotnet run --project src/RulesCompiler.Console -- --version| Option | Short | Description |
|---|---|---|
--config |
-c |
Path to configuration file (JSON, YAML, or TOML) |
--output |
-o |
Path to output file |
--copy |
Copy output to rules directory | |
--verbose |
Enable verbose output from hostlist-compiler | |
--validate |
Validate configuration only (no compilation) | |
--validate-config |
Enable configuration validation before compilation (default: true) | |
--no-validate-config |
Disable configuration validation before compilation | |
--fail-on-warnings |
Fail compilation if configuration has validation warnings | |
--version |
-v |
Show version information |
The compiler supports three configuration formats that map directly to the hostlist-compiler configuration schema.
| Property | Type | Required | Description |
|---|---|---|---|
name |
string | Yes | Name of the filter list |
description |
string | No | Description of the filter list |
homepage |
string | No | Homepage URL |
license |
string | No | License identifier |
version |
string | No | Version number |
sources |
array | Yes | List of filter sources to compile |
transformations |
array | No | Global transformations to apply |
inclusions |
array | No | Global inclusion patterns |
inclusions_sources |
array | No | Files containing inclusion patterns |
exclusions |
array | No | Global exclusion patterns |
exclusions_sources |
array | No | Files containing exclusion patterns |
| Property | Type | Required | Description |
|---|---|---|---|
source |
string | Yes | URL or local file path |
name |
string | No | Source identifier |
type |
string | No | Format: adblock (default) or hosts |
transformations |
array | No | Source-specific transformations |
inclusions |
array | No | Source-specific inclusion patterns |
inclusions_sources |
array | No | Files with source inclusions |
exclusions |
array | No | Source-specific exclusion patterns |
exclusions_sources |
array | No | Files with source exclusions |
Transformations are always applied in this fixed order regardless of configuration order:
| Transformation | Description |
|---|---|
RemoveComments |
Removes all comment lines (! or #) |
Compress |
Converts hosts format to adblock syntax |
RemoveModifiers |
Removes unsupported modifiers from rules |
Validate |
Removes dangerous/incompatible rules |
ValidateAllowIp |
Like Validate but allows IP address rules |
Deduplicate |
Removes duplicate rules |
InvertAllow |
Converts @@exceptions to blocking rules |
RemoveEmptyLines |
Removes blank lines |
TrimLines |
Trims whitespace from lines |
InsertFinalNewLine |
Ensures file ends with newline |
ConvertToAscii |
Converts IDN to punycode |
Inclusion and exclusion patterns support:
- Plain strings: Exact match
- Wildcards:
*.example.com,*tracking* - Regular expressions:
/pattern/(case-insensitive by default) - Comments: Lines starting with
!are ignored
{
"name": "My Filter List",
"description": "Custom ad-blocking filter",
"version": "1.0.0",
"sources": [
{
"name": "Local Rules",
"source": "data/local.txt",
"type": "adblock"
},
{
"name": "EasyList",
"source": "https://easylist.to/easylist/easylist.txt",
"type": "adblock",
"transformations": ["RemoveModifiers", "Validate"]
}
],
"transformations": ["Deduplicate", "RemoveEmptyLines", "InsertFinalNewLine"],
"exclusions": ["*.google.com", "/analytics/"]
}name: My Filter List
description: Custom ad-blocking filter
version: "1.0.0"
sources:
- name: Local Rules
source: data/local.txt
type: adblock
- name: EasyList
source: https://easylist.to/easylist/easylist.txt
type: adblock
transformations:
- RemoveModifiers
- Validate
transformations:
- Deduplicate
- RemoveEmptyLines
- InsertFinalNewLine
exclusions:
- "*.google.com"
- "/analytics/"name = "My Filter List"
description = "Custom ad-blocking filter"
version = "1.0.0"
transformations = ["Deduplicate", "RemoveEmptyLines", "InsertFinalNewLine"]
exclusions = ["*.google.com", "/analytics/"]
[[sources]]
name = "Local Rules"
source = "data/local.txt"
type = "adblock"
[[sources]]
name = "EasyList"
source = "https://easylist.to/easylist/easylist.txt"
type = "adblock"
transformations = ["RemoveModifiers", "Validate"]using RulesCompiler.Extensions;
using RulesCompiler.Models;
using RulesCompiler.Abstractions;
using Microsoft.Extensions.DependencyInjection;
// Setup DI
var services = new ServiceCollection();
services.AddLogging();
services.AddRulesCompiler();
var provider = services.BuildServiceProvider();
// Get compiler service
var compiler = provider.GetRequiredService<IRulesCompilerService>();
// Compile with options
var options = new CompilerOptions
{
ConfigPath = "config.yaml",
OutputPath = "output.txt",
Verbose = true,
ValidateConfig = true
};
var result = await compiler.RunAsync(options);
if (result.Success)
{
Console.WriteLine($"Compiled {result.RuleCount} rules");
Console.WriteLine($"Output: {result.OutputPath}");
}// Validate configuration before compilation
var validation = await compiler.ValidateConfigurationAsync("config.yaml");
if (!validation.IsValid)
{
foreach (var error in validation.Errors)
{
Console.WriteLine($"Error in {error.Field}: {error.Message}");
}
}
foreach (var warning in validation.Warnings)
{
Console.WriteLine($"Warning in {warning.Field}: {warning.Message}");
}var config = await compiler.ReadConfigurationAsync("config.yaml");
Console.WriteLine($"Filter: {config.Name}");
Console.WriteLine($"Sources: {config.Sources.Count}");
Console.WriteLine($"Transformations: {string.Join(", ", config.Transformations)}");using RulesCompiler.Models;
// Check if transformation is valid
bool isValid = TransformationHelper.IsValid("Deduplicate"); // true
// Get all transformations
var all = TransformationHelper.AllTransformations;
// Get recommended transformations for typical use
var recommended = TransformationHelper.RecommendedTransformations;
// Get transformations optimized for hosts file sources
var hostsTransforms = TransformationHelper.HostsFileTransformations;
// Validate a list of transformations
var invalid = TransformationHelper.GetInvalidTransformations(["Valid", "Invalid"]);| Interface | Description |
|---|---|
IConfigurationReader |
Reads and parses configuration files |
IFilterCompiler |
Compiles filter rules via hostlist-compiler |
IOutputWriter |
Handles output file operations |
IRulesCompilerService |
Main orchestration service |
| Model | Description |
|---|---|
CompilerConfiguration |
Configuration file model with all hostlist-compiler options |
FilterSource |
Source filter list definition |
CompilerResult |
Compilation result with metrics |
CompilerOptions |
Compilation options (verbose, validate, etc.) |
Transformation |
Enum of all available transformations |
SourceType |
Enum for source types (adblock, hosts) |
VersionInfo |
Component version information |
ConfigurationFormat |
Enum for JSON/YAML/TOML formats |
| Service | Description |
|---|---|
ConfigurationReader |
Parses JSON, YAML, and TOML configs with snake_case support |
ConfigurationValidator |
Validates configuration with error/warning reporting |
FilterCompiler |
Executes hostlist-compiler CLI with verbose support |
OutputWriter |
Copies output, computes hashes, counts rules |
RulesCompilerService |
Orchestrates the full pipeline with validation |
Register all services with a single extension method:
services.AddRulesCompiler();This registers:
CommandHelperIConfigurationReader->ConfigurationReaderIFilterCompiler->FilterCompilerIOutputWriter->OutputWriterIRulesCompilerService->RulesCompilerService
cd src/rules-compiler-dotnet
dotnet test RulesCompiler.slnx
# With verbose output
dotnet test RulesCompiler.slnx --verbosity detailed
# Run specific test class
dotnet test --filter "FullyQualifiedName~ConfigurationValidatorTests"
dotnet test --filter "FullyQualifiedName~TransformationTests"| Variable | Description |
|---|---|
RULESCOMPILER_config |
Default configuration file path |
RULESCOMPILER_Logging__LogLevel__Default |
Log level (Debug, Information, Warning, Error) |
src/rules-compiler-dotnet/
├── Config/ # Default configuration files
│ ├── compiler-config.json # JSON format
│ ├── compiler-config.yaml # YAML format
│ ├── compiler-config.toml # TOML format
│ └── compiler-config-advanced.yaml # Advanced example
├── src/
│ ├── RulesCompiler/ # Core library
│ │ ├── Abstractions/ # Interfaces
│ │ ├── Configuration/ # Config reader and validator
│ │ ├── Extensions/ # DI extensions
│ │ ├── Helpers/ # Utility helpers
│ │ ├── Models/ # Data models
│ │ └── Services/ # Service implementations
│ ├── RulesCompiler.Console/ # Console application
│ └── RulesCompiler.Tests/ # Unit tests
└── RulesCompiler.slnx # Solution file
- Uses
System.Runtime.InteropServices.RuntimeInformationfor platform detection - Path handling via
Path.CombineandPath.GetFullPath - UTF-8 encoding for all file operations
- Falls back to
npxif hostlist-compiler not globally installed
- Rules Compiler (TypeScript) - TypeScript implementation
- Rules Compiler (Python) - Python implementation
- Rules Compiler (Rust) - Rust implementation
- @adguard/hostlist-compiler - Underlying compiler
GPLv3 - See LICENSE for details.