go-structurizr

repository·master·Indexed 18 days ago

https://github.com/krzysztofreczek/go-structurizr

A Go library that automates the generation of C4 component diagrams from Go source code. It uses a Scraper to examine structures via reflection and a View to render the resulting model.Structure into PlantUML format. Supports configuration via Go code or YAML files for defining component identification rules, styling, and filtering.

Tokens
1.6K
Snippets
9
Records
10
Agent score
13%

What's inside go-structurizr

  1. How go-structurizr works

    master

    The library uses two main components to convert Go code into C4 component diagrams in PlantUML format:

    1. Scraper: Uses reflection to examine Go structures. It identifies components based on whether they implement the model.HasInfo interface or match specific registered rules and configurations.
    2. View: Takes the model.Structure produced by the Scraper and renders it into PlantUML code. The View handles titles, component styling (colors, shapes), and filtering components via tags.

    The typical workflow is: Scrape Go code $\rightarrow$ Produce model.Structure $\rightarrow$ Pass to View $\rightarrow$ Render PlantUML.

  2. Configure View via YAML

    master

    You can define view settings in go-structurizr.yml. This includes the title, line color, component styles (mapped by ID), and filtering by component_tags or root_component_tags.

    view:
      title: "Title"
      line_color: 000000ff
      styles:
        - id: TAG
          background_color: ffffffff
          font_color: 000000ff
          border_color: 000000ff
          shape: database
      root_component_tags:
        - ROOT
      component_tags:
        - TAG
  3. Configure Scraper via YAML

    master

    You can define scraper rules in a go-structurizr.yml file. This allows you to map package and name regexes to component metadata like description, technology, and tags. You can use regex groups in the name field using {1}, {2}, etc., to dynamically generate component names.

    configuration:
      pkgs:
        - "github.com/org/pkg"
    
    rules:
      - name_regexp: "(\\w*)\\.(\\w*)Client$"
        pkg_regexps:
          - "github.com/org/pkg/foo/.*"
        component:
          name: "Client of external {1} service"
          description: "foo client"
          technology: "gRPC"
          tags:
            - TAG
  4. Render a scraped structure to PlantUML

    master

    Once you have a model.Structure (from the Scraper) and a configured View, you can render the structure to a file using v.RenderStructureTo(structure, writer).

    // structure is obtained from s.Scrape(app)
    outFile, _ := os.Create("c4.plantuml")
    defer func() {
        _ = outFile.Close()
    }()
    
    err = v.RenderStructureTo(structure, outFile)
  5. Configure and instantiate a Scraper in Go

    master

    To use the Scraper in your code, you must first create a configuration that specifies the package prefixes you want to reflect. Only types within these packages will be processed.

    config := scraper.NewConfiguration(
        "github.com/org/pkg",
    )
    s := scraper.NewScraper(config)
  6. Register Scraper rules to identify components

    master

    You can register custom rules with the Scraper to define how specific types are identified as components. A rule matches types based on package regular expressions and name regular expressions, then uses an apply function to generate model.Info.

    The apply function receives the component name and any regex capture groups as arguments.

    r, err := scraper.NewRule().
        WithPkgRegexps("github.com/org/pkg/foo/.*").
        WithNameRegexp(`^(\w*)\.(\w*)Client$`).
        WithApplyFunc(
            func(_ string, groups ...string) model.Info {
                // groups[1] and groups[2] contain regex matches
                n := fmt.Sprintf("Client of external %s service", groups[1])
                return model.ComponentInfo(n, "foo client", "gRPC", "TAG")
            }).
        Build()
    err = s.RegisterRule(r)
  7. Configure and instantiate a View in Go

    master

    A View defines how the scraped structure is rendered. You can customize the title, component styles (color, shape, etc.), and filter which components are shown using tags.

    Use view.NewView() and the builder pattern to customize the output.

    v := view.NewView().
        WithTitle("Title").
        WithComponentStyle(
            view.NewComponentStyle("TAG").
                WithBackgroundColor(color.White).
                WithFontColor(color.Black).
                WithBorderColor(color.Black).
                WithShape("database").
                Build(),
        ).
        WithComponentTag("TAG").
        WithRootComponentTag("ROOT").
        Build()