gerberguard

    A lightweight Gerber PCB manufacturing file inspection and preflight tool written in MoonBit.

    gerber
    pcb
    eda
    manufacturing
    preflight
    Download zip
    Author
    Version
    0.1.0
    License
    Apache-2.0
    Last updated
    last month
    Downloads
    4

    Dependencies

    #GerberGuard-MBT

    GerberGuard-MBT is a lightweight Gerber PCB manufacturing file inspection and preflight tool implemented in MoonBit.

    It scans Gerber command streams, extracts format, unit and X2 metadata, tracks aperture definitions and graphics state, validates common structural relationships such as undefined apertures, region state, plot state and end-of-file markers, and produces deterministic text or JSON reports.

    Version 0.1.0 intentionally implements a limited modern Gerber subset. It does not render PCB geometry or attempt full manufacturing-rule verification. The project focuses on a small, reliable and testable core suitable for command-line use and CI pipelines.

    GerberGuard 0.1.0 implements a deliberately limited subset of the Gerber Layer Format.

    It is intended for inspection and basic preflight checks.

    It is not a complete Gerber conformance checker, renderer, PCB DRC engine, or CAM system.

    GerberGuard-MBT 是一个使用 MoonBit 编写的轻量级 PCB Gerber 制造文件检查与预检工具。它读取 Gerber 命令流,提取单位、坐标格式、Aperture 和部分 X2 文件属性,并检查常见结构问题。项目不渲染 PCB 图形,不进行 DRC,也不判断 PCB 是否可以生产。

    GerberGuard focuses on a small but useful task: deterministic, offline preflight inspection of Gerber manufacturing files.

    Instead of rendering geometry, it checks the command stream and graphics-state relationships, making the implementation compact, testable and suitable for automated CI pipelines.

    #Features

    • Gerber UTF-8 file inspection
    • Modern FS format detection
    • Metric and inch unit detection
    • Aperture definition tracking
    • Undefined aperture detection
    • D01/D02/D03 statistics
    • Basic circular plotting checks
    • Region state validation
    • Gerber X2 FileFunction inspection
    • Human-readable reports
    • JSON reports
    • Native command-line interface

    #Supported Syntax

    #What GerberGuard Does Not Do

    GerberGuard does not:

    • render Gerber geometry
    • perform PCB DRC
    • determine manufacturability
    • parse Excellon files
    • parse KiCad or Altium project files
    • validate aperture macro geometry
    • validate region geometry
    • validate arc geometry
    • implement the complete Gerber specification

    #Installation

    Requires a MoonBit toolchain with Native support.

    moon version --all moon update

    #Usage

    moon run cmd/main --target native -- inspect <FILE> [--json] moon run cmd/main --target native -- check <FILE> [--json] moon run cmd/main --target native -- --help moon run cmd/main --target native -- --version

    After moon build --release --target native, the executable can also be invoked as gerberguard depending on your packaging/install path.

    #inspect example

    moon run cmd/main --target native -- inspect samples/pass/minimal.gbr

    GerberGuard 0.1.0 File: samples/pass/minimal.gbr Format: Gerber Layer Format (supported subset) Unit: millimeter Coordinate format: 4.6 File function: Copper,L1,Top File polarity: Positive Generation software: - Statistics ---------- Apertures: 1 Aperture macros: 0 Moves: 1 Draws: 1 Flashes: 0 Regions: 0 Arc draws: 0 Comments: 0 Attributes: 2 Unknown commands: 0 Result: PASS Errors: 0 Warnings: 0

    #check example

    moon run cmd/main --target native -- check samples/fail/undefined_aperture.gbr

    GerberGuard 0.1.0 ERROR G201 line 4 Undefined aperture D15. Result: FAIL Errors: 1 Warnings: 0

    #JSON example

    moon run cmd/main --target native -- check \ samples/pass/minimal.gbr \ --json

    The JSON mode writes one JSON document to stdout without banners or debug logs.

    { "tool": "gerberguard", "version": "0.1.0", "command": "check", "file": "samples/pass/minimal.gbr", "status": "pass", "unit": "mm", "coordinate_format": { "integer_digits": 4, "decimal_digits": 6 }, "file_function": "Copper,L1,Top", "file_polarity": "Positive", "generation_software": null, "statistics": { "apertures": 1, "aperture_macros": 0, "moves": 1, "draws": 1, "flashes": 0, "regions": 0, "arc_draws": 0, "comments": 0, "attributes": 2, "unknown_commands": 0 }, "errors": 0, "warnings": 0, "issues": [] }

    #Exit Codes

    CodeMeaning
    0PASS or PASS WITH WARNINGS
    1Report contains one or more Error issues
    2CLI usage / argument error
    3File IO / UTF-8 decode error

    #Error Model

    Deterministic issue codes are documented in docs/ERROR_CODES.md.

    #Development

    Contribution scope and the required local workflow are documented in CONTRIBUTING.md. Security and private-fixture reporting guidance is documented in SECURITY.md. Release and Mooncakes publication steps are documented in docs/RELEASING.md.

    moon fmt moon check --target all --deny-warn moon test --target all --deny-warn moon build --release --target native moon info git diff --exit-code

    #Testing

    Unit tests cover scanner, parser, checker, reporters and CLI parsing. Fixtures live under samples/pass, samples/warn and samples/fail. The complete reproducible acceptance procedure is in ACCEPTANCE.md.

    #Project Structure

    model.mbt scanner.mbt parser.mbt checker.mbt report_text.mbt report_json.mbt cli.mbt cmd/main/main.mbt samples/{pass,warn,fail}/ docs/{ARCHITECTURE,SUPPORTED_SYNTAX,ERROR_CODES}.md .github/workflows/ci.yml

    #Limitations

    GerberGuard v0.1.0 is a Gerber supported-subset preflight checker. It performs structural inspection only.

    #Gerber Specification Reference

    This project targets a practical modern subset of the Gerber Layer Format (Ucamco), especially common X2 attributes and graphics-state commands used in manufacturing handoff files.

    Source, fixture, generated-file, dependency, and AI-assistance disclosures are documented in docs/PROVENANCE.md.

    #License

    Apache-2.0. See LICENSE.

    AnalysisStatus

    pub(all) enum AnalysisStatus {
    Pass
    PassWithWarnings
    Fail
    } derive(Eq,
    Debug
    )

    ApertureDefinition

    pub(all) struct ApertureDefinition {
    code : Int
    template : String
    parameters_raw : String?
    line : Int
    } derive(Eq,
    Debug
    )

    AttributeScope

    pub(all) enum AttributeScope {
    File
    Aperture
    Object
    } derive(Eq,
    Debug
    )

    CliCommand

    pub(all) enum CliCommand {
    Inspect
    Check
    Help
    Version
    } derive(Eq,
    Debug
    )

    CliConfig

    pub(all) struct CliConfig {
    command : CliCommand
    file : String?
    json : Bool
    } derive(Eq,
    Debug
    )

    CliError

    pub(all) enum CliError {
    Usage(String)
    } derive(Eq,
    Debug
    )

    CoordinateFields

    pub(all) struct CoordinateFields {
    x : String?
    y : String?
    i : String?
    j : String?
    } derive(Eq,
    Debug
    )

    CoordinateFormat

    pub(all) struct CoordinateFormat {
    integer_digits : Int
    decimal_digits : Int
    } derive(Eq,
    Debug
    )

    GerberAttribute

    pub(all) struct GerberAttribute {
    scope : AttributeScope
    name : String
    raw_value : String?
    line : Int
    } derive(Eq,
    Debug
    )

    GerberCommand

    pub(all) enum GerberCommand {
    Comment(String)
    Format(CoordinateFormat)
    Unit(GerberUnit)
    ApertureMacro(String, String)
    ApertureDefinition(ApertureDefinition)
    SelectAperture(Int)
    SetPlotMode(PlotMode)
    MultiQuadrant
    Move(CoordinateFields)
    Draw(CoordinateFields)
    Flash(CoordinateFields)
    BeginRegion
    EndRegion
    SetPolarity(Polarity)
    Attribute(GerberAttribute)
    DeleteAttribute(String?)
    EndFile
    UnknownWord(String)
    UnknownExtended(String)
    Malformed(String)
    } derive(Eq,
    Debug
    )

    GerberReport

    pub(all) struct GerberReport {
    status : AnalysisStatus
    unit : GerberUnit?
    coordinate_format : CoordinateFormat?
    file_function : String?
    file_polarity : String?
    generation_software : String?
    statistics : GerberStatistics
    issues : Array[Issue]
    } derive(Eq,
    Debug
    )

    GerberStatistics

    pub(all) struct GerberStatistics {
    apertures : Int
    aperture_macros : Int
    moves : Int
    draws : Int
    flashes : Int
    regions : Int
    arc_draws : Int
    comments : Int
    attributes : Int
    unknown_commands : Int
    } derive(Eq,
    Debug
    )

    GerberUnit

    pub(all) enum GerberUnit {
    Millimeter
    Inch
    } derive(Eq,
    Debug
    )

    Issue

    pub(all) struct Issue {
    code : String
    severity : Severity
    message : String
    line : Int?
    } derive(Eq,
    Debug
    )

    LocatedCommand

    pub(all) struct LocatedCommand {
    command : GerberCommand
    line : Int
    } derive(Eq,
    Debug
    )

    PlotMode

    pub(all) enum PlotMode {
    Linear
    Clockwise
    CounterClockwise
    } derive(Eq,
    Debug
    )

    Polarity

    pub(all) enum Polarity {
    Dark
    Clear
    } derive(Eq,
    Debug
    )

    RawToken

    pub(all) struct RawToken {
    kind : RawTokenKind
    raw : String
    line : Int
    } derive(Eq,
    Debug
    )

    RawTokenKind

    pub(all) enum RawTokenKind {
    Word
    ExtendedBlock
    } derive(Eq,
    Debug
    )

    Severity

    pub(all) enum Severity {
    Error
    Warning
    } derive(Eq,
    Debug
    )

    MAX_EXTENDED_BLOCK_BYTES

    let MAX_EXTENDED_BLOCK_BYTES : Int

    MAX_INPUT_BYTES

    let MAX_INPUT_BYTES : Int

    MAX_TOKEN_COUNT

    let MAX_TOKEN_COUNT : Int

    MAX_WORD_BYTES

    let MAX_WORD_BYTES : Int

    VERSION

    let VERSION : String

    analyze

    fn analyze(source : String) -> GerberReport

    exit_code_for_report

    fn exit_code_for_report(report : GerberReport) -> Int

    input_too_large_report

    fn input_too_large_report() -> GerberReport

    parse_cli

    fn parse_cli(args : ArrayView[String]) -> Result[CliConfig, CliError]

    render_check

    fn render_check(report : GerberReport, file_name : String) -> String

    render_inspect

    fn render_inspect(report : GerberReport, file_name : String) -> String

    render_json

    fn render_json(report : GerberReport, file_name : String, command : CliCommand) -> String

    truncate_for_message

    fn truncate_for_message(s : String) -> String

    usage_text

    fn usage_text() -> String

    version_text

    fn version_text() -> String