###### *<div align="right"><sub>// by RuztyCrabs</sub></div>*
<img src="https://raw.githubusercontent.com/RuztyCrabs/Blazelint/refs/heads/main/docs/assets/blazelint-banner-2.webp" alt="BlazeLint banner" style="width: 2000px; height: auto;">
##
> [!WARNING]
> This is a **University Research Project** and **SHOULD NOT BE USED ON PRODUCTION ENVIRONMENTS**. The goal is to determine the feasibility, performance and developer experience of Rust Programming Language for implementing static code analyzers for Ballerina Language.
## Table of Contents
- [Documentation](#documentation)
- [Installation](#installation)
- [Usage](#usage)
- [Configuration](#configuration)
- [Development environment](#development-environment)
- [Using GitHub Codespaces](#using-github-codespaces)
- [Using VS Code ](#using-vs-code-if-you-have-it-installed-locally)
- [Building](#building)
- [Prerequisites ](#prerequisites-skip-if-using-the-dev-container)
- [Steps](#steps)
- [Debugging](#debugging)
- [Prerequisites ](#prerequisites-skip-if-using-the-dev-container-1)
- [Steps](#steps-1)
- [Contributing](#contributing)
- [TODO](#todo)
- [License](#license)
## Documentation
* [BNF Grammar for Ballerina Subset](docs/BNF.md)
* [Software Requirement Specification (SRS)](https://github.com/RuztyCrabs/Blazelint/releases/latest/download/BlazeLint-SRS.pdf)
* [Pipeline overview](docs/pipeline_overview.md)
* [Quick Reference](docs/QUICK_REFERENCE.md)
* [Implementation Notes](docs/IMPLEMENTATION_NOTES.md)
## Installation
Install the latest published version from [crates.io](https://crates.io/crates/blazelint):
```bash
cargo install blazelint
```
Pre-build binaries are available for Linux from the [latest GitHub release](https://github.com/RuztyCrabs/Blazelint/releases/latest).
_Windows and MacOS binaries will be added in a later release._
## Usage
### Basic Usage
Analyze a Ballerina source file by passing its path to `blazelint`:
```bash
blazelint path/to/file.bal
```
> [!NOTE]
> Use the limited subset document in the [BNF](docs/BNF.md) when defining Ballerina syntax to be linted.
The tool prints the input program, a token stream, the parsed AST, and exits or emits diagnostics if there is any and exits with a non-zero status.
### Development Usage
Running from a checked-out repository is also supported:
```bash
cargo run -- path/to/file.bal
```
> [!NOTE]
> `cargo run` builds and executes an unoptimized build (for debug requirements). Always use `cargo build --release` for any benchmark or observations on performance.
For a quick smoke test, you can reuse the sample program in `tests/test-bal-files/`:
```bash
blazelint tests/test-bal-files/simple_errors.bal
```
## Configuration
### Configuration File
Blazelint looks for a `.blazerc` configuration file in the current directory or any parent directory. The configuration uses TOML format:
```toml
# .blazerc - Blazelint Configuration File
[rules]
# Naming convention rules
camel-case = "error" # Enforces camelCase for variables/functions
constant-case = "warn" # Enforces SCREAMING_SNAKE_CASE for constants
# Code style rules
line-length = "warn" # Limits line length
max-function-length = "error" # Limits function body length
missing-return = "error" # Ensures functions have return statements
unused-variables = "warn" # Detects unused variable declarations
# Disable specific rules
some-rule = "off"
[settings]
max-line-length = 120 # Maximum characters per line
max-function-length = 50 # Maximum lines in function body
```
#### Rule Configuration Values
Each rule can be configured with one of these severity levels:
- `"error"` - Causes build failure (non-zero exit code)
- `"warn"` - Shows warnings but allows build to succeed
- `"info"` - Shows informational messages
- `"off"` - Disables the rule completely
#### Available Rules
| `camel-case` | Enforces camelCase naming for variables and functions | `error` | None |
| `constant-case` | Enforces SCREAMING_SNAKE_CASE for constants | `warn` | None |
| `line-length` | Limits line length | `warn` | `max-line-length` |
| `max-function-length` | Limits function body length | `warn` | `max-function-length` |
| `missing-return` | Ensures functions have return statements | `error` | None |
| `unused-variables` | Detects unused variable declarations | `warn` | None |
### Configuration Discovery
Blazelint searches for `.blazerc` files in this order:
1. **Current directory**: `./.blazerc`
2. **Parent directories**: Walks up the directory tree looking for `.blazerc`
3. **Default configuration**: Uses built-in defaults if no file found
### Rule Engine
The rule engine features:
- **Dynamic Rule Loading**: Only enabled rules are executed
- **Configurable Severity**: Each rule respects configured severity levels
- **Caching**: Configuration is cached for performance
- **Extensible Design**: New rules can be added easily
## Development environment
A pre-configured [Dev Container](https://containers.dev/) is available that can be used to investigate, develop or debug the program without installing anything on the host machine.
It can be launched and used fully remotely inside a browser using GitHub codespaces, or locally using Visual Studio Code.
### Using GitHub Codespaces
1. Click **Code → Create codespace** from the GitHub UI.
2. Wait for the Codespace to provision (first run will take some significant time).
3. Start Developing!
### Using Visual Studio Code
1. Install the **Dev Containers** extension.
2. Clone this repository and open it in VS Code.
3. Run the **Dev Containers: Reopen in Container** command.
4. Wait till the container spins up.
5. Start Developing!
The container comes with:
- Rust toolchain
- Typst CLI for building the SRS
- Ballerina runtime
- Extensions for Language Servers, syntax highlighting and debugging support
- Common utilities (zsh, GitHub CLI, git, etc.)
### Development Dependencies
The project uses the following key dependencies:
- **Core**: Standard library only for main linting logic
- **Configuration**: `serde`, `toml` for config file parsing
- **Utilities**: `once_cell`, `thiserror` for error handling and caching
- **Testing**: `assert_cmd`, `tempfile` for integration tests
## Building
### Prerequisites
- Git 2.51.0 or newer
- Rust Toolchain 1.86.0 or newer [(Get it here)](https://rust-lang.org/tools/install/)
### Steps
1. Create a fork and clone to local:
```bash
git clone https://github.com/<your-profile-name>/Blazelint.git
```
2. `cd` into the directory:
```bash
cd Blazelint
```
3. Build with cargo:
```bash
cargo build --release
```
## Debugging
### Prerequisites
- Build requirements stated [here](#building).
- [Visual Studio Code IDE by Microsoft](https://code.visualstudio.com/download)
- [Rust Analyzer extension by rust-lang.org](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer)
- [CodeLLDB extension by Vadim Chugunov](https://marketplace.visualstudio.com/items?itemName=vadimcn.vscode-lldb)
- Ballerina toolchain and IDE extension (optional - for testing or writing ballerina codes)
### Steps
- You can adjust the `tests/test-bal-files/` files if you need to debug a specific diagnostic.
- Create a `.blazerc` config file to test configuration changes.
- Set breakpoints as needed.
- Click on **Run and Debug** from the main method or use `ctrl+shift+D` to jump to debug menu.
> [!NOTE]
> It is possible to debug with any IDE including Neovim, Emacs and etc but we recommend Visual Studio Code for easier setup.
## Contributing
- Changes should be developed and push to following branches based on the area of the feature.
- feature/linter-core: Changes to the linter engine (lexer, parser, semantic analyzer and BNF document).
- feature/rule-engine: Changes to rule engine, configuration system, and linter rules.
- ci/cd: Changes related to continous integration and deployments.
- docs: Changes related to documentation.
- Run all formatter, lint, and test checks locally before opening a pull request:
```bash
bash scripts/check.sh
```
## Release Process
BlazeLint uses a **tag-driven release workflow** for simplicity. To cut a new release:
1. Decide the next semantic version (e.g. `1.2.3`).
2. Update the version in `Cargo.toml` (or use the existing bump workflow via GitHub UI if preferred).
3. Ensure all checks pass locally:
```bash
bash scripts/check.sh
```
4. Commit and push the version change to `main`.
5. Create and push the tag matching the version (must start with `v`):
```bash
git tag -a v1.2.3 -m "Release v1.2.3"
git push origin v1.2.3
```
6. GitHub Actions workflow `Publish crate` (release-crate.yml) will:
- Verify the tag matches `Cargo.toml`.
- Build and test the project.
- Package a Linux binary.
- Create a GitHub Release with artifacts.
- Publish the crate to crates.io (requires `CRATES_IO_TOKEN` secret).
### Dry Run
You can simulate locally before tagging:
```bash
cargo publish --dry-run
```
### Notes
- Tag pattern: `v*.*.*` (e.g. `v0.3.1`).
- If the tag does not match the `Cargo.toml` version, the build fails early.
- Existing automated workflows (`bump-version.yml` + PR + tag) still work if you prefer that path.
For multi-platform binaries, extend `simple-release.yml` with matrix builds and upload additional artifacts.
### Adding New Rules
When adding a new linter rule:
1. **Create the rule**: Implement the `LintRule` trait in `src/linter/rules/`
2. **Register the rule**: Add to the rule registry in `src/lib.rs`
3. **Add default configuration**: Update `Config::default()` in `src/config.rs`
4. **Add tests**: Include unit tests and integration tests
5. **Update docs**: Add rule to the Available Rules table above
### Configuration Changes
When modifying configuration:
1. **Update schema**: Modify configuration structs in `src/config.rs`
2. **Update defaults**: Ensure backward compatibility in `Config::default()`
3. **Update validation**: Add appropriate validation logic in `validate_config()`
4. **Update tests**: Test configuration loading and validation
5. **Update documentation**: Update configuration examples and rule tables
## TODO
Roadmap of the project can be viewed from [here](TODO.md).
## License
This project is licensed under the [MIT License](LICENSE).