|
# Contributing to Nimcheck
|
|
|
|
Pure Nim stdlib, tokenizer-based validation, no external parser dependencies.
|
|
|
|
---
|
|
|
|
## Before you start
|
|
|
|
1. Read [docs/STATUS.md](docs/STATUS.md) — what's done and project scope.
|
|
2. Read [README.md](README.md) — architecture and API.
|
|
3. Default branch is **`master`**. Open PRs against `master`.
|
|
4. CI must pass: `make lint && make test` (see [docs/GITEA.md](docs/GITEA.md)).
|
|
|
|
---
|
|
|
|
## Development setup
|
|
|
|
```bash
|
|
git clone https://retoor.molodetz.nl/retoor/nimcheck.git
|
|
cd nimcheck
|
|
nimble build
|
|
nimble test
|
|
```
|
|
|
|
Requires **Nim >= 2.0.0**.
|
|
|
|
---
|
|
|
|
## Code style
|
|
|
|
- Match existing naming and module layout.
|
|
- Keep validators simple: tokenize → analyze → report.
|
|
- **Never throw from validation paths** — catch and return `E9999`.
|
|
- No new external dependencies without discussion.
|
|
- Minimal comments; code should be self-explanatory.
|
|
|
|
---
|
|
|
|
## Adding a new language
|
|
|
|
### 1. Types and detection
|
|
|
|
In `src/nimcheck/core/types.nim`:
|
|
|
|
- Add `lfYourlang` to `LanguageFlavor` if missing.
|
|
- Add string conversion in `$` / `parseFlavor` helpers.
|
|
|
|
In `src/nimcheck/core/detector.nim`:
|
|
|
|
- Add extension mappings to `extensionMap`.
|
|
- Add shebang entries if applicable.
|
|
- Add content-scoring keywords (avoid false positives — see entropy/margin rules).
|
|
|
|
### 2. Tokenizer
|
|
|
|
Create `src/nimcheck/tokenizers/<lang>_tokenizer.nim` (or extend `extended_tokenizers.nim` / `cfamily_tokenizers.nim` for CLike langs):
|
|
|
|
```nim
|
|
type MyLangTokenizer* = ref object of TokenizerBase
|
|
|
|
method tokenize*(self: MyLangTokenizer) =
|
|
while self.hasMore():
|
|
let posBefore = self.pos
|
|
# ... lex next token ...
|
|
self.finishTokenizeStep(posBefore) # REQUIRED — prevents infinite loops
|
|
self.emitToken(tkEndOfFile, "", self.currentPos())
|
|
```
|
|
|
|
Rules:
|
|
|
|
- Always call `finishTokenizeStep(posBefore)` at end of each loop iteration.
|
|
- Use `closeBracket()` for `)`, `]`, `}` — it advances position.
|
|
- Record errors via `recordError()`, don't raise.
|
|
|
|
### 3. Validator
|
|
|
|
Create `src/nimcheck/languages/<lang>_validator.nim`:
|
|
|
|
```nim
|
|
type MyLangValidator* = ref object of ValidatorBase
|
|
|
|
method createTokenizer*(self: MyLangValidator): TokenizerBase = ...
|
|
|
|
method analyzeTokens*(self: MyLangValidator) =
|
|
procCall ValidatorBase(self).analyzeTokens() # bracket validation
|
|
# language-specific block/string/structure checks
|
|
```
|
|
|
|
Register in `init()`:
|
|
|
|
```nim
|
|
registerValidator("mylang", proc(...) = result = newMyLangValidator(...))
|
|
```
|
|
|
|
### 4. Wire up
|
|
|
|
- Import validator in `src/nimcheck.nim` (inside the validator import block).
|
|
- Add factory case in `src/nimcheck/core/validatorbase.nim` `createValidator()` if needed.
|
|
|
|
### 5. Tests
|
|
|
|
For each language add:
|
|
|
|
```
|
|
tests/fixtures/<lang>/valid.*
|
|
tests/fixtures/<lang>/invalid.*
|
|
tests/fixtures/<lang>/edge_cases.*
|
|
tests/test_<lang>.nim # basic: good code, bad code, files, detectFlavor
|
|
tests/test_<lang>_exhaustive.nim
|
|
```
|
|
|
|
Add shared snippets to `tests/test_common.nim` if other tests need them.
|
|
|
|
Import in `tests/test_all.nim`.
|
|
|
|
**Makefile tab pitfall:** In Nim `"""` strings, a line starting with `\t` is often backslash+t (ord 92+116), not TAB (ord 9). Use:
|
|
|
|
```nim
|
|
"""recipe line""" & "\t" & """command"""
|
|
```
|
|
|
|
### 6. Documentation
|
|
|
|
Update `README.md` language table and `docs/STATUS.md` if adding a flavor.
|
|
|
|
---
|
|
|
|
## Running tests
|
|
|
|
```bash
|
|
make test # everything
|
|
nim c -r tests/test_go.nim # single language
|
|
make test-nim # via Makefile shortcut
|
|
nimble test # via nimble task
|
|
```
|
|
|
|
---
|
|
|
|
## Pull request checklist
|
|
|
|
- [ ] `make lint` passes
|
|
- [ ] `make test` passes
|
|
- [ ] New language has fixtures + basic + exhaustive tests
|
|
- [ ] `detectFlavor` works for good-code sample in `test_common.nim`
|
|
- [ ] No debug binaries or `*.log` committed
|
|
- [ ] README / STATUS updated if behavior or flavors changed
|
|
|
|
---
|
|
|
|
## Reporting bugs
|
|
|
|
Include:
|
|
|
|
1. Nim version (`nim --version`)
|
|
2. Input source (minimal repro)
|
|
3. Expected vs actual `ValidationResult`
|
|
4. Whether it hangs (likely tokenizer loop — check `finishTokenizeStep`)
|
|
|
|
---
|
|
|
|
## License
|
|
|
|
By contributing, you agree your changes are licensed under the project MIT license. |