rules_vsg

Bazel rules for VSG (VHDL Style Guide).

Overview

rules_vsg runs the VSG linter and formatter against vhdl_library targets:

  • vsg_test — a Bazel test rule that lints a vhdl_library and fails on violations.
  • @rules_vsg//vsg:fix — a bazel run-able binary that discovers vhdl_* targets under a query scope and applies vsg --fix in place to their sources.
  • vsg_aspect — an aspect that runs VSG as a side effect of bazel build, opt-in via .bazelrc.
  • vsg_toolchain — wraps the vsg pip package as a Bazel toolchain.

Setup

rules_vsg ships with no registered toolchain. VSG is a pip-distributed Python tool and you supply it as a py_library via whichever pip integration you prefer.

The example below uses rules_req_compile, but anything that produces a py_library exposing the vsg package will work.

MODULE.bazel

bazel_dep(name = "rules_vsg",  version = "{version}")
bazel_dep(name = "rules_vhdl", version = "0.1.2")
bazel_dep(name = "rules_venv", version = "0.17.0")
bazel_dep(name = "rules_req_compile", version = "1.1.2")

requirements = use_extension("@rules_req_compile//extensions:python.bzl", "requirements")
requirements.parse(
    name = "pip_deps",
    requirements_locks = {
        "//tools/requirements:requirements_linux_x86_64.txt": "//tools/requirements:linux_x86_64",
    },
)
use_repo(requirements, "pip_deps")

register_toolchains("//tools/toolchains:vsg_toolchain")

//tools/toolchains/BUILD.bazel

load("@rules_vsg//vsg:defs.bzl", "vsg_toolchain")

vsg_toolchain(
    name = "vsg_toolchain_impl",
    vsg = "@pip_deps//vsg",
)

toolchain(
    name = "vsg_toolchain",
    toolchain = ":vsg_toolchain_impl",
    toolchain_type = "@rules_vsg//vsg:toolchain_type",
)

//tools/requirements/requirements.in

vsg

Populate the lockfile with:

bazel run //tools/requirements:requirements.linux_x86_64.update

Usage

load("@rules_vhdl//vhdl:defs.bzl", "vhdl_library")
load("@rules_vsg//vsg:defs.bzl", "vsg_test")

vhdl_library(
    name = "math_pkg",
    srcs = ["math_pkg.vhd", "adder.vhd"],
)

vsg_test(
    name = "math_pkg_vsg_test",
    target = ":math_pkg",
    config = ":vsg_config.yaml",
)

Run:

  • bazel test //:math_pkg_vsg_test — fails on violations
  • bazel run @rules_vsg//vsg:fix -- //:math_pkg — applies vsg --fix in place to that library's sources
  • bazel run @rules_vsg//vsg:fix — same, across every vhdl_* target in the workspace

vsg_test always emits JUnit XML at $XML_OUTPUT_FILE when running under bazel test, so test results integrate with the standard Bazel test report. The workspace fixer discovers targets via bazel query and only mutates files inside the calling workspace — external-repo sources (@repo//...) are never touched.

Aspect mode

To run VSG on every vhdl_library in the workspace as part of bazel build, add to .bazelrc:

build:vsg --aspects=@rules_vsg//vsg:vsg_aspect.bzl%vsg_aspect
build:vsg --output_groups=+vsg_checks
build:vsg --@rules_vsg//vsg:config=//:vsg_config.yaml

Then run with bazel build --config=vsg //.... Tag a target with no_vsg (or nolint, noformat) to opt out.

Extra vsg arguments

The //vsg:extra_args build flag forwards additional arguments to vsg_test and vsg_aspect invocations. Set it repeatedly in .bazelrc, one flag per argument:

build --@rules_vsg//vsg:extra_args=-of=summary

The workspace fixer (@rules_vsg//vsg:fix) does not read this flag — it accepts extra vsg arguments via CLI passthrough only (-- <args> after the scope). See the vsg:fix page for details.

Rule reference

Generated reference for each rule is in the Rules section.