Skip to content

Conversation

@arijit-dasgupta
Copy link
Contributor

Part of MET-7 and part of MET-12.

In this PR, I have set up C++ and Python linting and formatting using pixi. Python format and linting is done using ruff while C++ is done using clang-tools.We can run them on our own, but they will automatically get triggered via pre-commits hooks anyways. Linting rules could be too strict, so we should feel free to disable warnings that don't make sense.

There is also a pre-push hook that runs all the GPU and CPU unit tests (building on top of #2 and #3 ) locally

@linear
Copy link

linear bot commented Nov 9, 2025

MET-7 Pre-commit

Deliverable:

  • have a pre-commit hook that runs linter, formatter (both C++ and Python)
  • have a pre-push hook that runs the unit tests (?)

MET-12 pre-commit hook for linting and formatting in both C++ and Python

@arijit-dasgupta
Copy link
Contributor Author

Part of MET-6

In this PR, I also add in the CI support. It is really simple. All it does is create the virtual environment on a github runner, installs pixi, installs the genmetaballs package via pixi and cmake and tests for C++ and Python formatting an linting. That's it.

For now, I don't think it is worth the effort to set up Spot GPU runners to do remote GPU CI actions. The pre-push should be good enough fo rnow.

@arijit-dasgupta arijit-dasgupta changed the title C++ and Python Linting + Formatting + Format checks, including pre-commit and pre-push for GPU-code unit testing C++ and Python Linting + Formatting + Format checks, including pre-commit and pre-push for GPU-code unit testing + CI Nov 9, 2025
Copy link
Contributor

@mugamma mugamma left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great job dude! My overall comment is let's slim this down significantly. I don't think we need 7 scripts for linting. Let's just have a single simple lint/format/fix pixi taks, which is also called in the hooks. It's fine if this task is calling a script. I love the dev-setup task, and I think it should just do all that is needed for the setup of the dev env.

So at the end of the day it would be good to have

  1. A script for setting up the repo (also runnable through pixi dev-setup)
  2. A script for linting and formatting (also runnable through pixi lint)
  3. Hooks that call the second script

Comment on lines 37 to 42
- name: Check formatting
run: pixi run format-check

- name: Lint code
run: pixi run lint

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's also add the tests here. It's actually more important to run the tests than it is to do formatting and linting.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The issue here is that the ci has no GPU, so no CUDA code will run. That's why it can be more of a pre-push thing

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see this makes sense. Let me look into this.

# Run tests (pre-push hook)
- id: test
name: Run all tests
entry: scripts/test-quiet.sh
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this not using the pixi run test task that we already have?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does do that! (running ctest and pytest), but suppress the output to be quiet. I think everytime we push, it might get messy to have a a barrage of stdout or stderr. But honestly, who cares, we can remove this too.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense. TBH I prefer a pixi run test to a whole separate file in the codebase, but I do understand it's a matter of taste. I'm fine with keeping it this way.

README.md Outdated
Comment on lines 77 to 93
Lint all files:
```bash
pixi run lint
```

Auto-fix linting issues:
```bash
pixi run lint-fix
```

**Language-specific commands:**
- `format-cpp`, `format-python` - Format specific language
- `format-check-cpp`, `format-check-python` - Check formatting for specific language
- `lint-cpp`, `lint-python` - Lint specific language
- `lint-cpp-fix`, `lint-python-fix` - Auto-fix linting issues for specific language
- `lint-full` - C++/CUDA linting with compile_commands.json (more accurate)
- `lint-full-fix` - Auto-fix C++/CUDA issues using compile_commands.json
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's just have a single lint command that lints and tries to fix all files.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sounds good!

pyproject.toml Outdated
Comment on lines 43 to 69
compile-commands = "cmake -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON"
# Combined formatting and linting (C++/CUDA + Python)
format = { cmd = "scripts/format/all.sh" }
format-check = { cmd = "scripts/format/check-all.sh" }
lint = { cmd = "scripts/lint/all.sh" }
lint-fix = { cmd = "scripts/lint/fix-all.sh" }
# C++/CUDA only
format-cpp = { cmd = "scripts/format/cpp.sh" }
format-check-cpp = { cmd = "scripts/format/cpp.sh check" }
lint-cpp = { cmd = "scripts/lint/cpp.sh" }
lint-cpp-fix = { cmd = "scripts/lint/cpp-fix.sh" }
# lint-full: Uses compile_commands.json for more accurate C++/CUDA linting
# (includes proper include paths, defines, and compiler flags from CMake)
lint-full = { cmd = "scripts/lint/cpp.sh full" }
lint-full-fix = { cmd = "scripts/lint/cpp-fix.sh full" }
# Python only
format-python = { cmd = "scripts/format/python.sh" }
format-check-python = { cmd = "scripts/format/python.sh check" }
lint-python = { cmd = "scripts/lint/python.sh" }
lint-python-fix = { cmd = "scripts/lint/python-fix.sh" }
# Git hooks (using pre-commit framework)
install-hooks = { cmd = "pre-commit install && pre-commit install --hook-type pre-push" }
# Dev setup: install git hooks (for development workflow)
dev-setup = { cmd = "pre-commit install && pre-commit install --hook-type pre-push" }
# Pre-commit tasks
pre-commit-run = { cmd = "pre-commit run --all-files" }
pre-commit-run-push = { cmd = "scripts/test-quiet.sh" }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should definitely simplify this. Let's just have a single simple lint/format/fix command, which is also called in the hooks. I love the dev-setup task, and I think it should just do all that is needed for the setup of the dev env.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed!

Comment on lines +34 to +35
- name: Install dependencies
run: pixi install
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "Install pixi" step (line 18) is already implicitly running pixi install --locked under the hood, so we probably don't need to explicitly run pixi install again. Let's get rid of this in the future :)

@arijit-dasgupta arijit-dasgupta merged commit 1cda667 into master Nov 16, 2025
1 check passed
@arijit-dasgupta arijit-dasgupta deleted the arijit/lint-and-check-precommit branch November 16, 2025 22:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants