This is a collection of Luminar's development tools. These tools are used to help developers in their day-to-day tasks.
Note
Since I was the main author of these tools while working at Luminar, I am maintaining this fork to keep them up to date. I try to contribute back if possible but since I am no longer working at Luminar, it is not guaranteed that my contributions are accepted.
- Tools
- Hooks
check-build-file-without-extensionscheck-snake-casecheck-cpp-and-cu-unit-test-naming-patterncheck-no-dashescheck-sys-path-appendcheck-sys-path-insertgo-fmtgo-importsgo-revivegenerate-hook-docscheck-number-of-lines-countcheck-shellscript-set-optionscheck-jira-reference-in-todocheck-load-statementcheck-rule-has-tagcheck-non-existing-and-duplicate-excludesprint-pre-commit-metricssync-vscode-configsync-tool-versionscheck-max-one-sentence-per-linecheck-ownership
- Contributing
See the README.md in the configure_vscode_for_bazel package for documentation on the configure-vscode-for-bazel tool.
See the README.md in the whoowns package for documentation on the whoowns tool.
Check that BUILD files have a .bazel ending. BUILD.bazel file is the recommended way to name these files.
Check that all source code files are snake_case. We don't want to use camelCase or kebab-case file names.
Check that all C++ and Cuda unit test files end with _test.cpp or _test.cu (no _tests)
and that they're under a /tests/ folder (not /test/).
Check that markdown filenames do not use dashes
Check that no sys.path.append is used in Python code
Check that no sys.path.insert is used in Python code
Format go files
Order go imports
Run Go Revive linter
Generate markdown documentation from the hook descriptions in .pre-commit-hooks.yaml into the README.md. Docs are generated between hooks-doc start and hooks-doc end markdown comment blocks.
Check that number of lines in scripts do not exceed max-lines.
Use --max-lines=<number> to set the maximum number of lines.
Default is 50 for shell scripts.
Check if options are set with set -euxo pipefail. Use # nolint(set_options) to ignore this check.
Check that all TODO comments follow the same pattern and link a Jira ticket: TODO(ABC-1234):.
Check that a rule is loaded from a specific rule set.
Use --rule-path to set the rule load path and --rule-name to set the rule name.
Both arguments are required.
Example args in the pre-commit config: args: [--rule-path=@rules_python//python:defs.bzl, --rule-name=py_test].
Make sure you don't put any ticks around the rule path and rule name.
This hook can be used multiple times to check different rules.
Check that a Bazel rule contains a specific tag in its tags attribute.
Use --rule-name to select the rule and --tag to define the required tag.
Both arguments are required.
Example args in the pre-commit config: args: [--rule-name=py_venv, --tag=manual]
This is useful for checks such as: py_venv(..., tags = ["manual"]) or pkg_tar(..., tags = ["no-remote"]).
Alternatively, you can
- make use of Bazel's
--modify_execution_infoflag, see https://github.com/bazel-contrib/tar.bzl?tab=readme-ov-file#remote-cache-and-rbe - wrap the rule with a macro that always applies these tags (combine this with the
check-load-statementhook to make sure users always use the wrapper)
This hook can be used multiple times to check different rules and tags.
Check for non existing and duplicate paths in .pre-commit-config.yaml.
Background: In a big codebase, the exclude lists can be quite long and it's easy to make a typo or forget to remove an entry when it's no longer needed. This hook helps you to maintain a clean and up to date exclude list.
Count the number of excludes in .pre-commit-config.yaml and print them in json format.
Use --output-file to also write the metrics to a file in json format.
Paths are relative to the root of the repository.
On large projects this can help to collect metrics over time for how many files are excluded from pre-commit.
Sync VSCode settings and extensions from devcontainer.json to .vscode folder.
devcontainer.json will be now your source of truth.
Entries defined in settings.json and extensions.json which don't exist in devcontainer.json will be left as is.
If settings.json and extensions.json are ignored in Git, consider running the hook in post-checkout and post-merge stages by overwriting the stages config.
In this case, define your default_install_hook_types in the pre-commit config and set always_run: true for this hook.
Sync tool versions across files based on .versions.yaml.
Each version entry defines a name, a version, and a list of entries containing
a file path and a regex pattern with a single capture group for the version.
You can also use THE_VERSION in the pattern as a placeholder for that capture group
(defaults to SemVer with an optional leading v).
Use version_override on an entry to replace with a different value than the sync version.
If you need prefixes like py314, use an explicit capture group instead of THE_VERSION.
Example .versions.yaml:
name: tool-versions
sync_versions:
- name: rust
version: 1.91.0
entries:
- path: MODULE.bazel
pattern: RUST_VERSION\s*=\s*"THE_VERSION"
- path: .pre-commit-config.yaml
pattern: rust:\s*([0-9.]+)
- name: python
version: 3.14
entries:
- path: .python-version
pattern: ([0-9]+\.[0-9]+)
- path: pyproject.toml
pattern: target-version\s*=\s*\"py([0-9]+)\"
version_override: '314'Check that each line in markdown files contains at most one sentence.
This makes diffs easier to read and avoids merge conflicts.
Sentences are split on ., !, or ? followed by a space and a capital letter.
This hook doesn't respect surrounding indentation, so be sure to combine it with https://github.com/hukkin/mdformat or a similar formatter that fixes indentation.
Check if all folders in the CODEOWNERS file exist, there are no duplicates, and it has acceptable codeowners.
What is an acceptable codeowner?
We want to make sure that every folder has a codeowner other than the team that should exclusively own the CODEOWNERS file.
For this, we define a CODEOWNERS_OWNER using the --codeowners-owner argument.
Your CODEOWNERS file should look as follows:
* CODEOWNERS_OWNER
# Here goes all your CODEOWNERS file content overriding the wildcard owner
# leave this at the bottom to have highest ownership priority
/.github/CODEOWNERS CODEOWNERS_OWNERIf the hook detects CODEOWNERS_OWNER owns anything else than .github/CODEOWNERS it will fail to make sure every file added has an acceptable codeowner.
Please refer to the CONTRIBUTING.md file for information on how to contribute to this project.