EasyP Protocol Buffers Toolkit

repository·main·Indexed 42 days ago

https://github.com/easyp-tech/easyp

A modern Protocol Buffers toolkit providing a unified CLI for linting, breaking change detection, code generation, and Git-based package management. It includes a Go-based MCP server for describing easyp.yaml schema metadata and a React-based markdown rendering library featuring automatic TOC generation, code line focusing, and custom HTML blocks.

Tokens
98.3K
Snippets
333
Records
409
Agent score
50%

What's inside EasyP

  1. What is EasyP?

    main

    EasyP is a modern Protocol Buffers (protobuf) toolkit that unifies the entire protobuf workflow into a single CLI tool. It replaces fragmented processes with a standardized, opinionated approach to:

    • Linting: Comprehensive support for buf rules with customizable profiles.
    • Package Management: Git-native dependency management using Git repositories (GitHub, GitLab, etc.) instead of a centralized registry, ensuring no vendor lock-in and full support for private repositories.
    • Code Generation: Supports both local protoc plugins and remote plugins via the EasyP API service.
    • Breaking Change Detection: Automatically checks API compatibility against Git branches.

    All workflows are managed through a single easyp.yaml configuration file.

  2. Overview of the EasyP Generator

    main

    The EasyP Generator is a powerful tool designed to simplify the process of generating code from .proto files. Instead of using complex and long protoc commands directly, EasyP provides a declarative YAML-based configuration layer.

    Key capabilities include:

    • Simplified Code Generation: Uses declarative YAML configurations to manage the generation process.
    • protoc Wrapper: Acts as a high-level API over protoc, supporting all standard protoc options and plugins.
    • Flexibility: Allows using standard protoc plugin parameters directly within the configuration.
    • Multi-source Input: Supports generating code from local directories and remote Git repositories simultaneously.
    • Remote Generation: Enables code generation from remote Git repositories without requiring a local checkout.
    • Package Manager Integration: Automatically resolves and connects .proto dependencies through the EasyP package manager.
  3. Overview of EasyP API Service

    main
    The EasyP API Service is a centralized platform for executing protobuf/gRPC plugins within isolated Docker containers. It solves the problem of version inconsistency, operational overhead, and security risks associated with managing plugins locally on developer machines. Instead of installing plugins manually, developers use the service to run plugins in a standardized, containerized environment.
  4. What is Managed Mode in EasyP?

    main

    Managed mode automatically applies file and field options to your protobuf descriptors during code generation without modifying the original .proto files. This allows you to maintain clean, language-agnostic .proto files while enforcing language-specific naming conventions (like Java packages or C# namespaces) via centralized configuration in easyp.yaml.

    Key Concepts:

    • In-memory application: Options are applied during generation, so your source files remain unchanged.
    • Default values: EasyP provides sensible defaults based on language conventions (e.g., java_package_prefix defaults to "com", cc_enable_arenas defaults to true).
    • Compatibility: It is compatible with buf's managed mode.
    • Precedence:
      1. Disable rules (highest priority)
      2. Override rules (last matching rule wins)
      3. Default values (only if no override matches and not disabled)
    # Basic setup to enable managed mode
    generate:
      inputs:
        - directory: "proto"
      plugins:
        - name: go
          out: ./gen/go
      managed:
        enabled: true
  5. Understand the RPC_REQUEST_RESPONSE_UNIQUE linter rule

    main

    The RPC_REQUEST_RESPONSE_UNIQUE rule is a linter rule used to ensure that every RPC method in a service uses a unique combination of request and response messages. This prevents ambiguity and ensures that different RPC calls do not accidentally share the same message types, which can lead to maintenance issues or logical errors in generated code.

    This rule belongs to the following categories:

    • MINIMAL
    • BASIC
    • DEFAULT
  6. Understand the PACKAGE_SAME_CSHARP_NAMESPACE rule

    main

    The PACKAGE_SAME_CSHARP_NAMESPACE rule is a linting rule used to ensure consistency in C# code generation. It verifies that all .proto files belonging to the same package declaration use the exact same csharp_namespace option. This prevents fragmented or inconsistent namespace structures in the generated C# code for a single package.

    This rule falls under the following severity categories:

    • MINIMAL
    • BASIC
    • DEFAULT
  7. Understand the DIRECTORY_SAME_PACKAGE linter rule

    main

    The DIRECTORY_SAME_PACKAGE rule ensures that all .proto files located within a specific directory belong to the same Protobuf package. This rule is categorized under MINIMAL, BASIC, and DEFAULT linting levels.

    To satisfy this rule, the package name declared in the .proto file should reflect the directory structure. For example, if a file is located at dir/foo/foo.proto, its package declaration should be package dir.foo; rather than just package foo;.

    // Good Example
    // File: dir/foo/foo.proto
    
    syntax = "proto3";
    
    package dir.foo;
    
    message Foo {
        string bar = 1;
    }
  8. Breaking Change Rule: ONEOF_NO_DELETE

    main

    The ONEOF_NO_DELETE rule is a WIRE+ category breaking change check. It prevents the deletion of oneof fields from messages. Deleting a oneof is considered a breaking change because it destroys wire format compatibility, removes generated code (accessor methods and wrapper types), and violates the mutual exclusivity semantics that the API design relies on.

    Impact of deleting a oneof:

    • Wire Format: Fields are no longer mutually exclusive; multiple fields can be set simultaneously.
    • Generated Code: OneOf accessor methods and wrapper types are removed, causing compilation errors in client code.
    • Business Logic: The guarantee that only one field is set is lost, requiring manual validation logic.
    • Validation: Clients expecting type-safe oneof structures will break.
  9. Understand the SERVICE_NO_DELETE breaking change rule

    main

    The SERVICE_NO_DELETE rule (part of the WIRE+ category) prevents the deletion of services from .proto files. Deleting a service is considered a breaking change because it removes generated code and service definitions that client applications rely on for compilation and runtime communication.

    When this rule is violated, the breaking change check will emit an error similar to: services.proto:8:1: Previously present service "OrderService" was deleted from file. (BREAKING_CHECK)

  10. Create Custom HTML Blocks

    main

    Use specific HTML div classes to create informational blocks. These blocks are styled automatically by the library.

    Supported types via the custom-block class:

    • tip: Helpful tips
    • warning: Warnings
    • danger: Critical danger alerts
    • details: Additional information/expandable content

    Example Usage:

    <div class="tip custom-block">
    **Tip**: This is helpful information!
    </div>
    
    <div class="warning custom-block">
    **Warning**: Be careful with this!
    </div>

    Standalone Component:

    import { CustomBlock } from '@/lib/markdown';
    
    <CustomBlock type="tip" title="Pro Tip">
      This is a helpful tip!
    </CustomBlock>
    <div class="tip custom-block">
    **Tip**: This is helpful information!
    </div>
  11. Linter rule categories and groupings

    main

    The EasyP linter uses categories to allow developers to quickly set levels of strictness. You can include these categories in the use section of your easyp.yaml configuration.

    Available Categories

    • MINIMAL: Ensures basic package integrity (e.g., PACKAGE_DEFINED, PACKAGE_SAME_DIRECTORY).
    • BASIC: Enforces common naming and structural conventions (e.g., FIELD_LOWER_SNAKE_CASE, MESSAGE_PASCAL_CASE, SERVICE_PASCAL_CASE).
    • DEFAULT: Recommended rules for most projects (e.g., SERVICE_SUFFIX, RPC_REQUEST_STANDARD_NAME).
    • COMMENTS: Requires documentation for various elements (e.g., COMMENT_SERVICE, COMMENT_RPC, COMMENT_FIELD).
    • UNARY_RPC: Restricts streaming RPCs (e.g., RPC_NO_CLIENT_STREAMING).

    Mixing Categories and Rules

    You can mix categories and specific individual rules in your use list:

    # Example: Mixing categories and specific rules
    use:
      - MINIMAL
      - COMMENT_SERVICE
      - COMMENT_RPC
      - ENUM_PASCAL_CASE
    use:
      - MINIMAL
      - COMMENT_SERVICE
      - COMMENT_RPC
      - ENUM_PASCAL_CASE
  12. Understand the PACKAGE_DIRECTORY_MATCH linter rule

    main

    The PACKAGE_DIRECTORY_MATCH rule is a linter rule used to ensure project consistency by verifying that the directory structure of your .proto files matches their declared package name.

    This rule belongs to the following categories:

    • MINIMAL
    • BASIC
    • DEFAULT

    If a file is located in a directory named bar/ but its internal package declaration is foo;, the linter will trigger an error.