blazelint 0.3.0

A code linter for Ballerina programming language
Documentation
###### *<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

| Rule | Description | Default Severity | Settings |
|------|-------------|------------------|----------|
| `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).