Skip to content

voidreamer/usd-lint

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

usd-lint

CI License

A fast, configurable linter for OpenUSD scene description files (.usda).

Catch naming violations, structural anti-patterns, composition mistakes, and property issues before they become production problems, in milliseconds, with zero Python or USD SDK dependencies.

$ usd-lint ./assets/

assets/shot_010/layout.usda
  3:1  warning  Prim "world" does not match PascalCase convention  [naming/prim-case]
    ↳ Rename to "World"
  8:5  warning  references on prim "hero" has no explicit list-op  [composition/require-list-op]
    ↳ Use `prepend references` for predictable composition order
  42:9 warning  Primvar "primvars:st" on prim "Ground" has no interpolation specified  [properties/primvar-interpolation]
    ↳ Add `interpolation = "vertex"` (or faceVarying/constant/uniform)

────────────────────────────────────────────────────────────
⚠ 3 files checked: 0 errors, 2 warnings, 1 info

Why?

Studios adopting OpenUSD generate thousands of .usda files across departments. Without automated validation:

  • Naming conventions drift between artists and teams
  • Deep nesting makes scenes slow to load and hard to debug
  • Bare references = (without prepend) causes subtle composition bugs
  • Missing defaultPrim breaks referencing in downstream shots
  • Primvars without interpolation cause silent render failures

usd-lint catches all of this at authoring time. It runs in CI, pre-commit hooks, or your editor. It does not replace usdchecker; it enforces your studio's conventions on top of format validity.

Features

  • Fast. Rust-native USDA parser. Lints thousands of files in seconds.
  • Configurable. .usdlint.toml controls every rule. Per-rule severity overrides.
  • 10 built-in rules across 4 categories (naming, structure, composition, properties).
  • Multiple output formats. Colored terminal, JSON (for CI), GitHub Actions annotations.
  • Zero runtime dependencies. Single static binary. Drop it anywhere in your pipeline.

Installation

From source (requires Rust)

cargo install --git https://github.com/voidreamer/usd-lint

From releases

Download pre-built binaries for Linux, macOS (Intel + Apple Silicon), and Windows from the Releases page.

In CI (GitHub Actions)

- name: Lint USD files
  run: |
    curl -L https://github.com/voidreamer/usd-lint/releases/latest/download/usd-lint-x86_64-unknown-linux-gnu -o usd-lint
    chmod +x usd-lint
    ./usd-lint ./assets/ --format github --strict

Quick Start

# Lint the current directory (searches recursively for .usda/.usd files)
usd-lint .

# Lint specific files
usd-lint assets/hero.usda shots/shot_010/layout.usda

# Generate a default config
usd-lint init

# List all available rules
usd-lint list-rules

# JSON output for CI/CD
usd-lint ./assets/ --format json

# GitHub Actions annotations
usd-lint ./assets/ --format github

# Fail on warnings too (useful for CI)
usd-lint ./assets/ --strict

Configuration

Create a .usdlint.toml in your project root (or run usd-lint init):

[global]
default_severity = "warning"
include = ["**/*.usda", "**/*.usd"]
exclude = ["**/legacy/**"]

[naming]
prim_case = "pascal_case"          # PascalCase for prim names
property_case = "camel_case"       # camelCase for properties
prim_disallowed = ["tmp", "test", "delete_me", "untitled"]
require_default_prim = true

[structure]
max_depth = 12                     # Flag deeply nested hierarchies
max_children = 500                 # Flag prims with too many children
require_kind_on_root = true        # Root prims need `kind` metadata

[composition]
require_list_op = true             # Require prepend/append on arcs
max_references_per_prim = 10

[properties]
require_primvar_interpolation = true

# Per-rule overrides
[rules."naming/prim-case"]
severity = "error"                 # Promote to error for strict enforcement

[rules."structure/require-kind"]
enabled = false                    # Disable if your studio doesn't use `kind`

Rules

Rule ID Category Description
naming/prim-case Naming Prim names follow configured casing (default: PascalCase)
naming/property-case Naming Property names follow configured casing (default: camelCase)
naming/disallowed-names Naming Prim names don't contain disallowed substrings
naming/default-prim Naming Layer metadata includes defaultPrim
structure/max-depth Structure Prim hierarchy doesn't exceed max depth
structure/max-children Structure Prims don't have excessive child counts
structure/require-kind Structure Root def prims have kind metadata
composition/require-list-op Composition Arcs use explicit prepend/append
composition/max-references Composition Prims don't exceed max reference count
properties/primvar-interpolation Properties Primvars have interpolation specified

Architecture

src/
├── parser/          # PEG grammar (pest) + AST types for USDA
│   ├── usda.pest    # The grammar
│   ├── ast.rs       # Typed AST nodes (Prim, Property, CompositionArc, etc.)
│   └── parse.rs     # pest -> AST conversion
├── config/          # TOML config loading + rule settings
├── rules/           # Lint rules
│   ├── builtins.rs  # All 10 built-in rules
│   └── engine.rs    # Orchestrates parsing + rule execution
├── reporter/        # Output formatters (text, JSON, GitHub Actions)
├── cli/             # clap-based CLI argument parsing
├── lib.rs           # Library entry point (for use as a crate)
└── main.rs          # Binary entry point

Roadmap

  • USDC support: binary crate file reading (via C FFI to the USD SDK)
  • Python bindings: PyO3-based, pip install usd-lint
  • Custom rules: user-defined rules via TOML patterns or Lua scripts
  • Auto-fix: --fix flag to automatically correct simple violations
  • Editor integrations: LSP server, VS Code extension
  • Reference validation: check that @asset_path@ targets actually exist on disk
  • Performance benchmarks: track parsing speed across releases

Contributing

Contributions are welcome. Whether it is a new rule, a bug fix, or documentation improvements.

# Clone and build
git clone https://github.com/voidreamer/usd-lint.git
cd usd-lint
cargo build

# Run tests
cargo test

# Run against the test fixtures
cargo run -- tests/fixtures/

# Run with a specific config
cargo run -- tests/fixtures/ --config examples/default.usdlint.toml

License

Dual-licensed under MIT or Apache-2.0, at your option.


Built by Alejandro Cabrera. Pipeline TD with 10+ years in VFX and feature animation.

About

No description, website, or topics provided.

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages